--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+
+<fileset-config file-format-version="1.2.0" simple-config="false" sync-formatter="false">
+ <local-check-config name="JalviewCheckstyle" location="utils/checkstyle/checkstyle.xml" type="project" description="">
+ <additional-data name="protect-config-file" value="false"/>
+ </local-check-config>
+ <fileset name="source" enabled="true" check-config-name="JalviewCheckstyle" local="true">
+ <file-match-pattern match-pattern="src/.*.java" include-pattern="true"/>
+ <file-match-pattern match-pattern="resources/.*.properties" include-pattern="true"/>
+ </fileset>
+ <filter name="NonSrcDirs" enabled="false"/>
+</fileset-config>
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 4th June 2014.
+This is the authoritative list. It was correct on 6th Oct 2016.
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 !
--- /dev/null
+If you use Jalview in your work, please cite the Jalview 2 paper in Bioinformatics:
+
+Waterhouse, A.M., Procter, J.B., Martin, D.M.A, Clamp, M., Barton, G.J (2009),
+"Jalview version 2: A Multiple Sequence Alignment and Analysis Workbench,"
+Bioinformatics 25 (9) 1189-1191 doi: 10.1093/bioinformatics/btp033
-jalview.release=Release_2_9_0b1_Branch
-jalview.version=2.9.0b2
+jalview.release=Release_2_10_0_Branch
+jalview.version=2.10.0b1
quaqua: v.8.0 (latest stable) by Randel S Hofer. LGPL and BSD Modified license: downloaded from http://www.randelshofer.ch/quaqua/
-lib/htsjdk-1.120-SNAPSHOT.jar: built from maven master at https://github.com/samtools/htsjdk MIT License to Broad Institute
+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/biojava-core-4.1.0.jar LGPLv2.1 - latest license at https://github.com/biojava/biojava/blob/master/LICENSE
+
+lib/biojava-ontology-4.1.0.jar LGPLv2.1 - latest license at https://github.com/biojava/biojava/blob/master/LICENSE
Additional dependencies
examples/javascript/jquery*.js : BSD license
examples/javascript/jshashtable-2.1.js : Apache License
-Tools not bundled with Jalview source
-jbake (http://jbake.org MIT license) was used to build the JalviewLite examples pages found in the examples directory.
-
</axis-wsdl2java>
</target>
-<target name="makedist" depends="build, buildPropertiesFile, buildindices">
+<target name="makedist" depends="build, buildPropertiesFile, linkcheck, buildindices">
<!-- make the package jar if not already existing -->
<mkdir dir="${packageDir}" />
<!-- clean dir if it already existed -->
<target name="compileApplet" depends="init,clean">
<mkdir dir="${outputDir}" />
- <javac source="${javac.source}" target="${javac.target}" srcdir="${sourceDir}" destdir="${outputDir}" debug="${javac.debug}" classpathref="jalviewlite.deps" includes="jalview/appletgui/**" excludes="ext/**,gui/**,jbgui/**,MCview/**,org/**,vamsas/**,jalview/ext/rbvi/**,jalview/ext/paradise/**,jalview/ext/ensembl/**,jalview/ext/so" />
+ <javac source="${javac.source}" target="${javac.target}" srcdir="${sourceDir}" destdir="${outputDir}" debug="${javac.debug}" classpathref="jalviewlite.deps" includes="jalview/appletgui/**" excludes="ext/**,gui/**,jbgui/**,MCview/**,org/**,vamsas/**,jalview/ext/rbvi/**,jalview/ext/paradise/**,jalview/ext/ensembl/**,jalview/ext/so/**" />
</target>
<target name="packageApplet" depends="compileApplet, buildPropertiesFile">
<pathelement location="appletlib/${jsoup}" />
<pathelement location="appletlib/${jsonSimple}" />
<pathelement location="appletlib/${javaJson}" />
- <fileset dir="${java.home}/lib">
- <include name="plugin.jar" />
+ <fileset dir="${java.home}/lib">
+ <include name="plugin.jar" />
</fileset>
</path>
<taskdef resource="proguard/ant/task.properties" classpath="utils/proguard.jar" />
<proguard verbose="true" >
- <injar file="in.jar" />
- <outjar file="${jalviewLiteJar}" />
- <libraryjar refid="obfuscateDeps.path" />
+ <injar file="in.jar" />
+ <outjar file="${jalviewLiteJar}" />
+ <libraryjar refid="obfuscateDeps.path" />
<dontwarn />
<keep access="public" type="class" name="jalview.bin.JalviewLite">
<field access="public" />
<constructor/>
<method name="*"/>
</keep>
-
+
<keep access="public" type="class" name="MCview.PDBfile">
<field access="public" />
<method access="public" />
<method access="public" />
<constructor access="public" />
</keep>
-
+
<keep access="public" type="class" name="jalview.ext.jmol.JmolParser">
<field access="public" />
<method access="public" />
<constructor access="public" />
</keep>
-
-
+
+
<!-- -libraryjars "${obfuscateDeps}"
-injars in.jar
-outjars jalviewApplet.jar
</target>
<target name="sourcedist" description="create jalview source distribution" depends="init">
<delete file="${source.dist.name}" />
- <tar destfile="${source.dist.name}" compression="gzip">
- <tarfileset dir="./" prefix="jalview" preserveLeadingSlashes="true">
+ <!-- temporary copy of source to update timestamps -->
+ <copy todir="_sourcedist">
+ <fileset dir=".">
<include name="LICENSE" />
<include name="README" />
<include name="build.xml" />
<include name="utils/**/*" />
<include name="${docDir}/**/*" />
<include name="examples/**/*" />
+ </fileset>
+ </copy>
+
+ <tstamp prefix="build">
+ <format property="year" pattern="yyyy" />
+ </tstamp>
+ <!-- each replacetoken CDATA body must be on one line -
+ otherwise the pattern doesn't match -->
+ <replace value="${JALVIEW_VERSION}">
+ <replacetoken><![CDATA[$$Version-Rel$$]]></replacetoken>
+ <fileset dir="_sourcedist">
+ <include name="**/*" />
+ </fileset>
+ </replace>
+ <replace dir="_sourcedist" value="${build.year}">
+ <replacetoken><![CDATA[$$Year-Rel$$]]></replacetoken>
+ <fileset dir="_sourcedist">
+ <include name="**/*" />
+ </fileset>
+ </replace>
+
+ <tar destfile="${source.dist.name}" compression="gzip">
+ <tarfileset dir="_sourcedist/" prefix="jalview" preserveLeadingSlashes="true">
</tarfileset>
</tar>
+
+ <delete dir="_sourcedist" />
</target>
<target name="prepubapplet_1" depends="makeApplet">
<copy todir="${packageDir}/examples">
</packageset>
</javadoc>
</target>
+<target name="linkcheck" depends="init,prepare">
+ <javac srcdir="utils" destdir="utils" includes="HelpLinksChecker.java"/>
+ <java fork="true" dir="${helpDir}" classpath="utils" classname="HelpLinksChecker" failonerror="true">
+ <arg file="${helpDir}"/>
+ <arg value="-nointernet"/>
+ </java>
+</target>
</project>
<!DOCTYPE html>
+<!--
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ -->
<html>
<head>
<title>BioJSON Format Documentation</title>
</html>
-
\ No newline at end of file
+
+<!--
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ -->
<!DOCTYPE html>
<html>
<head>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML+RDFa 1.1//EN">
-<html lang="en" dir="ltr" version="HTML+RDFa 1.1"
+<!--
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ -->
+ <html lang="en" dir="ltr" version="HTML+RDFa 1.1"
xmlns:content="http://purl.org/rss/1.0/modules/content/"
xmlns:dc="http://purl.org/dc/terms/"
xmlns:foaf="http://xmlns.com/foaf/0.1/" xmlns:og="http://ogp.me/ns#"
Iron-sulfur (2Fe-2S) FER_BRANA -1 77 77 METAL
<html>Fer2 Status: True Positive <a href="http://pfam.xfam.org/family/PF00111">Pfam 8_8</a></html> FER_BRANA -1 8 83 Pfam
Ferredoxin_fold Status: True Positive FER_BRANA -1 2 96 Cath
-Iron-sulfur (2Fe-2S) FER2_ARATH -1 91 91 METAL
-Iron-sulfur (2Fe-2S) FER2_ARATH -1 96 96 METAL
-Iron-sulfur (2Fe-2S) FER2_ARATH -1 99 99 METAL
-Iron-sulfur (2Fe-2S) FER2_ARATH -1 129 129 METAL
-<html>Fer2 Status: True Positive <a href="http://pfam.xfam.org/family/PF00111">Pfam 60_13</a></html> FER2_ARATH -1 60 135 Pfam
-Ferredoxin_fold Status: True Positive FER2_ARATH -1 50 145 Cath
+Iron-sulfur (2Fe-2S) FER1_ARATH -1 91 91 METAL
+Iron-sulfur (2Fe-2S) FER1_ARATH -1 96 96 METAL
+Iron-sulfur (2Fe-2S) FER1_ARATH -1 99 99 METAL
+Iron-sulfur (2Fe-2S) FER1_ARATH -1 129 129 METAL
+<html>Fer2 Status: True Positive <a href="http://pfam.xfam.org/family/PF00111">Pfam 60_13</a></html> FER1_ARATH -1 60 135 Pfam
+Ferredoxin_fold Status: True Positive FER1_ARATH -1 50 145 Cath
<html>Fer2 Status: True Positive <a href="http://pfam.xfam.org/family/PF00111">Pfam 60_11</a></html> Q93Z60_ARATH -1 60 118 Pfam
Ferredoxin_fold Status: True Positive Q93Z60_ARATH -1 52 118 Cath
Iron-sulfur (2Fe-2S) FER1_MAIZE -1 91 91 METAL
<html>High confidence server. Only hits with scores over 0.8 are reported. <a href="http://www.cbs.dtu.dk/cgi-bin/proview/webface-link?seqid=P00221&service=NetPhos-2.0">PHOSPHORYLATION (S) 112_11</a></html> FER1_SPIOL -1 112 112 PHOSPHORYLATION (S)
<html>High confidence server. Only hits with scores over 0.8 are reported. <a href="http://www.cbs.dtu.dk/cgi-bin/proview/webface-link?seqid=P00221&service=NetPhos-2.0">PHOSPHORYLATION (T) 139_13</a></html> FER1_SPIOL -1 139 139 PHOSPHORYLATION (T)
<html>High confidence server. Only hits with scores over 0.8 are reported. <a href="http://www.cbs.dtu.dk/cgi-bin/proview/webface-link?seqid=P00221&service=NetPhos-2.0">PHOSPHORYLATION (Y) 73_7</a></html> FER1_SPIOL -1 73 73 PHOSPHORYLATION (Y)
-<html>High confidence server. Only hits with scores over 0.8 are reported. <a href="http://www.cbs.dtu.dk/cgi-bin/proview/webface-link?seqid=FER1_ARATH&service=NetPhos-2.0">PHOSPHORYLATION (S) 19_1</a></html> FER1_ARATH -1 19 19 PHOSPHORYLATION (S)
-<html>High confidence server. Only hits with scores over 0.8 are reported. <a href="http://www.cbs.dtu.dk/cgi-bin/proview/webface-link?seqid=FER1_ARATH&service=NetPhos-2.0">PHOSPHORYLATION (S) 24_2</a></html> FER1_ARATH -1 24 24 PHOSPHORYLATION (S)
-<html>High confidence server. Only hits with scores over 0.8 are reported. <a href="http://www.cbs.dtu.dk/cgi-bin/proview/webface-link?seqid=FER1_ARATH&service=NetPhos-2.0">PHOSPHORYLATION (S) 90_9</a></html> FER1_ARATH -1 90 90 PHOSPHORYLATION (S)
-<html>High confidence server. Only hits with scores over 0.8 are reported. <a href="http://www.cbs.dtu.dk/cgi-bin/proview/webface-link?seqid=FER1_ARATH&service=NetPhos-2.0">PHOSPHORYLATION (S) 107_10</a></html> FER1_ARATH -1 107 107 PHOSPHORYLATION (S)
-<html>High confidence server. Only hits with scores over 0.8 are reported. <a href="http://www.cbs.dtu.dk/cgi-bin/proview/webface-link?seqid=FER1_ARATH&service=NetPhos-2.0">PHOSPHORYLATION (S) 114_11</a></html> FER1_ARATH -1 114 114 PHOSPHORYLATION (S)
-<html>High confidence server. Only hits with scores over 0.8 are reported. <a href="http://www.cbs.dtu.dk/cgi-bin/proview/webface-link?seqid=FER1_ARATH&service=NetPhos-2.0">PHOSPHORYLATION (T) 141_14</a></html> FER1_ARATH -1 141 141 PHOSPHORYLATION (T)
-<html>High confidence server. Only hits with scores over 0.8 are reported. <a href="http://www.cbs.dtu.dk/cgi-bin/proview/webface-link?seqid=FER1_ARATH&service=NetPhos-2.0">PHOSPHORYLATION (Y) 75_7</a></html> FER1_ARATH -1 75 75 PHOSPHORYLATION (Y)
+<html>High confidence server. Only hits with scores over 0.8 are reported. <a href="http://www.cbs.dtu.dk/cgi-bin/proview/webface-link?seqid=FER2_ARATH&service=NetPhos-2.0">PHOSPHORYLATION (S) 19_1</a></html> FER2_ARATH -1 19 19 PHOSPHORYLATION (S)
+<html>High confidence server. Only hits with scores over 0.8 are reported. <a href="http://www.cbs.dtu.dk/cgi-bin/proview/webface-link?seqid=FER2_ARATH&service=NetPhos-2.0">PHOSPHORYLATION (S) 24_2</a></html> FER2_ARATH -1 24 24 PHOSPHORYLATION (S)
+<html>High confidence server. Only hits with scores over 0.8 are reported. <a href="http://www.cbs.dtu.dk/cgi-bin/proview/webface-link?seqid=FER2_ARATH&service=NetPhos-2.0">PHOSPHORYLATION (S) 90_9</a></html> FER2_ARATH -1 90 90 PHOSPHORYLATION (S)
+<html>High confidence server. Only hits with scores over 0.8 are reported. <a href="http://www.cbs.dtu.dk/cgi-bin/proview/webface-link?seqid=FER2_ARATH&service=NetPhos-2.0">PHOSPHORYLATION (S) 107_10</a></html> FER2_ARATH -1 107 107 PHOSPHORYLATION (S)
+<html>High confidence server. Only hits with scores over 0.8 are reported. <a href="http://www.cbs.dtu.dk/cgi-bin/proview/webface-link?seqid=FER2_ARATH&service=NetPhos-2.0">PHOSPHORYLATION (S) 114_11</a></html> FER2_ARATH -1 114 114 PHOSPHORYLATION (S)
+<html>High confidence server. Only hits with scores over 0.8 are reported. <a href="http://www.cbs.dtu.dk/cgi-bin/proview/webface-link?seqid=FER2_ARATH&service=NetPhos-2.0">PHOSPHORYLATION (T) 141_14</a></html> FER2_ARATH -1 141 141 PHOSPHORYLATION (T)
+<html>High confidence server. Only hits with scores over 0.8 are reported. <a href="http://www.cbs.dtu.dk/cgi-bin/proview/webface-link?seqid=FER2_ARATH&service=NetPhos-2.0">PHOSPHORYLATION (Y) 75_7</a></html> FER2_ARATH -1 75 75 PHOSPHORYLATION (Y)
<html>High confidence server. Only hits with scores over 0.8 are reported. <a href="http://www.cbs.dtu.dk/cgi-bin/proview/webface-link?seqid=P00227&service=NetPhos-2.0">PHOSPHORYLATION (S) 38_3</a></html> FER_BRANA -1 38 38 PHOSPHORYLATION (S)
<html>High confidence server. Only hits with scores over 0.8 are reported. <a href="http://www.cbs.dtu.dk/cgi-bin/proview/webface-link?seqid=P00227&service=NetPhos-2.0">PHOSPHORYLATION (S) 62_6</a></html> FER_BRANA -1 62 62 PHOSPHORYLATION (S)
<html>High confidence server. Only hits with scores over 0.8 are reported. <a href="http://www.cbs.dtu.dk/cgi-bin/proview/webface-link?seqid=P00227&service=NetPhos-2.0">PHOSPHORYLATION (T) 89_8</a></html> FER_BRANA -1 89 89 PHOSPHORYLATION (T)
<html>
+<!--
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ -->
<header><title>BioJS viewer</title></header>
<body>
-(((FER_BRANA:128.0,FER3_RAPSA:128.0):50.75,FER_CAPAA:178.75):121.94443,(Q93Z60_ARATH:271.45456,((O80429_MAIZE:183.0,FER1_MAIZE:183.0):30.5,((Q7XA98_TRIPR:90.0,FER1_PEA:90.0):83.32143,(((FER2_ARATH:64.0,FER1_ARATH:64.0):94.375,(FER1_SPIOL:124.5,FER1_MESCR:124.5):33.875):6.4166718,((Q93XJ9_SOLTU:33.5,FER1_SOLLC:33.5):49.0,FER_CAPAN:82.5):82.29167):8.529755):40.178574):57.95456):29.239868);
+(((FER_BRANA:128.0,FER3_RAPSA:128.0):50.75,FER_CAPAA:178.75):121.94443,(Q93Z60_ARATH:271.45456,((O80429_MAIZE:183.0,FER1_MAIZE:183.0):30.5,((Q7XA98_TRIPR:90.0,FER1_PEA:90.0):83.32143,(((FER1_ARATH:64.0,FER2_ARATH:64.0):94.375,(FER1_SPIOL:124.5,FER1_MESCR:124.5):33.875):6.4166718,((Q93XJ9_SOLTU:33.5,FER1_SOLLC:33.5):49.0,FER_CAPAN:82.5):82.29167):8.529755):40.178574):57.95456):29.239868);
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
+
import jalview.workers.FeatureCounterI;
import jalview.workers.AlignmentAnnotationFactory;
* Example script that registers two alignment annotation calculators
* - one that counts residues in a column with Pfam annotation
* - one that counts only charged residues with Pfam annotation
- * To try this, first load uniref50.fa from the examples folder, then load features
- * from examples/exampleFeatures.txt, before running this script from the Groovy console.
+ *
+ * To try:
+ * 1. load uniref50.fa from the examples folder
+ * 2. load features onto it from from examples/exampleFeatures.txt
+ * 3. Open this script in the Groovy console.
+ * 4. Either execute this script from the console, or via Calculate->Run Groovy Script
- * Modify this example as required to count by column any desired value that can be
- * derived from the residue and sequence features at each position of an alignment.
+ * To explore further, try changing this script to count other kinds of occurrences of
+ * residue and sequence features at columns in an alignment.
*/
/*
}
/*
- * Closure that counts residues with a Pfam feature annotation
+ * Closure that computes an annotation based on
+ * presence of particular residues and features
* Parameters are
* - the name (label) for the alignment annotation
* - the description (tooltip) for the annotation
}
/*
- * Define an annotation that counts any residue with Pfam domain annotation
+ * Define an annotation row that counts any residue with Pfam domain annotation
*/
def pfamAnnotation = getColumnCounter("Pfam", "Count of residues with Pfam domain annotation", {true}, hasPfam)
/*
- * Define an annotation that counts charged residues with Pfam domain annotation
+ * Define an annotation row that counts charged residues with Pfam domain annotation
*/
def chargedPfamAnnotation = getColumnCounter("Pfam charged", "Count of charged residues with Pfam domain annotation", isCharged, hasPfam)
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML+RDFa 1.1//EN">
-<html lang="en" dir="ltr" version="HTML+RDFa 1.1"
+<!--
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ -->
+ <html lang="en" dir="ltr" version="HTML+RDFa 1.1"
xmlns:content="http://purl.org/rss/1.0/modules/content/"
xmlns:dc="http://purl.org/dc/terms/"
xmlns:foaf="http://xmlns.com/foaf/0.1/" xmlns:og="http://ogp.me/ns#"
----------------------------------------------------------ATYKVKFITPEGEQ
EVECDDDVYVLDAAEEAGIDLPYSCRAGSCSSCAGKVVSGSVDQSDQSFLDDDQIAEGFVLTCAAYPTSDVT
IETHREEDMV--
->FER1_ARATH/1-148
+>FER2_ARATH/1-148
----MASTALSSAIVGTSFIRRSPAPISLRSLPSANT-QSLFGLKS-GTARGGRVTAMATYKVKFITPEGEL
EVECDDDVYVLDAAEEAGIDLPYSCRAGSCSSCAGKVVSGSVDQSDQSFLDDEQIGEGFVLTCAAYPTSDVT
IETHKEEDIV--
----------------------------------------------------------ATYKVKFITPEGEQ
EVECDDDVYVLDAAEEAGIDLPYSCRAGSCSSCAGKVVSGFVDQSDESFLDDDQIAEGFVLTCAAYPTSDVT
IETHKEEELV--
->FER2_ARATH/1-148
+>FER1_ARATH/1-148
----MASTALSSAIVSTSFLRRQQTPISLRSLPFANT-QSLFGLKS-STARGGRVTAMATYKVKFITPEGEQ
EVECEEDVYVLDAAEEAGLDLPYSCRAGSCSSCAGKVVSGSIDQSDQSFLDDEQMSEGYVLTCVAYPTSDVV
IETHKEEAIM--
R -> K FER3_RAPSA -1 91 91 VARIANT
M -> V FER3_RAPSA -1 95 95 VARIANT
<html>Description: Fer2 Status: True Positive <a href="http://pfam.xfam.org/family/PF00111">Pfam 8_83</a></html> FER3_RAPSA -1 8 83 Pfam
-Chloroplast FER1_ARATH -1 1 52 TRANSIT
-Iron-sulfur (2Fe-2S) FER1_ARATH -1 91 91 METAL
-Iron-sulfur (2Fe-2S) FER1_ARATH -1 96 96 METAL
-Iron-sulfur (2Fe-2S) FER1_ARATH -1 99 99 METAL
-Iron-sulfur (2Fe-2S) FER1_ARATH -1 129 129 METAL
-<html>Description: Fer2 Status: True Positive <a href="http://pfam.xfam.org/family/PF00111">Pfam 60_135</a></html> FER1_ARATH -1 60 135 Pfam
-Iron-sulfur (2Fe-2S) FER_BRANA -1 39 39 METAL
-Iron-sulfur (2Fe-2S) FER_BRANA -1 44 44 METAL
-Iron-sulfur (2Fe-2S) FER_BRANA -1 47 47 METAL
-Iron-sulfur (2Fe-2S) FER_BRANA -1 77 77 METAL
-<html>Description: Fer2 Status: True Positive <a href="http://pfam.xfam.org/family/PF00111">Pfam 8_83</a></html> FER_BRANA -1 8 83 Pfam
Chloroplast FER2_ARATH -1 1 52 TRANSIT
Iron-sulfur (2Fe-2S) FER2_ARATH -1 91 91 METAL
Iron-sulfur (2Fe-2S) FER2_ARATH -1 96 96 METAL
Iron-sulfur (2Fe-2S) FER2_ARATH -1 99 99 METAL
Iron-sulfur (2Fe-2S) FER2_ARATH -1 129 129 METAL
<html>Description: Fer2 Status: True Positive <a href="http://pfam.xfam.org/family/PF00111">Pfam 60_135</a></html> FER2_ARATH -1 60 135 Pfam
+Iron-sulfur (2Fe-2S) FER_BRANA -1 39 39 METAL
+Iron-sulfur (2Fe-2S) FER_BRANA -1 44 44 METAL
+Iron-sulfur (2Fe-2S) FER_BRANA -1 47 47 METAL
+Iron-sulfur (2Fe-2S) FER_BRANA -1 77 77 METAL
+<html>Description: Fer2 Status: True Positive <a href="http://pfam.xfam.org/family/PF00111">Pfam 8_83</a></html> FER_BRANA -1 8 83 Pfam
+Chloroplast FER1_ARATH -1 1 52 TRANSIT
+Iron-sulfur (2Fe-2S) FER1_ARATH -1 91 91 METAL
+Iron-sulfur (2Fe-2S) FER1_ARATH -1 96 96 METAL
+Iron-sulfur (2Fe-2S) FER1_ARATH -1 99 99 METAL
+Iron-sulfur (2Fe-2S) FER1_ARATH -1 129 129 METAL
+<html>Description: Fer2 Status: True Positive <a href="http://pfam.xfam.org/family/PF00111">Pfam 60_135</a></html> FER1_ARATH -1 60 135 Pfam
<html>Description: Fer2 Status: True Positive <a href="http://pfam.xfam.org/family/PF00111">Pfam 60_118</a></html> Q93Z60_ARATH -1 60 118 Pfam
Chloroplast FER1_MAIZE -1 1 52 TRANSIT
STRAND FER1_MAIZE -1 57 59 STRAND
--- /dev/null
+>a
+QQQ
+>b
+QQQ
+>c
+QQQ
+>d
+QQQ
+>e
+QQQ
+>f
+QQQ
+>g
+QQQ
+>h
+QQQ
--- /dev/null
+feature_1 8c25cd
+
+STARTGROUP Jalview
+feature_1 a -1 1 1 feature_1 0.4
+feature_1 a -1 2 2 feature_1 0.6
+feature_1 b -1 1 1 feature_1 0.8
+feature_1 b -1 2 2 feature_1 1.0
+feature_1 c -1 1 1 feature_1 1.5
+feature_1 d -1 1 1 feature_1 2.0
+feature_1 e -1 1 1 feature_1 3.0
+ENDGROUP Jalview
--- /dev/null
+ATOM 7013 N ALA A 650 -32.039 -14.559 -3.977 1.00 97.16 N
+ATOM 7014 CA ALA A 650 -33.253 -15.372 -3.971 1.00101.29 C
+ATOM 7015 C ALA A 650 -32.928 -16.865 -4.014 1.00102.48 C
+ATOM 7016 O ALA A 650 -33.833 -17.704 -4.075 1.00102.31 O
+ATOM 7017 CB ALA A 650 -34.168 -14.987 -5.138 1.00 94.98 C
+ATOM 7018 N MET A 651 -31.636 -17.186 -3.978 1.00 98.86 N
+ATOM 7019 CA MET A 651 -31.164 -18.568 -4.040 1.00 95.81 C
+ATOM 7020 C MET A 651 -29.680 -18.618 -3.678 1.00 95.69 C
+ATOM 7021 O MET A 651 -28.847 -18.030 -4.367 1.00 93.27 O
+ATOM 7022 CB MET A 651 -31.414 -19.157 -5.435 1.00 94.70 C
+ATOM 7023 CG MET A 651 -31.097 -18.189 -6.581 1.00 93.74 C
+ATOM 7024 SD MET A 651 -31.780 -18.651 -8.198 1.00 87.88 S
+ATOM 7025 CE MET A 651 -30.854 -20.142 -8.594 1.00 81.80 C
+ATOM 7026 N LYS A 652 -29.355 -19.313 -2.589 1.00 95.36 N
+ATOM 7027 CA LYS A 652 -27.982 -19.355 -2.075 1.00 88.97 C
+ATOM 7028 C LYS A 652 -27.021 -20.133 -2.984 1.00 89.03 C
+ATOM 7029 O LYS A 652 -27.393 -21.143 -3.592 1.00 90.36 O
+ATOM 7030 CB LYS A 652 -27.953 -19.930 -0.656 1.00 85.99 C
+ATOM 7031 N ARG A 653 -25.784 -19.655 -3.070 1.00 83.57 N
+ATOM 7032 CA ARG A 653 -24.765 -20.305 -3.888 1.00 82.09 C
+ATOM 7033 C ARG A 653 -23.704 -20.963 -3.017 1.00 79.82 C
+ATOM 7034 O ARG A 653 -23.327 -20.431 -1.977 1.00 79.58 O
+ATOM 7035 CB ARG A 653 -24.115 -19.291 -4.831 1.00 84.10 C
+ATOM 7036 CG ARG A 653 -23.554 -18.068 -4.129 1.00 82.91 C
+ATOM 7037 CD ARG A 653 -23.098 -17.010 -5.124 1.00 84.28 C
+ATOM 7038 NE ARG A 653 -23.064 -15.675 -4.527 1.00 83.48 N
+ATOM 7039 CZ ARG A 653 -21.959 -15.047 -4.134 1.00 82.34 C
+ATOM 7040 NH1 ARG A 653 -20.770 -15.621 -4.277 1.00 80.52 N
+ATOM 7041 NH2 ARG A 653 -22.045 -13.836 -3.602 1.00 84.76 N
+ATOM 7042 N ARG A 654 -23.219 -22.122 -3.446 1.00 83.16 N
+ATOM 7043 CA ARG A 654 -22.263 -22.882 -2.647 1.00 84.47 C
+ATOM 7044 C ARG A 654 -20.845 -22.831 -3.207 1.00 82.72 C
+ATOM 7045 O ARG A 654 -20.611 -22.306 -4.294 1.00 84.47 O
+ATOM 7046 CB ARG A 654 -22.720 -24.337 -2.500 1.00 86.90 C
+ATOM 7047 CG ARG A 654 -22.700 -25.156 -3.785 1.00 90.62 C
+ATOM 7048 CD ARG A 654 -21.792 -26.372 -3.625 1.00 94.56 C
+ATOM 7049 NE ARG A 654 -22.296 -27.559 -4.313 1.00100.64 N
+ATOM 7050 CZ ARG A 654 -21.755 -28.770 -4.203 1.00101.77 C
+ATOM 7051 NH1 ARG A 654 -20.690 -28.949 -3.433 1.00 99.43 N
+ATOM 7052 NH2 ARG A 654 -22.277 -29.803 -4.858 1.00103.21 N
+ATOM 7053 N ARG A 655 -19.901 -23.377 -2.452 1.00 80.06 N
+ATOM 7054 CA ARG A 655 -18.522 -23.461 -2.899 1.00 81.57 C
+ATOM 7055 C ARG A 655 -18.393 -24.576 -3.925 1.00 85.28 C
+ATOM 7056 O ARG A 655 -19.120 -25.567 -3.865 1.00 87.19 O
+ATOM 7057 CB ARG A 655 -17.617 -23.772 -1.718 1.00 83.19 C
+ATOM 7058 CG ARG A 655 -17.720 -25.217 -1.265 1.00 86.49 C
+ATOM 7059 CD ARG A 655 -17.099 -25.402 0.093 1.00 85.01 C
+ATOM 7060 NE ARG A 655 -15.880 -24.617 0.223 1.00 85.24 N
+ATOM 7061 CZ ARG A 655 -15.123 -24.608 1.310 1.00 87.53 C
+ATOM 7062 NH1 ARG A 655 -15.465 -25.351 2.354 1.00 87.44 N
+ATOM 7063 NH2 ARG A 655 -14.028 -23.864 1.350 1.00 89.64 N
<html>
+<!--
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ -->
<input type="hidden" name="seqData" id="seqData" value='{"seqs":[{"name":"FER_CAPAA/1-97","start":1,"svid":"1.0","end":97,"id":"4362914","seq":"-----------------------------------------------------------ASYKVKLITPDGPIEFDCPDDVYILDQAEEAGHDLPYSCRAGSCSSCAGKIAGGAVDQTDGNFLDDDQLEEGWVLTCVAYPQSDVTIETHKEAELVG-","order":1},{"name":"FER_CAPAN/1-144","start":1,"svid":"1.0","end":144,"id":"87519910","seq":"MA------SVSATMISTSFMPRKPAVTSL-KPIPNVGE--ALFGLKS-A--NGGKVTCMASYKVKLITPDGPIEFDCPDNVYILDQAEEAGHDLPYSCRAGSCSSCAGKIAGGAVDQTDGNFLDDDQLEEGWVLTCVAYPQSDVTIETHKEAELVG-","order":2},{"name":"FER1_SOLLC/1-144","start":1,"svid":"1.0","end":144,"id":"706449716","seq":"MA------SISGTMISTSFLPRKPAVTSL-KAISNVGE--ALFGLKS-G--RNGRITCMASYKVKLITPEGPIEFECPDDVYILDQAEEEGHDLPYSCRAGSCSSCAGKVTAGSVDQSDGNFLDEDQEAAGFVLTCVAYPKGDVTIETHKEEELTA-","order":3},{"name":"Q93XJ9_SOLTU/1-144","start":1,"svid":"1.0","end":144,"id":"1704607829","seq":"MA------SISGTMISTSFLPRKPVVTSL-KAISNVGE--ALFGLKS-G--RNGRITCMASYKVKLITPDGPIEFECPDDVYILDQAEEEGHDLPYSCRAGSCSSCAGKVTAGTVDQSDGKFLDDDQEAAGFVLTCVAYPKCDVTIETHKEEELTA-","order":4},{"name":"FER1_PEA/1-149","start":1,"svid":"1.0","end":149,"id":"1901660614","seq":"MATT---PALYGTAVSTSFLRTQPMPMSV-TTTKAFSN--GFLGLKT-SLKRGDLAVAMASYKVKLVTPDGTQEFECPSDVYILDHAEEVGIDLPYSCRAGSCSSCAGKVVGGEVDQSDGSFLDDEQIEAGFVLTCVAYPTSDVVIETHKEEDLTA-","order":5},{"name":"Q7XA98_TRIPR/1-152","start":1,"svid":"1.0","end":152,"id":"1329985289","seq":"MATT---PALYGTAVSTSFMRRQPVPMSV-ATTTTTKAFPSGFGLKSVSTKRGDLAVAMATYKVKLITPEGPQEFDCPDDVYILDHAEEVGIELPYSCRAGSCSSCAGKVVNGNVNQEDGSFLDDEQIEGGWVLTCVAFPTSDVTIETHKEEELTA-","order":6},{"name":"FER1_MESCR/1-148","start":1,"svid":"1.0","end":148,"id":"966876644","seq":"MAAT--TAALSGATMSTAFAPK--TPPMTAALPTNVGR--ALFGLKS-SASR-GRVTAMAAYKVTLVTPEGKQELECPDDVYILDAAEEAGIDLPYSCRAGSCSSCAGKVTSGSVNQDDGSFLDDDQIKEGWVLTCVAYPTGDVTIETHKEEELTA-","order":7},{"name":"FER1_SPIOL/1-147","start":1,"svid":"1.0","end":147,"id":"235809389","seq":"MAAT--TTTMMG--MATTFVPKPQAPPMMAALPSNTGR--SLFGLKT-GSR--GGRMTMAAYKVTLVTPTGNVEFQCPDDVYILDAAEEEGIDLPYSCRAGSCSSCAGKLKTGSLNQDDQSFLDDDQIDEGWVLTCAAYPVSDVTIETHKEEELTA-","order":8},{"name":"FER3_RAPSA/1-96","start":1,"svid":"1.0","end":96,"id":"924845395","seq":"-----------------------------------------------------------ATYKVKFITPEGEQEVECDDDVYVLDAAEEAGIDLPYSCRAGSCSSCAGKVVSGSVDQSDQSFLDDDQIAEGFVLTCAAYPTSDVTIETHREEDMV--","order":9},{"name":"FER1_ARATH/1-148","start":1,"svid":"1.0","end":148,"id":"1472020737","seq":"MAST----ALSSAIVGTSFIRRSPAPISLRSLPSANTQ--SLFGLKS-GTARGGRVTAMATYKVKFITPEGELEVECDDDVYVLDAAEEAGIDLPYSCRAGSCSSCAGKVVSGSVDQSDQSFLDDEQIGEGFVLTCAAYPTSDVTIETHKEEDIV--","order":10},{"name":"FER_BRANA/1-96","start":1,"svid":"1.0","end":96,"id":"1690335343","seq":"-----------------------------------------------------------ATYKVKFITPEGEQEVECDDDVYVLDAAEEAGIDLPYSCRAGSCSSCAGKVVSGFVDQSDESFLDDDQIAEGFVLTCAAYPTSDVTIETHKEEELV--","order":11},{"name":"FER2_ARATH/1-148","start":1,"svid":"1.0","end":148,"id":"467823576","seq":"MAST----ALSSAIVSTSFLRRQQTPISLRSLPFANTQ--SLFGLKS-STARGGRVTAMATYKVKFITPEGEQEVECEEDVYVLDAAEEAGLDLPYSCRAGSCSSCAGKVVSGSIDQSDQSFLDDEQMSEGYVLTCVAYPTSDVVIETHKEEAIM--","order":12},{"name":"Q93Z60_ARATH/1-118","start":1,"svid":"1.0","end":118,"id":"752877418","seq":"MAST----ALSSAIVSTSFLRRQQTPISLRSLPFANTQ--SLFGLKS-STARGGRVTAMATYKVKFITPEGEQEVECEEDVYVLDAAEEAGLDLPYSCRAGSCSSCAGKVVSGSIDQSDQSFLDD--------------------------------","order":13},{"name":"FER1_MAIZE/1-150","start":1,"svid":"1.0","end":150,"id":"299304633","seq":"MATVLGSPRAPAFFFSSSSLRAAPAPTAV--ALPAAKV--GIMGRSA-SSRR--RLRAQATYNVKLITPEGEVELQVPDDVYILDQAEEDGIDLPYSCRAGSCSSCAGKVVSGSVDQSDQSYLDDGQIADGWVLTCHAYPTSDVVIETHKEEELTGA","order":14},{"name":"O80429_MAIZE/1-140","start":1,"svid":"1.0","end":140,"id":"1991448556","seq":"MAAT---------ALSMSILR---APPPCFSSPLRLRV--AVAKPLA-APMRRQLLRAQATYNVKLITPEGEVELQVPDDVYILDFAEEEGIDLPFSCRAGSCSSCAGKVVSGSVDQSDQSFLNDNQVADGWVLTCAAYPTSDVVIETHKEDDLL--","order":15},{"name":"1A70|/1-97","start":1,"svid":"1.0","end":97,"id":"2114395721","seq":"-----------------------------------------------------------AAYKVTLVTPTGNVEFQCPDDVYILDAAEEEGIDLPYSCRAGSCSSCAGKLKTGSLNQDDQSFLDDDQIDEGWVLTCAAYPVSDVTIETHKKEELTA","order":16}],"appSettings":{"globalColorScheme":"foo","webStartUrl":"www.jalview.org/services/launchApp","application":"Jalview","hiddenSeqs":"2114395721","showSeqFeatures":"false","version":"2.9"},"seqGroups":[{"displayText":true,"startRes":59,"groupName":"ferredoxin","endRes":124,"colourText":false,"seqsHash":["1472020737","299304633","966876644","1901660614","706449716","235809389","467823576","924845395","1690335343","4362914","87519910","752877418","1329985289","1991448556","1704607829"],"svid":"1.0","showNonconserved":false,"colourScheme":"Zappo","displayBoxes":true}],"alignAnnotation":[{"svid":"1.0","annotations":[{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"1","value":1,"secondaryStructure":"E"},{"displayCharacter":"","value":0,"secondaryStructure":"E"},{"displayCharacter":"","value":0,"secondaryStructure":"E"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"2","value":2,"secondaryStructure":"E"},{"displayCharacter":"","value":0,"secondaryStructure":"E"},{"displayCharacter":"","value":0,"secondaryStructure":"E"},{"displayCharacter":"","value":0,"secondaryStructure":"E"},{"displayCharacter":"","value":0,"secondaryStructure":"E"},{"displayCharacter":"","value":0,"secondaryStructure":"E"},{"displayCharacter":"","value":0,"secondaryStructure":"E"},{"displayCharacter":"","value":0,"secondaryStructure":"E"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"3","value":3,"secondaryStructure":"H"},{"displayCharacter":"","value":0,"secondaryStructure":"H"},{"displayCharacter":"","value":0,"secondaryStructure":"H"},{"displayCharacter":"","value":0,"secondaryStructure":"H"},{"displayCharacter":"","value":0,"secondaryStructure":"H"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"description":"Fe","displayCharacter":"Fe","value":0,"secondaryStructure":" "},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"description":"Fe","displayCharacter":"Fe","value":0,"secondaryStructure":" "},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"description":"Fe","displayCharacter":"Fe","value":0,"secondaryStructure":" "},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"4","value":4,"secondaryStructure":"E"},{"displayCharacter":"","value":0,"secondaryStructure":"E"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"5","value":5,"secondaryStructure":"E"},{"displayCharacter":"","value":0,"secondaryStructure":"E"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"6","value":6,"secondaryStructure":"H"},{"displayCharacter":"","value":0,"secondaryStructure":"H"},{"displayCharacter":"","value":0,"secondaryStructure":"H"},{"displayCharacter":"","value":0,"secondaryStructure":"H"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"7","value":7,"secondaryStructure":"E"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"description":"Fe","displayCharacter":"Fe","value":0,"secondaryStructure":" "},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"E"},{"displayCharacter":"","value":0,"secondaryStructure":"E"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"9","value":9,"secondaryStructure":"E"},{"displayCharacter":"","value":0,"secondaryStructure":"E"},{"displayCharacter":"","value":0,"secondaryStructure":"E"},{"displayCharacter":"","value":0,"secondaryStructure":"E"},{"displayCharacter":"","value":0,"secondaryStructure":"E"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"}],"description":"New description","label":"Secondary Structure"},{"svid":"1.0","annotations":[{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"description":"Fe","displayCharacter":"Fe","value":0,"secondaryStructure":" "},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"description":"Fe","displayCharacter":"Fe","value":0,"secondaryStructure":" "},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"description":"Fe","displayCharacter":"Fe","value":0,"secondaryStructure":" "},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"description":"Fe","displayCharacter":"Fe","value":0,"secondaryStructure":" "},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"},{"displayCharacter":"","value":0,"secondaryStructure":"\u0000"}],"description":"New description","label":"Iron Sulphur Contacts"}],"svid":"1.0","seqFeatures":[{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ALA: 1 1a70 ","xStart":59,"xEnd":60,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ALA: 2 1a70 ","xStart":60,"xEnd":61,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"TYR: 3 1a70 ","xStart":61,"xEnd":62,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"LYS: 4 1a70 ","xStart":62,"xEnd":63,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"VAL: 5 1a70 ","xStart":63,"xEnd":64,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"THR: 6 1a70 ","xStart":64,"xEnd":65,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"LEU: 7 1a70 ","xStart":65,"xEnd":66,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"VAL: 8 1a70 ","xStart":66,"xEnd":67,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"THR: 9 1a70 ","xStart":67,"xEnd":68,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"PRO: 10 1a70 ","xStart":68,"xEnd":69,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"THR: 11 1a70 ","xStart":69,"xEnd":70,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"GLY: 12 1a70 ","xStart":70,"xEnd":71,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ASN: 13 1a70 ","xStart":71,"xEnd":72,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"VAL: 14 1a70 ","xStart":72,"xEnd":73,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"GLU: 15 1a70 ","xStart":73,"xEnd":74,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"PHE: 16 1a70 ","xStart":74,"xEnd":75,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"GLN: 17 1a70 ","xStart":75,"xEnd":76,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"CYS: 18 1a70 ","xStart":76,"xEnd":77,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"PRO: 19 1a70 ","xStart":77,"xEnd":78,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ASP: 20 1a70 ","xStart":78,"xEnd":79,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ASP: 21 1a70 ","xStart":79,"xEnd":80,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"VAL: 22 1a70 ","xStart":80,"xEnd":81,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"TYR: 23 1a70 ","xStart":81,"xEnd":82,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ILE: 24 1a70 ","xStart":82,"xEnd":83,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"LEU: 25 1a70 ","xStart":83,"xEnd":84,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ASP: 26 1a70 ","xStart":84,"xEnd":85,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ALA: 27 1a70 ","xStart":85,"xEnd":86,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ALA: 28 1a70 ","xStart":86,"xEnd":87,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"GLU: 29 1a70 ","xStart":87,"xEnd":88,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"GLU: 30 1a70 ","xStart":88,"xEnd":89,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"GLU: 31 1a70 ","xStart":89,"xEnd":90,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"GLY: 32 1a70 ","xStart":90,"xEnd":91,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ILE: 33 1a70 ","xStart":91,"xEnd":92,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ASP: 34 1a70 ","xStart":92,"xEnd":93,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"LEU: 35 1a70 ","xStart":93,"xEnd":94,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"PRO: 36 1a70 ","xStart":94,"xEnd":95,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"TYR: 37 1a70 ","xStart":95,"xEnd":96,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"SER: 38 1a70 ","xStart":96,"xEnd":97,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"CYS: 39 1a70 ","xStart":97,"xEnd":98,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ARG: 40 1a70 ","xStart":98,"xEnd":99,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ALA: 41 1a70 ","xStart":99,"xEnd":100,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"GLY: 42 1a70 ","xStart":100,"xEnd":101,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"SER: 43 1a70 ","xStart":101,"xEnd":102,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"CYS: 44 1a70 ","xStart":102,"xEnd":103,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"SER: 45 1a70 ","xStart":103,"xEnd":104,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"SER: 46 1a70 ","xStart":104,"xEnd":105,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"CYS: 47 1a70 ","xStart":105,"xEnd":106,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ALA: 48 1a70 ","xStart":106,"xEnd":107,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"GLY: 49 1a70 ","xStart":107,"xEnd":108,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"LYS: 50 1a70 ","xStart":108,"xEnd":109,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"LEU: 51 1a70 ","xStart":109,"xEnd":110,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"LYS: 52 1a70 ","xStart":110,"xEnd":111,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"THR: 53 1a70 ","xStart":111,"xEnd":112,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"GLY: 54 1a70 ","xStart":112,"xEnd":113,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"SER: 55 1a70 ","xStart":113,"xEnd":114,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"LEU: 56 1a70 ","xStart":114,"xEnd":115,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ASN: 57 1a70 ","xStart":115,"xEnd":116,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"GLN: 58 1a70 ","xStart":116,"xEnd":117,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ASP: 59 1a70 ","xStart":117,"xEnd":118,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ASP: 60 1a70 ","xStart":118,"xEnd":119,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"GLN: 61 1a70 ","xStart":119,"xEnd":120,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"SER: 62 1a70 ","xStart":120,"xEnd":121,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"PHE: 63 1a70 ","xStart":121,"xEnd":122,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"LEU: 64 1a70 ","xStart":122,"xEnd":123,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ASP: 65 1a70 ","xStart":123,"xEnd":124,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ASP: 66 1a70 ","xStart":124,"xEnd":125,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ASP: 67 1a70 ","xStart":125,"xEnd":126,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"GLN: 68 1a70 ","xStart":126,"xEnd":127,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ILE: 69 1a70 ","xStart":127,"xEnd":128,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ASP: 70 1a70 ","xStart":128,"xEnd":129,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"GLU: 71 1a70 ","xStart":129,"xEnd":130,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"GLY: 72 1a70 ","xStart":130,"xEnd":131,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"TRP: 73 1a70 ","xStart":131,"xEnd":132,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"VAL: 74 1a70 ","xStart":132,"xEnd":133,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"LEU: 75 1a70 ","xStart":133,"xEnd":134,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"THR: 76 1a70 ","xStart":134,"xEnd":135,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"CYS: 77 1a70 ","xStart":135,"xEnd":136,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ALA: 78 1a70 ","xStart":136,"xEnd":137,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ALA: 79 1a70 ","xStart":137,"xEnd":138,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"TYR: 80 1a70 ","xStart":138,"xEnd":139,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"PRO: 81 1a70 ","xStart":139,"xEnd":140,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"VAL: 82 1a70 ","xStart":140,"xEnd":141,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"SER: 83 1a70 ","xStart":141,"xEnd":142,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ASP: 84 1a70 ","xStart":142,"xEnd":143,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"VAL: 85 1a70 ","xStart":143,"xEnd":144,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"THR: 86 1a70 ","xStart":144,"xEnd":145,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ILE: 87 1a70 ","xStart":145,"xEnd":146,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"GLU: 88 1a70 ","xStart":146,"xEnd":147,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"THR: 89 1a70 ","xStart":147,"xEnd":148,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"HIS: 90 1a70 ","xStart":148,"xEnd":149,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"LYS: 91 1a70 ","xStart":149,"xEnd":150,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"GLU: 93 1a70 ","xStart":151,"xEnd":152,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"GLU: 94 1a70 ","xStart":152,"xEnd":153,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"LEU: 95 1a70 ","xStart":153,"xEnd":154,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"THR: 96 1a70 ","xStart":154,"xEnd":155,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ALA: 97 1a70 ","xStart":155,"xEnd":156,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ALA:1 1a70 ","xStart":59,"xEnd":60,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ALA:2 1a70 ","xStart":60,"xEnd":61,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"TYR:3 1a70 ","xStart":61,"xEnd":62,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"LYS:4 1a70 ","xStart":62,"xEnd":63,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"VAL:5 1a70 ","xStart":63,"xEnd":64,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"THR:6 1a70 ","xStart":64,"xEnd":65,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"LEU:7 1a70 ","xStart":65,"xEnd":66,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"VAL:8 1a70 ","xStart":66,"xEnd":67,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"THR:9 1a70 ","xStart":67,"xEnd":68,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"PRO:10 1a70 ","xStart":68,"xEnd":69,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"THR:11 1a70 ","xStart":69,"xEnd":70,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"GLY:12 1a70 ","xStart":70,"xEnd":71,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ASN:13 1a70 ","xStart":71,"xEnd":72,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"VAL:14 1a70 ","xStart":72,"xEnd":73,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"GLU:15 1a70 ","xStart":73,"xEnd":74,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"PHE:16 1a70 ","xStart":74,"xEnd":75,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"GLN:17 1a70 ","xStart":75,"xEnd":76,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"CYS:18 1a70 ","xStart":76,"xEnd":77,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"PRO:19 1a70 ","xStart":77,"xEnd":78,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ASP:20 1a70 ","xStart":78,"xEnd":79,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ASP:21 1a70 ","xStart":79,"xEnd":80,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"VAL:22 1a70 ","xStart":80,"xEnd":81,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"TYR:23 1a70 ","xStart":81,"xEnd":82,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ILE:24 1a70 ","xStart":82,"xEnd":83,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"LEU:25 1a70 ","xStart":83,"xEnd":84,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ASP:26 1a70 ","xStart":84,"xEnd":85,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ALA:27 1a70 ","xStart":85,"xEnd":86,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ALA:28 1a70 ","xStart":86,"xEnd":87,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"GLU:29 1a70 ","xStart":87,"xEnd":88,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"GLU:30 1a70 ","xStart":88,"xEnd":89,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"GLU:31 1a70 ","xStart":89,"xEnd":90,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"GLY:32 1a70 ","xStart":90,"xEnd":91,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ILE:33 1a70 ","xStart":91,"xEnd":92,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ASP:34 1a70 ","xStart":92,"xEnd":93,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"LEU:35 1a70 ","xStart":93,"xEnd":94,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"PRO:36 1a70 ","xStart":94,"xEnd":95,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"TYR:37 1a70 ","xStart":95,"xEnd":96,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"SER:38 1a70 ","xStart":96,"xEnd":97,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"CYS:39 1a70 ","xStart":97,"xEnd":98,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ARG:40 1a70 ","xStart":98,"xEnd":99,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ALA:41 1a70 ","xStart":99,"xEnd":100,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"GLY:42 1a70 ","xStart":100,"xEnd":101,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"SER:43 1a70 ","xStart":101,"xEnd":102,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"CYS:44 1a70 ","xStart":102,"xEnd":103,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"SER:45 1a70 ","xStart":103,"xEnd":104,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"SER:46 1a70 ","xStart":104,"xEnd":105,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"CYS:47 1a70 ","xStart":105,"xEnd":106,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ALA:48 1a70 ","xStart":106,"xEnd":107,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"GLY:49 1a70 ","xStart":107,"xEnd":108,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"LYS:50 1a70 ","xStart":108,"xEnd":109,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"LEU:51 1a70 ","xStart":109,"xEnd":110,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"LYS:52 1a70 ","xStart":110,"xEnd":111,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"THR:53 1a70 ","xStart":111,"xEnd":112,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"GLY:54 1a70 ","xStart":112,"xEnd":113,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"SER:55 1a70 ","xStart":113,"xEnd":114,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"LEU:56 1a70 ","xStart":114,"xEnd":115,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ASN:57 1a70 ","xStart":115,"xEnd":116,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"GLN:58 1a70 ","xStart":116,"xEnd":117,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ASP:59 1a70 ","xStart":117,"xEnd":118,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ASP:60 1a70 ","xStart":118,"xEnd":119,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"GLN:61 1a70 ","xStart":119,"xEnd":120,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"SER:62 1a70 ","xStart":120,"xEnd":121,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"PHE:63 1a70 ","xStart":121,"xEnd":122,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"LEU:64 1a70 ","xStart":122,"xEnd":123,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ASP:65 1a70 ","xStart":123,"xEnd":124,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ASP:66 1a70 ","xStart":124,"xEnd":125,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ASP:67 1a70 ","xStart":125,"xEnd":126,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"GLN:68 1a70 ","xStart":126,"xEnd":127,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ILE:69 1a70 ","xStart":127,"xEnd":128,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ASP:70 1a70 ","xStart":128,"xEnd":129,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"GLU:71 1a70 ","xStart":129,"xEnd":130,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"GLY:72 1a70 ","xStart":130,"xEnd":131,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"TRP:73 1a70 ","xStart":131,"xEnd":132,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"VAL:74 1a70 ","xStart":132,"xEnd":133,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"LEU:75 1a70 ","xStart":133,"xEnd":134,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"THR:76 1a70 ","xStart":134,"xEnd":135,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"CYS:77 1a70 ","xStart":135,"xEnd":136,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ALA:78 1a70 ","xStart":136,"xEnd":137,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ALA:79 1a70 ","xStart":137,"xEnd":138,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"TYR:80 1a70 ","xStart":138,"xEnd":139,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"PRO:81 1a70 ","xStart":139,"xEnd":140,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"VAL:82 1a70 ","xStart":140,"xEnd":141,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"SER:83 1a70 ","xStart":141,"xEnd":142,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ASP:84 1a70 ","xStart":142,"xEnd":143,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"VAL:85 1a70 ","xStart":143,"xEnd":144,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"THR:86 1a70 ","xStart":144,"xEnd":145,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ILE:87 1a70 ","xStart":145,"xEnd":146,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"GLU:88 1a70 ","xStart":146,"xEnd":147,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"THR:89 1a70 ","xStart":147,"xEnd":148,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"HIS:90 1a70 ","xStart":148,"xEnd":149,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"LYS:91 1a70 ","xStart":149,"xEnd":150,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"GLU:93 1a70 ","xStart":151,"xEnd":152,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"GLU:94 1a70 ","xStart":152,"xEnd":153,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"LEU:95 1a70 ","xStart":153,"xEnd":154,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"THR:96 1a70 ","xStart":154,"xEnd":155,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"235809389","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ALA:97 1a70 ","xStart":155,"xEnd":156,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"ALA: 1 1a70 ","xStart":59,"xEnd":60,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"ALA: 2 1a70 ","xStart":60,"xEnd":61,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"TYR: 3 1a70 ","xStart":61,"xEnd":62,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"LYS: 4 1a70 ","xStart":62,"xEnd":63,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"VAL: 5 1a70 ","xStart":63,"xEnd":64,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"THR: 6 1a70 ","xStart":64,"xEnd":65,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"LEU: 7 1a70 ","xStart":65,"xEnd":66,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"VAL: 8 1a70 ","xStart":66,"xEnd":67,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"THR: 9 1a70 ","xStart":67,"xEnd":68,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"PRO: 10 1a70 ","xStart":68,"xEnd":69,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"THR: 11 1a70 ","xStart":69,"xEnd":70,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"GLY: 12 1a70 ","xStart":70,"xEnd":71,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"ASN: 13 1a70 ","xStart":71,"xEnd":72,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"VAL: 14 1a70 ","xStart":72,"xEnd":73,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"GLU: 15 1a70 ","xStart":73,"xEnd":74,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"PHE: 16 1a70 ","xStart":74,"xEnd":75,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"GLN: 17 1a70 ","xStart":75,"xEnd":76,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"CYS: 18 1a70 ","xStart":76,"xEnd":77,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"PRO: 19 1a70 ","xStart":77,"xEnd":78,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"ASP: 20 1a70 ","xStart":78,"xEnd":79,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"ASP: 21 1a70 ","xStart":79,"xEnd":80,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"VAL: 22 1a70 ","xStart":80,"xEnd":81,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"TYR: 23 1a70 ","xStart":81,"xEnd":82,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"ILE: 24 1a70 ","xStart":82,"xEnd":83,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"LEU: 25 1a70 ","xStart":83,"xEnd":84,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"ASP: 26 1a70 ","xStart":84,"xEnd":85,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"ALA: 27 1a70 ","xStart":85,"xEnd":86,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"ALA: 28 1a70 ","xStart":86,"xEnd":87,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"GLU: 29 1a70 ","xStart":87,"xEnd":88,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"GLU: 30 1a70 ","xStart":88,"xEnd":89,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"GLU: 31 1a70 ","xStart":89,"xEnd":90,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"GLY: 32 1a70 ","xStart":90,"xEnd":91,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"ILE: 33 1a70 ","xStart":91,"xEnd":92,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"ASP: 34 1a70 ","xStart":92,"xEnd":93,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"LEU: 35 1a70 ","xStart":93,"xEnd":94,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"PRO: 36 1a70 ","xStart":94,"xEnd":95,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"TYR: 37 1a70 ","xStart":95,"xEnd":96,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"SER: 38 1a70 ","xStart":96,"xEnd":97,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"CYS: 39 1a70 ","xStart":97,"xEnd":98,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"ARG: 40 1a70 ","xStart":98,"xEnd":99,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"ALA: 41 1a70 ","xStart":99,"xEnd":100,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"GLY: 42 1a70 ","xStart":100,"xEnd":101,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"SER: 43 1a70 ","xStart":101,"xEnd":102,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"CYS: 44 1a70 ","xStart":102,"xEnd":103,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"SER: 45 1a70 ","xStart":103,"xEnd":104,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"SER: 46 1a70 ","xStart":104,"xEnd":105,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"CYS: 47 1a70 ","xStart":105,"xEnd":106,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"ALA: 48 1a70 ","xStart":106,"xEnd":107,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"GLY: 49 1a70 ","xStart":107,"xEnd":108,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"LYS: 50 1a70 ","xStart":108,"xEnd":109,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"LEU: 51 1a70 ","xStart":109,"xEnd":110,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"LYS: 52 1a70 ","xStart":110,"xEnd":111,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"THR: 53 1a70 ","xStart":111,"xEnd":112,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"GLY: 54 1a70 ","xStart":112,"xEnd":113,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"SER: 55 1a70 ","xStart":113,"xEnd":114,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"LEU: 56 1a70 ","xStart":114,"xEnd":115,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"ASN: 57 1a70 ","xStart":115,"xEnd":116,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"GLN: 58 1a70 ","xStart":116,"xEnd":117,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"ASP: 59 1a70 ","xStart":117,"xEnd":118,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"ASP: 60 1a70 ","xStart":118,"xEnd":119,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"GLN: 61 1a70 ","xStart":119,"xEnd":120,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"SER: 62 1a70 ","xStart":120,"xEnd":121,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"PHE: 63 1a70 ","xStart":121,"xEnd":122,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"LEU: 64 1a70 ","xStart":122,"xEnd":123,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"ASP: 65 1a70 ","xStart":123,"xEnd":124,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"ASP: 66 1a70 ","xStart":124,"xEnd":125,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"ASP: 67 1a70 ","xStart":125,"xEnd":126,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"GLN: 68 1a70 ","xStart":126,"xEnd":127,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"ILE: 69 1a70 ","xStart":127,"xEnd":128,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"ASP: 70 1a70 ","xStart":128,"xEnd":129,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"GLU: 71 1a70 ","xStart":129,"xEnd":130,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"GLY: 72 1a70 ","xStart":130,"xEnd":131,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"TRP: 73 1a70 ","xStart":131,"xEnd":132,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"VAL: 74 1a70 ","xStart":132,"xEnd":133,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"LEU: 75 1a70 ","xStart":133,"xEnd":134,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"THR: 76 1a70 ","xStart":134,"xEnd":135,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"CYS: 77 1a70 ","xStart":135,"xEnd":136,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"ALA: 78 1a70 ","xStart":136,"xEnd":137,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"ALA: 79 1a70 ","xStart":137,"xEnd":138,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"TYR: 80 1a70 ","xStart":138,"xEnd":139,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"PRO: 81 1a70 ","xStart":139,"xEnd":140,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"VAL: 82 1a70 ","xStart":140,"xEnd":141,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"SER: 83 1a70 ","xStart":141,"xEnd":142,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"ASP: 84 1a70 ","xStart":142,"xEnd":143,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"VAL: 85 1a70 ","xStart":143,"xEnd":144,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"THR: 86 1a70 ","xStart":144,"xEnd":145,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"ILE: 87 1a70 ","xStart":145,"xEnd":146,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"GLU: 88 1a70 ","xStart":146,"xEnd":147,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"THR: 89 1a70 ","xStart":147,"xEnd":148,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"HIS: 90 1a70 ","xStart":148,"xEnd":149,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"LYS: 91 1a70 ","xStart":149,"xEnd":150,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"LYS: 92 1a70 ","xStart":150,"xEnd":151,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"GLU: 93 1a70 ","xStart":151,"xEnd":152,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"GLU: 94 1a70 ","xStart":152,"xEnd":153,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"LEU: 95 1a70 ","xStart":153,"xEnd":154,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"THR: 96 1a70 ","xStart":154,"xEnd":155,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":""},"svid":"1.0","description":"ALA: 97 1a70 ","xStart":155,"xEnd":156,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ALA:1 1a70 ","xStart":59,"xEnd":60,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ALA:2 1a70 ","xStart":60,"xEnd":61,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"TYR:3 1a70 ","xStart":61,"xEnd":62,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"LYS:4 1a70 ","xStart":62,"xEnd":63,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"VAL:5 1a70 ","xStart":63,"xEnd":64,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"THR:6 1a70 ","xStart":64,"xEnd":65,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"LEU:7 1a70 ","xStart":65,"xEnd":66,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"VAL:8 1a70 ","xStart":66,"xEnd":67,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"THR:9 1a70 ","xStart":67,"xEnd":68,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"PRO:10 1a70 ","xStart":68,"xEnd":69,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"THR:11 1a70 ","xStart":69,"xEnd":70,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"GLY:12 1a70 ","xStart":70,"xEnd":71,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ASN:13 1a70 ","xStart":71,"xEnd":72,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"VAL:14 1a70 ","xStart":72,"xEnd":73,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"GLU:15 1a70 ","xStart":73,"xEnd":74,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"PHE:16 1a70 ","xStart":74,"xEnd":75,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"GLN:17 1a70 ","xStart":75,"xEnd":76,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"CYS:18 1a70 ","xStart":76,"xEnd":77,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"PRO:19 1a70 ","xStart":77,"xEnd":78,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ASP:20 1a70 ","xStart":78,"xEnd":79,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ASP:21 1a70 ","xStart":79,"xEnd":80,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"VAL:22 1a70 ","xStart":80,"xEnd":81,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"TYR:23 1a70 ","xStart":81,"xEnd":82,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ILE:24 1a70 ","xStart":82,"xEnd":83,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"LEU:25 1a70 ","xStart":83,"xEnd":84,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ASP:26 1a70 ","xStart":84,"xEnd":85,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ALA:27 1a70 ","xStart":85,"xEnd":86,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ALA:28 1a70 ","xStart":86,"xEnd":87,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"GLU:29 1a70 ","xStart":87,"xEnd":88,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"GLU:30 1a70 ","xStart":88,"xEnd":89,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"GLU:31 1a70 ","xStart":89,"xEnd":90,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"GLY:32 1a70 ","xStart":90,"xEnd":91,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ILE:33 1a70 ","xStart":91,"xEnd":92,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ASP:34 1a70 ","xStart":92,"xEnd":93,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"LEU:35 1a70 ","xStart":93,"xEnd":94,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"PRO:36 1a70 ","xStart":94,"xEnd":95,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"TYR:37 1a70 ","xStart":95,"xEnd":96,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"SER:38 1a70 ","xStart":96,"xEnd":97,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"CYS:39 1a70 ","xStart":97,"xEnd":98,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ARG:40 1a70 ","xStart":98,"xEnd":99,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ALA:41 1a70 ","xStart":99,"xEnd":100,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"GLY:42 1a70 ","xStart":100,"xEnd":101,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"SER:43 1a70 ","xStart":101,"xEnd":102,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"CYS:44 1a70 ","xStart":102,"xEnd":103,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"SER:45 1a70 ","xStart":103,"xEnd":104,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"SER:46 1a70 ","xStart":104,"xEnd":105,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"CYS:47 1a70 ","xStart":105,"xEnd":106,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ALA:48 1a70 ","xStart":106,"xEnd":107,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"GLY:49 1a70 ","xStart":107,"xEnd":108,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"LYS:50 1a70 ","xStart":108,"xEnd":109,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"LEU:51 1a70 ","xStart":109,"xEnd":110,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"LYS:52 1a70 ","xStart":110,"xEnd":111,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"THR:53 1a70 ","xStart":111,"xEnd":112,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"GLY:54 1a70 ","xStart":112,"xEnd":113,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"SER:55 1a70 ","xStart":113,"xEnd":114,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"LEU:56 1a70 ","xStart":114,"xEnd":115,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ASN:57 1a70 ","xStart":115,"xEnd":116,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"GLN:58 1a70 ","xStart":116,"xEnd":117,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ASP:59 1a70 ","xStart":117,"xEnd":118,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ASP:60 1a70 ","xStart":118,"xEnd":119,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"GLN:61 1a70 ","xStart":119,"xEnd":120,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"SER:62 1a70 ","xStart":120,"xEnd":121,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"PHE:63 1a70 ","xStart":121,"xEnd":122,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"LEU:64 1a70 ","xStart":122,"xEnd":123,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ASP:65 1a70 ","xStart":123,"xEnd":124,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ASP:66 1a70 ","xStart":124,"xEnd":125,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ASP:67 1a70 ","xStart":125,"xEnd":126,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"GLN:68 1a70 ","xStart":126,"xEnd":127,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ILE:69 1a70 ","xStart":127,"xEnd":128,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ASP:70 1a70 ","xStart":128,"xEnd":129,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"GLU:71 1a70 ","xStart":129,"xEnd":130,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"GLY:72 1a70 ","xStart":130,"xEnd":131,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"TRP:73 1a70 ","xStart":131,"xEnd":132,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"VAL:74 1a70 ","xStart":132,"xEnd":133,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"LEU:75 1a70 ","xStart":133,"xEnd":134,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"THR:76 1a70 ","xStart":134,"xEnd":135,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"CYS:77 1a70 ","xStart":135,"xEnd":136,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ALA:78 1a70 ","xStart":136,"xEnd":137,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ALA:79 1a70 ","xStart":137,"xEnd":138,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"TYR:80 1a70 ","xStart":138,"xEnd":139,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"PRO:81 1a70 ","xStart":139,"xEnd":140,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"VAL:82 1a70 ","xStart":140,"xEnd":141,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"SER:83 1a70 ","xStart":141,"xEnd":142,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ASP:84 1a70 ","xStart":142,"xEnd":143,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"VAL:85 1a70 ","xStart":143,"xEnd":144,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"THR:86 1a70 ","xStart":144,"xEnd":145,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ILE:87 1a70 ","xStart":145,"xEnd":146,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"GLU:88 1a70 ","xStart":146,"xEnd":147,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"THR:89 1a70 ","xStart":147,"xEnd":148,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"HIS:90 1a70 ","xStart":148,"xEnd":149,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"LYS:91 1a70 ","xStart":149,"xEnd":150,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"LYS:92 1a70 ","xStart":150,"xEnd":151,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"GLU:93 1a70 ","xStart":151,"xEnd":152,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"GLU:94 1a70 ","xStart":152,"xEnd":153,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"LEU:95 1a70 ","xStart":153,"xEnd":154,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"THR:96 1a70 ","xStart":154,"xEnd":155,"type":"RESNUM"},{"fillColor":"#ffffff","score":0,"sequenceRef":"2114395721","featureGroup":"1a70","otherDetails":{"status":"IEA:jalview"},"svid":"1.0","description":"ALA:97 1a70 ","xStart":155,"xEnd":156,"type":"RESNUM"}]}'>
<style type="text/css"> div.parent{ width:100%;<!-- overflow: auto; -->}
div.titlex{ width:11%; float: left; }
-----------------------------------------------------------ATYKVKFITPEGE
QEVECDDDVYVLDAAEEAGIDLPYSCRAGSCSSCAGKVVSGSVDQSDQSFLDDDQIAEGFVLTCAAYPTSDV
TIETHREEDMV--
->FER1_ARATH Ferredoxin-1, chloroplast precursor
+>FER2_ARATH Ferredoxin-2, chloroplast precursor
MAST----ALSSAIVGTSFIRRSPAPISLRSLPSANTQ--SLFGLKS-GTARGGRVTAMATYKVKFITPEGE
LEVECDDDVYVLDAAEEAGIDLPYSCRAGSCSSCAGKVVSGSVDQSDQSFLDDEQIGEGFVLTCAAYPTSDV
TIETHKEEDIV--
-----------------------------------------------------------ATYKVKFITPEGE
QEVECDDDVYVLDAAEEAGIDLPYSCRAGSCSSCAGKVVSGFVDQSDESFLDDDQIAEGFVLTCAAYPTSDV
TIETHKEEELV--
->FER2_ARATH Ferredoxin-2, chloroplast precursor
+>FER1_ARATH Ferredoxin-1, chloroplast precursor
MAST----ALSSAIVSTSFLRRQQTPISLRSLPFANTQ--SLFGLKS-STARGGRVTAMATYKVKFITPEGE
QEVECEEDVYVLDAAEEAGLDLPYSCRAGSCSSCAGKVVSGSIDQSDQSFLDDEQMSEGYVLTCVAYPTSDV
VIETHKEEAIM--
AAYKVTLVTPTGNVEFQCPDDVYILDAAEEEGIDLPYSCRAGSCSSCAGKLKTGSLNQDDQSFLDD
>FER3_RAPSA/1-66 Ferredoxin, leaf L-A
ATYKVKFITPEGEQEVECDDDVYVLDAAEEAGIDLPYSCRAGSCSSCAGKVVSGSVDQSDQSFLDD
->FER1_ARATH/53-118 Ferredoxin-1, chloroplast precursor
+>FER2_ARATH/53-118 Ferredoxin-1, chloroplast precursor
ATYKVKFITPEGELEVECDDDVYVLDAAEEAGIDLPYSCRAGSCSSCAGKVVSGSVDQSDQSFLDD
>FER_BRANA/1-66 Ferredoxin
ATYKVKFITPEGEQEVECDDDVYVLDAAEEAGIDLPYSCRAGSCSSCAGKVVSGFVDQSDESFLDD
->FER2_ARATH/53-118 Ferredoxin-2, chloroplast precursor
+>FER1_ARATH/53-118 Ferredoxin-2, chloroplast precursor
ATYKVKFITPEGEQEVECEEDVYVLDAAEEAGLDLPYSCRAGSCSSCAGKVVSGSIDQSDQSFLDD
>Q93Z60_ARATH/53-118 At1g10960/T19D16_12
ATYKVKFITPEGEQEVECEEDVYVLDAAEEAGLDLPYSCRAGSCSSCAGKVVSGSIDQSDQSFLDD
<mapID target="home" url="html/index.html" />
<mapID target="new" url="html/whatsNew.html"/>
- <mapID target="release" url="html/releases.html#Jalview.2.9"/>
+ <mapID target="release" url="html/releases.html#Jalview.2.10.0b1"/>
<mapID target="alannotation" url="html/features/annotation.html"/>
<mapID target="keys" url="html/keys.html"/>
<mapID target="newkeys" url="html/features/newkeystrokes.html"/>
<mapID target="memory" url="html/memory.html" />
<mapID target="groovy" url="html/features/groovy.html" />
+ <mapID target="groovy.featurecounter" url="html/groovy/featureCounter.html" />
<mapID target="privacy" url="html/privacy.html" />
<mapID target="vamsas" url="html/vamsas/index.html"/>
<mapID target="aminoAcids" url="html/misc/aminoAcids.html" />
<mapID target="biojson" url="html/features/bioJsonFormat.html" />
<mapID target="pdbfetcher" url="html/features/pdbsequencefetcher.html" />
+ <mapID target="siftsmapping" url="html/features/siftsmapping.html" />
<mapID target="pdbchooser" url="html/features/structurechooser.html" />
<mapID target="selectcolbyannot" url="html/features/columnFilterByAnnotation.html" />
<mapID target="biojsmsa" url="html/features/biojsmsa.html" />
+ <mapID target="ensemblfetch" url="html/features/ensemblsequencefetcher.html" />
+
+ <mapID target="uniprotfetcher" url="html/features/uniprotsequencefetcher.html" />
+
<mapID target="backIcon" url="icons/back.png" />
<mapID target="forwardIcon" url="icons/forward.png" />
<mapID target="homeIcon" url="icons/Home.png" />
<!-- DO NOT WRAP THESE LINES - help2Website relies on each item being on one line! -->
<tocitem text="Jalview Documentation" target="home" expand="true">
<tocitem text="What's new" target="new" expand="true">
- <tocitem text="Split Frame View" target="splitframe" />
- <tocitem text="PDB Sequence Fetcher" target="pdbfetcher" />
- <tocitem text="PDB Structure Chooser" target="pdbchooser" />
- <tocitem text="Chimera Viewer" target="chimera" />
- <tocitem text="Select Columns by Annotation" target="selectcolbyannot" />
+ <tocitem text="Retrieval from ENSEMBL" target="ensemblfetch" />
+ <tocitem text="UniProt Free Text Search" target="uniprotfetcher" />
+ <tocitem text="SIFTS for mapping PDB structures to UniProt" target="siftsmapping" />
<tocitem text="Latest Release Notes" target="release"/>
</tocitem>
<tocitem text="By RNA Helices" target="colours.rnahelices" />
</tocitem>
- <tocitem text="Calculations" target="calculations" expand="false">
+ <tocitem text="Calculations" expand="false">
<tocitem text="Sorting alignments" target="sorting" />
<tocitem text="Calculating trees" target="trees" />
<tocitem text="Principal Component Analysis" target="pca" />
<tocitem text="PDB Sequence Fetcher" target="pdbfetcher" />
<tocitem text="PDB Structure Chooser" target="pdbchooser" />
<tocitem text="Jmol Viewer" target="pdbjmol" />
- <tocitem text="Chimera Viewer" target="chimera" />
- <tocitem text="Simple PDB Viewer" target="pdbmcviewer" />
+ <tocitem text="Chimera Viewer" target="chimera" />
</tocitem>
<tocitem text="Viewing RNA structures" target="varna" expand="false"/>
<tocitem text="VAMSAS Data Exchange" target="vamsas">
</tocitem>
<tocitem text="Preferences" target="preferences" />
<tocitem text="Memory Settings" target="memory" expand="false"/>
+ <tocitem text="Scripting with Groovy" target="groovy">
+ <tocitem text="Groovy Feature Counter example" target="groovy.featurecounter"/>
+ </tocitem>
<tocitem text="Command Line" target="commandline" expand="false">
<tocitem text="Command Line Arguments" target="clarguments" />
- <tocitem text="Groovy Shell" target="groovy" />
</tocitem>
<tocitem text="Privacy" target="privacy" />
</tocitem>
entry from the consensus annotation label to copy the alignment's
consensus sequence to the clipboard.
<p>
- <strong>Sequence logo</strong>
+ <a name="logo"><strong>Sequence logo</strong></a>
</p>
By clicking on the label you can also activate the sequence logo. It
indicates the relative amount of residues per column which can be
<strong>Normalise Consensus Logo</strong> to scale all columns of the
logo to the same height.
- <p>
- <strong>Group Consensus</strong><br>
- If sequence groups have been defined, then selecting option 'Group Consensus' in the <a href="../menus/alwannotation.html">Annotations menu</a> will
- result in Consensus being calculated for each group, as well as the alignment as a whole.
+ <p>
+ <strong>Group Consensus</strong><br> If sequence groups have
+ been defined, then selecting option 'Group Consensus' in the <a
+ href="../menus/alwannotation.html">Annotations menu</a> will
+ result in Consensus being calculated for each group, as well as the
+ alignment as a whole.
</p>
<p>
<strong>cDNA Consensus</strong>
<b>9</b> No. 6 (745-756)).
</ul>
<em><a
- href="http://www.compbio.dundee.ac.uk/papers/amas/amas3d.html"
- >View an HTML version of the paper</a></em>
+ href="http://www.compbio.dundee.ac.uk/papers/amas/amas3d.html">View
+ an HTML version of the paper</a></em>
</p>
<p>
Conservation is measured as a numerical index reflecting the
<strong>Colouring an alignment by conservation</strong><br>
Conservation scores can be used to colour an alignment. This is
explained further in the help page for <a
- href="../colourSchemes/conservation.html"
- >conservation colouring</a>.
+ href="../colourSchemes/conservation.html">conservation
+ colouring</a>.
</p>
<p>
- <strong>Group conservation</strong><br>
- If sequence groups have been defined, then selecting option 'Group Conservation' in the <a href="../menus/alwannotation.html">Annotations menu</a> will
- result in Conservation being calculated for each group, as well as the alignment as a whole.
+ <strong>Group conservation</strong><br> If sequence groups have
+ been defined, then selecting option 'Group Conservation' in the <a
+ href="../menus/alwannotation.html">Annotations menu</a> will
+ result in Conservation being calculated for each group, as well as
+ the alignment as a whole.
</p>
</body>
</html>
pair of sequences - computed with one of the available score
matrices, such as <a href="scorematrices.html#blosum62">BLOSUM62</a>,
<a href="scorematrices.html#pam250">PAM250</a>, or the <a
- href="scorematrices.html#simplenucleotide"
- >simple single nucleotide substitution matrix</a>. The options
- available for calculation are given in the <strong><em>Change
+ href="scorematrices.html#simplenucleotide">simple single
+ nucleotide substitution matrix</a>. The options available for
+ calculation are given in the <strong><em>Change
Parameters</em></strong> menu.
</p>
<p>
- <em>PCA Calculation modes</em><br /> The default Jalview calculation
- mode (indicated when <em><strong>Jalview PCA
- Calculation</strong></em> is ticked in the <strong><em>Change
+ <em>PCA Calculation modes</em><br /> The default Jalview
+ calculation mode (indicated when <em><strong>Jalview
+ PCA Calculation</strong></em> is ticked in the <strong><em>Change
Parameters</em></strong> menu) is to perform a PCA on a matrix where elements
in the upper diagonal give the sum of scores for mutating in one
direction, and the lower diagonal is the sum of scores for mutating
gives an asymmetric matrix, and a different PCA to a matrix produced
with the method described in the paper by G. Casari, C. Sander and
A. Valencia. Structural Biology volume 2, no. 2, February 1995 (<a
- href="http://www.ncbi.nlm.nih.gov/entrez/query.fcgi?cmd=Retrieve&db=pubmed&dopt=Abstract&list_uids=7749921"
- >pubmed</a>) and implemented at the SeqSpace server at the EBI. This
- method preconditions the matrix by multiplying it with its
- transpose, and can be employed in the PCA viewer by unchecking the <strong><em>Jalview
+ href="http://www.ncbi.nlm.nih.gov/entrez/query.fcgi?cmd=Retrieve&db=pubmed&dopt=Abstract&list_uids=7749921">pubmed</a>)
+ and implemented at the SeqSpace server at the EBI. This method
+ preconditions the matrix by multiplying it with its transpose, and
+ can be employed in the PCA viewer by unchecking the <strong><em>Jalview
PCA Calculation</em></strong> option in the <strong><em>Change
Parameters</em></strong> menu.
</p>
menu or pressing <strong>'CONTROL+D'</strong> brings up a dialog box
asking you to select a threshold. If the percentage identity between
the aligned positions of any two sequences in the visible alignment
- exceeds this value, the shorter sequence is discarded.<br>
- <em>Note:</em> The redundancy calculation is done when the dialog
- box is opened. For large numbers of sequences this can take a long
- time as all pairs have to be compared.
+ exceeds this value, the shorter sequence is discarded.<br> <em>Note:</em>
+ The redundancy calculation is done when the dialog box is opened.
+ For large numbers of sequences this can take a long time as all
+ pairs have to be compared.
</p>
</body>
</html>
<p>
<strong>Reference Sequence Alignment Views</strong>
</p>
+ <p>Many alignment analysis tasks concern a query, or reference
+ sequence. For instance, when searching for sequences from other
+ organisms that are similar to a newly sequenced gene, or when
+ searching for structurally similar sequences for use in homology
+ modelling.</p>
<p>
- The reference sequence for an alignment is indicated by its ID being
- shown in bold. When a reference sequence has been defined, the <strong>Format→Show
- unconserved</strong> option highlights mutations with respect to the
- reference sequence, rather than the alignment's consensus sequence.
+ <strong>What happens when a reference sequence is defined ?</strong>
</p>
+ <p>The reference sequence for an alignment is indicated by its ID
+ being shown in bold. In addition:</p>
+ <ul>
+ <li><strong>Reference sequence numbering</strong>. Instead of
+ column numbers, the alignment ruler shows the reference sequence
+ positions at each column. At each tick mark, either the reference
+ sequence symbol and position is given, or the column number when a
+ gap is present at that position in the reference sequence.</li>
+ <li><strong>Format→Show unconserved</strong> highlights
+ mutations with respect to the reference sequence, rather than the
+ alignment's consensus sequence.</li>
+ </ul>
<p>
+ <strong>Defining the reference sequence</strong>
+ </p>
+ <p>Each alignment view can have its own reference sequence.</p>
<ul>
- <li>Jalview automatically assigns a reference sequence when <a
- href="../webServices/jnet.html"
- >JPred4</a> predictions are imported.
- </li>
- <li><strong>Assigning a reference sequence</strong><br /> A
- sequence can be marked as the reference sequence by right-clicking
- on it's ID to open the popup menu, and selecting the "<strong>(Sequence
- ID)→Mark as Reference</strong>" entry."</li>
+ <li><strong>Manually assigning a reference sequence</strong><br />
+ A sequence can be marked as the reference sequence by
+ right-clicking on its ID to open the popup menu, and selecting the
+ "<strong>(Sequence ID)→Mark as Reference</strong>" entry.</li>
+ <li><strong>Defining a reference when importing
+ annotation</strong><br />Jalview automatically assigns a reference
+ sequence when importing analysis results, such as those returned
+ from <a href="../webServices/jnet.html">JPred4</a> . A reference
+ sequence can also be assigned via the <a
+ href="../features/annotationsFormat.html#refsandviews">SET_REF</a>
+ command in an alignment annotation file.</li>
</ul>
<p>
<em>Reference sequence based alignment visualisation was
- introduced in Jalview 2.9.</em>
+ introduced in Jalview 2.9, and support for storage and retrieval
+ of reference sequence views in 2.10.</em>
</p>
</html>
matrix, and (since 2.8.1) is available for Tree and PCA
calculations.</li>
<li><a href="#simplenucleotide">Simple Nucleotide
- Substitution</a> is a (fairly) arbitrary DNA/RNA substitution matrix.</li>
+ Substitution</a> is a (fairly) arbitrary DNA/RNA substitution
+ matrix.</li>
<!-- <li><a href="#conservation">Conservation Matrices</a> A range of matrices for distinguishing amino-acids by physicochemical property conservation.
</li> -->
</ul>
<strong><a name="pam250">PAM250</a></strong><br /> <em><strong>P</strong>ercentage
<strong>A</strong>ccepted <strong>M</strong>utation matrix. PAM250
estimates substitutions after 250% of sites have changed (each
- site can be mutated multple times).<br /> Jalview 2.8.1 introduced
- support for PAM250 based <a href="../calculations/pca.html">PCA</a>
- and <a href="../calculations/tree.html">tree</a> calculations.</em>
+ site can be mutated multple times).<br /> Jalview 2.8.1
+ introduced support for PAM250 based <a
+ href="../calculations/pca.html">PCA</a> and <a
+ href="../calculations/tree.html">tree</a> calculations.</em>
<table border="1">
<tr>
<td></td>
</table>
<strong><em>This nucleotide matrix was introduced in
Jalview 2.8. If you'd like to improve it - please take a look at <a
- href="http://issues.jalview.org/browse/JAL-1027"
- >Issue JAL-1027 - introduce a nucleotide substitution matrix that
+ href="http://issues.jalview.org/browse/JAL-1027">Issue
+ JAL-1027 - introduce a nucleotide substitution matrix that
supports RNA/DNA and ambiguity codes</a>
</em></strong>
</p>
</p>
<p>
This menu appears if the alignment contains any <a
- href="../features/annotationsFormat.html"
- >sequence associated alignment annotation</a> with associated
- score values. Each entry is the label for a distinct group of
- sequence associated annotation scores which can be used for
- sorting.
+ href="../features/annotationsFormat.html">sequence
+ associated alignment annotation</a> with associated score values.
+ Each entry is the label for a distinct group of sequence
+ associated annotation scores which can be used for sorting.
</p>
</ul>
<p>
+ <strong>Sorting according to sequence features</strong><br />
+ Additional sort operations for alignments containing sequence
+ features are provided in the <strong><a
+ href="../features/featuresettings.html#sortbyfeature">Feature
+ Settings</a></strong> dialog, opened via <strong>View→Feature
+ Settings...</strong>
+ <p>
<strong>Reversing the Order</strong>
</p>
<p>Selecting any item from the Sort menu will sort sequences in an
ascending order according to the property defining the sort. If the
same sort is re-applied, the sequences will be sorted in the inverse
- order. In the case of trees and alignment orderings, Jalview will
- remember your last choice for sorting the alignment and only apply
- the inverse ordering if you select the same tree or alignment
- ordering item again.</p>
+ order. In both cases, for sequences which are equivalent under the
+ sort operation, their order will be preserved (since version 2.10).
+ In the case of trees and alignment orderings, Jalview will remember
+ your last choice for sorting the alignment and only apply the
+ inverse ordering if you select the same tree or alignment ordering
+ item again.</p>
</body>
</html>
<strong>Alignment RNA Structure Consensus Annotation</strong>
</p>
+ <p>The RNA structure consensus displayed below the alignment gives
+ the percentage of valid base pairs per column for the first
+ secondary structure annotation shown on the annotation panel. These
+ values are shown as a histogram labeled "StrucConsensus",
+ where a symbol below each bar indicates whether the majority of base
+ pairs are:
+ <ul>
+ <li>'(' - Watson-Crick (C:G, A:U/T)</li>
+ <li>'[' - Non-canonical (a.ka. wobble) (G:U/T)</li>
+ <li>'{' - Invalid (a.k.a. tertiary) (the rest)</li>
+ </ul>
+ <p>Mousing over the column gives the fraction of pairs classified
+ as Watson-Crick, Canonical or Invalid.</p>
+
<p>
- The RNA structure consensus displayed below the alignment is the
- percentage of valid base pairs per column. It is calculated in
- relation to a secondary structure and just paired columns are
- calculated. The canonical Watson-Crick base pairings (A-T/U, G-C)
- and the wobble base pair (G-T/U) are regarded as valid pairings.<br>
- The amount of valid base pairs is indicated by the profile in the
- Alignment Annotation row.<br> By default this calculation
- includes gaps in columns. You can choose to ignore gaps in the
- calculation by right clicking on the label "StrConsensus"
- to the left of the structure consensus bar chart.<br>
+ By default this calculation includes gaps in columns. You can choose
+ to ignore gaps in the calculation by right clicking on the label
+ "StrucConsensus" to the left of the structure consensus
+ bar chart.<br>
<p>
- <strong>Structure logo</strong>
- </p>
- By clicking on the label you can also activate the structure logo. It
- is very similar to a sequence logo but counts the numbers of base
- pairs. There are two residues per column, the actual column and the
- interacting base. The opening bracket is always the one on the left
- side.
- <br> Like sequence logos the relative amount of a specific base
- pair can be estimated by its size in the logo. The tool tip of a
- column gives the exact numbers for all occurring valid base pairs.
+ <strong>RNA Structure logo</strong><br /> Right-clicking on the
+ label allows you to enable the structure logo. It is very similar to
+ a sequence logo but instead shows the distribution of base pairs.
+ There are two residues per column, the actual column and the
+ interacting base. The opening bracket is always the one on the left
+ side. <br> Like <a href="consensus.html#logo">sequence
+ logos</a>, the relative amount of a specific base pair can be
+ estimated by its size in the logo, and this can be made more obvious
+ by <em>normalising</em> the logo (enabled via the popup menu). When
+ the logo is displayed, the tool tip for a column gives the exact
+ percentages for all base pairs at that position.
</p>
</body>
</html>
Trees are calculated on either the complete alignment, or just the
currently selected group of sequences, using the functions in the <strong>Calculate→Calculate
tree</strong> submenu. Once calculated, trees are displayed in a new <a
- href="../calculations/treeviewer.html"
- >tree viewing window</a>. There are four different calculations, using
- one of two distance measures and constructing the tree from one of
- two algorithms :
+ href="../calculations/treeviewer.html">tree viewing
+ window</a>. There are four different calculations, using one of two
+ distance measures and constructing the tree from one of two
+ algorithms :
</p>
<p>
<strong>Distance Measures</strong>
scores for the residue pairs at each aligned position.
<ul>
<li>For details about each model, see the <a
- href="scorematrices.html"
- >list of built-in score matrices</a>.
+ href="scorematrices.html">list of built-in score
+ matrices</a>.
</li>
</ul></li>
<li><strong>Sequence Feature Similarity</strong><br>Trees
</ul>
<p>
A newly calculated tree will be displayed in a new <a
- href="../calculations/treeviewer.html"
- >tree viewing window</a>. In addition, a new entry with the same tree
- viewer window name will be added in the Sort menu so that the
- alignment can be reordered to reflect the ordering of the leafs of
- the tree. If the tree was calculated on a selected region of the
- alignment, then the title of the tree view will reflect this.
+ href="../calculations/treeviewer.html">tree viewing
+ window</a>. In addition, a new entry with the same tree viewer window
+ name will be added in the Sort menu so that the alignment can be
+ reordered to reflect the ordering of the leafs of the tree. If the
+ tree was calculated on a selected region of the alignment, then the
+ title of the tree view will reflect this.
</p>
<p>
phylogenetic trees, which can cope with large numbers of sequences,
use better distance methods and can perform bootstrapping. Jalview
can read <a
- href="http://evolution.genetics.washington.edu/phylip/newick_doc.html"
- >Newick</a> format tree files using the 'Load Associated Tree' entry
- of the alignment's File menu. Sequences in the alignment will be
+ href="http://evolution.genetics.washington.edu/phylip/newick_doc.html">Newick</a>
+ format tree files using the 'Load Associated Tree' entry of the
+ alignment's File menu. Sequences in the alignment will be
automatically associated to nodes in the tree, by matching Sequence
IDs to the tree's leaf names.
</p>
</p>
<p>
The tree viewing window is opened when a tree has been <a
- href="tree.html"
- >calculated from an alignment</a>, or imported via a file or web
- service. It includes <a href="#menus">menus</a> for controlling
- layout and file and figure creation, and enables various selection
- and colouring operations on the associated sequences in the
- alignment.
+ href="tree.html">calculated from an alignment</a>, or
+ imported via a file or web service. It includes <a href="#menus">menus</a>
+ for controlling layout and file and figure creation, and enables
+ various selection and colouring operations on the associated
+ sequences in the alignment.
</p>
<p>
<strong><em>Selecting Sequence Leaf Nodes</em></strong><br>
tree is rendered and labeled:
<ul>
<li><strong>Fit to Window</strong>
- <p>The tree layout will be scaled to fit in the display window.
- You may need to reduce the font size to minimise the leaf label
- overlap when this option is selected.</p></li>
+ <p>The tree layout will be scaled to fit in the display
+ window. You may need to reduce the font size to minimise the
+ leaf label overlap when this option is selected.</p></li>
<li><strong>Font Size ...</strong><em>n</em>
- <p>
+ <p>
Brings up a dialog box to set the font size for the leaf names.
<em>n</em> is the current font size.
</p></li>
<li><strong>Show Distances</strong>
- <p>Labels each branch or leaf with its associated branch length.</p></li>
+ <p>Labels each branch or leaf with its associated branch
+ length.</p></li>
<li><strong>Show Bootstrap values</strong>
- <p>Labels each branch or leaf with its associated bootstrap
+ <p>Labels each branch or leaf with its associated bootstrap
value.</p></li>
<li><strong>Mark unlinked leaves</strong>
- <p>Toggles the display of a '*' at the beginning of a leaf label
- to indicate that there is no sequence corresponding to that leaf
- in the associated alignment.</p></li>
+ <p>Toggles the display of a '*' at the beginning of a leaf
+ label to indicate that there is no sequence corresponding to
+ that leaf in the associated alignment.</p></li>
<li><strong>Sort Alignment By Tree</strong>
<p>
Sorts any associated alignment views using the current tree. (<em>Only
<li><strong>Associate Leaves with ...</strong>
<p>
Only visible when there are <a
- href="../features/multipleviews.html"
- >multiple views</a> of the same alignment to show and edit which
- alignment views are associated with the leaves of the displayed
- tree.
+ href="../features/multipleViews.html">multiple
+ views</a> of the same alignment to show and edit which alignment
+ views are associated with the leaves of the displayed tree.
</p>
</ul>
</p>
</div>
<ul>
<li>Select which annotation to base the colouring scheme on
- using the top left selection box.<br />If the <strong>Per-sequence
- only</strong> tick box is not greyed out, then ticking it will limit the
- available annotation rows to just those that are sequence
- associated (e.g. T-COFFEE scores and <a
- href="../webServices/proteinDisorder.html"
- >protein disorder predictions</a>), which will colour each sequence
- according to its own per-residue scores.<br /> <em>Per-sequence
- associated annotation colouring was introduced in Jalview 2.8</em>
+ using the top left selection box. Sequence associated alignment
+ annotation are shown with the seuqence's name appended.<br />If
+ the <strong>Per-sequence only</strong> tick box is not greyed out,
+ then ticking it will limit the list of available annotation rows
+ to just the labels for those that are sequence associated.
+ Annotation rows on each sequence with the same label (e.g.
+ T-COFFEE scores and <a href="../webServices/proteinDisorder.html">protein
+ disorder predictions</a>) will then be used to colour its
+ corresponding positions in the alignment.<br /> <em>Per-sequence
+ associated annotation colouring is currently only available in
+ the Desktop.</em>
</li>
<li>If the "Use Original Colours" box is selected,
the colouring scheme will use the colouring scheme present on the
<li>Press the "Defaults" button to reset the
minimum and maximum colours to their default settings (these
are configured in the applet's parameters or the <a
- href="../features/preferences.html"
- >application's user preferences</a>.).<br /> <em>Default min
- and max colours were introduced in Jalview 2.7</em>
+ href="../features/preferences.html">application's
+ user preferences</a>.).<br /> <em>Default min and max
+ colours were introduced in Jalview 2.7</em>
</ul>
</li>
alignment analysis (Livingstone C.D. and Barton G.J. (1993), Protein
Sequence Alignments: A Strategy for the Hierarchical Analysis of
Residue Conservation.CABIOS Vol. 9 No. 6 (745-756)). See the <a
- href="../calculations/conservation.html"
- >conservation calculation</a> help page for a more thorough
- explanation of the calculation.
+ href="../calculations/conservation.html">conservation
+ calculation</a> help page for a more thorough explanation of the
+ calculation.
</p>
<p>For an already coloured alignment, the conservation index at
each alignment position is used to modify the shading intensity of
<p>
Conservation can be calculated over all sequences in an alignment,
or just within specific groups (such as those defined by <a
- href="../calculations/tree.html"
- >phylogenetic tree partitioning</a>). The option 'apply to all groups'
- controls whether the contrast slider value will be applied to the
- indices for the currently selected group, or all groups defined over
- the alignment.
+ href="../calculations/tree.html">phylogenetic tree
+ partitioning</a>). The option 'apply to all groups' controls whether
+ the contrast slider value will be applied to the indices for the
+ currently selected group, or all groups defined over the alignment.
</p>
</body>
</html>
the background colour.</p>
<p>
The <strong>"Colour→<a
- href="../colourSchemes/textcolour.html"
- >Colour Text...</a>"
+ href="../colourSchemes/textcolour.html">Colour Text...</a>"
</strong> entry opens a dialog box to set a different text colour for light
and dark background, and the intensity threshold for transition
between them.
on its helices. The helices are determined from the secondary
structure line in the Stockholm file (#GC SS_cons) written in WUSS
notation that specifies base pairing. See <a
- href="http://en.wikipedia.org/wiki/Stockholm_format"
- > Wikipedia</a> or <a
- href="http://jalview-rnasupport.blogspot.com/2010/06/parsing-wuss-notation-of-rna-secondary.html"
- > Jalview RNA Support Blog</a> for more information about Stockholm
+ href="http://en.wikipedia.org/wiki/Stockholm_format">
+ Wikipedia</a> or <a
+ href="http://jalview-rnasupport.blogspot.com/2010/06/parsing-wuss-notation-of-rna-secondary.html">
+ Jalview RNA Support Blog</a> for more information about Stockholm
files and WUSS notation.
</p>
Select "Colour"
clicking the left mouse button and pressing a combination of either
shift and control (or the alt, option or apple key on Macs) and
dragging the mouse. Pressing <em>F2</em> toggles the alternative <a
- href="../features/cursorMode.html"
- >'Cursor mode'</a> keyboard editing facility, where the space bar and
- delete keys add and remove gaps at the current editing position. The
- key strokes for both these modes are summarised in the <a
- href="../keys.html"
- >keystrokes table</a>.
+ href="../features/cursorMode.html">'Cursor mode'</a> keyboard
+ editing facility, where the space bar and delete keys add and remove
+ gaps at the current editing position. The key strokes for both these
+ modes are summarised in the <a href="../keys.html">keystrokes
+ table</a>.
</p>
<p>
<strong>Tip:</strong> For large alignments, deselect "Calculate
right to insert gaps and remove gaps.<br> If the current
selection is a group over all sequences in the alignment, or a group
over some sequences or all columns in the alignment, then hold down
- either "Control" key (or the "Alt;" on OSX if
- "Control" does not work) and drag the residue left or
- right to edit all sequences in the defined group at once.
+ "Control" key ("Cmd" key on OSX) and drag the residue
+ left or right to edit all sequences in the defined group at once.
</p>
<p>
<em>Copy/paste/cut/delete</em> - any sequences which are in the
* along with Jalview. If not, see <http://www.gnu.org/licenses/>.
* The Jalview Authors are detailed in the 'AUTHORS' file.
-->
-<head><title>Alignment Annotation</title></head>
+<head>
+<title>Alignment Annotation</title>
+</head>
<body>
-<p><strong>Alignment Annotation</strong></p>
+ <p>
+ <strong>Alignment Annotation</strong>
+ </p>
-<p>In addition to the definition of groups and sequence features,
- Jalview can display symbols and graphs under the columns of an
- alignment, and allow you to mark particular columns of an alignment and add symbols and text
- in the annotation area shown below the alignment (which may be hidden if <strong>View→Show
- Annotation</strong> is not ticked). Any displayed annotation row can be hidden (using the pop-up
- menu obtained by right-clicking the label), or re-ordered by dragging the label to a new
- position with the left mouse button.</p>
-<p>
-Web services can also add annotation to an alignment (see the <a
-href="../webServices/jnet.html">JNet</a> and <a
-href="../webServices/proteinDisorder.html">Disorder</a> protein
-structure prediction services), and as of Jalview 2.08 quantitative
-and symbolic annotations can be added to an alignment via an <a
-href="annotationsFormat.html">Annotations File</a> dragged into the
-alignment window or loaded from the alignment's file menu.
-</p>
-<p><a name="seqannots"/><strong>Sequence Reference Annotation</strong>
-</p>
-<p>
- Sequence reference annotation is created from 3D structure
- data, and from the results of sequence based prediction of
- <a href="../webServices/jnet.html">secondary structure</a> and <a
- href="../webServices/proteinDisorder.html">disordered region</a>
- prediction methods.
-</p>
-<p><strong>Sequence Group Annotation</strong>
-</p>
-<p>
- If sequence groups are defined, <a href="../calculations/conservation.html">Conservation</a>
- and <a href="../calculations/consensus.html">Consensus</a> annotation can be enabled
- for each group from the <a href="../menus/alwannotation.html">Annotations menu</a>, or can
- be imported from a Jalview <a href="annotationsFormat.html">Annotations file</a>.
-</p>
-<p><strong>Sequence Selection from Annotation</strong>
-</p>
-<p>
- Sequences associated with sequence (or sequence group) annotations can be selected by
- double-clicking the annotation label with these key combinations:
- <ul>
- <li>double-click - Select associated sequences (replaces current selection)</li>
- <li>shift double-click - add sequences to selection</li>
- <li>Ctrl (Mac CMD) double-click - toggles inclusion of associated sequences in the current selection</li>
- </ul>
- Note this also works in combination with manual sequence selection in the alignment.
-<p><strong>Interactive Alignment Annotation</strong></p>
-<p>
-Annotation rows are added using the <strong>Annotation Label</strong>
-menu, which is obtained by clicking anywhere on the annotation row labels
-area (below the sequence ID area).
-</p>
-<ul>
- <li><strong>Add New Row</strong><br>
- <em>Adds a new, named annotation row (a dialog box will pop up for you to
- enter the label for the new row). </em> </li>
- <li><strong>Edit Label/Description</strong><br>
- <em>This opens a dialog where you can change the name (displayed label), or the description
- (as shown on the label tooltip) of the clicked annotation. </em> </li>
- <li><strong>Hide This Row</strong><br>
- <em>Hides the annotation row whose label was clicked in order to bring up
- the menu.</em> </li>
- <li><strong>Hide All <em><label></em></strong><br>
- <em>Hides all annotation rows whose label matches the one clicked.
- (This option is only shown for annotations that relate to individual sequences,
- not for whole alignment annotations. Since Jalview 2.8.2.)</em> </li>
- <li><strong>Delete This Row</strong><br>
- <em>Deletes the annotation row whose label was clicked in order to bring up
- the menu.</em> </li>
- <li><strong>Show All Hidden Rows</strong><br>
- <em>Shows all hidden annotation rows.</em> </li>
- <li><strong>Export Annotation</strong> <em>(Application only)</em><br>
- <em>Annotations can be saved to file or output to a text window in either the
- Jalview annotations format or as a spreadsheet style set of comma separated values (CSV). </em> </li>
- <li><strong>Show Values in Text Box</strong> <em>(applet only)</em><br>
- <em>Opens a text box with a list of comma-separated values corresponding
- to the annotation (numerical or otherwise) at each position in the row.
- This is useful to export alignment quality measurements for further analysis.</em>
- </li>
- <li><strong>Scale Label To Column</strong><em>(introduced in 2.5)</em><br>
- <em>Selecting this toggles whether column labels will be shrunk to fit within each column, or displayed using the view's standard font size.</em></li>
-</ul>
-<p>
-<strong>Editing Label and secondary structure Annotation</strong></p>
-<p>
-Use the <strong>left mouse button</strong> to select a position along the row that are to
-be annotated - these regions will be coloured red. <strong>Control</strong> and <strong>shift</strong> in combination
-with the left-click will select more than one position, or a range of
-positions on the alignment.
-</p>
-<p>Once the desired position has been selected, use the <strong>right mouse
-button</strong> to open the <strong>annotation menu</strong>:</p>
-<ul>
-<li>Helix<br><em>Mark selected positions with a helix glyph (a red
-oval), and optional text label (see below). A
-dialog box will open for you to enter the text. Consecutive ovals
-will be rendered as an unbroken red line.</em>
-</li>
-<li>Sheet<br><em>Mark selected positions with a sheet glyph (a green
-arrow oriented from left to right), and optional text label (see
-below). A dialog box will open for you to enter the text. Consecutive
-arrows will be joined together to form a single green arrow.</em>
-</li>
-<li><a name="rna">RNA Helix</a> (only shown when working with nucleotide sequences)<br>
-<em>Mark selected positions as participating in a base pair
-either upstream or downstream. When the dialog box opens, enter a
-'(' to indicate these bases pair with columns upstream (to right),
-and ')' to indicate this region pairs with bases to the left of the
-highlighted columns.<br />If any brackets do not match up, then an
-orange square will highlight the first position where a bracket was
-found not to match.
-</em>
-</li>
-<li>Label<br><em>Set the text label at the selected positions. A
-dialog box will open for you to enter the text. If
-more than one consecutive position is marked with the same label, only
-the first position's label will be rendered.</em>
-</li>
-<li>Colour<br><em>Changes the colour of the annotation text label.</em>
-</li>
-<li>Remove Annotation<br><em>Blanks any annotation at the selected positions on
-the row. Note: <strong>This cannot be undone</strong></em>
-</li>
-</ul>
-<p>
-User defined annotation is stored and retrieved using <a
-href="../features/jalarchive.html">Jalview Archives</a>.
-</p>
-<p><em>Current Limitations</em></p>
-<p>As of version 2.5, the Jalview user interface does not support the
-creation and editing of quantitative annotation (histograms and line graphs), or
-to create annotation associated with a specific sequence. It is also incapable of
-annotation grouping or changing the style of existing annotation (to change between line or bar charts, or to make multiple line graphs). These annotation capabilities are only possible by the import of an
-<a href="annotationsFormat.html">Annotation file</a>.<br>
-</p>
+ <p>
+ In addition to the definition of groups and sequence features,
+ Jalview can display symbols and graphs under the columns of an
+ alignment. These annotation tracks are displayed in the annotation
+ area below the alignment. The annotation area's visibility is
+ controlled with the <strong>View→Show Annotation</strong>
+ option.
+ </p>
+ <p>
+ <strong>Types of annotation</strong>
+ <ul>
+ <li><a name="seqannots"><strong>Sequence
+ associated annotation.</strong></a><br />Data displayed on sequence
+ annotation rows are associated with the positions of a sequence.
+ Often this is 'Reference annotation' such as secondary structure
+ information derived from 3D structure data, or from the results of
+ sequence based prediction of <a href="../webServices/jnet.html">secondary
+ structure</a> and <a href="../webServices/proteinDisorder.html">disorder</a>.
+ If reference annotation is available for a the currently selected
+ sequences, it can be shown by selecting the <strong>Add
+ Reference Annotation</strong> option in the sequence or selection popup
+ menu.</li>
+ <li><strong>Group associated annotation.</strong><br />Data can
+ be associated with groups defined on the alignment. If sequence
+ groups are defined, <a href="../calculations/conservation.html">Conservation</a>
+ and <a href="../calculations/consensus.html">Consensus</a>
+ annotation can be enabled for each group from the <a
+ href="../menus/alwannotation.html">Annotations menu</a>, or can be
+ imported from a Jalview <a href="annotationsFormat.html">Annotations
+ file</a>.</li>
+ <li><strong>Alignment associated annotation.</strong><br />Annotation
+ rows associated with columns on the alignment are simply
+ 'alignment annotation'. Controls allow you to <a href="#iaannot">interactively
+ create alignment annotation</a> to add labels and symbols to
+ alignment columns. Jalview's consensus, conservation and quality
+ calculations also create histogram and sequence logo annotations
+ on the alignment.</li>
+ </ul>
+ <p>
+ <strong>Importing and exporting annotation</strong><br />
+ Annotations on an alignment view are saved in Jalview project files.
+ You can also load <a href="annotationsFormat.html">Annotations
+ Files</a> in order to add any kind of quantitative and symbolic
+ annotations to an alignment. To see an example, use the <strong>Export
+ Features/Annotation</strong> option from an alignment window's File menu.
+ </p>
+ <p>
+ <strong>Layout and display controls</strong><br /> Individual and
+ groups of annotation rows can be shown or hidden using the pop-up
+ menu obtained by right-clicking the label. You can also reorder them
+ by dragging the label to a new position with the left mouse button.
+ The <strong>Annotations</strong> menu provides settings controlling
+ the ordering and display of sequence, group and alignment associated
+ annotation. The <strong>Colour by annotation</strong> option in the
+ colour menu allows annotation to be used to <a
+ href="../colourSchemes/annotationColouring.html">shade the
+ alignment</a>. Annotations can also be used to <a
+ href="../features/columnFilterByAnnotation.html">select or
+ hide columns</a> via the dialog opened from the <strong>Selection</strong>
+ menu.
+ </p>
+ <p>
+ <strong>Sequence Highlighting and Selection from Annotation</strong>
+ </p>
+ <p>
+ A <strong>single click</strong> on the label of an annotation row
+ associated with sequences and sequence groups will cause the
+ associated sequences to be highlighted in the alignment view. <strong>Double
+ clicking</strong> the label will select the associated sequences, replacing
+ any existing selection. Like with other kinds of selection, <strong>shift
+ double-click</strong> will add associated sequences, and <strong>Ctrl
+ (Mac CMD) double-click</strong> will toggle inclusion of associated
+ sequences in the selection.
+ <p>
+ <strong>Interactive Alignment Annotation</strong>
+ </p>
+ <p>
+ <a name="iaannot"> Annotation rows</a> are added using the <strong>Annotation
+ Label</strong> menu, which is obtained by clicking anywhere on the
+ annotation row labels area (below the sequence ID area).
+ </p>
+ <ul>
+ <li><strong>Add New Row</strong><br> <em>Adds a new,
+ named annotation row (a dialog box will pop up for you to enter
+ the label for the new row). </em></li>
+ <li><strong>Edit Label/Description</strong><br> <em>This
+ opens a dialog where you can change the name (displayed label),
+ or the description (as shown on the label tooltip) of the
+ clicked annotation. </em></li>
+ <li><strong>Hide This Row</strong><br> <em>Hides the
+ annotation row whose label was clicked in order to bring up the
+ menu.</em></li>
+ <li><strong>Hide All <em><label></em></strong><br> <em>Hides
+ all annotation rows whose label matches the one clicked. (This
+ option is only shown for annotations that relate to individual
+ sequences, not for whole alignment annotations. Since Jalview
+ 2.8.2.)</em></li>
+ <li><strong>Delete This Row</strong><br> <em>Deletes
+ the annotation row whose label was clicked in order to bring up
+ the menu.</em></li>
+ <li><strong>Show All Hidden Rows</strong><br> <em>Shows
+ all hidden annotation rows.</em></li>
+ <li><strong>Export Annotation</strong> <em>(Application
+ only)</em><br> <em>Annotations can be saved to file or
+ output to a text window in either the Jalview annotations format
+ or as a spreadsheet style set of comma separated values (CSV). </em>
+ </li>
+ <li><strong>Show Values in Text Box</strong> <em>(applet
+ only)</em><br> <em>Opens a text box with a list of
+ comma-separated values corresponding to the annotation
+ (numerical or otherwise) at each position in the row. This is
+ useful to export alignment quality measurements for further
+ analysis.</em></li>
+ <li><strong>Scale Label To Column</strong><em>(introduced
+ in 2.5)</em><br> <em>Selecting this toggles whether column
+ labels will be shrunk to fit within each column, or displayed
+ using the view's standard font size.</em></li>
+ </ul>
+ <p>
+ <strong>Editing labels and secondary structure annotation
+ rows</strong>
+ </p>
+ <p>
+ Use the <strong>left mouse button</strong> to select a position
+ along the row that are to be annotated - these regions will be
+ coloured red. Press <strong>Control</strong> or <strong>shift</strong>
+ in combination with the left-click to either select an additional
+ position, or a range of positions on the alignment.
+ </p>
+ <p>
+ Once positions have been selected, use the <strong>right
+ mouse button</strong> and select one of the following from the <strong>annotation
+ menu</strong>:
+ </p>
+ <ul>
+ <li>Helix<br> <em>Marks selected positions with a
+ helix glyph (a red oval), and optional text label (see below). A
+ dialog box will open for you to enter the text. Consecutive
+ ovals will be rendered as an unbroken red line.</em>
+ </li>
+ <li>Sheet<br> <em>Marks selected positions with a
+ sheet glyph (a green arrow oriented from left to right), and
+ optional text label (see below). A dialog box will open for you
+ to enter the text. Consecutive arrows will be joined together to
+ form a single green arrow.</em>
+ </li>
+ <li><a name="rna">RNA Helix</a> (only shown when working with
+ nucleotide sequences)<br> <em>Marks selected positions
+ as participating in a base pair either upstream or downstream.
+ When the dialog box opens, enter a '(' to indicate these bases
+ pair with columns upstream (to right), and ')' to indicate this
+ region pairs with bases to the left of the highlighted columns.
+ Other kinds of base-pair annotation are also supported (e.g. 'A'
+ and 'a', or '<' and '>'), and Jalview will suggest an
+ appropriate symbol based on the closest unmatched parenthesis to
+ the left.<br />If any brackets do not match up, then an orange
+ square will highlight the first position where a bracket was
+ found not to match.
+ </em></li>
+ <li>Label<br> <em>Set the text label at the selected
+ positions. A dialog box will open for you to enter the text. If
+ more than one consecutive position is marked with the same
+ label, only the first position's label will be rendered.</em>
+ </li>
+ <li>Colour<br> <em>Changes the colour of the
+ annotation text label.</em>
+ </li>
+ <li>Remove Annotation<br> <em>Blanks any annotation
+ at the selected positions on the row. Note: <strong>This
+ cannot be undone</strong>
+ </em>
+ </li>
+ </ul>
+ <p>
+ User defined annotation is stored and retrieved using <a
+ href="../features/jalarchive.html">Jalview Archives</a>.
+ </p>
+ <p>
+ <em>Current Limitations</em>
+ </p>
+ <p>
+ The Jalview user interface does not support interactive creation and
+ editing of quantitative annotation (histograms and line graphs), or
+ to create annotation associated with a specific sequence or group.
+ It is also incapable of annotation grouping or changing the style of
+ existing annotation (e.g. to change between line or bar charts, or
+ to make multiple line graphs). These annotation capabilities are
+ only possible by the import of an <a href="annotationsFormat.html">Annotation
+ file</a>.<br>
+ </p>
</body>
</html>
Alignment annotations can be imported onto an alignment since
version 2.08 of Jalview, via an annotations file. It is a simple
ASCII text file consisting of tab delimited records similar to the <a
- href="featuresFormat.html"
- >Sequence Features File</a>, and introduced primarily for use with the
- Jalview applet.
+ href="featuresFormat.html">Sequence Features File</a>, and
+ introduced primarily for use with the Jalview applet.
</p>
<p>
alignment window.
</p>
<p>
- <strong>THE ANNOTATION FILE FORMAT</strong> <br />An annotation file
- consists of lines containing an instruction followed by tab
+ <strong>THE ANNOTATION FILE FORMAT</strong> <br />An annotation
+ file consists of lines containing an instruction followed by tab
delimited fields. Any lines starting with "#" are
considered comments, and ignored. The sections below describe the
structure of an annotation file.
</ul>
<p>
At the end of this document, you can also find notes on <a
- href="#compatibility"
- >compatibility</a> of annotation files across different versions of
- Jalview. An <a href="#exampleann">example annotation file</a> is
- also provided along with instructions on how to import it to
- Jalview.
+ href="#compatibility">compatibility</a> of annotation files
+ across different versions of Jalview. An <a href="#exampleann">example
+ annotation file</a> is also provided along with instructions on how to
+ import it to Jalview.
</p>
<hr />
<p>
followed by a <em>description</em> for the row, which is shown in a
tooltip when the user mouses over the annotation row's label. Since
Jalview 2.7, the description field may also contain HTML tags (in
- the same way as a <a href="featuresFormat.html">sequence feature's</a>
- label), providing the text is enclosed in an <html/> tag.
+ the same way as a <a href="featuresFormat.html">sequence
+ feature's</a> label), providing the text is enclosed in an
+ <html/> tag.
<ul>
<em>Please note: URL links embedded in HTML descriptions are
not yet supported.</em>
<em>GRAPH_TYPE</em>. The allowed values of <em>GRAPH_TYPE</em> and
corresponding interpretation of each <em>Value</em> are shown below:
+
<ul>
<li><strong>BAR_GRAPH</strong><br> Plots a histogram with
</ul>
</p>
<p>
- <strong><a name="groupdefs">SEQUENCE_GROUP</a></strong><br /> Groups
- of sequences and column ranges can be defined using a tab delimited
- statement like:
+ <strong><a name="groupdefs">SEQUENCE_GROUP</a></strong><br />
+ Groups of sequences and column ranges can be defined using a tab
+ delimited statement like:
</p>
<pre>SEQUENCE_GROUP	Group_Name	Group_Start	Group_End	<em>Sequences</em>
</pre>
<tr>
<td width="50%">hide</td>
<td>Boolean (default false) indicating whether the rows in
- this group should be marked as hidden.<br />
- <em>Note:</em> if the group is sequence associated (specified by
+ this group should be marked as hidden.<br /> <em>Note:</em>
+ if the group is sequence associated (specified by
SEQUENCE_REF), then all members will be hidden and marked as
represented by the reference sequence.
</td>
</p>
<p>
The BioJSON specification is published at <a
- href="http://jalview.github.io/biojson/"
- >http://jalview.github.io/biojson/</a>.
+ href="http://jalview.github.io/biojson/">http://jalview.github.io/biojson/</a>.
</p>
<p>
<em>Import of BioJSON data from HTML pages</em>
</p>
<p>
Since Jalview 2.8.2, <a href="http://www.cgl.ucsf.edu/chimera/">Chimera</a>
- (http://www.cgl.ucsf.edu/chimera/) has been integrated into Jalview
- for interactively viewing structures opened by entries in the <strong>"Structure"</strong>
- submenu in the <a href="../menus/popupMenu.html">sequence id
- pop-up menu</a> (if you can't see this, then you need to <a
- href="viewingpdbs.html"
- >associate a PDB structure</a> with the sequence). Chimera is
- available from the Jalview desktop, provided Chimera has been
- separately installed.
+ (http://www.cgl.ucsf.edu/chimera/) can be used for viewing
+ structures opened via the <a href="structurechooser.html"><strong>"View
+ Structure Data.."</strong> dialog</a>.
</p>
<p>
You can set a default choice of Jmol or Chimera structure viewer in
<a href="preferences.html#structure"> Preferences</a>. You can also
optionally specify the path to the Chimera program here (if it
- differs from the standard paths searched by Jalview).
+ differs from the standard paths searched by Jalview).<br /> <strong>Please
+ make sure your version of Chimera is up to date. Jalview requires
+ at least Chimera version 1.11.1</strong>
+ </p>
<p>
If you save your Jalview session as a project file, the state of any
open Chimera windows will also be saved, and can be reopened by
loading the project file on any machine with Chimera installed. <em>Since
Jalview 2.9.</em>
- <!-- <p>The following menu entries are provided for viewing structure data<br>
- <ul>
- <li>The <strong>"Structure→View
- Structure→</strong> submenu allows a single PDB structure to be chosen
- for display from the available structures for a sequence.
- </li>
- <li>The <strong>"Structure→View all <em>N</em>
- structures
- </strong> option will open a new window containing all structures associated
- with the current selection.
- </li>
- <li>The <strong>"Structure→View all <em>N</em>
- representative structures
- </strong> option will open a new window containing exactly one structure per
- currently selected sequence.<br /></li>
- </ul>
- <br>
-</p> -->
<p>
<a name="align"><strong>Superposing structures based on
their aligned sequences</strong></a><br> If several structures are
Help menu.
<p>
Basic screen operations (see <a
- href="http://www.cgl.ucsf.edu/chimera/current/docs/UsersGuide/mouse.html"
- >Chimera help</a> at
+ href="http://www.cgl.ucsf.edu/chimera/current/docs/UsersGuide/mouse.html">Chimera
+ help</a> at
http://www.cgl.ucsf.edu/chimera/current/docs/UsersGuide/mouse.html
for full details).
<table border="1">
</strong><em> Colours each residue in the structure with the colour
of its corresponding residue in the associated sequence as
rendered in the associated alignment views, including any
- Uniprot sequence features or region colourings.<br />Pick
+ UniProt sequence features or region colourings.<br />Pick
which of the associated alignment views are used to colour
the structures using the <strong>View→Colour
by ..</strong> sub menu.
colourschemes.<br>
</strong><em>The remaining entries apply the colourschemes available
from the standard and user defined <a
- href="../colourSchemes/index.html"
- >amino acid colours</a>.
+ href="../colourSchemes/index.html">amino acid
+ colours</a>.
</em></li>
</ul></li>
<li><strong>Chimera<br>
</p>
Jalview and Chimera communicate using Chimera's
<a
- href="http://www.cgl.ucsf.edu/chimera/current/docs/ContributedSoftware/restserver/restserver.html"
- >REST service</a>
+ href="http://www.cgl.ucsf.edu/chimera/current/docs/ContributedSoftware/restserver/restserver.html">REST
+ service</a>
(http://www.cgl.ucsf.edu/chimera/current/docs/ContributedSoftware/restserver/restserver.html).
<br> Technically this requires both Chimera and Jalview to open
ports on the local network, and this may be blocked by Windows
<div align="center">-annotations FILE/URL</div>
</td>
<td>Add precalculated annotations to the alignment. See <a
- href="annotationsFormat.html" target="NEW"
- >Annotation File</a> description.
+ href="annotationsFormat.html" target="NEW">Annotation
+ File</a> description.
</td>
</tr>
<tr>
</tr>
<tr>
<td>
+ <div align="center">-nonews</div>
+ <td>
+ <div align="left">
+ Disable check for <a href="../webServices/newsreader.html">Jalview
+ news</a> on startup (not recommended other than for classroom /
+ demo usage)
+ </div>
+ </td>
+ </tr>
+ <tr>
+ <td>
<div align="center">-nousagestats</div>
<td>
<div align="left">Turn off google analytics usage tracking</div>
The 'Select/Hide by Annotation' window allows columns to be selected
or hidden according to annotation rows on the alignment. The dialog
box is opened <em>via</em> "<strong>Select→Select/Hide
- Columns by Annotation...</strong>", and different filters are
- presented dependent upon the data shown in the selected annotation
+ Columns by Annotation...</strong>", and different filters are then
+ presented for filtering data according to the selected annotation
row.
</p>
<table>
<td><img src="AnnotationColumnSelectionWithoutSM.gif"></td>
</tr>
</table>
-
- <p>If an annotation with numeric values is selected, the threshold
+ <p>The drop down menu lists the annotation available on the
+ alignment. Sequence associated annotation rows will be shown with
+ the sequence ID appended to the annotation label. It is only
+ possible to select one row at a time.</p>
+ <p>
+ If an annotation with numeric values is selected, the threshold
filter option is activated. For other types of annotation, use the
text box and secondary structure check boxes (right). The radio
buttons at the bottom of the dialog specify the action applied to
- columns matching the query.</p>
+ columns matching the query.<br /> <em>Note: annotation
+ containing only numeric labels (e.g. T-COFFEE column confidence
+ scores) will not be treated as quantitative data. You will need to
+ enter search expressions to select columns in this case.</em>
+ </p>
<ul>
<li><strong>Search Filter</strong>
<ul>
<pre>java -Djava.ext.dirs=$INSTALL_DIR$/lib -cp $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 Jalview accepts.
+ href="clarguments.html">command line arguments</a> that
+ Jalview accepts.
</p>
<p> </p>
<p> </p>
<strong>Creating Sequence Features</strong>
<p>
Jalview can create sequence features from the matches of a <a
- href="search.html"
- >regular expression search</a>, or from the currently selected area
- via the <strong>"selection→Create sequence
- feature"</strong> entry in the <a href="../menus/popupMenu.html">selection
- area popup menu</a>. In both cases, the <strong>Create
- Features</strong> dialog box will then be opened:
+ href="search.html">regular expression search</a>, or from the
+ currently selected area via the <strong>"selection→Create
+ sequence feature"</strong> entry in the <a
+ href="../menus/popupMenu.html">selection area popup menu</a>. In
+ both cases, the <strong>Create Features</strong> dialog box will
+ then be opened:
</p>
<p>
<img src="crnewfeature.gif">
<p>
<strong>DAS Sequence Feature Retrieval</strong>
</p>
- <p>
- Jalview includes a client for retrieving sequences and their
- features via the <a href="http://www.biodas.org">Distributed
- Annotation System</a>.
- </p>
+ <p>Jalview includes a client for retrieving sequences and their
+ features via the Distributed Annotation System.</p>
<ol>
<li>Open the Feature Settings panel by selecting "View
-> Feature Settings..."</li>
</li>
</ol>
<p>
- If your DAS source selection contains sources which use Uniprot
- accession ids, you will be asked whether Jalview should find Uniprot
+ If your DAS source selection contains sources which use UniProt
+ accession ids, you will be asked whether Jalview should find UniProt
Accession ids for the given sequence names. It is important to
- realise that many DAS sources only use Uniprot accession ids, rather
- than Swissprot/Uniprot sequence names.<br> The <a
- href="../webServices/dbreffetcher.html"
- >database reference fetcher</a> documentation describes how Jalview
- discovers what database references are appropriate for the sequences
- in the alignment.
+ realise that many DAS sources only use UniProt accession ids, rather
+ than Swissprot/UniProt sequence names.<br> The <a
+ href="../webServices/dbreffetcher.html">database
+ reference fetcher</a> documentation describes how Jalview discovers
+ what database references are appropriate for the sequences in the
+ alignment.
<ul>
<li><em>Note</em><br> Please remember to save your
alignment if either the start/end numbering, or the sequence IDs
<p>
<em>DAS support was introduced in Jalview Version 2.1.</em>
</p>
+ <br />
+ <p>
+ <em>The DAS registry at http://www.dasregistry.org was
+ decommissioned early in 2015. An unmaintained mirror is currently
+ hosted at http://www.ebi.ac.uk/das-srv/registry/.</em>
+ </p>
<p>
</body>
</html>
</p>
<p>
Jalview can retrieve sequences and features from many <a
- href="http://biodas.org/"
- >DAS</a> sources. The DAS sources that it uses are discovered and
- selected <em>via</em> the DAS settings panel, opened either from the
- <a href="featuresettings.html">View→Feature Settings</a>
- dialog box from the alignment window's menu bar, or the <a
- href="featuresettings.html"
- >Tools→Preferences</a> dialog box opened from the Desktop menu
- bar.
+ href="http://biodas.org/">DAS</a> sources. The DAS sources
+ that it uses are discovered and selected <em>via</em> the DAS
+ settings panel, opened either from the <a
+ href="featuresettings.html">View→Feature Settings</a> dialog
+ box from the alignment window's menu bar, or the <a
+ href="featuresettings.html">Tools→Preferences</a>
+ dialog box opened from the Desktop menu bar.
</p>
<p>
<img src="das.gif">
<!-- and <strong>Feature Group</strong> -->
pull down menu. In addition to the Name, group, colour and
description attributes described for the <a
- href="creatinFeatures.html"
- >new feature dialog box</a>, a feature's start and end position can be
- changed either by entering a new position directly or by using the
- adjacent up and down buttons.
+ href="creatinFeatures.html">new feature dialog box</a>, a
+ feature's start and end position can be changed either by entering a
+ new position directly or by using the adjacent up and down buttons.
</p>
<p>
Select <strong>Amend</strong> to update the feature, <strong>Delete</strong>
--- /dev/null
+<html>
+<!--
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ -->
+<head>
+<title>Fetching ENSEMBL Data in Jalview</title>
+</head>
+<body>
+
+ <strong>Fetching ENSEMBL Data in Jalview</strong>
+ <br /> Jalview Version 2.10 (October 2016) introduced support to
+ retrieve annotated transcripts, peptides and genomic contigs from
+ <a href="http://www.ensembl.org">ENSEMBL</a>.
+ <br />
+ <img src="selectfetchdb.gif" align="right" width="480" height="204"
+ alt="Database selection dialog with Ensembl sequence source tooltip">
+
+ <p>Two types of ENSEMBL source are provided. ENSEMBL queries the
+ main ENSEMBL warehouse containing data for higher eukaryotes, and
+ EnsemblGenomes, which queries Ensembl Pathogens, and other
+ warehouses.</p>
+ <p>
+ <strong>General Use</strong><br /> If you have a set of Ensembl
+ gene or transcript IDs, then you can retrieve them <em>via</em> the
+ sequence fetcher dialog opened after selecting the most appropriate
+ source (either 'ENSEMBL', or Ensembl Genomes). However, Jalview's
+ Ensembl client has a couple of additional capabilities:
+ </p>
+ <p>
+ <strong>Retrieving aligned transcripts for a genomic ID</strong>
+ </p>
+ <p>If a single genomic identifier is entered in the Ensembl
+ fetcher, Jalview will return all transcripts and products for the
+ locus, and display them in a split view - complete with sequence
+ variant annotation.</p>
+ <p>
+ <strong>Retrieving orthologs for a gene ID</strong>
+ </p>
+ <p>
+ If a gene ID is entered (e.g. fox1), Jalview will resolve Ensembl
+ genomic identifiers for a predefined set of taxa (Mouse, Rat, Human,
+ Yeast in Jalview 2.10).<br />
+ </p>
+ <p>
+ <strong><a name="ensemblannotation">Ensembl Sequence
+ Features</a></strong><br /> Jalview 2.10 includes support for the
+ visualisation and transfer genomic and transcriptomic sequence
+ features onto protein product sequences. Retrieval of a genomic
+ locus results in a set of transcripts that are annotated with
+ nucleotide variant information and exonic regions. By default,
+ intronic regions will be hidden.
+ </p>
+ <p>
+ <strong><a name="variantvis">Variant information on
+ Protein Products</a></strong><br />Jalview can translate genomic variant
+ annotation into protein sequence variant codes for variants
+ intersecting coding regions of a gene. To see this in action, use
+ the <strong>Calculate→Show cross-references</strong> menu to
+ view protein product sequences for the currently displayed (or
+ selected) sequences. The same menu allows you to recover Ensembl
+ exon, transcript and variant information when viewing UniProt
+ sequences.
+ </p>
+ <p>
+ <strong>Viewing more information about variant annotation</strong><br />
+ Variants are highlighted as red sequence features on the protein
+ sequence, with each one reporting all protein sequence variants
+ observed at that position as a result of the genomic variants.
+ Right-clicking a variant allows you to open the Ensembl Variants web
+ page for each variant, via the <strong>Link</strong> submenu.
+ </p>
+ <p>
+ <strong>Work in Progress !</strong><br />In the next few releases,
+ we hope to improve and extend Jalview's support for working with
+ Ensembl. If you have any problems, questions or suggestions then
+ please get in contact with us via the Jalview discussion list.
+ </p>
+</body>
+</html>
\ No newline at end of file
<p>
If your sequence annotation is already available in GFF Format (see
- <a href="http://gmod.org/wiki/GFF2">gmod.org/wiki/GFF2</a>),
- then you can leave it as is, after first adding a line containing
- only 'GFF' after any Jalview feature colour definitions (<em>this
+ <a href="http://gmod.org/wiki/GFF2">gmod.org/wiki/GFF2</a>), then
+ you can leave it as is, after first adding a line containing only
+ 'GFF' after any Jalview feature colour definitions (<em>this
mixed format capability was added in Jalview 2.6</em>). Alternately,
you can use Jalview's own sequence feature annotation format, which
additionally allows HTML and URLs to be directly attached to each
</pre>
This format allows two alternate ways of referring to a sequence,
- either by its text ID, or its index (base 0) in an associated alignment.
- Normally, sequence features are associated with sequences rather than
- alignments, and the sequenceIndex field is given as "-1". In
- order to specify a sequence by its index in a particular alignment,
- the sequenceId should be given as "ID_NOT_SPECIFIED",
- otherwise the sequenceId field will be used in preference to the
- sequenceIndex field.
+ either by its text ID, or its index (base 0) in an associated
+ alignment. Normally, sequence features are associated with sequences
+ rather than alignments, and the sequenceIndex field is given as
+ "-1". In order to specify a sequence by its index in a
+ particular alignment, the sequenceId should be given as
+ "ID_NOT_SPECIFIED", otherwise the sequenceId field will be
+ used in preference to the sequenceIndex field.
</p>
description line will be translated into URL links. A link symbol
will be displayed adjacent to any feature which includes links, and
these are made available from the <a
- href="../menus/popupMenu.html#sqid.popup"
- >links submenu</a> of the popup menu which is obtained by
- right-clicking when a link symbol is displayed in the tooltip.<br>
- <em>Non-positional features</em><br> Specify the <em>start</em>
- and <em>end</em> for a feature to be <strong>0</strong> in order to
- attach it to the whole sequence. Non-positional features are shown
- in a tooltip when the mouse hovers over the sequence ID panel, and
- any embedded links can be accessed from the popup menu.<br /> <em>Scores</em><br>
+ href="../menus/popupMenu.html#sqid.popup">links submenu</a>
+ of the popup menu which is obtained by right-clicking when a link
+ symbol is displayed in the tooltip.<br> <em>Non-positional
+ features</em><br> Specify the <em>start</em> and <em>end</em> for
+ a feature to be <strong>0</strong> in order to attach it to the
+ whole sequence. Non-positional features are shown in a tooltip when
+ the mouse hovers over the sequence ID panel, and any embedded links
+ can be accessed from the popup menu.<br /> <em>Scores</em><br>
Scores can be associated with sequence features, and used to sort
sequences or shade the alignment (this was added in Jalview 2.5).
The score field is optional, and malformed scores will be ignored.
</p>
<p>
<strong><em>Feature settings pop-up menu</em></strong><br> <strong>Right-click</strong>
- on a feature to open a pop-up menu that allows you to sort the
- alignment or current selection using that feature type (see below),
- or toggle the type of colouring used for the feature. Features may
- be highlighted with either a single colour or a <a
- href="featureschemes.html"
- >feature colourscheme</a> based on either the scores associated with
- that feature or from the feature's description (e.g. to distinguish
- different names associated with a DOMAIN feature).
+ on a feature to open a pop-up menu that allows you to
+ <ul>
+ <li>Hide, show and select columns containing that feature</li>
+ <li>Sort the alignment or current selection using that feature
+ type (see below)</li>
+ <li>Toggle the type of colouring used for the feature</li>
+ </ul>
+ <p>
+ Features may be highlighted with either a single colour or a <a
+ href="featureschemes.html">feature colourscheme</a> based on
+ either the scores associated with that feature or from the feature's
+ description (e.g. to distinguish different names associated with a
+ DOMAIN feature).
</p>
<p>
- <strong>Ordering alignment by features</strong><br> The 'Seq
- Sort by Score' and 'Seq Sort by Density' buttons will sort the
- alignment based on the average score or total number of currently
- active features and groups on each sequence. To order the alignment
- using a specific feature type, use the <em>sort by ..</em> entries
- in the pop-up menu for that type.<br> <em>Feature sorting
- and graduated feature colouring were introduced in Jalview 2.5</em>
+ <strong><a name="sortbyfeature">Ordering alignment by
+ features</a></strong><br> The 'Seq Sort by Score' and 'Seq Sort by
+ Density' buttons will sort the alignment based on the average score
+ or total number of currently active features and groups on each
+ sequence. To order the alignment using a specific feature type, use
+ the <em>sort by ..</em> entries in the pop-up menu for that type.<br>
+ <em>Feature sorting and graduated feature colouring were
+ introduced in Jalview 2.5</em>
</p>
<p>
ordering based on the average length of each feature type.
</p>
<p>
- The <strong><em>transparency slider setting</em></strong> controls the visibility
- of features rendered below other features. Reducing the transparency
- will mean that features at the top of the list can obscure features
- lower down, and increasing it allows the user to 'see through' the
- upper layers of a set of features.
+ The <strong><em>transparency slider setting</em></strong> controls
+ the visibility of features rendered below other features. Reducing
+ the transparency will mean that features at the top of the list can
+ obscure features lower down, and increasing it allows the user to
+ 'see through' the upper layers of a set of features.
</p>
<p>
<strong><em>You can save all features, with their
<strong>The Groovy Shell</strong>
</p>
<p>
- <a href="http://www.groovy-lang.org/">Groovy</a> is an "<em>agile
- and dynamic language for the Java platform</em>". The groovy
- scripting language makes it extremely easy to programmatically
- interact with Java programs, in much the same way that Javascript is
- used to generate and interact with applets and other objects on the
- page.
+ Groovy (<a href="http://www.groovy-lang.org/">www.groovy-lang.org</a>)
+ is an "<em>agile and dynamic language for the Java
+ platform</em>". The groovy scripting language makes it extremely
+ easy to programmatically interact with Java programs, in much the
+ same way that Javascript is used to generate and interact with
+ applets and other objects on the page.
</p>
<p>
- <strong><em>Getting Groovy...</em> </strong><br> Jalview comes with
- an embedded installation of Groovy. All you need is to select <strong>Tools→Groovy
- Console...</strong> menu option from the Jalview Desktop's
- drop-down menu. After a short pause, you should then see the <a
- href="http://groovy-lang.org/groovyconsole.html"
- >Groovy Console</a> appear. This allows you to interactively execute Groovy
- scripts within the Jalview run-time environment.
+ <em>Getting Groovy...</em><br> Jalview comes with an embedded
+ installation of Groovy. Just select <strong>Tools→Groovy
+ Console...</strong> from the Jalview Desktop's drop-down menu. After a
+ short pause, you should then see the <a
+ href="http://groovy-lang.org/groovyconsole.html">Groovy
+ Console</a> appear. This allows you to interactively execute Groovy
+ scripts whilst Jalview is running. We've also provided a <strong>Calculations→Execute
+ Groovy Script</strong> button so you can execute the currently loaded
+ groovy script whilst viewing an alignment.
</p>
<p>
<strong>Executing groovy scripts on Jalview startup</strong><br>
</em>
</p>
<p>
- <strong>Executing a groovy script on a particular alignment</strong><br/>
-
- <p>
<strong>Access to Jalview's functions from Groovy Scripts</strong><br>
- There is as yet no properly defined scripting interface to Jalview,
- but all the public methods of the jalview class hierarchy can be
- called from Groovy scripts. The access point for this is the <strong>Jalview</strong>
- object defined in the groovy environment which corresponds to the
- <pre>jalview.gui.Desktop</pre>
- object which manages all the Jalview windows. Here's an example to get
- you started:
- <br>
+ The scripting interface to Jalview is still a work in progress, so
+ we recommend you also take a look at Jalview's source, since all the
+ public methods of the jalview class hierarchy can be called from
+ Groovy scripts. In addition, the following objects are also defined:
+
+
+
+ <ul>
+ <li><strong>Jalview</strong> - this is bound to <code>jalview.bin.Jalview</code>.<br />Useful
+ methods include:
+ <ul>
+ <li>Jalview.getAlignFrames() - returns a list of
+ jalview.gui.AlignFrame objects</li>
+ <li>Jalview.getCurrentAlignFrame() - returns the alignment
+ window which is currently being looked at by the user</li>
+ </ul></li>
+ <li><strong>currentAlFrame</strong> - this is only defined when
+ running a Groovy script via the -groovy command line argument. It
+ returns the first alignment window created after acting on the
+ other arguments passed on the command line.</li>
+ </ul>
+ <p>
+ <em>A simple script</em><br />
<ul>
<li>Getting the title, alignment and first sequence from the
current alignFrame<br> <pre>
def seq = alignment.getSequenceAt(0);
</pre>
</li>
- <li>When running a groovy script from the command line, the
- alignment that was just loaded can be referred to like so:<br>
- <pre>
+ <li>If you wanted to do the same thing from the command line,
+ you can refer to alignment that was just loaded with
+ currentAlFrame:<br> <pre>
print currentAlFrame.getTitle();</pre>
</ul>
- If you have downloaded the InstallAnywhere version of Jalview, you can
- find additional groovy scripts in the examples/groovy subfolder of the
- installation directory.
+ <p>
+ <em>Example scripts</em><br />If you have downloaded the
+ InstallAnywhere version of Jalview, you can find additional groovy
+ scripts in the examples/groovy subfolder of the installation
+ directory. The examples are also available at <a
+ href="http://www.jalview.org/examples/groovy">http://www.jalview.org/examples/groovy</a>.
+ </p>
+ <p>
+ <em>Using Groovy to add new Alignment Calculations</em><br />We've
+ simplified the alignment analysis programming interface in Jalview
+ 2.10 to make it easy for you to add your own dynamic annotation
+ tracks with Groovy. Have a look at the <a
+ href="../groovy/featureCounter.html">featureCounter.groovy</a>
+ example for more information.
+ </p>
+
</body>
</html>
<li><strong><a href="../calculations/tree.html">Tree</a></strong>,
<strong><a href="../calculations/pairwise.html">pairwise
alignment</a></strong> and <strong><a
- href="../calculations/pca.html"
- >PCA</a></strong> calculations will only be performed using the <em>visible</em>
- parts of the alignment.</li>
+ href="../calculations/pca.html">PCA</a></strong> calculations will
+ only be performed using the <em>visible</em> parts of the
+ alignment.</li>
<li><a href="../webServices/msaclient.html">Multiple
Sequence Alignments</a> are performed locally on on each visible
chunk of the input, and concatenated with the hidden regions to
structures opened by entries in the <strong>"Structure"</strong>
submenu in the <a href="../menus/popupMenu.html">sequence id
pop-up menu</a> (if you can't see this, then you need to <a
- href="viewingpdbs.html"
- >associate a PDB structure</a> with the sequence). Jmol is available
- from the Jalview desktop and should also run in the JalviewLite
- applet, providing the browser supports Java 1.5. If Jmol is not
- available, then the original <a href="pdbviewer.html">internal
- pdb viewer</a> will be used as a fallback.
+ href="viewingpdbs.html">associate a PDB structure</a> with
+ the sequence). Jmol is available from the Jalview desktop and should
+ also run in the JalviewLite applet, providing the browser supports
+ Java 1.5. If Jmol is not available, then the original <a
+ href="pdbviewer.html">internal pdb viewer</a> will be used as a
+ fallback.
</p>
<!-- <p>The following menu entries are provided for viewing structure data<br>
<ul>
</strong><em> Colours each residue in the structure with the colour
of its corresponding residue in the associated sequence as
rendered in the associated alignment views, including any
- Uniprot sequence features or region colourings.<br />Pick
+ UniProt sequence features or region colourings.<br />Pick
which of the associated alignment views are used to colour
the structures using the <strong>View→Colour
by ..</strong> sub menu.
colourschemes.<br>
</strong><em>The remaining entries apply the colourschemes available
from the standard and user defined <a
- href="../colourSchemes/index.html"
- >amino acid colours</a>.
+ href="../colourSchemes/index.html">amino acid
+ colours</a>.
</em></li>
</ul></li>
<li><strong>Jmol<br>
Jmol scripting console.</p>
<p>
The state of each Jmol display is stored within <a
- href="jalarchive.html"
- >Jalview archives</a> as a Jmol state recovery script file. This means
- that any Jmol visualization effects that you add beyond those
- provided by Jalview will be able to be stored and recovered along
- with the displayed alignments in Jalview.
+ href="jalarchive.html">Jalview archives</a> as a Jmol state
+ recovery script file. This means that any Jmol visualization effects
+ that you add beyond those provided by Jalview will be able to be
+ stored and recovered along with the displayed alignments in Jalview.
</p>
<p>
<strong>More Information</strong>
Jmol is a sophisticated program in its own right, with its own
command console and scripting language. Only the essentials have
been described here - the interested reader is referred to <a
- href="http://jmol.sourceforge.net/docs/"
- >Jmol's own comprehensive online documentation</a>.
+ href="http://jmol.sourceforge.net/docs/">Jmol's own
+ comprehensive online documentation</a>.
</p>
</p>
</body>
<!DOCTYPE html>
+<!--
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ -->
<html>
<head>
<meta charset="UTF-8">
<title>mmCIF File Format</title>
</head>
<body>
- <strong>mmCIF File Format</strong>
- <p>The mmCIF file format (macromolecular Crystallographic
- Information) was developed under the auspices of the International Union of Crystallography (IUCr) to extend the Crystallographic Information
- File (CIF) data representation used for describing small molecule
- structures and associated diffraction experiments.</p>
- <strong>Merits of mmCIF file format</strong>
- <ul>
- <li>Large structures (containing >62 chains and/or 99999 ATOM
- records) that cannot be fully represented in the PDB file format are
- available in the PDB archive as single PDBx/mmCIF files.</li>
- <li>PDBx/mmCIF file format provides richer data annotation</li>
- <li>PDBx/mmCIF became the standard PDB archive format in 2014.
- Since 2016 the PDB File Format is no longer being modified or
- extended to support new content.
- </li>
- </ul>
+ <strong>What is mmCIF ?</strong>
+ <br />mmCIF stands for 'macro-molecular Crystallographic Information
+ File'. This format was developed by the PDB consortium and the
+ International Union of Crystallography (IUCr), based on
+ Crystallographic Information File (CIF), a format used for describing
+ the structures of small molecules.
+ <br />mmCIF became the recommended format for the exchange of
+ biomacromolecular structures in 2014.
+ <p>
+ <strong>mmCIF and Jalview</strong> <br />Since Jalview 2.10, mmCIF
+ is used for structures downloaded from the PDB. This means:
+ </p>
+ <ol>
+ <li>Jalview can use the mmCIF to read structures that are too
+ large to be represented by a single PDB file. (ie, with more than
+ >62 chains and/or 99999 ATOM records).</li>
+ <li>Jalview users will have access to the richer annotation
+ provided by PDBx/mmCIF files.</li>
+ <li>There may be slight differences between sequences
+ containing modified residues for structures downloaded in mmCIF
+ format. This is because mmCIF differs from the PDB format in the
+ way it describes non-standard sequence data.</li>
+ </ol>
- <em>mmCIF file format support for importing 3D structure data from
- flat file and EMBL-PDBe via mmCIF was added in Jalview 2.9.1</em>
+ <em>Support for importing 3D structure data from flat file and
+ EMBL-PDBe as mmCIF was added in Jalview 2.10</em>
</body>
-</html>
\ No newline at end of file
+</html>
<p>
A tree calculated on a particular view, or loaded onto it, is by
default associated with just that view. However, the <a
- href="../calculations/treeviewer.html"
- >Tree Viewer's</a> <strong>"View→Associate
+ href="../calculations/treeviewer.html">Tree Viewer's</a> <strong>"View→Associate
leaves"</strong> submenu allows a tree's view association to be
changed to to any or all other views.
</p>
<strong>"File →Fetch Sequences"</strong>).
</p>
<img src="pdbseqfetcher.png" align="left"
- alt="PDB sequence fetcher (introduced in Jalview 2.9)"
- />
+ alt="PDB sequence fetcher (introduced in Jalview 2.9)" />
<p>
<strong>Searching the PDB Database</strong>
</p>
<p>
<ul>
- <li><strong>Searching a specific PDB field</strong><br />If you
- want to find structures based on a specific PDB metadata field,
- you can select it from the drop-down menu.</li>
+ <li><strong>Searching a specific PDB field</strong><br />If
+ you want to find structures based on a specific PDB metadata
+ field, you can select it from the drop-down menu.</li>
<li><strong>Retrieving a unique chain for a PDB entry</strong><br>To
retrieve a specific chain for a PDB entry, append the PDB ID with
a colon followed by the chain code in the search box.<br /> e.g
pop-up menu</a>. The internal PDB viewer is not able to show
superpositions, so no other options are provided. Structures can
only be viewed for sequences which have an <a
- href="viewingpdbs.html"
- >associated PDB structure</a>, and the PDB Viewer will only be
- associated with the particular alignment view from which it was
- opened.
+ href="viewingpdbs.html">associated PDB structure</a>, and the
+ PDB Viewer will only be associated with the particular alignment
+ view from which it was opened.
</p>
<p>
<strong>Controls</strong>
</strong><em> Colours each residue in the structure with the colour
of its corresponding residue in the associated sequence as
rendered in the associated alignment view, including any
- Uniprot sequence features or region colourings.<br>
+ UniProt sequence features or region colourings.<br>
Residues which only exist in the PDB structure are coloured
white if they are insertions (relative to the associated
sequence in the alignment) and grey if they are N or C
Jalview colourschemes.<br>
</em></strong> The remaining entries apply the colourschemes available from
the standard and user defined <a
- href="../colourSchemes/index.html"
- >amino acid colours</a>.</em></li>
+ href="../colourSchemes/index.html">amino acid
+ colours</a>.</em></li>
</ul></li>
<li><strong>View<br>
</strong><em> These options can be turned off to improve performance
</li>
<li>The <a href="../webServices/webServicesPrefs.html"><strong>"Web
Service"</strong> Preferences</a> tab allows you to configure the <a
- href="http://www.compbio.dundee.ac.uk/jabaws"
- >JABAWS</a> servers that Jalview uses, and change the layout of the
+ href="http://www.compbio.dundee.ac.uk/jabaws">JABAWS</a>
+ servers that Jalview uses, and change the layout of the
alignment's Web Services menu.
</li>
</ul>
</p>
<p>
<em>Open Overview Window</em> - When this is selected, the <a
- href="overview.html"
- >alignment overview</a> panel is opened by default for a new alignment
- window.
+ href="overview.html">alignment overview</a> panel is opened
+ by default for a new alignment window.
</p>
<p>
<em>Show Annotations</em> - If this is selected the new window will
<em>Open file</em> - If this is selected then the default alignment
file will be opened when Jalview is started. You can change the
default file by clicking on file name and either typing in the file
- path or selecting it from the file chooser window.<br />
- <em>Note: The default example alignment is updated periodically
- to demonstrate new features in Jalview.</em>
+ path or selecting it from the file chooser window.<br /> <em>Note:
+ The default example alignment is updated periodically to
+ demonstrate new features in Jalview.</em>
</p>
<p>
<a name="colours"><strong>"Colours"
<p>
<em>Annotation Shading Default</em> - set the default minimum and
maximum colours used when <a
- href="../colourSchemes/annotationColouring.html"
- >Colour by Annotation...</a> is selected from the alignment window's
- colours menu.
+ href="../colourSchemes/annotationColouring.html">Colour
+ by Annotation...</a> is selected from the alignment window's colours
+ menu.
</p>
<p>
<a name="structure"><strong>"Structure"
<em>URL Link From Sequence ID</em><br> These definitions are
used to generate URLs from a sequence's ID or database cross
references. Read more about <a
- href="../webServices/urllinks.html#urllinks"
- >configuring URL links here</a>.
+ href="../webServices/urllinks.html#urllinks">configuring
+ URL links here</a>.
</p>
<p>
<em>Default Browser (Unix)</em><br> Its difficult in Java to
</p>
<p>
When this option is enabled, Jalview embeds <a
- href="bioJsonFormat.html"
- >BioJSON</a> data within HTML files exported from Jalview at
- generation time. This enables the exported HTML files to be
- extracted and imported back into the Jalview desktop application at
- a later time.
+ href="bioJsonFormat.html">BioJSON</a> data within HTML files
+ exported from Jalview at generation time. This enables the exported
+ HTML files to be extracted and imported back into the Jalview
+ desktop application at a later time.
<p>
<em>Use Modeller Output</em>
</p>
<p>
Jalview can colour parts of a sequence based on the presence of
sequence features - which may be retrieved from database records
- (such as Uniprot), the result of <a href="search.html">sequence
+ (such as UniProt), the result of <a href="search.html">sequence
motif searches</a> or simply read from a <a href="featuresFormat.html">sequence
features file</a>. You can also <a href="creatinFeatures.html">create
features</a> from the results of searches or the current selection,
<p>
By default, Jalview will assign a color to each feature based on its
type. These colours can be changed from the <a
- href="featuresettings.html"
- >feature settings</a> and <a href="editingFeatures.html">amend
- features</a> dialog boxes. Since Jalview 2.5, it is also possible to
- define <a href="featureschemes.html">feature colourschemes</a> to
- shade features based on their associated scores or text labels.
+ href="featuresettings.html">feature settings</a> and <a
+ href="editingFeatures.html">amend features</a> dialog boxes. Since
+ Jalview 2.5, it is also possible to define <a
+ href="featureschemes.html">feature colourschemes</a> to shade
+ features based on their associated scores or text labels.
</p>
<p>
<strong>Sequence Feature Groups</strong>
<p>
Since Jalview 2.08, sequence features assigned to a sequence can be
organised into groups, which may indicate that the features were all
- retrieved from the same database (such as Uniprot features), or
+ retrieved from the same database (such as UniProt features), or
generated by the same analysis process (as might be specified in a <a
- href="featuresFormat.html"
- >sequence features file</a>).
+ href="featuresFormat.html">sequence features file</a>).
</p>
<p>
<strong>Sequence Feature Inheritance</strong>
<p>
Once sequence features have been loaded, their display can be fully
controlled using the alignment window's <a
- href="featuresettings.html"
- >Sequence Feature Settings</a> dialog box. Feature colour schemes and
- display parameters are unique to a particular alignment, so it is
- possible to colour the same sequence features differently in
- different alignment views.<br> Since Jalview 2.1, it is
- possible to add <a href="dassettings.html">DAS features</a> to an
- alignment via the DAS tabbed pane of the feature settings window.
+ href="featuresettings.html">Sequence Feature Settings</a>
+ dialog box. Feature colour schemes and display parameters are unique
+ to a particular alignment, so it is possible to colour the same
+ sequence features differently in different alignment views.<br>
+ Since Jalview 2.1, it is possible to add <a href="dassettings.html">DAS
+ features</a> to an alignment via the DAS tabbed pane of the feature
+ settings window.
</p>
<p>
<strong>View→Sequence ID Tooltip→Show
Precalculated Sequence Features may be added to an alignment from
the command line, drag and drop, or from the "File→Load
Features / Annotations" menu item. See the <a
- href="featuresFormat.html"
- >Features File Format</a> for more details.
+ href="featuresFormat.html">Features File Format</a> for more
+ details.
</p>
</body>
</html>
Institute, or, since Jalview 2.4, DAS servers capable of the <em>sequence</em>
command (configured in <a href="dassettings.html">DAS settings</a>).
</p>
- <img src="seqfetcher.gif" align="center"
- alt="The Jalview Sequence Fetcher Dialog Box"
- >
- <p>The Sequence Fetcher dialog box can be opened via the
- "File" menu on the main desktop in order to retrieve
- sequences as a new alignment, or opened via the "File"
- menu of an existing alignment to import additional sequences. There
- may be a short delay when the sequence fetcher is first opened,
- whilst Jalview compiles the list of available sequence datasources
- from the currently defined DAS server registry.</p>
+ <p>The Sequence Fetcher can be opened via the "File"
+ menu on the main desktop in order to retrieve sequences as a new
+ alignment, or opened via the "File" menu of an existing
+ alignment to import additional sequences. There may be a short delay
+ when the sequence fetcher is first opened, whilst Jalview compiles
+ the list of available sequence datasources from the currently
+ defined DAS server registry.</p>
<p>
- First, <strong>select the database you want to retrieve
- sequences from</strong> by clicking the button labeled 'Select database
- retrieval source'. If a database source is already selected, then
- the button's label will change to show the currently selected
- database.
+ Every time a new fetcher is opened, you will need to <strong>select
+ the database you want to retrieve sequences</strong> from the database
+ chooser.
</p>
- <img src="selectfetchdb.gif" align="left"
- alt="Database selection dialog for fetching sequences (introduced in Jalview 2.8)"
- >
- <p>Since Jalview 2.8, the available databases are shown as a tree
- in a popup dialog box. The databases are ordered alphabetically, and
- if there are many sources for the same type of sequence identifier,
- they will be grouped together in a sub-branch branch labeled with
- the identifier.</p>
+ <img src="selectfetchdb.gif" align="left" width="480" height="204"
+ alt="Database selection dialog for fetching sequences (introduced in Jalview 2.8)">
<p>
- Once you have selected the sequence database using the popup dialog
- box, <strong>enter one or more accession ids</strong> (as a
- semi-colon separated list), or press the "Example" button
- to paste the example accession for the currently selected database
- into the retrieval box. Finally, press "OK" to initiate
- the retrieval.
- </p>
- <p>
- <strong>Fetching from The PDB with the EMBL-EBI PDBe Search
- Interface</strong>
- </p>
- <p>
- Since Jalview 2.9, selecting PDB as the sequence database will open
- the <a href="pdbsequencefetcher.html">PDB Sequence Fetcher</a> for
- discovering and retrieving structures.
+ The databases are shown as a tree, and ordered alphabetically;
+ tooltips are shown if you mouse over some sources, explaining what
+ the database will retrieve. You can select one by using the up/down
+ arrow keys and hitting return, or by double clicking with the mouse.
+ <br />
+ <em>If you have DAS sources enabled, then you may have several
+ sources for the same type of sequence identifier, and these will
+ be grouped together in a sub-branch branch labeled with the
+ identifier.</em>
</p>
+ <p>Once you have selected a sequence database, its fetcher dialog
+ will open. Jalview provides two types of dialog:</p>
+ <ol>
+ <li><strong>The Free-text Search Interface</strong> <br />Free-text
+ search clients are provided for PDB (Since 2.9), and UniProt
+ (Since 2.10). They provide access to each database's own query
+ system, enabling you to retrieve data by accession, free text
+ description, or any other type of supported field. For full
+ details, see each client's help page:
+ <ul>
+ <li><a href="pdbsequencefetcher.html">PDB Sequence
+ Fetcher</a></li>
+ <li><a href="uniprotsequencefetcher.html">UniProt
+ Sequence Fetcher</a></li>
+ </ul></li>
+ <li><strong>Accession based sequence retrieval</strong> <br />
+
+ <img src="seqfetcher.gif" align="center"
+ alt="The Jalview Sequence Fetcher Dialog Box"><br /> To
+ retrieve sequences, simply <strong>enter one or more
+ accession ids</strong> (as a semi-colon separated list), or press the
+ "Example" button to paste the example accession for the
+ currently selected database into the retrieval box. Finally, press
+ "OK" to initiate the retrieval.</li>
+ </ol>
<p>
<strong>Only retrieving part of a sequence</strong>
</p>
<p>
- DAS sources (indicated by a "<em>(DAS)</em>") allow a
- range to be specified in addition to a sequence ID. To retrieve 50
- residues starting at position 35 in UNIPROT sequence P73137 using
- the UNIPROT DAS server, you would enter "'P73137:35,84'.<br />
- <em>Full support for DAS range queries was introduced in
- Jalview 2.8</em>
+ When using DAS sources (indicated by a "<em>(DAS)</em>"),
+ you can append a range in addition to a sequence ID. For example, to
+ retrieve 50 residues starting at position 35 in UNIPROT sequence
+ P73137 using the UNIPROT DAS server, you would enter
+ "'P73137:35,84'.<br /> <em>Full support for DAS range
+ queries was introduced in Jalview 2.8</em>
</p>
<p>If you use the WSDBFetch sequence fetcher services (EMBL,
- Uniprot, PFAM, and RFAM) in work for publication, please cite:</p>
+ UniProt, PFAM, and RFAM) in work for publication, please cite:</p>
<p>
Pillai S., Silventoinen V., Kallio K., Senger M., Sobhany S., Tate
J., Velankar S., Golovin A., Henrick K., Rice P., Stoehr P., Lopez
<p>
<strong>Mapping Between Different Sequences</strong>
</p>
+ <!-- TODO: review and check if this page is really needed -->
<p>A new feature in Jalview 2.3 is the ability to map between
sequences in different domains, based on alignment, or by the use of
explicit mappings provided by databases.</p>
correspondence between DNA and protein sequences. This mapping can
be imported directly from EMBL and EMBLCDS database records
retrieved by the <a href="seqfetch.html">Sequence Fetcher</a>, and
- allows sequence features to be mapped directly from Uniprot das
+ allows sequence features to be mapped directly from UniProt das
sources to their coding region on EMBL sequence records.
</p>
- <p>In Jalview 2.9.1 <a href="siftsmapping.html">SIFTS Mapping</a> was added as a better means for explicitly identifying the coordinates corresponding to a displayed sequence when viewing a PDB structure associated with a sequence </p>
+ <em><a href="siftsmapping.html">SIFTS Mapping</a> between PDB and
+ UniProt data was introduced in Jalview 2.10</em>
</body>
</html>
<!DOCTYPE html>
+<!--
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ -->
<html>
<head>
<meta charset="UTF-8">
-<title>SIFTS Mapping</title>
+<title>SIFTS Mapping from UniProt for PDB Structures</title>
</head>
<body>
-
- <p><strong>SIFTS Mapping</strong></p>
-
+
<p>
- SIFTS (Structure integration with function, taxonomy
- and sequences) provides an up-to-date resource for residue-level
- mapping between Uniprot and PDB entries. The information is updated and
- released weekly simultaneously with the release of new PDB entries.
- SIFTS Entries are published as XML files and made publicly available via an FTP
- site hosted at the European Bioinformatics Institute.
+ <strong>SIFTS Mapping for UniProt sequences and PDB
+ Structures</strong><br /> SIFTS (Structure Integration with Function,
+ Taxonomy and Sequences) is a database of residue-level mappings
+ between UniProt protein sequences, and protein structures found in
+ the PDB. The database is updated for each PDB release, and is
+ provided by the <a href="https://www.ebi.ac.uk/pdbe/docs/sifts/">PDBe
+ at EMBL-EBI</a>.
</p>
-
+ <p>When Jalview imports PDB data for a protein sequence found in
+ UniProt, either via the 'View 3D Structure...' option, or the 'Fetch
+ DB Refs' web services menu, Jalview will also download its SIFTS
+ record and use that information to construct a mapping between the
+ sequence and downloaded structure.</p>
+ <p>If, for some reason, no SIFTS mapping data exists, then Jalview
+ will generate a mapping using the built-in Needleman and Wunsch
+ global alignment algorithm. This is how sequence-structure mappings
+ were created before version 2.10.</p>
<p>
- At the point of viewing a PDB structure, Jalview downloads a SIFTS file
- for the target entry and uses it to accurately map the sequence residues with the
- structure residue. Prior to SIFTS integration, Jalview uses Needleman and Wunsch
- Alignment algorithm to map sequence residues to structure residues, and that may not
- always result to a correct mapping since it is computational determined.
+ <strong>Controlling and troubleshooting SIFTS mappings</strong> <br />
+ Configuration options controlling whether SIFTS mappings are used
+ can be found in the <strong>Tools → Preferences →
+ Structure tab</strong>, under 'Sequence ↔ Structure method'.<br /> <em>Note:</em>
+ Changing the configuration will only affect how new mappings are
+ created. In order to recompute mappings for structures already
+ loaded, please reload the sequence & structural data.
</p>
-
+
<p>
- The default method for 'Sequence ↔ Structure' mapping can be configured
- in the Structure tab in the <strong>Tools → Preferences</strong> dialog box. When 'SIFTS'
- is enabled as the default, all mappings between 'Sequence ↔ Structure' is
- performed via SIFTS provided that there is a valid SIFTS entry for PDB structure. If no
- valid SIFTS resource is available, then the 'Sequence ↔ Structure' mapping falls
- back to Needleman and Wunsch Alignment algorithm.
+ <strong>Multi-Chain Mappings</strong> <br />SIFTS gives Jalview the
+ ability to display multi-chain mappings between UniProt sequences
+ and PDB structure data. This is important when working with
+ multimeric proteins, when the biological assembly can contain
+ several structures for the same protein sequence. Multi-chain
+ mapping allows all residues in a structure to be located in the
+ alignment, and also, when shading the structure by sequence colours,
+ enables conservation patterns between oligomer interfaces to be
+ explored.
</p>
-
- <p>To verify the mapping method used, you can view the mapping output via the structure viewer menu <strong>File → View mapping.</strong> A sample mapping output can be seen in the screenshot below. The highlighted position shows the method used. </p>
+ <p>To see this in action, Retrieve the UniProt sequence
+ FER1_MAIZE, and then view one of its structures: 3B2F. Mousing over
+ the sequence results to two positions being highlighted in the
+ structure, and colouring the alignment transfers the color to all
+ the mapped chains in the structure.</p>
+
<p>
- <img src="sifts_mapping_output.png" align="left" alt="SIFTS mapping output" />
+ <Strong>Viewing Mapping Output</Strong> <br /> The mapping provided
+ by the SIFTS record is accessible via <strong>File →
+ View mapping</strong> menu of the structure viewers. The screenshot below
+ shows the mapping created between UniProt sequence FER1_MAIZE and
+ proteins in PDB 3B2F, which reports mappings for two chains. The
+ mapping method is also reported (highlighted with red border).
+ <p>
+
+  <img src="sifts_mapping_output.png" align="left"
+ alt="SIFTS mapping output" /> <br />
+ <p>
+ <em>SIFTS Mapping integration was added in Jalview 2.10</em>
</p>
-
- <p><em>SIFTS Mapping integration was added in Jalview 2.9.1</em></p>
-
+
</body>
-</html>
\ No newline at end of file
+</html>
<ul>
<li>Mouseover or scrolling of either alignment is followed by
the other (unless you turn off <strong><a
- href="../menus/alwview.html"
- >"View→Automatic Scrolling"</a></strong>)
+ href="../menus/alwview.html">"View→Automatic
+ Scrolling"</a></strong>)
</li>
<li>On selecting rows, columns or regions in one alignment, the
corresponding selection is made in the other</li>
<li>Sequence ordering in one alignment (using the cursor, or <strong><a
- href="../calculations/sorting.html"
- >"Calculate→Sort")</a></strong> is also applied to the other
+ href="../calculations/sorting.html">"Calculate→Sort")</a></strong>
+ is also applied to the other
</li>
<li>Editing (gap insertion / deletion) in the protein alignment
is reflected in the cDNA (but not vice versa)</li>
<li>Any trees imported or created with <strong><a
- href="../calculations/tree.html"
- >"Calculate Tree"</a></strong> on one of the views allow both cDNA and
- Protein views to be grouped, coloured or sorted.
+ href="../calculations/tree.html">"Calculate Tree"</a></strong> on
+ one of the views allow both cDNA and Protein views to be grouped,
+ coloured or sorted.
</li>
<li>To allow for the different widths in cDNA and Protein
alignments, the <strong><a href="../menus/alwformat.html">"Format→Font"</a></strong>
</ul>
<p>
An alignment annotation row on the protein alignment shows the <strong><a
- href="../calculations/consensus.html"
- >cDNA consensus</a></strong> for each peptide column.<br /> This consensus may
- reveal variation in nucleotides coding for conserved protein
- residues.
+ href="../calculations/consensus.html">cDNA consensus</a></strong> for
+ each peptide column.<br /> This consensus may reveal variation in
+ nucleotides coding for conserved protein residues.
</p>
<a name="opensplit" />
<strong>Structure Chooser</strong>
</p>
- The Structure Chooser interface provides a smart technique for
- selecting PDB structures to view in Jalview by querying readily
- available meta-data of structures. The Interface can be invoked by
- selecting the
- <strong>"3D Structure Data.."</strong> option from a sequence's
- <a href="../menus/popupMenu.html">pop-up menu</a>. Some of the main
- features it provides are listed below:
+ <p>
+ The Structure Chooser interface allows you to interactively select
+ which PDB structures to view for the currently selected set of
+ sequences. It is opened by selecting the <strong>"3D
+ Structure Data.."</strong> option from the Sequence ID panel's <a
+ href="../menus/popupMenu.html">pop-up menu</a>. The dialog
+ provides:
+ </p>
<ul>
<li>Automatic discovery, retrieval and association of PDB
- entries for an alignment's sequences</li>
- <li>Visualisation of discovered structures' meta-data</li>
- <li>Ability to configure the meta-data entries to visualise</li>
- <li>Auto-selection of the best structure via filtering by the
- available metric parameters in the meta-data (i.e. resolution,
- quality etc).</li>
- <li>Selection of multiple structures in a single operation</li>
- </ul>
- Additionally, the Structure Chooser retains the following contemporary
- features of Jalview:
- <ul>
- <li>Manual association of PDB entries via entering the PDB Id
- or From File</li>
- <li>Ability to view cached PDB entries</li>
+ entries for sequences</li>
+ <li>Exploration of meta-data for available 3D structures</li>
+ <li>Automatic selection of the 'best structure' to display for
+ each sequence</li>
+ <li>Manual association of PDB entries by entering a PDB Id</li>
+ <li>Association of structure data from a local file (in mmCIF
+ or PDB format)</li>
</ul>
-
-
- <strong>Associating PDB files with Sequences</strong>
- <br> Discovery/Association of PDB entries to a sequence now
- happens automatically during the initialisation of the Structure
- Chooser Interface. Jalview uses the sequence's ID to query the PDB
- Rest API provided by the EBI to discover PDB Ids associated with the
- sequence.
-
- <br>
- <br>
- <strong>Configuring displayed meta-data for Structures</strong>
- <br> To configure the visible meta-data displayed for the
- discovered structures, click the 'Configure Displayed Columns' tab,
- then tick the options which you intend to make visible.
-
- <br>
- <br>
- <strong>Auto-selection of best Structures</strong>
- <br> Jalview can automatically filter and select the best
- structures using various metric categories avaialble from the
- meta-data of the structures. To perform this simply select any of the
- following options from the drop-down menu in the Structure Chooser
- interface: Best Uniprot coverage, Higest Resolution, Best Quality,
- Highest Protein Chain etc. When the 'Invert' option is selected,
- Jalview returns an inverse result for the current selected option in
- the drop-down menu.
+ <p>
+ <strong>Selecting and Viewing Structures</strong>
+ </p>
+ <p>
+ Once one or more structures have been selected, pressing the <strong>View</strong>
+ button will import them into <a
+ href="viewingpdbs.html#afterviewbutton">a new or existing
+ structure view</a>.
+ </p>
+ <p>
+ <strong>Automated discovery of structure data</strong>
+ </p>
+ <p>
+ After selecting "3D Structure Data ..", Jalview queries the PDB via
+ the PDBe SOLR Rest API provided by EMBL-EBI to discover PDB IDs
+ associated with the sequence. It does this based on the sequence's
+ ID string, and any other associated database IDs. <br />
+ <br />
+ <p>
+ <strong><a name="cachedstructview">Viewing existing
+ structures for your sequences</a></strong>
+ </p>
+ <p>
+ If you have already loaded 3D structure data for the selected
+ sequences, the structure chooser will first open with the <strong>Cached
+ Structures View</strong>. This view shows associations between each
+ sequence, and chains for 3D structure files already in memory. If
+ you want to download additional structures, select one of the other
+ options from the drop down menu.
+ </p>
+ <p>
+ <strong>Selection of the best structure for each sequence</strong>
+ </p>
+ <p>Jalview can automatically select the best structures according
+ to meta-data provided by the PDB. For alignments with no existing
+ structure data, the 'Best Quality' structure for each sequence will
+ by default be selected, but clicking on the drop down menu allows
+ other criteria to be chosen, including Resolution (only defined for
+ X-Ray structures), Highest Protein Chain etc. When 'Invert' is
+ selected, structures are selected in reverse order for the current
+ criteria (e.g. worst quality rather than best).</p>
<p>
<img src="schooser_main.png" style="width: 464px; height: 369px;">
<p><img src="schooser_cached.png"> -->
<br>The screenshot above shows the Structure Chooser interface
along with the meta-data of auto-discovered structures for the
- sample alignment. Note however that if no structures were
- auto-discovered, a different interface for manual association will
- be invoked as seen in the screenshot below.
+ sample alignment. If no structures were
+ auto-discovered, options for manually associating PDB records will be shown (see below).
<p>
- <img src="schooser_enter-id.png"
- style="width: 464px; height: 369px;"
- >
+ <strong>Exploration of meta-data for available structures</strong>
+ </p>
+ <p>Information on each structure available is displayed in columns
+ in the dialog box. By default, only the title, resolution and PDB
+ identifier are shown, but many more are provided by the PDBe. To
+ configure which ones are displayed, select the 'Configure Displayed
+ Columns' tab and tick the columns which you want to see.</p>
<p>
+ <img src="schooser_enter-id.png"
+ style="width: 464px; height: 369px;">
+ <br/>
<strong>Manual selection/association of PDB files with
Sequences</strong>
</p>
- <p>To manually associate PDB files with a sequence, select any of
- the follwing options listed below from the drop-down menu in the
- interface:
+ <p>To manually associate PDB files with a sequence, select 'From
+ File', or 'Enter PDB Id' from the drop-down menu:
<ul>
- <li><strong>From File</strong> - You can load a PDB file from
- the local machine or network and associate it with the selected
- sequence. PDB files associated in this way will also be saved in
- the <a href="jalarchive.html">Jalview Archive file</a>.<br></li>
- <li><strong>Enter PDB Id</strong> - Jalview will use the PDB
- Rest API, provided by the EBI, to fetch the PDB file with the
- entered Id.<br></li>
- <li><strong>Cached PDB Entries</strong> - You can view PDB
- structures which have previously been downloaded/viewed using this
- option. Jalview caches previously downloaded PDB entries in the
- computer memory. However, if the project is saved before exiting
- Jalview, Jalview will serialize the cached entries to the file
- system.</li>
+ <li><strong>From File</strong> - allows you to load a PDB file
+ from the local machine or network and associate it with the
+ selected sequence. PDB files associated in this way will also be
+ saved in the <a href="jalarchive.html">Jalview Archive file</a>.<br></li>
+ <li><strong>Enter PDB Id</strong> - allows you specify a PDB ID
+ for your sequence. The PDB Rest API, provided by EMBL-EBI, is used
+ to validate and fetch structure data.<br></li>
</ul>
<p>
<p>
<strong>UniProtKB query fields</strong>
</p>
-<p>Supported query fields for searching specific data in UniProtKB (see also <a href="text-search">query syntax</a>).</p>
+ <p>
+ Supported query fields for searching specific data in UniProtKB (see
+ also <a href="uniprotsequencefetcher.html#text-search">query
+ syntax</a>).
+ </p>
-<table border="1" width="95%">
- <tr>
- <th>Field</th>
- <th>Example</th>
- <th>Description</th>
- </tr>
- <tr>
- <td>accession</td>
- <td>
- <code>accession:P62988</code>
- </td>
- <td>
- Lists all entries with the primary or secondary
- accession number P62988.
- </td>
- </tr>
- <tr>
- <td>active</td>
- <td>
- <code>active:no </code>
- </td>
- <td>
- Lists all obsolete entries.
- </td>
- </tr>
- <tr>
- <td>annotation</td>
- <td>
- <code>
- annotation:(type:non-positional)
- <br />
- annotation:(type:positional)
- <br />
- annotation:(type:mod_res "Pyrrolidone carboxylic acid" evidence:experimental)
- </code>
- </td>
- <td>
- Lists all entries with:
- <ul>
- <li>any general annotation (comments [CC])</li>
- <li>any sequence annotation (features [FT])</li>
- <li>at least one amino acid modified with a Pyrrolidone carboxylic acid group</li>
- </ul>
- </td>
- </tr>
- <tr>
- <td>author</td>
- <td>
- <code>
- author:ashburner
- </code>
- </td>
- <td>
- Lists all entries with at least one reference co-authored by Michael Ashburner.
- </td>
- </tr>
- <tr>
- <td>cdantigen</td>
- <td>
- <code>
- cdantigen:CD233
- </code>
- </td>
- <td>
- Lists all entries whose cluster of differentiation number is CD233.
- </td>
- </tr>
- <tr>
- <td>citation</td>
- <td>
- <code>
- citation:("intracellular structural proteins")
- <br />
- citation:(author:ashburner journal:nature)
- citation:9169874
- </code>
- </td>
- <td>
- Lists all entries with a literature citation:
- <ul>
- <li>containing the phrase "intracellular structural proteins" in either title or abstract</li>
- <li>co-authored by Michael Ashburner and published in Nature</li>
- <li>with the PubMed identifier 9169874</li>
- </ul>
- </td>
- </tr>
- <tr>
- <td>cluster</td>
- <td>
- <code>
- cluster:UniRef90_A5YMT3
- </code>
- </td>
- <td>
- Lists all entries in the UniRef 90% identity cluster whose
- representative sequence is UniProtKB entry A5YMT3.
- </td>
- </tr>
- <tr>
- <td>count</td>
- <td>
- <code>
- annotation:(type:transmem count:5)<br />
- annotation:(type:transmem count:[5 TO *])<br />
- annotation:(type:cofactor count:[3 TO *])
- </code>
- </td>
- <td>Lists all entries with:
- <ul>
- <li>exactly 5 transmembrane regions</li>
- <li>5 or more transmembrane regions</li>
- <li>3 or more Cofactor comments</li>
- </ul>
- </td>
- </tr>
- <tr>
- <td>created</td>
- <td>
- <code>
- created:[20121001 TO *]<br />
- reviewed:yes AND created:[current TO *]
- </code>
- </td>
- <td>
- Lists all entries created since October 1st 2012.<br />
+ <table border="1" width="95%">
+ <tr>
+ <th>Field</th>
+ <th>Example</th>
+ <th>Description</th>
+ </tr>
+ <tr>
+ <td>accession</td>
+ <td><code>accession:P62988</code></td>
+ <td>Lists all entries with the primary or secondary accession
+ number P62988.</td>
+ </tr>
+ <tr>
+ <td>active</td>
+ <td><code>active:no </code></td>
+ <td>Lists all obsolete entries.</td>
+ </tr>
+ <tr>
+ <td>annotation</td>
+ <td><code>
+ annotation:(type:non-positional) <br />
+ annotation:(type:positional) <br /> annotation:(type:mod_res
+ "Pyrrolidone carboxylic acid" evidence:experimental)
+ </code></td>
+ <td>Lists all entries with:
+ <ul>
+ <li>any general annotation (comments [CC])</li>
+ <li>any sequence annotation (features [FT])</li>
+ <li>at least one amino acid modified with a Pyrrolidone
+ carboxylic acid group</li>
+ </ul>
+ </td>
+ </tr>
+ <tr>
+ <td>author</td>
+ <td><code> author:ashburner </code></td>
+ <td>Lists all entries with at least one reference co-authored
+ by Michael Ashburner.</td>
+ </tr>
+ <tr>
+ <td>cdantigen</td>
+ <td><code> cdantigen:CD233 </code></td>
+ <td>Lists all entries whose cluster of differentiation number
+ is CD233.</td>
+ </tr>
+ <tr>
+ <td>citation</td>
+ <td><code>
+ citation:("intracellular structural proteins") <br />
+ citation:(author:ashburner journal:nature) citation:9169874
+ </code></td>
+ <td>Lists all entries with a literature citation:
+ <ul>
+ <li>containing the phrase "intracellular structural
+ proteins" in either title or abstract</li>
+ <li>co-authored by Michael Ashburner and published in
+ Nature</li>
+ <li>with the PubMed identifier 9169874</li>
+ </ul>
+ </td>
+ </tr>
+ <tr>
+ <td>cluster</td>
+ <td><code> cluster:UniRef90_A5YMT3 </code></td>
+ <td>Lists all entries in the UniRef 90% identity cluster
+ whose representative sequence is UniProtKB entry A5YMT3.</td>
+ </tr>
+ <tr>
+ <td>count</td>
+ <td><code>
+ annotation:(type:transmem count:5)<br />
+ annotation:(type:transmem count:[5 TO *])<br />
+ annotation:(type:cofactor count:[3 TO *])
+ </code></td>
+ <td>Lists all entries with:
+ <ul>
+ <li>exactly 5 transmembrane regions</li>
+ <li>5 or more transmembrane regions</li>
+ <li>3 or more Cofactor comments</li>
+ </ul>
+ </td>
+ </tr>
+ <tr>
+ <td>created</td>
+ <td><code>
+ created:[20121001 TO *]<br /> reviewed:yes AND
+ created:[current TO *]
+ </code></td>
+ <td>Lists all entries created since October 1st 2012.<br />
Lists all new UniProtKB/Swiss-Prot entries in the last release.
- </td>
- </tr>
- <tr>
- <td>database</td>
- <td>
- <code>
- database:(type:pfam)
- <br />
- database:(type:pdb 1aut)
- </code>
- </td>
- <td>
- Lists all entries with:
- <ul>
- <li>a cross-reference to the Pfam database</li>
- <li>a cross-reference to the PDB database entry 1aut</li>
- </ul>
-
- </td>
- </tr>
- <tr>
- <td>domain</td>
- <td>
- <code>
- domain:VWFA
- </code>
- </td>
- <td>
- Lists all entries with a Von Willebrand factor type A domain described
- in the 'Family and Domains' section.
- </td>
- </tr>
- <tr>
- <td>ec</td>
- <td>
- <code>
- ec:3.2.1.23
- </code>
- </td>
- <td>
- Lists all beta-galactosidases.
- </td>
- </tr>
- <tr>
- <td>evidence</td>
- <td>
- <code>
- annotation:(type:signal evidence:ECO_0000269)<br />
- (type:mod_res phosphoserine evidence:ECO_0000269)<br />
- annotation:(type:function AND evidence:ECO_0000255)
- </code>
- </td>
- <td>Lists all entries with:
- <ul>
- <li>a signal sequence whose positions have been experimentally proven</li>
- <li>experimentally proven phosphoserine sites</li>
- <li>a function manually asserted according to rules</li>
- </ul>
- </td>
- </tr>
- <tr>
- <td>family</td>
- <td>
- <code>
- family:serpin
- </code>
- </td>
- <td>
- Lists all entries belonging to the Serpin family of proteins.
- </td>
- </tr>
- <tr>
- <td>fragment</td>
- <td>
- <code>
- fragment:yes
- </code>
- </td>
- <td>
- Lists all entries with an incomplete sequence.
- </td>
- </tr>
+ </td>
+ </tr>
+ <tr>
+ <td>database</td>
+ <td><code>
+ database:(type:pfam) <br /> database:(type:pdb 1aut)
+ </code></td>
+ <td>Lists all entries with:
+ <ul>
+ <li>a cross-reference to the Pfam database</li>
+ <li>a cross-reference to the PDB database entry 1aut</li>
+ </ul>
+
+ </td>
+ </tr>
+ <tr>
+ <td>domain</td>
+ <td><code> domain:VWFA </code></td>
+ <td>Lists all entries with a Von Willebrand factor type A
+ domain described in the 'Family and Domains' section.</td>
+ </tr>
+ <tr>
+ <td>ec</td>
+ <td><code> ec:3.2.1.23 </code></td>
+ <td>Lists all beta-galactosidases.</td>
+ </tr>
+ <tr>
+ <td>evidence</td>
+ <td><code>
+ annotation:(type:signal evidence:ECO_0000269)<br />
+ (type:mod_res phosphoserine evidence:ECO_0000269)<br />
+ annotation:(type:function AND evidence:ECO_0000255)
+ </code></td>
+ <td>Lists all entries with:
+ <ul>
+ <li>a signal sequence whose positions have been
+ experimentally proven</li>
+ <li>experimentally proven phosphoserine sites</li>
+ <li>a function manually asserted according to rules</li>
+ </ul>
+ </td>
+ </tr>
+ <tr>
+ <td>family</td>
+ <td><code> family:serpin </code></td>
+ <td>Lists all entries belonging to the Serpin family of
+ proteins.</td>
+ </tr>
+ <tr>
+ <td>fragment</td>
+ <td><code> fragment:yes </code></td>
+ <td>Lists all entries with an incomplete sequence.</td>
+ </tr>
+
+ <tr>
+ <td>gene</td>
+ <td><code> gene:HSPC233 </code></td>
+ <td>Lists all entries for proteins encoded by gene HSPC233.</td>
+ </tr>
+ <tr>
+ <td>go</td>
+ <td><code>
+ go:cytoskeleton <br /> go:0015629
+ </code></td>
+ <td>Lists all entries associated with:
+ <ul>
+ <li>a GO term containing the word "cytoskeleton"</li>
+ <li>the GO term Actin cytoskeleton and any subclasses</li>
+ </ul>
+ </td>
+ </tr>
+ <tr>
+ <td>host</td>
+ <td><code>
+ host:mouse <br /> host:10090 <br /> host:40674
+ </code></td>
+ <td>Lists all entries for viruses infecting:
+ <ul>
+ <li>organisms with a name containing the word "mouse"</li>
+ <li>Mus musculus (Mouse)</li>
+ <li>all mammals (all taxa classified under the taxonomy
+ node for Mammalia)</li>
+ </ul>
+ </td>
+ </tr>
+ <tr>
+ <td>id</td>
+ <td><code>id:P00750</code></td>
+ <td>Returns the entry with the primary accession number
+ P00750.</td>
+ </tr>
+ <tr>
+ <td>inn</td>
+ <td><code> inn:Anakinra </code></td>
+ <td>Lists all entries whose "International Nonproprietary
+ Name" is Anakinra.</td>
+ </tr>
+ <tr>
+ <td>interactor</td>
+ <td><code> interactor:P00520 </code></td>
+ <td>Lists all entries describing interactions with the
+ protein described by entry P00520.</td>
+ </tr>
+ <tr>
+ <td>keyword</td>
+ <td><code> keyword:toxin </code></td>
+ <td>Lists all entries associated with the keyword Toxin.</td>
+ </tr>
+ <tr>
+ <td>length</td>
+ <td><code> length:[500 TO 700] </code></td>
+ <td>Lists all entries describing sequences of length between
+ 500 and 700 residues.</td>
+ </tr>
+ <tr>
+ <td>lineage</td>
+ <td />
+ <td>This field is a synonym for the field <code>taxonomy</code>.
+ </td>
+ </tr>
+ <tr>
+ <td>mass</td>
+ <td><code> mass:[500000 TO *] </code></td>
+ <td>Lists all entries describing sequences with a mass of at
+ least 500,000 Da.</td>
+ </tr>
+ <tr>
+ <td>method</td>
+ <td><code>
+ method:maldi <br /> method:xray
+ </code></td>
+ <td>Lists all entries for proteins identified by:
+ matrix-assisted laser desorption/ionization (MALDI),
+ crystallography (X-Ray). The <code>method</code> field searches
+ names of physico-chemical identification methods in the
+ 'Biophysicochemical properties' subsection of the 'Function'
+ section, the 'Publications' and 'Cross-references' sections.
+ </td>
+ </tr>
+ <tr>
+ <td>mnemonic</td>
+ <td><code> mnemonic:ATP6_HUMAN </code></td>
+ <td>Lists all entries with entry name (ID) ATP6_HUMAN.
+ Searches also obsolete entry names.</td>
+ </tr>
+ <tr>
+ <td>modified</td>
+ <td><code>
+ modified:[20120101 TO 20120301]<br /> reviewed:yes AND
+ modified:[current TO *]
+ </code></td>
+ <td>Lists all entries that were last modified between January
+ and March 2012.<br /> Lists all UniProtKB/Swiss-Prot entries
+ modified in the last release.
+ </td>
+ </tr>
+ <tr>
+ <td>name</td>
+ <td><code> name:"prion protein" </code></td>
+ <td>Lists all entries for prion proteins.</td>
+ </tr>
+ <tr>
+ <td>organelle</td>
+ <td><code> organelle:Mitochondrion </code></td>
+ <td>Lists all entries for proteins encoded by a gene of the
+ mitochondrial chromosome.</td>
+ </tr>
+ <tr>
+ <td>organism</td>
+ <td><code>
+ organism:"Ovis aries" <br /> organism:9940 <br />
+ organism:sheep <br />
+ </code></td>
+ <td>Lists all entries for proteins expressed in sheep (first
+ 2 examples) and organisms whose name contains the term "sheep".
+ </td>
+ </tr>
- <tr>
- <td>gene</td>
- <td>
- <code>
- gene:HSPC233
- </code>
- </td>
- <td>
- Lists all entries for proteins encoded by gene HSPC233.
- </td>
- </tr>
- <tr>
- <td>go</td>
- <td>
- <code>
- go:cytoskeleton
- <br />
- go:0015629
- </code>
- </td>
- <td>
- Lists all entries associated with:
- <ul>
- <li>a GO term containing the word "cytoskeleton"</li>
- <li>the GO term Actin cytoskeleton and any subclasses</li>
- </ul>
- </td>
- </tr>
- <tr>
- <td>host</td>
- <td>
- <code>
- host:mouse
- <br />
- host:10090
- <br />
- host:40674
- </code>
- </td>
- <td>
- Lists all entries for viruses infecting:
- <ul>
- <li>organisms with a name containing the word "mouse"</li>
- <li>Mus musculus (Mouse)</li>
- <li>all mammals (all taxa classified under the taxonomy node for Mammalia)</li>
- </ul>
- </td>
- </tr>
- <tr>
- <td>id</td>
- <td>
- <code>id:P00750</code>
- </td>
- <td>
- Returns the entry with the primary
- accession number P00750.
- </td>
- </tr>
- <tr>
- <td>inn</td>
- <td>
- <code>
- inn:Anakinra
- </code>
- </td>
- <td>
- Lists all entries whose "International Nonproprietary Name" is Anakinra.
- </td>
- </tr>
- <tr>
- <td>interactor</td>
- <td>
- <code>
- interactor:P00520
- </code>
- </td>
- <td>
- Lists all entries describing interactions with the protein described by
- entry P00520.
- </td>
- </tr>
- <tr>
- <td>keyword</td>
- <td>
- <code>
- keyword:toxin
- </code>
- </td>
- <td>
- Lists all entries associated with the keyword Toxin.
- </td>
- </tr>
- <tr>
- <td>length</td>
- <td>
- <code>
- length:[500 TO 700]
- </code>
- </td>
- <td>
- Lists all entries describing sequences of length between 500 and 700 residues.
- </td>
- </tr>
- <tr>
- <td>lineage</td>
- <td />
- <td>
- This field is a synonym for the field <code>taxonomy</code>.
- </td>
- </tr>
- <tr>
- <td>mass</td>
- <td>
- <code>
- mass:[500000 TO *]
- </code>
- </td>
- <td>
- Lists all entries describing sequences with a mass of at least 500,000 Da.
- </td>
- </tr>
- <tr>
- <td>method</td>
- <td>
- <code>
- method:maldi
- <br />
- method:xray
- </code>
- </td>
- <td>
- Lists all entries for proteins identified by: matrix-assisted laser
- desorption/ionization (MALDI), crystallography (X-Ray). The
- <code>method</code> field searches names of physico-chemical
- identification methods in the 'Biophysicochemical properties' subsection of the 'Function' section, the 'Publications' and
- 'Cross-references' sections.
- </td>
- </tr>
- <tr>
- <td>mnemonic</td>
- <td>
- <code>
- mnemonic:ATP6_HUMAN
- </code>
- </td>
- <td>
- Lists all entries with entry name (ID) ATP6_HUMAN. Searches also
- obsolete entry names.
- </td>
- </tr>
- <tr>
- <td>modified</td>
- <td>
- <code>
- modified:[20120101 TO 20120301]<br />
- reviewed:yes AND modified:[current TO *]
- </code>
- </td>
- <td>
- Lists all entries that were last modified between January and March 2012.<br />
- Lists all UniProtKB/Swiss-Prot entries modified in the last release.
- </td>
- </tr>
- <tr>
- <td>name</td>
- <td>
- <code>
- name:"prion protein"
- </code>
- </td>
- <td>
- Lists all entries for prion proteins.
- </td>
- </tr>
- <tr>
- <td>organelle</td>
- <td>
- <code>
- organelle:Mitochondrion
- </code>
- </td>
- <td>
- Lists all entries for proteins encoded by a gene of the mitochondrial
- chromosome.
- </td>
- </tr>
- <tr>
- <td>organism</td>
- <td>
- <code>
- organism:"Ovis aries"
- <br />
- organism:9940
- <br />
- organism:sheep
- <br />
- </code>
- </td>
- <td>
- Lists all entries for proteins expressed in sheep (first 2 examples) and
- organisms whose name contains the term "sheep".
- </td>
- </tr>
-
- <tr>
- <td>plasmid</td>
- <td>
- <code>
- plasmid:ColE1
- </code>
- </td>
- <td>
- Lists all entries for proteins encoded by a gene of plasmid ColE1.
- </td>
- </tr>
- <tr>
- <td>proteome</td>
- <td>
- <code>
- proteome:UP000005640
- </code>
- </td>
- <td>
- Lists all entries from the human proteome.
- </td>
- </tr>
- <tr>
- <td>proteomecomponent</td>
- <td>
- <code>
- proteomecomponent:"chromosome 1" and organism:9606
- </code>
- </td>
- <td>
- Lists all entries from the human chromosome 1.
- </td>
- </tr>
- <tr>
- <td>replaces</td>
- <td>
- <code>
- replaces:P02023
- </code>
- </td>
- <td>
- Lists all entries that were created from a merge with entry P02023.
- </td>
- </tr>
- <tr>
- <td>reviewed</td>
- <td>
- <code>
- reviewed:yes
- </code>
- </td>
- <td>
- Lists all UniProtKB/Swiss-Prot entries.
- </td>
- </tr>
- <tr>
- <td>scope</td>
- <td>
- <code>
- scope:mutagenesis
- </code>
- </td>
- <td>
- Lists all entries containing a reference that was used to gather
- information about mutagenesis.
- </td>
- </tr>
- <tr>
- <td>sequence</td>
- <td>
- <code>
- sequence:P05067-9
- </code>
- </td>
- <td>
- Lists all entries containing a link to isoform 9 of the sequence
- described in entry P05067. Allows searching by specific sequence
- identifier.
- </td>
- </tr>
- <tr>
- <td>sequence_modified</td>
- <td>
- <code>
- sequence_modified:[20120101 TO 20120301]<br />
- reviewed:yes AND sequence_modified:[current TO *]
- </code>
- </td>
- <td>
- Lists all entries whose sequences were last modified between January and March 2012.<br />
- Lists all UniProtKB/Swiss-Prot entries whose sequences were modified in the last release.
- </td>
- </tr>
- <tr>
- <td>source</td>
- <td>
- <code>
- source:intact
- </code>
- </td>
- <td>
- Lists all entries containing a GO term whose annotation source is the
- IntAct database.
- </td>
- </tr>
- <tr>
- <td>strain</td>
- <td>
- <code>
- strain:wistar
- </code>
- </td>
- <td>
- Lists all entries containing a reference relevant to strain wistar.
- </td>
- </tr>
- <tr>
- <td>taxonomy</td>
- <td>
- <code>
- taxonomy:40674
- </code>
- </td>
- <td>
- Lists all entries for proteins expressed in Mammals. This field is used to retrieve
- entries for all organisms classified below a given taxonomic node taxonomy classification).
- </td>
- </tr>
- <tr>
- <td>tissue</td>
- <td>
- <code>
- tissue:liver
- </code>
- </td>
- <td>
- Lists all entries containing a reference describing the protein sequence
- obtained from a clone isolated from liver.
- </td>
- </tr>
- <tr>
- <td>web</td>
- <td>
- <code>
- web:wikipedia
- </code>
- </td>
- <td>
- Lists all entries for proteins that are described in Wikipedia.
- </td>
- </tr>
-</table>
+ <tr>
+ <td>plasmid</td>
+ <td><code> plasmid:ColE1 </code></td>
+ <td>Lists all entries for proteins encoded by a gene of
+ plasmid ColE1.</td>
+ </tr>
+ <tr>
+ <td>proteome</td>
+ <td><code> proteome:UP000005640 </code></td>
+ <td>Lists all entries from the human proteome.</td>
+ </tr>
+ <tr>
+ <td>proteomecomponent</td>
+ <td><code> proteomecomponent:"chromosome 1" and
+ organism:9606 </code></td>
+ <td>Lists all entries from the human chromosome 1.</td>
+ </tr>
+ <tr>
+ <td>replaces</td>
+ <td><code> replaces:P02023 </code></td>
+ <td>Lists all entries that were created from a merge with
+ entry P02023.</td>
+ </tr>
+ <tr>
+ <td>reviewed</td>
+ <td><code> reviewed:yes </code></td>
+ <td>Lists all UniProtKB/Swiss-Prot entries.</td>
+ </tr>
+ <tr>
+ <td>scope</td>
+ <td><code> scope:mutagenesis </code></td>
+ <td>Lists all entries containing a reference that was used to
+ gather information about mutagenesis.</td>
+ </tr>
+ <tr>
+ <td>sequence</td>
+ <td><code> sequence:P05067-9 </code></td>
+ <td>Lists all entries containing a link to isoform 9 of the
+ sequence described in entry P05067. Allows searching by specific
+ sequence identifier.</td>
+ </tr>
+ <tr>
+ <td>sequence_modified</td>
+ <td><code>
+ sequence_modified:[20120101 TO 20120301]<br /> reviewed:yes
+ AND sequence_modified:[current TO *]
+ </code></td>
+ <td>Lists all entries whose sequences were last modified
+ between January and March 2012.<br /> Lists all
+ UniProtKB/Swiss-Prot entries whose sequences were modified in
+ the last release.
+ </td>
+ </tr>
+ <tr>
+ <td>source</td>
+ <td><code> source:intact </code></td>
+ <td>Lists all entries containing a GO term whose annotation
+ source is the IntAct database.</td>
+ </tr>
+ <tr>
+ <td>strain</td>
+ <td><code> strain:wistar </code></td>
+ <td>Lists all entries containing a reference relevant to
+ strain wistar.</td>
+ </tr>
+ <tr>
+ <td>taxonomy</td>
+ <td><code> taxonomy:40674 </code></td>
+ <td>Lists all entries for proteins expressed in Mammals. This
+ field is used to retrieve entries for all organisms classified
+ below a given taxonomic node taxonomy classification).</td>
+ </tr>
+ <tr>
+ <td>tissue</td>
+ <td><code> tissue:liver </code></td>
+ <td>Lists all entries containing a reference describing the
+ protein sequence obtained from a clone isolated from liver.</td>
+ </tr>
+ <tr>
+ <td>web</td>
+ <td><code> web:wikipedia </code></td>
+ <td>Lists all entries for proteins that are described in
+ Wikipedia.</td>
+ </tr>
+ </table>
</body>
</html>
\ No newline at end of file
* The Jalview Authors are detailed in the 'AUTHORS' file.
-->
<head>
-<title>The Uniprot Free Text Search Interface</title>
+<title>The UniProt Free Text Search Interface</title>
</head>
<body>
- <strong>The Uniprot Free Text Search Interface</strong>
+ <strong>The UniProt Free Text Search Interface</strong>
+ <br /> Since version 2.10 (October 2016), the Jalview Desktop
+ provides a search interface for interactive discovery and retrieval of
+ sequence data from UniProt. This dialog enables UniProt sequence
+ metadata to be searched with free text and structured queries, which
+ allows sequences to be located via gene name, keywords, or even
+ <em>via</em> manual cross-referencing from UniProt or other
+ bioinformatics websites.
<p>
- Jalview provides a specialised interface that allows fast and
- efficient discovery and retrieval of data from the Uniprot database.
- It allows
- interactive querying of Uniprot metadata with free text and structured
- queries, so sequences can be located without prior knowledge of
- their database accessions, or <em>via</em> manual cross-referencing
- from Uniprot or other bioinformatics websites.
+ To open the UniProt Sequence Fetcher, select UniProt as the database
+ from any <a href="seqfetch.html">Sequence Fetcher</a> dialog (opened
+ <em>via</em> <strong>"File →Fetch
+ Sequences"</strong>).
</p>
<p>
- To open the UniProt Sequence Fetcher, select UniProt as the database from
- any <a href="seqfetch.html">Sequence Fetcher</a> dialog (opened <em>via</em>
- <strong>"File →Fetch Sequences"</strong>).
- </p>
- <p>
- <img src="uniprotseqfetcher.png" align="left"
- alt="Uniprot sequence fetcher (introduced in Jalview 2.9.1)"
- />
+ <img src="uniprotseqfetcher.png" align="left"
+ alt="UniProt sequence fetcher (introduced in Jalview 2.10)" />
</p>
<p>
- <strong>Searching the Uniprot Database</strong>
+ <strong>Searching the UniProt Database</strong>
</p>
<p>
- To search the Uniprot, begin typing in the text box. The results of your
- query are shown in the search results tab, which queries Uniprot after 1.5secs every time
- you type in the search text box. You can sort results according to
- the displayed columns, and select entries with the mouse or
- keyboard. Once you have selected one or more entries, hit the <strong>OK</strong>
- button to retrieve and visualise the sequences in Jalview Alignment interface.
+ To search UniProt, simply begin typing in the text box. After a
+ short delay (about 1.5 seconds), results will be shown in the table
+ below. You can sort results by clicking on the displayed columns,
+ and select entries with the mouse or keyboard. Once you have
+ selected one or more entries, hit the <strong>OK</strong> button to
+ retrieve the sequences.
</p>
<ul>
- <li><strong>Searching a specific Uniprot field </strong> If you
- want to find sequences based on a specific Uniprot metadata field,
- you can select it from the drop-down menu.</li>
-
+ <li><strong>Searching a specific UniProt field </strong> To
+ find sequences with particular UniProt metadata, you can select a
+ field to search from the drop-down menu.</li>
+
+
+ <li><strong>Bulk UniProt record retrieval</strong><br> To
+ retrieve several uniprot accessions at once, first select <strong>UniProt
+ ID</strong> from the dropdown menu, then paste in the accession IDs as a
+ semi-colon separated list. (e.g. fila_human; mnt_human;
+ mnt_mouse).<br />Hitting Return or OK will automatically fetch
+ those IDs, like the default Sequence Fetcher interface.</li>
- <li><strong>Bulk Uniprot retrieval</strong><br>
- Firstly, switch the search target to Uniprot Id, then enter multiple IDs by separating them with a semi-colon.
- e.g. fila_human; mnt_human; mnt_mouse.<br />Hitting Return or OK will automatically
- fetch those IDs, like the default Sequence Fetcher interface.</li>
-
- <li><strong>Advanced / Custom querying</strong>
- The table below provides a brief overview of the supported Uniprot query syntax (see <a href="uniprotqueryfields.html">query fields for UniProtKB</a>):
- <table border="1" width="95%">
- <tr>
- <td><code>human antigen</code></td>
- <td rowspan="3">All entries containing both terms.</td>
- </tr>
- <tr>
- <td><code>human AND antigen</code></td>
- </tr>
- <tr>
- <td><code>human && antigen</code></td>
- </tr>
- <tr>
- <td><code>"human antigen"</code></td>
- <td>All entries containing both terms in the exact order.</td>
- </tr>
- <tr>
- <td><code>human -antigen</code></td>
- <td rowspan="3">All entries containing the term <code>human</code>
- but not <code>antigen</code>.
- </td>
- </tr>
- <tr>
- <td><code>human NOT antigen</code></td>
- </tr>
- <tr>
- <td><code>human ! antigen</code></td>
- </tr>
- <tr>
- <td><code>human OR mouse</code></td>
- <td rowspan="2">All entries containing either term.</td>
- </tr>
- <tr>
- <td><code>human || mouse</code></td>
- </tr>
- <tr>
- <td><code>antigen AND (human OR mouse)</code></td>
- <td>Using parentheses to override boolean precedence rules.</td>
- </tr>
- <tr>
- <td><code>anti*</code></td>
- <td>All entries containing terms starting with <code>anti</code>.
- Asterisks can also be used at the beginning and within terms. <strong>Note:</strong>
- Terms starting with an asterisk or a single letter followed by an
- asterisk can slow down queries considerably.
- </td>
- </tr>
- <tr>
- <td><code> author:Tiger*</code></td>
- <td>Citations that have an author whose name starts with <code>Tiger</code>.
- To search in a specific field of a dataset, you must prefix your
- search term with the field name and a colon. To discover what
- fields can be queried explicitly, observe the query hints that are
- shown after submitting a query or use the query builder (see
- below).
- </td>
- </tr>
- <tr>
- <td><code>length:[100 TO *]</code></td>
- <td>All entries with a sequence of at least 100 amino acids.</td>
- </tr>
- <tr>
- <td><code>citation:(author:Arai author:Chung)</code></td>
- <td>All entries with a publication that was coauthored by two
- specific authors.</td>
- </tr>
- </table>
- </li>
-</ul>
+ <li><strong><a name="text-search">Complex queries
+ with the UniProt query Syntax</a></strong> The text box also allows complex
+ queries to be entered. The table below provides a brief overview
+ of the supported syntax (see <a href="uniprotqueryfields.html">query
+ fields for UniProtKB</a>):
+ <table border="1" width="95%">
+ <tr>
+ <td><code>human antigen</code></td>
+ <td rowspan="3">All entries containing both terms.</td>
+ </tr>
+ <tr>
+ <td><code>human AND antigen</code></td>
+ </tr>
+ <tr>
+ <td><code>human && antigen</code></td>
+ </tr>
+ <tr>
+ <td><code>"human antigen"</code></td>
+ <td>All entries containing both terms in the exact order.</td>
+ </tr>
+ <tr>
+ <td><code>human -antigen</code></td>
+ <td rowspan="3">All entries containing the term <code>human</code>
+ but not <code>antigen</code>.
+ </td>
+ </tr>
+ <tr>
+ <td><code>human NOT antigen</code></td>
+ </tr>
+ <tr>
+ <td><code>human ! antigen</code></td>
+ </tr>
+ <tr>
+ <td><code>human OR mouse</code></td>
+ <td rowspan="2">All entries containing either term.</td>
+ </tr>
+ <tr>
+ <td><code>human || mouse</code></td>
+ </tr>
+ <tr>
+ <td><code>antigen AND (human OR mouse)</code></td>
+ <td>Using parentheses to override boolean precedence
+ rules.</td>
+ </tr>
+ <tr>
+ <td><code>anti*</code></td>
+ <td>All entries containing terms starting with <code>anti</code>.
+ Asterisks can also be used at the beginning and within
+ terms. <strong>Note:</strong> Terms starting with an
+ asterisk or a single letter followed by an asterisk can slow
+ down queries considerably.
+ </td>
+ </tr>
+ <tr>
+ <td><code> author:Tiger*</code></td>
+ <td>Citations that have an author whose name starts with
+ <code>Tiger</code>. To search in a specific field of a
+ dataset, you must prefix your search term with the field
+ name and a colon. To discover what fields can be queried
+ explicitly, observe the query hints that are shown after
+ submitting a query or use the query builder (see below).
+ </td>
+ </tr>
+ <tr>
+ <td><code>length:[100 TO *]</code></td>
+ <td>All entries with a sequence of at least 100 amino
+ acids.</td>
+ </tr>
+ <tr>
+ <td><code>citation:(author:Arai author:Chung)</code></td>
+ <td>All entries with a publication that was coauthored by
+ two specific authors.</td>
+ </tr>
+ </table></li>
+ </ul>
<p>
<strong>Result pagination</strong>
</p>
- The query results returned from the Uniprot server are paginated for performance optimisation.
- The button labelled <strong>' << '</strong> and <strong>' >> '</strong> can be used to navigate to the next or previous result page respectively.
- The page range is shown on the title bar of the Free Text Search interface. Jalview's pagination implementation supports multiple selection of entries across multiple pages.
-
-
- <p>
- <strong>Customising The Uniprot Sequence Fetcher</strong>
- </p>
+ The query results returned from the UniProt server are paginated for
+ performance optimisation. The button labelled
+ <strong>' << '</strong> and
+ <strong>' >> '</strong> can be used to navigate to the
+ next or previous result page respectively. The page range is shown on
+ the title bar of the Free Text Search interface. Jalview's pagination
+ implementation supports multiple selection of entries across multiple
+ pages.
+
+
<p>
- To change the displayed meta-data in the search result, click the
- 'Customise Displayed Options' tab, and select the fields you'd like
- to displayed or remove.
+ <strong>Customising The UniProt Sequence Fetcher</strong>
</p>
+ <p>To change the displayed meta-data in the search result, click
+ the 'Customise Displayed Options' tab, and select the fields you'd
+ like to be displayed or removed.</p>
<p>
- <em>The Uniprot Free Test Search Interface was introduced in
- Jalview 2.9.1</em>
+ <em>The UniProt Free Test Search Interface was introduced in
+ Jalview 2.10.0</em>
</p>
</body>
</html>
\ No newline at end of file
<strong>The VARNA RNA Viewer</strong>
</p>
<p>
- <a href="http://varna.lri.fr/index.html">VARNA</a> was integrated
- into Jalview 2.8 to allow interactive viewing of RNA secondary
- structure annotation. It is opened by selecting the <strong>"Structure→View
+ <a href="http://varna.lri.fr">VARNA</a> was integrated into Jalview
+ 2.8 to allow interactive viewing of RNA secondary structure
+ annotation. It is opened by selecting the <strong>"Structure→View
Structure:"</strong> option in the <a href="../menus/popupMenu.html">sequence
id pop-up menu</a> (if you can't see this, then no RNA structure is
associated with your sequence or alignment). In the pop-up menu all
<p>
VARNA is a very powerful RNA viewer on its own. Only the essentials
have been described here - the interested reader is referred to <a
- href="http://varna.lri.fr/index.php?page=manual&css=varna"
- >VARNA's own comprehensive online documentation</a>.
+ href="http://varna.lri.fr/index.php?page=manual&css=varna">VARNA's
+ own comprehensive online documentation</a>.
</p>
</body>
</html>
</head>
<body>
<p>
- <strong>Viewing PDB Structures</strong>
+ <strong>Discovering and Viewing PDB Structures</strong>
</p>
- Jalview can be used to view protein structures by following the steps
- below:
+ Jalview can be used to explore the 3D structures of sequences in an
+ alignment by following the steps below:
<ol>
<li>Select the <strong>"3D Structure Data..."</strong> option
from a sequence's <a href="../menus/popupMenu.html">pop-up
pane.
</li>
<li>However, if no structure was found, the <a
- href="structurechooser.html"
- >Structure Chooser</a> interface will present options for manual
- association of PDB structures.
+ href="structurechooser.html">Structure Chooser</a> interface
+ will present options for manual association of PDB structures.
</li>
</ul>
</li>
- <li><strong>Selecting Structures</strong><br /> If structures
- have been discovered, then some will already be selected according
- to predefined selection criteria, such as structures with the
- highest resolution. Use the drop down menu to select structures
- according to different criteria, or, alternatively, choose
- structures manually by selecting with the keyboard and mouse.
+ <li><strong>Selecting Structures</strong><br />You can select
+ the structures that you want to open and view by selecting them
+ with the mouse and keyboard.<br />By default, if structures were
+ discovered, then some will already be selected according to the
+ criteria shown in the drop-down menu. The default criteria is
+ 'highest resolution', simply choose another to pick structures in
+ a different way.<br />
<ul>
- <li><strong>Viewing Cached Structures</strong><br />If you
- have previously downloaded structures for your sequences, they
- can be viewed by selecting the <strong>Cached PDB
- Entries</strong> option from the drop down menu at the top of the
- dialog box.</li>
+ <li><strong>Viewing Cached Structures</strong><br />If
+ previously downloaded structures are available for your
+ sequences, the structure chooser will automatically offer them
+ via the <strong>Cached PDB Entries</strong> view. If you wish
+ to download new structures, select one of the PDBe selection
+ criteria from the drop-down menu.</li>
+ </ul></li>
+ <li><strong>To view selected structures, click the <strong>"View"</strong>
+ button.
+ </strong><br />
+ <ul>
+ <li>Additional structure data will be downloaded with the
+ EMBL-EBI's dbfetch service</li>
+ <li><a href="siftsmapping.html">SIFTS</a> records will also
+ be downloaded for mapping UniProt protein sequence data to PDB
+ coordinates.</li>
+ <li>A new structure viewer will open, or you will be
+ prompted to add structures to existing viewers (see <a
+ href="#afterviewbutton">below</a> for details).
+ </li>
</ul></li>
- <li>To view selected structures, click the <strong>"View"</strong>
- button.
- </li>
</ol>
-
+ <p>
+ <strong>Structure Viewers in the Jalview Desktop</strong><br/>
The
<a href="jmol.html">Jmol viewer</a> has been included since Jalview
2.3. Jalview 2.8.2 included support for
the <a href="xsspannotation.html">Annotation from Structure</a> page
for more information.
</p>
-
<p>
- If a <strong>single</strong> PDB structure is selected, one of the
- following will happen:
+ <strong><a name="afterviewbutton">After pressing the
+ 'View' button in the Structure Chooser</a></strong><br /> The behaviour of
+ the 'View' button depends on the number of structures selected, and
+ whether structure views already exist for the selected structures or
+ aligned sequences.
+ </p>
+ <p>
+ If multiple structures are selected, then Jalview will always create
+ a new structure view. The selected structures will be imported into
+ this view, and superposed with the matched positions from the
+ aligned sequences.<br /> If a <strong>single</strong> PDB structure
+ is selected, one of the following will happen:
</p>
<ul>
<li>If another structure is already shown for the current
alignment, then you will be asked if you want to add and <a
- href="jmol.html#align"
- >align this structure</a> to the structure in the existing view. (<em>new
- feature in Jalview 2.6</em>).
- </li>
+ href="jmol.html#align"></a> to
+ the structure in the existing view. (<em>new feature in Jalview
+ 2.6</em>).
+ </li>
<li>If the structure is already shown, then you will be
prompted to associate the sequence with an existing view of the
<p>
- <strong>Importing PDB Entries or files in PDB format</strong><br>
- You can retrieve sequences from the PDB using the <a
- href="pdbsequencefetcher.html"
- >Sequence Fetcher</a>. Any sequences retrieved with this service are
- automatically associated with their source database entry. For PDB
- sequences, simply select PDB as the database and enter your known
- PDB id (appended with ':' and a chain code, if desired).<br>
- Jalview will also read PDB files directly. Simply load in the file
+ <strong>Retrieving sequences from the PDB</strong><br>You can
+ retrieve sequences from the PDB using the <a
+ href="pdbsequencefetcher.html">Sequence Fetcher</a>. The sequences
+ retrieved with this service are derived directly from the PDB 3D
+ structure data, which can be viewed in the same way above. Secondary
+ structure and temperature factor annotation can also be added. <br />
+
+ <br>Jalview will also read PDB files directly - either in PDB
+ format, or <a href="mmcif.html">mmCIF</a>. Simply load in the file
as you would an alignment file. The sequences of any protein or
nucleotide chains will be extracted from the file and viewed in the
alignment window.
</p>
<p>
- <strong>Importing PDB Entries or files in mmCIF format</strong><br>
- <a href="mmcif.html">mmCIF file format</a> provides an alternative means for
- importing 3D structure data from flat file and EMBL-PDBe
- web-service. To enable mmCIF as the default format for
- importing PBD sequences from the PDB sequence fetcher, add or modify the
- property
- <code>DEFAULT_STRUCTURE_FORMAT=mmCIF</code> in Jalview properties file.
- Once this is done, the steps followed in retrieving PDB format files above can
- be followed to obtain the same data with mmCIF. <em>mmCIF format file support was added in Jalview 2.9.1.</em></p>
-
-
-
- <p>
<strong>Associating a large number of PDB files to
sequences in an alignment</strong><br /> It is often the case when working
with structure alignments that you will have a directory of PDB
desktop, Jalview will give you the option of associating PDB files
with sequences that have the same filename. This means, for example,
you can automatically associate PDB files with names like '1gaq.pdb'
- with sequences that have an ID like '1gaq'. <br />
- <em>Note: This feature was added in Jalview 2.7</em>
+ with sequences that have an ID like '1gaq'. <br /> <em>Note:
+ This feature was added in Jalview 2.7</em>
</p>
<p>
<em>Note for Jalview applet users:<br> Due to the applet
Features"</strong> menu item and the <a href="featuresettings.html">Feature
Settings dialog box</a>.
</p>
+ <br />
+ <hr>
+ <p>
+ <strong>Switching between mmCIF and PDB format for
+ downloading files from the PDB</strong><br /> Jalview now employs the <a
+ href="mmcif.html">mmCIF format</a> for importing 3D structure data
+ from flat file and EMBL-PDBe web-service, as recommended by the
+ wwwPDB. If you prefer (for any reason) to download data as PDB files
+ instead, then first close Jalview, and add the following line to
+ your .jalview_properties file:<br />
+ <code> PDB_DOWNLOAD_FORMAT=PDB </code>
+ <br /> When this setting is configured, Jalview will only request
+ PDB format files from EMBL-EBI's PDBe.<br /> <em>mmCIF format
+ file support was added in Jalview 2.10.</em>
+ </p>
<p>
<em><strong>Outstanding problem with cut'n'pasted
- files in Jalview 2.6 and Jalview 2.7</strong><br> Structures
- imported via the cut'n'paste dialog box will not be correctly
- highlighted or coloured when they are displayed in structure
- views, especially if they contain more than one PDB structure. See
- the bug report at http://issues.jalview.org/browse/JAL-623 for
- news on this problem.</em>
+ files in Jalview 2.6 and Jalview 2.7</strong><br>Structures imported
+ via the cut'n'paste dialog box will not be correctly highlighted
+ or coloured when they are displayed in structure views, especially
+ if they contain more than one PDB structure. See the bug report at
+ http://issues.jalview.org/browse/JAL-623 for news on this problem.</em>
</p>
+
</body>
</html>
tab in the <strong>Tools→Preferences</strong> dialog allow the
processing of structure data to be disabled, or selectively enabled.
For more information, take a look at the <a
- href="preferences.html#structure"
- >documentation for the structure panel</a>.
+ href="preferences.html#structure">documentation for the
+ structure panel</a>.
</p>
<p>
<em>The display of secondary structure data was introduced in
Jalview 2.8.2, and is made possible by Jalview's use of <a
- href="jmol.html"
- >Jmol's DSSP implementation</a>, based on the original <a
- href="http://www.ncbi.nlm.nih.gov/pubmed/6667333"
- >Kabsch and Sander algorithm</a> ported by <a
- href="http://swift.cmbi.ru.nl/gv/dssp/"
- >Robbie P. Joosten and colleagues</a>, and a client for <a
- href="https://github.com/fjossinet/PyRNA"
- >Fabrice Jossinet's pyRNA services</a> that was developed by Anne
- Menard, Jim Procter and Yann Ponty as part of the Jalview Summer
- of Code 2012.
+ href="jmol.html">Jmol's DSSP implementation</a>, based on the
+ original <a href="http://www.ncbi.nlm.nih.gov/pubmed/6667333">Kabsch
+ and Sander algorithm</a> ported by <a
+ href="http://swift.cmbi.ru.nl/gv/dssp/">Robbie P. Joosten
+ and colleagues</a>, and a client for <a
+ href="https://github.com/fjossinet/PyRNA">Fabrice
+ Jossinet's pyRNA services</a> that was developed by Anne Menard, Jim
+ Procter and Yann Ponty as part of the Jalview Summer of Code 2012.
</em>
</p>
</body>
--- /dev/null
+<html>
+<!--
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ -->
+<head>
+<title>Extending Jalview with Groovy - Feature Counter Example</title>
+</head>
+<body>
+ <p>
+ <strong>Extending Jalview with Groovy - A customisable
+ feature counter</strong><br /> <br />The groovy script below shows how to
+ add a new calculation track to a Jalview alignment window.
+ </p>
+ <p>As currently written, it will add two tracks to a protein
+ alignment view which count Pfam features in each column, and ones
+ where a charge residue also occur.</p>
+ <p>To try it for yourself:</p>
+ <ol>
+ <li>Copy and paste it into the groovy script console</li>
+ <li>Load the example Feredoxin project (the one that opens by
+ default when you first launched Jalview)</li>
+ <li>Select <strong>Calculations→Execute Groovy
+ Script</strong> from the alignment window's menu bar to run the script on
+ the current view.
+ </li>
+ </ol>
+ <em><a
+ href="http://www.jalview.org/examples/groovy/featureCounter.groovy">http://www.jalview.org/examples/groovy/featureCounter.groovy</a>
+ - rendered with <a href="http://hilite.me">hilite.me</a></em>
+ <!-- HTML generated using hilite.me -->
+ <div
+ style="background: #ffffff; overflow: auto; width: auto; border: solid gray; border-width: .1em .1em .1em .8em; padding: .2em .6em;">
+ <pre style="margin: 0; line-height: 125%">
+<span style="color: #888888">/*</span>
+<span style="color: #888888"> * Jalview - A Sequence Alignment Editor and Viewer (Version 2.10)</span>
+<span style="color: #888888"> * Copyright (C) 2016 The Jalview Authors</span>
+<span style="color: #888888"> * </span>
+<span style="color: #888888"> * This file is part of Jalview.</span>
+<span style="color: #888888"> * </span>
+<span style="color: #888888"> * Jalview is free software: you can redistribute it and/or</span>
+<span style="color: #888888"> * modify it under the terms of the GNU General Public License </span>
+<span style="color: #888888"> * as published by the Free Software Foundation, either version 3</span>
+<span style="color: #888888"> * of the License, or (at your option) any later version.</span>
+<span style="color: #888888"> * </span>
+<span style="color: #888888"> * Jalview is distributed in the hope that it will be useful, but </span>
+<span style="color: #888888"> * WITHOUT ANY WARRANTY; without even the implied warranty </span>
+<span style="color: #888888"> * of MERCHANTABILITY or FITNESS FOR A PARTICULAR </span>
+<span style="color: #888888"> * PURPOSE. See the GNU General Public License for more details.</span>
+<span style="color: #888888"> * </span>
+<span style="color: #888888"> * You should have received a copy of the GNU General Public License</span>
+<span style="color: #888888"> * along with Jalview. If not, see <http://www.gnu.org/licenses/>.</span>
+<span style="color: #888888"> * The Jalview Authors are detailed in the 'AUTHORS' file.</span>
+<span style="color: #888888"> */</span>
+
+<span style="color: #008800; font-weight: bold">import</span> <span
+ style="color: #0e84b5; font-weight: bold">jalview.workers.FeatureCounterI</span><span
+ style="color: #333333">;</span>
+<span style="color: #008800; font-weight: bold">import</span> <span
+ style="color: #0e84b5; font-weight: bold">jalview.workers.AlignmentAnnotationFactory</span><span
+ style="color: #333333">;</span>
+
+<span style="color: #888888">/*</span>
+<span style="color: #888888"> * Example script that registers two alignment annotation calculators</span>
+<span style="color: #888888"> * - one that counts residues in a column with Pfam annotation</span>
+<span style="color: #888888"> * - one that counts only charged residues with Pfam annotation</span>
+<span style="color: #888888"> *</span>
+<span style="color: #888888"> * To try:</span>
+<span style="color: #888888"> * 1. load uniref50.fa from the examples folder</span>
+<span style="color: #888888"> * 2. load features onto it from from examples/exampleFeatures.txt</span>
+<span style="color: #888888"> * 3. Open this script in the Groovy console.</span>
+<span style="color: #888888"> * 4. Either execute this script from the console, or via Calculate->Run Groovy Script</span>
+<span style="color: #888888"> </span>
+<span style="color: #888888"> * To explore further, try changing this script to count other kinds of occurrences of </span>
+<span style="color: #888888"> * residue and sequence features at columns in an alignment.</span>
+<span style="color: #888888"> */</span>
+
+<span style="color: #888888">/*</span>
+<span style="color: #888888"> * A closure that returns true for any Charged residue</span>
+<span style="color: #888888"> */</span>
+<span style="color: #333399; font-weight: bold">def</span> isCharged <span
+ style="color: #333333">=</span> <span style="color: #333333">{</span> residue <span
+ style="color: #333333">-></span>
+ <span style="color: #008800; font-weight: bold">switch</span><span
+ style="color: #333333">(</span>residue<span
+ style="color: #333333">)</span> <span style="color: #333333">{</span>
+ <span style="color: #008800; font-weight: bold">case</span> <span
+ style="color: #333333">[</span><span
+ style="background-color: #fff0f0">'D'</span><span
+ style="color: #333333">,</span> <span
+ style="background-color: #fff0f0">'d'</span><span
+ style="color: #333333">,</span> <span
+ style="background-color: #fff0f0">'E'</span><span
+ style="color: #333333">,</span> <span
+ style="background-color: #fff0f0">'e'</span><span
+ style="color: #333333">,</span> <span
+ style="background-color: #fff0f0">'H'</span><span
+ style="color: #333333">,</span> <span
+ style="background-color: #fff0f0">'h'</span><span
+ style="color: #333333">,</span> <span
+ style="background-color: #fff0f0">'K'</span><span
+ style="color: #333333">,</span> <span
+ style="background-color: #fff0f0">'k'</span><span
+ style="color: #333333">,</span> <span
+ style="background-color: #fff0f0">'R'</span><span
+ style="color: #333333">,</span> <span
+ style="background-color: #fff0f0">'r'</span><span
+ style="color: #333333">]:</span>
+ <span style="color: #008800; font-weight: bold">return</span> <span
+ style="color: #008800; font-weight: bold">true</span>
+ <span style="color: #333333">}</span>
+ <span style="color: #008800; font-weight: bold">false</span>
+<span style="color: #333333">}</span>
+
+<span style="color: #888888">/*</span>
+<span style="color: #888888"> * A closure that returns 1 if sequence features include type 'Pfam', else 0</span>
+<span style="color: #888888"> * Argument should be a list of SequenceFeature </span>
+<span style="color: #888888"> */</span>
+<span style="color: #333399; font-weight: bold">def</span> hasPfam <span
+ style="color: #333333">=</span> <span style="color: #333333">{</span> features <span
+ style="color: #333333">-></span>
+ <span style="color: #008800; font-weight: bold">for</span> <span
+ style="color: #333333">(</span>sf <span
+ style="color: #008800; font-weight: bold">in</span> features<span
+ style="color: #333333">)</span>
+ <span style="color: #333333">{</span>
+ <span style="color: #888888">/*</span>
+<span style="color: #888888"> * Here we inspect the type of the sequence feature.</span>
+<span style="color: #888888"> * You can also test sf.description, sf.score, sf.featureGroup,</span>
+<span style="color: #888888"> * sf.strand, sf.phase, sf.begin, sf.end</span>
+<span style="color: #888888"> * or sf.getValue(attributeName) for GFF 'column 9' properties</span>
+<span style="color: #888888"> */</span>
+ <span style="color: #008800; font-weight: bold">if</span> <span
+ style="color: #333333">(</span><span
+ style="background-color: #fff0f0">"Pfam"</span><span
+ style="color: #333333">.</span><span style="color: #0000CC">equals</span><span
+ style="color: #333333">(</span>sf<span style="color: #333333">.</span><span
+ style="color: #0000CC">type</span><span style="color: #333333">))</span>
+ <span style="color: #333333">{</span>
+ <span style="color: #008800; font-weight: bold">return</span> <span
+ style="color: #008800; font-weight: bold">true</span>
+ <span style="color: #333333">}</span>
+ <span style="color: #333333">}</span>
+ <span style="color: #008800; font-weight: bold">false</span>
+<span style="color: #333333">}</span>
+
+<span style="color: #888888">/*</span>
+<span style="color: #888888"> * Closure that computes an annotation based on </span>
+<span style="color: #888888"> * presence of particular residues and features</span>
+<span style="color: #888888"> * Parameters are</span>
+<span style="color: #888888"> * - the name (label) for the alignment annotation</span>
+<span style="color: #888888"> * - the description (tooltip) for the annotation</span>
+<span style="color: #888888"> * - a closure (groovy function) that tests whether to include a residue</span>
+<span style="color: #888888"> * - a closure that tests whether to increment count based on sequence features </span>
+<span style="color: #888888"> */</span>
+<span style="color: #333399; font-weight: bold">def</span> getColumnCounter <span
+ style="color: #333333">=</span> <span style="color: #333333">{</span> name<span
+ style="color: #333333">,</span> desc<span style="color: #333333">,</span> acceptResidue<span
+ style="color: #333333">,</span> acceptFeatures <span
+ style="color: #333333">-></span>
+ <span style="color: #333333">[</span>
+ <span style="color: #997700; font-weight: bold">getName:</span> <span
+ style="color: #333333">{</span> name <span
+ style="color: #333333">},</span>
+ <span style="color: #997700; font-weight: bold">getDescription:</span> <span
+ style="color: #333333">{</span> desc <span
+ style="color: #333333">},</span>
+ <span style="color: #997700; font-weight: bold">getMinColour:</span> <span
+ style="color: #333333">{</span> <span style="color: #333333">[</span><span
+ style="color: #0000DD; font-weight: bold">0</span><span
+ style="color: #333333">,</span> <span
+ style="color: #0000DD; font-weight: bold">255</span><span
+ style="color: #333333">,</span> <span
+ style="color: #0000DD; font-weight: bold">255</span><span
+ style="color: #333333">]</span> <span style="color: #333333">},</span> <span
+ style="color: #888888">// cyan</span>
+ <span style="color: #997700; font-weight: bold">getMaxColour:</span> <span
+ style="color: #333333">{</span> <span style="color: #333333">[</span><span
+ style="color: #0000DD; font-weight: bold">0</span><span
+ style="color: #333333">,</span> <span
+ style="color: #0000DD; font-weight: bold">0</span><span
+ style="color: #333333">,</span> <span
+ style="color: #0000DD; font-weight: bold">255</span><span
+ style="color: #333333">]</span> <span style="color: #333333">},</span> <span
+ style="color: #888888">// blue</span>
+ <span style="color: #997700; font-weight: bold">count:</span>
+ <span style="color: #333333">{</span> res<span
+ style="color: #333333">,</span> feats <span
+ style="color: #333333">-></span>
+ <span style="color: #333399; font-weight: bold">def</span> c <span
+ style="color: #333333">=</span> <span
+ style="color: #0000DD; font-weight: bold">0</span>
+ <span style="color: #008800; font-weight: bold">if</span> <span
+ style="color: #333333">(</span>acceptResidue<span
+ style="color: #333333">.</span><span style="color: #0000CC">call</span><span
+ style="color: #333333">(</span>res<span style="color: #333333">))</span>
+ <span style="color: #333333">{</span>
+ <span style="color: #008800; font-weight: bold">if</span> <span
+ style="color: #333333">(</span>acceptFeatures<span
+ style="color: #333333">.</span><span style="color: #0000CC">call</span><span
+ style="color: #333333">(</span>feats<span style="color: #333333">))</span>
+ <span style="color: #333333">{</span>
+ c<span style="color: #333333">++</span>
+ <span style="color: #333333">}</span>
+ <span style="color: #333333">}</span>
+ c
+ <span style="color: #333333">}</span>
+ <span style="color: #333333">]</span> <span
+ style="color: #008800; font-weight: bold">as</span> FeatureCounterI
+<span style="color: #333333">}</span>
+
+<span style="color: #888888">/*</span>
+<span style="color: #888888"> * Define an annotation row that counts any residue with Pfam domain annotation</span>
+<span style="color: #888888"> */</span>
+<span style="color: #333399; font-weight: bold">def</span> pfamAnnotation <span
+ style="color: #333333">=</span> getColumnCounter<span
+ style="color: #333333">(</span><span
+ style="background-color: #fff0f0">"Pfam"</span><span
+ style="color: #333333">,</span> <span
+ style="background-color: #fff0f0">"Count of residues with Pfam domain annotation"</span><span
+ style="color: #333333">,</span> <span style="color: #333333">{</span><span
+ style="color: #008800; font-weight: bold">true</span><span
+ style="color: #333333">},</span> hasPfam<span
+ style="color: #333333">)</span>
+
+<span style="color: #888888">/*</span>
+<span style="color: #888888"> * Define an annotation row that counts charged residues with Pfam domain annotation</span>
+<span style="color: #888888"> */</span>
+<span style="color: #333399; font-weight: bold">def</span> chargedPfamAnnotation <span
+ style="color: #333333">=</span> getColumnCounter<span
+ style="color: #333333">(</span><span
+ style="background-color: #fff0f0">"Pfam charged"</span><span
+ style="color: #333333">,</span> <span
+ style="background-color: #fff0f0">"Count of charged residues with Pfam domain annotation"</span><span
+ style="color: #333333">,</span> isCharged<span
+ style="color: #333333">,</span> hasPfam<span
+ style="color: #333333">)</span>
+
+<span style="color: #888888">/*</span>
+<span style="color: #888888"> * Register the annotations</span>
+<span style="color: #888888"> */</span>
+AlignmentAnnotationFactory<span style="color: #333333">.</span><span
+ style="color: #0000CC">newCalculator</span><span
+ style="color: #333333">(</span>pfamAnnotation<span
+ style="color: #333333">)</span>
+AlignmentAnnotationFactory<span style="color: #333333">.</span><span
+ style="color: #0000CC">newCalculator</span><span
+ style="color: #333333">(</span>chargedPfamAnnotation<span
+ style="color: #333333">)</span>
+</pre>
+ </div>
+</body>
+</html>
<p>
For more information, you might also want to take a look at the
documentation section of the Jalview website (<a
- href="http://www-test.jalview.org/about/documentation"
- >http://www.jalview.org/about/documentation</a>).
+ href="http://www-test.jalview.org/about/documentation">http://www.jalview.org/about/documentation</a>).
</p>
<p>
If you are using the Jalview Desktop application and are looking for
google the online version of these pages. If you don't find what you
are looking for, or want to report a bug or make a feature request,
then get in contact over at <a
- href="http://www.jalview.org/community"
- >http://www.jalview.org/community</a>
+ href="http://www.jalview.org/community">http://www.jalview.org/community</a>
</p>
<p>
<strong>25</strong> (9) 1189-1191 doi: 10.1093/bioinformatics/btp033
</p>
<p>
- <strong>The Jalview Authors</strong><br /> The following people have
- contributed to Jalview's development:
+ <strong>The Jalview Authors</strong><br /> The following people
+ have contributed to Jalview's development:
<ul>
<li>Jalview 1
<ul>
<body>
<p>
<strong>Exporting alignments as graphics and lineart<a
- name="export"
- ></a></strong>
+ name="export"></a></strong>
</p>
<p>
The alignment view can be printed using <strong>File→Print</strong>,
menu</a>.
</p>
<img src="seqreport.gif"
- alt="Sequence Annotation is displayed as HTML in a report window"
- />
+ alt="Sequence Annotation is displayed as HTML in a report window" />
<p>
<strong>Copying and pasting annotation to other programs</strong><br>
The <strong>File→Save</strong> option in the sequence
<tr>
<td width="17%">JSON</td>
<td width="60%">Data starts with '{' <br>Data ends with
- '}' <br>
- <br>See <a href="../features/bioJsonFormat.html">BioJSON</a>
- for more infomation about the Jalview JSON format <br></td>
+ '}' <br> <br>See <a
+ href="../features/bioJsonFormat.html">BioJSON</a> for more
+ infomation about the Jalview JSON format <br></td>
<td width="23%">.json</td>
</tr>
NBRF/PIR (including MODELLER variant), Pfam/Stockholm</em>
</p>
<p>
- The EBI has <a href="http://www.ebi.ac.uk/help/formats.html">examples</a>
- of these file formats.
- </p>
- <p>
Additionally, whole sets of coloured and annotated alignments and
trees can be read from a <a href="../features/jalarchive.html">Jalview
(jar) format</a> file using <strong>Desktop→Load
</p>
<p>
Jalview can also read Jalview specific files for <a
- href="../features/featuresFormat.html"
- >sequence features</a> and <a
- href="../features/annotationsFormat.html"
- >alignment annotation</a>.
+ href="../features/featuresFormat.html">sequence features</a>
+ and <a href="../features/annotationsFormat.html">alignment
+ annotation</a>.
</p>
<p>
<strong>Output</strong>
</p>
<p>
The homology modelling program, <a
- href="http://salilab.org/modeller/"
- >Modeller</a> uses a special form of the PIR format where information
- about sequence numbering and chain codes are written into the
- 'description' line between the PIR protein tag and the protein
- alignment entry:
+ href="http://salilab.org/modeller/">Modeller</a> uses a
+ special form of the PIR format where information about sequence
+ numbering and chain codes are written into the 'description' line
+ between the PIR protein tag and the protein alignment entry:
</p>
<pre>>P1;Q93Z60_ARATH
sequence:Q93Z60_ARATH:1:.:118:.:.
no information is lost if this parsing process fails.</p>
<p>
The 'Modeller Output' flag in the 'Output' tab of the Jalview <a
- href="../features/preferences.html"
- >Preferences dialog box</a> controls whether Jalview will also output
- MODELLER style PIR files. In this case, any existing 'non-modeller
- PIR' header information in the description string of an alignment is
- appended to an automatically generated modeller description line for
- that sequence.
+ href="../features/preferences.html">Preferences dialog
+ box</a> controls whether Jalview will also output MODELLER style PIR
+ files. In this case, any existing 'non-modeller PIR' header
+ information in the description string of an alignment is appended to
+ an automatically generated modeller description line for that
+ sequence.
</p>
<p>The general format used for generating the Modeller/PIR
sequence description line is shown below :
T-COFFEE score files like the <a href="#tcoffeeeg">one below</a> can
be displayed on the alignment using the <strong><em>Colours→T-COFFEE
Scores</em></strong> or <strong><em>Colour → <a
- href="../colourSchemes/annotationColouring.html"
- >Colour by Annotation</a></em></strong> options.
+ href="../colourSchemes/annotationColouring.html">Colour
+ by Annotation</a></em></strong> options.
</p>
<img src="../colourSchemes/colbytcoffee.png" />
<p>
Jalview has two distinct modes of keyboard operation - in 'Normal'
mode, single keystrokes (including those shown next to menu items)
provide short cuts to common commands. In <a
- href="features/cursorMode.html"
- >'Cursor'</a> mode (enabled by <em>F2</em>), some of these are
- disabled and more complex 'Compound Keystrokes' can be entered to
- perform precise navigation, selection and editing operations.
+ href="features/cursorMode.html">'Cursor'</a> mode (enabled by
+ <em>F2</em>), some of these are disabled and more complex 'Compound
+ Keystrokes' can be entered to perform precise navigation, selection
+ and editing operations.
</p>
<table border="1">
<tr>
<td>Cursor</td>
<td>Move cursor to a particular column (<strong><em>p1</em></strong>)
and row (<strong><em>p2</em></strong>) in the alignment.<br>
- <em>e.g. '5,6<Return>' moves the cursor to the 5th
+ <em>e.g. '5,6<Return>' moves the cursor to the 5th
column in the 6th sequence.</em></td>
</tr>
<tr>
<td><strong><em>[p]</em><br>Space</strong></td>
<td>Cursor</td>
<td>Inserts one (or optionally <strong><em>p</em></strong>)
- gaps at the current position.<br>
- <em>Hold down Control or Shift to insert gaps over a sequence
- group</em></td>
+ gaps at the current position.<br> <em>Hold down
+ Control or Shift to insert gaps over a sequence group</em></td>
</tr>
<tr>
<td><strong><em>[p]</em><br>Delete<br></strong></td>
<td>Cursor</td>
<td>Removes one (or optionally <strong><em>p</em></strong>)
- gaps at the cursor position.<br>
- <em>Hold down Control or Shift to insert gaps over a sequence
- group</em></td>
+ gaps at the cursor position.<br> <em>Hold down Control
+ or Shift to insert gaps over a sequence group</em></td>
</tr>
<tr>
<td><strong><em>[p]</em><br>Backspace<br></strong></td>
<td>Cursor</td>
<td>Removes one (or optionally <strong><em>p</em></strong>)
- gaps at the cursor position.<br>
- <em>Hold down Control or Shift to insert gaps over a sequence
- group</em></td>
+ gaps at the cursor position.<br> <em>Hold down Control
+ or Shift to insert gaps over a sequence group</em></td>
</tr>
</table>
<p> </p>
file. You can obtain a JNLP file with modified memory settings
from our service with the following link (replace 2G with
desired memory in G or M):<br /> <a
- href="http://www.jalview.org/services/launchApp?jvm-max-heap=2G"
- >http://www.jalview.org/services/launchApp?jvm-max-heap=2G</a>
+ href="http://www.jalview.org/services/launchApp?jvm-max-heap=2G">http://www.jalview.org/services/launchApp?jvm-max-heap=2G</a>
</p>
<p>
Alternatively, if you want to create your own JNLP file then
please download the latest JNLP file from <a
- href="http://www.jalview.org/webstart/jalview.jnlp"
- >http://www.jalview.org/webstart/jalview.jnlp</a> and modify the
- max-heap-size parameter for the j2se tag in the
+ href="http://www.jalview.org/webstart/jalview.jnlp">http://www.jalview.org/webstart/jalview.jnlp</a>
+ and modify the max-heap-size parameter for the j2se tag in the
<resources> element. e.g.
<pre>
<j2se version="1.7+" initial-heap-size="500M" max-heap-size="1000M"/>
The lines you need to change are in the <em>Info.plist</em>
file inside the <em>Jalview.app/Contents</em> directory
(which is where the installAnywhere installation was made) :
+
<pre>
<key&ht;VMOptions</key&ht;
<ul>
<li><strong>Fetch Sequence</strong><br> <em>Shows
a dialog window in which you can retrieve known ids from
- Uniprot, EMBL, EMBLCDS, PFAM, Rfam, or PDB database using
+ UniProt, EMBL, EMBLCDS, PFAM, Rfam, or PDB database using
Web Services provided by the European Bioinformatics
Institute. See <a href="../features/seqfetch.html">Sequence
Fetcher</a>
</em></li>
<li><strong>Load Features / Annotations<br>
</strong><em>Load files describing precalculated <a
- href="../features/featuresFormat.html"
- >sequence features</a> or <a
- href="../features/annotationsFormat.html"
- >alignment annotations</a>.
+ href="../features/featuresFormat.html">sequence
+ features</a> or <a href="../features/annotationsFormat.html">alignment
+ annotations</a>.
</em></li>
<li><strong>Close (Control W)</strong><br> <em>Close
the alignment window. Make sure you have saved your
</strong><em>All columns which only contain gap characters
("-", ".") will be deleted.<br> You
may set the default gap character in <a
- href="../features/preferences.html"
- >preferences</a>.
+ href="../features/preferences.html">preferences</a>.
</em></li>
<li><strong>Remove All Gaps (Control Shift E)</strong><br>
<em>Gap characters ("-", ".") will be
deleted from the selected area of the alignment. If no
selection is made, ALL the gaps in the alignment will be
removed.<br> You may set the default gap character in <a
- href="../features/preferences.html"
- >preferences</a>.
+ href="../features/preferences.html">preferences</a>.
</em></li>
<li><strong>Remove Redundancy (Control D)<br>
</strong><em>Selecting this option brings up a window asking you to
with alignment analysis programs which require 'properly
aligned sequences' to be all the same length.<br> You
may set the default for <strong>Pad Gaps</strong> in the <a
- href="../features/preferences.html"
- >preferences</a>.
+ href="../features/preferences.html">preferences</a>.
</em></li>
</ul></li>
<li><strong>Select</strong>
<strong>WARNING</strong>: This cannot be undone.
</em></li>
<li><strong><a
- href="../features/columnFilterByAnnotation.html"
- >Select/Hide Columns by Annotation</a></strong> <br /> <em>Select
- or Hide columns in the alignment according to secondary
- structure, labels and values shown in alignment annotation
- rows. </em></li>
+ href="../features/columnFilterByAnnotation.html">Select/Hide
+ Columns by Annotation</a></strong> <br /> <em>Select or Hide
+ columns in the alignment according to secondary structure,
+ labels and values shown in alignment annotation rows. </em></li>
</ul></li>
<li><strong>View</strong>
<ul>
<li><strong>Show Sequence Features</strong><br> <em>Show
or hide sequence features on this alignment.</em></li>
<li><strong><a
- href="../features/featuresettings.html"
- >Sequence Feature Settings...</a> </strong><em><br> <em>Opens
- the Sequence Feature Settings dialog box to control the
- colour and display of sequence features on the alignment,
- and configure and retrieve features from DAS annotation
+ href="../features/featuresettings.html">Sequence
+ Feature Settings...</a> </strong><em><br> <em>Opens the
+ Sequence Feature Settings dialog box to control the colour
+ and display of sequence features on the alignment, and
+ configure and retrieve features from DAS annotation
servers.</em></li>
<li><strong>Sequence ID Tooltip</strong><em>
(application only) <br>This submenu's options allow the
rendering. </em></li>
<li><strong>Wrap<br>
</strong><em>When ticked, the alignment display is "<a
- href="../features/wrap.html"
- >wrapped</a>" to the width of the alignment window. This is
- useful if your alignment has only a few sequences to view
- its full width at once.
+ href="../features/wrap.html">wrapped</a>" to
+ the width of the alignment window. This is useful if your
+ alignment has only a few sequences to view its full width at
+ once.
</em><br> Additional options for display of sequence numbering
and scales are also visible in wrapped layout mode:<br>
<ul>
- <li><strong>Scale Above</strong><br>
- <em> Show the alignment column position scale.</em></li>
- <li><strong>Scale Left</strong><br>
- <em> Show the sequence position for the first aligned
- residue in each row in the left column of the alignment.</em></li>
- <li><strong>Scale Right</strong><br>
- <em> Show the sequence position for the last aligned
- residue in each row in the right-most column of the
- alignment.</em></li>
+ <li><strong>Scale Above</strong><br> <em>
+ Show the alignment column position scale.</em></li>
+ <li><strong>Scale Left</strong><br> <em> Show
+ the sequence position for the first aligned residue in
+ each row in the left column of the alignment.</em></li>
+ <li><strong>Scale Right</strong><br> <em>
+ Show the sequence position for the last aligned residue
+ in each row in the right-most column of the alignment.</em></li>
<li><strong>Show Sequence Limits<br>
</strong><em>If this box is selected the sequence name will have
the start and end position of the sequence appended to
colour will be applied to all currently defined groups.<br>
</em></li>
<li><strong><a
- href="../colourSchemes/textcolour.html"
- >Colour Text...</a> </strong><em><br> Opens the Colour Text
- dialog box to set a different text colour for light and dark
- background, and the intensity threshold for transition between
- them. </em></li>
+ href="../colourSchemes/textcolour.html">Colour
+ Text...</a> </strong><em><br> Opens the Colour Text dialog box
+ to set a different text colour for light and dark background,
+ and the intensity threshold for transition between them. </em></li>
<li>Colour Scheme options: <strong>None, ClustalX,
Blosum62 Score, Percentage Identity, Zappo, Taylor,
Hydrophobicity, Helix Propensity, Strand Propensity, Turn
<li><strong>By Annotation</strong><br> <em>Colours
the alignment on a per-column value from a specified
annotation. See <a
- href="../colourSchemes/annotationColouring.html"
- >Annotation Colouring</a>.
+ href="../colourSchemes/annotationColouring.html">Annotation
+ Colouring</a>.
</em><br></li>
<li><strong>By RNA Helices</strong><br> <em>Colours
the helices of an RNA alignment loaded from a Stockholm file.
provided in this menu.</strong></li>
<li><strong>Pairwise Alignments</strong><br> <em>Applies
Smith and Waterman algorithm to selected sequences. See <a
- href="../calculations/pairwise.html"
- >pairwise alignments</a>.
+ href="../calculations/pairwise.html">pairwise
+ alignments</a>.
</em><br></li>
<li><strong>Principal Component Analysis</strong><br> <em>Shows
a spatial clustering of the sequences based on similarity
scores calculated with the alignment. See <a
- href="../calculations/pca.html"
- >Principal Component Analysis</a>.
+ href="../calculations/pca.html">Principal
+ Component Analysis</a>.
</em> <br></li>
<li><strong>Extract Scores ... (optional)</strong><br> <em>This
option is only visible if Jalview detects one or more
or elsewhere. You need a continuous network connection in order to
use these services through Jalview.</p>
<ul>
- <li><strong>Alignment</strong><br />
- <em> Align the currently selected sequences or all sequences
- in the alignment, or re-align unaligned sequences to the
- aligned sequences. Entries in this menu provide access to the
- various alignment programs supported by <a
- href="../webServices/JABAWS.html"
- >JABAWS</a>. See the <a href="../webServices/msaclient.html">Multiple
- Sequence Alignment webservice client</a> entry for more
- information.
+ <li><strong>Alignment</strong><br /> <em> Align the
+ currently selected sequences or all sequences in the
+ alignment, or re-align unaligned sequences to the aligned
+ sequences. Entries in this menu provide access to the various
+ alignment programs supported by <a
+ href="../webServices/JABAWS.html">JABAWS</a>. See the
+ <a href="../webServices/msaclient.html">Multiple Sequence
+ Alignment webservice client</a> entry for more information.
</em></li>
<li><strong>Secondary Structure Prediction</strong>
<ul>
<li><strong>Multi-Harmony</strong><br> <em>Performs
functional residue analysis on a protein family alignment
with sub-families defined on it. See the <a
- href="../webServices/shmr.html"
- >Multi-Harmony service</a> entry for more information.
+ href="../webServices/shmr.html">Multi-Harmony
+ service</a> entry for more information.
</em></li>
</ul></li>
</ul></li>
<body>
<p>
- <strong>Alignment Window Annotations Menu</strong> (Since Jalview
- 2.8.2)
+ <strong>Alignment Window Annotations Menu</strong> <em>Since
+ Jalview 2.8.2</em>
</p>
<ul>
<li><strong>Show Alignment Related</strong><em><br>
example, Consensus).</em></li>
<li><em>You can also selectively show or hide annotations
from the <a href="./popupMenu.html">Popup</a> or <a
- href="../features/annotation.html"
- >Annotation</a> menus.
+ href="../features/annotation.html">Annotation</a> menus.
</em></li>
<li><strong>Sort by Sequence</strong><em><br>Sort
sequence-specific annotations by sequence order in the alignment
<ul>
<li><strong>Annotation Label Popup Menu</strong><br> <em>This
menu is opened by clicking anywhere on the annotation row labels
- area (below the sequence ID area).</em>
+ area (below the sequence ID area).</em> <br />
+ <em><strong>Mac Users:</strong> pressing CTRL whilst clicking
+ the mouse/track pad is the same as a right-click. See your
+ system's settings to configure your track-pad's corners to
+ generate right-clicks.</em>
<ul>
<li><strong>Add New Row</strong><br> <em>Adds a
new, named annotation row (a dialog box will pop up for you
</ul></li>
<li><strong>Pairwise Alignments</strong><br> <em>Applies
Smith and Waterman algorithm to selected sequences. See <a
- href="../calculations/pairwise.html"
- >pairwise alignments</a>.
+ href="../calculations/pairwise.html">pairwise
+ alignments</a>.
</em><br></li>
<li><strong>Principal Component Analysis</strong><br> <em>Shows
a spatial clustering of the sequences based on similarity scores
calculated over the alignment.. See <a
- href="../calculations/pca.html"
- >Principal Component Analysis</a>.
+ href="../calculations/pca.html">Principal Component
+ Analysis</a>.
</em> <br></li>
<li><strong>Extract Scores ... (optional)</strong><br> <em>This
option is only visible if Jalview detects one or more
parsed into sequence associated annotation which can then be
used to sort the alignment via the Sort by→Score menu.
</em> <br></li>
- <li><strong>Translate as cDNA</strong> (not applet)<br>
- <em>This option is visible for nucleotide alignments. Selecting
- this option shows the DNA's calculated protein product in a new
- <a href="../features/splitView.html">split frame</a> window.
- Note that the translation is not frame- or intron-aware; it
- simply translates all codons in each sequence, using the
- standard <a href="../misc/geneticCode.html">genetic code</a>
- (any incomplete final codon is discarded). You can perform this
- action on the whole alignment, or selected rows, columns, or
- regions.
+ <li><strong>Translate as cDNA</strong> (not applet)<br> <em>This
+ option is visible for nucleotide alignments. Selecting this
+ option shows the DNA's calculated protein product in a new <a
+ href="../features/splitView.html">split frame</a> window. Note
+ that the translation is not frame- or intron-aware; it simply
+ translates all codons in each sequence, using the standard <a
+ href="../misc/geneticCode.html">genetic code</a> (any incomplete
+ final codon is discarded). You can perform this action on the
+ whole alignment, or selected rows, columns, or regions.
</em> <br></li>
<li><strong>Reverse, Reverse Complement</strong> (not applet)<br>
- <em>These options are visible for nucleotide alignments. Selecting them adds the reverse (or reverse complement)
- of the sequences (or selected region) as new sequences in the alignment. To try this out, add this sequence and
- perform 'Reverse Complement' followed by 'Translate as cDNA':
- <br><small>
- Seq GTCATTTGCGCGTGTTGATTATTCGGACCGCTCCACTTCCCTTTACTCGTGCGTTCAATTGATTTAATCCTC
- TGGGGGGGCTCTGGTTTACATAGCTTAAATCTATTCCATTCAAGGAAGCTCATG</small>
+ <em>These options are visible for nucleotide alignments.
+ Selecting them adds the reverse (or reverse complement) of the
+ sequences (or selected region) as new sequences in the
+ alignment. To try this out, add this sequence and perform
+ 'Reverse Complement' followed by 'Translate as cDNA': <br>
+ <small> Seq
+ GTCATTTGCGCGTGTTGATTATTCGGACCGCTCCACTTCCCTTTACTCGTGCGTTCAATTGATTTAATCCTC
+ TGGGGGGGCTCTGGTTTACATAGCTTAAATCTATTCCATTCAAGGAAGCTCATG</small>
</em> <br></li>
<li><strong>Get Cross-References</strong> (not applet)<br>
- <em>This option is visible where sequences have
+ <em>This option is visible where sequences have
cross-references to other standard databases; for example, an
EMBL entry may have cross-references to one or more UNIPROT
entries. Select the database to view all cross-referenced
</strong><em>All columns which only contain gap characters
("-", ".") will be deleted.<br> You may
set the default gap character in <a
- href="../features/preferences.html"
- >preferences</a>.
+ href="../features/preferences.html">preferences</a>.
</em></li>
<li><strong>Remove All Gaps (Control Shift E)</strong><br>
<em>Gap characters ("-", ".") will be
deleted from the selected area of the alignment. If no selection
is made, ALL the gaps in the alignment will be removed.<br>
You may set the default gap character in <a
- href="../features/preferences.html"
- >preferences</a>.
+ href="../features/preferences.html">preferences</a>.
</em></li>
<li><strong>Remove Redundancy (Control D)<br>
</strong><em>Selecting this option brings up a window asking you to
</p>
<ul>
<li><strong>Fetch Sequence</strong><br> <em>Shows a
- dialog window in which you can select known ids from Uniprot,
+ dialog window in which you can select known ids from UniProt,
EMBL, EMBLCDS, PDB, PFAM, or RFAM databases using Web Services
provided by the European Bioinformatics Institute. See <a
- href="../features/seqfetch.html"
- >Sequence Fetcher</a>
+ href="../features/seqfetch.html">Sequence Fetcher</a>
</em>.</li>
<li><strong>Add Sequences</strong><em><br> Add
sequences to the visible alignment from file, URL, or cut &
<li><strong>Export Image</strong> <em><br> Creates an
alignment graphic with the current view's annotation, alignment
background colours and group colours. If the alignment is <a
- href="../features/wrap.html"
- >wrapped</a>, the output will also be wrapped and will have the same
- visible residue width as the open alignment. </em>
+ href="../features/wrap.html">wrapped</a>, the output will
+ also be wrapped and will have the same visible residue width as
+ the open alignment. </em>
<ul>
<li><strong>HTML<br>
</strong><em>Create a <a href="../io/export.html">web page</a> from
</em></li>
<li><strong>Load Features / Annotations<br>
</strong><em>Load files describing precalculated <a
- href="../features/featuresFormat.html"
- >sequence features</a> or <a
- href="../features/annotationsFormat.html"
- >alignment annotations</a>.
+ href="../features/featuresFormat.html">sequence
+ features</a> or <a href="../features/annotationsFormat.html">alignment
+ annotations</a>.
</em></li>
<li><strong>Close (Control W)</strong><br> <em>Close
the alignment window. Make sure you have saved your alignment
for faster alignment rendering. </em></em></li>
<li><strong>Wrap<br>
</strong><em>When ticked, the alignment display is "<a
- href="../features/wrap.html"
- >wrapped</a>" to the width of the alignment window. This is
- useful if your alignment has only a few sequences to view its full
- width at once.<br> Additional options for display of sequence
- numbering and scales are also visible in wrapped layout mode:
+ href="../features/wrap.html">wrapped</a>" to the width
+ of the alignment window. This is useful if your alignment has only
+ a few sequences to view its full width at once.<br>
+ Additional options for display of sequence numbering and scales
+ are also visible in wrapped layout mode:
</em>
<ul>
<li><strong>Scale Left</strong><br> <em>Show the
<strong>WARNING</strong>: This cannot be undone.
</em></li>
<li><strong><a
- href="../features/columnFilterByAnnotation.html"
- >Select/Hide Columns by Annotation</a></strong> <br /> <em>Select or
- Hide columns in the alignment according to secondary structure,
- labels and values shown in alignment annotation rows. </em></li>
+ href="../features/columnFilterByAnnotation.html">Select/Hide
+ Columns by Annotation</a></strong> <br /> <em>Select or Hide columns
+ in the alignment according to secondary structure, labels and
+ values shown in alignment annotation rows. </em></li>
</ul>
</body>
</html>
</ul></li>
<li><strong>Fetch Sequence<br>
</strong><em>Shows a dialog window in which you can select known ids
- from Uniprot, EMBL, EMBLCDS or PDB database using Web
+ from UniProt, EMBL, EMBLCDS or PDB database using Web
Services provided by the European Bioinformatics Institute.</em></li>
<li><strong>Save Project</strong><br> <em>Saves
all currently open alignment windows with their current view
settings and any associated trees, as a <a
- href="../features/jalarchive.html"
- >Jalview Archive</a> (which has a .jar extension).
+ href="../features/jalarchive.html">Jalview
+ Archive</a> (which has a .jar extension).
</em></li>
<li><strong>Load Project</strong><br> <em>Loads
Jalview archives <strong>only</strong>.
window to the top of the pile when it is selected.
<ul>
<li><strong>Close All</strong><br> Close all
- alignment and analysis windows.<br>
- <strong>Note: This will erase all alignments from
- memory, and cannot be undone!</strong></li>
+ alignment and analysis windows.<br> <strong>Note:
+ This will erase all alignments from memory, and cannot be
+ undone!</strong></li>
<li><strong>Raise Associated Windows</strong><br>
Bring all windows associated with the current alignment to
the top of the pile.</li>
<p>
The <a href="popupMenu.html">Popup Menus</a> are opened by clicking
with the right mouse button in the alignment display area or on a
- sequence label in the alignment window.
+ sequence label in the alignment window.<br /> <em><strong>Mac
+ Users:</strong> pressing CTRL whilst clicking the mouse/track pad is the
+ same as a right-click. See your system's settings to configure
+ your track-pad's corners to generate right-clicks.</em>
</p>
<p>
The <a href="alwannotationpanel.html">Annotations Menu</a> is opened
<strong>Popup Menu</strong><br> <em>This menu is visible
when right clicking either within a selected region on the
alignment or on a selected sequence name. It may not be accessible
- when in 'Cursor Mode' (toggled with the F2 key).</em>
+ when in 'Cursor Mode' (toggled with the F2 key).</em><br /> <em><strong>Mac
+ Users:</strong> pressing CTRL whilst clicking the mouse/track pad is the
+ same as a right-click. See your system's settings to configure
+ your track-pad's corners to generate right-clicks.</em>
</p>
<ul>
<li><strong>Selection</strong>
<li><a name="sqreport"><strong>Sequence
Details...<br>
</strong></a><em>(Since Jalview 2.8)<br>Open an <a
- href="../io/exportseqreport.html"
- >HTML report containing the annotation and database cross
- references</a> normally shown in the sequence's tooltip.
+ href="../io/exportseqreport.html">HTML report
+ containing the annotation and database cross references</a> normally
+ shown in the sequence's tooltip.
</em></li>
<li><strong>Show Annotations...<br>
</strong><em>Choose to show (unhide) either All or a selected type
</strong><em>The selection area will be output to a a text window in
the selected alignment format. </em></li>
<li><strong><a
- href="../features/creatinFeatures.html"
- >Create Sequence Feature...</a></strong><br> <em>Opens the
- dialog box for creating sequence features over the currently
- selected region on each selected sequence.</em></li>
+ href="../features/creatinFeatures.html">Create
+ Sequence Feature...</a></strong><br> <em>Opens the dialog box
+ for creating sequence features over the currently selected
+ region on each selected sequence.</em></li>
<li><strong>Create Group<br>
</strong><em>This will define a new group from the current
selection.</em><strong> </strong></li>
<li><a name="sqreport"><strong>Sequence
Details ...<br>
</strong></a><em>(Since Jalview 2.8)<br>Open an <a
- href="../io/exportseqreport.html"
- >HTML report containing the annotation and database cross
- references</a> normally shown in the sequence's tooltip.
+ href="../io/exportseqreport.html">HTML report
+ containing the annotation and database cross references</a>
+ normally shown in the sequence's tooltip.
</em></li>
<li><strong>Edit Name/Description<br>
</strong><em>You may edit the name and description of each sequence.
and sequence description to be entered. Press OK to accept
your edit. To save sequence descriptions, you must save in
Fasta, PIR or Jalview File format.</em></li>
- <li><strong>Add <a href="../features/annotation.html#seqannots">Reference Annotations</a></strong><br>
- <em>When enabled, copies any available alignment
- annotation for this sequence to the current view.</em></li>
+ <li><strong>Add <a
+ href="../features/annotation.html#seqannots">Reference
+ Annotations</a></strong><br> <em>When enabled, copies any
+ available alignment annotation for this sequence to the
+ current view.</em></li>
<li><strong>Set as Reference</strong> or <strong>Unmark
- as Reference</strong><br /> Sets or unsets the reference sequence for
- the the alignment.</li>
+ as Reference</strong><br /> Sets or unsets the reference sequence
+ for the the alignment.</li>
<li><strong>Represent Group With (Sequence Id)</strong><br>
<em>All sequences in the current selection group will be
Connections tab.<br> Since Jalview 2.4, links will
also be made for database cross references (where the
database name exactly matches the link name set up in <a
- href="../features/preferences.html"
- >Preferences</a>). <br>Since Jalview 2.5, links are also
- shown for non-positional sequence features attached to the
- sequence, and any regular-expression based URL links that
- matched the description line.
+ href="../features/preferences.html">Preferences</a>).
+ <br>Since Jalview 2.5, links are also shown for
+ non-positional sequence features attached to the sequence,
+ and any regular-expression based URL links that matched
+ the description line.
</em><strong><br> </strong></li>
</ul></li>
<li><strong>3D Structure Data...</strong> </strong><em>This menu is
visible when you right-click on a sequence name. When this
- option is clicked, Jalview will open a <a
- href="../features/structurechooser.html"
- >'Structure Chooser' </a> dialogue with options to select the
- structure which will eventually be opened in a 3D interactive
- view.<br> These entries will only be present if the
- sequence has <a href="../features/viewingpdbs.html">associated
- PDB structures</a>.
+ option is clicked, Jalview will open the <a
+ href="../features/structurechooser.html">'Structure Chooser'
+ </a>, which allows you to discover and view 3D structures for the
+ current selection. For more info, see <a
+ href="../features/viewingpdbs.html">viewing PDB structures</a>.
</em></li>
- <li><strong>VARNA 2D Structure</strong><br />
- <em> If the sequence or alignment has RNA structure, then <strong>VARNA
+ <li><strong>VARNA 2D Structure</strong><br /> <em> If the
+ sequence or alignment has RNA structure, then <strong>VARNA
2D Structure</strong> entries will also be present enabling you to open
a linked view of the RNA structure in <a
- href="../features/varna.html"
- >VARNA</a>.
+ href="../features/varna.html">VARNA</a>.
</em></li>
<li><a name="hideinserts"><strong>Hide Insertions</strong></a><br />
<em>Hides columns containing gaps in the current sequence or
elsewhere. You need a continuous network connection in order to use
these services through Jalview.</p>
<ul>
- <li><strong>Alignment</strong><br />
- <em> Align the currently selected sequences or all sequences in
- the alignment, or re-align unaligned sequences to the aligned
- sequences. Entries in this menu provide access to the various
- alignment programs supported by <a
- href="../webServices/JABAWS.html"
- >JABAWS</a>. See the <a href="../webServices/msaclient.html">Multiple
+ <li><strong>Alignment</strong><br /> <em> Align the
+ currently selected sequences or all sequences in the alignment,
+ or re-align unaligned sequences to the aligned sequences.
+ Entries in this menu provide access to the various alignment
+ programs supported by <a href="../webServices/JABAWS.html">JABAWS</a>.
+ See the <a href="../webServices/msaclient.html">Multiple
Sequence Alignment webservice client</a> entry for more
information.
</em></li>
<li><strong>Multi-Harmony</strong><br> <em>Performs
functional residue analysis on a protein family alignment
with sub-families defined on it. See the <a
- href="../webServices/shmr.html"
- >Multi-Harmony service</a> entry for more information.
+ href="../webServices/shmr.html">Multi-Harmony
+ service</a> entry for more information.
</em></li>
</ul></li>
</ul>
way:
<ul>
<li><em>RFAM</em> - Sequences can be <a
- href="../features/seqfetch.html"
- >fetched</a> from the RFAM database by accession number or ID.</li>
+ href="../features/seqfetch.html">fetched</a> from the RFAM
+ database by accession number or ID.</li>
<li><em>Stockholm files</em> - WUSS (or VIENNA) dot-bracket
notation found in the secondary structure annotation line will be
imported as sequence or alignment associated secondary structure
annotation.</li>
<li><em>Clustal files</em> - certain RNA alignment programs,
- such as <a
- href="http://rna.informatik.uni-freiburg.de:8080/LocARNA.jsp"
- >LocaRNA</a> output consensus RNA secondary structure lines in the
- line normally reserved for the Clustal consensus line in a clustal
+ such as <a href="http://rna.informatik.uni-freiburg.de/LocARNA">LocaRNA</a>
+ output consensus RNA secondary structure lines in the line
+ normally reserved for the Clustal consensus line in a clustal
file.</li>
<li><em>RNAML</em> Jalview can import RNAML files containing
sequences and extended secondary structure annotation derived from
the alignment will have a secondary structure line shown below it,
and a number of additional options become available:
<ul>
- <li><a href="../colourschemes/rnaHelicesColouring.html">RNA
+ <li><a href="../colourSchemes/rnahelicesColouring.html">RNA
Helix colouring</a> - highlights columns of alignment involved in
particular RNA helices, Uses the first displayed secondary
structure annotation.</li>
per-sequence secondary structure is available).</li>
</ul>
<p>
- <strong>Pseudo-knots</strong><br /> Jalview 2.8.2 introduced limited
- support for working with structures including pseudoknots. Where
- possible, extended WUSS symbols (e.g. different types of
+ <strong>Pseudo-knots</strong><br /> Jalview 2.8.2 introduced
+ limited support for working with structures including pseudoknots.
+ Where possible, extended WUSS symbols (e.g. different types of
parentheses, or upper and lower case letters) are preserved when
parsing RNA structure annotation and will be shaded differently when
displayed in the structure.<br /> Extended WUSS annotation is also
<li><em>HTTP logs on the Jalview website</em><br> We
record IP addresses of machines which access the web site, either
via the browser when downloading the application, or when the
- Jalview Desktop user interface is launched.<br>
- <br>
+ Jalview Desktop user interface is launched.<br> <br>
<ul>
<li><i>The JNLP file at
www.jalview.org/webstart/jalview.jnlp is retrieved to
interactions with the public Jalview web services are
logged, but we delete all job data (input data and results)
after about two weeks.</i></li>
- </ul>
- <br></li>
+ </ul> <br></li>
<li><em>Google Analytics</em><br> Since Jalview 2.4.0b2,
the Jalview Desktop records usage data with Google Analytics via
the <a href="http://code.google.com/p/jgoogleanalytics/">JGoogleAnalytics</a>
run Jalview in 'headless mode' via the command line, then the
program shouldn't try to contact any of the web servers mentioned
above (if it does, then it's a bug!). You can also specify some <a
- href="features/commandline.html"
- >command line options</a> to disable the questionnaire and usage
- statistics check. Finally, the <a
- href="features/preferences.html#connections"
- >Connections Tab</a> of the Jalview preferences contains options for
- controlling the submission of usage statistics.
+ href="features/commandline.html">command line options</a> to
+ disable the questionnaire and usage statistics check. Finally, the <a
+ href="features/preferences.html#connections">Connections
+ Tab</a> of the Jalview preferences contains options for controlling
+ the submission of usage statistics.
<p>
<strong>Other Web Clients in Jalview</strong><br> The Jalview
desktop is intended to make it easier to interact with web-based
<tr>
<td width="60" nowrap>
<div align="center">
- <strong><a name="Jalview.2.9.1">2.9.1</a><br /> <em>21/6/2016</em></strong>
+ <strong><a name="Jalview.2.10.0b1">2.10.0b1</a><br />
+ <em>25/10/2016</em></strong>
+ </div>
+ </td>
+ <td><em>Application</em>
+ <ul>
+ <li>3D Structure chooser opens with 'Cached structures'
+ view if structures already loaded</li>
+ <li>Progress bar reports models as they are loaded to
+ structure views</li>
+ </ul></td>
+ <td>
+ <div align="left">
+ <em>General</em>
+ <ul>
+ <li>Colour by conservation always enabled and no tick
+ shown in menu when BLOSUM or PID shading applied</li>
+ <li>FER1_ARATH and FER2_ARATH labels were switched in
+ example sequences/projects/trees</li>
+ </ul>
+ <em>Application</em>
+ <ul>
+ <li>Jalview projects with views of local PDB structure
+ files saved on Windows cannot be opened on OSX</li>
+ <li>Multiple structure views can be opened and
+ superposed without timeout for structures with multiple
+ models or multiple sequences in alignment</li>
+ <li>Cannot import or associated local PDB files without
+ a PDB ID HEADER line</li>
+ <li>RMSD is not output in Jmol console when
+ superposition is performed</li>
+ <li>Drag and drop of URL from Browser fails for Linux
+ and OSX versions earlier than El Capitan</li>
+ <li>ENA client ignores invalid content from ENA server</li>
+ <li>Exceptions are not raised in console when ENA
+ client attempts to fetch non-existent IDs via Fetch DB
+ Refs UI option</li>
+ <li>Exceptions are not raised in console when a new
+ view is created on the alignment</li>
+ <li>OSX right-click fixed for group selections:
+ CMD-click to insert/remove gaps in groups and CTRL-click
+ to open group pop-up menu</li>
+ </ul>
+ <em>Build and deployment</em>
+ <ul>
+ <li>URL link checker now copes with multi-line anchor
+ tags</li>
+ </ul>
+ <em>New Known Issues</em>
+ <ul>
+ <li>Drag and drop from URL links in browsers do not
+ work on Windows</li>
+ </ul>
+ </div>
+ </td>
+ </tr>
+ <tr>
+ <td width="60" nowrap>
+ <div align="center">
+ <strong><a name="Jalview.2.10.0">2.10.0</a><br /> <em>06/10/2016</em></strong>
</div>
</td>
<td><em>General</em>
<ul>
- <li><!-- JAL---></li>
- <li><!-- JAL-192 --->Alignment ruler shows positions relative to reference sequence</li>
+ <li>
+ <!-- JAL-2124 -->Updated Spanish translations.
+ </li>
+ <li>
+ <!-- JAL-2164,JAL-1919,JAL-2148 -->Jmol now primary parser
+ for importing structure data to Jalview. Enables mmCIF and
+ better PDB parsing.
+ </li>
+ <li>
+ <!-- JAL-192 --->Alignment ruler shows positions relative to
+ reference sequence
+ </li>
+ <li>
+ <!-- JAL-2202 -->Position/residue shown in status bar when
+ mousing over sequence associated annotation
+ </li>
+ <li>
+ <!-- JAL-2171 -->Default RNA SS symbol to 'matching bracket'
+ for manual entry
+ </li>
+ <li>
+ <!-- JAL-2214 -->RNA Structure consensus indicates wc-only
+ '()', canonical '[]' and invalid '{}' base pair populations
+ for each column
+ </li>
+ <li>
+ <!-- JAL-2092 -->Feature settings popup menu options for
+ showing or hiding columns containing a feature
+ </li>
+ <li>
+ <!-- JAL-1557 -->Edit selected group by double clicking on
+ group and sequence associated annotation labels
+ </li>
+ <li>
+ <!-- JAL-2236 -->Sequence name added to annotation label in
+ select/hide columns by annotation and colour by annotation
+ dialogs
+ </li>
+
</ul> <em>Application</em>
<ul>
- <li><!-- JAL---></li>
- <li><!-- JAL-2027-->Support for reverse-complement coding regions in ENA and EMBL</li>
- <li><!-- JAL-1855, JAL-2113, JAL-2114-->Upgrade to EMBL XML 1.2 for ENA record retrieval</li>
- <li><!-- JAL 1812 -->New 'execute Groovy script' option in an alignment window's Calculate menu</li>
- <li><!-- JAL 1812 -->Allow groovy scripts that call Jalview.getAlignFrames() to run in headless mode</li>
- <li><!-- JAL-1369 --->Store/restore reference sequence in Jalview projects</li>
-
- </ul> <em>Applet</em>
+ <li>
+ <!-- JAL-2050-->Automatically hide introns when opening a
+ gene/transcript view
+ </li>
+ <li>
+ <!-- JAL-1563 -->Uniprot Sequence fetcher Free Text Search
+ dialog
+ </li>
+ <li>
+ <!-- JAL-1957, JAL-1479 JAL-1491 -->UniProt - PDB protein
+ structure mappings with the EMBL-EBI PDBe SIFTS database
+ </li>
+ <li>
+ <!-- JAL-2079 -->Updated download sites used for Rfam and
+ Pfam sources to xfam.org
+ </li>
+ <li>
+ <!-- JAL-2084 -->Disabled Rfam(Full) in the sequence fetcher
+ </li>
+ <li>
+ <!-- JAL-2123 -->Show residue labels in Chimera when mousing
+ over sequences in Jalview
+ </li>
+ <li>
+ <!-- JAL-2027-->Support for reverse-complement coding
+ regions in ENA and EMBL
+ </li>
+ <li>
+ <!-- JAL-1855, JAL-2113, JAL-2114-->Upgrade to EMBL XML 1.2
+ for record retrieval via ENA rest API
+ </li>
+ <li>
+ <!-- JAL-2027 -->Support for ENA CDS records with reverse
+ complement operator
+ </li>
+ <li>
+ <!-- JAL-1812 -->Update to groovy-2.4.6-indy - for faster
+ groovy script execution
+ </li>
+ <li>
+ <!-- JAL-1812 -->New 'execute Groovy script' option in an
+ alignment window's Calculate menu
+ </li>
+ <li>
+ <!-- JAL-1812 -->Allow groovy scripts that call
+ Jalview.getAlignFrames() to run in headless mode
+ </li>
+ <li>
+ <!-- JAL-2068 -->Support for creating new alignment
+ calculation workers from groovy scripts
+ </li>
+ <li>
+ <!-- JAL-1369 --->Store/restore reference sequence in
+ Jalview projects
+ </li>
+ <li>
+ <!-- JAL-1803 -->Chain codes for a sequence's PDB
+ associations are now saved/restored from project
+ </li>
+ <li>
+ <!-- JAL-1993 -->Database selection dialog always shown
+ before sequence fetcher is opened
+ </li>
+ <li>
+ <!-- JAL-2183 -->Double click on an entry in Jalview's
+ database chooser opens a sequence fetcher
+ </li>
+ <li>
+ <!-- JAL-1563 -->Free-text search client for UniProt using
+ the UniProt REST API
+ </li>
+ <li>
+ <!-- JAL-2168 -->-nonews command line parameter to prevent
+ the news reader opening
+ </li>
+ <li>
+ <!-- JAL-2028 -->Displayed columns for PDBe and Uniprot
+ querying stored in preferences
+ </li>
+ <li>
+ <!-- JAL-2091 -->Pagination for displaying PDBe and Uniprot
+ search results
+ </li>
+ <li>
+ <!-- JAL-1977-->Tooltips shown on database chooser
+ </li>
+ <li>
+ <!-- JAL-391 -->Reverse complement function in calculate
+ menu for nucleotide sequences
+ </li>
+ <li>
+ <!-- JAL-2005, JAL-599 -->Alignment sort by feature scores
+ and feature counts preserves alignment ordering (and
+ debugged for complex feature sets).
+ </li>
+ <li>
+ <!-- JAL-2152-->Chimera 1.11.1 minimum requirement for
+ viewing structures with Jalview 2.10
+ </li>
+ <li>
+ <!-- JAL-1705, JAL-1975, JAL-2050,JAL-2041,JAL-2105 -->Retrieve
+ genome, transcript CCDS and gene ids via the Ensembl and
+ Ensembl Genomes REST API
+ </li>
+ <li>
+ <!-- JAL-2049 -->Protein sequence variant annotation
+ computed for 'sequence_variant' annotation on CDS regions
+ (Ensembl)
+ </li>
+ <li>
+ <!-- JAL-2232 -->ENA CDS 'show cross references' for Uniprot
+ sequences
+ </li>
+ <li>
+ <!-- JAL-2213,JAL-1856 -->Improved warning messages when DB
+ Ref Fetcher fails to match, or otherwise updates sequence
+ data from external database records.
+ </li>
+ <li>
+ <!-- JAL-2154 -->Revised Jalview Project format for
+ efficient recovery of sequence coding and alignment
+ annotation relationships.
+ </li>
+ </ul> <!-- <em>Applet</em>
<ul>
- <li><!-- JAL---></li>
- </ul></td>
+ <li>
+ -- JAL---
+ </li>
+ </ul> --></td>
<td>
<div align="left">
<em>General</em>
<ul>
- <li><!-- JAL-2077 -->reinstate CTRL-click for opening pop-up menu on OSX</li>
- <li><!-- JAL-2018-->Export features in Jalview format (again) includes graduated colourschemes</li>
- <li><!-- JAL-1722, JAL-2001-->More responsive when working with big alignments and lots of hidden columns</li>
- <li><!-- JAL-2053-->hidden column markers not always rendered at right of alignment window</li>
- <li><!-- JAL-2067, JAL- -->Tidied up links in help file table of contents</li>
- <li><!-- JAL-2072 -->Feature based tree calculation not shown for DNA alignments</li>
- <li><!-- JAL-2075 -->Hidden columns ignored during feature based tree calculation</li>
- <li><!-- JAL-2065 -->Alignment view stops updating when show unconserved enabled for group on alignment</li>
- <li><!-- JAL-2086 -->Cannot insert gaps into sequence when set as reference</li>
-
+ <li>
+ <!-- JAL-2077 -->reinstate CTRL-click for opening pop-up
+ menu on OSX
+ </li>
+ <li>
+ <!-- JAL-2018-->Export features in Jalview format (again)
+ includes graduated colourschemes
+ </li>
+ <li>
+ <!-- JAL-2172,JAL-1722, JAL-2001-->More responsive when
+ working with big alignments and lots of hidden columns
+ </li>
+ <li>
+ <!-- JAL-2053-->Hidden column markers not always rendered
+ at right of alignment window
+ </li>
+ <li>
+ <!-- JAL-2067 -->Tidied up links in help file table of
+ contents
+ </li>
+ <li>
+ <!-- JAL-2072 -->Feature based tree calculation not shown
+ for DNA alignments
+ </li>
+ <li>
+ <!-- JAL-2075 -->Hidden columns ignored during feature
+ based tree calculation
+ </li>
+ <li>
+ <!-- JAL-2065 -->Alignment view stops updating when show
+ unconserved enabled for group on alignment
+ </li>
+ <li>
+ <!-- JAL-2086 -->Cannot insert gaps into sequence when
+ set as reference
+ </li>
+ <li>
+ <!-- JAL-2146 -->Alignment column in status incorrectly
+ shown as "Sequence position" when mousing over
+ annotation
+ </li>
+ <li>
+ <!-- JAL-2099 -->Incorrect column numbers in ruler when
+ hidden columns present
+ </li>
+ <li>
+ <!-- JAL-1577 -->Colour by RNA Helices not enabled when
+ user created annotation added to alignment
+ </li>
+ <li>
+ <!-- JAL-1841 -->RNA Structure consensus only computed for
+ '()' base pair annotation
+ </li>
+ <li>
+ <!-- JAL-2215, JAL-1841 -->Enabling 'Ignore Gaps' results
+ in zero scores for all base pairs in RNA Structure
+ Consensus
+ </li>
+ <li>
+ <!-- JAL-2174-->Extend selection with columns containing
+ feature not working
+ </li>
+ <li>
+ <!-- JAL-2275 -->Pfam format writer puts extra space at
+ beginning of sequence
+ </li>
+ <li>
+ <!-- JAL-1827 -->Incomplete sequence extracted from pdb
+ entry 3a6s
+ </li>
+ <li>
+ <!-- JAL-2238 -->Cannot create groups on an alignment from
+ from a tree when t-coffee scores are shown
+ </li>
+ <li>
+ <!-- JAL-1836,1967 -->Cannot import and view PDB
+ structures with chains containing negative resnums (4q4h)
+ </li>
+ <li>
+ <!-- JAL-1998 -->ArithmeticExceptions raised when parsing
+ some structures
+ </li>
+ <li>
+ <!-- JAL-1991, JAl-1952 -->'Empty' alignment blocks added
+ to Clustal, PIR and PileUp output
+ </li>
+ <li>
+ <!-- JAL-2008 -->Reordering sequence features that are
+ not visible causes alignment window to repaint
+ </li>
+ <li>
+ <!-- JAL-2006 -->Threshold sliders don't work in
+ graduated colour and colour by annotation row for e-value
+ scores associated with features and annotation rows
+ </li>
+ <li>
+ <!-- JAL-1797 -->amino acid physicochemical conservation
+ calculation should be case independent
+ </li>
+ <li>
+ <!-- JAL-2173 -->Remove annotation also updates hidden
+ columns
+ </li>
+ <li>
+ <!-- JAL-2234 -->FER1_ARATH and FER2_ARATH mislabelled in
+ example file (uniref50.fa, feredoxin.fa, unaligned.fa,
+ exampleFile_2_7.jar, exampleFile.jar, exampleFile_2_3.jar)
+ </li>
+ <li>
+ <!-- JAL-2065 -->Null pointer exceptions and redraw
+ problems when reference sequence defined and 'show
+ non-conserved' enabled
+ </li>
+ <li>
+ <!-- JAL-1306 -->Quality and Conservation are now shown on
+ load even when Consensus calculation is disabled
+ </li>
</ul>
<em>Application</em>
<ul>
- <li><!-- JAL-1944 not yet fixed Error thrown when exporting a view with hidden sequences as flat-file alignment--></li>
- <li><!-- JAL-1911-->Corrupt preferences for SVG, EPS & HTML output when running on non-gb/us i18n platforms</li>
- <li><!-- JAL-1552-->URLs and links can imported by drag'n'drop on OSX webstart</li>
- <li><!-- JAL-2030-->InstallAnywhere distribution fails when launching Chimera</li>
- <li><!-- JAL-2080-->Jalview very slow to launch via webstart (also hotfix for 2.9.0b2)</li>
- <li><!-- JAL-2085 -->Cannot save project when view has a reference sequence defined</li>
- <li><!-- JAL-1011 -->Columns are suddenly selected in other alignments and views when revealing hidden columns</li>
- <li><!-- JAL-1989 -->Hide columns not mirrored in complement view in a cDNA/Protein splitframe</li>
- <!-- may exclude, this is an external service stability issue JAL-1941 /> RNA 3D structure not added via DSSR service</li> -->
+ <li>
+ <!-- JAL-1552-->URLs and links can't be imported by
+ drag'n'drop on OSX when launched via webstart (note - not
+ yet fixed for El Capitan)
+ </li>
+ <li>
+ <!-- JAL-1911-->Corrupt preferences for SVG, EPS & HTML
+ output when running on non-gb/us i18n platforms
+ </li>
+ <li>
+ <!-- JAL-1944 -->Error thrown when exporting a view with
+ hidden sequences as flat-file alignment
+ </li>
+ <li>
+ <!-- JAL-2030-->InstallAnywhere distribution fails when
+ launching Chimera
+ </li>
+ <li>
+ <!-- JAL-2080-->Jalview very slow to launch via webstart
+ (also hotfix for 2.9.0b2)
+ </li>
+ <li>
+ <!-- JAL-2085 -->Cannot save project when view has a
+ reference sequence defined
+ </li>
+ <li>
+ <!-- JAL-1011 -->Columns are suddenly selected in other
+ alignments and views when revealing hidden columns
+ </li>
+ <li>
+ <!-- JAL-1989 -->Hide columns not mirrored in complement
+ view in a cDNA/Protein splitframe
+ </li>
+ <li>
+ <!-- JAL-1369 -->Cannot save/restore representative
+ sequence from project when only one sequence is
+ represented
+ </li>
+ <li>
+ <!-- JAL-2002 -->Disabled 'Best Uniprot Coverage' option
+ in Structure Chooser
+ </li>
+ <li>
+ <!-- JAL-2215 -->Modifying 'Ignore Gaps' on consensus or
+ structure consensus didn't refresh annotation panel
+ </li>
+ <li>
+ <!-- JAL-1962 -->View mapping in structure view shows
+ mappings between sequence and all chains in a PDB file
+ </li>
+ <li>
+ <!-- JAL-2102, JAL-2101, JAL-2102, -->PDB and Uniprot FTS
+ dialogs format columns correctly, don't display array
+ data, sort columns according to type
+ </li>
+ <li>
+ <!-- JAL-1975 -->Export complete shown after destination
+ file chooser is cancelled during an image export
+ </li>
+ <li>
+ <!-- JAL-2025 -->Error when querying PDB Service with
+ sequence name containing special characters
+ </li>
+ <li>
+ <!-- JAL-2024 -->Manual PDB structure querying should be
+ case insensitive
+ </li>
+ <li>
+ <!-- JAL-2104 -->Large tooltips with broken HTML
+ formatting don't wrap
+ </li>
+ <li>
+ <!-- JAL-1128 -->Figures exported from wrapped view are
+ truncated so L looks like I in consensus annotation
+ </li>
+ <li>
+ <!-- JAL-2003 -->Export features should only export the
+ currently displayed features for the current selection or
+ view
+ </li>
+ <li>
+ <!-- JAL-2036 -->Enable 'Get Cross-References' in menu
+ after fetching cross-references, and restoring from project
+ </li>
+ <li>
+ <!-- JAL-2032 -->Mouseover of a copy of a sequence is not
+ followed in the structure viewer
+ </li>
+ <li>
+ <!-- JAL-2163 -->Titles for individual alignments in
+ splitframe not restored from project
+ </li>
+ <li>
+ <!-- JAL-2145 -->missing autocalculated annotation at
+ trailing end of protein alignment in transcript/product
+ splitview when pad-gaps not enabled by default
+ </li>
+ <li>
+ <!-- JAL-1797 -->amino acid physicochemical conservation
+ is case dependent
+ </li>
+ <li>
+ <!-- JAL-1448 -->RSS reader doesn't stay hidden after last
+ article has been read (reopened issue due to
+ internationalisation problems)
+ </li>
+ <li>
+ <!-- JAL-1960 -->Only offer PDB structures in structure
+ viewer based on sequence name, PDB and UniProt
+ cross-references
+ </li>
+
+ <li>
+ <!-- JAL-1976 -->No progress bar shown during export of
+ alignment as HTML
+ </li>
+ <li>
+ <!-- JAL-2213 -->Structures not always superimposed after
+ multiple structures are shown for one or more sequences.
+ </li>
+ <li>
+ <!-- JAL-1370 -->Reference sequence characters should not
+ be replaced with '.' when 'Show unconserved' format option
+ is enabled.
+ </li>
+ <li>
+ <!-- JAL-1823 -->Cannot specify chain code when entering
+ specific PDB id for sequence
+ </li>
+ <li>
+ <!-- JAL-1944 -->File->Export->.. as doesn't work when
+ 'Export hidden sequences' is enabled, but 'export hidden
+ columns' is disabled.
+ </li>
+ <li>
+ <!--JAL-2026-->Best Quality option in structure chooser
+ selects lowest rather than highest resolution structures
+ for each sequence
+ </li>
+ <li>
+ <!-- JAL-1887 -->Incorrect start and end reported for PDB
+ to sequence mapping in 'View Mappings' report
+ </li>
+ <!-- may exclude, this is an external service stability issue JAL-1941
+ -- > RNA 3D structure not added via DSSR service</li> -->
</ul>
<em>Applet</em>
<ul>
- <li><!-- --></li>
+ <li>
+ <!-- JAL-2151 -->Incorrect columns are selected when
+ hidden columns present before start of sequence
+ </li>
+ <li>
+ <!-- JAL-1986 -->Missing dependencies on applet pages
+ (JSON jars)
+ </li>
+ <li>
+ <!-- JAL-1947 -->Overview pixel size changes when
+ sequences are hidden in applet
+ </li>
+ <li>
+ <!-- JAL-1996 -->Updated instructions for applet
+ deployment on examples pages.
+ </li>
</ul>
</div>
</td>
<li>Updated Spanish translations of localized text for
2.9</li>
</ul> <em>Application</em>
- <ul>
+ <ul>
<!-- <li>cDNA/Protein splitframe window geometry preserved in Jalview projects</li>-->
<li>Signed OSX InstallAnywhere installer<br></li>
<li>Support for per-sequence based annotations in BioJSON</li>
region export in flat file generation</li>
<li>Export alignment views for display with the <a
- href="http://biojs.io/d/msa">BioJS MSAViewer</a></li>
+ href="http://msa.biojs.net/">BioJS MSAViewer</a></li>
<li>Export scrollable SVG in HTML page</li>
<li>Optional embedding of BioJSON data when exporting
<a href="https://www.certum.eu">Certum</a> to the Jalview
open source project).
</li>
- <li>Jalview SRS links replaced by Uniprot and EBI-search
+ <li>Jalview SRS links replaced by UniProt and EBI-search
</li>
<li>Output in Stockholm format</li>
<li>Allow import of data from gzipped files</li>
current built in colourscheme is saved as new scheme</li>
<li>AlignFrame->Save in application pops up save
dialog for valid filename/format</li>
- <li>Cannot view associated structure for Uniprot sequence</li>
- <li>PDB file association breaks for Uniprot sequence
+ <li>Cannot view associated structure for UniProt sequence</li>
+ <li>PDB file association breaks for UniProt sequence
P37173</li>
<li>Associate PDB from file dialog does not tell you
which sequence is to be associated with the file</li>
<li>URL links generated from description line for
regular-expression based URL links (applet and application)
+
+
+
+
<li>Non-positional feature URL links are shown in link
menu</li>
between different screens.</li>
<li>New preference items for sequence ID tooltip and
consensus annotation</li>
- <li>Client to submit sequences and IDs to Envision2 Workflows</li>
+ <li>Client to submit sequences and IDs to Envision2
+ Workflows</li>
<li><em>Vamsas Capabilities</em>
<ul>
<li>Improved VAMSAS synchronization (Jalview archive
<li>Save works when Jalview project is default format</li>
<li>Save as dialog opened if current alignment format is
not a valid output format</li>
- <li>Uniprot canonical names introduced for both das and
+ <li>UniProt canonical names introduced for both das and
vamsas</li>
<li>Histidine should be midblue (not pink!) in Zappo</li>
<li>error messages passed up and output when data read
due to null pointer exceptions</li>
<li>Secondary structure lines are drawn starting from
first column of alignment</li>
- <li>Uniprot XML import updated for new schema release in
+ <li>UniProt XML import updated for new schema release in
July 2008</li>
<li>Sequence feature to sequence ID match for Features
file is case-insensitive</li>
<li>PCA and PDB Viewers zoom via mouse roller
<li>User-defined sub-tree colours and sub-tree selection
+
+
+
+
<li>'New Window' button on the 'Output to Text box'
</ul>
of alignment)
<li>Slowed DAS Feature Fetching for increased robustness.
+
+
+
+
<li>Made angle brackets in ASCII feature descriptions
display correctly
<li>Re-instated Zoom function for PCA
<li>Sequence descriptions conserved in web service
analysis results
- <li>Uniprot ID discoverer uses any word separated by
+ <li>UniProt ID discoverer uses any word separated by
∣
<li>WsDbFetch query/result association resolved
<li>Tree leaf to sequence mapping improved
<li>Smooth fonts switch moved to FontChooser dialog box.
+
+
+
+
</ul>
</td>
and <strong>A</strong>nalysis of <strong>Molecular</strong> <strong>S</strong>equences,
<strong>Alignements</strong> and <strong>S</strong>tructures).
Currently, the only other VAMSAS enabled application is <a
- href="http://www.topali.org"
- >TOPALi</a> - a user friendly program for phylogenetics and
- evolutionary analysis.
+ href="http://www.topali.org">TOPALi</a> - a user friendly
+ program for phylogenetics and evolutionary analysis.
<p>
VAMSAS enabled applications access a shared bioinformatics dataset
containing sequences, alignments, annotation and trees, which can be
represented by an XML document analogous to a <a
- href="../features/jalarchive.html"
- >Jalview Project Archive</a>.
+ href="../features/jalarchive.html">Jalview Project
+ Archive</a>.
</p>
<br>
<strong>Connecting to a VAMSAS session</strong>
The majority of these scores were described by Valdar in 2002
(Scoring residue conservation. <em>Proteins: Structure,
Function, and Genetics</em> 43(2): 227-241. <a
- href="http://www.ncbi.nlm.nih.gov/pubmed/12112692"
- >PubMed</a> or available on the <a
- href="http://valdarlab.unc.edu/publications.html"
- >Valdar Group publications page</a>), but the SMERFs score was
- developed later and described by Manning et al. in 2008 (<a
- href="http://www.biomedcentral.com/1471-2105/9/51"
- >BMC Bioinformatics 2008, 9:51 doi:10.1186/1471-2105-9-51</a>).
+ href="http://www.ncbi.nlm.nih.gov/pubmed/12112692">PubMed</a>
+ or available on the <a
+ href="http://valdarlab.unc.edu/publications.html">Valdar
+ Group publications page</a>), but the SMERFs score was developed later
+ and described by Manning et al. in 2008 (<a
+ href="http://www.biomedcentral.com/1471-2105/9/51">BMC
+ Bioinformatics 2008, 9:51 doi:10.1186/1471-2105-9-51</a>).
</p>
<p>
<strong>Enabling and disabling AACon calculations</strong><br />
<strong>Configuring which AACon calculations are performed</strong><br />
The <strong>Web Services→Conservation→Change
AACon Settings ...</strong> menu entry will open a <a
- href="webServicesParams.html"
- >web services parameter dialog</a> for the currently configured AACon
- server. Standard presets are provided for quick and more expensive
- conservation calculations, and parameters are also provided to
- change the way that SMERFS calculations are performed.<br /> <em>AACon
- settings for an alignment are saved in <a
- href="../features/jalarchive.html"
- >Jalview projects</a> along with the latest calculation results.
+ href="webServicesParams.html">web services parameter
+ dialog</a> for the currently configured AACon server. Standard presets
+ are provided for quick and more expensive conservation calculations,
+ and parameters are also provided to change the way that SMERFS
+ calculations are performed.<br /> <em>AACon settings for an
+ alignment are saved in <a href="../features/jalarchive.html">Jalview
+ projects</a> along with the latest calculation results.
</em>
</p>
<p>
the <a href="webServicesPrefs.html">Web Services Preferences
Panel</a>, and detailed information about a particular service is
available from the help text and web pages accessible from its <a
- href="webServicesParams.html"
- >job parameters dialog box</a>.
+ href="webServicesParams.html">job parameters dialog box</a>.
</p>
<p>
<strong>Obtaining JABAWS</strong><br> One of the aims of JABAWS
stand-alone execution of analysis programs, or as a job submission
engine - enabling larger numbers of jobs to be handled. If you would
like to download and install JABAWS for your own use, please go to <a
- href="http://www.compbio.dundee.ac.uk/jabaws"
- >http://www.compbio.dundee.ac.uk/jabaws</a> for more information.
+ href="http://www.compbio.dundee.ac.uk/jabaws">http://www.compbio.dundee.ac.uk/jabaws</a>
+ for more information.
</p>
<p>
<strong>Configuring your own JABAWS services for use by
Jalview</strong><br> Once you have downloaded and installed JABAWS,
and verified it is working, all that is needed is to add the URL for
your JABAWS server(s) to the list in the <a
- href="webServicesPrefs.html"
- >Web Services Preferences Panel</a>. After adding your service and
- saving your preferences or hitting the 'refresh web services'
- button, you should be able to submit jobs to the server via the
- alignment window's web services menu. Your JABAWS servers list is
- stored in your Jalview preferences, so you will only have to
- configure Jalview once for each new server.
+ href="webServicesPrefs.html">Web Services Preferences
+ Panel</a>. After adding your service and saving your preferences or
+ hitting the 'refresh web services' button, you should be able to
+ submit jobs to the server via the alignment window's web services
+ menu. Your JABAWS servers list is stored in your Jalview
+ preferences, so you will only have to configure Jalview once for
+ each new server.
</p>
<p>
<em>Support for accessing JABAWS servers was introduced in
Gruber, and Peter F. Stadler, <em>RNAalifold: Improved
consensus structure prediction for RNA alignments</em> (BMC
Bioinformatics, 9:474, 2008). Download the paper at <a
- href="http://www.biomedcentral.com/1471-2105/9/474"
- >http://www.biomedcentral.com/1471-2105/9/474</a>.
+ href="http://www.biomedcentral.com/1471-2105/9/474">http://www.biomedcentral.com/1471-2105/9/474</a>.
</p>
<p>
<strong>Running RNAalifold from Jalview</strong><br />
<Strong>RNAalifold prediction parameters</Strong> <br /> JABAWS and
Jalview only provide access to a selection of the RNAalifold
arguments. For a full description, see the documentation at <a
- href="http://www.tbi.univie.ac.at/RNA/RNAalifold.html"
- >http://www.tbi.univie.ac.at/RNA/RNAalifold.html</a>.
+ href="http://www.tbi.univie.ac.at/RNA/RNAalifold.html">http://www.tbi.univie.ac.at/RNA/RNAalifold.html</a>.
</p>
<p>
<strong>Supported Arguments which give alternate structures</strong>
Calculate an MEA structure where the expected Accuracy is computed
from the base pair probabilities. A more detailed description can be
found in the <strong>RNAfold</strong> program documentation at <a
- href="http://www.tbi.univie.ac.at/RNA/RNAfold.html"
- >http://www.tbi.univie.ac.at/RNA/RNAfold.html</a>.
+ href="http://www.tbi.univie.ac.at/RNA/RNAfold.html">http://www.tbi.univie.ac.at/RNA/RNAfold.html</a>.
</p>
<p>
<strong>Example RNAalifold Structure Annotation rows</strong>
Database references are associated with a sequence are displayed as a
list in the tooltip shown when mousing over its sequence ID. Jalview
uses references for the retrieval of <a
- href="../features/viewingpdbs.html"
- >PDB structures</a> and <a href="../features/dasfeatures.html">DAS
- features</a>, and for retrieving sequence cross-references such as the
- protein products of a DNA sequence.
+ href="../features/viewingpdbs.html">PDB structures</a> and <a
+ href="../features/dasfeatures.html">DAS features</a>, and for
+ retrieving sequence cross-references such as the protein products of a
+ DNA sequence.
</p>
<p>
<strong>Initiating reference retrieval</strong><br> The
<p>
<strong>The Sequence Identification Process</strong><br> The
method of accession id discovery is derived from the method which
- earlier Jalview versions used for Uniprot sequence feature retrieval,
- and was originally restricted to the identification of valid Uniprot
+ earlier Jalview versions used for UniProt sequence feature retrieval,
+ and was originally restricted to the identification of valid UniProt
accessions.<br> Essentially, Jalview will try to retrieve records
from a subset of the databases accessible by the <a
- href="../features/seqfetch.html"
- >sequence fetcher</a> using each sequence's ID string (or each string in
- the ID separated by the '∣' symbol).
+ href="../features/seqfetch.html">sequence fetcher</a> using each
+ sequence's ID string (or each string in the ID separated by the
+ '∣' symbol).
</p>
<p>If a record (or set of records) is retrieved by any query derived
from the ID string of a sequence, then the sequence is aligned to the
<ul>
<li>Programs for <a href="msaclient.html">multiple
sequence alignment</a>, made available <em>via</em> <a
- href="JABAWS.html"
- >Java Bioinformatic Analysis Web Service (JABAWS)</a> servers.
+ href="JABAWS.html">Java Bioinformatic Analysis
+ Web Service (JABAWS)</a> servers.
</li>
<li>Jalview SOAP Web Services for <a href="jnet.html">secondary
structure prediction</a> based at the University of Dundee.
</li>
<li>Services for alignment analysis, such as <a
- href="shmr.html"
- >Multi-Harmony</a>.
+ href="shmr.html">Multi-Harmony</a>.
</ul>
<p>
<strong>Web Service Dialog Box</strong>
citation information, and monitors the progress of the
calculation. The cancel button will permanently cancel the job,
but this is only possible for some services.</p> The <a
- href="webServicesPrefs.html"
- >Web Services Preference panel</a> controls the display and appearance
- of the submission and analysis services in the <strong>Web
- Services</strong> menu.
+ href="webServicesPrefs.html">Web Services Preference
+ panel</a> controls the display and appearance of the submission and
+ analysis services in the <strong>Web Services</strong> menu.
</li>
<li>If Jalview encounters problems accessing any services, it
may display a <a href="webServicesPrefs.html#wswarnings">warning
<p>
<strong>More about Jalview's Web Services</strong> <br>
Jalview's distributed computations utilise <a
- href="http://en.wikipedia.org/wiki/SOAP"
- >SOAP</a> and <a
- href="http://en.wikipedia.org/wiki/Representational_State_Transfer"
- >REST</a> web services exposing sequence alignment, analysis, and
- secondary structure prediction programs. Originally, Jalview 2's
- services were maintained by the Barton group at the University of
- Dundee, and ran programs on the Life Sciences High-performance
- Computing Cluster. With the advent of <a
- href="http://www.compbio.dundee.ac.uk/JABAWS"
- >JABAWS</a>, however, it is possible for anyone to host Jalview web
- services.
+ href="http://en.wikipedia.org/wiki/SOAP">SOAP</a> and <a
+ href="http://en.wikipedia.org/wiki/Representational_State_Transfer">REST</a>
+ web services exposing sequence alignment, analysis, and secondary
+ structure prediction programs. Originally, Jalview 2's services were
+ maintained by the Barton group at the University of Dundee, and ran
+ programs on the Life Sciences High-performance Computing Cluster.
+ With the advent of <a href="http://www.compbio.dundee.ac.uk/jabaws">JABAWS</a>,
+ however, it is possible for anyone to host Jalview web services.
</p>
</body>
</html>
JPred4: a protein secondary structure prediction server<br /> <em>Nucleic
Acids Research</em>, <strong>Web Server issue</strong> (first
published 15th April 2015)<br /> <a
- href="http://dx.doi.org/10.1093/nar/gkv332"
- >http://dx.doi.org/10.1093/nar/gkv332</a>
+ href="http://dx.doi.org/10.1093/nar/gkv332">http://dx.doi.org/10.1093/nar/gkv332</a>
</li>
<li>Cole C., Barber J.D. and Barton G.J. (2008) The Jpred 3
secondary structure prediction server <em>Nucleic Acids
</p>
<em>JNet annotation created in Jalview 2.8.2 and later versions
can be displayed on other alignments via the <a
- href="../features/annotation.html#seqannots"
- >Add reference annotation</a> Sequence ID popup menu option.
+ href="../features/annotation.html#seqannots">Add reference
+ annotation</a> Sequence ID popup menu option.
</em>
<em>As of Jalview 2.6, the Jnet service accessed accessed via the
'Secondary structure prediction' submenu should be considered a
<li><a href="http://www.drive5.com/muscle">Muscle</a> (version
3.8.31)</li>
<li><a
- href="http://www.tcoffee.org/Projects_home_page/t_coffee_home_page.html"
- >Tcoffee</a> (version 8.99)</li>
+ href="http://www.tcoffee.org/Projects_home_page/t_coffee_home_page.html">Tcoffee</a>
+ (version 8.99)</li>
<li><a href="http://probcons.stanford.edu/">Probcons</a>
(version 1.12)</li>
</ul>
<strong>Multiple Alignments of Sequences with hidden
columns</strong><br> Multiple alignment services are 'column
separable' analysis operations. If the input contains <a
- href="../features/hiddenRegions.html"
- >hidden columns</a> then each visible segment of the input sequence
- set will be submitted for alignment separately, and the results
- concatenated (with the hidden regions preserved) once all alignment
- functions have completed. Each sub-job's state is reported in its
- own tab:
+ href="../features/hiddenRegions.html">hidden columns</a> then
+ each visible segment of the input sequence set will be submitted for
+ alignment separately, and the results concatenated (with the hidden
+ regions preserved) once all alignment functions have completed. Each
+ sub-job's state is reported in its own tab:
<p>
<center>
<strong>Multiple Multiple Sequence Alignment sub jobs
* along with Jalview. If not, see <http://www.gnu.org/licenses/>.
* The Jalview Authors are detailed in the 'AUTHORS' file.
-->
-<head>Jalview Desktop RSS News Reader
+<head>
</head>
<body>
<p>
<strong>The Jalview Desktop RSS News Reader</strong><br /> The
Jalview Desktop includes a built in news reader for the <a
- href="http://www.jalview.org/feeds/desktop/rss"
- >Jalview Desktop News Channel</a>.
+ href="http://www.jalview.org/feeds/desktop/rss">Jalview
+ Desktop News Channel</a>.
</p>
<p>We will use the desktop news channel to keep you informed of
important updates relevant to users of the Jalview desktop, such as
web service outages and user community events.</p>
- <p>The news reader will be launched automatically when you start
- the Desktop if new items are available. Should you want to browse
- older items, however, you can open it manually from the 'Jalview
- news reader' option in the Desktop's 'Tools' menu.</p>
- <img src="jalviewrssreader.gif" align="center" width="513"
- height="337" alt="Snapshot of the Jalview Desktop's RSS reader"
- />
+ <p>
+ The news reader will be launched automatically when you start the
+ Desktop if new items are available. Should you want to browse older
+ items, however, you can open it manually from the 'Jalview news
+ reader' option in the Desktop's <a href="../menus/desktopMenu.html">'Tools'
+ menu</a>.
+ </p>
+ <br />
+ <div style="text-align: center;">
+ <img src="jalviewrssreader.gif" width="513" height="337"
+ alt="Snapshot of the Jalview Desktop's RSS reader" />
+ </div>
+
+ <br />
<p>
The <em>Jalview news reader</em> was introduced in <a
- href="http://www.jalview.org/releaseHistory.html#Jalview2.7"
- >Jalview version 2.7</a>. Its implementation is based on <a
- href="http://jswingreader.sourceforge.net/"
- >JSwingReader</a>.
+ href="http://www.jalview.org/releaseHistory.html#Jalview2.7">Jalview
+ version 2.7</a>. Its implementation is based on <a
+ href="http://jswingreader.sourceforge.net/">JSwingReader</a>.
</p>
+ <br />
+ <em>If you need to prevent the news-reader opening, then add the
+ <a href="../features/clarguments.html">command-line parameter</a>
+ '-nonews' to Jalview's command-line launch.
+ </em>
</body>
</html>
The <strong>Web Services→Disorder</strong> menu in the
alignment window allows access to protein disorder prediction
services provided by the configured <a
- href="http://www.compbio.dundee.ac.uk/jabaws"
- >JABAWS servers</a>. Each service operates on sequences in the
- alignment or currently selected region (<em>since Jalview
- 2.8.0b1</em>) to identify regions likely to be unstructured or
- flexible, or alternately, fold to form globular domains.
+ href="http://www.compbio.dundee.ac.uk/jabaws">JABAWS
+ servers</a>. Each service operates on sequences in the alignment or
+ currently selected region (<em>since Jalview 2.8.0b1</em>) to
+ identify regions likely to be unstructured or flexible, or
+ alternately, fold to form globular domains.
</p>
<p>
Predictor results include both <a
- href="../features/seqfeatures.html"
- >sequence features</a> and sequence associated <a
- href="../features/annotation.html"
- >alignment annotation</a> rows. Features display is controlled from
- the <a href="../features/featureSettings.html">Feature Settings</a>
+ href="../features/seqfeatures.html">sequence features</a> and
+ sequence associated <a href="../features/annotation.html">alignment
+ annotation</a> rows. Features display is controlled from the <a
+ href="../features/featuresettings.html">Feature Settings</a>
dialog box. Clicking on the ID for a disorder prediction annotation
row will highlight or select (if double clicked) the associated
sequence for that row. You can also use the <em>Sequence
Associated</em> option in the <a
- href="../colourSchemes/annotationColouring.html"
- >Colour By Annotation</a> dialog box to colour sequences according to
- the results of predictors shown as annotation rows.
+ href="../colourSchemes/annotationColouring.html">Colour
+ By Annotation</a> dialog box to colour sequences according to the
+ results of predictors shown as annotation rows.
</p>
<p>JABAWS 2.0 provides four disorder predictors which are
described below:</p>
<td>Sequence Feature &<br />Annotation Row
</td>
<td>Predicts loops/coils according to DSSP definition<a
- href="#dsspstates"
- >[1]</a>.<br />Features mark range(s) of residues predicted as
- loops/coils, and annotation row gives raw value for each
- residue. Value over 0.516 indicates loop/coil.
+ href="#dsspstates">[1]</a>.<br />Features mark range(s)
+ of residues predicted as loops/coils, and annotation row gives
+ raw value for each residue. Value over 0.516 indicates
+ loop/coil.
</td>
</tr>
<tr>
<p>
<strong><a name="ronn"></a><a
- href="http://www.strubi.ox.ac.uk/RONN"
- >RONN</a></strong> <em>a.k.a.</em> Regional Order Neural Network<br />This
- predictor employs an approach known as the 'bio-basis' method to
- predict regions of disorder in sequences based on their local
- similarity with a gold-standard set of disordered protein sequences.
- It yields a set of disorder prediction scores, which are shown as
- sequence annotation below the alignment.
+ href="http://www.strubi.ox.ac.uk/RONN">RONN</a></strong> <em>a.k.a.</em>
+ Regional Order Neural Network<br />This predictor employs an
+ approach known as the 'bio-basis' method to predict regions of
+ disorder in sequences based on their local similarity with a
+ gold-standard set of disordered protein sequences. It yields a set
+ of disorder prediction scores, which are shown as sequence
+ annotation below the alignment.
</p>
<table border="1">
<tr>
</p>
<p>
<strong><a name="iupred"></a><a
- href="http://iupred.enzim.hu/Help.php"
- >IUPred</a></strong><br /> IUPred employs an empirical model to estimate
- likely regions of disorder. There are three different prediction
- types offered, each using different parameters optimized for
- slightly different applications. It provides raw scores based on two
- models for predicting regions of 'long disorder' and 'short
- disorder'. A third predictor identifies regions likely to form
- structured domains.
+ href="http://iupred.enzim.hu/Help.php">IUPred</a></strong><br />
+ IUPred employs an empirical model to estimate likely regions of
+ disorder. There are three different prediction types offered, each
+ using different parameters optimized for slightly different
+ applications. It provides raw scores based on two models for
+ predicting regions of 'long disorder' and 'short disorder'. A third
+ predictor identifies regions likely to form structured domains.
</p>
<table border="1">
<tr>
</table>
<p>
<strong><a name="globplot"></a><a
- href="http://globplot.embl.de/"
- >GLOBPLOT</a></strong><br /> Defines regions of globularity or natively
- unstructured regions based on a running sum of the propensity of
- residues to be structured or unstructured. The propensity is
- calculated based on the probability of each amino acid being
- observed within well defined regions of secondary structure or
- within regions of random coil. The initial signal is smoothed with a
- Savitzky-Golay filter, and its first order derivative computed.
- Residues for which the first order derivative is positive are
- designated as natively unstructured, whereas those with negative
- values are structured.<br />
+ href="http://globplot.embl.de/">GLOBPLOT</a></strong><br /> Defines
+ regions of globularity or natively unstructured regions based on a
+ running sum of the propensity of residues to be structured or
+ unstructured. The propensity is calculated based on the probability
+ of each amino acid being observed within well defined regions of
+ secondary structure or within regions of random coil. The initial
+ signal is smoothed with a Savitzky-Golay filter, and its first order
+ derivative computed. Residues for which the first order derivative
+ is positive are designated as natively unstructured, whereas those
+ with negative values are structured.<br />
<table border="1">
<tr>
<td><strong>Name</strong></td>
a protein sequence multiple alignment that has been sub-divided into
groups containing at least two non-identical protein sequences. An
easy way to create groups is to use the built-in <a
- href="../calculations/tree.html"
- >neighbour-joining or UPGMA tree</a> routines to calculate a tree for
- the alignment, and then click on the tree to subdivide the
- alignment.
+ href="../calculations/tree.html">neighbour-joining or
+ UPGMA tree</a> routines to calculate a tree for the alignment, and
+ then click on the tree to subdivide the alignment.
</p>
<p>
The SHMR service operates on the currently selected visible
region(s) of the alignment. Once submitted, a job progress window
will display status information about your job, including a URL
which allows you to visit the status page on the <a
- href="http://zeus.few.vu.nl/programs/shmrwww/"
- >IBIVU SHMR server</a>.
+ href="http://zeus.few.vu.nl/programs/shmrwww/">IBIVU SHMR
+ server</a>.
</p>
<p>When the job is complete, Jalview will automatically open a new
window containing the alignment and groups that were submitted for
analysis, with additional histograms added portraying the SHMR
scores for each column of the sub-grouped alignment.</p>
<p>
- If you use this service in your work, please cite :<br />
+ If you use this service in your work, please cite :<br />
<a name="shmrref" /> Brandt, B.W.*, Feenstra, K.A*. and Heringa, J.
(2010) Multi-Harmony: detecting functional specificity from sequence
alignment. <a
- href="http://nar.oxfordjournals.org/cgi/content/abstract/gkq415"
- >Nucleic Acids Res. 38: W35-W40.</a> (<em>* joint first authors</em>)
-
+ href="http://nar.oxfordjournals.org/cgi/content/abstract/gkq415">Nucleic
+ Acids Res. 38: W35-W40.</a> (<em>* joint first authors</em>)
<p>
<strong><em>Note:</em></strong> The Multi-Harmony service is
implemented with a prototype of Jalview's RESTful web service client
your web browser. <br> Double-clicking on the ID of a sequence
will open the first URL that can be generated from its sequence ID.
This is often the SRS site, but you can easily configure your own <a
- href="#urllinks"
- >sequence URL links</a>.
+ href="#urllinks">sequence URL links</a>.
</p>
<p>
Other links for a sequence either derived from any other configured
<p>
<strong><a name="urllinks">Configuring URL Links</a></strong> <br>URL
links are defined in the "Connections" tab of the <a
- href="../features/preferences.html"
- >Jalview desktop preferences</a>, or specified as <a
- href="http://www.jalview.org/examples/appletParameters.html#parameters"
- >applet parameters</a>. <br> By default the item "SRS"
- is added to this link menu. This link will show a web page in your
- default browser with the selected sequence id as part of the URL.<br>
+ href="../features/preferences.html">Jalview desktop
+ preferences</a>, or specified as <a
+ href="http://www.jalview.org/examples/appletParameters.html#parameters">applet
+ parameters</a>. <br> By default the item "SRS" is added
+ to this link menu. This link will show a web page in your default
+ browser with the selected sequence id as part of the URL.<br>
In the preferences dialog box, click <strong>new</strong> to add a
new link, and <strong>edit</strong> to modify an existing link, or <strong>delete</strong>
to remove it.<br> You can name the link, this will be displayed
<p>
Some Jalview services, including those provided by <a
- href="JABAWS.html"
- >JABAWS</a>, support a range of parameters and options, enabling you
- to employ the most appropriate settings for the input data. In
- addition to any preset combinations provided by services themselves,
- the Web services parameters dialog box also allows you to create and
- store your own parameter sets, so they can be accessed quickly from
- the presets menu.
+ href="JABAWS.html">JABAWS</a>, support a range of parameters
+ and options, enabling you to employ the most appropriate settings
+ for the input data. In addition to any preset combinations provided
+ by services themselves, the Web services parameters dialog box also
+ allows you to create and store your own parameter sets, so they can
+ be accessed quickly from the presets menu.
</p>
<p>
<Strong>Accessing the parameter dialog box</Strong><br> The
<p>
<center>
<img src="wsparams.gif" align="center" width="480" height="499"
- alt="Analysis Parameters Dialog Box for JABAWS Services"
- > <br> Parameter settings dialog box for JABAWS MAFFT Service
+ alt="Analysis Parameters Dialog Box for JABAWS Services">
+ <br> Parameter settings dialog box for JABAWS MAFFT Service
</center>
</p>
<p>The menu and text box at the top of the dialog box displays the
this), allowing you to provide notes to accompany the parameter set.
The modification of these or any of the option or parameter settings
will enable one or more of the following buttons, that allow you to:
+
<ul>
<li><em>Revert</em> the changes you have made. This will undo
<p>
<center>
<img src="wsprefs.gif" align="center"
- alt="Web Services Preferences Panel" width="571" height="461"
- ><br> Web Services Preference Panel
+ alt="Web Services Preferences Panel" width="571" height="461"><br>
+ Web Services Preference Panel
</center>
</p>
<p>
<center>
<img src="invalidurldialog.gif" align="center"
alt="Web Services Invalid URL Warning dialog box" width="389"
- height="258"
- ><br> Web Services Invalid URL Warning dialog box
+ height="258"><br> Web Services Invalid URL Warning
+ dialog box
</center>
<br>
<strong><em>Note:</em></strong> this warning will be shown if you are
</head>
<body>
<p>
- <strong>What's new ?</strong>
+ <strong>What's new in Jalview 2.10.0b1 ?</strong>
</p>
<p>
- Jalview 2.9.1 is the next major release in the Jalview 2.9 series. Full details are in the
- <a href="releases.html#Jalview.2.9.1">Jalview 2.9.1 Release Notes</a>.
+ Jalview 2.10.0b1 is a patch release for 2.10, the next major release
+ in the Jalview 2 series. Full details are in the <a
+ href="releases.html#Jalview.2.10.0b1">Jalview 2.10b1 Release
+ Notes</a>, but the highlights are below.
</p>
- <p>
- <strong>Highlights in Jalview 2.9.1</strong>
<ul>
+ <li>Drag and drop reinstated for the Jalview desktop on
+ Windows, Linux and older OSX systems.</li>
+ <li>Problems loading local PDB files have been fixed</li>
+ <li>Conservation shading can be disabled for PID and consensus
+ based colour scheme</li>
+ </ul>
+ <p><em>Major highlights of the 2.10.0 Release</em></p>
+ <ul>
+ <li><strong>Ensembl sequence fetcher</strong><br />Annotated
+ Genes, transcripts and proteins can be retrieved via Jalview's new
+ <a href="features/ensemblsequencefetcher.html">Ensembl REST
+ client</a>. Support for import of Ensembl data allows:
+ <ul>
+ <li><strong>Aligned locus view</strong><br />Transcripts
+ retrieved for a gene identifier via the Ensembl or
+ EnsemblGenomes sequence databases are automatically aligned to
+ their reference genome, and introns hidden from the view.</li>
+ <li><strong>Sequence variant data</strong><br />Jalview
+ propagates variant annotation on genomic regions onto
+ transcripts and protein products, complete with associated
+ metadata such as clinical significance.</li>
+ </ul></li>
+ <li><strong>Ensembl and ENA 'show cross-references'
+ support</strong><br />The Calculations menu's <strong>'Show
+ cross-references'</strong> now offers Ensembl as well as EMBLCDS and
+ Uniprot when CDS/Protein mapping data is available for download or
+ display. This allows variant annotation to be added directly to an
+ alignment of UniProt sequences.</li>
+ <li><strong>Working with structures</strong>
+ <ul>
+ <li><strong>More accurate structure mappings</strong><br />
+ Jalview now utilises the PDBe's SIFTS database (at EMBL-EBI)
+ to <a href="features/siftsmapping.html">match structures
+ to UniProt sequences</a>, even for structures containing
+ multiple copies of a sequence.</li>
+ <li><strong>Import structures as mmCIF</strong><br />Jalview
+ now downloads data from the EMBL-EBI's PDBe site as <a
+ href="features/mmcif.html">mmCIF</a>. This allows very large
+ structures to be imported, such as the HIV virus capsid
+ assembly.</li>
+ <li><strong>Chimera users will need to upgrade to
+ 1.11.1</strong><br />If you use Chimera to view structures
+ downloaded by Jalview 2.10, you will need to make sure you are
+ running the latest version of <a href="features/chimera.html">Chimera</a>.</li>
+ </ul></li>
+ <li><strong>UniProt Free Text Search</strong><br />The new
+ search dialog for UniProt allows you to browse and retrieve
+ sequences with free-text search, or structured queries.</li>
+ <li><strong>Reference sequence alignment view</strong><br />
+ Jalview 2.9 introduced support for reference sequences. In 2.10,
+ when a reference sequence is defined for the alignment, the
+ alignment column ruler is now numbered according to the reference
+ sequence. The reference sequence for alignment views can also be
+ saved and restored from Jalview projects.</li>
</ul>
</body>
-YEAR=2014
-AUTHORS=J Procter, AM Waterhouse, M Carstairs, TC Ofoegbu, J Engelhardt, LM Lui, A Menard, D Barton, N Sherstnev, D Roldan-Martinez, M Clamp, S Searle, G Barton
-AUTHORFNAMES=Jim Procter, Andrew Waterhouse, Mungo Carstairs, Tochukwu 'Charles' Ofoegbu, Jan Engelhardt, Lauren Lui, Anne Menard, Daniel Barton, Natasha Sherstnev, David Roldan-Martinez, Michele Clamp, James Cuff, Steve Searle, David Martin & Geoff Barton
+YEAR=2016
+AUTHORS=J Procter, M Carstairs, 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, 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
-->
<class name="jalview.datamodel.xdb.embl.EmblFile">
<map-to xml="ROOT"/>
+ <field name="text" type="string">
+ <bind-xml node="text"/>
+ </field>
<field name="entries" type="jalview.datamodel.xdb.embl.EmblEntry" collection="vector">
<bind-xml name="entry"/>
</field>
_data_column.is_shown_by_default
_data_column.is_searchable
PDB Id;pdb_id;String;g2;40;60;45;true;true
-Title;title;String;g6;300;1500;400;true;false
+Title;title;String;g6;50;1500;400;true;false
Molecule;molecule_name;String;g3;50;400;95;false;true
Molecule Type;molecule_type;String;g3;50;400;95;false;true
Sequence;molecule_sequence;String;g6;50;400;95;false;false
Number of Polymer Entities;number_of_polymer_entities;int;g6;50;400;95;false;false
Number of Bound Entities;number_of_bound_entities;int;g6;50;400;95;false;false
Crystallisation Reservoir;crystallisation_reservoir;String;g6;50;400;95;false;false
-Data Scalling Software;data_scaling_software;String;g4;50;400;95;false;false
+Data Scaling Software;data_scaling_software;String;g4;50;400;95;false;false
Detector;detector;String;g6;50;400;95;false;false
Detector Type;detector_type;String;g6;50;400;95;false;false
Modified Residue Flag;modified_residue_flag;String;g6;50;400;95;false;false
action.create = Create
action.update = Update
action.delete = Delete
-action.snapshot = Snapshot
action.clear = Clear
action.accept = Accept
action.select_ddbb = --- Select Database ---
action.save_as = Save as...
action.save = Save
action.cancel_fetch = Cancel Fetch
-action.save_omit_hidden_columns = Save / Omit Hidden Regions
action.change_font = Change Font
action.change_font_tree_panel = Change Font (Tree Panel)
action.colour = Colour
action.fetch_db_references = Fetch DB References
action.view_flanking_regions = Show flanking regions
label.view_flanking_regions = Show sequence data either side of the subsequences involved in this alignment
-label.str = Str:
-label.seq = Seq:
label.structures_manager = Structures Manager
label.nickname = Nickname:
label.url = URL:
label.input_file_url = Enter URL or Input File
-label.select_feature = Select feature:
+label.select_feature = Select feature
label.name = Name
+label.name\: = Name:
label.name_param = Name: {0}
label.group = Group
+label.group\: = Group:
label.group_name = Group Name
label.group_description = Group Description
label.edit_group_name_description = Edit Group Name/Description
label.colour = Colour:
-label.description = Description:
+label.description = Description
+label.description\: = Description:
label.start = Start:
label.end = End:
label.current_parameter_set_name = Current parameter set name:
label.to_new_alignment = To New Alignment
label.to_this_alignment = Add To This Alignment
label.apply_colour_to_all_groups = Apply Colour To All Groups
-label.modify_identity_thereshold = Modify Identity Threshold...
-label.modify_conservation_thereshold = Modify Conservation Threshold...
+label.modify_identity_threshold = Modify Identity Threshold...
+label.modify_conservation_threshold = Modify Conservation Threshold...
label.input_from_textbox = Input from textbox
label.centre_column_labels = Centre column labels
label.automatic_scrolling = Automatic Scrolling
label.all_but_selected_region = All but Selected Region (Shift+Ctrl+H)
label.selected_region = Selected Region
label.all_sequences_columns = All Sequences and Columns
-label.hide_insertions = Hide columns gapped for selection
label.hide_selected_annotations = Hide selected annotations
label.show_selected_annotations = Show selected annotations
label.group_consensus = Group Consensus
label.font = Font:
label.size = Size:
label.style = Style:
-label.enter_redundancy_threshold = Enter the redundancy threshold
label.calculating = Calculating....
label.modify_conservation_visibility = Modify conservation visibility
label.colour_residues_above_occurence = Colour residues above % occurence
label.example_param = Example: {0}
label.select_file_format_before_saving = You must select a file format before saving!
label.file_format_not_specified = File format not specified
-label.alignment_contains_hidden_columns = The Alignment contains hidden regions (hidden sequences/columns).\nDo you want to save only the visible alignment?
label.couldnt_save_file = Couldn't save file: {0}
label.error_saving_file = Error Saving File
label.remove_from_default_list = Remove from default list?
label.translation_failed = Translation Failed
label.error_when_translating_sequences_submit_bug_report = Unfortunately, something went wrong when translating your sequences.\nPlease take a look in the Jalview java console\nand submit a bug report including the stacktrace.
label.implementation_error = Implementation error:
-label.automatically_associate_pdb_files_with_sequences_same_name = Do you want to automatically associate the {0} PDB files with sequences in the alignment that have the same name?
-label.automatically_associate_pdb_files_by_name = Automatically Associate PDB files by name
+label.automatically_associate_structure_files_with_sequences_same_name = Do you want to automatically associate the {0} structure file(s) with sequences in the alignment that have the same name?
+label.automatically_associate_structure_files_by_name = Automatically Associate Structure files by name
label.ignore_unmatched_dropped_files_info = <html>Do you want to <em>ignore</em> the {0} files whose names did not match any sequence IDs ?</html>
label.ignore_unmatched_dropped_files = Ignore unmatched dropped files?
label.view_name_original = Original
label.enter_view_name = Enter View Name
label.enter_label = Enter label
-label.enter_label_for_the_structure = Enter a label for the structure?
+label.enter_label_for_the_structure = Enter a label for the structure
label.pdb_entry_is_already_displayed = {0} is already displayed.\nDo you want to re-use this viewer ?
label.map_sequences_to_visible_window = Map Sequences to Visible Window: {0}
label.add_pdbentry_to_view = Do you want to add {0} to the view called\n{1}\n
label.features_can_be_added_from_searches_1 = (Features can be added from searches or
label.features_can_be_added_from_searches_2 = from Jalview / GFF features files)
label.calculating_pca= Calculating PCA
-label.reveal_columns = Reveal Columns
label.jalview_cannot_open_file = Jalview can't open file
label.jalview_applet = Jalview applet
label.loading_data = Loading data
label.calculating_tree = Calculating tree
label.state_queueing = queuing
label.state_running = running
-label.state_complete = complete
label.state_completed = finished
label.state_job_cancelled = job cancelled!!
label.state_job_error = job error!
label.chimera_help = Chimera Help
label.close_viewer = Close Viewer
label.confirm_close_chimera = This will close Jalview''s connection to {0}.<br>Do you want to close the Chimera window as well?
-label.chimera_help = Chimera Help
label.all = All
label.sort_by = Sort alignment by
label.sort_by_score = Sort by Score
label.align_structures_using_linked_alignment_views = Align structures using {0} linked alignment views
label.connect_to_session = Connect to session {0}
label.threshold_feature_display_by_score = Threshold the feature display by score.
-label.threshold_feature_no_thereshold = No Threshold
-label.threshold_feature_above_thereshold = Above Threshold
-label.threshold_feature_below_thereshold = Below Threshold
-label.adjust_thereshold = Adjust threshold
+label.threshold_feature_no_threshold = No Threshold
+label.threshold_feature_above_threshold = Above Threshold
+label.threshold_feature_below_threshold = Below Threshold
+label.adjust_threshold = Adjust threshold
label.toggle_absolute_relative_display_threshold = Toggle between absolute and relative display threshold.
label.display_features_same_type_different_label_using_different_colour = Display features of the same type with a different label using a different colour. (e.g. domain features)
label.select_colour_minimum_value = Select Colour for Minimum Value
label.select_colour_maximum_value = Select Colour for Maximum Value
-label.open_new_jmol_view_with_all_structures_associated_current_selection_superimpose_using_alignment = Open a new structure viewer with all structures associated with the current selection and superimpose them using the alignment.
label.open_url_param = Open URL {0}
label.open_url_seqs_param = Open URL ({0}..) ({1} seqs)
label.load_pdb_file_associate_with_sequence = Load a PDB file and associate it with sequence {0}
label.logo = Logo
label.non_positional_features = List Non-positional Features
label.database_references = List Database References
-label.share_selection_across_views = Share selection across views
-label.scroll_highlighted_regions = Scroll to highlighted regions
+#label.share_selection_across_views = Share selection across views
+#label.scroll_highlighted_regions = Scroll to highlighted regions
label.gap_symbol = Gap Symbol
label.prot_alignment_colour = Protein Alignment Colour
label.nuc_alignment_colour = Nucleotide Alignment Colour
label.adjusting_parameters_for_calculation = Adjusting parameters for existing Calculation
label.2d_rna_structure_line = 2D RNA {0} (alignment)
label.2d_rna_sequence_name = 2D RNA - {0}
-label.edit_name_and_description_current_group = Edit name and description of current group.
-label.view_structure_for = View structure for {0}
-label.view_all_structures = View all {0} structures.
-label.view_all_representative_structures = View all {0} representative structures.
-label.open_new_jmol_view_with_all_representative_structures_associated_current_selection_superimpose_using_alignment = Opens a new structure viewer with all representative structures\nassociated with the current selection\nsuperimposed with the current alignment.
-label.associate_structure_with_sequence = Associate Structure with Sequence
+label.edit_name_and_description_current_group = Edit name and description of current group
label.from_file = From File
label.enter_pdb_id = Enter PDB Id (or pdbid:chaincode)
-label.discover_pdb_ids = Discover PDB IDs
label.text_colour = Text Colour
action.set_text_colour = Text Colour...
label.structure = Structure
-label.view_structure = View Structure
-label.view_protein_structure = View Protein Structure
label.show_pdbstruct_dialog = 3D Structure Data...
label.view_rna_structure = VARNA 2D Structure
label.clustalx_colours = Clustalx colours
label.reverse = Reverse
label.reverse_complement = Reverse Complement
label.linked_view_title = Linked CDS and protein view
-label.align = Align
label.extract_scores = Extract Scores
label.get_cross_refs = Get Cross-References
label.sort_alignment_new_tree = Sort Alignment With New Tree
label.add_local_source = Add Local Source
label.set_as_default = Set as Default
label.show_labels = Show labels
-label.background_colour = Background Colour
action.background_colour = Background Colour...
label.associate_nodes_with = Associate Nodes With
label.jalview_pca_calculation = Jalview PCA Calculation
label.add_sbrs_definition = Add a SBRS Definition
label.edit_sbrs_definition = Edit SBRS Definition
label.delete_sbrs_definition = Delete SBRS Definition
-label.your_sequences_have_been_verified = Your sequences have been verified against known sequence databases. Some of the ids have been\n altered, most likely the start/end residue will have been updated.\n Save your alignment to maintain the updated id.\n\n
-label.sequence_names_updated = Sequence names updated
+label.your_sequences_have_been_verified = Your sequences have been verified against known sequence databases.\n(Use Calculate | Show flanking regions to show enclosing sequence.)\nTo preserve data changes, save your alignment.\n\n
+label.sequences_updated = Sequences updated
label.dbref_search_completed = DBRef search completed
label.show_all_chains = Show all chains
label.fetch_all_param = Fetch all {0}
label.invalid_font = Invalid Font
label.separate_multiple_accession_ids = Enter one or more accession IDs separated by a semi-colon ";"
label.separate_multiple_query_values = Enter one or more {0}s separated by a semi-colon ";"
-label.search_all = Enter one or more search values separated by a semi-colon ";" (Note: This Searches the entire database)
+label.search_all = Enter one or more search values separated by a semi-colon ";" (Note: This searches the entire database)
label.replace_commas_semicolons = Replace commas with semi-colons
label.parsing_failed_syntax_errors_shown_below_param = Parsing failed. Syntax errors shown below {0}
label.parsing_failed_unrecoverable_exception_thrown_param = \nParsing failed. An unrecoverable exception was thrown\:\n {0}
option.trim_retrieved_seqs = Trim retrieved sequences
label.trim_retrieved_sequences = When the reference sequence is longer than the sequence that you are working with, only keep the relevant subsequences.
label.use_sequence_id_1 = Use $SEQUENCE_ID$ or $SEQUENCE_ID=/<regex>/=$
-label.use_sequence_id_2 = \nto embed sequence id in URL
+label.use_sequence_id_2 = to embed sequence id in URL
+label.use_sequence_id_3 = Use $SEQUENCE_NAME$ similarly to embed sequence name
+label.use_sequence_id_4 =
label.ws_parameters_for = Parameters for {0}
label.switch_server = Switch server
label.choose_jabaws_server = Choose a server for running this service
label.rest_client_submit = {0} using {1}
label.fetch_retrieve_from =Retrieve from {0}</html>
label.fetch_retrieve_from_all_sources = Retrieve from all {0} sources in {1}<br>First is :{2}<html>
-#label.feature_settings_click_drag = <html>Click/drag feature types up or down to change render order.<br/>Double click to select columns containing feature in alignment/current selection<br/>Pressing Alt will select columns outside features rather than inside<br/>Pressing Shift to modify current selection (rather than clear current selection)<br/>Press CTRL or Command/Meta to toggle columns in/outside features<br/></html>
label.feature_settings_click_drag = Drag up or down to change render order.<br/>Double click to select columns containing feature.
label.transparency_tip = Adjust transparency to 'see through' feature colours.
label.opt_and_params_further_details = see further details by right-clicking
label.service_preset = Service Preset
label.run_with_preset = Run {0} with preset
label.view_service_doc_url = <html>View <a href="{0}">{1}</a></html>
-label.submit_sequence = <html>Submit {0} {1} {2} {3} to<br/>{4}</html>
action.by_title_param = By {0}
-label.alignment = Alignment
-label.secondary_structure_prediction = Secondary Structure Prediction
-label.sequence_database_search = Sequence Database Search
-label.analysis = Analysis
-label.protein_disorder = Protein Disorder
label.source_from_db_source = Sources from {0}
label.from_msname = from {0}
label.superpose_with = Superpose with
-action.do = Do
label.scale_label_to_column = Scale Label to Column
label.add_new_row = Add New Row
label.edit_label_description = Edit Label/Description
label.copied_sequences = Copied sequences
label.cut_sequences = Cut Sequences
label.conservation_colour_increment = Conservation Colour Increment ({0})
-label.percentage_identity_thereshold = Percentage Identity Threshold ({0})
+label.percentage_identity_threshold = Percentage Identity Threshold ({0})
label.error_unsupported_owwner_user_colour_scheme = Unsupported owner for User Colour scheme dialog
label.save_alignment_to_file = Save Alignment to file
label.save_features_to_file = Save Features to File
label.saving_vamsas_doc = Saving VAMSAS Document to {0}
label.load_feature_colours = Load Feature Colours
label.save_feature_colours = Save Feature Colour Scheme
-label.dataset_for = {0} Dataset for {1}
label.select_startup_file = Select startup file
label.select_default_browser = Select default web browser
label.save_tree_as_newick = Save tree as newick file
error.implementation_error_sortbyfeature = Implementation Error - sortByFeature method must be one of FEATURE_SCORE, FEATURE_LABEL or FEATURE_DENSITY.
error.not_yet_implemented = Not yet implemented
error.unknown_type_dna_or_pep = Unknown Type {0} - dna or pep are the only allowed values.
-error.implementation_error_dont_know_thereshold_annotationcolourgradient = Implementation error: don't know about threshold setting for current AnnotationColourGradient.
-error.implementation_error_embeddedpopup_not_null = Implementation error - embeddedPopup must be non-null
-error.invalid_colour_for_mycheckbox = Invalid color for MyCheckBox
-error.implementation_error_unrecognised_render_object_for_features_type = Implementation Error: Unrecognised render object {0} for features of type {1}
-error.implementation_error_unsupported_feature_colour_object = Implementation error: Unsupported feature colour object.
+error.implementation_error_dont_know_threshold_annotationcolourgradient = Implementation error: don't know about threshold setting for current AnnotationColourGradient.
error.invalid_separator_parameter = Invalid separator parameter - must be non-zero length
error.alignment_cigararray_not_implemented = Alignment(CigarArray) not yet implemented
-error.weak_sequencei_equivalence_not_yet_implemented = Weak sequenceI equivalence not yet implemented.
-error.implementation_error_can_only_make_alignmnet_from_cigararray = Implementation Error - can only make an alignment view from a CigarArray of sequences.
error.empty_view_cannot_be_updated = empty view cannot be updated.
error.mismatch_between_number_of_sequences_in_block = Mismatch between number of sequences in block {0} ({1}) and the original view ({2})
error.padding_not_yet_implemented = Padding not yet implemented
error.implementation_bug_cigar_operation = Implementation Bug. Cigar Operation {0} {1} not one of {2}, {3}, or {4}.
error.implementation_error_for_new_cigar = Implementation error for new Cigar(SequenceI)
error.implementation_error_cigar_seq_no_operations = Implementation error: {0}th sequence Cigar has no operations.
-error.implementation_error_jmol_getting_data = Implementation error - Jmol seems to be still working on getting its data - report at http://issues.jalview.org/browse/JAL-1016
error.implementation_error_no_pdbentry_from_index = Implementation error - no corresponding pdbentry (for index {0}) to add sequences mappings to
error.jmol_version_not_compatible_with_jalview_version = Jmol version {0} is not compatible with this version of Jalview. Report this problem at issues.jalview.org
error.not_implemented_remove = Remove: Not implemented
error.not_implemented_clone = Clone: Not implemented
-error.implementation_error_chimera_getting_data = Implementation error - Chimera seems to be still working on getting its data - report at http://issues.jalview.org/browse/JAL-1016
error.call_setprogressbar_before_registering_handler = call setProgressBar before registering the progress bar's handler.
label.cancelled_params = Cancelled {0}
error.implementation_error_cannot_show_view_alignment_frame = Implementation error: cannot show a view from another alignment in an AlignFrame.
-error.implementation_error_dont_know_about_thereshold_setting = Implementation error: don't know about threshold setting for current AnnotationColourGradient.
+error.implementation_error_dont_know_about_threshold_setting = Implementation error: don't know about threshold setting for current AnnotationColourGradient.
error.eps_generation_not_implemented = EPS Generation not yet implemented
error.png_generation_not_implemented = PNG Generation not yet implemented
error.try_join_vamsas_session_another = Trying to join a vamsas session when another is already connected
error.implementation_error_cannot_find_marshaller_for_param_set =Implementation error: Can't find a marshaller for the parameter set
error.implementation_error_old_jalview_object_not_bound =IMPLEMENTATION ERROR: old jalview object is not bound ! ({0})
error.implementation_error_vamsas_doc_class_should_bind_to_type = Implementation Error: Vamsas Document Class {0} should bind to a {1} (found a {2})
-error.implementation_error_jalview_class_should_bind_to_type = Implementation Error: Jalview Class {0} should bind to a {1} (found a {2})
error.invalid_vamsas_rangetype_cannot_resolve_lists = Invalid vamsas RangeType - cannot resolve both lists of Pos and Seg from choice!
error.implementation_error_maplist_is_null = Implementation error. MapList is null for initMapType.
error.implementation_error_cannot_have_null_alignment = Implementation error: Cannot have null alignment property key
error.dbrefsource_implementation_exception =DBRefSource Implementation Exception
error.implementation_error_dbinstance_must_implement_interface = Implmentation Error - getDbInstances must be given a class that implements jalview.ws.seqfetcher.DbSourceProxy (was given{0})
error.implementation_error_must_init_dbsources =Implementation error. Must initialise dbSources
-label.view_controller_toggled_marked = {0} {1} columns containing features of type {2} across {3} sequence(s)
+label.view_controller_toggled_marked = {0} {1} columns {2} features of type {3} across {4} sequence(s)
label.toggled = Toggled
label.marked = Marked
-label.not = not
+label.containing = containing
+label.not_containing = not containing
label.no_feature_of_type_found = No features of type {0} found.
label.submission_params = Submission {0}
label.empty_alignment_job = Empty Alignment Job
label.pca_calculating = Calculating PCA
label.select_foreground_colour = Choose foreground colour
label.select_colour_for_text = Select Colour for Text
-label.adjunst_foreground_text_colour_thereshold = Adjust Foreground Text Colour Threshold
+label.adjunst_foreground_text_colour_threshold = Adjust Foreground Text Colour Threshold
label.select_subtree_colour = Select Sub-Tree Colour
label.create_new_sequence_features = Create New Sequence Feature(s)
label.amend_delete_features = Amend/Delete Features for {0}
exception.mismatched_closing_char = Mismatched closing character {0}
exception.mismatched_opening_char = Mismatched opening character {0} at {1}
exception.invalid_datasource_couldnt_obtain_reader = Invalid datasource. Could not obtain Reader
-exception.index_value_not_in_range = {0}: Index value {1} not in range [0..{2}]
exception.unterminated_cigar_string = Unterminated cigar string
exception.unexpected_operation_cigar_string_pos = Unexpected operation {0} in cigar string (position {1} in {2}
exception.couldnt_parse_responde_from_annotated3d_server = Couldn't parse response from Annotate3d server
exception.pfam_no_sequences_found = No sequences found (PFAM input)
exception.stockholm_invalid_format = This file is not in valid STOCKHOLM format: First line does not contain '# STOCKHOLM'
exception.couldnt_parse_sequence_line = Could not parse sequence line: {0}
-exception.error_parsing_line = Error parsing {0}
exception.unknown_annotation_detected = Unknown annotation detected: {0} {1}
exception.couldnt_store_sequence_mappings = Couldn't store sequence mappings for {0}
exception.matrix_too_many_iteration = Too many iterations in {0} (max is {1})
exception.browser_unable_to_locate = Unable to locate browser: {0}
exception.invocation_target_exception_creating_aedesc = InvocationTargetException while creating AEDesc: {0}
exception.illegal_access_building_apple_evt= IllegalAccessException while building AppleEvent: {0}
-exception.instantiation_creating_aedesc = InstantiationException while creating AEDesc: {0}
exception.unable_to_launch_url = Unable to launch URL: {0}
exception.unable_to_create_internet_config = Unable to create an Internet Config instance: {0}
exception.invocation_target_calling_url = InvocationTargetException while calling openURL: {0}
exception.das_source_doesnt_support_sequence_command = Source {0} does not support the sequence command.
exception.invalid_das_source = Invalid das source: {0}
exception.ebiembl_retrieval_failed_on = EBI EMBL XML retrieval failed on {0}:{1}
-label.no_embl_record_found = # No EMBL record retrieved for {0}:{1}
-label.embl_successfully_parsed = # Successfully parsed the {0} queries into an Alignment
exception.no_pdb_records_for_chain = No PDB Records for {0} chain {1}
exception.unexpected_handling_rnaml_translation_for_pdb = Unexpected exception when handling RNAML translation of PDB data
exception.couldnt_recover_sequence_properties_for_alignment = Couldn't recover sequence properties for alignment
status.fetching_db_refs = Fetching db refs
status.loading_cached_pdb_entries = Loading Cached PDB Entries
status.searching_for_pdb_structures = Searching for PDB Structures
-status.opening_file = opening file
+status.opening_file_for = opening file for
status.colouring_chimera = Colouring Chimera
label.font_doesnt_have_letters_defined = Font doesn't have letters defined\nso cannot be used\nwith alignment data
label.font_too_small = Font size is too small
label.add_jabaws_url = Add new JABAWS URL
label.news_from_jalview = News from http://www.jalview.org
label.cut_paste_alignmen_file = Cut & Paste Alignment File
-label.enter_redundancy_thereshold = Enter the redundancy threshold
-label.select_dark_light_set_thereshold = <html><i>Select a dark and light text colour, then set the threshold to<br>switch between colours, based on background colour</i></html>
+label.enter_redundancy_threshold = Enter the redundancy threshold
+label.select_dark_light_set_threshold = <html><i>Select a dark and light text colour, then set the threshold to<br>switch between colours, based on background colour</i></html>
label.select_feature_colour = Select Feature Colour
label.delete_all = Delete all sequences
warn.delete_all = <html>Deleting all sequences will close the alignment window.<br>Confirm deletion or Cancel.
label.no_colour_selection_warn = Error saving colour scheme
label.open_split_window? = Would you like to open as a split window, with cDNA and protein linked?
label.open_split_window = Open split window
-label.no_mappings = No mappings found
action.no = No
action.yes = Yes
label.for = for
label.select_by_annotation = Select/Hide Columns by Annotation
action.select_by_annotation = Select/Hide Columns by Annotation...
label.threshold_filter = Threshold Filter
-action.hide = Hide
-action.select = Select
label.alpha_helix = Alpha Helix
label.beta_strand = Beta Strand
label.turn = Turn
label.select_all = Select All
label.structures_filter = Structures Filter
label.search_filter = Search Filter
-label.description = Description
label.include_description= Include Description
action.back = Back
label.hide_insertions = Hide Insertions
label.mark_as_representative = Mark as representative
label.open_jabaws_web_page = Open JABAWS web page
-label.opens_the_jabaws_server_homepage = Opens the JABAWS server's homepage in web browser
label.pdb_sequence_fetcher = PDB Sequence Fetcher
label.result = result
label.results = results
status.obtaining_mapping_with_sifts = Obtaining mapping with SIFTS
status.obtaining_mapping_with_nw_alignment = Obtaining mapping with NW alignment
status.exporting_alignment_as_x_file = Exporting alignment as {0} file
+label.column = Column
+label.cant_map_cds = Unable to map CDS to protein\nCDS missing or incomplete
+label.operation_failed = Operation failed
action.create = Crear
action.update = Actualizar
action.delete = Borrar
-action.snapshot = Imagen
action.clear = Limpiar
action.accept = Aceptar
action.select_ddbb = --- Seleccionar base de datos ---
action.save_as = Guardar como
action.save = Guardar
action.cancel_fetch = Cancelar búsqueda
-action.save_omit_hidden_columns = Guardar / Omitir las columnas ocultas
action.change_font = Cambiar Fuente
action.change_font_tree_panel = Cambiar fuente (panel del árbol)
action.colour = Color
action.fetch_db_references = Recuperar referencias a base de datos
action.view_flanking_regions = Mostrar flancos
label.view_flanking_regions = Mostrar los datos de la secuencia a ambos lados de las subsecuencias implicadas en este alineamiento
-label.str = Str:
-label.seq = Seq:
label.structures_manager = Administrar estructuras
label.nickname = Sobrenombre:
label.url = URL:
label.input_file_url = Introducir URL en el fichero de entrada
-label.select_feature = Seleccionar función:
-label.name = Nombre:
+label.select_feature = Seleccionar caracterÃstica
+label.name = Nombre
+label.name\: = Nombre:
label.name_param = Nombre: {0}
-label.group = Grupo:
+label.group = Grupo
+label.group\: = Grupo:
label.group_name = Nombre del grupo
label.group_description = Descripción del grupo
label.edit_group_name_description = Editar nombre/descripción del grupo
label.colour = Color:
-label.description = Descripción:
+label.description = Descripción
+label.description\: = Descripción:
label.start = Comenzar:
label.end = Terminar:
label.current_parameter_set_name = Nombre actual del conjunto de parámetros:
label.to_new_alignment = A nuevo alineamiento
label.to_this_alignment = Añadir a este alineamiento
label.apply_colour_to_all_groups = Aplicar color a todos los grupos
-label.modify_identity_thereshold = Modificar el umbral de identidad...
-label.modify_conservation_thereshold = Modificar el umbral de conservación...
+label.modify_identity_threshold = Modificar el umbral de identidad...
+label.modify_conservation_threshold = Modificar el umbral de conservación...
label.input_from_textbox = Introducir desde el cuadro de texto
label.centre_column_labels = Centrar las etiquetas de las columnas
label.automatic_scrolling = Desplazamiento automático
label.about = Acerca de...
label.show_sequence_limits = Mostrar los lÃmites de la secuencia
label.feature_settings = Ajustar funciones...
-label.sequence_features = Funciones de la secuencia
label.all_columns = Todas las columnas
label.all_sequences = Todas las secuencias
label.selected_columns = Columnas seleccionadas
label.font = Fuente:
label.size = Talla:
label.style = Estilo:
-label.enter_redundancy_threshold = Introducir el umbral de redundancia
label.calculating = Calculando....
label.modify_conservation_visibility = Modificar la visibilidad de conservación
label.colour_residues_above_occurence = Residuos de color por encima del % de aparición
label.select_das_service_from_table = Seleccionar servicio DAS de la tabla para leer una descripción completa aquÃ.
label.session_update = Actualizar sesión
label.new_vamsas_session = Nueva sesión Vamsas
-label.load_vamsas_session = Cargar sesión Vamsas
-label.save_vamsas_session = Guardar sesión Vamsas
action.save_vamsas_session = Guardar Sesión Vamsas
label.select_vamsas_session_opened_as_new_vamsas_session= Selecciones una sesión vamsas para abrirla como una nueva sesión.
label.open_saved_vamsas_session = Abrir una sesión VAMSAS guardada
label.example_param = Ejemplo: {0}
label.select_file_format_before_saving = Debe seleccionar un formato de fichero antes de guardar!
label.file_format_not_specified = Formato de fichero no especificado
-label.alignment_contains_hidden_columns = El alineamiento contiene columnas ocultas.\nQuieres guardar s\u00F3lo el alineamiento visible?
label.couldnt_save_file = No se pudo guardar el fichero: {0}
label.error_saving_file = Error guardando el fichero
label.remove_from_default_list = eliminar de la lista de defectuosos?
label.translation_failed = Translation Failed
label.error_when_translating_sequences_submit_bug_report = Desafortunadamente, algo fue mal a la hora de traducir tus secuencias.\nPor favor, revisa la consola Jalview java \ny presenta un informe de error que incluya el seguimiento.
label.implementation_error = Error de implementación:
-label.automatically_associate_pdb_files_with_sequences_same_name = Quieres asociar automáticamente los {0} ficheros PDB con las secuencias del alineamiento que tengan el mismo nombre?
-label.automatically_associate_pdb_files_by_name = Asociar los ficheros PDB por nombre automáticamente
+label.automatically_associate_structure_files_with_sequences_same_name = Quieres asociar automáticamente los {0} ficheros structure con las secuencias del alineamiento que tengan el mismo nombre?
+label.automatically_associate_structure_files_by_name = Asociar los ficheros structure por nombre automáticamente
label.ignore_unmatched_dropped_files_info = Quieres <em>ignorar</em> los {0} ficheros cuyos nombres no coincidan con ningún IDs de las secuencias ?
label.ignore_unmatched_dropped_files = Ignorar los ficheros sin coincidencias?
-label.enter_view_name = Introducir nombre visible (¿?)
+label.enter_view_name = Introduzca un nombre para la vista
label.enter_label = Introducir etiqueta
-label.enter_label_for_the_structure = Introducir una etiqueta para la estructura?
+label.enter_label_for_the_structure = Introducir una etiqueta para la estructura
label.pdb_entry_is_already_displayed = {0} Ya est\u00E1 mostrado.\nQuieres volver a usar este visor?
label.map_sequences_to_visible_window = Mapa de secuencias en ventana visible: {0}
label.add_pdbentry_to_view = Quieres a\u00F1adir {0} a la vista llamada\n{1}\n
label.features_can_be_added_from_searches_1 = (Las funciones pueden ser añadidas de búsquedas o
label.features_can_be_added_from_searches_2 = de ficheros de funciones Jalview / GFF)
label.calculating_pca= Calculando PCA
-label.reveal_columns = Mostrar Columnas
label.jalview_cannot_open_file = Jalview no puede abrir el fichero
label.jalview_applet = Aplicación Jalview
label.loading_data = Cargando datos
label.calculating_tree = Calculando árbol
label.state_queueing = En cola
label.state_running = Procesando
-label.state_complete = Completar
label.state_completed = Finalizado
label.state_job_cancelled = ¡Trabajo cancelado!
label.state_job_error = Error del trabajo!
label.load_features_annotations = Cargar caracterÃsticas/anotaciones ...
label.export_features = Exportar caracterÃsticas...
label.export_annotations = Exportar anotaciones ...
-label.jalview_copy = Copiar (sólo Jalview)
-label.jalview_cut = Cortar (sólo Jalview)
label.to_upper_case = Pasar a mayúsculas
label.to_lower_case = Pasar a minúsculas
label.toggle_case = Alternar mayúsculas y minúsculas
label.edit_sequence = Editar secuencia
label.edit_sequences = Editar secuencias
label.sequence_details = Detalles de la secuencia
-label.jmol_help = Ayuda de Jmol
-label.all = Todo
+label.jmol_help = Ayuda de Jmol
+# Todos/Todas is gender-sensitive, but currently only used for feminine (cadena / anotación)!
+label.all = Todas
label.sort_by = Ordenar por
label.sort_by_score = Ordenar por puntuación
label.sort_by_density = Ordenar por densidad
label.align_structures_using_linked_alignment_views = Alinear las estructuras utlizando las {0} vistas de alineamiento enlazadas
label.connect_to_session = Conectar a la sesión {0}
label.threshold_feature_display_by_score = Filtrar la caracterÃstica mostrada por puntuación.
-label.threshold_feature_no_thereshold = Sin umbral
-label.threshold_feature_above_thereshold = Por encima del umbral
-label.threshold_feature_below_thereshold = Por debajo del umbral
-label.adjust_thereshold = Ajustar umbral
+label.threshold_feature_no_threshold = Sin umbral
+label.threshold_feature_above_threshold = Por encima del umbral
+label.threshold_feature_below_threshold = Por debajo del umbral
+label.adjust_threshold = Ajustar umbral
label.toggle_absolute_relative_display_threshold = Cambiar entre mostrar el umbral absoluto y el relativo.
label.display_features_same_type_different_label_using_different_colour = Mostrar las caracterÃsticas del mismo tipo con una etiqueta diferente y empleando un color distinto (p.e. caracterÃsticas del dominio)
label.select_colour_minimum_value = Seleccionar el color para el valor mÃnimo
label.select_colour_maximum_value = Seleccionar el color para el valor máximo
-label.open_new_jmol_view_with_all_structures_associated_current_selection_superimpose_using_alignment = Abrir una nueva vista Jmol con todas las estructuras asociadas con la selección acxtual y superponer las utilizando el alineamiento.
label.open_url_param = Abrir URL {0}
label.open_url_seqs_param = Abrir URL ({0}..) ({1} secuencias)
label.load_pdb_file_associate_with_sequence = Cargar un fichero PDB y asociarlo con la secuencia {0}
label.logo = Logo
label.non_positional_features = CaracterÃsticas no posicionales
label.database_references = Referencias a base de datos
-label.share_selection_across_views = Compartir la selección en todas las vistas
-label.scroll_highlighted_regions = Desplazarse hasta las regiones resaltadas
+#label.share_selection_across_views = Compartir la selección en todas las vistas
+#label.scroll_highlighted_regions = Desplazarse hasta las regiones resaltadas
label.gap_symbol = SÃmbolo del hueco
-label.alignment_colour = Color del alineamiento
label.address = Dirección
label.port = Puerto
label.default_browser_unix = Navegador por defecto (Unix)
label.adjusting_parameters_for_calculation = Ajustar los parámetros para el cálculo existente
label.2d_rna_structure_line = 2D RNA {0}
label.2d_rna_sequence_name = 2D RNA - {0}
-label.edit_name_and_description_current_group = Editar el nombre y la descripción del grupo actual.
-label.view_structure_for = Visualizar la estructura para {0}
-label.view_all_structures = Visualizar todas las {0} estructuras.
-label.view_all_representative_structures = Visualizar todas las {0} estructuras representativas.
-label.open_new_jmol_view_with_all_representative_structures_associated_current_selection_superimpose_using_alignment = Abrir una nueva vista de Jmol con todas las estructuras representativas\nasociadas con la selecci\u00F3n actual\nsuperpuesta con el alineamiento actual.
-label.associate_structure_with_sequence = Asociar estructura con la secuencia
+label.edit_name_and_description_current_group = Editar el nombre y la descripción del grupo actual
label.from_file = desde fichero
label.enter_pdb_id = Introducir PDB Id
-label.discover_pdb_ids = Buscar PDB ids
label.text_colour = Color del texto
label.structure = Estructura
-label.view_structure = Visualizar estructura
label.clustalx_colours = Colores de Clustalx
label.above_identity_percentage = Sobre % identidad
label.create_sequence_details_report_annotation_for = Anotación para {0}
label.add_local_source = Añadir fuente local
label.set_as_default = Establecer por defecto
label.show_labels = Mostrar etiquetas
-label.background_colour = Color de fondo
label.associate_nodes_with = Asociar nodos con
label.jalview_pca_calculation = Cálculo del PCA por Jalview
label.link_name = Nombre del enalce
label.add_sbrs_definition = Añadir una definición SBRS
label.edit_sbrs_definition = Editar una definición SBRS
label.delete_sbrs_definition = Borrar una definición SBRS
-label.your_sequences_have_been_verified = Sus secuencias has sido verificadas en una base de datos de secuencias conocidas. Algunos de sus ID se han alterado y\n, probablemente, el residuo de inicio/fin se haya actualizado.\nGuarde su alineamiento para mantener el ID actualizado.\n\n
-label.sequence_names_updated = Nombres de secuencia actualizados
+label.your_sequences_have_been_verified = Sus secuencias has sido verificadas en una base de datos de secuencias conocidas.\n(Usar Calcular | Mostrar flancos para ver ampliación.)\nPara mantener los datos actualizados, guarde su alineamiento.\n\n
+label.sequences_updated = Secuencias actualizadas
label.dbref_search_completed = Búsqueda de DBRef terminada
label.show_all_chains = Mostrar todas las cadenas
label.fetch_all_param = Recuperar todas {0}
option.trim_retrieved_seqs = Ajustar las secuencias recuperadas
label.trim_retrieved_sequences = Cuando la secuencia de referencia es más larga que la secuencia con la que está trabajando, sólo se mantienen las subsecuencias relevantes.
label.use_sequence_id_1 = Utilice $SEQUENCE_ID$ o $SEQUENCE_ID=/<regex>/=$
-label.use_sequence_id_2 = \nto para embeber el id de la secuencia en una URL
+label.use_sequence_id_2 = para embeber el id de la secuencia en una URL
+label.use_sequence_id_3 = Utilice $SEQUENCE_NAME$ de manera similar para embeber
+label.use_sequence_id_4 = el nombre de la secuencia
label.ws_parameters_for = Parámetros para {0}
label.switch_server = Cambiar servidor
label.open_jabaws_web_page = Abra el página principal del servidor JABAWS en un navegador web
label.service_preset = Preselección del servicio
label.run_with_preset = Ejecutar {0} con preselección
label.view_service_doc_url = Visualizar <a href="{0}">{1}</a></html>
-label.submit_sequence = Enviar {0} {1} {2} {3} a<br/>{4}</html>
action.by_title_param = por {0}
-label.alignment = Alineamiento
-label.secondary_structure_prediction = Predicción de la estructura secundaria
-label.sequence_database_search = Búsqueda en base de datos de secuencias
-label.analysis = Análisis
-label.protein_disorder = Desorden en la proteÃna
label.source_from_db_source = Fuentes de {0}
label.from_msname = de {0}
label.superpose_with = Superponer con...
-action.do = Hacer
label.scale_label_to_column = Ajustar la etiqueta a la columna
label.add_new_row = Añadir nuevo fila
label.edit_label_description = Editar etiqueta/descripción
label.copied_sequences = Secuencias copiadas
label.cut_sequences = Cortar secuencias
label.conservation_colour_increment = Incremento de Conservación del Color ({0})
-label.percentage_identity_thereshold = Umbral del Porcentaje de Identidad ({0})
+label.percentage_identity_threshold = Umbral del Porcentaje de Identidad ({0})
label.error_unsupported_owwner_user_colour_scheme = Propietario no soportado para el diálogo del Esquema Cromático del Usuario
label.save_alignment_to_file = Guardar Alineamiento en fichero
label.save_features_to_file = Guardar CaracterÃsticas en un fichero
label.saving_vamsas_doc = Guardando el documento VAMSAS en {0}
label.load_feature_colours = Cargar colores de caracterÃsticas
label.save_feature_colours = Guardar esquema cromático de caracterÃsticas
-label.dataset_for = {0} conjunto de datos para {1}
label.select_startup_file = Seleccionar fichero de arranque
label.select_default_browser = Seleccionar navegador web por defecto
label.save_tree_as_newick = Guardar árbol como fichero newick
error.implementation_error_sortbyfeature = Error de implementación - sortByFeature debe ser uno de FEATURE_SCORE, FEATURE_LABEL o FEATURE_DENSITY.
error.not_yet_implemented = No se ha implementado todavÃa
error.unknown_type_dna_or_pep = Tipo desconocido {0} - dna o pep son los únicos valores permitidos
-error.implementation_error_dont_know_thereshold_annotationcolourgradient = Error de implementación: no se conoce el valor umbral para el AnnotationColourGradient actual.
-error.implementation_error_embeddedpopup_not_null = Error de implementación - embeddedPopup debe ser no nulo.
-error.invalid_colour_for_mycheckbox = Color no válido para MyCheckBox
-error.implementation_error_unrecognised_render_object_for_features_type = Error de implementación: no se reconoce el objeto de representación {0} para las caracterÃsticas de tipo {1}
-error.implementation_error_unsupported_feature_colour_object = Error de implementación: objeto de color de caracterÃsticas no soportado.
+error.implementation_error_dont_know_threshold_annotationcolourgradient = Error de implementación: no se conoce el valor umbral para el AnnotationColourGradient actual.
error.invalid_separator_parameter = Separador de parámetros no válido - debe tener longitud mayor que cero
error.alignment_cigararray_not_implemented = Alignment(CigarArray) no se ha implementado todavÃa
-error.weak_sequencei_equivalence_not_yet_implemented = Equivalencia débil sequenceI no se ha implementado todavÃa.
-error.implementation_error_can_only_make_alignmnet_from_cigararray = Error de implementación - sólo se puede construir un vista de alineamiento a partir de una CigarArray de secuencias.
error.empty_view_cannot_be_updated = una vista vacÃa no se puede actualizar.
error.mismatch_between_number_of_sequences_in_block = No hay coincidencia entre el número de secuencias en el bloque {0} ({1}) y la vista original ({2})
error.padding_not_yet_implemented = El relleno no se ha implementado todavÃa
error.implementation_bug_cigar_operation = Bug de implementación. La operación Cigar {0} {1} no es ni {2}, ni {3} ni {4}.
error.implementation_error_for_new_cigar = Error de implementación en new Cigar(SequenceI)
error.implementation_error_cigar_seq_no_operations = Error de implementación: la {0}a secuencia Cigar no tiene operaciones.
-error.implementation_error_jmol_getting_data = Error de implementación - Jmol parece estar todavÃa intentando recuperar sus datos - informe de ello en http://issues.jalview.org/browse/JAL-1016
error.implementation_error_no_pdbentry_from_index = Error de implementación - no existe la correspondiente entrada pdb (para el Ãndice {0}) para añadir el mapeo de secuencias a
error.jmol_version_not_compatible_with_jalview_version = La versión {0} de Jmol no es compatible con esta versión de Jalview. Informe de este problema en http://issues.jalview.org
error.not_implemented_remove = Borrar: no implementado
error.not_implemented_clone = Clonar: no implementado
-error.implementation_error_chimera_getting_data = Error de implementación - Chimera parece estar todavÃa intentando recuperar sus datos - informe de ello en http://issues.jalview.org/browse/JAL-1016
error.call_setprogressbar_before_registering_handler = llamada a setProgressBar antes de registrar el manejador de la barra de estado
label.cancelled_params = {0} cancelado
error.implementation_error_cannot_show_view_alignment_frame = Error de implementación: no es posible mostrar una vista de otro alineamiento en un AlignFrame.
-error.implementation_error_dont_know_about_thereshold_setting = Error de implementación: no se conoce la configuración del umbral para el AnnotationColourGradient actual.
+error.implementation_error_dont_know_about_threshold_setting = Error de implementación: no se conoce la configuración del umbral para el AnnotationColourGradient actual.
error.eps_generation_not_implemented = La generación de EPS no se ha implementado todavÃa
error.png_generation_not_implemented = La generación de PNG no se ha implementado todavÃa
error.try_join_vamsas_session_another = Tratando de establecer una sesión VAMSAS cuando ya habÃa otra conectada
error.implementation_error_cannot_find_marshaller_for_param_set =Error de implementación: no puede encontrar un marshaller para el conjunto de parámetros
error.implementation_error_old_jalview_object_not_bound =Error de implementación: ¡el objeto Jalview antiguo no está enlazado! ({0})
error.implementation_error_vamsas_doc_class_should_bind_to_type = Error de implementación: la clase de documento VAMSAS {0} debe enlazar a {1} (pero se ha encontrado que lo está a {2})
-error.implementation_error_jalview_class_should_bind_to_type = Error de implementación: la clase Jalview {0} debe enlazar a {1} (pero se ha encontrado que lo está a {2})
error.invalid_vamsas_rangetype_cannot_resolve_lists = RangeType VAMSAS no válido - ¡no es posible resolver ambas listas de Pos y Seg con los valores elegidos!
error.implementation_error_maplist_is_null = Error de implementación. MapList es nulo en initMapType.
error.implementation_error_cannot_have_null_alignment = Error de implementación: no es posible tener una clave nula en el alineamiento
error.dbrefsource_implementation_exception = Excepción de implementación DBRefSource
error.implementation_error_dbinstance_must_implement_interface = Error de Implementación- getDbInstances debe recibir una clase que implemente jalview.ws.seqfetcher.DbSourceProxy (recibió {0})
error.implementation_error_must_init_dbsources =Error de implementación. Debe inicializar dbSources
-label.view_controller_toggled_marked = {0} {1} columnas conteniendo caracterÃsticas del tipo {2} en {3} secuencia(s)
+label.view_controller_toggled_marked = {0} {1} columnas {2} caracterÃsticas del tipo {3} en {4} secuencia(s)
label.toggled = Invertida
label.marked = Marcada
-label.not = no
+label.containing = conteniendo
+label.not_containing = no conteniendo
label.no_feature_of_type_found = No se han encontrado caracterÃsticas del tipo {0}.
label.submission_params = EnvÃo {0}
label.empty_alignment_job = Trabajo de alineamiento vacÃo
label.pca_calculating = Calculando PCA
label.select_foreground_colour = Escoger color del primer plano
label.select_colour_for_text = Seleccione el color del texto
-label.adjunst_foreground_text_colour_thereshold = Ajustar el umbral del color del texto en primer plano
+label.adjunst_foreground_text_colour_threshold = Ajustar el umbral del color del texto en primer plano
label.select_subtree_colour = Seleccioanr el color del sub-árbol
label.create_new_sequence_features = Crear nueva(s) caracterÃstica(s) de secuencia
label.amend_delete_features = Arrelgar/Borrar caracterÃsticas de {0}
exception.mismatched_closing_char = Carácter de cierre discordante {0}
exception.mismatched_opening_char = Carácter de apertura discordante {0} en {1}
exception.invalid_datasource_couldnt_obtain_reader = Fuente de datos no válida. No es posible obtener el Reader
-exception.index_value_not_in_range = {0}: el valor del Ãndice {1} en se encuentra en el rango [0..{2}]
exception.unterminated_cigar_string = Cadena cigar sin terminar
exception.unexpected_operation_cigar_string_pos = Operación no esperada {0} en una cadena cigar (posición {1} en {2})
exception.couldnt_parse_responde_from_annotated3d_server = No es posible parsear la respuesta procedente del servidor Annotate3d
exception.pfam_no_sequences_found = No se han encontrado secuencias (entrada PFAM)
exception.stockholm_invalid_format = Este fichero no es tiene un formato STOCKHOLM válido: la primera lÃnea no contiene '# STOCKHOLM'
exception.couldnt_parse_sequence_line = No es posible parse la lÃnea de secuencia: {0}
-exception.error_parsing_line = Error parseando {0}
exception.unknown_annotation_detected = Anotación desconocida detectada: {0} {1}
exception.couldnt_store_sequence_mappings = No es posible almacenar los mapeos de secuencia para {0}
exception.matrix_too_many_iteration = Demasiadas iteraciones en {0} (el máximo es {1})
exception.browser_unable_to_locate = Imposible encontrar el navegador: {0}
exception.invocation_target_exception_creating_aedesc = InvocationTargetException mientras se creaba AEDesc: {0}
exception.illegal_access_building_apple_evt= IllegalAccessException mientras se construÃa AppleEvent: {0}
-exception.instantiation_creating_aedesc = InstantiationException mientras se creaba AEDesc: {0}
exception.unable_to_launch_url = Imposible lanzar la URL: {0}
exception.unable_to_create_internet_config = Imposible crear una instancia de configuración de Internet: {0}
exception.invocation_target_calling_url = InvocationTargetException mientras se invocaba openURL: {0}
exception.das_source_doesnt_support_sequence_command = La fuente {0} no soporta el comando sequence.
exception.invalid_das_source = Fuente DAS no válida: {0}
exception.ebiembl_retrieval_failed_on = La recuperación de datos EBI EMBL XML ha fallado en {0}:{1}
-label.no_embl_record_found = # No se ha recuperado ningún registro EMBL de {0}:{1}
-label.embl_successfully_parsed = # Se han parseado con éxito las consultas {0} en un alineamiento
exception.no_pdb_records_for_chain = No se han encontrado registros {0} para la cadena {1}
exception.unexpected_handling_rnaml_translation_for_pdb = Excepcion inesperada cuando se traducÃan a RNAML los datos PDB
exception.couldnt_recover_sequence_properties_for_alignment = No es posible recuperar las propiedades de la secuencia para el alineamiento
label.add_jabaws_url = Añadir nueva JABAWS URL
label.news_from_jalview = Noticias de http://www.jalview.org
label.cut_paste_alignmen_file = Cortar & Pegar fichero de alineamiento
-label.enter_redundancy_thereshold = Introducir el umbral de redundancia
-label.select_dark_light_set_thereshold = <i>Seleccionar un color oscuro y un color claro para el texto y establecer el umbral en que<br>cambiar entre colores, basándose en el color de fondo</i>
+label.enter_redundancy_threshold = Introducir el umbral de redundancia
+label.select_dark_light_set_threshold = <i>Seleccionar un color oscuro y un color claro para el texto y establecer el umbral en que<br>cambiar entre colores, basándose en el color de fondo</i>
label.select_feature_colour = Seleccionar color de las caracterÃsticas
label.ignore_gaps_consensus = Ignorar huecos en el consenso
label.show_group_histogram = Mostrar histograma de grupo
info.invalid_msa_notenough=No suficientes datos de sequencia para alinear
label.result=resultado
label.results=resultados
-label.no_mappings=No hay mapeados encontrados
label.struct_from_pdb=Procesar la estructura secundaria PDB
label.hide_selected_annotations=Ocultar anotaciones seleccionados
info.select_annotation_row=Seleccionar Fila de Anotaciones
action.yes=SÃ
label.export_settings=Exportar Ajustes
label.linked_view_title=Vista vinculada de cDNA y proteÃna
-label.view_protein_structure=Ver Estructura Proteica
label.couldnt_read_data=No se pudo leer los datos
-status.opening_file=abriendo fichero
+status.opening_file_for=abriendo fichero para
label.except_selected_sequences=Todo excepto secuencias seleccionadas
label.structure_chooser_no_of_structures=Selector de Estructuras - {0} Encontró ({1})
label.search_filter=filtro de búsqueda
action.export_features=Exportar CaracterÃsticas
error.invalid_regex=Expresión regular inválida
label.autoadd_temp=Añadir anotación factor de temperatura al alineamiento
-tooltip.rnalifold_settings=Modificar la configuración de la predicción RNAAlifold. Úselo para ocultar o mostrar resultados del cálculo de RNA, o cambiar parámetros de el plegado de RNA.
label.chimera_path_tip=Jalview intentará primero las rutas introducidas aquÃ, Y si no las rutas usuales de instalación
label.structure_chooser=Selector de Estructuras
label.structure_chooser_manual_association=Selector de Estructuras - asociación manual
label.show_pdbstruct_dialog=Datos de Estructura 3D...
label.hide_all=Ocultar todos
label.invert=Invertir
-label.pdb_sequence_getcher=Buscador de Secuencias PDB
tooltip.aacon_settings=Cambiar ajustes para cálculos AACon
-label.align=Alinear
label.mark_as_representative=Marcar como representativa
label.include_description=Incluir Descripción
label.for=para
label.protein=ProteÃna
warn.oneseq_msainput_selection=La selección actual sólo contiene una única secuencia. ¿Quieres enviar todas las secuencias para la alineación en su lugar?
label.use_rnaview=Usar RNAView para estructura secondaria
-label.opens_the_jabaws_server_homepage=Abre la página de inicio del servidor JABAWS en navegador
label.search_all=Introducir uno o más valores de búsqueda separados por punto y coma ";" (Nota: buscará en toda la base de datos PDB)
label.confirm_close_chimera=Cerrará la conexión de Jalview a {0}.<br>¿Quieres cerrar la ventana Chimera también?
tooltip.rnalifold_calculations=Se calcularán predicciones de estructura secondaria de RNA para el alineaminento, y se actualizarán si se efectuan cambios
-Calcular predicciónes de estructura secondaria para el alineamiento
+tooltip.rnalifold_settings=Modificar la configuración de la predicción RNAAlifold. Úselo para ocultar o mostrar resultados del cálculo de RNA, o cambiar parámetros de el plegado de RNA.
label.show_selected_annotations=Mostrar anotaciones seleccionadas
status.colouring_chimera=Coloreando Chimera
label.configure_displayed_columns=Configurar Columnas Mostradas
-exception.pdb_server_error=Error desde el servidor PDB
exception.resource_not_be_found=El recurso solicitado no se ha encontrado
label.aacon_calculations=cálculos AACon
label.pdb_web-service_error=Error de servicio web PDB
warn.delete_all=<html>Borrar todas las secuencias cerrará la ventana del alineamiento.<br>Confirmar o Cancelar.
label.select_all=Seleccionar Todos
label.alpha_helix=Hélice Alfa
-label.sequence_details_for=Detalles de secuencia para {0}
label.chimera_help=Ayuda para Chimera
label.find_tip=Buscar alineamiento, selección o IDs de secuencia para una subsecuencia (sin huecos)
-exception.pdb_server_unreachable=Jalview no puede conectar con el servidor PDBE Solr.\nPor favor, asegúrese de que está conectado a Internet y vuelva a intentarlo.
label.structure_viewer=Visualizador de estructura for defecto
label.embbed_biojson=Incrustar BioJSON al exportar HTML
label.transparency_tip=Ajustar la transparencia a "ver a través" los colores de las caracterÃsticas.
info.invalid_msa_input_mininfo=Necesita por lo menos dos secuencias con al menos 3 residuos cada una, sin regiones ocultas entre ellas.
label.chimera_missing=Visualizador de estructura Chimera no encontrado.<br/>Por favor, introduzca la ruta de Chimera,<br/>o descargar e instalar la UCSF Chimera.
label.save_as_biojs_html=Guardar como HTML BioJs
-exception.pdb_rest_service_no_longer_available=Servicios Rest PDB ya no están disponibles!
exception.fts_server_unreachable=Jalview no puede conectar con el servidor {0}. \nPor favor asegúrese de que está conectado a Internet y vuelva a intentarlo.
exception.outofmemory_loading_mmcif_file=Sin memoria al cargar el fichero mmCIF
label.hide_columns_not_containing=Ocultar las columnas que no contengan
status.fetching_3d_structures_for=Buscando la estructura 3D para {0}
status.fetching_3d_structures_for_selected_entries=Buscando las estructuras 3D para entradas seleccionadas...
status.fetching_dbrefs_for_sequences_without_valid_refs=Buscando referencias para {0} secuencia(s) sin referencia válida necesaria para mapeado SIFTS
-status.obtaining_mapping_with_nw_alignment=Obteniendo mapeo por alineamiento Needleman y Wunsch
\ No newline at end of file
+status.obtaining_mapping_with_nw_alignment=Obteniendo mapeo por alineamiento Needleman y Wunsch
+status.exporting_alignment_as_x_file = Exportando alineamiento como fichero tipo {0}
+label.column = Columna
+label.cant_map_cds = No se pudo mapear CDS a proteÃna\nDatos CDS faltantes o incompletos
+label.operation_failed = Operación fallada
<class name="jalview.datamodel.PDBEntry">
<field name="type"><bind-xml node="attribute"/></field>
<field name="id"><bind-xml node="attribute"/></field>
- <field name="property" collection="hashtable">
+ <field name="props" collection="hashtable">
<bind-xml name="property">
<class name="org.exolab.castor.mapping.MapItem">
<field name="key">
for (int i = 0; i < pdb.getChains().size(); i++)
{
- mappingDetails.append("\n\nPDB Sequence is :\nSequence = "
- + pdb.getChains().elementAt(i).sequence.getSequenceAsString());
+ mappingDetails
+ .append("\n\nPDB Sequence is :\nSequence = "
+ + pdb.getChains().elementAt(i).sequence
+ .getSequenceAsString());
mappingDetails.append("\nNo of residues = "
+ pdb.getChains().elementAt(i).residues.size() + "\n\n");
// Align the sequence to the pdb
// TODO: DNa/Pep switch
AlignSeq as = new AlignSeq(sequence,
- pdb.getChains().elementAt(i).sequence,
- pdb.getChains().elementAt(i).isNa ? AlignSeq.DNA : AlignSeq.PEP);
+ pdb.getChains().elementAt(i).sequence, pdb.getChains()
+ .elementAt(i).isNa ? AlignSeq.DNA : AlignSeq.PEP);
as.calcScoreMatrix();
as.traceAlignment();
PrintStream ps = new PrintStream(System.out)
chain = str.substring(21, 22);
resNumber = Integer.parseInt(str.substring(22, 26).trim());
- resNumIns = str.substring(22, 27);
+ resNumIns = str.substring(22, 27).trim();
insCode = str.substring(26, 27).charAt(0);
this.x = (new Float(str.substring(30, 38).trim()).floatValue());
this.y = (new Float(str.substring(38, 46).trim()).floatValue());
}
}
+ @Override
+ public boolean equals(Object that)
+ {
+ if (this == that || that == null)
+ {
+ return true;
+ }
+ if (that instanceof Atom)
+ {
+ Atom other = (Atom) that;
+ return other.resName.equals(this.resName)
+ && other.resNumber == this.resNumber
+ && other.resNumIns.equals(this.resNumIns)
+ && other.chain.equals(this.chain);
+ }
+ return false;
+ }
+
public Atom(float x, float y, float z)
{
this.x = x;
for (int i = 0; i < pdb.getChains().size(); i++)
{
- mappingDetails.append("\n\nPDB Sequence is :\nSequence = "
- + pdb.getChains().elementAt(i).sequence.getSequenceAsString());
+ mappingDetails
+ .append("\n\nPDB Sequence is :\nSequence = "
+ + pdb.getChains().elementAt(i).sequence
+ .getSequenceAsString());
mappingDetails.append("\nNo of residues = "
+ pdb.getChains().elementAt(i).residues.size() + "\n\n");
import jalview.datamodel.SequenceI;
import jalview.schemes.ColourSchemeI;
import jalview.schemes.ResidueProperties;
+import jalview.structure.StructureImportSettings;
import jalview.structure.StructureMapping;
-import jalview.structure.StructureViewSettings;
import java.awt.Color;
import java.util.List;
}
for (int i = 0; i < features.length; i++)
{
- if (features[i].getFeatureGroup().equals(pdbid))
+ if (features[i].getFeatureGroup() != null
+ && features[i].getFeatureGroup().equals(pdbid))
{
SequenceFeature tx = new SequenceFeature(features[i]);
tx.setBegin(1 + residues.elementAt(tx.getBegin() - offset).atoms
else
{
- // Make a new Residue object with the new atoms vector
- residues.addElement(new Residue(resAtoms, resNumber - 1, count));
+ // Make a new Residue object with the new atoms vector
+ residues.addElement(new Residue(resAtoms, resNumber - 1, count));
- Residue tmpres = residues.lastElement();
- Atom tmpat = tmpres.atoms.get(0);
- // Make A new SequenceFeature for the current residue numbering
+ Residue tmpres = residues.lastElement();
+ Atom tmpat = tmpres.atoms.get(0);
+ // Make A new SequenceFeature for the current residue numbering
SequenceFeature sf = new SequenceFeature("RESNUM", tmpat.resName
- + ":" + tmpat.resNumIns + " " + pdbid + id, "", offset
- + count, offset + count, pdbid);
- resFeatures.addElement(sf);
- resAnnotation.addElement(new Annotation(tmpat.tfactor));
- // Keep totting up the sequence
+ + ":" + tmpat.resNumIns + " " + pdbid + id, "", offset
+ + count, offset + count, pdbid);
+ resFeatures.addElement(sf);
+ resAnnotation.addElement(new Annotation(tmpat.tfactor));
+ // Keep totting up the sequence
- if ((symbol = ResidueProperties.getAA3Hash().get(tmpat.resName)) == null)
- {
- String nucname = tmpat.resName.trim();
- // use the aaIndex rather than call 'toLower' - which would take a bit
- // more time.
- deoxyn = nucname.length() == 2
- && ResidueProperties.aaIndex[nucname.charAt(0)] == ResidueProperties.aaIndex['D'];
- if (tmpat.name.equalsIgnoreCase("CA")
- || ResidueProperties.nucleotideIndex[nucname
- .charAt((deoxyn ? 1 : 0))] == -1)
+ if ((symbol = ResidueProperties.getAA3Hash().get(tmpat.resName)) == null)
{
+ String nucname = tmpat.resName.trim();
+ // use the aaIndex rather than call 'toLower' - which would take a bit
+ // more time.
+ deoxyn = nucname.length() == 2
+ && ResidueProperties.aaIndex[nucname.charAt(0)] == ResidueProperties.aaIndex['D'];
+ if (tmpat.name.equalsIgnoreCase("CA")
+ || ResidueProperties.nucleotideIndex[nucname
+ .charAt((deoxyn ? 1 : 0))] == -1)
+ {
char r = ResidueProperties
.getSingleCharacterCode(ResidueProperties
.getCanonicalAminoAcid(tmpat.resName));
seq.append(r == '0' ? 'X' : r);
// System.err.println("PDBReader:Null aa3Hash for " +
// tmpat.resName);
+ }
+ else
+ {
+ // nucleotide flag
+ nucleotide = true;
+ seq.append(nucname.charAt((deoxyn ? 1 : 0)));
+ }
}
else
{
- // nucleotide flag
- nucleotide = true;
- seq.append(nucname.charAt((deoxyn ? 1 : 0)));
- }
- }
- else
- {
- if (nucleotide)
- {
- System.err
- .println("Warning: mixed nucleotide and amino acid chain.. its gonna do bad things to you!");
+ if (nucleotide)
+ {
+ System.err
+ .println("Warning: mixed nucleotide and amino acid chain.. its gonna do bad things to you!");
+ }
+ seq.append(ResidueProperties.aa[((Integer) symbol).intValue()]);
}
- seq.append(ResidueProperties.aa[((Integer) symbol).intValue()]);
- }
count++;
}
}
// System.out.println("PDB Sequence is :\nSequence = " + seq);
// System.out.println("No of residues = " + residues.size());
- if (StructureViewSettings.isShowSeqFeatures())
+ if (StructureImportSettings.isShowSeqFeatures())
{
- for (i = 0, iSize = resFeatures.size(); i < iSize; i++)
- {
- sequence.addSequenceFeature(resFeatures.elementAt(i));
- resFeatures.setElementAt(null, i);
- }
+ for (i = 0, iSize = resFeatures.size(); i < iSize; i++)
+ {
+ sequence.addSequenceFeature(resFeatures.elementAt(i));
+ resFeatures.setElementAt(null, i);
+ }
}
if (visibleChainAnnotation)
{
{
for (AlignmentAnnotation ana : sequence.getAnnotation())
{
- List<AlignmentAnnotation> transfer = sq
+ List<AlignmentAnnotation> transfer = dsq
.getAlignmentAnnotations(ana.getCalcId(), ana.label);
if (transfer == null || transfer.size() == 0)
{
ana = new AlignmentAnnotation(ana);
ana.liftOver(dsq, sqmpping);
+ dsq.addAlignmentAnnotation(ana);
// mapping.transfer(ana);
}
else
worker.start();
}
- if (pdbentry.getProperty() != null)
+ String method = (String) pdbentry.getProperty("method");
+ if (method != null)
{
- if (pdbentry.getProperty().get("method") != null)
- {
- title.append(" Method: ");
- title.append(pdbentry.getProperty().get("method"));
- }
- if (pdbentry.getProperty().get("chains") != null)
- {
- title.append(" Chain:");
- title.append(pdbentry.getProperty().get("chains"));
- }
+ title.append(" Method: ");
+ title.append(method);
+ }
+ String ch = (String) pdbentry.getProperty("chains");
+ if (ch != null)
+ {
+ title.append(" Chain:");
+ title.append(ch);
}
Desktop.addInternalFrame(this, title.toString(), 400, 400);
}
@Override
public void mousePressed(MouseEvent evt)
{
- if (evt.isPopupTrigger())
+ if (evt.isPopupTrigger()) // Mac
{
- radioItem.removeActionListener(radioItem.getActionListeners()[0]);
-
- int option = JOptionPane.showInternalConfirmDialog(
- jalview.gui.Desktop.desktop,
- MessageManager
- .getString("label.remove_from_default_list"),
- MessageManager
- .getString("label.remove_user_defined_colour"),
- JOptionPane.YES_NO_OPTION);
- if (option == JOptionPane.YES_OPTION)
- {
- jalview.gui.UserDefinedColours
- .removeColourFromDefaults(radioItem.getText());
- coloursMenu.remove(radioItem);
- }
- else
+ offerRemoval(radioItem);
+ }
+ }
+
+ @Override
+ public void mouseReleased(MouseEvent evt)
+ {
+ if (evt.isPopupTrigger()) // Windows
+ {
+ offerRemoval(radioItem);
+ }
+ }
+
+ /**
+ * @param radioItem
+ */
+ void offerRemoval(final JRadioButtonMenuItem radioItem)
+ {
+ radioItem.removeActionListener(radioItem.getActionListeners()[0]);
+
+ int option = JOptionPane.showInternalConfirmDialog(
+ jalview.gui.Desktop.desktop, MessageManager
+ .getString("label.remove_from_default_list"),
+ MessageManager
+ .getString("label.remove_user_defined_colour"),
+ JOptionPane.YES_NO_OPTION);
+ if (option == JOptionPane.YES_OPTION)
+ {
+ jalview.gui.UserDefinedColours
+ .removeColourFromDefaults(radioItem.getText());
+ coloursMenu.remove(radioItem);
+ }
+ else
+ {
+ radioItem.addActionListener(new ActionListener()
{
- radioItem.addActionListener(new ActionListener()
+ @Override
+ public void actionPerformed(ActionEvent evt)
{
- @Override
- public void actionPerformed(ActionEvent evt)
- {
- user_actionPerformed(evt);
- }
- });
- }
+ user_actionPerformed(evt);
+ }
+ });
}
}
});
}
public PDBfile(boolean addAlignmentAnnotations, boolean predictSecStr,
- boolean externalSecStr, String file, String protocol)
+ boolean externalSecStr, String dataObject, String protocol)
throws IOException
{
- super(false, file, protocol);
+ super(false, dataObject, protocol);
addSettings(addAlignmentAnnotations, predictSecStr, externalSecStr);
doParse();
}
public PDBfile(boolean addAlignmentAnnotations, boolean predictSecStr,
- boolean externalSecStr,
- FileParse source) throws IOException
+ boolean externalSecStr, FileParse source) throws IOException
{
super(false, source);
addSettings(addAlignmentAnnotations, predictSecStr, externalSecStr);
Atom tmpatom = new Atom(line);
try
{
- tmpchain = findChain(tmpatom.chain);
+ tmpchain = findChain(tmpatom.chain);
if (tmpatom.resNumIns.trim().equals(lastID))
{
// phosphorylated protein - seen both CA and P..
markCalcIds();
}
-
-
/**
* Process a parsed chain to construct and return a Sequence, and add it to
* the list of sequences parsed.
*/
public class ChimeraManager
{
+ private static final int REST_REPLY_TIMEOUT_MS = 15000;
+
+ private static final int CONNECTION_TIMEOUT_MS = 100;
+
private static final boolean debug = false;
private int chimeraRestPort;
BufferedReader response = null;
try
{
- response = HttpClientUtils
- .doHttpUrlPost(restUrl, commands, 100, 5000);
+ response = HttpClientUtils.doHttpUrlPost(restUrl, commands, CONNECTION_TIMEOUT_MS,
+ REST_REPLY_TIMEOUT_MS);
String line = "";
while ((line = response.readLine()) != null)
{
*/
package jalview.analysis;
+import jalview.analysis.ResidueCount.SymbolCounts;
import jalview.datamodel.AlignedCodonFrame;
import jalview.datamodel.AlignmentAnnotation;
import jalview.datamodel.AlignmentI;
import jalview.datamodel.Annotation;
import jalview.datamodel.SequenceI;
+import jalview.ext.android.SparseIntArray;
+import jalview.util.Comparison;
import jalview.util.Format;
import jalview.util.MappingUtils;
import jalview.util.QuickSort;
*/
public class AAFrequency
{
- private static final int TO_UPPER_CASE = 'A' - 'a'; // -32
-
- public static final String MAXCOUNT = "C";
-
- public static final String MAXRESIDUE = "R";
-
- public static final String PID_GAPS = "G";
-
- public static final String PID_NOGAPS = "N";
-
public static final String PROFILE = "P";
- public static final String ENCODED_CHARS = "E";
-
/*
* Quick look-up of String value of char 'A' to 'Z'
*/
}
}
- public static final Hashtable[] calculate(List<SequenceI> list,
+ public static final Profile[] calculate(List<SequenceI> list,
int start, int end)
{
return calculate(list, start, end, false);
}
- public static final Hashtable[] calculate(List<SequenceI> sequences,
+ public static final Profile[] calculate(List<SequenceI> sequences,
int start, int end, boolean profile)
{
SequenceI[] seqs = new SequenceI[sequences.size()];
}
}
- Hashtable[] reply = new Hashtable[width];
+ Profile[] reply = new Profile[width];
if (end >= width)
{
}
}
- public static final void calculate(SequenceI[] sequences, int start,
- int end, Hashtable[] result, boolean profile)
+ /**
+ * Calculate the consensus symbol(s) for each column in the given range.
+ *
+ * @param sequences
+ * @param start
+ * start column (inclusive, base zero)
+ * @param end
+ * end column (exclusive)
+ * @param result
+ * array in which to store profile per column
+ * @param saveFullProfile
+ * if true, store all symbol counts
+ */
+ public static final void calculate(final SequenceI[] sequences,
+ int start, int end, Profile[] result, boolean saveFullProfile)
{
- Hashtable residueHash;
- int maxCount, nongap, i, j, v;
- int jSize = sequences.length;
- String maxResidue;
- char c = '-';
- float percentage;
-
- int[] values = new int[255];
+ // long now = System.currentTimeMillis();
+ int seqCount = sequences.length;
+ boolean nucleotide = false;
+ int nucleotideCount = 0;
+ int peptideCount = 0;
- char[] seq;
-
- for (i = start; i < end; i++)
+ for (int column = start; column < end; column++)
{
- residueHash = new Hashtable();
- maxCount = 0;
- maxResidue = "";
- nongap = 0;
- values = new int[255];
+ /*
+ * Apply a heuristic to detect nucleotide data (which can
+ * be counted in more compact arrays); here we test for
+ * more than 90% nucleotide; recheck every 10 columns in case
+ * of misleading data e.g. highly conserved Alanine in peptide!
+ * Mistakenly guessing nucleotide has a small performance cost,
+ * as it will result in counting in sparse arrays.
+ * Mistakenly guessing peptide has a small space cost,
+ * as it will use a larger than necessary array to hold counts.
+ */
+ if (nucleotideCount > 100 && column % 10 == 0)
+ {
+ nucleotide = (9 * peptideCount < nucleotideCount);
+ }
+ ResidueCount residueCounts = new ResidueCount(nucleotide);
- for (j = 0; j < jSize; j++)
+ for (int row = 0; row < seqCount; row++)
{
- if (sequences[j] == null)
+ if (sequences[row] == null)
{
System.err
.println("WARNING: Consensus skipping null sequence - possible race condition.");
continue;
}
- seq = sequences[j].getSequence();
- if (seq.length > i)
+ char[] seq = sequences[row].getSequence();
+ if (seq.length > column)
{
- c = seq[i];
-
- if (c == '.' || c == ' ')
+ char c = seq[column];
+ residueCounts.add(c);
+ if (Comparison.isNucleotide(c))
{
- c = '-';
+ nucleotideCount++;
}
-
- if (c == '-')
- {
- values['-']++;
- continue;
- }
- else if ('a' <= c && c <= 'z')
+ else if (!Comparison.isGap(c))
{
- c += TO_UPPER_CASE;
+ peptideCount++;
}
-
- nongap++;
- values[c]++;
-
}
else
{
- values['-']++;
- }
- }
- if (jSize == 1)
- {
- maxResidue = String.valueOf(c);
- maxCount = 1;
- }
- else
- {
- for (v = 'A'; v <= 'Z'; v++)
- {
- // TODO why ignore values[v] == 1?
- if (values[v] < 1 /* 2 */|| values[v] < maxCount)
- {
- continue;
- }
-
- if (values[v] > maxCount)
- {
- maxResidue = CHARS[v - 'A'];
- }
- else if (values[v] == maxCount)
- {
- maxResidue += CHARS[v - 'A'];
- }
- maxCount = values[v];
+ /*
+ * count a gap if the sequence doesn't reach this column
+ */
+ residueCounts.addGap();
}
}
- if (maxResidue.length() == 0)
- {
- maxResidue = "-";
- }
- if (profile)
- {
- // TODO use a 1-dimensional array with jSize, nongap in [0] and [1]
- residueHash.put(PROFILE, new int[][] { values,
- new int[] { jSize, nongap } });
- }
- residueHash.put(MAXCOUNT, new Integer(maxCount));
- residueHash.put(MAXRESIDUE, maxResidue);
- percentage = ((float) maxCount * 100) / jSize;
- residueHash.put(PID_GAPS, new Float(percentage));
+ int maxCount = residueCounts.getModalCount();
+ String maxResidue = residueCounts.getResiduesForCount(maxCount);
+ int gapCount = residueCounts.getGapCount();
+ Profile profile = new Profile(seqCount, gapCount, maxCount,
+ maxResidue);
- if (nongap > 0)
+ if (saveFullProfile)
{
- // calculate for non-gapped too
- percentage = ((float) maxCount * 100) / nongap;
+ profile.setCounts(residueCounts);
}
- residueHash.put(PID_NOGAPS, new Float(percentage));
- result[i] = residueHash;
+ result[column] = profile;
}
+ // long elapsed = System.currentTimeMillis() - now;
+ // System.out.println(elapsed);
}
/**
- * Compute all or part of the annotation row from the given consensus
- * hashtable
+ * Make an estimate of the profile size we are going to compute i.e. how many
+ * different characters may be present in it. Overestimating has a cost of
+ * using more memory than necessary. Underestimating has a cost of needing to
+ * extend the SparseIntArray holding the profile counts.
*
- * @param consensus
- * - pre-allocated annotation row
- * @param hconsensus
- * @param iStart
- * @param width
- * @param ignoreGapsInConsensusCalculation
- * @param includeAllConsSymbols
- * @param nseq
+ * @param profileSizes
+ * counts of sizes of profiles so far encountered
+ * @return
*/
- public static void completeConsensus(AlignmentAnnotation consensus,
- Hashtable[] hconsensus, int iStart, int width,
- boolean ignoreGapsInConsensusCalculation,
- boolean includeAllConsSymbols, long nseq)
+ static int estimateProfileSize(SparseIntArray profileSizes)
{
- completeConsensus(consensus, hconsensus, iStart, width,
- ignoreGapsInConsensusCalculation, includeAllConsSymbols, null,
- nseq);
+ if (profileSizes.size() == 0)
+ {
+ return 4;
+ }
+
+ /*
+ * could do a statistical heuristic here e.g. 75%ile
+ * for now just return the largest value
+ */
+ return profileSizes.keyAt(profileSizes.size() - 1);
}
/**
* Derive the consensus annotations to be added to the alignment for display.
* This does not recompute the raw data, but may be called on a change in
- * display options, such as 'show logo', which may in turn result in a change
- * in the derived values.
+ * display options, such as 'ignore gaps', which may in turn result in a
+ * change in the derived values.
*
* @param consensus
* the annotation row to add annotations to
- * @param hconsensus
+ * @param profiles
* the source consensus data
* @param iStart
* start column
* @param width
* end column
- * @param ignoreGapsInConsensusCalculation
- * if true, use the consensus calculated ignoring gaps
- * @param includeAllConsSymbols
+ * @param ignoreGaps
+ * if true, normalise residue percentages ignoring gaps
+ * @param showSequenceLogo
* if true include all consensus symbols, else just show modal
* residue
- * @param alphabet
* @param nseq
* number of sequences
*/
public static void completeConsensus(AlignmentAnnotation consensus,
- Hashtable[] hconsensus, int iStart, int width,
- boolean ignoreGapsInConsensusCalculation,
- boolean includeAllConsSymbols, char[] alphabet, long nseq)
+ Profile[] profiles, int iStart, int width, boolean ignoreGaps,
+ boolean showSequenceLogo, long nseq)
{
+ // long now = System.currentTimeMillis();
if (consensus == null || consensus.annotations == null
|| consensus.annotations.length < width)
{
- // called with a bad alignment annotation row - wait for it to be
- // initialised properly
+ /*
+ * called with a bad alignment annotation row
+ * wait for it to be initialised properly
+ */
return;
}
- final Format fmt = getPercentageFormat(nseq);
+ final int dp = getPercentageDp(nseq);
for (int i = iStart; i < width; i++)
{
- Hashtable hci;
- if (i >= hconsensus.length || ((hci = hconsensus[i]) == null))
- {
- // happens if sequences calculated over were shorter than alignment
- // width
- consensus.annotations[i] = null;
- continue;
- }
- Float fv = (Float) hci
- .get(ignoreGapsInConsensusCalculation ? PID_NOGAPS : PID_GAPS);
- if (fv == null)
+ Profile profile;
+ if (i >= profiles.length || ((profile = profiles[i]) == null))
{
+ /*
+ * happens if sequences calculated over were
+ * shorter than alignment width
+ */
consensus.annotations[i] = null;
- // data has changed below us .. give up and
continue;
}
- float value = fv.floatValue();
- String maxRes = hci.get(AAFrequency.MAXRESIDUE).toString();
- StringBuilder mouseOver = new StringBuilder(64);
- if (maxRes.length() > 1)
- {
- mouseOver.append("[").append(maxRes).append("] ");
- maxRes = "+";
- }
- else
- {
- mouseOver.append(hci.get(AAFrequency.MAXRESIDUE) + " ");
- }
- int[][] profile = (int[][]) hci.get(AAFrequency.PROFILE);
- if (profile != null && includeAllConsSymbols)
+
+ float value = profile.getPercentageIdentity(ignoreGaps);
+
+ String description = getTooltip(profile, value, showSequenceLogo,
+ ignoreGaps, dp);
+
+ String modalResidue = profile.getModalResidue();
+ if ("".equals(modalResidue))
{
- int sequenceCount = profile[1][0];
- int nonGappedCount = profile[1][1];
- int normalisedBy = ignoreGapsInConsensusCalculation ? nonGappedCount
- : sequenceCount;
- mouseOver.setLength(0);
- if (alphabet != null)
- {
- for (int c = 0; c < alphabet.length; c++)
- {
- float tval = profile[0][alphabet[c]] * 100f / normalisedBy;
- mouseOver
- .append(((c == 0) ? "" : "; "))
- .append(alphabet[c])
- .append(" ")
- .append(((fmt != null) ? fmt.form(tval) : ((int) tval)))
- .append("%");
- }
- }
- else
- {
- // TODO do this sort once only in calculate()?
- // char[][] ca = new char[profile[0].length][];
- char[] ca = new char[profile[0].length];
- float[] vl = new float[profile[0].length];
- for (int c = 0; c < ca.length; c++)
- {
- ca[c] = (char) c;
- // ca[c] = new char[]
- // { (char) c };
- vl[c] = profile[0][c];
- }
- QuickSort.sort(vl, ca);
- for (int p = 0, c = ca.length - 1; profile[0][ca[c]] > 0; c--)
- {
- final char residue = ca[c];
- if (residue != '-')
- {
- float tval = profile[0][residue] * 100f / normalisedBy;
- mouseOver
- .append((((p == 0) ? "" : "; ")))
- .append(residue)
- .append(" ")
- .append(((fmt != null) ? fmt.form(tval)
- : ((int) tval))).append("%");
- p++;
- }
- }
- }
+ modalResidue = "-";
}
- else
+ else if (modalResidue.length() > 1)
{
- mouseOver.append(
- (((fmt != null) ? fmt.form(value) : ((int) value))))
- .append("%");
+ modalResidue = "+";
}
- consensus.annotations[i] = new Annotation(maxRes,
- mouseOver.toString(), ' ', value);
+ consensus.annotations[i] = new Annotation(modalResidue,
+ description, ' ', value);
}
+ // long elapsed = System.currentTimeMillis() - now;
+ // System.out.println(-elapsed);
}
/**
- * Returns a Format designed to show all significant figures for profile
- * percentages. For less than 100 sequences, returns null (the integer
- * percentage value will be displayed). For 100-999 sequences, returns "%3.1f"
+ * Returns a tooltip showing either
+ * <ul>
+ * <li>the full profile (percentages of all residues present), if
+ * showSequenceLogo is true, or</li>
+ * <li>just the modal (most common) residue(s), if showSequenceLogo is false</li>
+ * </ul>
+ * Percentages are as a fraction of all sequence, or only ungapped sequences
+ * if ignoreGaps is true.
*
- * @param nseq
+ * @param profile
+ * @param pid
+ * @param showSequenceLogo
+ * @param ignoreGaps
+ * @param dp
+ * the number of decimal places to format percentages to
* @return
*/
- protected static Format getPercentageFormat(long nseq)
+ static String getTooltip(Profile profile, float pid,
+ boolean showSequenceLogo, boolean ignoreGaps, int dp)
{
- int scale = 0;
- while (nseq >= 10)
+ ResidueCount counts = profile.getCounts();
+
+ String description = null;
+ if (counts != null && showSequenceLogo)
{
- scale++;
- nseq /= 10;
+ int normaliseBy = ignoreGaps ? profile.getNonGapped() : profile
+ .getHeight();
+ description = counts.getTooltip(normaliseBy, dp);
}
- return scale <= 1 ? null : new Format("%3." + (scale - 1) + "f");
+ else
+ {
+ StringBuilder sb = new StringBuilder(64);
+ String maxRes = profile.getModalResidue();
+ if (maxRes.length() > 1)
+ {
+ sb.append("[").append(maxRes).append("]");
+ }
+ else
+ {
+ sb.append(maxRes);
+ }
+ if (maxRes.length() > 0)
+ {
+ sb.append(" ");
+ Format.appendPercentage(sb, pid, dp);
+ sb.append("%");
+ }
+ description = sb.toString();
+ }
+ return description;
}
/**
* in descending order of percentage value
* </pre>
*
- * @param hconsensus
- * the data table from which to extract and sort values
+ * @param profile
+ * the data object from which to extract and sort values
* @param ignoreGaps
* if true, only non-gapped values are included in percentage
* calculations
* @return
*/
- public static int[] extractProfile(Hashtable hconsensus,
+ public static int[] extractProfile(Profile profile,
boolean ignoreGaps)
{
int[] rtnval = new int[64];
- int[][] profile = (int[][]) hconsensus.get(AAFrequency.PROFILE);
- if (profile == null)
+ ResidueCount counts = profile.getCounts();
+ if (counts == null)
{
return null;
}
- char[] ca = new char[profile[0].length];
- float[] vl = new float[profile[0].length];
- for (int c = 0; c < ca.length; c++)
- {
- ca[c] = (char) c;
- vl[c] = profile[0][c];
- }
- QuickSort.sort(vl, ca);
+
+ SymbolCounts symbolCounts = counts.getSymbolCounts();
+ char[] symbols = symbolCounts.symbols;
+ int[] values = symbolCounts.values;
+ QuickSort.sort(values, symbols);
int nextArrayPos = 2;
int totalPercentage = 0;
- int distinctValuesCount = 0;
- final int divisor = profile[1][ignoreGaps ? 1 : 0];
- for (int c = ca.length - 1; profile[0][ca[c]] > 0; c--)
+ final int divisor = ignoreGaps ? profile.getNonGapped() : profile
+ .getHeight();
+
+ /*
+ * traverse the arrays in reverse order (highest counts first)
+ */
+ for (int i = symbols.length - 1; i >= 0; i--)
{
- if (ca[c] != '-')
- {
- rtnval[nextArrayPos++] = ca[c];
- final int percentage = (int) (profile[0][ca[c]] * 100f / divisor);
- rtnval[nextArrayPos++] = percentage;
- totalPercentage += percentage;
- distinctValuesCount++;
- }
+ int theChar = symbols[i];
+ int charCount = values[i];
+
+ rtnval[nextArrayPos++] = theChar;
+ final int percentage = (charCount * 100) / divisor;
+ rtnval[nextArrayPos++] = percentage;
+ totalPercentage += percentage;
}
- rtnval[0] = distinctValuesCount;
+ rtnval[0] = symbols.length;
rtnval[1] = totalPercentage;
int[] result = new int[rtnval.length + 1];
result[0] = AlignmentAnnotation.SEQUENCE_PROFILE;
String modalCodon = String.valueOf(CodingUtils
.decodeCodon(modalCodonEncoded));
if (sortedCodonCounts.length > 1
- && sortedCodonCounts[codons.length - 2] == modalCodonEncoded)
+ && sortedCodonCounts[codons.length - 2] == sortedCodonCounts[codons.length - 1])
{
+ /*
+ * two or more codons share the modal count
+ */
modalCodon = "+";
}
float pid = sortedCodonCounts[sortedCodonCounts.length - 1] * 100
StringBuilder samePercent = new StringBuilder();
String percent = null;
String lastPercent = null;
- Format fmt = getPercentageFormat(nseqs);
+ int percentDecPl = getPercentageDp(nseqs);
for (int j = codons.length - 1; j >= 0; j--)
{
final int pct = codonCount * 100 / totalCount;
String codon = String
.valueOf(CodingUtils.decodeCodon(codonEncoded));
- percent = fmt == null ? Integer.toString(pct) : fmt.form(pct);
+ StringBuilder sb = new StringBuilder();
+ Format.appendPercentage(sb, pct, percentDecPl);
+ percent = sb.toString();
if (showProfileLogo || codonCount == modalCodonCount)
{
if (percent.equals(lastPercent) && j > 0)
mouseOver.toString(), ' ', pid);
}
}
+
+ /**
+ * Returns the number of decimal places to show for profile percentages. For
+ * less than 100 sequences, returns zero (the integer percentage value will be
+ * displayed). For 100-999 sequences, returns 1, for 1000-9999 returns 2, etc.
+ *
+ * @param nseq
+ * @return
+ */
+ protected static int getPercentageDp(long nseq)
+ {
+ int scale = 0;
+ while (nseq >= 100)
+ {
+ scale++;
+ nseq /= 10;
+ }
+ return scale;
+ }
}
}
pid = pid / (aseq1.length - count) * 100;
- output = output.append(new Format("Percentage ID = %2.2f\n")
- .form(pid));
+ output = output.append(new Format("Percentage ID = %2.2f\n").form(pid));
try
{
os.print(output.toString());
public static void sortByFeature(String featureLabel, String groupLabel,
int start, int stop, AlignmentI alignment, String method)
{
- sortByFeature(featureLabel == null ? null
+ sortByFeature(
+ featureLabel == null ? null
: Arrays.asList(new String[] { featureLabel }),
- groupLabel == null ? null
- : Arrays.asList(new String[]{ groupLabel }), start, stop, alignment, method);
+ groupLabel == null ? null : Arrays
+ .asList(new String[] { groupLabel }), start, stop,
+ alignment, method);
}
private static boolean containsIgnoreCase(final String lab,
}
public static void sortByFeature(List<String> featureLabels,
- List<String> groupLabels, int start, int stop, AlignmentI alignment,
- String method)
+ List<String> groupLabels, int start, int stop,
+ AlignmentI alignment, String method)
{
if (method != FEATURE_SCORE && method != FEATURE_LABEL
&& method != FEATURE_DENSITY)
import jalview.datamodel.AlignedCodon;
import jalview.datamodel.AlignedCodonFrame;
+import jalview.datamodel.AlignedCodonFrame.SequenceToSequenceMapping;
import jalview.datamodel.Alignment;
import jalview.datamodel.AlignmentAnnotation;
import jalview.datamodel.AlignmentI;
import jalview.io.gff.SequenceOntologyI;
import jalview.schemes.ResidueProperties;
import jalview.util.Comparison;
+import jalview.util.DBRefUtils;
import jalview.util.MapList;
import jalview.util.MappingUtils;
import jalview.util.StringUtils;
public class AlignmentUtils
{
+ private static final int CODON_LENGTH = 3;
+
private static final String SEQUENCE_VARIANT = "sequence_variant:";
+
private static final String ID = "ID";
/**
* A data model to hold the 'normal' base value at a position, and an optional
* sequence variant feature
*/
- static class DnaVariant
+ static final class DnaVariant
{
- String base;
+ final String base;
SequenceFeature variant;
DnaVariant(String nuc)
{
base = nuc;
+ variant = null;
}
DnaVariant(String nuc, SequenceFeature var)
base = nuc;
variant = var;
}
+
+ public String getSource()
+ {
+ return variant == null ? null : variant.getFeatureGroup();
+ }
}
/**
/*
* cdnaStart/End, proteinStartEnd are base 1 (for dataset sequence mapping)
*/
- final int mappedLength = 3 * aaSeqChars.length;
+ final int mappedLength = CODON_LENGTH * aaSeqChars.length;
int cdnaLength = cdnaSeqChars.length;
int cdnaStart = cdnaSeq.getStart();
int cdnaEnd = cdnaSeq.getEnd();
*/
if (cdnaLength != mappedLength && cdnaLength > 2)
{
- String lastCodon = String.valueOf(cdnaSeqChars, cdnaLength - 3, 3)
- .toUpperCase();
+ String lastCodon = String.valueOf(cdnaSeqChars,
+ cdnaLength - CODON_LENGTH, CODON_LENGTH).toUpperCase();
for (String stop : ResidueProperties.STOP)
{
if (lastCodon.equals(stop))
{
- cdnaEnd -= 3;
- cdnaLength -= 3;
+ cdnaEnd -= CODON_LENGTH;
+ cdnaLength -= CODON_LENGTH;
break;
}
}
int startOffset = 0;
if (cdnaLength != mappedLength
&& cdnaLength > 2
- && String.valueOf(cdnaSeqChars, 0, 3).toUpperCase()
+ && String.valueOf(cdnaSeqChars, 0, CODON_LENGTH).toUpperCase()
.equals(ResidueProperties.START))
{
- startOffset += 3;
- cdnaStart += 3;
- cdnaLength -= 3;
+ startOffset += CODON_LENGTH;
+ cdnaStart += CODON_LENGTH;
+ cdnaLength -= CODON_LENGTH;
}
if (translatesAs(cdnaSeqChars, startOffset, aaSeqChars))
* protein is translation of dna (+/- start/stop codons)
*/
MapList map = new MapList(new int[] { cdnaStart, cdnaEnd }, new int[]
- { proteinStart, proteinEnd }, 3, 1);
+ { proteinStart, proteinEnd }, CODON_LENGTH, 1);
return map;
}
int aaPos = 0;
int dnaPos = cdnaStart;
- for (; dnaPos < cdnaSeqChars.length - 2
- && aaPos < aaSeqChars.length; dnaPos += 3, aaPos++)
+ for (; dnaPos < cdnaSeqChars.length - 2 && aaPos < aaSeqChars.length; dnaPos += CODON_LENGTH, aaPos++)
{
- String codon = String.valueOf(cdnaSeqChars, dnaPos, 3);
+ String codon = String.valueOf(cdnaSeqChars, dnaPos, CODON_LENGTH);
final String translated = ResidueProperties.codonTranslate(codon);
/*
{
return true;
}
- if (dnaPos == cdnaSeqChars.length - 3)
+ if (dnaPos == cdnaSeqChars.length - CODON_LENGTH)
{
- String codon = String.valueOf(cdnaSeqChars, dnaPos, 3);
+ String codon = String.valueOf(cdnaSeqChars, dnaPos, CODON_LENGTH);
if ("STOP".equals(ResidueProperties.codonTranslate(codon)))
{
return true;
*/
public static int alignProteinAsDna(AlignmentI protein, AlignmentI dna)
{
+ if (protein.isNucleotide() || !dna.isNucleotide())
+ {
+ System.err.println("Wrong alignment type in alignProteinAsDna");
+ return 0;
+ }
List<SequenceI> unmappedProtein = new ArrayList<SequenceI>();
Map<AlignedCodon, Map<SequenceI, AlignedCodon>> alignedCodons = buildCodonColumnsMap(
protein, dna, unmappedProtein);
}
/**
+ * Realigns the given dna to match the alignment of the protein, using codon
+ * mappings to translate aligned peptide positions to codons.
+ *
+ * Always produces a padded CDS alignment.
+ *
+ * @param dna
+ * the alignment whose sequences are realigned by this method
+ * @param protein
+ * the protein alignment whose alignment we are 'copying'
+ * @return the number of sequences that were realigned
+ */
+ public static int alignCdsAsProtein(AlignmentI dna, AlignmentI protein)
+ {
+ if (protein.isNucleotide() || !dna.isNucleotide())
+ {
+ System.err.println("Wrong alignment type in alignProteinAsDna");
+ return 0;
+ }
+ // todo: implement this
+ List<AlignedCodonFrame> mappings = protein.getCodonFrames();
+ int alignedCount = 0;
+ int width = 0; // alignment width for padding CDS
+ for (SequenceI dnaSeq : dna.getSequences())
+ {
+ if (alignCdsSequenceAsProtein(dnaSeq, protein, mappings,
+ dna.getGapCharacter()))
+ {
+ alignedCount++;
+ }
+ width = Math.max(dnaSeq.getLength(), width);
+ }
+ int oldwidth;
+ int diff;
+ for (SequenceI dnaSeq : dna.getSequences())
+ {
+ oldwidth = dnaSeq.getLength();
+ diff = width - oldwidth;
+ if (diff > 0)
+ {
+ dnaSeq.insertCharAt(oldwidth, diff, dna.getGapCharacter());
+ }
+ }
+ return alignedCount;
+ }
+
+ /**
+ * Helper method to align (if possible) the dna sequence to match the
+ * alignment of a mapped protein sequence. This is currently limited to
+ * handling coding sequence only.
+ *
+ * @param cdsSeq
+ * @param protein
+ * @param mappings
+ * @param gapChar
+ * @return
+ */
+ static boolean alignCdsSequenceAsProtein(SequenceI cdsSeq,
+ AlignmentI protein, List<AlignedCodonFrame> mappings, char gapChar)
+ {
+ SequenceI cdsDss = cdsSeq.getDatasetSequence();
+ if (cdsDss == null)
+ {
+ System.err
+ .println("alignCdsSequenceAsProtein needs aligned sequence!");
+ return false;
+ }
+
+ List<AlignedCodonFrame> dnaMappings = MappingUtils
+ .findMappingsForSequence(cdsSeq, mappings);
+ for (AlignedCodonFrame mapping : dnaMappings)
+ {
+ SequenceI peptide = mapping.findAlignedSequence(cdsSeq, protein);
+ if (peptide != null)
+ {
+ int peptideLength = peptide.getLength();
+ Mapping map = mapping.getMappingBetween(cdsSeq, peptide);
+ if (map != null)
+ {
+ MapList mapList = map.getMap();
+ if (map.getTo() == peptide.getDatasetSequence())
+ {
+ mapList = mapList.getInverse();
+ }
+ int cdsLength = cdsDss.getLength();
+ int mappedFromLength = MappingUtils.getLength(mapList
+ .getFromRanges());
+ int mappedToLength = MappingUtils
+ .getLength(mapList.getToRanges());
+ boolean addStopCodon = (cdsLength == mappedFromLength
+ * CODON_LENGTH + CODON_LENGTH)
+ || (peptide.getDatasetSequence().getLength() == mappedFromLength - 1);
+ if (cdsLength != mappedToLength && !addStopCodon)
+ {
+ System.err
+ .println(String
+ .format("Can't align cds as protein (length mismatch %d/%d): %s",
+ cdsLength, mappedToLength,
+ cdsSeq.getName()));
+ }
+
+ /*
+ * pre-fill the aligned cds sequence with gaps
+ */
+ char[] alignedCds = new char[peptideLength * CODON_LENGTH
+ + (addStopCodon ? CODON_LENGTH : 0)];
+ Arrays.fill(alignedCds, gapChar);
+
+ /*
+ * walk over the aligned peptide sequence and insert mapped
+ * codons for residues in the aligned cds sequence
+ */
+ char[] alignedPeptide = peptide.getSequence();
+ char[] nucleotides = cdsDss.getSequence();
+ int copiedBases = 0;
+ int cdsStart = cdsDss.getStart();
+ int proteinPos = peptide.getStart() - 1;
+ int cdsCol = 0;
+ for (char residue : alignedPeptide)
+ {
+ if (Comparison.isGap(residue))
+ {
+ cdsCol += CODON_LENGTH;
+ }
+ else
+ {
+ proteinPos++;
+ int[] codon = mapList.locateInTo(proteinPos, proteinPos);
+ if (codon == null)
+ {
+ // e.g. incomplete start codon, X in peptide
+ cdsCol += CODON_LENGTH;
+ }
+ else
+ {
+ for (int j = codon[0]; j <= codon[1]; j++)
+ {
+ char mappedBase = nucleotides[j - cdsStart];
+ alignedCds[cdsCol++] = mappedBase;
+ copiedBases++;
+ }
+ }
+ }
+ }
+
+ /*
+ * append stop codon if not mapped from protein,
+ * closing it up to the end of the mapped sequence
+ */
+ if (copiedBases == nucleotides.length - CODON_LENGTH)
+ {
+ for (int i = alignedCds.length - 1; i >= 0; i--)
+ {
+ if (!Comparison.isGap(alignedCds[i]))
+ {
+ cdsCol = i + 1; // gap just after end of sequence
+ break;
+ }
+ }
+ for (int i = nucleotides.length - CODON_LENGTH; i < nucleotides.length; i++)
+ {
+ alignedCds[cdsCol++] = nucleotides[i];
+ }
+ }
+ cdsSeq.setSequence(new String(alignedCds));
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ /**
* Builds a map whose key is an aligned codon position (3 alignment column
* numbers base 0), and whose value is a map from protein sequence to each
* protein's peptide residue for that codon. The map generates an ordering of
// TODO resolve JAL-2022 so this fudge can be removed
int mappedSequenceCount = protein.getHeight() - unmappedProtein.size();
addUnmappedPeptideStarts(alignedCodons, mappedSequenceCount);
-
+
return alignedCodons;
}
* added to the alignment dataset.
*
* @param dna
- * aligned dna sequences
- * @param mappings
- * from dna to protein
- * @param al
+ * aligned nucleotide (dna or cds) sequences
+ * @param dataset
+ * the alignment dataset the sequences belong to
+ * @param products
+ * (optional) to restrict results to CDS that map to specified
+ * protein products
* @return an alignment whose sequences are the cds-only parts of the dna
* sequences (or null if no mappings are found)
*/
public static AlignmentI makeCdsAlignment(SequenceI[] dna,
- List<AlignedCodonFrame> mappings, AlignmentI al)
+ AlignmentI dataset, SequenceI[] products)
{
+ if (dataset == null || dataset.getDataset() != null)
+ {
+ throw new IllegalArgumentException(
+ "IMPLEMENTATION ERROR: dataset.getDataset() must be null!");
+ }
+ List<SequenceI> foundSeqs = new ArrayList<SequenceI>();
List<SequenceI> cdsSeqs = new ArrayList<SequenceI>();
-
- for (SequenceI seq : dna)
+ List<AlignedCodonFrame> mappings = dataset.getCodonFrames();
+ HashSet<SequenceI> productSeqs = null;
+ if (products != null)
+ {
+ productSeqs = new HashSet<SequenceI>();
+ for (SequenceI seq : products)
+ {
+ productSeqs.add(seq.getDatasetSequence() == null ? seq : seq
+ .getDatasetSequence());
+ }
+ }
+
+ /*
+ * Construct CDS sequences from mappings on the alignment dataset.
+ * The logic is:
+ * - find the protein product(s) mapped to from each dna sequence
+ * - if the mapping covers the whole dna sequence (give or take start/stop
+ * codon), take the dna as the CDS sequence
+ * - else search dataset mappings for a suitable dna sequence, i.e. one
+ * whose whole sequence is mapped to the protein
+ * - if no sequence found, construct one from the dna sequence and mapping
+ * (and add it to dataset so it is found if this is repeated)
+ */
+ for (SequenceI dnaSeq : dna)
{
- AlignedCodonFrame cdsMappings = new AlignedCodonFrame();
+ SequenceI dnaDss = dnaSeq.getDatasetSequence() == null ? dnaSeq
+ : dnaSeq.getDatasetSequence();
+
List<AlignedCodonFrame> seqMappings = MappingUtils
- .findMappingsForSequence(seq, mappings);
- List<AlignedCodonFrame> alignmentMappings = al.getCodonFrames();
+ .findMappingsForSequence(dnaSeq, mappings);
for (AlignedCodonFrame mapping : seqMappings)
{
- for (Mapping aMapping : mapping.getMappingsFromSequence(seq))
+ List<Mapping> mappingsFromSequence = mapping
+ .getMappingsFromSequence(dnaSeq);
+
+ for (Mapping aMapping : mappingsFromSequence)
{
- SequenceI cdsSeq = makeCdsSequence(seq.getDatasetSequence(),
- aMapping);
+ MapList mapList = aMapping.getMap();
+ if (mapList.getFromRatio() == 1)
+ {
+ /*
+ * not a dna-to-protein mapping (likely dna-to-cds)
+ */
+ continue;
+ }
+
+ /*
+ * skip if mapping is not to one of the target set of proteins
+ */
+ SequenceI proteinProduct = aMapping.getTo();
+ if (productSeqs != null && !productSeqs.contains(proteinProduct))
+ {
+ continue;
+ }
+
+ /*
+ * try to locate the CDS from the dataset mappings;
+ * guard against duplicate results (for the case that protein has
+ * dbrefs to both dna and cds sequences)
+ */
+ SequenceI cdsSeq = findCdsForProtein(mappings, dnaSeq,
+ seqMappings, aMapping);
+ if (cdsSeq != null)
+ {
+ if (!foundSeqs.contains(cdsSeq))
+ {
+ foundSeqs.add(cdsSeq);
+ SequenceI derivedSequence = cdsSeq.deriveSequence();
+ cdsSeqs.add(derivedSequence);
+ if (!dataset.getSequences().contains(cdsSeq))
+ {
+ dataset.addSequence(cdsSeq);
+ }
+ }
+ continue;
+ }
+
+ /*
+ * didn't find mapped CDS sequence - construct it and add
+ * its dataset sequence to the dataset
+ */
+ cdsSeq = makeCdsSequence(dnaSeq.getDatasetSequence(), aMapping,
+ dataset).deriveSequence();
+ // cdsSeq has a name constructed as CDS|<dbref>
+ // <dbref> will be either the accession for the coding sequence,
+ // marked in the /via/ dbref to the protein product accession
+ // or it will be the original nucleotide accession.
+ SequenceI cdsSeqDss = cdsSeq.getDatasetSequence();
+
cdsSeqs.add(cdsSeq);
-
+
+ if (!dataset.getSequences().contains(cdsSeqDss))
+ {
+ // check if this sequence is a newly created one
+ // so needs adding to the dataset
+ dataset.addSequence(cdsSeqDss);
+ }
+
/*
* add a mapping from CDS to the (unchanged) mapped to range
*/
List<int[]> cdsRange = Collections.singletonList(new int[] { 1,
cdsSeq.getLength() });
- MapList map = new MapList(cdsRange, aMapping.getMap()
- .getToRanges(), aMapping.getMap().getFromRatio(),
- aMapping.getMap().getToRatio());
- cdsMappings.addMap(cdsSeq, aMapping.getTo(), map);
+ MapList cdsToProteinMap = new MapList(cdsRange,
+ mapList.getToRanges(), mapList.getFromRatio(),
+ mapList.getToRatio());
+ AlignedCodonFrame cdsToProteinMapping = new AlignedCodonFrame();
+ cdsToProteinMapping.addMap(cdsSeqDss, proteinProduct,
+ cdsToProteinMap);
/*
+ * guard against duplicating the mapping if repeating this action
+ */
+ if (!mappings.contains(cdsToProteinMapping))
+ {
+ mappings.add(cdsToProteinMapping);
+ }
+
+ propagateDBRefsToCDS(cdsSeqDss, dnaSeq.getDatasetSequence(),
+ proteinProduct, aMapping);
+ /*
* add another mapping from original 'from' range to CDS
*/
- map = new MapList(aMapping.getMap().getFromRanges(), cdsRange, 1,
- 1);
- cdsMappings.addMap(seq.getDatasetSequence(), cdsSeq, map);
+ AlignedCodonFrame dnaToCdsMapping = new AlignedCodonFrame();
+ MapList dnaToCdsMap = new MapList(mapList.getFromRanges(),
+ cdsRange, 1, 1);
+ dnaToCdsMapping.addMap(dnaSeq.getDatasetSequence(), cdsSeqDss,
+ dnaToCdsMap);
+ if (!mappings.contains(dnaToCdsMapping))
+ {
+ mappings.add(dnaToCdsMapping);
+ }
- alignmentMappings.add(cdsMappings);
+ /*
+ * add DBRef with mapping from protein to CDS
+ * (this enables Get Cross-References from protein alignment)
+ * This is tricky because we can't have two DBRefs with the
+ * same source and accession, so need a different accession for
+ * the CDS from the dna sequence
+ */
+
+ // specific use case:
+ // Genomic contig ENSCHR:1, contains coding regions for ENSG01,
+ // ENSG02, ENSG03, with transcripts and products similarly named.
+ // cannot add distinct dbrefs mapping location on ENSCHR:1 to ENSG01
+
+ // JBPNote: ?? can't actually create an example that demonstrates we
+ // need to
+ // synthesize an xref.
+
+ for (DBRefEntry primRef : dnaDss.getPrimaryDBRefs())
+ {
+ // creates a complementary cross-reference to the source sequence's
+ // primary reference.
+
+ DBRefEntry cdsCrossRef = new DBRefEntry(primRef.getSource(),
+ primRef.getSource() + ":" + primRef.getVersion(),
+ primRef.getAccessionId());
+ cdsCrossRef
+ .setMap(new Mapping(dnaDss, new MapList(dnaToCdsMap)));
+ cdsSeqDss.addDBRef(cdsCrossRef);
+
+ // problem here is that the cross-reference is synthesized -
+ // cdsSeq.getName() may be like 'CDS|dnaaccession' or
+ // 'CDS|emblcdsacc'
+ // assuming cds version same as dna ?!?
+
+ DBRefEntry proteinToCdsRef = new DBRefEntry(
+ primRef.getSource(), primRef.getVersion(),
+ cdsSeq.getName());
+ //
+ proteinToCdsRef.setMap(new Mapping(cdsSeqDss, cdsToProteinMap
+ .getInverse()));
+ proteinProduct.addDBRef(proteinToCdsRef);
+ }
/*
* transfer any features on dna that overlap the CDS
*/
- transferFeatures(seq, cdsSeq, map, null, SequenceOntologyI.CDS);
+ transferFeatures(dnaSeq, cdsSeq, dnaToCdsMap, null,
+ SequenceOntologyI.CDS);
}
}
}
+ AlignmentI cds = new Alignment(cdsSeqs.toArray(new SequenceI[cdsSeqs
+ .size()]));
+ cds.setDataset(dataset);
+
+ return cds;
+ }
+
+ /**
+ * A helper method that finds a CDS sequence in the alignment dataset that is
+ * mapped to the given protein sequence, and either is, or has a mapping from,
+ * the given dna sequence.
+ *
+ * @param mappings
+ * set of all mappings on the dataset
+ * @param dnaSeq
+ * a dna (or cds) sequence we are searching from
+ * @param seqMappings
+ * the set of mappings involving dnaSeq
+ * @param aMapping
+ * an initial candidate from seqMappings
+ * @return
+ */
+ static SequenceI findCdsForProtein(List<AlignedCodonFrame> mappings,
+ SequenceI dnaSeq, List<AlignedCodonFrame> seqMappings,
+ Mapping aMapping)
+ {
+ /*
+ * TODO a better dna-cds-protein mapping data representation to allow easy
+ * navigation; until then this clunky looping around lists of mappings
+ */
+ SequenceI seqDss = dnaSeq.getDatasetSequence() == null ? dnaSeq
+ : dnaSeq.getDatasetSequence();
+ SequenceI proteinProduct = aMapping.getTo();
+
+ /*
+ * is this mapping from the whole dna sequence (i.e. CDS)?
+ * allowing for possible stop codon on dna but not peptide
+ */
+ int mappedFromLength = MappingUtils.getLength(aMapping.getMap()
+ .getFromRanges());
+ int dnaLength = seqDss.getLength();
+ if (mappedFromLength == dnaLength
+ || mappedFromLength == dnaLength - CODON_LENGTH)
+ {
+ return seqDss;
+ }
+
/*
- * add CDS seqs to shared dataset
+ * looks like we found the dna-to-protein mapping; search for the
+ * corresponding cds-to-protein mapping
*/
- Alignment dataset = al.getDataset();
- for (SequenceI seq : cdsSeqs)
+ List<AlignedCodonFrame> mappingsToPeptide = MappingUtils
+ .findMappingsForSequence(proteinProduct, mappings);
+ for (AlignedCodonFrame acf : mappingsToPeptide)
{
- if (!dataset.getSequences().contains(seq.getDatasetSequence()))
+ for (SequenceToSequenceMapping map : acf.getMappings())
{
- dataset.addSequence(seq.getDatasetSequence());
+ Mapping mapping = map.getMapping();
+ if (mapping != aMapping
+ && mapping.getMap().getFromRatio() == CODON_LENGTH
+ && proteinProduct == mapping.getTo()
+ && seqDss != map.getFromSeq())
+ {
+ mappedFromLength = MappingUtils.getLength(mapping.getMap()
+ .getFromRanges());
+ if (mappedFromLength == map.getFromSeq().getLength())
+ {
+ /*
+ * found a 3:1 mapping to the protein product which covers
+ * the whole dna sequence i.e. is from CDS; finally check it
+ * is from the dna start sequence
+ */
+ SequenceI cdsSeq = map.getFromSeq();
+ List<AlignedCodonFrame> dnaToCdsMaps = MappingUtils
+ .findMappingsForSequence(cdsSeq, seqMappings);
+ if (!dnaToCdsMaps.isEmpty())
+ {
+ return cdsSeq;
+ }
+ }
+ }
}
}
- AlignmentI cds = new Alignment(cdsSeqs.toArray(new SequenceI[cdsSeqs
- .size()]));
- cds.setDataset(dataset);
-
- return cds;
+ return null;
}
/**
*
* @param seq
* @param mapping
- * @return
+ * @param dataset
+ * - existing dataset. We check for sequences that look like the CDS
+ * we are about to construct, if one exists already, then we will
+ * just return that one.
+ * @return CDS sequence (as a dataset sequence)
*/
- static SequenceI makeCdsSequence(SequenceI seq, Mapping mapping)
+ static SequenceI makeCdsSequence(SequenceI seq, Mapping mapping,
+ AlignmentI dataset)
{
char[] seqChars = seq.getSequence();
List<int[]> fromRanges = mapping.getMap().getFromRanges();
}
}
- SequenceI newSeq = new Sequence(seq.getName() + "|"
- + mapping.getTo().getName(), newSeqChars, 1, newPos);
- newSeq.createDatasetSequence();
+ /*
+ * assign 'from id' held in the mapping if set (e.g. EMBL protein_id),
+ * else generate a sequence name
+ */
+ String mapFromId = mapping.getMappedFromId();
+ String seqId = "CDS|" + (mapFromId != null ? mapFromId : seq.getName());
+ SequenceI newSeq = new Sequence(seqId, newSeqChars, 1, newPos);
+ if (dataset != null)
+ {
+ SequenceI[] matches = dataset.findSequenceMatch(newSeq.getName());
+ if (matches != null)
+ {
+ boolean matched = false;
+ for (SequenceI mtch : matches)
+ {
+ if (mtch.getStart() != newSeq.getStart())
+ {
+ continue;
+ }
+ if (mtch.getEnd() != newSeq.getEnd())
+ {
+ continue;
+ }
+ if (!Arrays.equals(mtch.getSequence(), newSeq.getSequence()))
+ {
+ continue;
+ }
+ if (!matched)
+ {
+ matched = true;
+ newSeq = mtch;
+ }
+ else
+ {
+ System.err
+ .println("JAL-2154 regression: warning - found (and ignnored a duplicate CDS sequence):"
+ + mtch.toString());
+ }
+ }
+ }
+ }
+ // newSeq.setDescription(mapFromId);
+
return newSeq;
}
/**
+ * add any DBRefEntrys to cdsSeq from contig that have a Mapping congruent to
+ * the given mapping.
+ *
+ * @param cdsSeq
+ * @param contig
+ * @param mapping
+ * @return list of DBRefEntrys added.
+ */
+ public static List<DBRefEntry> propagateDBRefsToCDS(SequenceI cdsSeq,
+ SequenceI contig, SequenceI proteinProduct, Mapping mapping)
+ {
+
+ // gather direct refs from contig congrent with mapping
+ List<DBRefEntry> direct = new ArrayList<DBRefEntry>();
+ HashSet<String> directSources = new HashSet<String>();
+ if (contig.getDBRefs() != null)
+ {
+ for (DBRefEntry dbr : contig.getDBRefs())
+ {
+ if (dbr.hasMap() && dbr.getMap().getMap().isTripletMap())
+ {
+ MapList map = dbr.getMap().getMap();
+ // check if map is the CDS mapping
+ if (mapping.getMap().equals(map))
+ {
+ direct.add(dbr);
+ directSources.add(dbr.getSource());
+ }
+ }
+ }
+ }
+ DBRefEntry[] onSource = DBRefUtils.selectRefs(
+ proteinProduct.getDBRefs(),
+ directSources.toArray(new String[0]));
+ List<DBRefEntry> propagated = new ArrayList<DBRefEntry>();
+
+ // and generate appropriate mappings
+ for (DBRefEntry cdsref : direct)
+ {
+ // clone maplist and mapping
+ MapList cdsposmap = new MapList(Arrays.asList(new int[][] { new int[]
+ { cdsSeq.getStart(), cdsSeq.getEnd() } }), cdsref.getMap().getMap()
+ .getToRanges(), 3, 1);
+ Mapping cdsmap = new Mapping(cdsref.getMap().getTo(), cdsref.getMap()
+ .getMap());
+
+ // create dbref
+ DBRefEntry newref = new DBRefEntry(cdsref.getSource(),
+ cdsref.getVersion(), cdsref.getAccessionId(), new Mapping(
+ cdsmap.getTo(), cdsposmap));
+
+ // and see if we can map to the protein product for this mapping.
+ // onSource is the filtered set of accessions on protein that we are
+ // tranferring, so we assume accession is the same.
+ if (cdsmap.getTo() == null && onSource != null)
+ {
+ List<DBRefEntry> sourceRefs = DBRefUtils.searchRefs(onSource,
+ cdsref.getAccessionId());
+ if (sourceRefs != null)
+ {
+ for (DBRefEntry srcref : sourceRefs)
+ {
+ if (srcref.getSource().equalsIgnoreCase(cdsref.getSource()))
+ {
+ // we have found a complementary dbref on the protein product, so
+ // update mapping's getTo
+ newref.getMap().setTo(proteinProduct);
+ }
+ }
+ }
+ }
+ cdsSeq.addDBRef(newref);
+ propagated.add(newref);
+ }
+ return propagated;
+ }
+
+ /**
* Transfers co-located features on 'fromSeq' to 'toSeq', adjusting the
* feature start/end ranges, optionally omitting specified feature types.
* Returns the number of features copied.
/*
* dna length should map to protein (or protein plus stop codon)
*/
- int codesForResidues = mappedDnaLength / 3;
+ int codesForResidues = mappedDnaLength / CODON_LENGTH;
if (codesForResidues == (proteinLength + 1))
{
// assuming extra codon is for STOP and not in peptide
if (codesForResidues == proteinLength)
{
proteinRange.add(new int[] { proteinStart, proteinEnd });
- return new MapList(ranges, proteinRange, 3, 1);
+ return new MapList(ranges, proteinRange, CODON_LENGTH, 1);
}
return null;
}
* sort to get sequence features in start position order
* - would be better to store in Sequence as a TreeSet or NCList?
*/
- Arrays.sort(peptide.getSequenceFeatures(),
- new Comparator<SequenceFeature>()
- {
- @Override
- public int compare(SequenceFeature o1, SequenceFeature o2)
+ if (peptide.getSequenceFeatures() != null)
+ {
+ Arrays.sort(peptide.getSequenceFeatures(),
+ new Comparator<SequenceFeature>()
{
- int c = Integer.compare(o1.getBegin(), o2.getBegin());
- return c == 0 ? Integer.compare(o1.getEnd(), o2.getEnd())
- : c;
- }
- });
+ @Override
+ public int compare(SequenceFeature o1, SequenceFeature o2)
+ {
+ int c = Integer.compare(o1.getBegin(), o2.getBegin());
+ return c == 0 ? Integer.compare(o1.getEnd(), o2.getEnd())
+ : c;
+ }
+ });
+ }
return count;
}
* are currently ignored here
*/
String trans = codon.contains("-") ? "-"
- : (codon.length() > 3 ? null : ResidueProperties
+ : (codon.length() > CODON_LENGTH ? null : ResidueProperties
.codonTranslate(codon));
if (trans != null && !trans.equals(residue))
{
// set score to 0f so 'graduated colour' option is offered! JAL-2060
SequenceFeature sf = new SequenceFeature(
SequenceOntologyI.SEQUENCE_VARIANT, desc, peptidePos,
- peptidePos, 0f, "Jalview");
+ peptidePos, 0f, var.getSource());
StringBuilder attributes = new StringBuilder(32);
String id = (String) var.variant.getValue(ID);
if (id != null)
}
sf.setValue(ID, id);
attributes.append(ID).append("=").append(id);
- // TODO handle other species variants
+ // TODO handle other species variants JAL-2064
StringBuilder link = new StringBuilder(32);
try
{
- link.append(desc).append(" ").append(id)
+ link.append(desc)
+ .append(" ")
+ .append(id)
.append("|http://www.ensembl.org/Homo_sapiens/Variation/Summary?v=")
.append(URLEncoder.encode(id, "UTF-8"));
sf.addLink(link.toString());
// as if
}
}
- String clinSig = (String) var.variant
- .getValue(CLINICAL_SIGNIFICANCE);
+ String clinSig = (String) var.variant.getValue(CLINICAL_SIGNIFICANCE);
if (clinSig != null)
{
sf.setValue(CLINICAL_SIGNIFICANCE, clinSig);
* @param dnaToProtein
* @return
*/
+ @SuppressWarnings("unchecked")
static LinkedHashMap<Integer, List<DnaVariant>[]> buildDnaVariantsMap(
SequenceI dnaSeq, MapList dnaToProtein)
{
List<DnaVariant>[] codonVariants = variants.get(peptidePosition);
if (codonVariants == null)
{
- codonVariants = new ArrayList[3];
+ codonVariants = new ArrayList[CODON_LENGTH];
codonVariants[0] = new ArrayList<DnaVariant>();
codonVariants[1] = new ArrayList<DnaVariant>();
codonVariants[2] = new ArrayList<DnaVariant>();
/*
* save nucleotide (and any variant) for each codon position
*/
- for (int codonPos = 0; codonPos < 3; codonPos++)
+ for (int codonPos = 0; codonPos < CODON_LENGTH; codonPos++)
{
String nucleotide = String.valueOf(
dnaSeq.getCharAt(codon[codonPos] - dnaStart))
*
* @param seqs
* @param xrefs
+ * @param dataset
+ * the alignment dataset shared by the new copy
* @return
*/
public static AlignmentI makeCopyAlignment(SequenceI[] seqs,
- SequenceI[] xrefs)
+ SequenceI[] xrefs, AlignmentI dataset)
{
AlignmentI copy = new Alignment(new Alignment(seqs));
-
- /*
- * add mappings between sequences to the new alignment
- */
- AlignedCodonFrame mappings = new AlignedCodonFrame();
- copy.addCodonFrame(mappings);
- for (int i = 0; i < copy.getHeight(); i++)
- {
- SequenceI from = seqs[i];
- SequenceI to = copy.getSequenceAt(i);
- if (to.getDatasetSequence() != null)
- {
- to = to.getDatasetSequence();
- }
- int start = from.getStart();
- int end = from.getEnd();
- MapList map = new MapList(new int[] { start, end }, new int[] {
- start, end }, 1, 1);
- mappings.addMap(to, from, map);
- }
-
+ copy.setDataset(dataset);
+ boolean isProtein = !copy.isNucleotide();
SequenceIdMatcher matcher = new SequenceIdMatcher(seqs);
if (xrefs != null)
{
{
for (DBRefEntry dbref : dbrefs)
{
- if (dbref.getMap() == null || dbref.getMap().getTo() == null)
+ if (dbref.getMap() == null || dbref.getMap().getTo() == null
+ || dbref.getMap().getTo().isProtein() != isProtein)
{
continue;
}
*/
public static int alignAs(AlignmentI unaligned, AlignmentI aligned)
{
+ /*
+ * easy case - aligning a copy of aligned sequences
+ */
+ if (alignAsSameSequences(unaligned, aligned))
+ {
+ return unaligned.getHeight();
+ }
+
+ /*
+ * fancy case - aligning via mappings between sequences
+ */
List<SequenceI> unmapped = new ArrayList<SequenceI>();
Map<Integer, Map<SequenceI, Character>> columnMap = buildMappedColumnsMap(
unaligned, aligned, unmapped);
int width = columnMap.size();
char gap = unaligned.getGapCharacter();
int realignedCount = 0;
+ // TODO: verify this loop scales sensibly for very wide/high alignments
for (SequenceI seq : unaligned.getSequences())
{
if (!unmapped.contains(seq))
{
char[] newSeq = new char[width];
- Arrays.fill(newSeq, gap);
+ Arrays.fill(newSeq, gap); // JBPComment - doubt this is faster than the
+ // Integer iteration below
int newCol = 0;
int lastCol = 0;
}
newCol++;
}
-
+
/*
* trim trailing gaps
*/
System.arraycopy(newSeq, 0, tmp, 0, lastCol + 1);
newSeq = tmp;
}
+ // TODO: optimise SequenceI to avoid char[]->String->char[]
seq.setSequence(String.valueOf(newSeq));
realignedCount++;
}
}
/**
+ * If unaligned and aligned sequences share the same dataset sequences, then
+ * simply copies the aligned sequences to the unaligned sequences and returns
+ * true; else returns false
+ *
+ * @param unaligned
+ * - sequences to be aligned based on aligned
+ * @param aligned
+ * - 'guide' alignment containing sequences derived from same dataset
+ * as unaligned
+ * @return
+ */
+ static boolean alignAsSameSequences(AlignmentI unaligned,
+ AlignmentI aligned)
+ {
+ if (aligned.getDataset() == null || unaligned.getDataset() == null)
+ {
+ return false; // should only pass alignments with datasets here
+ }
+
+ // map from dataset sequence to alignment sequence(s)
+ Map<SequenceI, List<SequenceI>> alignedDatasets = new HashMap<SequenceI, List<SequenceI>>();
+ for (SequenceI seq : aligned.getSequences())
+ {
+ SequenceI ds = seq.getDatasetSequence();
+ if (alignedDatasets.get(ds) == null)
+ {
+ alignedDatasets.put(ds, new ArrayList<SequenceI>());
+ }
+ alignedDatasets.get(ds).add(seq);
+ }
+
+ /*
+ * first pass - check whether all sequences to be aligned share a dataset
+ * sequence with an aligned sequence
+ */
+ for (SequenceI seq : unaligned.getSequences())
+ {
+ if (!alignedDatasets.containsKey(seq.getDatasetSequence()))
+ {
+ return false;
+ }
+ }
+
+ /*
+ * second pass - copy aligned sequences;
+ * heuristic rule: pair off sequences in order for the case where
+ * more than one shares the same dataset sequence
+ */
+ for (SequenceI seq : unaligned.getSequences())
+ {
+ List<SequenceI> alignedSequences = alignedDatasets.get(seq
+ .getDatasetSequence());
+ // TODO: getSequenceAsString() will be deprecated in the future
+ // TODO: need to leave to SequenceI implementor to update gaps
+ seq.setSequence(alignedSequences.get(0).getSequenceAsString());
+ if (alignedSequences.size() > 0)
+ {
+ // pop off aligned sequences (except the last one)
+ alignedSequences.remove(0);
+ }
+ }
+
+ return true;
+ }
+
+ /**
* Returns a map whose key is alignment column number (base 1), and whose
* values are a map of sequence characters in that column.
*
{
/*
* Map will hold, for each aligned column position, a map of
- * {unalignedSequence, sequenceCharacter} at that position.
+ * {unalignedSequence, characterPerSequence} at that position.
* TreeMap keeps the entries in ascending column order.
*/
Map<Integer, Map<SequenceI, Character>> map = new TreeMap<Integer, Map<SequenceI, Character>>();
/*
- * r any sequences that have no mapping so can't be realigned
+ * record any sequences that have no mapping so can't be realigned
*/
unmapped.addAll(unaligned.getSequences());
return false;
}
+ /*
+ * invert mapping if it is from unaligned to aligned sequence
+ */
+ if (seqMap.getTo() == fromSeq.getDatasetSequence())
+ {
+ seqMap = new Mapping(seq.getDatasetSequence(), seqMap.getMap()
+ .getInverse());
+ }
+
char[] fromChars = fromSeq.getSequence();
int toStart = seq.getStart();
char[] toChars = seq.getSequence();
* of the next character of the mapped-to sequence; stop when all
* the characters of the range have been counted
*/
- while (mappedCharPos <= range[1])
+ while (mappedCharPos <= range[1] && fromCol <= fromChars.length
+ && fromCol >= 0)
{
if (!Comparison.isGap(fromChars[fromCol - 1]))
{
import jalview.datamodel.Annotation;
import jalview.datamodel.Sequence;
import jalview.datamodel.SequenceI;
+import jalview.ext.android.SparseIntArray;
+import jalview.schemes.ResidueProperties;
import java.awt.Color;
-import java.util.Enumeration;
-import java.util.Hashtable;
import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
import java.util.Vector;
/**
int end;
- Vector seqNums; // vector of int vectors where first is sequence checksum
+ Vector<int[]> seqNums; // vector of int vectors where first is sequence
+ // checksum
int maxLength = 0; // used by quality calcs
boolean seqNumsChanged = false; // updated after any change via calcSeqNum;
- Hashtable[] total;
+ Map<String, Integer>[] total;
boolean canonicaliseAa = true; // if true then conservation calculation will
// symbol
/** Stores calculated quality values */
- public Vector quality;
+ private Vector<Double> quality;
/** Stores maximum and minimum values of quality values */
- public Double[] qualityRange = new Double[2];
+ private double[] qualityRange = new double[2];
- String consString = "";
+ private Sequence consSequence;
- Sequence consSequence;
+ private int threshold;
- Hashtable propHash;
+ private String name = "";
- int threshold;
-
- String name = "";
-
- int[][] cons2;
+ private int[][] cons2;
private String[] consSymbs;
*
* @param name
* Name of conservation
- * @param propHash
- * hash of properties for each symbol
* @param threshold
* to count the residues in residueHash(). commonly used value is 3
* @param sequences
* @param end
* end residue position
*/
- public Conservation(String name, Hashtable propHash, int threshold,
+ public Conservation(String name, int threshold,
List<SequenceI> sequences, int start, int end)
{
this.name = name;
- this.propHash = propHash;
this.threshold = threshold;
this.start = start;
this.end = end;
seqNums.addElement(new int[sq.length() + 1]);
}
- if (sq.hashCode() != ((int[]) seqNums.elementAt(i))[0])
+ if (sq.hashCode() != seqNums.elementAt(i)[0])
{
int j;
int len;
*/
public void calculate()
{
- Hashtable resultHash, ht;
- int thresh, j, jSize = sequences.length;
- int[] values; // Replaces residueHash
- String type, res = null;
- char c;
- Enumeration enumeration2;
+ int jSize = sequences.length;
+ // int[] values; // Replaces residueHash
+ SparseIntArray values = new SparseIntArray();
- total = new Hashtable[maxLength];
+ total = new Map[maxLength];
for (int i = start; i <= end; i++)
{
- values = new int[255];
+ // values = new int[255];
+ values.clear();
- for (j = 0; j < jSize; j++)
+ for (int j = 0; j < jSize; j++)
{
if (sequences[j].getLength() > i)
{
- c = sequences[j].getCharAt(i);
+ char c = sequences[j].getCharAt(i);
if (canonicaliseAa)
{ // lookup the base aa code symbol
- c = (char) jalview.schemes.ResidueProperties.aaIndex[sequences[j]
- .getCharAt(i)];
+ c = (char) ResidueProperties.aaIndex[sequences[j].getCharAt(i)];
if (c > 20)
{
c = '-';
else
{
// recover canonical aa symbol
- c = jalview.schemes.ResidueProperties.aa[c].charAt(0);
+ c = ResidueProperties.aa[c].charAt(0);
}
}
else
c = toUpperCase(c);
}
- values[c]++;
+ // values[c]++;
+ values.add(c, 1);
}
else
{
- values['-']++;
+ // values['-']++;
+ values.add('-', 1);
}
}
// What is the count threshold to count the residues in residueHash()
- thresh = (threshold * (jSize)) / 100;
+ int thresh = (threshold * jSize) / 100;
// loop over all the found residues
- resultHash = new Hashtable();
- for (char v = '-'; v < 'Z'; v++)
+ // Hashtable<String, Integer> resultHash = new Hashtable<String,
+ // Integer>();
+ Map<String, Integer> resultHash = new TreeMap<String, Integer>();
+ // for (char v = '-'; v < 'Z'; v++)
+ for (int key = 0; key < values.size(); key++)
{
-
- if (values[v] > thresh)
+ char v = (char) values.keyAt(key);
+ // if (values[v] > thresh)
+ if (values.valueAt(key) > thresh)
{
- res = String.valueOf(v);
+ String res = String.valueOf(v);
// Now loop over the properties
- enumeration2 = propHash.keys();
-
- while (enumeration2.hasMoreElements())
+ for (String type : ResidueProperties.propHash.keySet())
{
- type = (String) enumeration2.nextElement();
- ht = (Hashtable) propHash.get(type);
+ Map<String, Integer> ht = ResidueProperties.propHash.get(type);
// Have we ticked this before?
if (!resultHash.containsKey(type))
resultHash.put(type, ht.get("-"));
}
}
- else if (((Integer) resultHash.get(type)).equals(ht.get(res)) == false)
+ else if (!resultHash.get(type).equals(ht.get(res)))
{
resultHash.put(type, new Integer(-1));
}
* Calculates the conservation sequence
*
* @param consflag
- * if true, poitiveve conservation; false calculates negative
+ * if true, positive conservation; false calculates negative
* conservation
* @param percentageGaps
* commonly used value is 25
*/
public void verdict(boolean consflag, float percentageGaps)
{
- StringBuffer consString = new StringBuffer();
- String type;
- Integer result;
- int[] gapcons;
- int totGaps, count;
- float pgaps;
- Hashtable resultHash;
- Enumeration enumeration;
+ StringBuilder consString = new StringBuilder(end);
// NOTE THIS SHOULD CHECK IF THE CONSEQUENCE ALREADY
// EXISTS AND NOT OVERWRITE WITH '-', BUT THIS CASE
consSymbs = new String[end - start + 1];
for (int i = start; i <= end; i++)
{
- gapcons = countConsNGaps(i);
- totGaps = gapcons[1];
- pgaps = ((float) totGaps * 100) / sequences.length;
- consSymbs[i - start] = new String();
+ int[] gapcons = countConsNGaps(i);
+ int totGaps = gapcons[1];
+ float pgaps = ((float) totGaps * 100) / sequences.length;
+ StringBuilder positives = new StringBuilder(64);
+ StringBuilder negatives = new StringBuilder(32);
+ // consSymbs[i - start] = "";
if (percentageGaps > pgaps)
{
- resultHash = total[i - start];
+ Map<String, Integer> resultHash = total[i - start];
// Now find the verdict
- count = 0;
- enumeration = resultHash.keys();
-
- while (enumeration.hasMoreElements())
+ int count = 0;
+ for (String type : resultHash.keySet())
{
- type = (String) enumeration.nextElement();
- result = (Integer) resultHash.get(type);
+ int result = resultHash.get(type).intValue();
// Do we want to count +ve conservation or +ve and -ve cons.?
if (consflag)
{
- if (result.intValue() == 1)
+ if (result == 1)
{
- consSymbs[i - start] = type + " " + consSymbs[i - start];
+ // consSymbs[i - start] = type + " " + consSymbs[i - start];
+ positives.append(positives.length() == 0 ? "" : " ");
+ positives.append(type);
count++;
}
}
else
{
- if (result.intValue() != -1)
+ if (result != -1)
{
+ if (result == 0)
{
- if (result.intValue() == 0)
- {
- consSymbs[i - start] = consSymbs[i - start] + " !" + type;
- }
- else
- {
- consSymbs[i - start] = type + " " + consSymbs[i - start];
- }
+ /*
+ * add negatively conserved properties on the end
+ */
+ // consSymbs[i - start] = consSymbs[i - start] + " !" + type;
+ negatives.append(negatives.length() == 0 ? "" : " ");
+ negatives.append("!").append(type);
+ }
+ else
+ {
+ /*
+ * put positively conserved properties on the front
+ */
+ // consSymbs[i - start] = type + " " + consSymbs[i - start];
+ positives.append(positives.length() == 0 ? "" : " ");
+ positives.append(type);
}
-
count++;
}
}
}
+ if (negatives.length() > 0)
+ {
+ positives.append(" ").append(negatives);
+ }
+ consSymbs[i - start] = positives.toString();
if (count < 10)
{
*/
private void percentIdentity2()
{
- seqNums = new Vector();
+ seqNums = new Vector<int[]>();
// calcSeqNum(s);
int i = 0, iSize = sequences.length;
// Do we need to calculate this again?
while (j < sequences.length)
{
- sqnum = (int[]) seqNums.elementAt(j);
+ sqnum = seqNums.elementAt(j);
for (i = 1; i < sqnum.length; i++)
{
/**
* Calculates the quality of the set of sequences
*
- * @param start
+ * @param startRes
* Start residue
- * @param end
+ * @param endRes
* End residue
*/
- public void findQuality(int start, int end)
+ public void findQuality(int startRes, int endRes)
{
- quality = new Vector();
+ quality = new Vector<Double>();
double max = -10000;
- int[][] BLOSUM62 = jalview.schemes.ResidueProperties.getBLOSUM62();
+ int[][] BLOSUM62 = ResidueProperties.getBLOSUM62();
// Loop over columns // JBPNote Profiling info
// long ts = System.currentTimeMillis();
for (l = 0; l < size; l++)
{
- lengths[l] = ((int[]) seqNums.elementAt(l)).length - 1;
+ lengths[l] = seqNums.elementAt(l).length - 1;
}
- for (j = start; j <= end; j++)
+ for (j = startRes; j <= endRes; j++)
{
bigtot = 0;
{
tot = 0;
xx = new double[24];
- seqNum = (j < lengths[k]) ? ((int[]) seqNums.elementAt(k))[j + 1]
- : 23; // Sequence, or gap at the end
+ seqNum = (j < lengths[k]) ? seqNums.elementAt(k)[j + 1] : 23; // Sequence,
+ // or gap
+ // at the
+ // end
// This is a loop over r
for (i = 0; i < 23; i++)
double newmax = -10000;
- for (j = start; j <= end; j++)
+ for (j = startRes; j <= endRes; j++)
{
- tmp = ((Double) quality.elementAt(j)).doubleValue();
+ tmp = quality.elementAt(j).doubleValue();
tmp = ((max - tmp) * (size - cons2[j][23])) / size;
// System.out.println(tmp+ " " + j);
}
// System.out.println("Quality " + s);
- qualityRange[0] = new Double(0);
- qualityRange[1] = new Double(newmax);
+ qualityRange[0] = 0D;
+ qualityRange[1] = newmax;
}
/**
- * complete the given consensus and quuality annotation rows. Note: currently
+ * 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.
*
char c;
- if (conservation.annotations != null
+ if (conservation != null && conservation.annotations != null
&& conservation.annotations.length < alWidth)
{
conservation.annotations = new Annotation[alWidth];
if (quality2 != null)
{
- quality2.graphMax = qualityRange[1].floatValue();
+ quality2.graphMax = (float) qualityRange[1];
if (quality2.annotations != null
&& quality2.annotations.length < alWidth)
{
quality2.annotations = new Annotation[alWidth];
}
- qmin = qualityRange[0].floatValue();
- qmax = qualityRange[1].floatValue();
+ qmin = (float) qualityRange[0];
+ qmax = (float) qualityRange[1];
}
- for (int i = 0; i < alWidth; i++)
+ for (int i = istart; i < alWidth; i++)
{
float value = 0;
value = 10;
}
- float vprop = value - min;
- vprop /= max;
- int consp = i - start;
- String conssym = (value > 0 && consp > -1 && consp < consSymbs.length) ? consSymbs[consp]
- : "";
- conservation.annotations[i] = new Annotation(String.valueOf(c),
- conssym, ' ', value, new Color(minR + (maxR * vprop), minG
- + (maxG * vprop), minB + (maxB * vprop)));
+ if (conservation != null)
+ {
+ float vprop = value - min;
+ vprop /= max;
+ int consp = i - start;
+ String conssym = (value > 0 && consp > -1 && consp < consSymbs.length) ? consSymbs[consp]
+ : "";
+ conservation.annotations[i] = new Annotation(String.valueOf(c),
+ conssym, ' ', value, new Color(minR + (maxR * vprop), minG
+ + (maxG * vprop), minB + (maxB * vprop)));
+ }
// Quality calc
if (quality2 != null)
{
- value = ((Double) quality.elementAt(i)).floatValue();
- vprop = value - qmin;
+ value = quality.elementAt(i).floatValue();
+ float vprop = value - qmin;
vprop /= qmax;
quality2.annotations[i] = new Annotation(" ",
String.valueOf(value), ' ', value, new Color(minR
*
* @param name
* - name of conservation
- * @param consHash
- * - hash table of properties for each amino acid (normally
- * ResidueProperties.propHash)
* @param threshold
* - minimum number of conserved residues needed to indicate
* conservation (typically 3)
* @return Conservation object ready for use in visualization
*/
public static Conservation calculateConservation(String name,
- Hashtable consHash, int threshold, List<SequenceI> seqs,
- int start, int end, boolean posOrNeg, int consPercGaps,
- boolean calcQuality)
- {
- Conservation cons = new Conservation(name, consHash, threshold, seqs,
- start, end);
- return calculateConservation(cons, posOrNeg, consPercGaps, calcQuality);
- }
-
- /**
- * @param b
- * positive (true) or negative (false) conservation
- * @param consPercGaps
- * percentage of gaps tolerated in column
- * @param calcQuality
- * flag indicating if alignment quality should be calculated
- * @return Conservation object ready for use in visualization
- */
- public static Conservation calculateConservation(Conservation cons,
- boolean b, int consPercGaps, boolean calcQuality)
+ int threshold, List<SequenceI> seqs, int start, int end,
+ boolean posOrNeg, int consPercGaps, boolean calcQuality)
{
+ Conservation cons = new Conservation(name, threshold, seqs, start, end);
cons.calculate();
- cons.verdict(b, consPercGaps);
+ cons.verdict(posOrNeg, consPercGaps);
if (calcQuality)
{
import jalview.datamodel.SequenceI;
import jalview.util.DBRefUtils;
import jalview.util.MapList;
-import jalview.ws.SequenceFetcher;
+import jalview.ws.SequenceFetcherFactory;
import jalview.ws.seqfetcher.ASequenceFetcher;
import java.util.ArrayList;
+import java.util.Iterator;
import java.util.List;
-import java.util.Vector;
/**
- * Functions for cross-referencing sequence databases. user must first specify
- * if cross-referencing from protein or dna (set dna==true)
+ * Functions for cross-referencing sequence databases.
*
* @author JimP
*
public class CrossRef
{
/*
- * A sub-class that ignores Parent attribute when comparing sequence
- * features. This avoids 'duplicate' CDS features that only
- * differ in their parent Transcript ids.
+ * the dataset of the alignment for which we are searching for
+ * cross-references; in some cases we may resolve xrefs by
+ * searching in the dataset
*/
- class MySequenceFeature extends SequenceFeature
- {
- private SequenceFeature feat;
+ private AlignmentI dataset;
- MySequenceFeature(SequenceFeature sf)
- {
- this.feat = sf;
- }
+ /*
+ * the sequences for which we are seeking cross-references
+ */
+ private SequenceI[] fromSeqs;
- @Override
- public boolean equals(Object o)
- {
- return feat.equals(o, true);
- }
- }
+ /**
+ * matcher built from dataset
+ */
+ SequenceIdMatcher matcher;
/**
- * Select just the DNA or protein references for a protein or dna sequence
- *
- * @param fromDna
- * if true, select references from DNA (i.e. Protein databases), else
- * DNA database references
- * @param refs
- * a set of references to select from
- * @return
+ * sequences found by cross-ref searches to fromSeqs
*/
- public static DBRefEntry[] findXDbRefs(boolean fromDna, DBRefEntry[] refs)
- {
- return DBRefUtils.selectRefs(refs, fromDna ? DBRefSource.PROTEINDBS
- : DBRefSource.DNACODINGDBS);
- // could attempt to find other cross
- // refs here - ie PDB xrefs
- // (not dna, not protein seq)
- }
+ List<SequenceI> rseqs;
/**
- * @param dna
- * true if seqs are DNA seqs
+ * Constructor
+ *
* @param seqs
- * @return a list of sequence database cross reference source types
+ * the sequences for which we are seeking cross-references
+ * @param ds
+ * the containing alignment dataset (may be searched to resolve
+ * cross-references)
*/
- public static String[] findSequenceXrefTypes(boolean dna, SequenceI[] seqs)
+ public CrossRef(SequenceI[] seqs, AlignmentI ds)
{
- return findSequenceXrefTypes(dna, seqs, null);
+ fromSeqs = seqs;
+ dataset = ds.getDataset() == null ? ds : ds.getDataset();
}
/**
- * Indirect references are references from other sequences from the dataset to
- * any of the direct DBRefEntrys on the given sequences.
+ * Returns a list of distinct database sources for which sequences have either
+ * <ul>
+ * <li>a (dna-to-protein or protein-to-dna) cross-reference</li>
+ * <li>an indirect cross-reference - a (dna-to-protein or protein-to-dna)
+ * reference from another sequence in the dataset which has a cross-reference
+ * to a direct DBRefEntry on the given sequence</li>
+ * </ul>
*
* @param dna
- * true if seqs are DNA seqs
- * @param seqs
- * @return a list of sequence database cross reference source types
+ * - when true, cross-references *from* dna returned. When false,
+ * cross-references *from* protein are returned
+ * @return
*/
- public static String[] findSequenceXrefTypes(boolean dna,
- SequenceI[] seqs, AlignmentI dataset)
+ public List<String> findXrefSourcesForSequences(boolean dna)
{
- String[] dbrefs = null;
- List<String> refs = new ArrayList<String>();
- for (SequenceI seq : seqs)
+ List<String> sources = new ArrayList<String>();
+ for (SequenceI seq : fromSeqs)
{
if (seq != null)
{
- SequenceI dss = seq;
- while (dss.getDatasetSequence() != null)
- {
- dss = dss.getDatasetSequence();
- }
- DBRefEntry[] rfs = findXDbRefs(dna, dss.getDBRefs());
- if (rfs != null)
- {
- for (DBRefEntry ref : rfs)
- {
- if (!refs.contains(ref.getSource()))
- {
- refs.add(ref.getSource());
- }
- }
- }
- if (dataset != null)
- {
- // search for references to this sequence's direct references.
- DBRefEntry[] lrfs = CrossRef.findXDbRefs(!dna, seq.getDBRefs());
- List<SequenceI> rseqs = new ArrayList<SequenceI>();
- CrossRef.searchDatasetXrefs(seq, !dna, lrfs, dataset, rseqs,
- null); // don't need to specify codon frame for mapping here
- for (SequenceI rs : rseqs)
- {
- DBRefEntry[] xrs = findXDbRefs(dna, rs.getDBRefs());
- if (xrs != null)
- {
- for (DBRefEntry ref : xrs)
- {
- if (!refs.contains(ref.getSource()))
- {
- refs.add(ref.getSource());
- }
- }
- }
- // looks like copy and paste - change rfs to xrs?
- // for (int r = 0; rfs != null && r < rfs.length; r++)
- // {
- // if (!refs.contains(rfs[r].getSource()))
- // {
- // refs.add(rfs[r].getSource());
- // }
- // }
- }
- }
+ findXrefSourcesForSequence(seq, dna, sources);
}
}
- if (refs.size() > 0)
+ sources.remove(DBRefSource.EMBL); // hack to prevent EMBL xrefs resulting in
+ // redundant datasets
+ if (dna)
{
- dbrefs = new String[refs.size()];
- refs.toArray(dbrefs);
+ sources.remove(DBRefSource.ENSEMBL); // hack to prevent Ensembl and
+ // EnsemblGenomes xref option shown
+ // from cdna panel
+ sources.remove(DBRefSource.ENSEMBLGENOMES);
}
- return dbrefs;
+ // redundant datasets
+ return sources;
}
- public static boolean hasCdnaMap(SequenceI[] seqs)
+ /**
+ * Returns a list of distinct database sources for which a sequence has either
+ * <ul>
+ * <li>a (dna-to-protein or protein-to-dna) cross-reference</li>
+ * <li>an indirect cross-reference - a (dna-to-protein or protein-to-dna)
+ * reference from another sequence in the dataset which has a cross-reference
+ * to a direct DBRefEntry on the given sequence</li>
+ * </ul>
+ *
+ * @param seq
+ * the sequence whose dbrefs we are searching against
+ * @param fromDna
+ * when true, context is DNA - so sources identifying protein
+ * products will be returned.
+ * @param sources
+ * a list of sources to add matches to
+ */
+ void findXrefSourcesForSequence(SequenceI seq, boolean fromDna,
+ List<String> sources)
{
- // TODO unused - remove?
- String[] reftypes = findSequenceXrefTypes(false, seqs);
- for (int s = 0; s < reftypes.length; s++)
+ /*
+ * first find seq's xrefs (dna-to-peptide or peptide-to-dna)
+ */
+ DBRefEntry[] rfs = DBRefUtils.selectDbRefs(!fromDna, seq.getDBRefs());
+ addXrefsToSources(rfs, sources);
+ if (dataset != null)
{
- if (reftypes.equals(DBRefSource.EMBLCDS))
+ /*
+ * find sequence's direct (dna-to-dna, peptide-to-peptide) xrefs
+ */
+ DBRefEntry[] lrfs = DBRefUtils.selectDbRefs(fromDna, seq.getDBRefs());
+ List<SequenceI> foundSeqs = new ArrayList<SequenceI>();
+
+ /*
+ * find sequences in the alignment which xref one of these DBRefs
+ * i.e. is xref-ed to a common sequence identifier
+ */
+ searchDatasetXrefs(fromDna, seq, lrfs, foundSeqs, null);
+
+ /*
+ * add those sequences' (dna-to-peptide or peptide-to-dna) dbref sources
+ */
+ for (SequenceI rs : foundSeqs)
{
- return true;
- // no map
+ DBRefEntry[] xrs = DBRefUtils
+ .selectDbRefs(!fromDna, rs.getDBRefs());
+ addXrefsToSources(xrs, sources);
}
}
- return false;
}
- public static SequenceI[] getCdnaMap(SequenceI[] seqs)
+ /**
+ * Helper method that adds the source identifiers of some cross-references to
+ * a (non-redundant) list of database sources
+ *
+ * @param xrefs
+ * @param sources
+ */
+ void addXrefsToSources(DBRefEntry[] xrefs, List<String> sources)
{
- // TODO unused - remove?
- Vector cseqs = new Vector();
- for (int s = 0; s < seqs.length; s++)
+ if (xrefs != null)
{
- DBRefEntry[] cdna = findXDbRefs(true, seqs[s].getDBRefs());
- for (int c = 0; c < cdna.length; c++)
+ for (DBRefEntry ref : xrefs)
{
- if (cdna[c].getSource().equals(DBRefSource.EMBLCDS))
+ /*
+ * avoid duplication e.g. ENSEMBL and Ensembl
+ */
+ String source = DBRefUtils.getCanonicalName(ref.getSource());
+ if (!sources.contains(source))
{
- System.err
- .println("TODO: unimplemented sequence retrieval for coding region sequence.");
- // TODO: retrieve CDS dataset sequences
- // need global dataset sequence retriever/resolver to reuse refs
- // and construct Mapping entry.
- // insert gaps in CDS according to peptide gaps.
- // add gapped sequence to cseqs
+ sources.add(source);
}
}
}
- if (cseqs.size() > 0)
- {
- SequenceI[] rsqs = new SequenceI[cseqs.size()];
- cseqs.copyInto(rsqs);
- return rsqs;
- }
- return null;
-
}
/**
+ * Attempts to find cross-references from the sequences provided in the
+ * constructor to the given source database. Cross-references may be found
+ * <ul>
+ * <li>in dbrefs on the sequence which hold a mapping to a sequence
+ * <ul>
+ * <li>provided with a fetched sequence (e.g. ENA translation), or</li>
+ * <li>populated previously after getting cross-references</li>
+ * </ul>
+ * <li>as other sequences in the alignment which share a dbref identifier with
+ * the sequence</li>
+ * <li>by fetching from the remote database</li>
+ * </ul>
+ * The cross-referenced sequences, and mappings to them, are added to the
+ * alignment dataset.
*
- * @param seqs
- * sequences whose xrefs are being retrieved
- * @param dna
- * true if sequences are nucleotide
* @param source
- * @param al
- * alignment to search for cross-referenced sequences (and possibly
- * add to)
- * @return products (as dataset sequences)
+ * @return cross-referenced sequences (as dataset sequences)
*/
- public static Alignment findXrefSequences(SequenceI[] seqs,
- final boolean dna, final String source, AlignmentI al)
+ public Alignment findXrefSequences(String source, boolean fromDna)
{
- AlignmentI dataset = al.getDataset() == null ? al : al.getDataset();
- List<SequenceI> rseqs = new ArrayList<SequenceI>();
+
+ rseqs = new ArrayList<SequenceI>();
AlignedCodonFrame cf = new AlignedCodonFrame();
- for (SequenceI seq : seqs)
+ matcher = new SequenceIdMatcher(dataset.getSequences());
+
+ for (SequenceI seq : fromSeqs)
{
SequenceI dss = seq;
while (dss.getDatasetSequence() != null)
dss = dss.getDatasetSequence();
}
boolean found = false;
- DBRefEntry[] xrfs = CrossRef.findXDbRefs(dna, dss.getDBRefs());
+ DBRefEntry[] xrfs = DBRefUtils
+ .selectDbRefs(!fromDna, dss.getDBRefs());
+ // ENST & ENSP comes in to both Protein and nucleotide, so we need to
+ // filter them
+ // out later.
if ((xrfs == null || xrfs.length == 0) && dataset != null)
{
- System.out.println("Attempting to find ds Xrefs refs.");
- // FIXME should be dss not seq here?
- DBRefEntry[] lrfs = CrossRef.findXDbRefs(!dna, seq.getDBRefs());
- // less ambiguous would be a 'find primary dbRefEntry' method.
- // filter for desired source xref here
- found = CrossRef.searchDatasetXrefs(dss, !dna, lrfs, dataset,
- rseqs, cf);
+ /*
+ * found no suitable dbrefs on sequence - look for sequences in the
+ * alignment which share a dbref with this one
+ */
+ DBRefEntry[] lrfs = DBRefUtils.selectDbRefs(fromDna,
+ seq.getDBRefs());
+
+ /*
+ * find sequences (except this one!), of complementary type,
+ * which have a dbref to an accession id for this sequence,
+ * and add them to the results
+ */
+ found = searchDatasetXrefs(fromDna, dss, lrfs, rseqs, cf);
}
- for (int r = 0; xrfs != null && r < xrfs.length; r++)
+ if (xrfs == null && !found)
{
- DBRefEntry xref = xrfs[r];
- if (source != null && !source.equals(xref.getSource()))
- {
- continue;
- }
- if (xref.hasMap())
+ /*
+ * no dbref to source on this sequence or matched
+ * complementary sequence in the dataset
+ */
+ continue;
+ }
+ List<DBRefEntry> sourceRefs = DBRefUtils.searchRefsForSource(xrfs,
+ source);
+ Iterator<DBRefEntry> refIterator = sourceRefs.iterator();
+ // At this point, if we are retrieving Ensembl, we still don't filter out
+ // ENST when looking for protein crossrefs.
+ while (refIterator.hasNext())
+ {
+ DBRefEntry xref = refIterator.next();
+ found = false;
+ // we're only interested in coding cross-references, not
+ // locus->transcript
+ if (xref.hasMap() && xref.getMap().getMap().isTripletMap())
{
- if (xref.getMap().getTo() != null)
+ SequenceI mappedTo = xref.getMap().getTo();
+ if (mappedTo != null)
{
- SequenceI rsq = new Sequence(xref.getMap().getTo());
+ /*
+ * dbref contains the sequence it maps to; add it to the
+ * results unless we have done so already (could happen if
+ * fetching xrefs for sequences which have xrefs in common)
+ * for example: UNIPROT {P0CE19, P0CE20} -> EMBL {J03321, X06707}
+ */
+ found = true;
+ /*
+ * problem: matcher.findIdMatch() is lenient - returns a sequence
+ * with a dbref to the search arg e.g. ENST for ENSP - wrong
+ * but findInDataset() matches ENSP when looking for Uniprot...
+ */
+ SequenceI matchInDataset = findInDataset(xref);
+ if (matchInDataset != null && xref.getMap().getTo() != null
+ && matchInDataset != xref.getMap().getTo())
+ {
+ System.err
+ .println("Implementation problem (reopen JAL-2154): CrossRef.findInDataset seems to have recovered a different sequence than the one explicitly mapped for xref."
+ + "Found:"
+ + matchInDataset
+ + "\nExpected:"
+ + xref.getMap().getTo()
+ + "\nFor xref:"
+ + xref);
+ }
+ /*matcher.findIdMatch(mappedTo);*/
+ if (matchInDataset != null)
+ {
+ if (!rseqs.contains(matchInDataset))
+ {
+ rseqs.add(matchInDataset);
+ }
+ // even if rseqs contained matchInDataset - check mappings between
+ // these seqs are added
+ // need to try harder to only add unique mappings
+ if (xref.getMap().getMap().isTripletMap()
+ && dataset.getMapping(seq, matchInDataset) == null
+ && cf.getMappingBetween(seq, matchInDataset) == null)
+ {
+ // materialise a mapping for highlighting between these
+ // sequences
+ if (fromDna)
+ {
+ cf.addMap(dss, matchInDataset, xref.getMap().getMap(),
+ xref.getMap().getMappedFromId());
+ }
+ else
+ {
+ cf.addMap(matchInDataset, dss, xref.getMap().getMap()
+ .getInverse(), xref.getMap().getMappedFromId());
+ }
+ }
+
+ refIterator.remove();
+ continue;
+ }
+ // TODO: need to determine if this should be a deriveSequence
+ SequenceI rsq = new Sequence(mappedTo);
rseqs.add(rsq);
- if (xref.getMap().getMap().getFromRatio() != xref
- .getMap().getMap().getToRatio())
+ if (xref.getMap().getMap().isTripletMap())
{
// get sense of map correct for adding to product alignment.
- if (dna)
+ if (fromDna)
{
// map is from dna seq to a protein product
- cf.addMap(dss, rsq, xref.getMap().getMap());
+ cf.addMap(dss, rsq, xref.getMap().getMap(), xref.getMap()
+ .getMappedFromId());
}
else
{
// map should be from protein seq to its coding dna
- cf.addMap(rsq, dss, xref.getMap().getMap().getInverse());
+ cf.addMap(rsq, dss, xref.getMap().getMap().getInverse(),
+ xref.getMap().getMappedFromId());
}
}
- found = true;
}
}
+
if (!found)
{
- // do a bit more work - search for sequences with references matching
- // xrefs on this sequence.
- if (dataset != null)
+ SequenceI matchedSeq = matcher.findIdMatch(xref.getSource() + "|"
+ + xref.getAccessionId());
+ // if there was a match, check it's at least the right type of
+ // molecule!
+ if (matchedSeq != null && matchedSeq.isProtein() == fromDna)
{
- found |= searchDataset(dss, xref, dataset, rseqs, cf, false,
- !dna);
- if (found)
+ if (constructMapping(seq, matchedSeq, xref, cf, fromDna))
{
- xrfs[r] = null; // we've recovered seqs for this one.
+ found = true;
}
}
}
+
+ if (!found)
+ {
+ // do a bit more work - search for sequences with references matching
+ // xrefs on this sequence.
+ found = searchDataset(fromDna, dss, xref, rseqs, cf, false);
+ }
+ if (found)
+ {
+ refIterator.remove();
+ }
+ }
+
+ /*
+ * fetch from source database any dbrefs we haven't resolved up to here
+ */
+ if (!sourceRefs.isEmpty())
+ {
+ retrieveCrossRef(sourceRefs, seq, xrfs, fromDna, cf);
+ }
+ }
+
+ Alignment ral = null;
+ if (rseqs.size() > 0)
+ {
+ ral = new Alignment(rseqs.toArray(new SequenceI[rseqs.size()]));
+ if (!cf.isEmpty())
+ {
+ dataset.addCodonFrame(cf);
+ }
+ }
+ return ral;
+ }
+
+ private void retrieveCrossRef(List<DBRefEntry> sourceRefs, SequenceI seq,
+ DBRefEntry[] xrfs, boolean fromDna, AlignedCodonFrame cf)
+ {
+ ASequenceFetcher sftch = SequenceFetcherFactory.getSequenceFetcher();
+ SequenceI[] retrieved = null;
+ SequenceI dss = seq.getDatasetSequence() == null ? seq : seq
+ .getDatasetSequence();
+ // first filter in case we are retrieving crossrefs that have already been
+ // retrieved. this happens for cases where a database record doesn't yield
+ // protein products for CDS
+ removeAlreadyRetrievedSeqs(sourceRefs, fromDna);
+ if (sourceRefs.size() == 0)
+ {
+ // no more work to do! We already had all requested sequence records in
+ // the dataset.
+ return;
+ }
+ try
+ {
+ retrieved = sftch.getSequences(sourceRefs, !fromDna);
+ } catch (Exception e)
+ {
+ System.err
+ .println("Problem whilst retrieving cross references for Sequence : "
+ + seq.getName());
+ e.printStackTrace();
+ }
+
+ if (retrieved != null)
+ {
+ boolean addedXref = false;
+ List<SequenceI> newDsSeqs = new ArrayList<SequenceI>(), doNotAdd = new ArrayList<SequenceI>();
+
+ for (SequenceI retrievedSequence : retrieved)
+ {
+ // dataset gets contaminated ccwith non-ds sequences. why ??!
+ // try: Ensembl -> Nuc->Ensembl, Nuc->Uniprot-->Protein->EMBL->
+ SequenceI retrievedDss = retrievedSequence.getDatasetSequence() == null ? retrievedSequence
+ : retrievedSequence.getDatasetSequence();
+ addedXref |= importCrossRefSeq(cf, newDsSeqs, doNotAdd, dss,
+ retrievedDss);
}
- if (!found)
+ if (!addedXref)
{
- if (xrfs != null && xrfs.length > 0)
+ // try again, after looking for matching IDs
+ // shouldn't need to do this unless the dbref mechanism has broken.
+ updateDbrefMappings(seq, xrfs, retrieved, cf, fromDna);
+ for (SequenceI retrievedSequence : retrieved)
{
- // Try and get the sequence reference...
- /*
- * Ideal world - we ask for a sequence fetcher implementation here if
- * (jalview.io.RunTimeEnvironment.getSequenceFetcher()) (
- */
- ASequenceFetcher sftch = new SequenceFetcher();
- SequenceI[] retrieved = null;
- int l = xrfs.length;
- for (int r = 0; r < xrfs.length; r++)
+ // dataset gets contaminated ccwith non-ds sequences. why ??!
+ // try: Ensembl -> Nuc->Ensembl, Nuc->Uniprot-->Protein->EMBL->
+ SequenceI retrievedDss = retrievedSequence.getDatasetSequence() == null ? retrievedSequence
+ : retrievedSequence.getDatasetSequence();
+ addedXref |= importCrossRefSeq(cf, newDsSeqs, doNotAdd, dss,
+ retrievedDss);
+ }
+ }
+ for (SequenceI newToSeq : newDsSeqs)
+ {
+ if (!doNotAdd.contains(newToSeq)
+ && dataset.findIndex(newToSeq) == -1)
+ {
+ dataset.addSequence(newToSeq);
+ matcher.add(newToSeq);
+ }
+ }
+ }
+ }
+
+ /**
+ * Search dataset for sequences with a primary reference contained in
+ * sourceRefs.
+ *
+ * @param sourceRefs
+ * - list of references to filter.
+ * @param fromDna
+ * - type of sequence to search for matching primary reference.
+ */
+ private void removeAlreadyRetrievedSeqs(List<DBRefEntry> sourceRefs,
+ boolean fromDna)
+ {
+ DBRefEntry[] dbrSourceSet = sourceRefs.toArray(new DBRefEntry[0]);
+ for (SequenceI sq : dataset.getSequences())
+ {
+ boolean dupeFound = false;
+ // !fromDna means we are looking only for nucleotide sequences, not
+ // protein
+ if (sq.isProtein() == fromDna)
+ {
+ for (DBRefEntry dbr : sq.getPrimaryDBRefs())
+ {
+ for (DBRefEntry found : DBRefUtils.searchRefs(dbrSourceSet, dbr))
{
- // filter out any irrelevant or irretrievable references
- if (xrfs[r] == null
- || ((source != null && !source.equals(xrfs[r]
- .getSource())) || !sftch.isFetchable(xrfs[r]
- .getSource())))
- {
- l--;
- xrfs[r] = null;
- }
+ sourceRefs.remove(found);
+ dupeFound = true;
}
- if (l > 0)
+ }
+ }
+ if (dupeFound)
+ {
+ // rebuild the search array from the filtered sourceRefs list
+ dbrSourceSet = sourceRefs.toArray(new DBRefEntry[0]);
+ }
+ }
+ }
+
+ /**
+ * process sequence retrieved via a dbref on source sequence to resolve and
+ * transfer data
+ *
+ * @param cf
+ * @param sourceSequence
+ * @param retrievedSequence
+ * @return true if retrieveSequence was imported
+ */
+ private boolean importCrossRefSeq(AlignedCodonFrame cf,
+ List<SequenceI> newDsSeqs, List<SequenceI> doNotAdd,
+ SequenceI sourceSequence, SequenceI retrievedSequence)
+ {
+ /**
+ * set when retrievedSequence has been verified as a crossreference for
+ * sourceSequence
+ */
+ boolean imported = false;
+ DBRefEntry[] dbr = retrievedSequence.getDBRefs();
+ if (dbr != null)
+ {
+ for (DBRefEntry dbref : dbr)
+ {
+ SequenceI matched = findInDataset(dbref);
+ if (matched == sourceSequence)
+ {
+ // verified retrieved and source sequence cross-reference each other
+ imported = true;
+ }
+ // find any entry where we should put in the sequence being
+ // cross-referenced into the map
+ Mapping map = dbref.getMap();
+ if (map != null)
+ {
+ if (map.getTo() != null && map.getMap() != null)
{
- // System.out
- // .println("Attempting to retrieve cross referenced sequences.");
- DBRefEntry[] t = new DBRefEntry[l];
- l = 0;
- for (int r = 0; r < xrfs.length; r++)
+ if (map.getTo() == sourceSequence)
{
- if (xrfs[r] != null)
- {
- t[l++] = xrfs[r];
- }
+ // already called to import once, and most likely this sequence
+ // already imported !
+ continue;
}
- xrfs = t;
- try
+ if (matched == null)
{
- retrieved = sftch.getSequences(xrfs, !dna);
- // problem here is we don't know which of xrfs resulted in which
- // retrieved element
- } catch (Exception e)
- {
- System.err
- .println("Problem whilst retrieving cross references for Sequence : "
- + seq.getName());
- e.printStackTrace();
+ /*
+ * sequence is new to dataset, so save a reference so it can be added.
+ */
+ newDsSeqs.add(map.getTo());
+ continue;
}
- if (retrieved != null)
- {
- updateDbrefMappings(dna, seq, xrfs, retrieved, cf);
+ /*
+ * there was a matching sequence in dataset, so now, check to see if we can update the map.getTo() sequence to the existing one.
+ */
- SequenceIdMatcher matcher = new SequenceIdMatcher(
- dataset.getSequences());
- List<SequenceFeature> copiedFeatures = new ArrayList<SequenceFeature>();
- CrossRef me = new CrossRef();
- for (int rs = 0; rs < retrieved.length; rs++)
+ try
+ {
+ // compare ms with dss and replace with dss in mapping
+ // if map is congruent
+ SequenceI ms = map.getTo();
+ // TODO findInDataset requires exact sequence match but
+ // 'congruent' test is only for the mapped part
+ // maybe not a problem in practice since only ENA provide a
+ // mapping and it is to the full protein translation of CDS
+ // matcher.findIdMatch(map.getTo());
+ // TODO addendum: if matched is shorter than getTo, this will fail
+ // - when it should really succeed.
+ int sf = map.getMap().getToLowest();
+ int st = map.getMap().getToHighest();
+ SequenceI mappedrg = ms.getSubSequence(sf, st);
+ if (mappedrg.getLength() > 0
+ && ms.getSequenceAsString().equals(
+ matched.getSequenceAsString()))
{
- // TODO: examine each sequence for 'redundancy'
- DBRefEntry[] dbr = retrieved[rs].getDBRefs();
- if (dbr != null && dbr.length > 0)
+ /*
+ * sequences were a match,
+ */
+ String msg = "Mapping updated from " + ms.getName()
+ + " to retrieved crossreference "
+ + matched.getName();
+ System.out.println(msg);
+
+ DBRefEntry[] toRefs = map.getTo().getDBRefs();
+ if (toRefs != null)
{
- for (int di = 0; di < dbr.length; di++)
+ /*
+ * transfer database refs
+ */
+ for (DBRefEntry ref : toRefs)
{
- // find any entry where we should put in the sequence being
- // cross-referenced into the map
- Mapping map = dbr[di].getMap();
- if (map != null)
+ if (dbref.getSrcAccString().equals(
+ ref.getSrcAccString()))
{
- if (map.getTo() != null && map.getMap() != null)
+ continue; // avoid overwriting the ref on source sequence
+ }
+ matched.addDBRef(ref); // add or update mapping
+ }
+ }
+ doNotAdd.add(map.getTo());
+ map.setTo(matched);
+
+ /*
+ * give the reverse reference the inverse mapping
+ * (if it doesn't have one already)
+ */
+ setReverseMapping(matched, dbref, cf);
+
+ /*
+ * copy sequence features as well, avoiding
+ * duplication (e.g. same variation from two
+ * transcripts)
+ */
+ SequenceFeature[] sfs = ms.getSequenceFeatures();
+ if (sfs != null)
+ {
+ for (SequenceFeature feat : sfs)
+ {
+ /*
+ * make a flyweight feature object which ignores Parent
+ * attribute in equality test; this avoids creating many
+ * otherwise duplicate exon features on genomic sequence
+ */
+ SequenceFeature newFeature = new SequenceFeature(feat)
+ {
+ @Override
+ public boolean equals(Object o)
{
- SequenceI matched = matcher
- .findIdMatch(map.getTo());
- if (matched != null)
- {
- /*
- * already got an xref to this sequence; update this
- * map to point to the same sequence, and add
- * any new dbrefs to it
- */
- for (DBRefEntry ref : map.getTo().getDBRefs())
- {
- matched.addDBRef(ref); // add or update mapping
- }
- map.setTo(matched);
- }
- else
- {
- matcher.add(map.getTo());
- }
- try
- {
- // compare ms with dss and replace with dss in mapping
- // if map is congruent
- SequenceI ms = map.getTo();
- int sf = map.getMap().getToLowest();
- int st = map.getMap().getToHighest();
- SequenceI mappedrg = ms.getSubSequence(sf, st);
- // SequenceI loc = dss.getSubSequence(sf, st);
- if (mappedrg.getLength() > 0
- && ms.getSequenceAsString().equals(
- dss.getSequenceAsString()))
- // && mappedrg.getSequenceAsString().equals(
- // loc.getSequenceAsString()))
- {
- String msg = "Mapping updated from "
- + ms.getName()
- + " to retrieved crossreference "
- + dss.getName();
- System.out.println(msg);
- // method to update all refs of existing To on
- // retrieved sequence with dss and merge any props
- // on To onto dss.
- map.setTo(dss);
- /*
- * copy sequence features as well, avoiding
- * duplication (e.g. same variation from 2
- * transcripts)
- */
- SequenceFeature[] sfs = ms
- .getSequenceFeatures();
- if (sfs != null)
- {
- for (SequenceFeature feat : sfs)
- {
- /*
- * we override SequenceFeature.equals here (but
- * not elsewhere) to ignore Parent attribute
- * TODO not quite working yet!
- */
- if (!copiedFeatures
- .contains(me.new MySequenceFeature(
- feat)))
- {
- dss.addSequenceFeature(feat);
- copiedFeatures.add(feat);
- }
- }
- }
- cf.addMap(retrieved[rs].getDatasetSequence(),
- dss, map.getMap());
- }
- else
- {
- cf.addMap(retrieved[rs].getDatasetSequence(),
- map.getTo(), map.getMap());
- }
- } catch (Exception e)
- {
- System.err
- .println("Exception when consolidating Mapped sequence set...");
- e.printStackTrace(System.err);
- }
+ return super.equals(o, true);
}
- }
+ };
+ matched.addSequenceFeature(newFeature);
}
}
- retrieved[rs].updatePDBIds();
- rseqs.add(retrieved[rs]);
+
}
+ cf.addMap(retrievedSequence, map.getTo(), map.getMap());
+ } catch (Exception e)
+ {
+ System.err
+ .println("Exception when consolidating Mapped sequence set...");
+ e.printStackTrace(System.err);
}
}
}
}
}
+ if (imported)
+ {
+ retrievedSequence.updatePDBIds();
+ rseqs.add(retrievedSequence);
+ if (dataset.findIndex(retrievedSequence) == -1)
+ {
+ dataset.addSequence(retrievedSequence);
+ matcher.add(retrievedSequence);
+ }
+ }
+ return imported;
+ }
- Alignment ral = null;
- if (rseqs.size() > 0)
+ /**
+ * Sets the inverse sequence mapping in the corresponding dbref of the mapped
+ * to sequence (if any). This is used after fetching a cross-referenced
+ * sequence, if the fetched sequence has a mapping to the original sequence,
+ * to set the mapping in the original sequence's dbref.
+ *
+ * @param mapFrom
+ * the sequence mapped from
+ * @param dbref
+ * @param mappings
+ */
+ void setReverseMapping(SequenceI mapFrom, DBRefEntry dbref,
+ AlignedCodonFrame mappings)
+ {
+ SequenceI mapTo = dbref.getMap().getTo();
+ if (mapTo == null)
{
- ral = new Alignment(rseqs.toArray(new SequenceI[rseqs.size()]));
- if (cf != null && !cf.isEmpty())
+ return;
+ }
+ DBRefEntry[] dbrefs = mapTo.getDBRefs();
+ if (dbrefs == null)
+ {
+ return;
+ }
+ for (DBRefEntry toRef : dbrefs)
+ {
+ if (toRef.hasMap() && mapFrom == toRef.getMap().getTo())
{
- ral.addCodonFrame(cf);
+ /*
+ * found the reverse dbref; update its mapping if null
+ */
+ if (toRef.getMap().getMap() == null)
+ {
+ MapList inverse = dbref.getMap().getMap().getInverse();
+ toRef.getMap().setMap(inverse);
+ mappings.addMap(mapTo, mapFrom, inverse);
+ }
}
}
- return ral;
+ }
+
+ /**
+ * Returns null or the first sequence in the dataset which is identical to
+ * xref.mapTo, and has a) a primary dbref matching xref, or if none found, the
+ * first one with an ID source|xrefacc
+ *
+ * @param xref
+ * with map and mapped-to sequence
+ * @return
+ */
+ SequenceI findInDataset(DBRefEntry xref)
+ {
+ if (xref == null || !xref.hasMap() || xref.getMap().getTo() == null)
+ {
+ return null;
+ }
+ SequenceI mapsTo = xref.getMap().getTo();
+ String name = xref.getAccessionId();
+ String name2 = xref.getSource() + "|" + name;
+ SequenceI dss = mapsTo.getDatasetSequence() == null ? mapsTo : mapsTo
+ .getDatasetSequence();
+ // first check ds if ds is directly referenced
+ if (dataset.findIndex(dss) > -1)
+ {
+ return dss;
+ }
+ DBRefEntry template = new DBRefEntry(xref.getSource(), null,
+ xref.getAccessionId());
+ /**
+ * remember the first ID match - in case we don't find a match to template
+ */
+ SequenceI firstIdMatch = null;
+ for (SequenceI seq : dataset.getSequences())
+ {
+ // first check primary refs.
+ List<DBRefEntry> match = DBRefUtils.searchRefs(seq.getPrimaryDBRefs()
+ .toArray(new DBRefEntry[0]), template);
+ if (match != null && match.size() == 1 && sameSequence(seq, dss))
+ {
+ return seq;
+ }
+ /*
+ * clumsy alternative to using SequenceIdMatcher which currently
+ * returns sequences with a dbref to the matched accession id
+ * which we don't want
+ */
+ if (firstIdMatch == null
+ && (name.equals(seq.getName()) || seq.getName().startsWith(
+ name2)))
+ {
+ if (sameSequence(seq, dss))
+ {
+ firstIdMatch = seq;
+ }
+ }
+ }
+ return firstIdMatch;
+ }
+
+ /**
+ * Answers true if seq1 and seq2 contain exactly the same characters (ignoring
+ * case), else false. This method compares the lengths, then each character in
+ * turn, in order to 'fail fast'. For case-sensitive comparison, it would be
+ * possible to use Arrays.equals(seq1.getSequence(), seq2.getSequence()).
+ *
+ * @param seq1
+ * @param seq2
+ * @return
+ */
+ // TODO move to Sequence / SequenceI
+ static boolean sameSequence(SequenceI seq1, SequenceI seq2)
+ {
+ if (seq1 == seq2)
+ {
+ return true;
+ }
+ if (seq1 == null || seq2 == null)
+ {
+ return false;
+ }
+ char[] c1 = seq1.getSequence();
+ char[] c2 = seq2.getSequence();
+ if (c1.length != c2.length)
+ {
+ return false;
+ }
+ for (int i = 0; i < c1.length; i++)
+ {
+ int diff = c1[i] - c2[i];
+ /*
+ * same char or differ in case only ('a'-'A' == 32)
+ */
+ if (diff != 0 && diff != 32 && diff != -32)
+ {
+ return false;
+ }
+ }
+ return true;
}
/**
* retrieved sequence if found, and adds any new mappings to the
* AlignedCodonFrame
*
- * @param dna
* @param mapFrom
* @param xrefs
* @param retrieved
* @param acf
*/
- static void updateDbrefMappings(boolean dna, SequenceI mapFrom,
- DBRefEntry[] xrefs, SequenceI[] retrieved, AlignedCodonFrame acf)
+ void updateDbrefMappings(SequenceI mapFrom, DBRefEntry[] xrefs,
+ SequenceI[] retrieved, AlignedCodonFrame acf, boolean fromDna)
{
- SequenceIdMatcher matcher = new SequenceIdMatcher(retrieved);
+ SequenceIdMatcher idMatcher = new SequenceIdMatcher(retrieved);
for (DBRefEntry xref : xrefs)
{
if (!xref.hasMap())
{
String targetSeqName = xref.getSource() + "|"
+ xref.getAccessionId();
- SequenceI[] matches = matcher.findAllIdMatches(targetSeqName);
+ SequenceI[] matches = idMatcher.findAllIdMatches(targetSeqName);
if (matches == null)
{
return;
}
for (SequenceI seq : matches)
{
- MapList mapping = null;
- if (dna)
- {
- mapping = AlignmentUtils.mapCdnaToProtein(seq, mapFrom);
- }
- else
- {
- mapping = AlignmentUtils.mapCdnaToProtein(mapFrom, seq);
- if (mapping != null)
- {
- mapping = mapping.getInverse();
- }
- }
- if (mapping != null)
- {
- xref.setMap(new Mapping(seq, mapping));
- if (dna)
- {
- AlignmentUtils.computeProteinFeatures(mapFrom, seq, mapping);
- }
- if (dna)
- {
- acf.addMap(mapFrom, seq, mapping);
- }
- else
- {
- acf.addMap(seq, mapFrom, mapping.getInverse());
- }
- continue;
- }
+ constructMapping(mapFrom, seq, xref, acf, fromDna);
+ }
+ }
+ }
+ }
+
+ /**
+ * Tries to make a mapping between sequences. If successful, adds the mapping
+ * to the dbref and the mappings collection and answers true, otherwise
+ * answers false. The following methods of making are mapping are tried in
+ * turn:
+ * <ul>
+ * <li>if 'mapTo' holds a mapping to 'mapFrom', take the inverse; this is, for
+ * example, the case after fetching EMBL cross-references for a Uniprot
+ * sequence</li>
+ * <li>else check if the dna translates exactly to the protein (give or take
+ * start and stop codons></li>
+ * <li>else try to map based on CDS features on the dna sequence</li>
+ * </ul>
+ *
+ * @param mapFrom
+ * @param mapTo
+ * @param xref
+ * @param mappings
+ * @return
+ */
+ boolean constructMapping(SequenceI mapFrom, SequenceI mapTo,
+ DBRefEntry xref, AlignedCodonFrame mappings, boolean fromDna)
+ {
+ MapList mapping = null;
+ SequenceI dsmapFrom = mapFrom.getDatasetSequence() == null ? mapFrom
+ : mapFrom.getDatasetSequence();
+ SequenceI dsmapTo = mapTo.getDatasetSequence() == null ? mapTo : mapTo
+ .getDatasetSequence();
+ /*
+ * look for a reverse mapping, if found make its inverse.
+ * Note - we do this on dataset sequences only.
+ */
+ if (dsmapTo.getDBRefs() != null)
+ {
+ for (DBRefEntry dbref : dsmapTo.getDBRefs())
+ {
+ String name = dbref.getSource() + "|" + dbref.getAccessionId();
+ if (dbref.hasMap() && dsmapFrom.getName().startsWith(name))
+ {
+ /*
+ * looks like we've found a map from 'mapTo' to 'mapFrom'
+ * - invert it to make the mapping the other way
+ */
+ MapList reverse = dbref.getMap().getMap().getInverse();
+ xref.setMap(new Mapping(dsmapTo, reverse));
+ mappings.addMap(mapFrom, dsmapTo, reverse);
+ return true;
}
}
}
+
+ if (fromDna)
+ {
+ mapping = AlignmentUtils.mapCdnaToProtein(mapTo, mapFrom);
+ }
+ else
+ {
+ mapping = AlignmentUtils.mapCdnaToProtein(mapFrom, mapTo);
+ if (mapping != null)
+ {
+ mapping = mapping.getInverse();
+ }
+ }
+ if (mapping == null)
+ {
+ return false;
+ }
+ xref.setMap(new Mapping(mapTo, mapping));
+
+ /*
+ * and add a reverse DbRef with the inverse mapping
+ */
+ if (mapFrom.getDatasetSequence() != null && false)
+ // && mapFrom.getDatasetSequence().getSourceDBRef() != null)
+ {
+ // possible need to search primary references... except, why doesn't xref
+ // == getSourceDBRef ??
+ // DBRefEntry dbref = new DBRefEntry(mapFrom.getDatasetSequence()
+ // .getSourceDBRef());
+ // dbref.setMap(new Mapping(mapFrom.getDatasetSequence(), mapping
+ // .getInverse()));
+ // mapTo.addDBRef(dbref);
+ }
+
+ if (fromDna)
+ {
+ AlignmentUtils.computeProteinFeatures(mapFrom, mapTo, mapping);
+ mappings.addMap(mapFrom, mapTo, mapping);
+ }
+ else
+ {
+ mappings.addMap(mapTo, mapFrom, mapping.getInverse());
+ }
+
+ return true;
}
/**
* dataset (that is not equal to sequenceI) Identifies matching DBRefEntry
* based on source and accession string only - Map and Version are nulled.
*
+ * @param fromDna
+ * - true if context was searching from Dna sequences, false if
+ * context was searching from Protein sequences
* @param sequenceI
* @param lrfs
- * @param dataset
- * @param rseqs
+ * @param foundSeqs
* @return true if matches were found.
*/
- private static boolean searchDatasetXrefs(SequenceI sequenceI,
- boolean dna, DBRefEntry[] lrfs, AlignmentI dataset,
- List<SequenceI> rseqs, AlignedCodonFrame cf)
+ private boolean searchDatasetXrefs(boolean fromDna, SequenceI sequenceI,
+ DBRefEntry[] lrfs, List<SequenceI> foundSeqs, AlignedCodonFrame cf)
{
boolean found = false;
if (lrfs == null)
// add in wildcards
xref.setVersion(null);
xref.setMap(null);
- found = searchDataset(sequenceI, xref, dataset, rseqs, cf, false, dna);
+ found |= searchDataset(fromDna, sequenceI, xref, foundSeqs, cf, false);
}
return found;
}
/**
- * search a given sequence dataset for references matching cross-references to
- * the given sequence
- *
- * @param sequenceI
- * @param xrf
- * @param dataset
- * @param rseqs
- * set of unique sequences
- * @param cf
- * @return true if one or more unique sequences were found and added
- */
- public static boolean searchDataset(SequenceI sequenceI, DBRefEntry xrf,
- AlignmentI dataset, List<SequenceI> rseqs, AlignedCodonFrame cf)
- {
- return searchDataset(sequenceI, xrf, dataset, rseqs, cf, true, false);
- }
-
- /**
- * TODO: generalise to different protein classifications Search dataset for
- * DBRefEntrys matching the given one (xrf) and add the associated sequence to
- * rseq.
+ * Searches dataset for DBRefEntrys matching the given one (xrf) and adds the
+ * associated sequence to rseqs
*
- * @param sequenceI
+ * @param fromDna
+ * true if context was searching for refs *from* dna sequence, false
+ * if context was searching for refs *from* protein sequence
+ * @param fromSeq
+ * a sequence to ignore (start point of search)
* @param xrf
- * @param dataset
- * @param rseqs
+ * a cross-reference to try to match
+ * @param foundSeqs
+ * result list to add to
+ * @param mappings
+ * a set of sequence mappings to add to
* @param direct
- * - search all references or only subset
- * @param dna
- * search dna or protein xrefs (if direct=false)
+ * - indicates the type of relationship between returned sequences,
+ * xrf, and sequenceI that is required.
+ * <ul>
+ * <li>direct implies xrf is a primary reference for sequenceI AND
+ * the sequences to be located (eg a uniprot ID for a protein
+ * sequence, and a uniprot ref on a transcript sequence).</li>
+ * <li>indirect means xrf is a cross reference with respect to
+ * sequenceI or all the returned sequences (eg a genomic reference
+ * associated with a locus and one or more transcripts)</li>
+ * </ul>
* @return true if relationship found and sequence added.
*/
- public static boolean searchDataset(SequenceI sequenceI, DBRefEntry xrf,
- AlignmentI dataset, List<SequenceI> rseqs, AlignedCodonFrame cf,
- boolean direct, boolean dna)
+ boolean searchDataset(boolean fromDna, SequenceI fromSeq, DBRefEntry xrf,
+ List<SequenceI> foundSeqs, AlignedCodonFrame mappings,
+ boolean direct)
{
boolean found = false;
- SequenceI[] typer = new SequenceI[1];
if (dataset == null)
{
return false;
if (nxt.getDatasetSequence() != null)
{
System.err
- .println("Implementation warning: getProducts passed a dataset alignment without dataset sequences in it!");
+ .println("Implementation warning: CrossRef initialised with a dataset alignment with non-dataset sequences in it! ("
+ + nxt.getDisplayId(true)
+ + " has ds reference "
+ + nxt.getDatasetSequence().getDisplayId(true)
+ + ")");
+ }
+ if (nxt == fromSeq || nxt == fromSeq.getDatasetSequence())
+ {
+ continue;
}
- if (nxt != sequenceI && nxt != sequenceI.getDatasetSequence())
+ /*
+ * only look at same molecule type if 'direct', or
+ * complementary type if !direct
+ */
{
- // check if this is the correct sequence type
+ boolean isDna = !nxt.isProtein();
+ if (direct ? (isDna != fromDna) : (isDna == fromDna))
{
- typer[0] = nxt;
- boolean isDna = jalview.util.Comparison.isNucleotide(typer);
- if ((direct && isDna == dna) || (!direct && isDna != dna))
- {
- // skip this sequence because it is same molecule type
- continue;
- }
+ // skip this sequence because it is wrong molecule type
+ continue;
}
+ }
- // look for direct or indirect references in common
- DBRefEntry[] poss = nxt.getDBRefs(), cands = null;
- if (direct)
- {
- cands = jalview.util.DBRefUtils.searchRefs(poss, xrf);
- }
- else
+ // look for direct or indirect references in common
+ DBRefEntry[] poss = nxt.getDBRefs();
+ List<DBRefEntry> cands = null;
+
+ // todo: indirect specifies we select either direct references to nxt
+ // that match xrf which is indirect to sequenceI, or indirect
+ // references to nxt that match xrf which is direct to sequenceI
+ cands = DBRefUtils.searchRefs(poss, xrf);
+ // else
+ // {
+ // poss = DBRefUtils.selectDbRefs(nxt.isProtein()!fromDna, poss);
+ // cands = DBRefUtils.searchRefs(poss, xrf);
+ // }
+ if (!cands.isEmpty())
+ {
+ if (foundSeqs.contains(nxt))
{
- poss = CrossRef.findXDbRefs(dna, poss); //
- cands = jalview.util.DBRefUtils.searchRefs(poss, xrf);
+ continue;
}
- if (cands != null)
+ found = true;
+ foundSeqs.add(nxt);
+ if (mappings != null && !direct)
{
- if (!rseqs.contains(nxt))
+ /*
+ * if the matched sequence has mapped dbrefs to
+ * protein product / cdna, add equivalent mappings to
+ * our source sequence
+ */
+ for (DBRefEntry candidate : cands)
{
- rseqs.add(nxt);
- boolean foundmap = cf != null;
- // don't search if we aren't given a codon map object
- for (int r = 0; foundmap && r < cands.length; r++)
+ Mapping mapping = candidate.getMap();
+ if (mapping != null)
{
- if (cands[r].hasMap())
+ MapList map = mapping.getMap();
+ if (mapping.getTo() != null
+ && map.getFromRatio() != map.getToRatio())
{
- if (cands[r].getMap().getTo() != null
- && cands[r].getMap().getMap().getFromRatio() != cands[r]
- .getMap().getMap().getToRatio())
+ /*
+ * add a mapping, as from dna to peptide sequence
+ */
+ if (map.getFromRatio() == 3)
{
- foundmap = true;
- // get sense of map correct for adding to product
- // alignment.
- if (dna)
- {
- // map is from dna seq to a protein product
- cf.addMap(sequenceI, nxt, cands[r].getMap()
- .getMap());
- }
- else
- {
- // map should be from protein seq to its coding dna
- cf.addMap(nxt, sequenceI, cands[r].getMap()
- .getMap().getInverse());
- }
+ mappings.addMap(nxt, fromSeq, map);
+ }
+ else
+ {
+ mappings.addMap(nxt, fromSeq, map.getInverse());
}
}
}
- // TODO: add mapping between sequences if necessary
- found = true;
}
}
-
}
}
}
}
return found;
}
-
- /**
- * precalculate different products that can be found for seqs in dataset and
- * return them.
- *
- * @param dna
- * @param seqs
- * @param dataset
- * @param fake
- * - don't actually build lists - just get types
- * @return public static Object[] buildXProductsList(boolean dna, SequenceI[]
- * seqs, AlignmentI dataset, boolean fake) { String types[] =
- * jalview.analysis.CrossRef.findSequenceXrefTypes( dna, seqs,
- * dataset); if (types != null) { System.out.println("Xref Types for:
- * "+(dna ? "dna" : "prot")); for (int t = 0; t < types.length; t++) {
- * System.out.println("Type: " + types[t]); SequenceI[] prod =
- * jalview.analysis.CrossRef.findXrefSequences(seqs, dna, types[t]);
- * System.out.println("Found " + ((prod == null) ? "no" : "" +
- * prod.length) + " products"); if (prod!=null) { for (int p=0;
- * p<prod.length; p++) { System.out.println("Prod "+p+":
- * "+prod[p].getDisplayId(true)); } } } } else {
- * System.out.println("Trying getProducts for
- * "+al.getSequenceAt(0).getDisplayId(true));
- * System.out.println("Search DS Xref for: "+(dna ? "dna" : "prot"));
- * // have a bash at finding the products amongst all the retrieved
- * sequences. SequenceI[] prod =
- * jalview.analysis.CrossRef.findXrefSequences(al
- * .getSequencesArray(), dna, null, ds); System.out.println("Found " +
- * ((prod == null) ? "no" : "" + prod.length) + " products"); if
- * (prod!=null) { // select non-equivalent sequences from dataset list
- * for (int p=0; p<prod.length; p++) { System.out.println("Prod "+p+":
- * "+prod[p].getDisplayId(true)); } } } }
- */
}
final private int dnaWidth;
- final private Alignment dataset;
+ final private AlignmentI dataset;
/*
* Working variables for the translation.
char[] originalSequence = sequence.toCharArray();
int length = originalSequence.length;
char[] reversedSequence = new char[length];
-
+ int bases = 0;
for (int i = 0; i < length; i++)
{
- reversedSequence[length - i - 1] = complement ? getComplement(originalSequence[i])
+ char c = complement ? getComplement(originalSequence[i])
: originalSequence[i];
+ reversedSequence[length - i - 1] = c;
+ if (!Comparison.isGap(c))
+ {
+ bases++;
+ }
}
- SequenceI reversed = new Sequence(newName, reversedSequence, 1, length);
+ SequenceI reversed = new Sequence(newName, reversedSequence, 1, bases);
return reversed;
}
public static char getComplement(char c)
{
char result = c;
- switch (c) {
+ switch (c)
+ {
+ case '-':
+ case '.':
+ case ' ':
+ break;
case 'a':
result = 't';
break;
}
}
}
+
+ /*
+ * get selected columns (in the order they were selected);
+ * note this could include right-to-left ranges
+ */
int[] spos = new int[cs.getSelected().size()];
int width = -1;
int i = 0;
{
spos[i++] = pos.intValue();
}
- ;
+
for (i = 0; i < sequences.length; i++)
{
int slen = sequences[i].getLength();
*/
public class NJTree
{
- Vector cluster;
+ Vector<Cluster> cluster;
SequenceI[] sequence;
float rj;
- Vector groups = new Vector();
+ Vector<SequenceNode> groups = new Vector<SequenceNode>();
SequenceNode maxdist;
int ycount;
- Vector node;
+ Vector<SequenceNode> node;
String type;
Object found = null;
- Object leaves = null;
-
boolean hasDistances = true; // normal case for jalview trees
boolean hasBootstrap = false; // normal case for jalview trees
SequenceIdMatcher algnIds = new SequenceIdMatcher(seqs);
- Vector leaves = new Vector();
- findLeaves(top, leaves);
+ Vector<SequenceNode> leaves = findLeaves(top);
int i = 0;
int namesleft = seqs.length;
SequenceNode j;
SequenceI nam;
String realnam;
- Vector one2many = new Vector();
+ Vector<SequenceI> one2many = new Vector<SequenceI>();
int countOne2Many = 0;
while (i < leaves.size())
{
- j = (SequenceNode) leaves.elementAt(i++);
+ j = leaves.elementAt(i++);
realnam = j.getName();
nam = null;
String pwtype, ScoreModelI sm, int start, int end)
{
this.sequence = sequence;
- this.node = new Vector();
+ this.node = new Vector<SequenceNode>();
this.type = type;
this.pwtype = pwtype;
if (seqData != null)
*
* @return Newick File with all tree data available
*/
+ @Override
public String toString()
{
jalview.io.NewickFile fout = new jalview.io.NewickFile(getTopNode());
*/
public void UpdatePlaceHolders(List<SequenceI> list)
{
- Vector leaves = new Vector();
- findLeaves(top, leaves);
+ Vector<SequenceNode> leaves = findLeaves(top);
int sz = leaves.size();
SequenceIdMatcher seqmatcher = null;
while (i < sz)
{
- SequenceNode leaf = (SequenceNode) leaves.elementAt(i++);
+ SequenceNode leaf = leaves.elementAt(i++);
if (list.contains(leaf.element()))
{
{
@Override
- public void transform(BinaryNode node)
+ public void transform(BinaryNode nd)
{
- Object el = node.element();
+ Object el = nd.element();
if (el != null && el instanceof SequenceI)
{
- node.setName(((SequenceI) el).getName());
+ nd.setName(((SequenceI) el).getName());
}
}
});
}
joinClusters(one, two);
- top = (SequenceNode) (node.elementAt(one));
+ top = (node.elementAt(one));
reCount(top);
findHeight(top);
{
float dist = distance[i][j];
- int noi = ((Cluster) cluster.elementAt(i)).value.length;
- int noj = ((Cluster) cluster.elementAt(j)).value.length;
+ int noi = cluster.elementAt(i).value.length;
+ int noj = cluster.elementAt(j).value.length;
int[] value = new int[noi + noj];
for (int ii = 0; ii < noi; ii++)
{
- value[ii] = ((Cluster) cluster.elementAt(i)).value[ii];
+ value[ii] = cluster.elementAt(i).value[ii];
}
for (int ii = noi; ii < (noi + noj); ii++)
{
- value[ii] = ((Cluster) cluster.elementAt(j)).value[ii - noi];
+ value[ii] = cluster.elementAt(j).value[ii - noi];
}
Cluster c = new Cluster(value);
SequenceNode sn = new SequenceNode();
- sn.setLeft((SequenceNode) (node.elementAt(i)));
- sn.setRight((SequenceNode) (node.elementAt(j)));
+ sn.setLeft((node.elementAt(i)));
+ sn.setRight((node.elementAt(j)));
- SequenceNode tmpi = (SequenceNode) (node.elementAt(i));
- SequenceNode tmpj = (SequenceNode) (node.elementAt(j));
+ SequenceNode tmpi = (node.elementAt(i));
+ SequenceNode tmpj = (node.elementAt(j));
if (type.equals("NJ"))
{
*/
public void findClusterDistance(int i, int j)
{
- int noi = ((Cluster) cluster.elementAt(i)).value.length;
- int noj = ((Cluster) cluster.elementAt(j)).value.length;
+ int noi = cluster.elementAt(i).value.length;
+ int noj = cluster.elementAt(j).value.length;
// New distances from cluster to others
float[] newdist = new float[noseqs];
public float[][] findDistances(ScoreModelI _pwmatrix)
{
- float[][] distance = new float[noseqs][noseqs];
+ float[][] dist = new float[noseqs][noseqs];
if (_pwmatrix == null)
{
// Resolve substitution model
_pwmatrix = ResidueProperties.getScoreMatrix("BLOSUM62");
}
}
- distance = _pwmatrix.findDistances(seqData);
- return distance;
+ dist = _pwmatrix.findDistances(seqData);
+ return dist;
}
*/
public void makeLeaves()
{
- cluster = new Vector();
+ cluster = new Vector<Cluster>();
for (int i = 0; i < noseqs; i++)
{
}
/**
+ * Search for leaf nodes below (or at) the given node
+ *
+ * @param nd
+ * root node to search from
+ *
+ * @return
+ */
+ public Vector<SequenceNode> findLeaves(SequenceNode nd)
+ {
+ Vector<SequenceNode> leaves = new Vector<SequenceNode>();
+ findLeaves(nd, leaves);
+ return leaves;
+ }
+
+ /**
* Search for leaf nodes.
*
- * @param node
+ * @param nd
* root node to search from
* @param leaves
* Vector of leaves to add leaf node objects too.
*
* @return Vector of leaf nodes on binary tree
*/
- public Vector findLeaves(SequenceNode node, Vector leaves)
+ Vector<SequenceNode> findLeaves(SequenceNode nd,
+ Vector<SequenceNode> leaves)
{
- if (node == null)
+ if (nd == null)
{
return leaves;
}
- if ((node.left() == null) && (node.right() == null)) // Interior node
+ if ((nd.left() == null) && (nd.right() == null)) // Interior node
// detection
{
- leaves.addElement(node);
+ leaves.addElement(nd);
return leaves;
}
* TODO: Identify internal nodes... if (node.isSequenceLabel()) {
* leaves.addElement(node); }
*/
- findLeaves((SequenceNode) node.left(), leaves);
- findLeaves((SequenceNode) node.right(), leaves);
+ findLeaves((SequenceNode) nd.left(), leaves);
+ findLeaves((SequenceNode) nd.right(), leaves);
}
return leaves;
/**
* Find the leaf node with a particular ycount
*
- * @param node
+ * @param nd
* initial point on tree to search from
* @param count
* value to search for
*
* @return null or the node with ycound=count
*/
- public Object findLeaf(SequenceNode node, int count)
+ public Object findLeaf(SequenceNode nd, int count)
{
- found = _findLeaf(node, count);
+ found = _findLeaf(nd, count);
return found;
}
/*
* #see findLeaf(SequenceNode node, count)
*/
- public Object _findLeaf(SequenceNode node, int count)
+ public Object _findLeaf(SequenceNode nd, int count)
{
- if (node == null)
+ if (nd == null)
{
return null;
}
- if (node.ycount == count)
+ if (nd.ycount == count)
{
- found = node.element();
+ found = nd.element();
return found;
}
else
{
- _findLeaf((SequenceNode) node.left(), count);
- _findLeaf((SequenceNode) node.right(), count);
+ _findLeaf((SequenceNode) nd.left(), count);
+ _findLeaf((SequenceNode) nd.right(), count);
}
return found;
/**
* printNode is mainly for debugging purposes.
*
- * @param node
+ * @param nd
* SequenceNode
*/
- public void printNode(SequenceNode node)
+ public void printNode(SequenceNode nd)
{
- if (node == null)
+ if (nd == null)
{
return;
}
- if ((node.left() == null) && (node.right() == null))
+ if ((nd.left() == null) && (nd.right() == null))
{
- System.out
- .println("Leaf = " + ((SequenceI) node.element()).getName());
- System.out.println("Dist " + node.dist);
- System.out.println("Boot " + node.getBootstrap());
+ System.out.println("Leaf = " + ((SequenceI) nd.element()).getName());
+ System.out.println("Dist " + nd.dist);
+ System.out.println("Boot " + nd.getBootstrap());
}
else
{
- System.out.println("Dist " + node.dist);
- printNode((SequenceNode) node.left());
- printNode((SequenceNode) node.right());
+ System.out.println("Dist " + nd.dist);
+ printNode((SequenceNode) nd.left());
+ printNode((SequenceNode) nd.right());
}
}
/**
* DOCUMENT ME!
*
- * @param node
+ * @param nd
* DOCUMENT ME!
*/
- public void findMaxDist(SequenceNode node)
+ public void findMaxDist(SequenceNode nd)
{
- if (node == null)
+ if (nd == null)
{
return;
}
- if ((node.left() == null) && (node.right() == null))
+ if ((nd.left() == null) && (nd.right() == null))
{
- float dist = node.dist;
+ float dist = nd.dist;
if (dist > maxDistValue)
{
- maxdist = node;
+ maxdist = nd;
maxDistValue = dist;
}
}
else
{
- findMaxDist((SequenceNode) node.left());
- findMaxDist((SequenceNode) node.right());
+ findMaxDist((SequenceNode) nd.left());
+ findMaxDist((SequenceNode) nd.right());
}
}
*
* @return DOCUMENT ME!
*/
- public Vector getGroups()
+ public Vector<SequenceNode> getGroups()
{
return groups;
}
/**
* DOCUMENT ME!
*
- * @param node
+ * @param nd
* DOCUMENT ME!
* @param threshold
* DOCUMENT ME!
*/
- public void groupNodes(SequenceNode node, float threshold)
+ public void groupNodes(SequenceNode nd, float threshold)
{
- if (node == null)
+ if (nd == null)
{
return;
}
- if ((node.height / maxheight) > threshold)
+ if ((nd.height / maxheight) > threshold)
{
- groups.addElement(node);
+ groups.addElement(nd);
}
else
{
- groupNodes((SequenceNode) node.left(), threshold);
- groupNodes((SequenceNode) node.right(), threshold);
+ groupNodes((SequenceNode) nd.left(), threshold);
+ groupNodes((SequenceNode) nd.right(), threshold);
}
}
/**
* DOCUMENT ME!
*
- * @param node
+ * @param nd
* DOCUMENT ME!
*
* @return DOCUMENT ME!
*/
- public float findHeight(SequenceNode node)
+ public float findHeight(SequenceNode nd)
{
- if (node == null)
+ if (nd == null)
{
return maxheight;
}
- if ((node.left() == null) && (node.right() == null))
+ if ((nd.left() == null) && (nd.right() == null))
{
- node.height = ((SequenceNode) node.parent()).height + node.dist;
+ nd.height = ((SequenceNode) nd.parent()).height + nd.dist;
- if (node.height > maxheight)
+ if (nd.height > maxheight)
{
- return node.height;
+ return nd.height;
}
else
{
}
else
{
- if (node.parent() != null)
+ if (nd.parent() != null)
{
- node.height = ((SequenceNode) node.parent()).height + node.dist;
+ nd.height = ((SequenceNode) nd.parent()).height + nd.dist;
}
else
{
maxheight = 0;
- node.height = (float) 0.0;
+ nd.height = (float) 0.0;
}
- maxheight = findHeight((SequenceNode) (node.left()));
- maxheight = findHeight((SequenceNode) (node.right()));
+ maxheight = findHeight((SequenceNode) (nd.left()));
+ maxheight = findHeight((SequenceNode) (nd.right()));
}
return maxheight;
/**
* DOCUMENT ME!
*
- * @param node
+ * @param nd
* DOCUMENT ME!
*/
- public void printN(SequenceNode node)
+ public void printN(SequenceNode nd)
{
- if (node == null)
+ if (nd == null)
{
return;
}
- if ((node.left() != null) && (node.right() != null))
+ if ((nd.left() != null) && (nd.right() != null))
{
- printN((SequenceNode) node.left());
- printN((SequenceNode) node.right());
+ printN((SequenceNode) nd.left());
+ printN((SequenceNode) nd.right());
}
else
{
- System.out.println(" name = "
- + ((SequenceI) node.element()).getName());
+ System.out.println(" name = " + ((SequenceI) nd.element()).getName());
}
- System.out.println(" dist = " + node.dist + " " + node.count + " "
- + node.height);
+ System.out.println(" dist = " + nd.dist + " " + nd.count + " "
+ + nd.height);
}
/**
* DOCUMENT ME!
*
- * @param node
+ * @param nd
* DOCUMENT ME!
*/
- public void reCount(SequenceNode node)
+ public void reCount(SequenceNode nd)
{
ycount = 0;
_lycount = 0;
// _lylimit = this.node.size();
- _reCount(node);
+ _reCount(nd);
}
private long _lycount = 0, _lylimit = 0;
/**
* DOCUMENT ME!
*
- * @param node
+ * @param nd
* DOCUMENT ME!
*/
- public void _reCount(SequenceNode node)
+ public void _reCount(SequenceNode nd)
{
// if (_lycount<_lylimit)
// {
// System.err.println("Warning: depth of _recount greater than number of nodes.");
// }
- if (node == null)
+ if (nd == null)
{
return;
}
_lycount++;
- if ((node.left() != null) && (node.right() != null))
+ if ((nd.left() != null) && (nd.right() != null))
{
- _reCount((SequenceNode) node.left());
- _reCount((SequenceNode) node.right());
+ _reCount((SequenceNode) nd.left());
+ _reCount((SequenceNode) nd.right());
- SequenceNode l = (SequenceNode) node.left();
- SequenceNode r = (SequenceNode) node.right();
+ SequenceNode l = (SequenceNode) nd.left();
+ SequenceNode r = (SequenceNode) nd.right();
- node.count = l.count + r.count;
- node.ycount = (l.ycount + r.ycount) / 2;
+ nd.count = l.count + r.count;
+ nd.ycount = (l.ycount + r.ycount) / 2;
}
else
{
- node.count = 1;
- node.ycount = ycount++;
+ nd.count = 1;
+ nd.ycount = ycount++;
}
_lycount--;
}
/**
* DOCUMENT ME!
*
- * @param node
+ * @param nd
* DOCUMENT ME!
*/
- public void swapNodes(SequenceNode node)
+ public void swapNodes(SequenceNode nd)
{
- if (node == null)
+ if (nd == null)
{
return;
}
- SequenceNode tmp = (SequenceNode) node.left();
+ SequenceNode tmp = (SequenceNode) nd.left();
- node.setLeft(node.right());
- node.setRight(tmp);
+ nd.setLeft(nd.right());
+ nd.setRight(tmp);
}
/**
* DOCUMENT ME!
*
- * @param node
+ * @param nd
* DOCUMENT ME!
* @param dir
* DOCUMENT ME!
*/
- public void changeDirection(SequenceNode node, SequenceNode dir)
+ public void changeDirection(SequenceNode nd, SequenceNode dir)
{
- if (node == null)
+ if (nd == null)
{
return;
}
- if (node.parent() != top)
+ if (nd.parent() != top)
{
- changeDirection((SequenceNode) node.parent(), node);
+ changeDirection((SequenceNode) nd.parent(), nd);
- SequenceNode tmp = (SequenceNode) node.parent();
+ SequenceNode tmp = (SequenceNode) nd.parent();
- if (dir == node.left())
+ if (dir == nd.left())
{
- node.setParent(dir);
- node.setLeft(tmp);
+ nd.setParent(dir);
+ nd.setLeft(tmp);
}
- else if (dir == node.right())
+ else if (dir == nd.right())
{
- node.setParent(dir);
- node.setRight(tmp);
+ nd.setParent(dir);
+ nd.setRight(tmp);
}
}
else
{
- if (dir == node.left())
+ if (dir == nd.left())
{
- node.setParent(node.left());
+ nd.setParent(nd.left());
- if (top.left() == node)
+ if (top.left() == nd)
{
- node.setRight(top.right());
+ nd.setRight(top.right());
}
else
{
- node.setRight(top.left());
+ nd.setRight(top.left());
}
}
else
{
- node.setParent(node.right());
+ nd.setParent(nd.right());
- if (top.left() == node)
+ if (top.left() == nd)
{
- node.setLeft(top.right());
+ nd.setLeft(top.right());
}
else
{
- node.setLeft(top.left());
+ nd.setLeft(top.left());
}
}
}
*/
public void applyToNodes(NodeTransformI nodeTransformI)
{
- for (Enumeration nodes = node.elements(); nodes.hasMoreElements(); nodeTransformI
- .transform((BinaryNode) nodes.nextElement()))
+ for (Enumeration<SequenceNode> nodes = node.elements(); nodes
+ .hasMoreElements(); nodeTransformI.transform(nodes
+ .nextElement()))
{
;
}
--- /dev/null
+package jalview.analysis;
+
+
+/**
+ * A data bean to hold the result of computing a profile for a column of an
+ * alignment
+ *
+ * @author gmcarstairs
+ *
+ */
+public class Profile
+{
+ /*
+ * counts of keys (chars)
+ */
+ private ResidueCount counts;
+
+ /*
+ * the number of sequences in the profile
+ */
+ private int height;
+
+ /*
+ * the number of non-gapped sequences in the profile
+ */
+ private int gapped;
+
+ /*
+ * the highest count for any residue in the profile
+ */
+ private int maxCount;
+
+ /*
+ * the residue (e.g. K) or residues (e.g. KQW) with the
+ * highest count in the profile
+ */
+ private String modalResidue;
+
+ /**
+ * Constructor which allows derived data to be stored without having to store
+ * the full profile
+ *
+ * @param seqCount
+ * the number of sequences in the profile
+ * @param gaps
+ * the number of gapped sequences
+ * @param max
+ * the highest count for any residue
+ * @param modalres
+ * the residue (or concatenated residues) with the highest count
+ */
+ public Profile(int seqCount, int gaps, int max, String modalRes)
+ {
+ this.height = seqCount;
+ this.gapped = gaps;
+ this.maxCount = max;
+ this.modalResidue = modalRes;
+ }
+
+ /**
+ * Set the full profile of counts
+ *
+ * @param residueCounts
+ */
+ public void setCounts(ResidueCount residueCounts)
+ {
+ this.counts = residueCounts;
+ }
+
+ /**
+ * Returns the percentage identity of the profile, i.e. the highest proportion
+ * of conserved (equal) symbols. The percentage is as a fraction of all
+ * sequences, or only ungapped sequences if flag ignoreGaps is set true.
+ *
+ * @param ignoreGaps
+ * @return
+ */
+ public float getPercentageIdentity(boolean ignoreGaps)
+ {
+ if (height == 0)
+ {
+ return 0f;
+ }
+ float pid = 0f;
+ if (ignoreGaps && gapped < height)
+ {
+ pid = (maxCount * 100f) / (height - gapped);
+ }
+ else
+ {
+ pid = (maxCount * 100f) / height;
+ }
+ return pid;
+ }
+
+ /**
+ * Returns the full symbol counts for this profile
+ *
+ * @return
+ */
+ public ResidueCount getCounts()
+ {
+ return counts;
+ }
+
+ /**
+ * Returns the number of sequences in the profile
+ *
+ * @return
+ */
+ public int getHeight()
+ {
+ return height;
+ }
+
+ /**
+ * Returns the number of sequences in the profile which had a gap character
+ * (or were too short to be included in this column's profile)
+ *
+ * @return
+ */
+ public int getGapped()
+ {
+ return gapped;
+ }
+
+ /**
+ * Returns the highest count for any symbol(s) in the profile
+ *
+ * @return
+ */
+ public int getMaxCount()
+ {
+ return maxCount;
+ }
+
+ /**
+ * Returns the symbol (or concatenated symbols) which have the highest count
+ * in the profile, or an empty string if there were no symbols counted
+ *
+ * @return
+ */
+ public String getModalResidue()
+ {
+ return modalResidue;
+ }
+
+ /**
+ * Answers the number of non-gapped sequences in the profile
+ *
+ * @return
+ */
+ public int getNonGapped()
+ {
+ return height - gapped;
+ }
+}
--- /dev/null
+package jalview.analysis;
+
+import jalview.util.Comparison;
+import jalview.util.Format;
+import jalview.util.QuickSort;
+import jalview.util.SparseCount;
+
+/**
+ * A class to count occurrences of residues in a profile, optimised for speed
+ * and memory footprint.
+ * @author gmcarstairs
+ *
+ */
+public class ResidueCount
+{
+ /**
+ * A data bean to hold the results of counting symbols
+ */
+ public class SymbolCounts
+ {
+ /**
+ * the symbols seen (as char values), in no particular order
+ */
+ public final char[] symbols;
+
+ /**
+ * the counts for each symbol, in the same order as the symbols
+ */
+ public final int[] values;
+
+ SymbolCounts(char[] s, int[] v)
+ {
+ symbols = s;
+ values = v;
+ }
+ }
+
+ private static final int TOUPPERCASE = 'A' - 'a';
+
+ /*
+ * nucleotide symbols to count (including N unknown)
+ */
+ private static final String NUCS = "ACGNTU";
+
+ /*
+ * amino acid symbols to count (including X unknown)
+ * NB we also include U so as to support counting of RNA bases
+ * in the "don't know" case of nucleotide / peptide
+ */
+ private static final String AAS = "ACDEFGHIKLMNPQRSTUVWXY";
+
+ private static final int GAP_COUNT = 0;
+
+ /*
+ * fast lookup tables holding the index into our count
+ * arrays of each symbol; index 0 is reserved for gap counting
+ */
+ private static int[] NUC_INDEX = new int[26];
+
+ private static int[] AA_INDEX = new int[26];
+ static
+ {
+ for (int i = 0; i < NUCS.length(); i++)
+ {
+ NUC_INDEX[NUCS.charAt(i) - 'A'] = i + 1;
+ }
+ for (int i = 0; i < AAS.length(); i++)
+ {
+ AA_INDEX[AAS.charAt(i) - 'A'] = i + 1;
+ }
+ }
+
+ /*
+ * counts array, just big enough for the nucleotide or peptide
+ * character set (plus gap counts in position 0)
+ */
+ private short[] counts;
+
+ /*
+ * alternative array of int counts for use if any count
+ * exceeds the maximum value of short (32767)
+ */
+ private int[] intCounts;
+
+ /*
+ * flag set if we switch from short to int counts
+ */
+ private boolean useIntCounts;
+
+ /*
+ * general-purpose counter, only for use for characters
+ * that are not in the expected alphabet
+ */
+ private SparseCount otherData;
+
+ /*
+ * keeps track of the maximum count value recorded
+ * (if this class every allows decrements, would need to
+ * calculate this on request instead)
+ */
+ int maxCount;
+
+ /*
+ * if we think we are counting nucleotide, can get by with smaller
+ * array to hold counts
+ */
+ private boolean isNucleotide;
+
+ /**
+ * Default constructor allocates arrays able to count either nucleotide or
+ * peptide bases. Use this constructor if not sure which the data is.
+ */
+ public ResidueCount()
+ {
+ this(false);
+ }
+
+ /**
+ * Constructor that allocates an array just big enough for the anticipated
+ * characters, plus one position to count gaps
+ */
+ public ResidueCount(boolean nucleotide)
+ {
+ isNucleotide = nucleotide;
+ int charsToCount = nucleotide ? NUCS.length() : AAS.length();
+ counts = new short[charsToCount + 1];
+ }
+
+ /**
+ * Increments the count for the given character. The supplied character may be
+ * upper or lower case but counts are for the upper case only. Gap characters
+ * (space, ., -) are all counted together.
+ *
+ * @param c
+ * @return the new value of the count for the character
+ */
+ public int add(final char c)
+ {
+ char u = toUpperCase(c);
+ int newValue = 0;
+ int offset = getOffset(u);
+
+ /*
+ * offset 0 is reserved for gap counting, so 0 here means either
+ * an unexpected character, or a gap character passed in error
+ */
+ if (offset == 0)
+ {
+ if (Comparison.isGap(u))
+ {
+ newValue = addGap();
+ }
+ else
+ {
+ newValue = addOtherCharacter(u);
+ }
+ }
+ else
+ {
+ newValue = increment(offset);
+ }
+ return newValue;
+ }
+
+ /**
+ * Increment the count at the specified offset. If this would result in short
+ * overflow, promote to counting int values instead.
+ *
+ * @param offset
+ * @return the new value of the count at this offset
+ */
+ int increment(int offset)
+ {
+ int newValue = 0;
+ if (useIntCounts)
+ {
+ newValue = intCounts[offset];
+ intCounts[offset] = ++newValue;
+ }
+ else
+ {
+ if (counts[offset] == Short.MAX_VALUE)
+ {
+ handleOverflow();
+ newValue = intCounts[offset];
+ intCounts[offset] = ++newValue;
+ }
+ else
+ {
+ newValue = counts[offset];
+ counts[offset] = (short) ++newValue;
+ }
+ }
+ maxCount = Math.max(maxCount, newValue);
+ return newValue;
+ }
+
+ /**
+ * Switch from counting in short to counting in int
+ */
+ synchronized void handleOverflow()
+ {
+ intCounts = new int[counts.length];
+ for (int i = 0; i < counts.length; i++)
+ {
+ intCounts[i] = counts[i];
+ }
+ counts = null;
+ useIntCounts = true;
+ }
+
+ /**
+ * Returns this character's offset in the count array
+ *
+ * @param c
+ * @return
+ */
+ int getOffset(char c)
+ {
+ int offset = 0;
+ if ('A' <= c && c <= 'Z')
+ {
+ offset = isNucleotide ? NUC_INDEX[c - 'A'] : AA_INDEX[c - 'A'];
+ }
+ return offset;
+ }
+
+ /**
+ * @param c
+ * @return
+ */
+ protected char toUpperCase(final char c)
+ {
+ char u = c;
+ if ('a' <= c && c <= 'z')
+ {
+ u = (char) (c + TOUPPERCASE);
+ }
+ return u;
+ }
+
+ /**
+ * Increment count for some unanticipated character. The first time this
+ * called, a SparseCount is instantiated to hold these 'extra' counts.
+ *
+ * @param c
+ * @return the new value of the count for the character
+ */
+ int addOtherCharacter(char c)
+ {
+ if (otherData == null)
+ {
+ otherData = new SparseCount();
+ }
+ int newValue = otherData.add(c, 1);
+ maxCount = Math.max(maxCount, newValue);
+ return newValue;
+ }
+
+ /**
+ * Set count for some unanticipated character. The first time this called, a
+ * SparseCount is instantiated to hold these 'extra' counts.
+ *
+ * @param c
+ * @param value
+ */
+ void setOtherCharacter(char c, int value)
+ {
+ if (otherData == null)
+ {
+ otherData = new SparseCount();
+ }
+ otherData.put(c, value);
+ }
+
+ /**
+ * Increment count of gap characters
+ *
+ * @return the new count of gaps
+ */
+ public int addGap()
+ {
+ int newValue;
+ if (useIntCounts)
+ {
+ newValue = ++intCounts[GAP_COUNT];
+ }
+ else
+ {
+ newValue = ++counts[GAP_COUNT];
+ }
+ return newValue;
+ }
+
+ /**
+ * Answers true if we are counting ints (only after overflow of short counts)
+ *
+ * @return
+ */
+ boolean isCountingInts()
+ {
+ return useIntCounts;
+ }
+
+ /**
+ * Sets the count for the given character. The supplied character may be upper
+ * or lower case but counts are for the upper case only.
+ *
+ * @param c
+ * @param count
+ */
+ public void put(char c, int count)
+ {
+ char u = toUpperCase(c);
+ int offset = getOffset(u);
+
+ /*
+ * offset 0 is reserved for gap counting, so 0 here means either
+ * an unexpected character, or a gap character passed in error
+ */
+ if (offset == 0)
+ {
+ if (Comparison.isGap(u))
+ {
+ set(0, count);
+ }
+ else
+ {
+ setOtherCharacter(u, count);
+ maxCount = Math.max(maxCount, count);
+ }
+ }
+ else
+ {
+ set(offset, count);
+ maxCount = Math.max(maxCount, count);
+ }
+ }
+
+ /**
+ * Sets the count at the specified offset. If this would result in short
+ * overflow, promote to counting int values instead.
+ *
+ * @param offset
+ * @param value
+ */
+ void set(int offset, int value)
+ {
+ if (useIntCounts)
+ {
+ intCounts[offset] = value;
+ }
+ else
+ {
+ if (value > Short.MAX_VALUE || value < Short.MIN_VALUE)
+ {
+ handleOverflow();
+ intCounts[offset] = value;
+ }
+ else
+ {
+ counts[offset] = (short) value;
+ }
+ }
+ }
+
+ /**
+ * Returns the count for the given character, or zero if no count held
+ *
+ * @param c
+ * @return
+ */
+ public int getCount(char c)
+ {
+ char u = toUpperCase(c);
+ int offset = getOffset(u);
+ if (offset == 0)
+ {
+ if (!Comparison.isGap(u))
+ {
+ // should have called getGapCount()
+ return otherData == null ? 0 : otherData.get(u);
+ }
+ }
+ return useIntCounts ? intCounts[offset] : counts[offset];
+ }
+
+ public int getGapCount()
+ {
+ return useIntCounts ? intCounts[0] : counts[0];
+ }
+
+ /**
+ * Answers true if this object wraps a counter for unexpected characters
+ *
+ * @return
+ */
+ boolean isUsingOtherData()
+ {
+ return otherData != null;
+ }
+
+ /**
+ * Returns the character (or concatenated characters) for the symbol(s) with
+ * the given count in the profile. Can be used to get the modal residue by
+ * supplying the modal count value. Returns an empty string if no symbol has
+ * the given count. The symbols are in alphabetic order of standard peptide or
+ * nucleotide characters, followed by 'other' symbols if any.
+ *
+ * @return
+ */
+ public String getResiduesForCount(int count)
+ {
+ if (count == 0)
+ {
+ return "";
+ }
+
+ /*
+ * find counts for the given value and append the
+ * corresponding symbol
+ */
+ StringBuilder modal = new StringBuilder();
+ if (useIntCounts)
+ {
+ for (int i = 1; i < intCounts.length; i++)
+ {
+ if (intCounts[i] == count)
+ {
+ modal.append(isNucleotide ? NUCS.charAt(i - 1) : AAS
+ .charAt(i - 1));
+ }
+ }
+ }
+ else
+ {
+ for (int i = 1; i < counts.length; i++)
+ {
+ if (counts[i] == count)
+ {
+ modal.append(isNucleotide ? NUCS.charAt(i - 1) : AAS
+ .charAt(i - 1));
+ }
+ }
+ }
+ if (otherData != null)
+ {
+ for (int i = 0; i < otherData.size(); i++)
+ {
+ if (otherData.valueAt(i) == count)
+ {
+ modal.append((char) otherData.keyAt(i));
+ }
+ }
+ }
+ return modal.toString();
+ }
+
+ /**
+ * Returns the highest count for any symbol(s) in the profile (excluding gap)
+ *
+ * @return
+ */
+ public int getModalCount()
+ {
+ return maxCount;
+ }
+
+ /**
+ * Returns the number of distinct symbols with a non-zero count (excluding the
+ * gap symbol)
+ *
+ * @return
+ */
+ public int size() {
+ int size = 0;
+ if (useIntCounts)
+ {
+ for (int i = 1; i < intCounts.length; i++)
+ {
+ if (intCounts[i] > 0)
+ {
+ size++;
+ }
+ }
+ }
+ else
+ {
+ for (int i = 1; i < counts.length; i++)
+ {
+ if (counts[i] > 0)
+ {
+ size++;
+ }
+ }
+ }
+
+ /*
+ * include 'other' characters recorded (even if count is zero
+ * though that would be a strange use case)
+ */
+ if (otherData != null)
+ {
+ size += otherData.size();
+ }
+
+ return size;
+ }
+
+ /**
+ * Returns a data bean holding those symbols that have a non-zero count
+ * (excluding the gap symbol), with their counts.
+ *
+ * @return
+ */
+ public SymbolCounts getSymbolCounts()
+ {
+ int size = size();
+ char[] symbols = new char[size];
+ int[] values = new int[size];
+ int j = 0;
+
+ if (useIntCounts)
+ {
+ for (int i = 1; i < intCounts.length; i++)
+ {
+ if (intCounts[i] > 0)
+ {
+ char symbol = isNucleotide ? NUCS.charAt(i - 1) : AAS
+ .charAt(i - 1);
+ symbols[j] = symbol;
+ values[j] = intCounts[i];
+ j++;
+ }
+ }
+ }
+ else
+ {
+ for (int i = 1; i < counts.length; i++)
+ {
+ if (counts[i] > 0)
+ {
+ char symbol = isNucleotide ? NUCS.charAt(i - 1) : AAS
+ .charAt(i - 1);
+ symbols[j] = symbol;
+ values[j] = counts[i];
+ j++;
+ }
+ }
+ }
+ if (otherData != null)
+ {
+ for (int i = 0; i < otherData.size(); i++)
+ {
+ symbols[j] = (char) otherData.keyAt(i);
+ values[j] = otherData.valueAt(i);
+ j++;
+ }
+ }
+
+ return new SymbolCounts(symbols, values);
+ }
+
+ /**
+ * Returns a tooltip string showing residues in descending order of their
+ * percentage frequency in the profile
+ *
+ * @param normaliseBy
+ * the divisor for residue counts (may or may not include gapped
+ * sequence count)
+ * @param percentageDecPl
+ * the number of decimal places to show in percentages
+ * @return
+ */
+ public String getTooltip(int normaliseBy, int percentageDecPl)
+ {
+ SymbolCounts symbolCounts = getSymbolCounts();
+ char[] ca = symbolCounts.symbols;
+ int[] vl = symbolCounts.values;
+
+ /*
+ * sort characters into ascending order of their counts
+ */
+ QuickSort.sort(vl, ca);
+
+ /*
+ * traverse in reverse order (highest count first) to build tooltip
+ */
+ boolean first = true;
+ StringBuilder sb = new StringBuilder(64);
+ for (int c = ca.length - 1; c >= 0; c--)
+ {
+ final char residue = ca[c];
+ // TODO combine residues which share a percentage
+ // (see AAFrequency.completeCdnaConsensus)
+ float tval = (vl[c] * 100f) / normaliseBy;
+ sb.append(first ? "" : "; ").append(residue).append(" ");
+ Format.appendPercentage(sb, tval, percentageDecPl);
+ sb.append("%");
+ first = false;
+ }
+ return sb.toString();
+ }
+
+ /**
+ * Returns a string representation of the symbol counts, for debug purposes.
+ */
+ @Override
+ public String toString()
+ {
+ StringBuilder sb = new StringBuilder();
+ sb.append("[ ");
+ SymbolCounts sc = getSymbolCounts();
+ for (int i = 0; i < sc.symbols.length; i++)
+ {
+ sb.append(sc.symbols[i]).append(":").append(sc.values[i]).append(" ");
+ }
+ sb.append("]");
+ return sb.toString();
+ }
+}
import jalview.util.MessageManager;
import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashSet;
import java.util.Hashtable;
+import java.util.List;
import java.util.Stack;
import java.util.Vector;
public class Rna
{
- static Hashtable<Integer, Integer> pairHash = new Hashtable();
-
- private static final Character[] openingPars = { '(', '[', '{', '<', 'A',
- 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
- 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z' };
-
- private static final Character[] closingPars = { ')', ']', '}', '>', 'a',
- 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
- 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z' };
-
- private static HashSet<Character> openingParsSet = new HashSet<Character>(
- Arrays.asList(openingPars));
-
- private static HashSet<Character> closingParsSet = new HashSet<Character>(
- Arrays.asList(closingPars));
+ /**
+ * Answers true if the character is a valid open pair rna secondary structure
+ * symbol. Currently accepts A-Z, ([{<
+ *
+ * @param c
+ * @return
+ */
+ public static boolean isOpeningParenthesis(char c)
+ {
+ return ('A' <= c && c <= 'Z' || c == '(' || c == '[' || c == '{' || c == '<');
+ }
- private static Hashtable<Character, Character> closingToOpening = new Hashtable<Character, Character>()
- // Initializing final data structure
+ /**
+ * Answers true if the string is a valid open pair rna secondary structure
+ * symbol. Currently accepts A-Z, ([{<
+ *
+ * @param s
+ * @return
+ */
+ public static boolean isOpeningParenthesis(String s)
{
- private static final long serialVersionUID = 1L;
- {
- for (int i = 0; i < openingPars.length; i++)
- {
- // System.out.println(closingPars[i] + "->" + openingPars[i]);
- put(closingPars[i], openingPars[i]);
- }
- }
- };
+ return s != null && s.length() == 1
+ && isOpeningParenthesis(s.charAt(0));
+ }
- private static boolean isOpeningParenthesis(char c)
+ /**
+ * Answers true if the character is a valid close pair rna secondary structure
+ * symbol. Currently accepts a-z, )]}>
+ *
+ * @param c
+ * @return
+ */
+ public static boolean isClosingParenthesis(char c)
{
- return openingParsSet.contains(c);
+ return ('a' <= c && c <= 'z' || c == ')' || c == ']' || c == '}' || c == '>');
}
- private static boolean isClosingParenthesis(char c)
+ /**
+ * Answers true if the string is a valid close pair rna secondary structure
+ * symbol. Currently accepts a-z, )]}>
+ *
+ * @param s
+ * @return
+ */
+ public static boolean isClosingParenthesis(String s)
{
- return closingParsSet.contains(c);
+ return s != null && s.length() == 1
+ && isClosingParenthesis(s.charAt(0));
}
- private static char matchingOpeningParenthesis(char closingParenthesis)
- throws WUSSParseException
+ /**
+ * Returns the matching open pair symbol for the given closing symbol.
+ * Currently returns A-Z for a-z, or ([{< for )]}>, or the input symbol if it
+ * is not a valid closing symbol.
+ *
+ * @param c
+ * @return
+ */
+ public static char getMatchingOpeningParenthesis(char c)
{
- if (!isClosingParenthesis(closingParenthesis))
+ if ('a' <= c && c <= 'z')
{
- throw new WUSSParseException(
- MessageManager.formatMessage(
- "exception.querying_matching_opening_parenthesis_for_non_closing_parenthesis",
- new String[] { new StringBuffer(closingParenthesis)
- .toString() }), -1);
+ return (char) (c + 'A' - 'a');
+ }
+ switch (c)
+ {
+ case ')':
+ return '(';
+ case ']':
+ return '[';
+ case '}':
+ return '{';
+ case '>':
+ return '<';
+ default:
+ return c;
}
-
- return closingToOpening.get(closingParenthesis);
}
/**
* Based off of RALEE code ralee-get-base-pairs. Keeps track of open bracket
* positions in "stack" vector. When a close bracket is reached, pair this
- * with the last element in the "stack" vector and store in "pairs" vector.
- * Remove last element in the "stack" vector. Continue in this manner until
- * the whole string is processed.
+ * with the last matching element in the "stack" vector and store in "pairs"
+ * vector. Remove last element in the "stack" vector. Continue in this manner
+ * until the whole string is processed. Parse errors are thrown as exceptions
+ * wrapping the error location - position of the first unmatched closing
+ * bracket, or string length if there is an unmatched opening bracket.
*
* @param line
* Secondary structure line of an RNA Stockholm file
- * @return Array of SequenceFeature; type = RNA helix, begin is open base
- * pair, end is close base pair
+ * @return
+ * @throw {@link WUSSParseException}
*/
- public static Vector<SimpleBP> GetSimpleBPs(CharSequence line)
+ public static Vector<SimpleBP> getSimpleBPs(CharSequence line)
throws WUSSParseException
{
Hashtable<Character, Stack<Integer>> stacks = new Hashtable<Character, Stack<Integer>>();
else if (isClosingParenthesis(base))
{
- char opening = matchingOpeningParenthesis(base);
+ char opening = getMatchingOpeningParenthesis(base);
if (!stacks.containsKey(opening))
{
throw new WUSSParseException(MessageManager.formatMessage(
"exception.mismatched_unseen_closing_char",
- new String[] { new StringBuffer(base).toString() }), i);
+ new String[] { String.valueOf(base) }), i);
}
Stack<Integer> stack = stacks.get(opening);
// error whilst parsing i'th position. pass back
throw new WUSSParseException(MessageManager.formatMessage(
"exception.mismatched_closing_char",
- new String[] { new StringBuffer(base).toString() }), i);
+ new String[] { String.valueOf(base) }), i);
}
int temp = stack.pop();
Stack<Integer> stack = stacks.get(opening);
if (!stack.empty())
{
+ /*
+ * we have an unmatched opening bracket; report error as at
+ * i (length of input string)
+ */
throw new WUSSParseException(MessageManager.formatMessage(
"exception.mismatched_opening_char",
- new String[] { new StringBuffer(opening).toString(),
- Integer.valueOf(stack.pop()).toString() }), i);
+ new String[] { String.valueOf(opening),
+ String.valueOf(stack.pop()) }), i);
}
}
return pairs;
}
- public static SequenceFeature[] GetBasePairs(CharSequence line)
+ public static SequenceFeature[] getBasePairs(List<SimpleBP> bps)
throws WUSSParseException
{
- Vector<SimpleBP> bps = GetSimpleBPs(line);
SequenceFeature[] outPairs = new SequenceFeature[bps.size()];
for (int p = 0; p < bps.size(); p++)
{
- SimpleBP bp = bps.elementAt(p);
+ SimpleBP bp = bps.get(p);
outPairs[p] = new SequenceFeature("RNA helix", "", "", bp.getBP5(),
bp.getBP3(), "");
}
return outPairs;
}
- public static ArrayList<SimpleBP> GetModeleBP(CharSequence line)
+ public static List<SimpleBP> getModeleBP(CharSequence line)
throws WUSSParseException
{
- Vector<SimpleBP> bps = GetSimpleBPs(line);
+ Vector<SimpleBP> bps = getSimpleBPs(line);
return new ArrayList<SimpleBP>(bps);
}
int close; // Position of a close bracket under review
int j; // Counter
- Hashtable helices = new Hashtable(); // Keep track of helix number for each
- // position
+ Hashtable<Integer, Integer> helices = new Hashtable<Integer, Integer>();
+ // Keep track of helix number for each position
// Go through each base pair and assign positions a helix
for (i = 0; i < pairs.length; i++)
if ((popen < lastopen) && (popen > open))
{
if (helices.containsValue(popen)
- && (((Integer) helices.get(popen)) == helix))
+ && ((helices.get(popen)) == helix))
{
continue;
}
}
}
+
+ /**
+ * Answers true if the character is a recognised symbol for RNA secondary
+ * structure. Currently accepts a-z, A-Z, ()[]{}<>.
+ *
+ * @param c
+ * @return
+ */
+ public static boolean isRnaSecondaryStructureSymbol(char c)
+ {
+ return isOpeningParenthesis(c) || isClosingParenthesis(c);
+ }
+
+ /**
+ * Answers true if the string is a recognised symbol for RNA secondary
+ * structure. Currently accepts a-z, A-Z, ()[]{}<>.
+ *
+ * @param s
+ * @return
+ */
+ public static boolean isRnaSecondaryStructureSymbol(String s)
+ {
+ return isOpeningParenthesis(s) || isClosingParenthesis(s);
+ }
+
+ /**
+ * Translates a string to RNA secondary structure representation. Returns the
+ * string with any non-SS characters changed to spaces. Accepted characters
+ * are a-z, A-Z, and (){}[]<> brackets.
+ *
+ * @param ssString
+ * @return
+ */
+ public static String getRNASecStrucState(String ssString)
+ {
+ if (ssString == null)
+ {
+ return null;
+ }
+ StringBuilder result = new StringBuilder(ssString.length());
+ for (int i = 0; i < ssString.length(); i++)
+ {
+ char c = ssString.charAt(i);
+ result.append(isRnaSecondaryStructureSymbol(c) ? c : " ");
+ }
+ return result.toString();
+ }
+
+ /**
+ * Answers true if the base-pair is either a Watson-Crick (A:T/U, C:G) or a
+ * wobble (G:T/U) pair (either way round), else false
+ *
+ * @param first
+ * @param second
+ * @return
+ */
+ public static boolean isCanonicalOrWobblePair(char first, char second)
+ {
+ if (first > 'Z')
+ {
+ first -= 32;
+ }
+ if (second > 'Z')
+ {
+ second -= 32;
+ }
+
+ switch (first)
+ {
+ case 'A':
+ switch (second)
+ {
+ case 'T':
+ case 'U':
+ return true;
+ }
+ break;
+ case 'C':
+ switch (second)
+ {
+ case 'G':
+ return true;
+ }
+ break;
+ case 'T':
+ case 'U':
+ switch (second)
+ {
+ case 'A':
+ case 'G':
+ return true;
+ }
+ break;
+ case 'G':
+ switch (second)
+ {
+ case 'C':
+ case 'T':
+ case 'U':
+ return true;
+ }
+ break;
+ }
+ return false;
+ }
+
+ /**
+ * Answers true if the base-pair is Watson-Crick - (A:T/U or C:G, either way
+ * round), else false
+ *
+ * @param first
+ * @param second
+ * @return
+ */
+ public static boolean isCanonicalPair(char first, char second)
+ {
+
+ if (first > 'Z')
+ {
+ first -= 32;
+ }
+ if (second > 'Z')
+ {
+ second -= 32;
+ }
+
+ switch (first)
+ {
+ case 'A':
+ switch (second)
+ {
+ case 'T':
+ case 'U':
+ return true;
+ }
+ break;
+ case 'G':
+ switch (second)
+ {
+ case 'C':
+ return true;
+ }
+ break;
+ case 'C':
+ switch (second)
+ {
+ case 'G':
+ return true;
+ }
+ break;
+ case 'T':
+ case 'U':
+ switch (second)
+ {
+ case 'A':
+ return true;
+ }
+ break;
+ }
+ return false;
+ }
+
+ /**
+ * Returns the matching close pair symbol for the given opening symbol.
+ * Currently returns a-z for A-Z, or )]}> for ([{<, or the input symbol if it
+ * is not a valid opening symbol.
+ *
+ * @param c
+ * @return
+ */
+ public static char getMatchingClosingParenthesis(char c)
+ {
+ if ('A' <= c && c <= 'Z')
+ {
+ return (char) (c + 'a' - 'A');
+ }
+ switch (c)
+ {
+ case '(':
+ return ')';
+ case '[':
+ return ']';
+ case '{':
+ return '}';
+ case '<':
+ return '>';
+ default:
+ return c;
+ }
+ }
}
{
sqinfo.put("SeqFeatures", sfeat);
sqinfo.put("PdbId",
- (seq.getAllPDBEntries() != null) ? seq.getAllPDBEntries()
- : new Vector<PDBEntry>());
+ (seq.getAllPDBEntries() != null) ? seq.getAllPDBEntries()
+ : new Vector<PDBEntry>());
}
else
{
sqinfo.put("datasetSequence",
- (seq.getDatasetSequence() != null) ? seq.getDatasetSequence()
- : new Sequence("THISISAPLACEHOLDER", ""));
+ (seq.getDatasetSequence() != null) ? seq.getDatasetSequence()
+ : new Sequence("THISISAPLACEHOLDER", ""));
}
return sqinfo;
}
&& !(seqds.getName().equals("THISISAPLACEHOLDER") && seqds
.getLength() == 0))
{
- if (sfeatures!=null)
+ if (sfeatures != null)
{
System.err
.println("Implementation error: setting dataset sequence for a sequence which has sequence features.\n\tDataset sequence features will not be visible.");
{
if (s != null)
{
- id = new String(s.toLowerCase());
+ id = s.toLowerCase();
}
else
{
.indexOf(s.charAt(id.length())) > -1)) : false;
}
}
+
+ /**
+ * toString method returns the wrapped sequence id. For debugging purposes
+ * only, behaviour not guaranteed not to change.
+ */
+ @Override
+ public String toString()
+ {
+ return id;
+ }
}
}
import jalview.datamodel.Annotation;
import jalview.datamodel.SequenceFeature;
import jalview.datamodel.SequenceI;
+import jalview.util.Comparison;
import jalview.util.Format;
import java.util.ArrayList;
SequenceFeature[] rna = rnaStruc._rnasecstr;
char c, s, cEnd;
- int count = 0, nonGap = 0, i, bpEnd = -1, j, jSize = sequences.length;
+ int bpEnd = -1;
+ int jSize = sequences.length;
int[] values;
int[][] pairs;
float percentage;
- boolean wooble = true;
- for (i = start; i < end; i++) // foreach column
+
+ for (int i = start; i < end; i++) // foreach column
{
- residueHash = new Hashtable();
+ int canonicalOrWobblePairCount = 0, canonical = 0;
+ int otherPairCount = 0;
+ int nongap = 0;
maxResidue = "-";
values = new int[255];
pairs = new int[255][255];
bpEnd = -1;
- // System.out.println("s="+struc[i]);
if (i < struc.length)
{
s = struc[i];
-
}
else
{
s = '-';
}
- if (s != '(' && s != '[')
+ if (!Rna.isOpeningParenthesis(s))
{
if (s == '-')
{
}
else
{
-
bpEnd = findPair(rna, i);
if (bpEnd > -1)
{
- for (j = 0; j < jSize; j++) // foreach row
+ for (int j = 0; j < jSize; j++) // foreach row
{
if (sequences[j] == null)
{
.println("WARNING: Consensus skipping null sequence - possible race condition.");
continue;
}
- c = sequences[j].getCharAt(i);
- // System.out.println("c="+c);
- // standard representation for gaps in sequence and structure
- if (c == '.' || c == ' ')
- {
- c = '-';
- }
+ c = sequences[j].getCharAt(i);
+ cEnd = sequences[j].getCharAt(bpEnd);
- if (c == '-')
+ if (Comparison.isGap(c) || Comparison.isGap(cEnd))
{
values['-']++;
continue;
}
- cEnd = sequences[j].getCharAt(bpEnd);
-
- // System.out.println("pairs ="+c+","+cEnd);
- if (checkBpType(c, cEnd) == true)
+ nongap++;
+ /*
+ * ensure upper-case for counting purposes
+ */
+ if ('a' <= c && 'z' >= c)
{
- values['(']++; // H means it's a helix (structured)
- maxResidue = "(";
- wooble = true;
- // System.out.println("It's a pair wc");
-
+ c += 'A' - 'a';
}
- if (checkBpType(c, cEnd) == false)
+ if ('a' <= cEnd && 'z' >= cEnd)
{
- wooble = false;
- values['[']++; // H means it's a helix (structured)
- maxResidue = "[";
-
+ cEnd += 'A' - 'a';
+ }
+ if (Rna.isCanonicalOrWobblePair(c, cEnd))
+ {
+ canonicalOrWobblePairCount++;
+ if (Rna.isCanonicalPair(c, cEnd))
+ {
+ canonical++;
+ }
+ }
+ else
+ {
+ otherPairCount++;
}
pairs[c][cEnd]++;
-
}
}
- // nonGap++;
}
- // UPDATE this for new values
+
+ residueHash = new Hashtable();
if (profile)
{
// TODO 1-dim array with jsize in [0], nongapped in [1]; or Pojo
residueHash.put(PAIRPROFILE, pairs);
}
- if (wooble == true)
- {
- count = values['('];
- }
- if (wooble == false)
+ values['('] = canonicalOrWobblePairCount;
+ values['['] = canonical;
+ values['{'] = otherPairCount;
+ /*
+ * the count is the number of valid pairs (as a percentage, determines
+ * the relative size of the profile logo)
+ */
+ int count = canonicalOrWobblePairCount;
+
+ /*
+ * display '(' if most pairs are canonical, or as
+ * '[' if there are more wobble pairs.
+ */
+ if (canonicalOrWobblePairCount > 0 || otherPairCount > 0)
{
- count = values['['];
+ if (canonicalOrWobblePairCount >= otherPairCount)
+ {
+ maxResidue = (canonicalOrWobblePairCount - canonical) < canonical ? "("
+ : "[";
+ }
+ else
+ {
+ maxResidue = "{";
+ }
}
residueHash.put(MAXCOUNT, new Integer(count));
residueHash.put(MAXRESIDUE, maxResidue);
percentage = ((float) count * 100) / jSize;
residueHash.put(PID_GAPS, new Float(percentage));
- // percentage = ((float) count * 100) / (float) nongap;
- // residueHash.put(PID_NOGAPS, new Float(percentage));
+ percentage = ((float) count * 100) / nongap;
+ residueHash.put(PID_NOGAPS, new Float(percentage));
+
if (result[i] == null)
{
result[i] = residueHash;
{
values[')'] = values['('];
values[']'] = values['['];
+ values['}'] = values['{'];
values['('] = 0;
values['['] = 0;
+ values['{'] = 0;
+ maxResidue = maxResidue.equals("(") ? ")"
+ : maxResidue.equals("[") ? "]" : "}";
+
residueHash = new Hashtable();
- if (wooble == true)
- {
- // System.out.println(maxResidue+","+wooble);
- maxResidue = ")";
- }
- if (wooble == false)
- {
- // System.out.println(maxResidue+","+wooble);
- maxResidue = "]";
- }
if (profile)
{
residueHash.put(PROFILE, new int[][] { values,
percentage = ((float) count * 100) / jSize;
residueHash.put(PID_GAPS, new Float(percentage));
- result[bpEnd] = residueHash;
-
- }
- }
- }
-
- /**
- * Method to check if a base-pair is a canonical or a wobble bp
- *
- * @param up
- * 5' base
- * @param down
- * 3' base
- * @return True if it is a canonical/wobble bp
- */
- public static boolean checkBpType(char up, char down)
- {
- if (up > 'Z')
- {
- up -= 32;
- }
- if (down > 'Z')
- {
- down -= 32;
- }
+ percentage = ((float) count * 100) / nongap;
+ residueHash.put(PID_NOGAPS, new Float(percentage));
- switch (up)
- {
- case 'A':
- switch (down)
- {
- case 'T':
- return true;
- case 'U':
- return true;
- }
- break;
- case 'C':
- switch (down)
- {
- case 'G':
- return true;
- }
- break;
- case 'T':
- switch (down)
- {
- case 'A':
- return true;
- case 'G':
- return true;
- }
- break;
- case 'G':
- switch (down)
- {
- case 'C':
- return true;
- case 'T':
- return true;
- case 'U':
- return true;
- }
- break;
- case 'U':
- switch (down)
- {
- case 'A':
- return true;
- case 'G':
- return true;
+ result[bpEnd] = residueHash;
}
- break;
}
- return false;
}
/**
for (String j : test)
{
System.out.println(i + "-" + j + ": "
- + StructureFrequency.checkBpType(i.charAt(0), j.charAt(0)));
+ + Rna.isCanonicalOrWobblePair(i.charAt(0), j.charAt(0)));
}
}
}
void notifyStart(AlignCalcWorkerI worker);
/**
- * check if a calculation of this type is already active
- *
- * @param worker
- * @return
- */
- boolean alreadyDoing(AlignCalcWorkerI worker);
-
- /**
- * tell manager that worker is now processing data
+ * tell manager that a thread running worker's run() loop is ready to start
+ * processing data
*
* @param worker
+ * @return true if worker should start processing, false if another thread is
+ * in progress
*/
boolean notifyWorking(AlignCalcWorkerI worker);
*
* @param worker
*/
- void workerCannotRun(AlignCalcWorkerI worker);
+ void disableWorker(AlignCalcWorkerI worker);
/**
* indicate that a worker like this may be run on the platform.
* @param worker
* of class to be removed from the execution blacklist
*/
- void workerMayRun(AlignCalcWorkerI worker);
+ void enableWorker(AlignCalcWorkerI worker);
+
+ /**
+ * Answers true if the worker is disabled from running
+ *
+ * @param worker
+ * @return
+ */
+ boolean isDisabled(AlignCalcWorkerI worker);
/**
* launch a new worker
/**
*
* @param worker
- * @return
+ * @return true if the worker is currently running
*/
boolean isWorking(AlignCalcWorkerI worker);
*
* @param workerClass
*/
- void updateAnnotationFor(Class workerClass);
+ void updateAnnotationFor(Class<? extends AlignCalcWorkerI> workerClass);
/**
* return any registered workers of the given class
* @param workerClass
* @return null or one or more workers of the given class
*/
- List<AlignCalcWorkerI> getRegisteredWorkersOfClass(Class workerClass);
-
- /**
- * start any workers of the given class
- *
- * @param workerClass
- * @return false if no workers of given class were registered (note -
- * blacklisted classes cannot be restarted, so this method will return
- * true for blacklisted workers)
- */
- boolean startRegisteredWorkersOfClass(Class workerClass);
+ List<AlignCalcWorkerI> getRegisteredWorkersOfClass(
+ Class<? extends AlignCalcWorkerI> workerClass);
/**
* work out if there is an instance of a worker that is *waiting* to start
*
* @param typeToRemove
*/
- void removeRegisteredWorkersOfClass(Class typeToRemove);
+ void removeRegisteredWorkersOfClass(
+ Class<? extends AlignCalcWorkerI> typeToRemove);
+ /**
+ * Removes the worker that produces the given annotation, provided it is
+ * marked as 'deletable'. Some workers may need to continue to run as the
+ * results of their calculations are needed, e.g. for colour schemes.
+ *
+ * @param ann
+ */
+ void removeWorkerForAnnotation(AlignmentAnnotation ann);
}
* @param annot
* @return
*/
- public boolean involves(AlignmentAnnotation annot);
+ boolean involves(AlignmentAnnotation annot);
/**
* Updates the display of calculated annotation values (does not recalculate
- * the values). This allows for quick redraw of annotations when display
- * settings are changed.
+ * the values). This allows ßquick redraw of annotations when display settings
+ * are changed.
*/
- public void updateAnnotation();
+ void updateAnnotation();
/**
- * Removes any annotation managed by this worker from the alignment
+ * Removes any annotation(s) managed by this worker from the alignment
*/
void removeAnnotation();
+
+ /**
+ * Answers true if the worker should be deleted entirely when its annotation
+ * is deleted from the display, or false if it should continue to run. Some
+ * workers are required to run for their side-effects.
+ *
+ * @return
+ */
+ boolean isDeletable();
}
package jalview.api;
import jalview.analysis.Conservation;
+import jalview.analysis.Profile;
import jalview.datamodel.AlignmentAnnotation;
import jalview.datamodel.AlignmentI;
import jalview.datamodel.AlignmentView;
*/
public int calcPanelHeight();
+ /**
+ * Answers true if the viewport has at least one column selected
+ *
+ * @return
+ */
+ boolean hasSelectedColumns();
+
+ /**
+ * Answers true if the viewport has at least one hidden column
+ *
+ * @return
+ */
boolean hasHiddenColumns();
boolean isValidCharWidth();
ColumnSelection getColumnSelection();
- Hashtable[] getSequenceConsensusHash();
+ Profile[] getSequenceConsensusHash();
/**
* Get consensus data table for the cDNA complement of this alignment (if any)
boolean isClosed();
/**
+ * Dispose of all references or resources held by the viewport
+ */
+ void dispose();
+
+ /**
* get the associated calculation thread manager for the view
*
* @return
*
* @param hconsensus
*/
- void setSequenceConsensusHash(Hashtable[] hconsensus);
+ void setSequenceConsensusHash(Profile[] hconsensus);
/**
* Set the cDNA complement consensus for the viewport
* @return String[]
*/
String[] getViewAsString(boolean selectedRegionOnly);
-
+
/**
* This method returns the visible alignment as text, as seen on the GUI, ie
* if columns are hidden they will not be returned in the result. Use this for
*
* @return String[]
*/
- String[] getViewAsString(boolean selectedRegionOnly, boolean isExportHiddenSeqs);
+ String[] getViewAsString(boolean selectedRegionOnly,
+ boolean isExportHiddenSeqs);
void setSelectionGroup(SequenceGroup sg);
*/
void setFollowHighlight(boolean b);
-
public void applyFeaturesStyle(FeatureSettingsModelI featureSettings);
+
+ /**
+ * check if current selection group is defined on the view, or is simply a
+ * temporary group.
+ *
+ * @return true if group is defined on the alignment
+ */
+ boolean isSelectionDefinedGroup();
}
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
package jalview.api;
import jalview.datamodel.Mapping;
public void setVersion(String version);
/**
- *
- * @param startRes
- * index of start residue in the source DB
- */
- public void setStartRes(int startRes);
-
- /**
- *
- * @return index of start residue in the source DB
- */
- public int getStartRes();
-
- /**
- *
- * @param endRes
- * index of end residue in the source DB
- */
- public void setEndRes(int endRes);
-
- /**
- *
- * @return index of end residue in the source DB
- */
- public int getEndRes();
-
- /**
* access a mapping, if present that can be used to map positions from the
* associated dataset sequence to the DBRef's sequence frame.
*
* @return
*/
public boolean updateFrom(DBRefEntryI otherEntry);
+
+ /**
+ * Answers true if the ref looks like a primary (direct) database reference. <br>
+ * The only way a dbref's mappings can be fully verified is via the local
+ * sequence frame, so rather than use isPrimaryCandidate directly, please use
+ * SequenceI.getPrimaryDbRefs(). <br>
+ * Primary references indicate the local sequence data directly corresponds
+ * with the database record. All other references are secondary. Direct
+ * references indicate that part or all of the local sequence data can be
+ * mapped with another sequence, enabling annotation transfer.
+ * Cross-references indicate the local sequence data can be corresponded to
+ * some other linear coordinate system via a transformation. <br>
+ * This method is also sufficient to distinguish direct DBRefEntry mappings
+ * from other relationships - e.g. coding relationships (imply a 1:3/3:1
+ * mapping), but not transcript relationships, which imply a (possibly
+ * non-contiguous) 1:1 mapping.
+ *
+ * @return true if this reference provides a primary accession for the
+ * associated sequence object
+ */
+ public boolean isPrimaryCandidate();
}
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
package jalview.api;
import jalview.datamodel.SequenceFeature;
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
package jalview.api;
/**
*/
public String getDbCoordSys();
-
/**
* Get DB Source for the SIFTs Entry
*
*/
public StructureMapping getSiftsStructureMapping(SequenceI seq,
String pdbFile, String chain) throws SiftsException;
-
+
/**
* Get residue by residue mapping for a given Sequence and SIFTs entity
*
* @throws Exception
*/
public HashMap<Integer, int[]> getGreedyMapping(String entityId,
- SequenceI seq,
- java.io.PrintStream os) throws SiftsException;
+ SequenceI seq, java.io.PrintStream os) throws SiftsException;
}
\ No newline at end of file
import jalview.schemes.HydrophobicColourScheme;
import jalview.schemes.NucleotideColourScheme;
import jalview.schemes.PIDColourScheme;
-import jalview.schemes.ResidueProperties;
import jalview.schemes.StrandColourScheme;
import jalview.schemes.TaylorColourScheme;
import jalview.schemes.TurnColourScheme;
public class APopupMenu extends java.awt.PopupMenu implements
ActionListener, ItemListener
{
- private static final String ALL_ANNOTATIONS = "All";
-
Menu groupMenu = new Menu();
MenuItem editGroupName = new MenuItem();
"label.represent_group_with", new Object[] { "" }));
revealAll.setLabel(MessageManager.getString("action.reveal_all"));
revealSeq.setLabel(MessageManager.getString("action.reveal_sequences"));
- menu1.setLabel(MessageManager.getString("label.group") + ":");
+ menu1.setLabel(MessageManager.getString("label.group:"));
add(groupMenu);
this.add(seqMenu);
this.add(hideSeqs);
if (conservationMenuItem.getState())
{
- sg.cs.setConservation(Conservation.calculateConservation("Group",
- ResidueProperties.propHash, 3, sg.getSequences(ap.av
- .getHiddenRepSequences()), 0, ap.av.getAlignment()
- .getWidth(), false, ap.av.getConsPercGaps(), false));
+ sg.cs.setConservation(Conservation.calculateConservation("Group", 3,
+ sg.getSequences(ap.av.getHiddenRepSequences()), 0, ap.av
+ .getAlignment().getWidth(), false, ap.av
+ .getConsPercGaps(), false));
SliderPanel.setConservationSlider(ap, sg.cs, sg.getName());
SliderPanel.showConservationSlider();
}
showMenu.removeAll();
hideMenu.removeAll();
- final List<String> all = Arrays.asList(ALL_ANNOTATIONS);
+ final List<String> all = Arrays.asList(new String[] { MessageManager
+ .getString("label.all") });
addAnnotationTypeToShowHide(showMenu, forSequences, "", all, true, true);
addAnnotationTypeToShowHide(hideMenu, forSequences, "", all, true,
false);
import java.util.Arrays;
import java.util.Deque;
import java.util.HashMap;
-import java.util.Hashtable;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;
{
viewport.setColumnSelection(columnSelection);
}
+ viewport.setScaleAboveWrapped(scaleAbove.getState());
alignPanel = new AlignmentPanel(this, viewport);
avc = new jalview.controller.AlignViewController(this, viewport,
// Hide everything by the current selection - this is a hack - we do the
// invert and then hide
// first check that there will be visible columns after the invert.
- if ((viewport.getColumnSelection() != null
- && viewport.getColumnSelection().getSelected() != null && viewport
- .getColumnSelection().getSelected().size() > 0)
+ if (viewport.hasSelectedColumns()
|| (sg != null && sg.getSize() > 0 && sg.getStartRes() <= sg
.getEndRes()))
{
hide = true;
viewport.hideAllSelectedSeqs();
}
- else if (!(toggleCols && viewport.getColumnSelection().getSelected()
- .size() > 0))
+ else if (!(toggleCols && viewport.hasSelectedColumns()))
{
viewport.showAllHiddenSeqs();
}
if (toggleCols)
{
- if (viewport.getColumnSelection().getSelected().size() > 0)
+ if (viewport.hasSelectedColumns())
{
viewport.hideSelectedColumns();
if (!toggleSeqs)
if (alignPanel.getAlignment().getAlignmentAnnotation() != null)
{
for (AlignmentAnnotation aa : alignPanel.getAlignment()
- .getAlignmentAnnotation())
- {
- boolean visible = (aa.sequenceRef == null ? showForAlignment
- : showForSequences);
- aa.visible = visible;
+ .getAlignmentAnnotation())
+ {
+ boolean visible = (aa.sequenceRef == null ? showForAlignment
+ : showForSequences);
+ aa.visible = visible;
}
}
alignPanel.validateAnnotationDimensions(true);
FeaturesFile formatter = new FeaturesFile();
if (format.equalsIgnoreCase("Jalview"))
{
- features = formatter.printJalviewFormat(viewport
- .getAlignment().getSequencesArray(),
- getDisplayedFeatureCols());
+ features = formatter.printJalviewFormat(viewport.getAlignment()
+ .getSequencesArray(), getDisplayedFeatureCols());
}
else
{
}
sg.setEndRes(viewport.getAlignment().getWidth() - 1);
viewport.setSelectionGroup(sg);
- alignPanel.paintAlignment(true);
+ // JAL-2034 - should delegate to
+ // alignPanel to decide if overview needs
+ // updating.
+ alignPanel.paintAlignment(false);
PaintRefresher.Refresh(alignPanel, viewport.getSequenceSetId());
viewport.sendSelection();
}
viewport.setSelectionGroup(null);
alignPanel.idPanel.idCanvas.searchResults = null;
alignPanel.seqPanel.seqCanvas.highlightSearchResults(null);
- alignPanel.paintAlignment(true);
+ // JAL-2034 - should delegate to
+ // alignPanel to decide if overview needs
+ // updating.
+ alignPanel.paintAlignment(false);
PaintRefresher.Refresh(alignPanel, viewport.getSequenceSetId());
viewport.sendSelection();
}
nucleotideColour.setLabel(MessageManager.getString("label.nucleotide"));
nucleotideColour.addActionListener(this);
modifyPID.setLabel(MessageManager
- .getString("label.modify_identity_thereshold"));
+ .getString("label.modify_identity_threshold"));
modifyPID.addActionListener(this);
modifyConservation.setLabel(MessageManager
- .getString("label.modify_conservation_thereshold"));
+ .getString("label.modify_conservation_threshold"));
modifyConservation.addActionListener(this);
annotationColour.setLabel(MessageManager
.getString("action.by_annotation"));
}
if (needtoadd)
{
- // make a note of the access mode and add
- if (pdbentry.getProperty() == null)
- {
- pdbentry.setProperty(new Hashtable());
- }
- pdbentry.getProperty().put("protocol", protocol);
+ pdbentry.setProperty("protocol", protocol);
toaddpdb.addPDBId(pdbentry);
alignPanel.getStructureSelectionManager()
.registerPDBEntry(pdbentry);
if (protocol == null || protocol.trim().length() == 0
|| protocol.equals("null"))
{
- protocol = (String) pdb.getProperty().get("protocol");
+ protocol = (String) pdb.getProperty("protocol");
if (protocol == null)
{
System.err.println("Couldn't work out protocol to open structure: "
// this value is set false when selection area being dragged
boolean fastPaint = true;
- public void finalize()
+ @Override
+ public void finalize() throws Throwable
{
alignFrame = null;
av = null;
annotationPanel = null;
annotationPanelHolder = null;
annotationSpaceFillerHolder = null;
+ super.finalize();
}
public AlignmentPanel(AlignFrame af, final AlignViewport av)
addComponentListener(new ComponentAdapter()
{
+ @Override
public void componentResized(ComponentEvent evt)
{
setScrollValues(av.getStartRes(), av.getStartSeq());
final AlignmentPanel ap = this;
av.addPropertyChangeListener(new java.beans.PropertyChangeListener()
{
+ @Override
public void propertyChange(java.beans.PropertyChangeEvent evt)
{
if (evt.getPropertyName().equals("alignment"))
* automatically adjust annotation panel height for new annotation whilst
* ensuring the alignment is still visible.
*/
+ @Override
public void adjustAnnotationHeight()
{
// TODO: display vertical annotation scrollbar if necessary
}
+ @Override
public void adjustmentValueChanged(AdjustmentEvent evt)
{
int oldX = av.getStartRes();
/**
* Repaint the alignment and annotations, and, optionally, any overview window
*/
+ @Override
public void paintAlignment(boolean updateOverview)
{
final AnnotationSorter sorter = new AnnotationSorter(getAlignment(),
}
}
+ @Override
public void update(Graphics g)
{
paint(g);
}
+ @Override
public void paint(Graphics g)
{
invalidate();
*/
package jalview.appletgui;
+import jalview.datamodel.AlignmentAnnotation;
import jalview.datamodel.SequenceGroup;
import jalview.schemes.AnnotationColourGradient;
import jalview.schemes.ColourSchemeI;
slider.addAdjustmentListener(this);
slider.addMouseListener(this);
- if (av.getAlignment().getAlignmentAnnotation() == null)
+ AlignmentAnnotation[] anns = av.getAlignment().getAlignmentAnnotation();
+ if (anns == null)
{
return;
}
// seqAssociated.setState(acg.isSeqAssociated());
}
- Vector list = new Vector();
+ Vector<String> list = new Vector<String>();
int index = 1;
- for (int i = 0; i < av.getAlignment().getAlignmentAnnotation().length; i++)
+ for (int i = 0; i < anns.length; i++)
{
- String label = av.getAlignment().getAlignmentAnnotation()[i].label;
+ String label = anns[i].label;
+ if (anns[i].sequenceRef != null)
+ {
+ label = label + "_" + anns[i].sequenceRef.getName();
+ }
if (!list.contains(label))
{
list.addElement(label);
}
threshold.addItem(MessageManager
- .getString("label.threshold_feature_no_thereshold"));
+ .getString("label.threshold_feature_no_threshold"));
threshold.addItem(MessageManager
- .getString("label.threshold_feature_above_thereshold"));
+ .getString("label.threshold_feature_above_threshold"));
threshold.addItem(MessageManager
- .getString("label.threshold_feature_below_thereshold"));
+ .getString("label.threshold_feature_below_threshold"));
if (oldcs instanceof AnnotationColourGradient)
{
default:
throw new Error(
MessageManager
- .getString("error.implementation_error_dont_know_thereshold_annotationcolourgradient"));
+ .getString("error.implementation_error_dont_know_threshold_annotationcolourgradient"));
}
thresholdIsMin.setState(acg.thresholdIsMinMax);
thresholdValue.setText("" + acg.getAnnotationThreshold());
Checkbox thresholdIsMin = new Checkbox();
+ @Override
public void actionPerformed(ActionEvent evt)
{
if (evt.getSource() == thresholdValue)
}
}
+ @Override
public void itemStateChanged(ItemEvent evt)
{
if (evt.getSource() == currentColours)
changeColour();
}
+ @Override
public void adjustmentValueChanged(AdjustmentEvent evt)
{
if (!adjusting)
}
+ @Override
public void mouseClicked(MouseEvent evt)
{
}
+ @Override
public void mousePressed(MouseEvent evt)
{
}
+ @Override
public void mouseReleased(MouseEvent evt)
{
ap.paintAlignment(true);
}
+ @Override
public void mouseEntered(MouseEvent evt)
{
}
+ @Override
public void mouseExited(MouseEvent evt)
{
}
slider.addAdjustmentListener(this);
slider.addMouseListener(this);
- if (av.getAlignment().getAlignmentAnnotation() == null)
+ AlignmentAnnotation[] anns = av.getAlignment().getAlignmentAnnotation();
+ if (anns == null)
{
return;
}
setOldColumnSelection(av.getColumnSelection());
adjusting = true;
- Vector list = new Vector();
+ Vector<String> list = new Vector<String>();
int index = 1;
- for (int i = 0; i < av.getAlignment().getAlignmentAnnotation().length; i++)
+ for (int i = 0; i < anns.length; i++)
{
- String label = av.getAlignment().getAlignmentAnnotation()[i].label;
+ String label = anns[i].label;
+ if (anns[i].sequenceRef != null)
+ {
+ label = label + "_" + anns[i].sequenceRef.getName();
+ }
if (!list.contains(label))
{
list.addElement(label);
this.validate();
}
+ @Override
@SuppressWarnings("unchecked")
public void reset()
{
}
+ @Override
public void adjustmentValueChanged(AdjustmentEvent evt)
{
if (!adjusting)
});
}
+ @Override
public void valueChanged(boolean updateAllAnnotation)
{
if (slider.isEnabled())
}
}
+ @Override
public void actionPerformed(ActionEvent evt)
{
if (evt.getSource() == thresholdValue)
import jalview.datamodel.AlignmentAnnotation;
import jalview.datamodel.Annotation;
+import jalview.datamodel.SequenceI;
import jalview.renderer.AnnotationRenderer;
import jalview.renderer.AwtRenderPanelI;
+import jalview.schemes.ResidueProperties;
+import jalview.util.Comparison;
import jalview.util.MessageManager;
+import jalview.util.Platform;
import java.awt.Color;
import java.awt.Dimension;
public AnnotationPanel(AlignmentPanel ap)
{
- MAC = new jalview.util.Platform().isAMac();
+ new jalview.util.Platform();
+ MAC = Platform.isAMac();
this.ap = ap;
av = ap.av;
setLayout(null);
if (evt.getActionCommand().equals(REMOVE))
{
- for (int sel : av.getColumnSelection().getSelected())
+ for (int index : av.getColumnSelection().getSelected())
{
- // TODO: JAL-2001 check if applet has faulty 'REMOVE' selected columns
- // of
- // annotation if selection includes hidden columns
- anot[sel] = null;
+ if (av.getColumnSelection().isVisible(index))
+ {
+ anot[index] = null;
+ }
}
}
else if (evt.getActionCommand().equals(LABEL))
else if (evt.getActionCommand().equals(STEM))
{
type = 'S';
- symbol = "\u03C3";
+ int column = av.getColumnSelection().getSelectedRanges().get(0)[0];
+ symbol = aa[activeRow].getDefaultRnaHelixSymbol(column);
}
if (!aa[activeRow].hasIcons)
if ((evt.getModifiers() & InputEvent.BUTTON3_MASK) == InputEvent.BUTTON3_MASK
&& activeRow != -1)
{
- if (av.getColumnSelection() == null)
+ if (av.getColumnSelection() == null
+ || av.getColumnSelection().isEmpty())
{
return;
}
PopupMenu pop = new PopupMenu(
MessageManager.getString("label.structure_type"));
MenuItem item;
- /*
- * Just display the needed structure options
- */
- if (av.getAlignment().isNucleotide() == true)
+
+ if (av.getAlignment().isNucleotide())
{
item = new MenuItem(STEM);
item.addActionListener(this);
}
}
- int res = evt.getX() / av.getCharWidth() + av.getStartRes();
+ int column = evt.getX() / av.getCharWidth() + av.getStartRes();
if (av.hasHiddenColumns())
{
- res = av.getColumnSelection().adjustForHiddenColumns(res);
+ column = av.getColumnSelection().adjustForHiddenColumns(column);
}
- if (row > -1 && res < aa[row].annotations.length
- && aa[row].annotations[res] != null)
+ if (row > -1 && column < aa[row].annotations.length
+ && aa[row].annotations[column] != null)
{
- StringBuffer text = new StringBuffer("Sequence position " + (res + 1));
- if (aa[row].annotations[res].description != null)
+ StringBuilder text = new StringBuilder();
+ text.append(MessageManager.getString("label.column")).append(" ")
+ .append(column + 1);
+ String description = aa[row].annotations[column].description;
+ if (description != null && description.length() > 0)
+ {
+ text.append(" ").append(description);
+ }
+
+ /*
+ * if the annotation is sequence-specific, show the sequence number
+ * in the alignment, and (if not a gap) the residue and position
+ */
+ SequenceI seqref = aa[row].sequenceRef;
+ if (seqref != null)
{
- text.append(" " + aa[row].annotations[res].description);
+ int seqIndex = av.getAlignment().findIndex(seqref);
+ if (seqIndex != -1)
+ {
+ text.append(", ")
+ .append(MessageManager.getString("label.sequence"))
+ .append(" ").append(seqIndex + 1);
+ char residue = seqref.getCharAt(column);
+ if (!Comparison.isGap(residue))
+ {
+ text.append(" ");
+ String name;
+ if (av.getAlignment().isNucleotide())
+ {
+ name = ResidueProperties.nucleotideName.get(String
+ .valueOf(residue));
+ text.append(" Nucleotide: ").append(
+ name != null ? name : residue);
+ }
+ else
+ {
+ name = 'X' == residue ? "X" : ('*' == residue ? "STOP"
+ : ResidueProperties.aa2Triplet.get(String
+ .valueOf(residue)));
+ text.append(" Residue: ").append(
+ name != null ? name : residue);
+ }
+ int residuePos = seqref.findPosition(column);
+ text.append(" (").append(residuePos).append(")");
+ // int residuePos = seqref.findPosition(column);
+ // text.append(residue).append(" (")
+ // .append(residuePos).append(")");
+ }
+ }
}
+
ap.alignFrame.statusBar.setText(text.toString());
}
}
}
- public Vector getAnnotationItems(boolean isSeqAssociated)
- {
- Vector list = new Vector();
- int index = 1;
- int[] anmap = new int[av.getAlignment().getAlignmentAnnotation().length];
- for (int i = 0; i < av.getAlignment().getAlignmentAnnotation().length; i++)
- {
- if (av.getAlignment().getAlignmentAnnotation()[i].sequenceRef == null)
- {
- if (isSeqAssociated)
- {
- continue;
- }
- }
- else
- {
- enableSeqAss = true;
- }
- String label = av.getAlignment().getAlignmentAnnotation()[i].label;
- if (!list.contains(label))
- {
- anmap[list.size()] = i;
- list.add(label);
-
- }
- else
- {
- if (!isSeqAssociated)
- {
- anmap[list.size()] = i;
- list.add(label + "_" + (index++));
- }
- }
- }
- this.annmap = new int[list.size()];
- System.arraycopy(anmap, 0, this.annmap, 0, this.annmap.length);
- return list;
- }
-
protected int getSelectedThresholdItem(int indexValue)
{
int selectedThresholdItem = -1;
protected void populateThresholdComboBox(Choice threshold)
{
threshold.addItem(MessageManager
- .getString("label.threshold_feature_no_thereshold"));
+ .getString("label.threshold_feature_no_threshold"));
threshold.addItem(MessageManager
- .getString("label.threshold_feature_above_thereshold"));
+ .getString("label.threshold_feature_above_threshold"));
threshold.addItem(MessageManager
- .getString("label.threshold_feature_below_thereshold"));
+ .getString("label.threshold_feature_below_threshold"));
}
public jalview.datamodel.AlignmentAnnotation getCurrentAnnotation()
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.ArrayList;
-import java.util.Hashtable;
import java.util.List;
import java.util.Vector;
closeViewer();
}
});
- if (pdbentry.getProperty() == null)
- {
- pdbentry.setProperty(new Hashtable());
- pdbentry.getProperty().put("protocol", protocol);
- }
+ pdbentry.setProperty("protocol", protocol);
+
if (pdbentry.getFile() != null)
{
// import structure data from pdbentry.getFile based on given protocol
jPanel4.setBackground(Color.white);
threshold.addItemListener(this);
threshold.addItem(MessageManager
- .getString("label.threshold_feature_no_thereshold"));
+ .getString("label.threshold_feature_no_threshold"));
threshold.addItem(MessageManager
- .getString("label.threshold_feature_above_thereshold"));
+ .getString("label.threshold_feature_above_threshold"));
threshold.addItem(MessageManager
- .getString("label.threshold_feature_below_thereshold"));
+ .getString("label.threshold_feature_below_threshold"));
thresholdValue.addActionListener(this);
slider.setBackground(Color.white);
slider.setEnabled(false);
*/
public FeatureRenderer(AlignmentViewport av)
{
- super();
- this.av = av;
+ super(av);
+
}
static String lastFeatureAdded;
tmp = new Panel();
panel.add(tmp);
- tmp.add(new Label("Name: ", Label.RIGHT));
+ tmp.add(new Label(MessageManager.getString("label.name:"), Label.RIGHT));
tmp.add(name);
tmp = new Panel();
panel.add(tmp);
- tmp.add(new Label("Group: ", Label.RIGHT));
+ tmp.add(new Label(MessageManager.getString("label.group:"), Label.RIGHT));
tmp.add(source);
tmp = new Panel();
panel.add(tmp);
- tmp.add(new Label("Colour: ", Label.RIGHT));
+ tmp.add(new Label(MessageManager.getString("label.colour"), Label.RIGHT));
tmp.add(colourPanel);
bigPanel.add(panel, BorderLayout.NORTH);
panel = new Panel();
- panel.add(new Label("Description: ", Label.RIGHT));
+ panel.add(new Label(MessageManager.getString("label.description:"),
+ Label.RIGHT));
panel.add(new ScrollPane().add(description));
if (!newFeatures)
bigPanel.add(panel, BorderLayout.SOUTH);
panel = new Panel();
- panel.add(new Label(" Start:", Label.RIGHT));
+ panel.add(new Label(MessageManager.getString("label.start"),
+ Label.RIGHT));
panel.add(start);
- panel.add(new Label(" End:", Label.RIGHT));
+ panel.add(new Label(MessageManager.getString("label.end"),
+ Label.RIGHT));
panel.add(end);
bigPanel.add(panel, BorderLayout.CENTER);
}
}
protected void popupSort(final MyCheckbox check,
- final Map<String, float[][]> minmax,
- int x, int y)
+ final Map<String, float[][]> minmax, int x, int y)
{
final String type = check.type;
final FeatureColourI typeCol = fr.getFeatureStyle(type);
public void paint(Graphics g)
{
Dimension d = getSize();
- if (col.isColourByLabel())
+ if (col != null)
{
- g.setColor(Color.white);
- g.fillRect(d.width / 2, 0, d.width / 2, d.height);
- /*
- * g.setColor(Color.black); Font f=g.getFont().deriveFont(9);
- * g.setFont(f);
- *
- * // g.setFont(g.getFont().deriveFont( //
- * AffineTransform.getScaleInstance( //
- * width/g.getFontMetrics().stringWidth("Label"), //
- * height/g.getFontMetrics().getHeight()))); g.drawString("Label",
- * width/2, 0);
- */
+ if (col.isColourByLabel())
+ {
+ g.setColor(Color.white);
+ g.fillRect(d.width / 2, 0, d.width / 2, d.height);
+ /*
+ * g.setColor(Color.black); Font f=g.getFont().deriveFont(9);
+ * g.setFont(f);
+ *
+ * // g.setFont(g.getFont().deriveFont( //
+ * AffineTransform.getScaleInstance( //
+ * width/g.getFontMetrics().stringWidth("Label"), //
+ * height/g.getFontMetrics().getHeight()))); g.drawString("Label",
+ * width/2, 0);
+ */
- }
- else if (col.isGraduatedColour())
- {
- Color maxCol = col.getMaxColour();
- g.setColor(maxCol);
- g.fillRect(d.width / 2, 0, d.width / 2, d.height);
+ }
+ else if (col.isGraduatedColour())
+ {
+ Color maxCol = col.getMaxColour();
+ g.setColor(maxCol);
+ g.fillRect(d.width / 2, 0, d.width / 2, d.height);
+ }
}
if (hasLink)
* @param type
* @param columnsContaining
*/
- void hideFeatureColumns(final String type,
- boolean columnsContaining)
+ void hideFeatureColumns(final String type, boolean columnsContaining)
{
- if (ap.alignFrame.avc.markColumnsContainingFeatures(
- columnsContaining, false, false, type))
+ if (ap.alignFrame.avc.markColumnsContainingFeatures(columnsContaining,
+ false, false, type))
{
if (ap.alignFrame.avc.markColumnsContainingFeatures(
!columnsContaining, false, false, type))
*/
package jalview.appletgui;
+import static jalview.util.UrlConstants.EMBLEBI_STRING;
+import static jalview.util.UrlConstants.SRS_STRING;
+
import jalview.datamodel.Sequence;
import jalview.datamodel.SequenceFeature;
import jalview.datamodel.SequenceGroup;
}
{
// upgrade old SRS link
- int srsPos = links
- .indexOf("SRS|http://srs.ebi.ac.uk/srsbin/cgi-bin/wgetz?-newId+(([uniprot-all:$SEQUENCE_ID$]))+-view+SwissEntry");
+ int srsPos = links.indexOf(SRS_STRING);
if (srsPos > -1)
{
- links.setElementAt(
- "EMBL-EBI Search|http://www.ebi.ac.uk/ebisearch/search.ebi?db=allebi&query=$SEQUENCE_ID$",
- srsPos);
+ links.setElementAt(EMBLEBI_STRING, srsPos);
}
}
if (links.size() < 1)
{
links = new java.util.Vector();
- links.addElement("EMBL-EBI Search|http://www.ebi.ac.uk/ebisearch/search.ebi?db=allebi&query=$SEQUENCE_ID$");
+ links.addElement(EMBLEBI_STRING);
}
}
if ((av.getSelectionGroup() == null)
|| ((!jalview.util.Platform.isControlDown(e) && !e
- .isShiftDown()) && av
- .getSelectionGroup() != null))
+ .isShiftDown()) && av.getSelectionGroup() != null))
{
av.setSelectionGroup(new SequenceGroup());
av.getSelectionGroup().setStartRes(0);
{
miniMe = null;
int alwidth = av.getAlignment().getWidth();
- int alheight = av.getAlignment().getHeight();
+ int alheight = av.getAlignment().getHeight()
+ + av.getAlignment().getHiddenSequences().getSize();
if (av.isShowSequenceFeatures())
{
AlignmentI alignment = av.getAlignment();
for (row = 0; row <= sequencesHeight; row++)
{
+ if (resizeAgain)
+ {
+ break;
+ }
if ((int) (row * sampleRow) == lastrow)
{
sameRow++;
{
for (col = 0; col < width; col++)
{
+ if (resizeAgain)
+ {
+ break;
+ }
lastcol = (int) (col * sampleCol);
{
mg.translate(col, sequencesHeight);
import jalview.datamodel.ColumnSelection;
import jalview.datamodel.SequenceGroup;
+import jalview.renderer.ScaleRenderer;
+import jalview.renderer.ScaleRenderer.ScaleMark;
import jalview.util.MessageManager;
import java.awt.Color;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
+import java.util.List;
public class ScalePanel extends Panel implements MouseMotionListener,
MouseListener
PopupMenu pop = new PopupMenu();
if (reveal != null)
{
- MenuItem item = new MenuItem(
- MessageManager.getString("label.reveal"));
+ MenuItem item = new MenuItem(MessageManager.getString("label.reveal"));
item.addActionListener(new ActionListener()
{
@Override
{
av.hideColumns(res, res);
if (av.getSelectionGroup() != null
- && av.getSelectionGroup().getSize() == av
- .getAlignment().getHeight())
+ && av.getSelectionGroup().getSize() == av.getAlignment()
+ .getHeight())
{
av.setSelectionGroup(null);
}
// Fill the selected columns
ColumnSelection cs = av.getColumnSelection();
- gg.setColor(new Color(220, 0, 0));
- int avcharWidth = av.getCharWidth(), avcharHeight = av.getCharHeight();
- for (int sel : cs.getSelected())
+ int avCharWidth = av.getCharWidth();
+ int avcharHeight = av.getCharHeight();
+ if (cs != null)
{
- // TODO: JAL-2001 - provide a fast method to list visible selected in a
- // given range
- if (av.hasHiddenColumns())
+ gg.setColor(new Color(220, 0, 0));
+ boolean hasHiddenColumns = cs.hasHiddenColumns();
+ for (int sel : cs.getSelected())
{
- sel = av.getColumnSelection().findColumnPosition(sel);
- }
+ // TODO: JAL-2001 - provide a fast method to list visible selected in a
+ // given range
+ if (hasHiddenColumns)
+ {
+ if (cs.isVisible(sel))
+ {
+ sel = cs.findColumnPosition(sel);
+ }
+ else
+ {
+ continue;
+ }
+ }
- if ((sel >= startx) && (sel <= endx))
- {
- gg.fillRect((sel - startx) * avcharWidth, 0, avcharWidth,
- getSize().height);
+ if ((sel >= startx) && (sel <= endx))
+ {
+ gg.fillRect((sel - startx) * avCharWidth, 0, avCharWidth,
+ getSize().height);
+ }
}
}
// Draw the scale numbers
gg.setColor(Color.black);
- int scalestartx = (startx / 10) * 10;
- int widthx = 1 + endx - startx;
-
- FontMetrics fm = gg.getFontMetrics(av.getFont());
- int y = avcharHeight - fm.getDescent();
-
- if ((scalestartx % 10) == 0)
- {
- scalestartx += 5;
- }
-
- String string;
int maxX = 0;
+ List<ScaleMark> marks = new ScaleRenderer().calculateMarks(av, startx,
+ endx);
- for (int i = scalestartx; i < endx; i += 5)
+ FontMetrics fm = gg.getFontMetrics(av.getFont());
+ int y = avcharHeight;
+ int yOf = fm.getDescent();
+ y -= yOf;
+ for (ScaleMark mark : marks)
{
- if ((i % 10) == 0)
+ boolean major = mark.major;
+ int mpos = mark.column; // (i - startx - 1)
+ String mstring = mark.text;
+ if (mstring != null)
{
- string = String.valueOf(av.getColumnSelection()
- .adjustForHiddenColumns(i));
- if ((i - startx - 1) * avcharWidth > maxX)
+ if (mpos * avCharWidth > maxX)
{
- gg.drawString(string, (i - startx - 1) * avcharWidth, y);
- maxX = (i - startx + 1) * avcharWidth + fm.stringWidth(string);
+ gg.drawString(mstring, mpos * avCharWidth, y);
+ maxX = (mpos + 2) * avCharWidth + fm.stringWidth(mstring);
}
-
- gg.drawLine(((i - startx - 1) * avcharWidth) + (avcharWidth / 2),
- y + 2,
- ((i - startx - 1) * avcharWidth) + (avcharWidth / 2), y
- + (fm.getDescent() * 2));
-
+ }
+ if (major)
+ {
+ gg.drawLine((mpos * avCharWidth) + (avCharWidth / 2), y + 2,
+ (mpos * avCharWidth) + (avCharWidth / 2), y + (yOf * 2));
}
else
{
- gg.drawLine(((i - startx - 1) * avcharWidth) + (avcharWidth / 2), y
- + fm.getDescent(), ((i - startx - 1) * avcharWidth)
- + (avcharWidth / 2), y + (fm.getDescent() * 2));
+ gg.drawLine((mpos * avCharWidth) + (avCharWidth / 2), y + yOf,
+ (mpos * avCharWidth) + (avCharWidth / 2), y + (yOf * 2));
}
}
int res;
if (av.getShowHiddenMarkers())
{
- for (int i = 0; i < av.getColumnSelection().getHiddenColumns()
- .size(); i++)
+ int widthx = 1 + endx - startx;
+ for (int i = 0; i < cs.getHiddenColumns().size(); i++)
{
- res = av.getColumnSelection().findHiddenRegionPosition(i)
- - startx;
+ res = cs.findHiddenRegionPosition(i) - startx;
if (res < 0 || res > widthx)
{
continue;
}
- gg.fillPolygon(new int[] { res * avcharWidth - avcharHeight / 4,
- res * avcharWidth + avcharHeight / 4, res * avcharWidth },
- new int[] { y - avcharHeight / 2, y - avcharHeight / 2,
- y + 8 }, 3);
-
+ gg.fillPolygon(new int[] {
+ -1 + res * avCharWidth - avcharHeight / 4,
+ -1 + res * avCharWidth + avcharHeight / 4,
+ -1 + res * avCharWidth }, new int[] { y, y, y + 2 * yOf }, 3);
}
}
-
- if (reveal != null && reveal[0] > startx && reveal[0] < endx)
- {
- gg.drawString(MessageManager.getString("label.reveal_columns"),
- reveal[0] * avcharWidth, 0);
- }
}
-
}
}
import jalview.datamodel.SearchResults;
import jalview.datamodel.SequenceGroup;
import jalview.datamodel.SequenceI;
+import jalview.renderer.ScaleRenderer;
+import jalview.renderer.ScaleRenderer.ScaleMark;
import jalview.viewmodel.AlignmentViewport;
import java.awt.Color;
private void drawNorthScale(Graphics g, int startx, int endx, int ypos)
{
- int scalestartx = startx - startx % 10 + 10;
-
+ updateViewport();
g.setColor(Color.black);
-
- // NORTH SCALE
- for (int i = scalestartx; i < endx; i += 10)
+ for (ScaleMark mark : new ScaleRenderer().calculateMarks(av, startx,
+ endx))
{
- int value = i;
- if (av.hasHiddenColumns())
+ int mpos = mark.column; // (i - startx - 1)
+ if (mpos < 0)
{
- value = av.getColumnSelection().adjustForHiddenColumns(value);
+ continue;
}
+ String mstring = mark.text;
- g.drawString(String.valueOf(value), (i - startx - 1) * avcharWidth,
- ypos - (avcharHeight / 2));
-
- g.drawLine(((i - startx - 1) * avcharWidth) + (avcharWidth / 2),
- (ypos + 2) - (avcharHeight / 2),
- ((i - startx - 1) * avcharWidth) + (avcharWidth / 2),
- ypos - 2);
+ if (mark.major)
+ {
+ if (mstring != null)
+ {
+ g.drawString(mstring, mpos * avcharWidth, ypos
+ - (avcharHeight / 2));
+ }
+ g.drawLine((mpos * avcharWidth) + (avcharWidth / 2), (ypos + 2)
+ - (avcharHeight / 2), (mpos * avcharWidth)
+ + (avcharWidth / 2), ypos - 2);
+ }
}
}
Tooltip tooltip;
+ /**
+ * set when the current UI interaction has resulted in a change that requires
+ * overview shading to be recalculated. this could be changed to something
+ * more expressive that indicates what actually has changed, so selective
+ * redraws can be applied
+ */
+ private boolean needOverviewUpdate; // TODO: refactor to avcontroller
+
@Override
public void mouseDragged(MouseEvent evt)
{
{
return;
}
-
- stretchGroup.recalcConservation(); // always do this - annotation has own
- // state
+ // always do this - annotation has own state
+ // but defer colourscheme update until hidden sequences are passed in
+ boolean vischange = stretchGroup.recalcConservation(true);
+ // here we rely on stretchGroup == av.getSelection()
+ needOverviewUpdate |= vischange && av.isSelectionDefinedGroup();
if (stretchGroup.cs != null)
{
stretchGroup.cs.alignmentChanged(stretchGroup,
stretchGroup.getName());
}
}
+ PaintRefresher.Refresh(ap, av.getSequenceSetId());
+ ap.paintAlignment(needOverviewUpdate);
+ needOverviewUpdate = false;
changeEndRes = false;
changeStartRes = false;
stretchGroup = null;
- PaintRefresher.Refresh(ap, av.getSequenceSetId());
- ap.paintAlignment(true);
av.sendSelection();
}
if (res > (stretchGroup.getStartRes() - 1))
{
stretchGroup.setEndRes(res);
+ needOverviewUpdate |= av.isSelectionDefinedGroup();
}
}
else if (changeStartRes)
if (res < (stretchGroup.getEndRes() + 1))
{
stretchGroup.setStartRes(res);
+ needOverviewUpdate |= av.isSelectionDefinedGroup();
}
}
if (stretchGroup.getSequences(null).contains(nextSeq))
{
stretchGroup.deleteSequence(seq, false);
+ needOverviewUpdate |= av.isSelectionDefinedGroup();
}
else
{
}
stretchGroup.addSequence(nextSeq, false);
+ needOverviewUpdate |= av.isSelectionDefinedGroup();
}
}
pid = (SliderPanel) PIDSlider.getComponent(0);
pid.cs = cs;
}
- PIDSlider.setTitle(MessageManager
- .formatMessage("label.percentage_identity_thereshold",
+ PIDSlider
+ .setTitle(MessageManager.formatMessage(
+ "label.percentage_identity_threshold",
new String[] { source }));
if (ap.av.getAlignment().getGroups() != null)
import jalview.datamodel.SequenceNode;
import jalview.schemes.ColourSchemeI;
import jalview.schemes.ColourSchemeProperty;
-import jalview.schemes.ResidueProperties;
import jalview.schemes.UserColourScheme;
import jalview.util.Format;
import jalview.util.MappingUtils;
tree.findHeight(tree.getTopNode());
// Now have to calculate longest name based on the leaves
- Vector leaves = tree.findLeaves(tree.getTopNode(), new Vector());
+ Vector<SequenceNode> leaves = tree.findLeaves(tree.getTopNode());
boolean has_placeholders = false;
longestName = "";
for (int i = 0; i < leaves.size(); i++)
{
- SequenceNode lf = (SequenceNode) leaves.elementAt(i);
+ SequenceNode lf = leaves.elementAt(i);
if (lf.isPlaceholder())
{
}
else
{
- Vector leaves = new Vector();
- tree.findLeaves(highlightNode, leaves);
+ Vector<SequenceNode> leaves = tree.findLeaves(highlightNode);
for (int i = 0; i < leaves.size(); i++)
{
- SequenceI seq = (SequenceI) ((SequenceNode) leaves.elementAt(i))
- .element();
+ SequenceI seq = (SequenceI) leaves.elementAt(i).element();
treeSelectionChanged(seq);
}
}
Color col = new Color((int) (Math.random() * 255),
(int) (Math.random() * 255), (int) (Math.random() * 255));
- setColor((SequenceNode) tree.getGroups().elementAt(i), col.brighter());
+ setColor(tree.getGroups().elementAt(i), col.brighter());
- Vector l = tree.findLeaves(
- (SequenceNode) tree.getGroups().elementAt(i), new Vector());
+ Vector<SequenceNode> l = tree.findLeaves(tree.getGroups()
+ .elementAt(i));
- Vector sequences = new Vector();
+ Vector<SequenceI> sequences = new Vector<SequenceI>();
for (int j = 0; j < l.size(); j++)
{
- SequenceI s1 = (SequenceI) ((SequenceNode) l.elementAt(j))
- .element();
+ SequenceI s1 = (SequenceI) l.elementAt(j).element();
if (!sequences.contains(s1))
{
sequences.addElement(s1);
if (av.getGlobalColourScheme() != null
&& av.getGlobalColourScheme().conservationApplied())
{
- Conservation c = new Conservation("Group",
- ResidueProperties.propHash, 3, sg.getSequences(null),
- sg.getStartRes(), sg.getEndRes());
+ Conservation c = new Conservation("Group", 3,
+ sg.getSequences(null), sg.getStartRes(), sg.getEndRes());
c.calculate();
c.verdict(false, av.getConsPercGaps());
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
package jalview.bin;
import java.net.URLDecoder;
return vargs.size();
}
-}
\ No newline at end of file
+}
*/
package jalview.bin;
-import jalview.datamodel.DBRefSource;
-import jalview.structure.StructureViewSettings;
+import jalview.datamodel.PDBEntry;
+import jalview.structure.StructureImportSettings;
import jalview.ws.dbsources.das.api.DasSourceRegistryI;
import jalview.ws.dbsources.das.datamodel.DasSourceRegistry;
import jalview.ws.sifts.SiftsSettings;
import java.util.Collections;
import java.util.Date;
import java.util.Enumeration;
+import java.util.Locale;
import java.util.Properties;
import java.util.TreeSet;
private final static String DEFAULT_FAIL_SAFE_PID_THRESHOLD = "30";
- private final static String DEFAULT_STRUCTURE_FORMAT = DBRefSource.PDB;
+ /**
+ * Allowed values are PDB or mmCIF
+ */
+ private final static String PDB_DOWNLOAD_FORMAT = PDBEntry.Type.MMCIF
+ .toString();
+
+ private final static String DEFAULT_PDB_FILE_PARSER = StructureImportSettings.StructureParser.JMOL_PARSER
+ .toString();
+
+ /*
+ * a date formatter using a fixed (rather than the user's) locale;
+ * this ensures that date properties can be written and re-read successfully
+ * even if the user changes their locale setting
+ */
+ private static final DateFormat date_format = SimpleDateFormat
+ .getDateTimeInstance(SimpleDateFormat.MEDIUM,
+ SimpleDateFormat.MEDIUM, Locale.UK);
/**
* Initialises the Jalview Application Log
System.out
.println("Jalview Version: " + codeVersion + codeInstallation);
- StructureViewSettings.setCurrentDefaultFormat(jalview.bin.Cache
- .getDefault(
- "DEFAULT_STRUCTURE_FORMAT", DEFAULT_STRUCTURE_FORMAT));
+ StructureImportSettings.setDefaultStructureFileFormat(jalview.bin.Cache
+ .getDefault("PDB_DOWNLOAD_FORMAT", PDB_DOWNLOAD_FORMAT));
+ StructureImportSettings
+ .setDefaultPDBFileParser(DEFAULT_PDB_FILE_PARSER);
+ // StructureImportSettings
+ // .setDefaultPDBFileParser(jalview.bin.Cache.getDefault(
+ // "DEFAULT_PDB_FILE_PARSER", DEFAULT_PDB_FILE_PARSER));
// jnlpVersion will be null if we're using InstallAnywhere
// Dont do this check if running in headless mode
if (jnlpVersion == null
setProperty(property, jalview.util.Format.getHexString(colour));
}
- public static final DateFormat date_format = SimpleDateFormat
- .getDateTimeInstance();
-
/**
- * store a date in a jalview property
+ * Stores a formatted date in a jalview property, using a fixed locale.
*
- * @param string
- * @param time
+ * @param propertyName
+ * @param date
+ * @return the formatted date string
*/
- public static void setDateProperty(String property, Date time)
+ public static String setDateProperty(String propertyName, Date date)
{
- setProperty(property, date_format.format(time));
+ String formatted = date_format.format(date);
+ setProperty(propertyName, formatted);
+ return formatted;
}
/**
- * read a date stored in a jalview property
+ * Reads a date stored in a Jalview property, parses it (using a fixed locale
+ * format) and returns as a Date, or null if parsing fails
*
- * @param property
- * @return valid date as stored by setDateProperty, or null
+ * @param propertyName
+ * @return
*
*/
- public static Date getDateProperty(String property)
+ public static Date getDateProperty(String propertyName)
{
- String val = getProperty(property);
+ String val = getProperty(propertyName);
if (val != null)
{
try
} catch (Exception ex)
{
System.err.println("Invalid or corrupt date in property '"
- + property + "' : value was '" + val + "'");
+ + propertyName + "' : value was '" + val + "'");
}
}
return null;
import groovy.lang.Binding;
import groovy.util.GroovyScriptEngine;
+import jalview.ext.so.SequenceOntology;
import jalview.gui.AlignFrame;
import jalview.gui.Desktop;
import jalview.gui.PromptUserConfig;
import jalview.io.HtmlSvgOutput;
import jalview.io.IdentifyFile;
import jalview.io.NewickFile;
+import jalview.io.gff.SequenceOntologyFactory;
import jalview.schemes.ColourSchemeI;
import jalview.schemes.ColourSchemeProperty;
import jalview.schemes.UserColourScheme;
}
}
+ /*
+ * configure 'full' SO model if preferences say to,
+ * else use the default (SO Lite)
+ */
+ if (Cache.getDefault("USE_FULL_SO", false))
+ {
+ SequenceOntologyFactory.setInstance(new SequenceOntology());
+ }
+
if (!headless)
{
desktop = new Desktop();
Cache.log.debug("Starting questionnaire with default url: "
+ defurl);
desktop.checkForQuestionnaire(defurl);
-
}
}
}
{
System.err.println("CMD [-noquestionnaire] executed successfully!");
}
- desktop.checkForNews();
- }
- if (!isHeadlessMode())
- {
+ if (!aparser.contains("nonews"))
+ {
+ desktop.checkForNews();
+ }
+
BioJsHTMLOutput.updateBioJS();
}
System.out.println("Creating HTML image: " + file);
continue;
}
+ else if (format.equalsIgnoreCase("biojsmsa"))
+ {
+ BioJsHTMLOutput.updateBioJS();
+ try
+ {
+ Thread.sleep(1500);
+ } catch (InterruptedException e)
+ {
+ e.printStackTrace();
+ }
+ BioJsHTMLOutput bjs = new BioJsHTMLOutput(af.alignPanel, af);
+ bjs.exportJalviewAlignmentAsBioJsHtmlFile(file);
+ System.out.println("Creating BioJS MSA Viwer HTML file: "
+ + file);
+ continue;
+ }
else if (format.equalsIgnoreCase("imgMap"))
{
af.createImageMap(new File(file), imageName);
+ "-png FILE\tCreate PNG image FILE from alignment.\n"
+ "-svg FILE\tCreate SVG image FILE from alignment.\n"
+ "-html FILE\tCreate HTML file from alignment.\n"
+ + "-biojsMSA FILE\tCreate BioJS MSA Viewer HTML file from alignment.\n"
+ "-imgMap FILE\tCreate HTML file FILE with image map of PNG image.\n"
+ "-eps FILE\tCreate EPS file FILE from alignment.\n"
+ "-questionnaire URL\tQueries the given URL for information about any Jalview user questionnaires.\n"
+ "-noquestionnaire\tTurn off questionnaire check.\n"
+ + "-nonews\tTurn off check for Jalview news.\n"
+ "-nousagestats\tTurn off google analytics tracking for this session.\n"
+ "-sortbytree OR -nosortbytree\tEnable or disable sorting of the given alignment by the given tree\n"
// +
SequenceI rs = sel.getSequenceAt(0);
start = rs.findIndex(start);
end = rs.findIndex(end);
- if (csel != null)
- {
- List<Integer> cs = csel.getSelected();
- // note - the following actually clears cs as well, since
- // csel.getSelected returns a reference. Need to check if we need to
- // have a concurrentModification exception thrown here
- csel.clear();
- for (Integer selectedCol : cs)
- {
- csel.addElement(rs.findIndex(selectedCol));
- }
+ List<Integer> cs = new ArrayList<Integer>(csel.getSelected());
+ csel.clear();
+ for (Integer selectedCol : cs)
+ {
+ csel.addElement(rs.findIndex(selectedCol));
}
}
sel.setStartRes(start);
setEdit(new Edit(Action.CUT, seqs, column + 1, width, al));
}
-
performEdit(0, null);
}
// JBPNote this routine could also mark rows, not just columns.
// need a decent query structure to allow all types of feature searches
BitSet bs = new BitSet();
- int alw, alStart;
- SequenceCollectionI sqcol = (viewport.getSelectionGroup() == null ? viewport
- .getAlignment() : viewport.getSelectionGroup());
- alStart = sqcol.getStartRes();
- alw = sqcol.getEndRes() + 1;
+ SequenceCollectionI sqcol = (viewport.getSelectionGroup() == null || extendCurrent) ? viewport
+ .getAlignment() : viewport.getSelectionGroup();
+
+ int nseq = findColumnsWithFeature(featureType, sqcol, bs);
+
+ ColumnSelection cs = viewport.getColumnSelection();
+ if (cs == null)
+ {
+ cs = new ColumnSelection();
+ }
+
+ if (bs.cardinality() > 0 || invert)
+ {
+ boolean changed = cs.markColumns(bs, sqcol.getStartRes(),
+ sqcol.getEndRes(), invert, extendCurrent, toggle);
+ if (changed)
+ {
+ viewport.setColumnSelection(cs);
+ alignPanel.paintAlignment(true);
+ int columnCount = invert ? (sqcol.getEndRes() - sqcol.getStartRes() + 1)
+ - bs.cardinality()
+ : bs.cardinality();
+ avcg.setStatus(MessageManager.formatMessage(
+ "label.view_controller_toggled_marked",
+ new String[] {
+ toggle ? MessageManager.getString("label.toggled")
+ : MessageManager.getString("label.marked"),
+ String.valueOf(columnCount),
+ invert ? MessageManager
+ .getString("label.not_containing")
+ : MessageManager.getString("label.containing"),
+ featureType, Integer.valueOf(nseq).toString() }));
+ return true;
+ }
+ }
+ else
+ {
+ avcg.setStatus(MessageManager.formatMessage(
+ "label.no_feature_of_type_found",
+ new String[] { featureType }));
+ if (!extendCurrent)
+ {
+ cs.clear();
+ alignPanel.paintAlignment(true);
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Sets a bit in the BitSet for each column (base 0) in the sequence
+ * collection which includes the specified feature type. Returns the number of
+ * sequences which have the feature in the selected range.
+ *
+ * @param featureType
+ * @param sqcol
+ * @param bs
+ * @return
+ */
+ static int findColumnsWithFeature(String featureType,
+ SequenceCollectionI sqcol, BitSet bs)
+ {
+ final int startPosition = sqcol.getStartRes() + 1; // converted to base 1
+ final int endPosition = sqcol.getEndRes() + 1;
List<SequenceI> seqs = sqcol.getSequences();
int nseq = 0;
for (SequenceI sq : seqs)
{
- int tfeat = 0;
+ boolean sequenceHasFeature = false;
if (sq != null)
{
- SequenceFeature[] sf = sq.getSequenceFeatures();
- if (sf != null)
+ SequenceFeature[] sfs = sq.getSequenceFeatures();
+ if (sfs != null)
{
+ /*
+ * check whether the feature start/end (base 1)
+ * overlaps the selection start/end
+ */
int ist = sq.findIndex(sq.getStart());
int iend = sq.findIndex(sq.getEnd());
- if (iend < alStart || ist > alw)
+ if (iend < startPosition || ist > endPosition)
{
// sequence not in region
continue;
}
- for (SequenceFeature sfpos : sf)
+ for (SequenceFeature sf : sfs)
{
- // future functionalty - featureType == null means mark columns
+ // future functionality - featureType == null means mark columns
// containing all displayed features
- if (sfpos != null && (featureType.equals(sfpos.getType())))
+ if (sf != null && (featureType.equals(sf.getType())))
{
- tfeat++;
// optimisation - could consider 'spos,apos' like cursor argument
// - findIndex wastes time by starting from first character and
// counting
- int i = sq.findIndex(sfpos.getBegin());
- int j = sq.findIndex(sfpos.getEnd());
- if (j < alStart || i > alw)
+ int i = sq.findIndex(sf.getBegin());
+ int j = sq.findIndex(sf.getEnd());
+ if (j < startPosition || i > endPosition)
{
// feature is outside selected region
continue;
}
- if (i < alStart)
+ sequenceHasFeature = true;
+ if (i < startPosition)
{
- i = alStart;
+ i = startPosition;
}
if (i < ist)
{
i = ist;
}
- if (j > alw)
+ if (j > endPosition)
{
- j = alw;
+ j = endPosition;
}
for (; i <= j; i++)
{
- bs.set(i - 1);
+ bs.set(i - 1); // convert to base 0
}
}
}
}
- if (tfeat > 0)
+ if (sequenceHasFeature)
{
nseq++;
}
}
}
- ColumnSelection cs = viewport.getColumnSelection();
- if (bs.cardinality() > 0 || invert)
- {
- boolean changed = false;
- if (cs == null)
- {
- cs = new ColumnSelection();
- }
- else
- {
- if (!extendCurrent)
- {
- changed = !cs.isEmpty();
- cs.clear();
- }
- }
- if (invert)
- {
- // invert only in the currently selected sequence region
- for (int i = bs.nextClearBit(alStart), ibs = bs.nextSetBit(alStart); i >= alStart
- && i < (alw);)
- {
- if (ibs < 0 || i < ibs)
- {
- changed = true;
- if (toggle && cs.contains(i))
- {
- cs.removeElement(i++);
- }
- else
- {
- cs.addElement(i++);
- }
- }
- else
- {
- i = bs.nextClearBit(ibs);
- ibs = bs.nextSetBit(i);
- }
- }
- }
- else
- {
- for (int i = bs.nextSetBit(alStart); i >= alStart; i = bs
- .nextSetBit(i + 1))
- {
- changed = true;
- if (toggle && cs.contains(i))
- {
- cs.removeElement(i);
- }
- else
- {
- cs.addElement(i);
- }
- }
- }
- if (changed)
- {
- viewport.setColumnSelection(cs);
- alignPanel.paintAlignment(true);
- avcg.setStatus(MessageManager.formatMessage(
- "label.view_controller_toggled_marked",
- new String[] {
- (toggle ? MessageManager.getString("label.toggled")
- : MessageManager.getString("label.marked")),
- (invert ? (Integer.valueOf((alw - alStart)
- - bs.cardinality()).toString()) : (Integer
- .valueOf(bs.cardinality()).toString())),
- featureType, Integer.valueOf(nseq).toString() }));
- return true;
- }
- }
- else
- {
- avcg.setStatus(MessageManager.formatMessage(
- "label.no_feature_of_type_found",
- new String[] { featureType }));
- if (!extendCurrent && cs != null)
- {
- cs.clear();
- alignPanel.paintAlignment(true);
- }
- }
- return false;
+ return nseq;
}
@Override
import jalview.util.MapList;
import jalview.util.MappingUtils;
+import java.util.AbstractList;
import java.util.ArrayList;
import java.util.List;
/*
* Data bean to hold mappings from one sequence to another
*/
- private class SequenceToSequenceMapping
+ public class SequenceToSequenceMapping
{
private SequenceI fromSeq;
return String.format("From %s %s", fromSeq.getName(),
mapping.toString());
}
+
+ /**
+ * Returns a hashCode derived from the hashcodes of the mappings and fromSeq
+ *
+ * @see SequenceToSequenceMapping#hashCode()
+ */
+ @Override
+ public int hashCode()
+ {
+ return (fromSeq == null ? 0 : fromSeq.hashCode() * 31)
+ + mapping.hashCode();
+ }
+
+ /**
+ * Answers true if the objects hold the same mapping between the same two
+ * sequences
+ *
+ * @see Mapping#equals
+ */
+ @Override
+ public boolean equals(Object obj)
+ {
+ if (!(obj instanceof SequenceToSequenceMapping))
+ {
+ return false;
+ }
+ SequenceToSequenceMapping that = (SequenceToSequenceMapping) obj;
+ if (this.mapping == null)
+ {
+ return that.mapping == null;
+ }
+ // TODO: can simplify by asserting fromSeq is a dataset sequence
+ return (this.fromSeq == that.fromSeq || (this.fromSeq != null
+ && that.fromSeq != null
+ && this.fromSeq.getDatasetSequence() != null && this.fromSeq
+ .getDatasetSequence() == that.fromSeq.getDatasetSequence()))
+ && this.mapping.equals(that.mapping);
+ }
+
+ public SequenceI getFromSeq()
+ {
+ return fromSeq;
+ }
+
+ public Mapping getMapping()
+ {
+ return mapping;
+ }
}
private List<SequenceToSequenceMapping> mappings;
*/
public void addMap(SequenceI dnaseq, SequenceI aaseq, MapList map)
{
+ addMap(dnaseq, aaseq, map, null);
+ }
+
+ /**
+ * Adds a mapping between the dataset sequences for the associated dna and
+ * protein sequence objects
+ *
+ * @param dnaseq
+ * @param aaseq
+ * @param map
+ * @param mapFromId
+ */
+ public void addMap(SequenceI dnaseq, SequenceI aaseq, MapList map,
+ String mapFromId)
+ {
// JBPNote DEBUG! THIS !
// dnaseq.transferAnnotation(aaseq, mp);
// aaseq.transferAnnotation(dnaseq, new Mapping(map.getInverse()));
/*
* if we already hold a mapping between these sequences, just add to it
+ * note that 'adding' a duplicate map does nothing; this protects against
+ * creating duplicate mappings in AlignedCodonFrame
*/
for (SequenceToSequenceMapping ssm : mappings)
{
* otherwise, add a new sequence mapping
*/
Mapping mp = new Mapping(toSeq, map);
+ mp.setMappedFromId(mapFromId);
mappings.add(new SequenceToSequenceMapping(fromSeq, mp));
}
for (SequenceToSequenceMapping ssm : mappings)
{
- if (ssm.mapping.to == protein)
+ if (ssm.mapping.to == protein
+ && ssm.mapping.getMap().getFromRatio() == 3)
{
ml = ssm.mapping.map;
dnaSeq = ssm.fromSeq;
}
/**
- * Returns the first mapping found that is from 'fromSeq' to 'toSeq', or null
- * if none found
+ * Returns the first mapping found that is between 'fromSeq' and 'toSeq', or
+ * null if none found
*
* @param fromSeq
* aligned or dataset sequence
*/
public Mapping getMappingBetween(SequenceI fromSeq, SequenceI toSeq)
{
+ SequenceI dssFrom = fromSeq.getDatasetSequence() == null ? fromSeq
+ : fromSeq.getDatasetSequence();
+ SequenceI dssTo = toSeq.getDatasetSequence() == null ? toSeq : toSeq
+ .getDatasetSequence();
+
for (SequenceToSequenceMapping mapping : mappings)
{
SequenceI from = mapping.fromSeq;
SequenceI to = mapping.mapping.to;
- if ((from == fromSeq || from == fromSeq.getDatasetSequence())
- && (to == toSeq || to == toSeq.getDatasetSequence()))
+ if ((from == dssFrom && to == dssTo)
+ || (from == dssTo && to == dssFrom))
{
return mapping.mapping;
}
}
return null;
}
+
+ /**
+ * Returns a hashcode derived from the list of sequence mappings
+ *
+ * @see SequenceToSequenceMapping#hashCode()
+ * @see AbstractList#hashCode()
+ */
+ @Override
+ public int hashCode()
+ {
+ return this.mappings.hashCode();
+ }
+
+ /**
+ * Two AlignedCodonFrame objects are equal if they hold the same ordered list
+ * of mappings
+ *
+ * @see SequenceToSequenceMapping#
+ */
+ @Override
+ public boolean equals(Object obj)
+ {
+ if (!(obj instanceof AlignedCodonFrame))
+ {
+ return false;
+ }
+ return this.mappings.equals(((AlignedCodonFrame) obj).mappings);
+ }
+
+ public List<SequenceToSequenceMapping> getMappings()
+ {
+ return mappings;
+ }
}
package jalview.datamodel;
import jalview.analysis.AlignmentUtils;
+import jalview.datamodel.AlignedCodonFrame.SequenceToSequenceMapping;
import jalview.io.FastaFile;
import jalview.util.Comparison;
+import jalview.util.LinkedIdentityHashSet;
import jalview.util.MessageManager;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Hashtable;
-import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
*/
public class Alignment implements AlignmentI
{
- protected Alignment dataset;
+ private Alignment dataset;
protected List<SequenceI> sequences;
/*
* Share the same dataset sequence mappings (if any).
*/
- this.setCodonFrames(al.getCodonFrames());
+ if (dataset == null && al.getDataset() == null)
+ {
+ this.setCodonFrames(al.getCodonFrames());
+ }
}
/**
{
if (dataset != null)
{
+
// maintain dataset integrity
- if (snew.getDatasetSequence() != null)
- {
- getDataset().addSequence(snew.getDatasetSequence());
- }
- else
+ SequenceI dsseq = snew.getDatasetSequence();
+ if (dsseq == null)
{
// derive new sequence
SequenceI adding = snew.deriveSequence();
- getDataset().addSequence(adding.getDatasetSequence());
snew = adding;
+ dsseq = snew.getDatasetSequence();
}
+ if (getDataset().findIndex(dsseq) == -1)
+ {
+ getDataset().addSequence(dsseq);
+ }
+
}
if (sequences == null)
{
}
}
- /**
- * Adds a sequence to the alignment. Recalculates maxLength and size.
- *
- * @param snew
- */
@Override
- public void setSequenceAt(int i, SequenceI snew)
+ public SequenceI replaceSequenceAt(int i, SequenceI snew)
{
synchronized (sequences)
{
- deleteSequence(i);
- sequences.set(i, snew);
+ if (sequences.size() > i)
+ {
+ return sequences.set(i, snew);
+
+ }
+ else
+ {
+ sequences.add(snew);
+ hiddenSequences.adjustHeightSequenceAdded();
+ }
+ return null;
}
}
}
@Override
- public void finalize()
+ public void finalize() throws Throwable
{
if (getDataset() != null)
{
getDataset().removeAlignmentRef();
}
+ nullReferences();
+ super.finalize();
+ }
+
+ /**
+ * Defensively nulls out references in case this object is not garbage
+ * collected
+ */
+ void nullReferences()
+ {
dataset = null;
sequences = null;
groups = null;
}
/**
- * decrement the alignmentRefs counter by one and call finalize if it goes to
- * zero.
+ * decrement the alignmentRefs counter by one and null references if it goes
+ * to zero.
+ *
+ * @throws Throwable
*/
- private void removeAlignmentRef()
+ private void removeAlignmentRef() throws Throwable
{
if (--alignmentRefs == 0)
{
- finalize();
+ nullReferences();
}
}
}
@Override
- public void setDataset(Alignment data)
+ public void setDataset(AlignmentI data)
{
if (dataset == null && data == null)
{
}
else if (dataset == null && data != null)
{
- dataset = data;
+ if (!(data instanceof Alignment))
+ {
+ throw new Error(
+ "Implementation Error: jalview.datamodel.Alignment does not yet support other implementations of AlignmentI as its dataset reference");
+ }
+ dataset = (Alignment) data;
for (int i = 0; i < getHeight(); i++)
{
SequenceI currentSeq = getSequenceAt(i);
}
/**
+ * add dataset sequences to seq for currentSeq and any sequences it references
+ */
+ private void resolveAndAddDatasetSeq(SequenceI currentSeq,
+ Set<SequenceI> seqs, boolean createDatasetSequence)
+ {
+ SequenceI alignedSeq = currentSeq;
+ if (currentSeq.getDatasetSequence() != null)
+ {
+ currentSeq = currentSeq.getDatasetSequence();
+ }
+ else
+ {
+ if (createDatasetSequence)
+ {
+ currentSeq = currentSeq.createDatasetSequence();
+ }
+ }
+ if (seqs.contains(currentSeq))
+ {
+ return;
+ }
+ List<SequenceI> toProcess = new ArrayList<SequenceI>();
+ toProcess.add(currentSeq);
+ while (toProcess.size() > 0)
+ {
+ // use a queue ?
+ SequenceI curDs = toProcess.remove(0);
+ if (seqs.contains(curDs))
+ {
+ continue;
+ }
+ seqs.add(curDs);
+ // iterate over database references, making sure we add forward referenced
+ // sequences
+ if (curDs.getDBRefs() != null)
+ {
+ for (DBRefEntry dbr : curDs.getDBRefs())
+ {
+ if (dbr.getMap() != null && dbr.getMap().getTo() != null)
+ {
+ if (dbr.getMap().getTo() == alignedSeq)
+ {
+ /*
+ * update mapping to be to the newly created dataset sequence
+ */
+ dbr.getMap().setTo(currentSeq);
+ }
+ if (dbr.getMap().getTo().getDatasetSequence() != null)
+ {
+ throw new Error(
+ "Implementation error: Map.getTo() for dbref " + dbr
+ + " from " + curDs.getName()
+ + " is not a dataset sequence.");
+ }
+ // we recurse to add all forward references to dataset sequences via
+ // DBRefs/etc
+ toProcess.add(dbr.getMap().getTo());
+ }
+ }
+ }
+ }
+ }
+
+ /**
* Creates a new dataset for this alignment. Can only be done once - if
* dataset is not null this will not be performed.
*/
{
return;
}
- SequenceI[] seqs = new SequenceI[getHeight()];
- SequenceI currentSeq;
+ // try to avoid using SequenceI.equals at this stage, it will be expensive
+ Set<SequenceI> seqs = new LinkedIdentityHashSet<SequenceI>();
+
for (int i = 0; i < getHeight(); i++)
{
- currentSeq = getSequenceAt(i);
- if (currentSeq.getDatasetSequence() != null)
- {
- seqs[i] = currentSeq.getDatasetSequence();
- }
- else
+ SequenceI currentSeq = getSequenceAt(i);
+ resolveAndAddDatasetSeq(currentSeq, seqs, true);
+ }
+
+ // verify all mappings are in dataset
+ for (AlignedCodonFrame cf : codonFrameList)
+ {
+ for (SequenceToSequenceMapping ssm : cf.getMappings())
{
- seqs[i] = currentSeq.createDatasetSequence();
+ if (!seqs.contains(ssm.getFromSeq()))
+ {
+ resolveAndAddDatasetSeq(ssm.getFromSeq(), seqs, false);
+ }
+ if (!seqs.contains(ssm.getMapping().getTo()))
+ {
+ resolveAndAddDatasetSeq(ssm.getMapping().getTo(), seqs, false);
+ }
}
}
-
- dataset = new Alignment(seqs);
+ // finally construct dataset
+ dataset = new Alignment(seqs.toArray(new SequenceI[seqs.size()]));
// move mappings to the dataset alignment
dataset.codonFrameList = this.codonFrameList;
this.codonFrameList = null;
}
}
- /**
- * adds a set of mappings (while ignoring any duplicates)
- */
- @Override
- public void addCodonFrames(Iterable<AlignedCodonFrame> codons)
- {
- if (codons != null)
- {
- Iterator<AlignedCodonFrame> it = codons.iterator();
- while (it.hasNext())
- {
- addCodonFrame(it.next());
- }
- }
- }
-
/*
* (non-Javadoc)
*
@Override
public List<AlignedCodonFrame> getCodonFrames()
{
+ // TODO: Fix this method to fix failing AlignedCodonFrame tests
+ // this behaviour is currently incorrect. method should return codon frames
+ // for just the alignment,
+ // selected from dataset
return dataset != null ? dataset.getCodonFrames() : codonFrameList;
}
@Override
public void append(AlignmentI toappend)
{
- if (toappend == this)
- {
- System.err.println("Self append may cause a deadlock.");
- }
- // TODO test this method for a future 2.5 release
+ // TODO JAL-1270 needs test coverage
// currently tested for use in jalview.gui.SequenceFetcher
boolean samegap = toappend.getGapCharacter() == getGapCharacter();
char oldc = toappend.getGapCharacter();
.getFullAlignment().getSequences() : toappend.getSequences();
if (sqs != null)
{
+ // avoid self append deadlock by
+ List<SequenceI> toappendsq = new ArrayList<SequenceI>();
synchronized (sqs)
{
for (SequenceI addedsq : sqs)
}
}
}
- addSequence(addedsq);
+ toappendsq.add(addedsq);
}
}
+ for (SequenceI addedsq : toappendsq)
+ {
+ addSequence(addedsq);
+ }
}
AlignmentAnnotation[] alan = toappend.getAlignmentAnnotation();
for (int a = 0; alan != null && a < alan.length; a++)
addAnnotation(alan[a]);
}
+ // use add method
getCodonFrames().addAll(toappend.getCodonFrames());
List<SequenceGroup> sg = toappend.getGroups();
* Parameters control whether gaps in exon (mapped) and intron (unmapped)
* regions are preserved. Gaps that connect introns to exons are treated
* conservatively, i.e. only preserved if both intron and exon gaps are
- * preserved.
+ * preserved. TODO: check caveats below where the implementation fails
*
* @param al
+ * - must have same dataset, and sequences in al must have equivalent
+ * dataset sequence and start/end bounds under given mapping
* @param preserveMappedGaps
* if true, gaps within and between mapped codons are preserved
* @param preserveUnmappedGaps
boolean preserveUnmappedGaps)
{
// TODO should this method signature be the one in the interface?
+ // JBPComment - yes - neither flag is used, so should be deleted.
boolean thisIsNucleotide = this.isNucleotide();
boolean thatIsProtein = !al.isNucleotide();
if (!thatIsProtein && !thisIsNucleotide)
{
return AlignmentUtils.alignProteinAsDna(this, al);
}
+ else if (thatIsProtein && thisIsNucleotide)
+ {
+ return AlignmentUtils.alignCdsAsProtein(this, al);
+ }
return AlignmentUtils.alignAs(this, al);
}
import jalview.analysis.SecStrConsensus.SimpleBP;
import jalview.analysis.WUSSParseException;
-import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
+import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
/** Array of annotations placed in the current coordinate system */
public Annotation[] annotations;
- public ArrayList<SimpleBP> bps = null;
+ public List<SimpleBP> bps = null;
/**
* RNA secondary structure contact positions
{
try
{
- _rnasecstr = Rna.GetBasePairs(RNAannot);
- bps = Rna.GetModeleBP(RNAannot);
+ bps = Rna.getModeleBP(RNAannot);
+ _rnasecstr = Rna.getBasePairs(bps);
invalidrnastruc = -1;
} catch (WUSSParseException px)
{
// JBPNote: what does this do ?
public void ConcenStru(CharSequence RNAannot) throws WUSSParseException
{
- bps = Rna.GetModeleBP(RNAannot);
+ bps = Rna.getModeleBP(RNAannot);
}
/**
this(0, annotations.length);
}
- public AnnotCharSequence(int start, int end)
+ AnnotCharSequence(int start, int end)
{
offset = start;
max = end;
if (annotations == null)
{
visible = false; // try to prevent renderer from displaying.
+ invalidrnastruc = -1;
return; // this is a non-annotation row annotation - ie a sequence score.
}
* already
*/
public void remap(SequenceI newref, HashMap<Integer, int[]> mapping,
- int from, int to,
- int idxoffset)
+ int from, int to, int idxoffset)
{
if (mapping != null)
{
this.annotationId = ANNOTATION_ID_PREFIX + Long.toString(nextId());
}
+ /**
+ * Returns the match for the last unmatched opening RNA helix pair symbol
+ * preceding the given column, or '(' if nothing found to match.
+ *
+ * @param column
+ * @return
+ */
+ public String getDefaultRnaHelixSymbol(int column)
+ {
+ String result = "(";
+ if (annotations == null)
+ {
+ return result;
+ }
+
+ /*
+ * for each preceding column, if it contains an open bracket,
+ * count whether it is still unmatched at column, if so return its pair
+ * (likely faster than the fancy alternative using stacks)
+ */
+ for (int col = column - 1; col >= 0; col--)
+ {
+ Annotation annotation = annotations[col];
+ if (annotation == null)
+ {
+ continue;
+ }
+ String displayed = annotation.displayCharacter;
+ if (displayed == null || displayed.length() != 1)
+ {
+ continue;
+ }
+ char symbol = displayed.charAt(0);
+ if (!Rna.isOpeningParenthesis(symbol))
+ {
+ continue;
+ }
+
+ /*
+ * found an opening bracket symbol
+ * count (closing-opening) symbols of this type that follow it,
+ * up to and excluding the target column; if the count is less
+ * than 1, the opening bracket is unmatched, so return its match
+ */
+ String closer = String.valueOf(Rna
+ .getMatchingClosingParenthesis(symbol));
+ String opener = String.valueOf(symbol);
+ int count = 0;
+ for (int j = col + 1; j < column; j++)
+ {
+ if (annotations[j] != null)
+ {
+ String s = annotations[j].displayCharacter;
+ if (closer.equals(s))
+ {
+ count++;
+ }
+ else if (opener.equals(s))
+ {
+ count--;
+ }
+ }
+ }
+ if (count < 1)
+ {
+ return closer;
+ }
+ }
+ return result;
+ }
+
protected static synchronized long nextId()
{
return counter++;
*
* Calculates the maximum width of the alignment, including gaps.
*
- * @return Greatest sequence length within alignment.
+ * @return Greatest sequence length within alignment, or -1 if no sequences
+ * present
*/
@Override
int getWidth();
* Used to set a particular index of the alignment with the given sequence.
*
* @param i
- * Index of sequence to be updated.
+ * Index of sequence to be updated. if i>length, sequence will be
+ * added to end, with no intervening positions.
* @param seq
- * New sequence to be inserted.
+ * New sequence to be inserted. The existing sequence at position i
+ * will be replaced.
+ * @return existing sequence (or null if i>current length)
*/
- void setSequenceAt(int i, SequenceI seq);
+ SequenceI replaceSequenceAt(int i, SequenceI seq);
/**
* Deletes a sequence from the alignment
* @return Alignment containing dataset sequences or null of this is a
* dataset.
*/
- Alignment getDataset();
+ AlignmentI getDataset();
/**
* Set the associated dataset for the alignment, or create one.
* @param dataset
* The dataset alignment or null to construct one.
*/
- void setDataset(Alignment dataset);
+ void setDataset(AlignmentI dataset);
/**
* pads sequences with gaps (to ensure the set looks like an alignment)
void addCodonFrame(AlignedCodonFrame codons);
/**
- * add a set of aligned codons mappings for this alignment, apart from any
- * duplicates which are ignored
- *
- * @param codons
- */
- void addCodonFrames(Iterable<AlignedCodonFrame> codons);
-
- /**
* remove a particular codon frame reference from this alignment
*
* @param codons
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.List;
-import java.util.Vector;
/**
* Transient object compactly representing a 'view' of an alignment - with
*/
private class ScGroup
{
- public Vector seqs;
+ public List<SeqCigar> seqs;
public SequenceGroup sg;
ScGroup()
{
- seqs = new Vector();
+ seqs = new ArrayList<SeqCigar>();
+ }
+
+ /**
+ * @param seq
+ * @return true if seq was not a member before and was added to group
+ */
+ public boolean add(SeqCigar seq)
+ {
+ if (!seq.isMemberOf(this))
+ {
+ seqs.add(seq);
+ seq.setGroupMembership(this);
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ /**
+ *
+ * @param seq
+ * @return true if seq was a member and was removed from group
+ */
+ public boolean remove(SeqCigar seq)
+ {
+ if (seq.removeGroupMembership(this))
+ {
+ seqs.remove(seq);
+ return true;
+ }
+ return false;
+ }
+
+ public int size()
+ {
+ return seqs.size();
}
}
* vector of selected seqCigars. This vector is also referenced by each
* seqCigar contained in it.
*/
- private Vector selected;
+ private ScGroup selected;
/**
* Construct an alignmentView from a live jalview alignment view. Note -
if (selection != null && selection.getSize() > 0)
{
List<SequenceI> sel = selection.getSequences(null);
- this.selected = new Vector();
+ this.selected = new ScGroup();
selseqs = selection
.getSequencesInOrder(alignment, selectedRegionOnly);
}
if (selection != null && selection.getSize() > 0
&& !selectedRegionOnly)
{
- sequences[csi].setGroupMembership(selected);
- selected.addElement(sequences[csi]);
+ selected.add(sequences[csi]);
}
if (seqsets != null)
{
{
if ((seqsets.get(sg)).contains(selseqs[i]))
{
- sequences[csi].setGroupMembership(sgrps[sg]);
sgrps[sg].sg.deleteSequence(selseqs[i], false);
- sgrps[sg].seqs.addElement(sequences[csi]);
+ sgrps[sg].add(sequences[csi]);
if (!addedgps[sg])
{
if (scGroups == null)
if (!seqcigararray.isSeqCigarArray())
{
throw new Error(
- MessageManager
- .getString("error.implementation_error_can_only_make_alignmnet_from_cigararray"));
+ "Implementation Error - can only make an alignment view from a CigarArray of sequences.");
}
// contigs = seqcigararray.applyDeletions();
contigs = seqcigararray.getDeletedRegions();
+ sgr.sg.getEndRes());
for (int s = 0; s < sgr.seqs.size(); s++)
{
- if (!((SeqCigar) sgr.seqs.elementAt(s)).isMemberOf(sgr))
+ // JBPnote this should be a unit test for ScGroup
+ if (!sgr.seqs.get(s).isMemberOf(sgr))
{
- os.println("** WARNING: sequence "
- + ((SeqCigar) sgr.seqs.elementAt(s)).toString()
+ os.println("** WARNING: sequence " + sgr.seqs.get(s).toString()
+ " is not marked as member of group.");
}
}
{
case M:
cursor += range[i];
+ break;
case I:
vcursor += range[i];
break;
/*
* list of selected columns (ordered by selection order, not column order)
*/
- private List<Integer> order = new ArrayList<Integer>();
+ private List<Integer> order;
+
+ /*
+ * an unmodifiable view of the selected columns list
+ */
+ private List<Integer> _uorder;
/**
* bitfield for column selection - allows quick lookup
*/
- private BitSet selected = new BitSet();
+ private BitSet selected;
+
+ /**
+ * Constructor
+ */
+ IntList()
+ {
+ order = new ArrayList<Integer>();
+ _uorder = Collections.unmodifiableList(order);
+ selected = new BitSet();
+ }
+
+ /**
+ * Copy constructor
+ *
+ * @param other
+ */
+ IntList(IntList other)
+ {
+ this();
+ if (other != null)
+ {
+ int j = other.size();
+ for (int i = 0; i < j; i++)
+ {
+ add(other.elementAt(i));
+ }
+ }
+ }
/**
* adds a new column i to the selection - only if i is not already selected
*
* @param i
*/
- public void add(int i)
+ void add(int i)
{
if (!selected.get(i))
{
}
}
- public void clear()
+ void clear()
{
order.clear();
selected.clear();
}
- public void remove(int col)
+ void remove(int col)
{
Integer colInt = new Integer(col);
}
}
- public boolean contains(Integer colInt)
+ boolean contains(Integer colInt)
{
return selected.get(colInt);
}
- public boolean isEmpty()
+ boolean isEmpty()
{
return order.isEmpty();
}
- public List<Integer> getList()
+ /**
+ * Returns a read-only view of the selected columns list
+ *
+ * @return
+ */
+ List<Integer> getList()
{
- return order;
+ return _uorder;
}
- public int size()
+ int size()
{
return order.size();
}
* @param i
* @return
*/
- public int elementAt(int i)
+ int elementAt(int i)
{
return order.get(i);
}
* @param change
* - delta for shift
*/
- public void compensateForEdits(int start, int change)
+ void compensateForEdits(int start, int change)
{
BitSet mask = new BitSet();
for (int i = 0; i < order.size(); i++)
selected.or(mask);
}
- public boolean isSelected(int column)
+ boolean isSelected(int column)
{
return selected.get(column);
}
- public int getMaxColumn()
+ int getMaxColumn()
{
return selected.length() - 1;
}
- public int getMinColumn()
+ int getMinColumn()
{
return selected.get(0) ? 0 : selected.nextSetBit(0);
}
/**
* @return a series of selection intervals along the range
*/
- public List<int[]> getRanges()
+ List<int[]> getRanges()
{
List<int[]> rlist = new ArrayList<int[]>();
if (selected.isEmpty())
}
/**
- * Returns a list of selected columns. The list contains no duplicates but is
- * not necessarily ordered. It also may include columns hidden from the
- * current view
+ * Returns a read-only view of the (possibly empty) list of selected columns
+ * <p>
+ * The list contains no duplicates but is not necessarily ordered. It also may
+ * include columns hidden from the current view. To modify (for example sort)
+ * the list, you should first make a copy.
+ * <p>
+ * The list is not thread-safe: iterating over it could result in
+ * ConcurrentModificationException if it is modified by another thread.
*/
public List<Integer> getSelected()
{
{
if (copy != null)
{
- if (copy.selection != null)
- {
- selection = new IntList();
- for (int i = 0, j = copy.selection.size(); i < j; i++)
- {
- selection.add(copy.selection.elementAt(i));
- }
- }
+ selection = new IntList(copy.selection);
if (copy.hiddenColumns != null)
{
hiddenColumns = new Vector<int[]>(copy.hiddenColumns.size());
SequenceI[] seqs)
{
int i, iSize = seqs.length;
- String selection[] = new String[iSize];
+ String selections[] = new String[iSize];
if (hiddenColumns != null && hiddenColumns.size() > 0)
{
for (i = 0; i < iSize; i++)
visibleSeq.append(seqs[i].getSequence(blockStart, end));
}
- selection[i] = visibleSeq.toString();
+ selections[i] = visibleSeq.toString();
}
}
else
{
for (i = 0; i < iSize; i++)
{
- selection[i] = seqs[i].getSequenceAsString(start, end);
+ selections[i] = seqs[i].getSequenceAsString(start, end);
}
}
- return selection;
+ return selections;
}
/**
*/
public int[] locateVisibleBoundsOfSequence(SequenceI seq)
{
- int fpos=seq.getStart(),lpos= seq.getEnd();
+ int fpos = seq.getStart(), lpos = seq.getEnd();
int start = 0;
-
+
if (hiddenColumns == null || hiddenColumns.size() == 0)
{
int ifpos = seq.findIndex(fpos) - 1, ilpos = seq.findIndex(lpos) - 1;
return true;
}
+ /**
+ * Updates the column selection depending on the parameters, and returns true
+ * if any change was made to the selection
+ *
+ * @param markedColumns
+ * a set identifying marked columns (base 0)
+ * @param startCol
+ * the first column of the range to operate over (base 0)
+ * @param endCol
+ * the last column of the range to operate over (base 0)
+ * @param invert
+ * if true, deselect marked columns and select unmarked
+ * @param extendCurrent
+ * if true, extend rather than replacing the current column selection
+ * @param toggle
+ * if true, toggle the selection state of marked columns
+ *
+ * @return
+ */
+ public boolean markColumns(BitSet markedColumns, int startCol,
+ int endCol, boolean invert, boolean extendCurrent, boolean toggle)
+ {
+ boolean changed = false;
+ if (!extendCurrent && !toggle)
+ {
+ changed = !this.isEmpty();
+ clear();
+ }
+ if (invert)
+ {
+ // invert only in the currently selected sequence region
+ int i = markedColumns.nextClearBit(startCol);
+ int ibs = markedColumns.nextSetBit(startCol);
+ while (i >= startCol && i <= endCol)
+ {
+ if (ibs < 0 || i < ibs)
+ {
+ changed = true;
+ if (toggle && contains(i))
+ {
+ removeElement(i++);
+ }
+ else
+ {
+ addElement(i++);
+ }
+ }
+ else
+ {
+ i = markedColumns.nextClearBit(ibs);
+ ibs = markedColumns.nextSetBit(i);
+ }
+ }
+ }
+ else
+ {
+ int i = markedColumns.nextSetBit(startCol);
+ while (i >= startCol && i <= endCol)
+ {
+ changed = true;
+ if (toggle && contains(i))
+ {
+ removeElement(i);
+ }
+ else
+ {
+ addElement(i);
+ }
+ i = markedColumns.nextSetBit(i + 1);
+ }
+ }
+ return changed;
+ }
+
}
import jalview.api.DBRefEntryI;
+import java.util.Arrays;
+import java.util.List;
+
public class DBRefEntry implements DBRefEntryI
{
String source = "", version = "", accessionId = "";
- private int startRes, endRes;
/**
* maps from associated sequence to the database sequence's coordinate system
*/
}
-
public DBRefEntry(String source, String version, String accessionId)
{
this(source, version, accessionId, null);
String otherAccession = other.getAccessionId();
if ((accessionId == null && otherAccession != null)
|| (accessionId != null && otherAccession == null)
- || (accessionId != null && !accessionId.equalsIgnoreCase(otherAccession)))
+ || (accessionId != null && !accessionId
+ .equalsIgnoreCase(otherAccession)))
{
return false;
}
* otherwise the versions have to match
*/
String otherVersion = other.getVersion();
+
if ((version == null || version.equals("0") || version.endsWith(":0"))
&& otherVersion != null)
{
}
else
{
- if (!version.equalsIgnoreCase(otherVersion))
+ if (version != null
+ && (otherVersion == null || !version
+ .equalsIgnoreCase(otherVersion)))
{
return false;
}
return accessionId;
}
-
@Override
public void setAccessionId(String accessionId)
{
this.accessionId = accessionId;
}
-
@Override
public void setSource(String source)
{
this.source = source;
}
-
@Override
public void setVersion(String version)
{
this.version = version;
}
-
@Override
public Mapping getMap()
{
}
@Override
- public int getStartRes()
- {
- return startRes;
- }
-
- @Override
- public void setStartRes(int startRes)
+ public boolean isPrimaryCandidate()
{
- this.startRes = startRes;
- }
-
- @Override
- public int getEndRes()
- {
- return endRes;
- }
-
- @Override
- public void setEndRes(int endRes)
- {
- this.endRes = endRes;
+ /*
+ * if a map is present, unless it is 1:1 and has no SequenceI mate, it cannot be a primary reference.
+ */
+ if (map != null)
+ {
+ if (map.getTo() != null)
+ {
+ return false;
+ }
+ if (map.getMap().getFromRatio() != map.getMap().getToRatio()
+ || map.getMap().getFromRatio() != 1)
+ {
+ return false;
+ }
+ // check map is between identical single contiguous ranges
+ List<int[]> fromRanges = map.getMap().getFromRanges();
+ List<int[]> toRanges = map.getMap().getToRanges();
+ if (fromRanges.size() != 1 || toRanges.size() != 1)
+ {
+ return false;
+ }
+ if (fromRanges.get(0)[0] != toRanges.get(0)[0]
+ || fromRanges.get(0)[1] != toRanges.get(0)[1])
+ {
+ return false;
+ }
+ }
+ if (version == null)
+ {
+ // no version string implies the reference has not been verified at all.
+ return false;
+ }
+ // tricky - this test really needs to search the sequence's set of dbrefs to
+ // see if there is a primary reference that derived this reference.
+ String ucv = version.toUpperCase();
+ for (String primsrc : Arrays.asList(DBRefSource.allSources()))
+ {
+ if (ucv.startsWith(primsrc.toUpperCase()))
+ {
+ // by convention, many secondary references inherit the primary
+ // reference's
+ // source string as a prefix for any version information from the
+ // secondary reference.
+ return false;
+ }
+ }
+ return true;
}
}
*/
package jalview.datamodel;
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.List;
+
/**
* Defines internal constants for unambiguous annotation of DbRefEntry source
* strings and describing the data retrieved from external database sources (see
- * jalview.ws.DbSourcProxy)
+ * jalview.ws.DbSourcProxy) <br/>
+ * TODO: replace with ontology to allow recognition of particular attributes
+ * (e.g. protein coding, alignment (ortholog db, paralog db, domain db),
+ * genomic, transcriptomic, 3D structure providing (PDB, MODBASE, etc) ..).
*
* @author JimP
*
/**
* UNIPROT Accession Number
*/
- public static String UNIPROT = "UNIPROT";
+ public static final String UNIPROT = "UNIPROT";
/**
* UNIPROT Entry Name
*/
- public static String UP_NAME = "UNIPROT_NAME".toUpperCase();
+ public static final String UP_NAME = "UNIPROT_NAME".toUpperCase();
/**
* Uniprot Knowledgebase/TrEMBL as served from EMBL protein products.
/**
* PDB Entry Code
*/
- public static String PDB = "PDB";
-
- /**
- * mmCIF Entry Code
- */
- public static String MMCIF = "mmCIF";
+ public static final String PDB = "PDB";
/**
* EMBL ID
*/
- public static String EMBL = "EMBL";
+ public static final String EMBL = "EMBL";
/**
* EMBLCDS ID
*/
- public static String EMBLCDS = "EMBLCDS";
+ public static final String EMBLCDS = "EMBLCDS";
/**
* PFAM ID
*/
- public static String PFAM = "PFAM";
+ public static final String PFAM = "PFAM";
/**
* RFAM ID
*/
- public static String RFAM = "RFAM";
+ public static final String RFAM = "RFAM";
/**
* GeneDB ID
public static final String[] CODINGDBS = { EMBLCDS, GENEDB, ENSEMBL };
- public static final String[] PROTEINDBS = { UNIPROT, PDB, UNIPROTKB,
+ public static final String[] PROTEINDBS = { UNIPROT, UNIPROTKB,
EMBLCDSProduct, ENSEMBL }; // Ensembl ENSP* entries are protein
+
+ public static String[] allSources()
+ {
+ List<String> src = new ArrayList<String>();
+ for (Field f : DBRefSource.class.getFields())
+ {
+ if (String.class.equals(f.getType()))
+ {
+ try
+ {
+ src.add((String) f.get(null));
+ } catch (Exception x)
+ {
+ x.printStackTrace();
+ }
+ }
+ }
+ return src.toArray(new String[0]);
+ }
}
* makes a copy of the alignment with hidden sequences included. Using the
* copy for anything other than simple output is not recommended. Note - this
* method DOES NOT USE THE AlignmentI COPY CONSTRUCTOR!
+ *
* @return
*/
public AlignmentI getFullAlignment()
*/
package jalview.datamodel;
+import jalview.util.Comparison;
import jalview.util.MapList;
import java.util.Iterator;
int truePos = sequencePos - (start - 1);
while (alignedBases < truePos && alignedColumn < alignedSeq.length)
{
- if (alignedSeq[alignedColumn++] != gap)
+ char c = alignedSeq[alignedColumn++];
+ if (c != gap && !Comparison.isGap(c))
{
alignedBases++;
}
}
- /**
+ /*
* Contains the start-end pairs mapping from the associated sequence to the
* sequence in the database coordinate system. It also takes care of step
* difference between coordinate systems.
*/
MapList map = null;
- /**
+ /*
* The sequence that map maps the associated sequence to (if any).
*/
SequenceI to = null;
+ /*
+ * optional sequence id for the 'from' ranges
+ */
+ private String mappedFromId;
+
public Mapping(MapList map)
{
super();
map = new MapList(map2.map);
}
to = map2.to;
+ mappedFromId = map2.mappedFromId;
}
}
/**
* Equals that compares both the to references and MapList mappings.
*
- * @param other
+ * @param o
* @return
+ * @see MapList#equals
*/
@Override
public boolean equals(Object o)
{
- // TODO should override Object.hashCode() to ensure that equal objects have
- // equal hashcodes
if (o == null || !(o instanceof Mapping))
{
return false;
}
/**
+ * Returns a hashCode made from the sequence and maplist
+ */
+ @Override
+ public int hashCode()
+ {
+ int hashCode = (this.to == null ? 1 : this.to.hashCode());
+ if (this.map != null)
+ {
+ hashCode = hashCode * 31 + this.map.hashCode();
+ }
+
+ return hashCode;
+ }
+
+ /**
* get the 'initial' position in the associated sequence for a position in the
* mapped reference frame
*
: this.to.getName());
}
+ /**
+ * Returns the identifier for the 'from' range sequence, or null if not set
+ *
+ * @return
+ */
+ public String getMappedFromId()
+ {
+ return mappedFromId;
+ }
+
+ /**
+ * Sets the identifier for the 'from' range sequence
+ */
+ public void setMappedFromId(String mappedFromId)
+ {
+ this.mappedFromId = mappedFromId;
+ }
+
}
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
package jalview.datamodel;
/**
*/
package jalview.datamodel;
+import jalview.util.CaseInsensitiveString;
+
+import java.util.Collections;
+import java.util.Enumeration;
import java.util.Hashtable;
public class PDBEntry
{
+
+ /**
+ * constant for storing chain code in properties table
+ */
+ private static final String CHAIN_ID = "chain_code";
+
+ private Hashtable<String, Object> properties;
+
+ private static final int PDB_ID_LENGTH = 4;
+
private String file;
private String type;
private String id;
- private String chainCode;
-
public enum Type
{
- PDB, MMCIF, FILE
+ PDB, MMCIF, FILE;
+ /**
+ * case insensitive matching for Type enum
+ *
+ * @param value
+ * @return
+ */
+ public static Type getType(String value)
+ {
+ for (Type t : Type.values())
+ {
+ if (t.toString().equalsIgnoreCase(value))
+ {
+ return t;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * case insensitive equivalence for strings resolving to PDBEntry type
+ *
+ * @param t
+ * @return
+ */
+ public boolean matches(String t)
+ {
+ return (this.toString().equalsIgnoreCase(t));
+ }
}
- Hashtable properties;
- /*
- * (non-Javadoc)
- *
- * @see java.lang.Object#equals(java.lang.Object)
+ /**
+ * Answers true if obj is a PDBEntry with the same id and chain code (both
+ * ignoring case), file, type and properties
*/
@Override
public boolean equals(Object obj)
return true;
}
PDBEntry o = (PDBEntry) obj;
- return (type == o.type || (type != null && o.type != null && o.type
- .equals(type)))
- && (id == o.id || (id != null && o.id != null && o.id
- .equalsIgnoreCase(id)))
- && (chainCode == o.chainCode || (chainCode != null
- && o.chainCode != null && o.chainCode
- .equalsIgnoreCase(chainCode)))
- && (properties == o.properties || (properties != null
- && o.properties != null && properties
- .equals(o.properties)));
+ /*
+ * note that chain code is stored as a property wrapped by a
+ * CaseInsensitiveString, so we are in effect doing a
+ * case-insensitive comparison of chain codes
+ */
+ boolean idMatches = id == o.id
+ || (id != null && id.equalsIgnoreCase(o.id));
+ boolean fileMatches = file == o.file
+ || (file != null && file.equals(o.file));
+ boolean typeMatches = type == o.type
+ || (type != null && type.equals(o.type));
+ if (idMatches && fileMatches && typeMatches)
+ {
+ return properties == o.properties
+ || (properties != null && properties.equals(o.properties));
+ }
+ return false;
}
/**
public PDBEntry(String pdbId, String chain, PDBEntry.Type type,
String filePath)
{
+ init(pdbId, chain, type, filePath);
+ }
+
+ /**
+ * @param pdbId
+ * @param chain
+ * @param entryType
+ * @param filePath
+ */
+ void init(String pdbId, String chain, PDBEntry.Type entryType, String filePath)
+ {
this.id = pdbId;
- this.chainCode = chain;
- this.type = type == null ? null : type.toString();
+ this.type = entryType == null ? null : entryType.toString();
this.file = filePath;
+ setChainCode(chain);
}
/**
file = entry.file;
type = entry.type;
id = entry.id;
- chainCode = entry.chainCode;
if (entry.properties != null)
{
- properties = (Hashtable) entry.properties.clone();
+ properties = (Hashtable<String, Object>) entry.properties.clone();
+ }
+ }
+
+ /**
+ * Make a PDBEntry from a DBRefEntry. The accession code is used for the PDB
+ * id, but if it is 5 characters in length, the last character is removed and
+ * set as the chain code instead.
+ *
+ * @param dbr
+ */
+ public PDBEntry(DBRefEntry dbr)
+ {
+ if (!DBRefSource.PDB.equals(dbr.getSource()))
+ {
+ throw new IllegalArgumentException("Invalid source: "
+ + dbr.getSource());
+ }
+
+ String pdbId = dbr.getAccessionId();
+ String chainCode = null;
+ if (pdbId.length() == PDB_ID_LENGTH + 1)
+ {
+ char chain = pdbId.charAt(PDB_ID_LENGTH);
+ if (('a' <= chain && chain <= 'z') || ('A' <= chain && chain <= 'Z'))
+ {
+ pdbId = pdbId.substring(0, PDB_ID_LENGTH);
+ chainCode = String.valueOf(chain);
+ }
}
+ init(pdbId, chainCode, null, null);
}
- public void setFile(String file)
+ public void setFile(String f)
{
- this.file = file;
+ this.file = f;
}
public String getFile()
return id;
}
- public void setProperty(Hashtable property)
+ public void setProperty(String key, Object value)
{
- this.properties = property;
+ if (this.properties == null)
+ {
+ this.properties = new Hashtable<String, Object>();
+ }
+ properties.put(key, value);
}
- public Hashtable getProperty()
+ public Object getProperty(String key)
{
- return properties;
+ return properties == null ? null : properties.get(key);
+ }
+
+ /**
+ * Returns an enumeration of the keys of this object's properties (or an empty
+ * enumeration if it has no properties)
+ *
+ * @return
+ */
+ public Enumeration<String> getProperties()
+ {
+ if (properties == null)
+ {
+ return Collections.emptyEnumeration();
+ }
+ return properties.keys();
}
+ /**
+ *
+ * @return null or a string for associated chain IDs
+ */
public String getChainCode()
{
- return chainCode;
+ return (properties == null || properties.get(CHAIN_ID) == null) ? null
+ : properties.get(CHAIN_ID).toString();
}
+ /**
+ * Sets a non-case-sensitive property for the given chain code. Two PDBEntry
+ * objects which differ only in the case of their chain code are considered
+ * equal. This avoids duplication of objects in lists of PDB ids.
+ *
+ * @param chainCode
+ */
public void setChainCode(String chainCode)
{
- this.chainCode = chainCode;
+ if (chainCode == null)
+ {
+ deleteProperty(CHAIN_ID);
+ }
+ else
+ {
+ setProperty(CHAIN_ID, new CaseInsensitiveString(chainCode));
+ }
+ }
+
+ /**
+ * Deletes the property with the given key, and returns the deleted value (or
+ * null)
+ */
+ Object deleteProperty(String key)
+ {
+ Object result = null;
+ if (properties != null)
+ {
+ result = properties.remove(key);
+ }
+ return result;
}
@Override
{
return id;
}
+
+ /**
+ * Getter provided for Castor binding only. Application code should call
+ * getProperty() or getProperties() instead.
+ *
+ * @deprecated
+ * @see #getProperty(String)
+ * @see #getProperties()
+ * @see jalview.ws.dbsources.Uniprot#getUniprotEntries
+ * @return
+ */
+ @Deprecated
+ public Hashtable<String, Object> getProps()
+ {
+ return properties;
+ }
+
+ /**
+ * Setter provided for Castor binding only. Application code should call
+ * setProperty() instead.
+ *
+ * @deprecated
+ * @return
+ */
+ @Deprecated
+ public void setProps(Hashtable<String, Object> props)
+ {
+ properties = props;
+ }
+
+ /**
+ * Answers true if this object is either equivalent to, or can be 'improved'
+ * by, the given entry.
+ * <p>
+ * If newEntry has the same id (ignoring case), and doesn't have a conflicting
+ * file spec or chain code, then update this entry from its file and/or chain
+ * code.
+ *
+ * @param newEntry
+ * @return true if modifications were made
+ */
+ public boolean updateFrom(PDBEntry newEntry)
+ {
+ if (this.equals(newEntry))
+ {
+ return true;
+ }
+
+ String newId = newEntry.getId();
+ if (newId == null || getId() == null)
+ {
+ return false; // shouldn't happen
+ }
+
+ /*
+ * id has to match (ignoring case)
+ */
+ if (!getId().equalsIgnoreCase(newId))
+ {
+ return false;
+ }
+
+ /*
+ * Don't update if associated with different structure files
+ */
+ String newFile = newEntry.getFile();
+ if (newFile != null && getFile() != null && !newFile.equals(getFile()))
+ {
+ return false;
+ }
+
+ /*
+ * Don't update if associated with different chains (ignoring case)
+ */
+ String newChain = newEntry.getChainCode();
+ if (newChain != null && newChain.length() > 0 && getChainCode() != null
+ && getChainCode().length() > 0
+ && !getChainCode().equalsIgnoreCase(newChain))
+ {
+ return false;
+ }
+
+ /*
+ * set file path if not already set
+ */
+ String newType = newEntry.getType();
+ if (getFile() == null && newFile != null)
+ {
+ setFile(newFile);
+ setType(newType);
+ }
+
+ /*
+ * set file type if new entry has it and we don't
+ * (for the case where file was not updated)
+ */
+ if (getType() == null && newType != null)
+ {
+ setType(newType);
+ }
+
+ /*
+ * set chain if not already set (we excluded differing
+ * chains earlier) (ignoring case change only)
+ */
+ if (newChain != null && newChain.length() > 0
+ && !newChain.equalsIgnoreCase(getChainCode()))
+ {
+ setChainCode(newChain);
+ }
+
+ /*
+ * copy any new or modified properties
+ */
+ Enumeration<String> newProps = newEntry.getProperties();
+ while (newProps.hasMoreElements())
+ {
+ /*
+ * copy properties unless value matches; this defends against changing
+ * the case of chain_code which is wrapped in a CaseInsensitiveString
+ */
+ String key = newProps.nextElement();
+ Object value = newEntry.getProperty(key);
+ if (!value.equals(getProperty(key)))
+ {
+ setProperty(key, value);
+ }
+ }
+ return true;
+ }
}
import jalview.analysis.AlignSeq;
import jalview.api.DBRefEntryI;
+import jalview.util.Comparison;
+import jalview.util.DBRefUtils;
+import jalview.util.MapList;
import jalview.util.StringUtils;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collections;
import java.util.Enumeration;
import java.util.List;
import java.util.Vector;
String vamsasId;
- DBRefEntryI sourceDBRef;
-
DBRefEntry[] dbrefs;
RNA rna;
{
char[] oseq = seq.getSequence();
initSeqAndName(seq.getName(), Arrays.copyOf(oseq, oseq.length),
- seq.getStart(),
- seq.getEnd());
+ seq.getStart(), seq.getEnd());
}
description = seq.getDescription();
- sourceDBRef = seq.getSourceDBRef() == null ? null : new DBRefEntry(
- seq.getSourceDBRef());
if (seq != datasetSequence)
{
setDatasetSequence(seq.getDatasetSequence());
}
}
-
@Override
public void setSequenceFeatures(SequenceFeature[] features)
{
}
else
{
- System.err
- .println("Warning: JAL-2046 side effect ? Possible implementation error: overwriting dataset sequence features by setting sequence features on alignment");
+ if (datasetSequence.getSequenceFeatures() != features
+ && datasetSequence.getSequenceFeatures() != null
+ && datasetSequence.getSequenceFeatures().length > 0)
+ {
+ new Exception(
+ "Warning: JAL-2046 side effect ? Possible implementation error: overwriting dataset sequence features by setting sequence features on alignment")
+ .printStackTrace();
+ }
datasetSequence.setSequenceFeatures(features);
}
}
@Override
public synchronized void addSequenceFeature(SequenceFeature sf)
{
- if (sequenceFeatures==null && datasetSequence != null)
+ if (sequenceFeatures == null && datasetSequence != null)
{
datasetSequence.addSequenceFeature(sf);
return;
{
if (sequenceFeatures == null)
{
- if (datasetSequence!=null) {
- datasetSequence.deleteFeature(sf);
+ if (datasetSequence != null)
+ {
+ datasetSequence.deleteFeature(sf);
}
return;
}
}
@Override
- public void addPDBId(PDBEntry entry)
+ public boolean addPDBId(PDBEntry entry)
{
if (pdbIds == null)
{
pdbIds = new Vector<PDBEntry>();
+ pdbIds.add(entry);
+ return true;
}
- if (pdbIds.contains(entry))
- {
- updatePDBEntry(pdbIds.get(pdbIds.indexOf(entry)), entry);
- }
- else
- {
- pdbIds.addElement(entry);
- }
- }
- private static void updatePDBEntry(PDBEntry oldEntry, PDBEntry newEntry)
- {
- if (newEntry.getFile() != null)
+ for (PDBEntry pdbe : pdbIds)
{
- oldEntry.setFile(newEntry.getFile());
+ if (pdbe.updateFrom(entry))
+ {
+ return false;
+ }
}
+ pdbIds.addElement(entry);
+ return true;
}
/**
@Override
public void setDBRefs(DBRefEntry[] dbref)
{
+ if (dbrefs == null && datasetSequence != null
+ && this != datasetSequence)
+ {
+ datasetSequence.setDBRefs(dbref);
+ return;
+ }
dbrefs = dbref;
+ if (dbrefs != null)
+ {
+ DBRefUtils.ensurePrimaries(this);
+ }
}
@Override
@Override
public void addDBRef(DBRefEntry entry)
{
- // TODO add to dataset sequence instead if there is one?
+ if (datasetSequence != null)
+ {
+ datasetSequence.addDBRef(entry);
+ return;
+ }
+
if (dbrefs == null)
{
dbrefs = new DBRefEntry[0];
temp[temp.length - 1] = entry;
dbrefs = temp;
+
+ DBRefUtils.ensurePrimaries(this);
}
@Override
public void setDatasetSequence(SequenceI seq)
{
- // TODO check for circular reference before setting?
+ if (seq == this)
+ {
+ throw new IllegalArgumentException(
+ "Implementation Error: self reference passed to SequenceI.setDatasetSequence");
+ }
+ if (seq != null && seq.getDatasetSequence() != null)
+ {
+ throw new IllegalArgumentException(
+ "Implementation error: cascading dataset sequences are not allowed.");
+ }
datasetSequence = seq;
}
@Override
public SequenceI deriveSequence()
{
- Sequence seq=null;
+ Sequence seq = null;
if (datasetSequence == null)
{
if (isValidDatasetSequence())
else
{
// Create a new, valid dataset sequence
- createDatasetSequence();
+ createDatasetSequence();
}
}
return new Sequence(this);
}
+ private boolean _isNa;
+
+ private long _seqhash = 0;
+
+ /**
+ * Answers false if the sequence is more than 85% nucleotide (ACGTU), else
+ * true
+ */
+ @Override
+ public boolean isProtein()
+ {
+ if (datasetSequence != null)
+ {
+ return datasetSequence.isProtein();
+ }
+ if (_seqhash != sequence.hashCode())
+ {
+ _seqhash = sequence.hashCode();
+ _isNa = Comparison.isNucleotide(this);
+ }
+ return !_isNa;
+ };
+
/*
* (non-Javadoc)
*
dsseq.setDescription(description);
// move features and database references onto dataset sequence
dsseq.sequenceFeatures = sequenceFeatures;
- sequenceFeatures=null;
+ sequenceFeatures = null;
dsseq.dbrefs = dbrefs;
- dbrefs=null;
+ dbrefs = null;
// TODO: search and replace any references to this sequence with
// references to the dataset sequence in Mappings on dbref
dsseq.pdbIds = pdbIds;
{
return false;
}
- Vector newpdb = new Vector();
- for (int i = 0; i < dbrefs.length; i++)
- {
- if (DBRefSource.PDB.equals(dbrefs[i].getSource()))
- {
- PDBEntry pdbe = new PDBEntry();
- pdbe.setId(dbrefs[i].getAccessionId());
- if (pdbIds == null || pdbIds.size() == 0)
- {
- newpdb.addElement(pdbe);
- }
- else
- {
- Enumeration en = pdbIds.elements();
- boolean matched = false;
- while (!matched && en.hasMoreElements())
- {
- PDBEntry anentry = (PDBEntry) en.nextElement();
- if (anentry.getId().equals(pdbe.getId()))
- {
- matched = true;
- }
- }
- if (!matched)
- {
- newpdb.addElement(pdbe);
- }
- }
- }
- }
- if (newpdb.size() > 0)
+ boolean added = false;
+ for (DBRefEntry dbr : dbrefs)
{
- Enumeration en = newpdb.elements();
- while (en.hasMoreElements())
+ if (DBRefSource.PDB.equals(dbr.getSource()))
{
- addPDBId((PDBEntry) en.nextElement());
+ /*
+ * 'Add' any PDB dbrefs as a PDBEntry - add is only performed if the
+ * PDB id is not already present in a 'matching' PDBEntry
+ * Constructor parses out a chain code if appended to the accession id
+ * (a fudge used to 'store' the chain code in the DBRef)
+ */
+ PDBEntry pdbe = new PDBEntry(dbr);
+ added |= addPDBId(pdbe);
}
- return true;
}
- return false;
+ return added;
}
@Override
@Override
public PDBEntry getPDBEntry(String pdbIdStr)
{
- if (getDatasetSequence() == null
- || getDatasetSequence().getAllPDBEntries() == null)
+ if (getDatasetSequence() != null)
+ {
+ return getDatasetSequence().getPDBEntry(pdbIdStr);
+ }
+ if (pdbIds == null)
{
return null;
}
- List<PDBEntry> entries = getDatasetSequence().getAllPDBEntries();
+ List<PDBEntry> entries = getAllPDBEntries();
for (PDBEntry entry : entries)
{
if (entry.getId().equalsIgnoreCase(pdbIdStr))
}
@Override
- public void setSourceDBRef(DBRefEntryI dbRef)
- {
- this.sourceDBRef = dbRef;
- }
-
- @Override
- public DBRefEntryI getSourceDBRef()
+ public List<DBRefEntry> getPrimaryDBRefs()
{
- return this.sourceDBRef;
+ if (datasetSequence != null)
+ {
+ return datasetSequence.getPrimaryDBRefs();
+ }
+ if (dbrefs == null || dbrefs.length == 0)
+ {
+ return Collections.emptyList();
+ }
+ synchronized (dbrefs)
+ {
+ List<DBRefEntry> primaries = new ArrayList<DBRefEntry>();
+ DBRefEntry[] tmp = new DBRefEntry[1];
+ for (DBRefEntry ref : dbrefs)
+ {
+ if (!ref.isPrimaryCandidate())
+ {
+ continue;
+ }
+ if (ref.hasMap())
+ {
+ MapList mp = ref.getMap().getMap();
+ if (mp.getFromLowest() > start || mp.getFromHighest() < end)
+ {
+ // map only involves a subsequence, so cannot be primary
+ continue;
+ }
+ }
+ // whilst it looks like it is a primary ref, we also sanity check type
+ if (DBRefUtils.getCanonicalName(DBRefSource.PDB).equals(
+ DBRefUtils.getCanonicalName(ref.getSource())))
+ {
+ // PDB dbrefs imply there should be a PDBEntry associated
+ // TODO: tighten PDB dbrefs
+ // formally imply Jalview has actually downloaded and
+ // parsed the pdb file. That means there should be a cached file
+ // handle on the PDBEntry, and a real mapping between sequence and
+ // extracted sequence from PDB file
+ PDBEntry pdbentry = getPDBEntry(ref.getAccessionId());
+ if (pdbentry != null && pdbentry.getFile() != null)
+ {
+ primaries.add(ref);
+ }
+ continue;
+ }
+ // check standard protein or dna sources
+ tmp[0] = ref;
+ DBRefEntry[] res = DBRefUtils.selectDbRefs(!isProtein(), tmp);
+ if (res != null && res[0] == tmp[0])
+ {
+ primaries.add(ref);
+ continue;
+ }
+ }
+ return primaries;
+ }
}
}
import jalview.analysis.AAFrequency;
import jalview.analysis.Conservation;
+import jalview.analysis.Profile;
import jalview.schemes.ColourSchemeI;
-import jalview.schemes.ResidueProperties;
import java.awt.Color;
import java.util.ArrayList;
-import java.util.Hashtable;
import java.util.List;
import java.util.Map;
-import java.util.Vector;
/**
* Collects a set contiguous ranges on a set of sequences
Conservation conserve;
- Vector aaFrequency;
-
boolean displayBoxes = true;
boolean displayText = true;
}
/**
- * calculate residue conservation for group - but only if necessary.
+ * calculate residue conservation and colourschemes for group - but only if
+ * necessary. returns true if the calculation resulted in a visible change to
+ * group
+ */
+ public boolean recalcConservation()
+ {
+ return recalcConservation(false);
+ }
+
+ /**
+ * calculate residue conservation for group - but only if necessary. returns
+ * true if the calculation resulted in a visible change to group
+ *
+ * @param defer
+ * when set, colourschemes for this group are not refreshed after
+ * recalculation
*/
- public void recalcConservation()
+ public boolean recalcConservation(boolean defer)
{
if (cs == null && consensus == null && conservation == null)
{
- return;
+ return false;
}
+ // TODO: try harder to detect changes in state in order to minimise
+ // recalculation effort
+ boolean upd = false;
try
{
- Hashtable cnsns[] = AAFrequency.calculate(sequences, startRes,
+ Profile[] cnsns = AAFrequency.calculate(sequences, startRes,
endRes + 1, showSequenceLogo);
if (consensus != null)
{
_updateConsensusRow(cnsns, sequences.size());
+ upd = true;
}
if (cs != null)
{
cs.setConsensus(cnsns);
+ upd = true;
}
if ((conservation != null)
|| (cs != null && cs.conservationApplied()))
{
- Conservation c = new Conservation(groupName,
- ResidueProperties.propHash, 3, sequences, startRes,
- endRes + 1);
+ Conservation c = new Conservation(groupName, 3, sequences,
+ startRes, endRes + 1);
c.calculate();
c.verdict(false, consPercGaps);
if (conservation != null)
cs.setConservation(c);
}
}
+ // eager update - will cause a refresh of overview regardless
+ upd = true;
}
- if (cs != null)
+ if (cs != null && !defer)
{
+ // TODO: JAL-2034 should cs.alignmentChanged modify return state
cs.alignmentChanged(context != null ? context : this, null);
+ return true;
+ }
+ else
+ {
+ return upd;
}
} catch (java.lang.OutOfMemoryError err)
{
// TODO: catch OOM
System.out.println("Out of memory loading groups: " + err);
}
-
+ return upd;
}
private void _updateConservationRow(Conservation c)
c.completeAnnotations(conservation, null, startRes, endRes + 1);
}
- public Hashtable[] consensusData = null;
+ public Profile[] consensusData = null;
- private void _updateConsensusRow(Hashtable[] cnsns, long nseq)
+ private void _updateConsensusRow(Profile[] cnsns, long nseq)
{
if (consensus == null)
{
*/
package jalview.datamodel;
-import jalview.api.DBRefEntryI;
-
import java.util.List;
import java.util.Vector;
public int[] findPositionMap();
/**
+ * Answers true if the sequence is composed of amino acid characters. Note
+ * that implementations may use heuristic methods which are not guaranteed to
+ * give the biologically 'right' answer.
+ *
+ * @return
+ */
+ public boolean isProtein();
+
+ /**
* Delete a range of aligned sequence columns, creating a new dataset sequence
* if necessary and adjusting start and end positions accordingly.
*
* DOCUMENT ME!
*
* @param i
- * DOCUMENT ME!
+ * alignment column number
* @param c
- * DOCUMENT ME!
+ * character to insert
*/
public void insertCharAt(int i, char c);
/**
- * DOCUMENT ME!
+ * insert given character at alignment column position
*
* @param position
- * DOCUMENT ME!
+ * alignment column number
+ * @param count
+ * length of insert
* @param ch
- * DOCUMENT ME!
+ * character to insert
*/
public void insertCharAt(int position, int count, char ch);
public Vector<PDBEntry> getAllPDBEntries();
/**
- * add entry to the vector of PDBIds, if it isn't in the list already
+ * Adds the entry to the *normalised* list of PDBIds.
+ *
+ * If a PDBEntry is passed with the same entry.getID() string as one already
+ * in the list, or one is added that appears to be the same but has a chain ID
+ * appended, then the existing PDBEntry will be updated with the new
+ * attributes instead, unless the entries have distinct chain codes or
+ * associated structure files.
*
* @param entry
+ * @return true if the entry was added, false if updated
*/
- public void addPDBId(PDBEntry entry);
+ public boolean addPDBId(PDBEntry entry);
/**
* update the list of PDBEntrys to include any DBRefEntrys citing structural
public void setVamsasId(String id);
+ /**
+ * set the array of Database references for the sequence.
+ *
+ * @param dbs
+ * @deprecated - use is discouraged since side-effects may occur if DBRefEntry
+ * set are not normalised.
+ */
+ @Deprecated
public void setDBRefs(DBRefEntry[] dbs);
public DBRefEntry[] getDBRefs();
public PDBEntry getPDBEntry(String pdbId);
/**
- * Set the distinct source database, and accession number from which a
- * sequence and its start-end data were derived from. This is very important
- * for SIFTS mappings and must be set prior to performing SIFTS mapping.
+ * Get all primary database/accessions for this sequence's data. These
+ * DBRefEntry are expected to resolve to a valid record in the associated
+ * external database, either directly or via a provided 1:1 Mapping.
*
- * @param dbRef
- * the source dbRef for the sequence
- */
- public void setSourceDBRef(DBRefEntryI dbRef);
-
- /**
- * Get the distinct source database, and accession number from which a
- * sequence and its start-end data were derived from.
- *
- * @return
+ * @return just the primary references (if any) for this sequence, or an empty
+ * list
*/
- public DBRefEntryI getSourceDBRef();
+ public List<DBRefEntry> getPrimaryDBRefs();
}
* Data model for one entry returned from an EMBL query, as marshalled by a
* Castor binding file
*
- * For example:
- * http://www.ebi.ac.uk/Tools/dbfetch/dbfetch?db=ena_sequence&id=J03321
- * &format=emblxml
+ * For example: http://www.ebi.ac.uk/ena/data/view/J03321&display=xml
*
* @see embl_mapping.xml
*/
*/
public SequenceI getSequence(String sourceDb, List<SequenceI> peptides)
{
- SequenceI dna = new Sequence(sourceDb + "|" + accession,
- sequence.getSequence());
+ SequenceI dna = makeSequence(sourceDb);
+ if (dna == null)
+ {
+ return null;
+ }
dna.setDescription(description);
DBRefEntry retrievedref = new DBRefEntry(sourceDb,
getSequenceVersion(), accession);
retrievedref.setMap(new Mapping(null, new int[] { 1, dna.getLength() },
new int[] { 1, dna.getLength() }, 1, 1));
+ /*
+ * transform EMBL Database refs to canonical form
+ */
if (dbRefs != null)
{
for (DBRefEntry dbref : dbRefs)
{
+ dbref.setSource(DBRefUtils.getCanonicalName(dbref.getSource()));
dna.addDBRef(dbref);
}
}
{
for (EmblFeature feature : features)
{
- if (feature.dbRefs != null)
- {
- for (DBRefEntry dbref : feature.dbRefs)
- {
- dna.addDBRef(dbref);
- }
- }
if (FeatureProperties.isCodingFeature(sourceDb, feature.getName()))
{
parseCodingFeature(feature, sourceDb, dna, peptides, matcher);
}
/**
+ * @param sourceDb
+ * @return
+ */
+ SequenceI makeSequence(String sourceDb)
+ {
+ if (sequence == null)
+ {
+ System.err.println("No sequence was returned for ENA accession "
+ + accession);
+ return null;
+ }
+ SequenceI dna = new Sequence(sourceDb + "|" + accession,
+ sequence.getSequence());
+ return dna;
+ }
+
+ /**
* Extracts coding region and product from a CDS feature and properly decorate
* it with annotations.
*
* parent dna sequence for this record
* @param peptides
* list of protein product sequences for Embl entry
+ * @param matcher
+ * helper to match xrefs in already retrieved sequences
*/
void parseCodingFeature(EmblFeature feature, String sourceDb,
SequenceI dna, List<SequenceI> peptides, SequenceIdMatcher matcher)
{
boolean isEmblCdna = sourceDb.equals(DBRefSource.EMBLCDS);
- int[] exon = getCdsRanges(feature);
+ int[] exons = getCdsRanges(feature);
- String prseq = null;
- String prname = "";
- String prid = null;
+ String translation = null;
+ String proteinName = "";
+ String proteinId = null;
Map<String, String> vals = new Hashtable<String, String>();
/*
if (qname.equals("translation"))
{
// remove all spaces (precompiled String.replaceAll(" ", ""))
- prseq = SPACE_PATTERN.matcher(q.getValues()[0]).replaceAll("");
+ translation = SPACE_PATTERN.matcher(q.getValues()[0]).replaceAll(
+ "");
}
else if (qname.equals("protein_id"))
{
- prid = q.getValues()[0].trim();
+ proteinId = q.getValues()[0].trim();
}
else if (qname.equals("codon_start"))
{
else if (qname.equals("product"))
{
// sometimes name is returned e.g. for V00488
- prname = q.getValues()[0].trim();
+ proteinName = q.getValues()[0].trim();
}
else
{
}
}
- DBRefEntry protEMBLCDS = null;
- exon = MappingUtils.removeStartPositions(codonStart - 1, exon);
- boolean noProteinDbref = true;
+ DBRefEntry proteinToEmblProteinRef = null;
+ exons = MappingUtils.removeStartPositions(codonStart - 1, exons);
SequenceI product = null;
- Mapping map = null;
- if (prseq != null && prname != null && prid != null)
+ Mapping dnaToProteinMapping = null;
+ if (translation != null && proteinName != null && proteinId != null)
{
+ int translationLength = translation.length();
+
/*
* look for product in peptides list, if not found, add it
*/
- product = matcher.findIdMatch(prid);
+ product = matcher.findIdMatch(proteinId);
if (product == null)
{
- product = new Sequence(prid, prseq, 1, prseq.length());
- product.setDescription(((prname.length() == 0) ? "Protein Product from "
+ product = new Sequence(proteinId, translation, 1, translationLength);
+ product.setDescription(((proteinName.length() == 0) ? "Protein Product from "
+ sourceDb
- : prname));
+ : proteinName));
peptides.add(product);
matcher.add(product);
}
// we have everything - create the mapping and perhaps the protein
// sequence
- if (exon == null || exon.length == 0)
+ if (exons == null || exons.length == 0)
{
+ /*
+ * workaround until we handle dna location for CDS sequence
+ * e.g. location="X53828.1:60..1058" correctly
+ */
System.err
.println("Implementation Notice: EMBLCDS records not properly supported yet - Making up the CDNA region of this sequence... may be incorrect ("
+ sourceDb + ":" + getAccession() + ")");
- if (prseq.length() * 3 == (1 - codonStart + dna.getSequence().length))
+ if (translationLength * 3 == (1 - codonStart + dna.getSequence().length))
{
System.err
.println("Not allowing for additional stop codon at end of cDNA fragment... !");
- // this might occur for CDS sequences where no features are
- // marked.
- exon = new int[] { dna.getStart() + (codonStart - 1),
+ // this might occur for CDS sequences where no features are marked
+ exons = new int[] { dna.getStart() + (codonStart - 1),
dna.getEnd() };
- map = new Mapping(product, exon, new int[] { 1, prseq.length() },
- 3, 1);
+ dnaToProteinMapping = new Mapping(product, exons, new int[] { 1,
+ translationLength }, 3, 1);
}
- if ((prseq.length() + 1) * 3 == (1 - codonStart + dna.getSequence().length))
+ if ((translationLength + 1) * 3 == (1 - codonStart + dna
+ .getSequence().length))
{
System.err
.println("Allowing for additional stop codon at end of cDNA fragment... will probably cause an error in VAMSAs!");
- exon = new int[] { dna.getStart() + (codonStart - 1),
+ exons = new int[] { dna.getStart() + (codonStart - 1),
dna.getEnd() - 3 };
- map = new Mapping(product, exon, new int[] { 1, prseq.length() },
- 3, 1);
+ dnaToProteinMapping = new Mapping(product, exons, new int[] { 1,
+ translationLength }, 3, 1);
}
}
else
else
{
// final product length truncation check
- // TODO should from range include stop codon even if not in protein
- // in order to include stop codon in CDS sequence (as done for
- // Ensembl)?
- int[] cdsRanges = adjustForProteinLength(prseq.length(), exon);
- map = new Mapping(product, cdsRanges, new int[] { 1,
- prseq.length() }, 3, 1);
- // reconstruct the EMBLCDS entry
- // TODO: this is only necessary when there codon annotation is
- // complete (I think JBPNote)
- DBRefEntry pcdnaref = new DBRefEntry();
- pcdnaref.setAccessionId(prid);
- pcdnaref.setSource(DBRefSource.EMBLCDS);
- pcdnaref.setVersion(getSequenceVersion()); // same as parent EMBL
- // version.
- MapList mp = new MapList(new int[] { 1, prseq.length() },
- new int[] { 1 + (codonStart - 1),
- (codonStart - 1) + 3 * prseq.length() }, 1, 3);
- pcdnaref.setMap(new Mapping(mp));
+ int[] cdsRanges = adjustForProteinLength(translationLength, exons);
+ dnaToProteinMapping = new Mapping(product, cdsRanges, new int[] {
+ 1, translationLength }, 3, 1);
if (product != null)
{
- product.addDBRef(pcdnaref);
- protEMBLCDS = new DBRefEntry(pcdnaref);
- protEMBLCDS.setSource(DBRefSource.EMBLCDSProduct);
- product.addDBRef(protEMBLCDS);
+ /*
+ * make xref with mapping from protein to EMBL dna
+ */
+ DBRefEntry proteinToEmblRef = new DBRefEntry(DBRefSource.EMBL,
+ getSequenceVersion(), proteinId, new Mapping(
+ dnaToProteinMapping.getMap().getInverse()));
+ product.addDBRef(proteinToEmblRef);
+
+ /*
+ * make xref from protein to EMBLCDS; we assume here that the
+ * CDS sequence version is same as dna sequence (?!)
+ */
+ MapList proteinToCdsMapList = new MapList(new int[] { 1,
+ translationLength }, new int[] { 1 + (codonStart - 1),
+ (codonStart - 1) + 3 * translationLength }, 1, 3);
+ DBRefEntry proteinToEmblCdsRef = new DBRefEntry(
+ DBRefSource.EMBLCDS, getSequenceVersion(), proteinId,
+ new Mapping(proteinToCdsMapList));
+ product.addDBRef(proteinToEmblCdsRef);
+
+ /*
+ * make 'direct' xref from protein to EMBLCDSPROTEIN
+ */
+ proteinToEmblProteinRef = new DBRefEntry(proteinToEmblCdsRef);
+ proteinToEmblProteinRef.setSource(DBRefSource.EMBLCDSProduct);
+ proteinToEmblProteinRef.setMap(null);
+ product.addDBRef(proteinToEmblProteinRef);
}
}
}
- // add cds feature to dna seq - this may include the stop codon
- for (int xint = 0; exon != null && xint < exon.length; xint += 2)
+
+ /*
+ * add cds features to dna sequence
+ */
+ for (int xint = 0; exons != null && xint < exons.length; xint += 2)
{
- SequenceFeature sf = makeCdsFeature(exon, xint, prname, prid, vals,
- codonStart);
+ SequenceFeature sf = makeCdsFeature(exons, xint, proteinName,
+ proteinId, vals, codonStart);
sf.setType(feature.getName()); // "CDS"
sf.setEnaLocation(feature.getLocation());
sf.setFeatureGroup(sourceDb);
}
/*
- * add dbRefs to sequence, and mappings for Uniprot xrefs
+ * add feature dbRefs to sequence, and mappings for Uniprot xrefs
*/
+ boolean hasUniprotDbref = false;
if (feature.dbRefs != null)
{
boolean mappingUsed = false;
for (DBRefEntry ref : feature.dbRefs)
{
- ref.setSource(DBRefUtils.getCanonicalName(ref.getSource()));
- if (ref.getSource().equals(DBRefSource.UNIPROT))
+ /*
+ * ensure UniProtKB/Swiss-Prot converted to UNIPROT
+ */
+ String source = DBRefUtils.getCanonicalName(ref.getSource());
+ ref.setSource(source);
+ DBRefEntry proteinDbRef = new DBRefEntry(ref.getSource(),
+ ref.getVersion(), ref.getAccessionId());
+ if (source.equals(DBRefSource.UNIPROT))
{
String proteinSeqName = DBRefSource.UNIPROT + "|"
+ ref.getAccessionId();
- if (map != null && map.getTo() != null)
+ if (dnaToProteinMapping != null
+ && dnaToProteinMapping.getTo() != null)
{
if (mappingUsed)
{
* two or more Uniprot xrefs for the same CDS -
* each needs a distinct Mapping (as to a different sequence)
*/
- map = new Mapping(map);
+ dnaToProteinMapping = new Mapping(dnaToProteinMapping);
}
mappingUsed = true;
/*
* try to locate the protein mapped to (possibly by a
- * previous CDS feature)
+ * previous CDS feature); if not found, construct it from
+ * the EMBL translation
*/
SequenceI proteinSeq = matcher.findIdMatch(proteinSeqName);
if (proteinSeq == null)
matcher.add(proteinSeq);
peptides.add(proteinSeq);
}
- map.setTo(proteinSeq);
- map.getTo().addDBRef(
- new DBRefEntry(ref.getSource(), ref.getVersion(), ref
- .getAccessionId()));
- ref.setMap(map);
+ dnaToProteinMapping.setTo(proteinSeq);
+ dnaToProteinMapping.setMappedFromId(proteinId);
+ proteinSeq.addDBRef(proteinDbRef);
+ ref.setMap(dnaToProteinMapping);
}
- noProteinDbref = false;
+ hasUniprotDbref = true;
}
if (product != null)
{
- DBRefEntry pref = new DBRefEntry(ref.getSource(),
- ref.getVersion(), ref.getAccessionId());
+ /*
+ * copy feature dbref to our protein product
+ */
+ DBRefEntry pref = proteinDbRef;
pref.setMap(null); // reference is direct
product.addDBRef(pref);
// Add converse mapping reference
- if (map != null)
+ if (dnaToProteinMapping != null)
{
- Mapping pmap = new Mapping(dna, map.getMap().getInverse());
+ Mapping pmap = new Mapping(dna, dnaToProteinMapping.getMap()
+ .getInverse());
pref = new DBRefEntry(sourceDb, getSequenceVersion(),
this.getAccession());
pref.setMap(pmap);
- if (map.getTo() != null)
+ if (dnaToProteinMapping.getTo() != null)
{
- map.getTo().addDBRef(pref);
+ dnaToProteinMapping.getTo().addDBRef(pref);
}
}
}
dna.addDBRef(ref);
}
- if (noProteinDbref && product != null)
+ }
+
+ /*
+ * if we have a product (translation) but no explicit Uniprot dbref
+ * (example: EMBL AAFI02000057 protein_id EAL65544.1)
+ * then construct mappings to an assumed EMBLCDSPROTEIN accession
+ */
+ if (!hasUniprotDbref && product != null)
+ {
+ if (proteinToEmblProteinRef == null)
{
- // add protein coding reference to dna sequence so xref matches
- if (protEMBLCDS == null)
- {
- protEMBLCDS = new DBRefEntry();
- protEMBLCDS.setAccessionId(prid);
- protEMBLCDS.setSource(DBRefSource.EMBLCDSProduct);
- protEMBLCDS.setVersion(getSequenceVersion());
- protEMBLCDS
- .setMap(new Mapping(product, map.getMap().getInverse()));
- }
- product.addDBRef(protEMBLCDS);
+ // assuming CDSPROTEIN sequence version = dna version (?!)
+ proteinToEmblProteinRef = new DBRefEntry(
+ DBRefSource.EMBLCDSProduct, getSequenceVersion(), proteinId);
+ }
+ product.addDBRef(proteinToEmblProteinRef);
- // Add converse mapping reference
- if (map != null)
- {
- Mapping pmap = new Mapping(product, protEMBLCDS.getMap().getMap()
- .getInverse());
- DBRefEntry ncMap = new DBRefEntry(protEMBLCDS);
- ncMap.setMap(pmap);
- if (map.getTo() != null)
- {
- dna.addDBRef(ncMap);
- }
- }
+ if (dnaToProteinMapping != null
+ && dnaToProteinMapping.getTo() != null)
+ {
+ DBRefEntry dnaToEmblProteinRef = new DBRefEntry(
+ DBRefSource.EMBLCDSProduct, getSequenceVersion(), proteinId);
+ dnaToEmblProteinRef.setMap(dnaToProteinMapping);
+ dnaToProteinMapping.setMappedFromId(proteinId);
+ dna.addDBRef(dnaToEmblProteinRef);
}
}
}
}
/**
- * truncate the last exon interval to the prlength'th codon
+ * Truncates (if necessary) the exon intervals to match 3 times the length of
+ * the protein; also accepts 3 bases longer (for stop codon not included in
+ * protein)
*
- * @param prlength
+ * @param proteinLength
* @param exon
- * @return new exon
+ * an array of [start, end, start, end...] intervals
+ * @return the same array (if unchanged) or a truncated copy
*/
- static int[] adjustForProteinLength(int prlength, int[] exon)
+ static int[] adjustForProteinLength(int proteinLength, int[] exon)
{
- if (prlength <= 0 || exon == null)
+ if (proteinLength <= 0 || exon == null)
{
return exon;
}
- int desiredCdsLength = prlength * 3;
+ int expectedCdsLength = proteinLength * 3;
int exonLength = MappingUtils.getLength(Arrays.asList(exon));
/*
- * assuming here exon might include stop codon in addition to protein codons
+ * if exon length matches protein, or is shorter, or longer by the
+ * length of a stop codon (3 bases), then leave it unchanged
*/
- if (desiredCdsLength == exonLength
- || desiredCdsLength == exonLength - 3)
+ if (expectedCdsLength >= exonLength
+ || expectedCdsLength == exonLength - 3)
{
return exon;
}
for (int x = 0; x < exon.length; x += 2)
{
cdspos += Math.abs(exon[x + 1] - exon[x]) + 1;
- if (desiredCdsLength <= cdspos)
+ if (expectedCdsLength <= cdspos)
{
// advanced beyond last codon.
sxpos = x;
- if (desiredCdsLength != cdspos)
+ if (expectedCdsLength != cdspos)
{
// System.err
// .println("Truncating final exon interval on region by "
*/
if (exon[x + 1] >= exon[x])
{
- endxon = exon[x + 1] - cdspos + desiredCdsLength;
+ endxon = exon[x + 1] - cdspos + expectedCdsLength;
}
else
{
- endxon = exon[x + 1] + cdspos - desiredCdsLength;
+ endxon = exon[x + 1] + cdspos - expectedCdsLength;
}
break;
}
Vector<EmblError> errors;
+ String text;
+
/**
* @return the entries
*/
*/
static void canonicaliseDbRefs(EmblFile record)
{
+ if (record.getEntries() == null)
+ {
+ return;
+ }
for (EmblEntry entry : record.getEntries())
{
if (entry.getDbRefs() != null)
}
}
}
+
+ public String getText()
+ {
+ return text;
+ }
+
+ public void setText(String text)
+ {
+ this.text = text;
+ }
}
--- /dev/null
+package jalview.ext.android;
+
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+class ContainerHelpers
+{
+ static final boolean[] EMPTY_BOOLEANS = new boolean[0];
+
+ static final int[] EMPTY_INTS = new int[0];
+
+ static final long[] EMPTY_LONGS = new long[0];
+
+ static final Object[] EMPTY_OBJECTS = new Object[0];
+
+ // This is Arrays.binarySearch(), but doesn't do any argument validation.
+ static int binarySearch(int[] array, int size, int value)
+ {
+ int lo = 0;
+ int hi = size - 1;
+ while (lo <= hi)
+ {
+ final int mid = (lo + hi) >>> 1;
+ final int midVal = array[mid];
+ if (midVal < value)
+ {
+ lo = mid + 1;
+ }
+ else if (midVal > value)
+ {
+ hi = mid - 1;
+ }
+ else
+ {
+ return mid; // value found
+ }
+ }
+ return ~lo; // value not present
+ }
+
+ static int binarySearch(long[] array, int size, long value)
+ {
+ int lo = 0;
+ int hi = size - 1;
+ while (lo <= hi)
+ {
+ final int mid = (lo + hi) >>> 1;
+ final long midVal = array[mid];
+ if (midVal < value)
+ {
+ lo = mid + 1;
+ }
+ else if (midVal > value)
+ {
+ hi = mid - 1;
+ }
+ else
+ {
+ return mid; // value found
+ }
+ }
+ return ~lo; // value not present
+ }
+
+ // This is Arrays.binarySearch(), but doesn't do any argument validation.
+ static int binarySearch(short[] array, int size, short value)
+ {
+ int lo = 0;
+ int hi = size - 1;
+ while (lo <= hi)
+ {
+ final int mid = (lo + hi) >>> 1;
+ final int midVal = array[mid];
+ if (midVal < value)
+ {
+ lo = mid + 1;
+ }
+ else if (midVal > value)
+ {
+ hi = mid - 1;
+ }
+ else
+ {
+ return mid; // value found
+ }
+ }
+ return ~lo; // value not present
+ }
+}
--- /dev/null
+package jalview.ext.android;
+
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * SparseIntArrays map integers to integers. Unlike a normal array of integers,
+ * there can be gaps in the indices. It is intended to be more memory efficient
+ * than using a HashMap to map Integers to Integers, both because it avoids
+ * auto-boxing keys and values and its data structure doesn't rely on an extra
+ * entry object for each mapping.
+ *
+ * <p>
+ * Note that this container keeps its mappings in an array data structure, using
+ * a binary search to find keys. The implementation is not intended to be
+ * appropriate for data structures that may contain large numbers of items. It
+ * is generally slower than a traditional HashMap, since lookups require a
+ * binary search and adds and removes require inserting and deleting entries in
+ * the array. For containers holding up to hundreds of items, the performance
+ * difference is not significant, less than 50%.
+ * </p>
+ *
+ * <p>
+ * It is possible to iterate over the items in this container using
+ * {@link #keyAt(int)} and {@link #valueAt(int)}. Iterating over the keys using
+ * <code>keyAt(int)</code> with ascending values of the index will return the
+ * keys in ascending order, or the values corresponding to the keys in ascending
+ * order in the case of <code>valueAt(int)<code>.
+ * </p>
+ */
+public class SparseIntArray implements Cloneable
+{
+ private int[] mKeys;
+
+ private int[] mValues;
+
+ private int mSize;
+
+ /**
+ * Creates a new SparseIntArray containing no mappings.
+ */
+ public SparseIntArray()
+ {
+ this(10);
+ }
+
+ /**
+ * Creates a new SparseIntArray containing no mappings that will not require
+ * any additional memory allocation to store the specified number of mappings.
+ * If you supply an initial capacity of 0, the sparse array will be
+ * initialized with a light-weight representation not requiring any additional
+ * array allocations.
+ */
+ public SparseIntArray(int initialCapacity)
+ {
+ if (initialCapacity == 0)
+ {
+ mKeys = ContainerHelpers.EMPTY_INTS;
+ mValues = ContainerHelpers.EMPTY_INTS;
+ }
+ else
+ {
+ initialCapacity = idealIntArraySize(initialCapacity);
+ mKeys = new int[initialCapacity];
+ mValues = new int[initialCapacity];
+ }
+ mSize = 0;
+ }
+
+ @Override
+ public SparseIntArray clone()
+ {
+ SparseIntArray clone = null;
+ try
+ {
+ clone = (SparseIntArray) super.clone();
+ clone.mKeys = mKeys.clone();
+ clone.mValues = mValues.clone();
+ } catch (CloneNotSupportedException cnse)
+ {
+ /* ignore */
+ }
+ return clone;
+ }
+
+ /**
+ * Gets the int mapped from the specified key, or <code>0</code> if no such
+ * mapping has been made.
+ */
+ public int get(int key)
+ {
+ return get(key, 0);
+ }
+
+ /**
+ * Gets the int mapped from the specified key, or the specified value if no
+ * such mapping has been made.
+ */
+ public int get(int key, int valueIfKeyNotFound)
+ {
+ int i = ContainerHelpers.binarySearch(mKeys, mSize, key);
+ if (i < 0)
+ {
+ return valueIfKeyNotFound;
+ }
+ else
+ {
+ return mValues[i];
+ }
+ }
+
+ /**
+ * Removes the mapping from the specified key, if there was any.
+ */
+ public void delete(int key)
+ {
+ int i = ContainerHelpers.binarySearch(mKeys, mSize, key);
+ if (i >= 0)
+ {
+ removeAt(i);
+ }
+ }
+
+ /**
+ * Removes the mapping at the given index.
+ */
+ public void removeAt(int index)
+ {
+ System.arraycopy(mKeys, index + 1, mKeys, index, mSize - (index + 1));
+ System.arraycopy(mValues, index + 1, mValues, index, mSize
+ - (index + 1));
+ mSize--;
+ }
+
+ /**
+ * Adds a mapping from the specified key to the specified value, replacing the
+ * previous mapping from the specified key if there was one.
+ */
+ public void put(int key, int value)
+ {
+ int i = ContainerHelpers.binarySearch(mKeys, mSize, key);
+ if (i >= 0)
+ {
+ mValues[i] = value;
+ }
+ else
+ {
+ i = ~i;
+ if (mSize >= mKeys.length)
+ {
+ int n = idealIntArraySize(mSize + 1);
+ int[] nkeys = new int[n];
+ int[] nvalues = new int[n];
+ // Log.e("SparseIntArray", "grow " + mKeys.length + " to " + n);
+ System.arraycopy(mKeys, 0, nkeys, 0, mKeys.length);
+ System.arraycopy(mValues, 0, nvalues, 0, mValues.length);
+ mKeys = nkeys;
+ mValues = nvalues;
+ }
+ if (mSize - i != 0)
+ {
+ // Log.e("SparseIntArray", "move " + (mSize - i));
+ System.arraycopy(mKeys, i, mKeys, i + 1, mSize - i);
+ System.arraycopy(mValues, i, mValues, i + 1, mSize - i);
+ }
+ mKeys[i] = key;
+ mValues[i] = value;
+ mSize++;
+ }
+ }
+
+ /**
+ * Returns the number of key-value mappings that this SparseIntArray currently
+ * stores.
+ */
+ public int size()
+ {
+ return mSize;
+ }
+
+ /**
+ * Given an index in the range <code>0...size()-1</code>, returns the key from
+ * the <code>index</code>th key-value mapping that this SparseIntArray stores.
+ *
+ * <p>
+ * The keys corresponding to indices in ascending order are guaranteed to be
+ * in ascending order, e.g., <code>keyAt(0)</code> will return the smallest
+ * key and <code>keyAt(size()-1)</code> will return the largest key.
+ * </p>
+ */
+ public int keyAt(int index)
+ {
+ return mKeys[index];
+ }
+
+ /**
+ * Given an index in the range <code>0...size()-1</code>, returns the value
+ * from the <code>index</code>th key-value mapping that this SparseIntArray
+ * stores.
+ *
+ * <p>
+ * The values corresponding to indices in ascending order are guaranteed to be
+ * associated with keys in ascending order, e.g., <code>valueAt(0)</code> will
+ * return the value associated with the smallest key and
+ * <code>valueAt(size()-1)</code> will return the value associated with the
+ * largest key.
+ * </p>
+ */
+ public int valueAt(int index)
+ {
+ return mValues[index];
+ }
+
+ /**
+ * Returns the index for which {@link #keyAt} would return the specified key,
+ * or a negative number if the specified key is not mapped.
+ */
+ public int indexOfKey(int key)
+ {
+ return ContainerHelpers.binarySearch(mKeys, mSize, key);
+ }
+
+ /**
+ * Returns an index for which {@link #valueAt} would return the specified key,
+ * or a negative number if no keys map to the specified value. Beware that
+ * this is a linear search, unlike lookups by key, and that multiple keys can
+ * map to the same value and this will find only one of them.
+ */
+ public int indexOfValue(int value)
+ {
+ for (int i = 0; i < mSize; i++)
+ {
+ if (mValues[i] == value)
+ {
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ /**
+ * Removes all key-value mappings from this SparseIntArray.
+ */
+ public void clear()
+ {
+ mSize = 0;
+ }
+
+ /**
+ * Puts a key/value pair into the array, optimizing for the case where the key
+ * is greater than all existing keys in the array.
+ */
+ public void append(int key, int value)
+ {
+ if (mSize != 0 && key <= mKeys[mSize - 1])
+ {
+ put(key, value);
+ return;
+ }
+ int pos = mSize;
+ if (pos >= mKeys.length)
+ {
+ int n = idealIntArraySize(pos + 1);
+ int[] nkeys = new int[n];
+ int[] nvalues = new int[n];
+ // Log.e("SparseIntArray", "grow " + mKeys.length + " to " + n);
+ System.arraycopy(mKeys, 0, nkeys, 0, mKeys.length);
+ System.arraycopy(mValues, 0, nvalues, 0, mValues.length);
+ mKeys = nkeys;
+ mValues = nvalues;
+ }
+ mKeys[pos] = key;
+ mValues[pos] = value;
+ mSize = pos + 1;
+ }
+
+ /**
+ * Inlined here by copying from com.android.internal.util.ArrayUtils
+ *
+ * @param i
+ * @return
+ */
+ public static int idealIntArraySize(int need)
+ {
+ return idealByteArraySize(need * 4) / 4;
+ }
+
+ /**
+ * Inlined here by copying from com.android.internal.util.ArrayUtils
+ *
+ * @param i
+ * @return
+ */
+ public static int idealByteArraySize(int need)
+ {
+ for (int i = 4; i < 32; i++)
+ {
+ if (need <= (1 << i) - 12)
+ {
+ return (1 << i) - 12;
+ }
+ }
+
+ return need;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * <p>
+ * This implementation composes a string by iterating over its mappings.
+ */
+ @Override
+ public String toString()
+ {
+ if (size() <= 0)
+ {
+ return "{}";
+ }
+ StringBuilder buffer = new StringBuilder(mSize * 28);
+ buffer.append('{');
+ for (int i = 0; i < mSize; i++)
+ {
+ if (i > 0)
+ {
+ buffer.append(", ");
+ }
+ int key = keyAt(i);
+ buffer.append(key);
+ buffer.append('=');
+ int value = valueAt(i);
+ buffer.append(value);
+ }
+ buffer.append('}');
+ return buffer.toString();
+ }
+
+ /**
+ * Method (copied from put) added for Jalview to efficiently increment a key's
+ * value if present, else add it with the given value. This avoids a double
+ * binary search (once to get the value, again to put the updated value).
+ *
+ * @param key
+ * @oparam toAdd
+ * @return the new value of the count for the key
+ * @throw ArithmeticException if the result would exceed the maximum value of
+ * an int
+ */
+ public int add(int key, int toAdd)
+ {
+ int newValue = toAdd;
+ int i = ContainerHelpers.binarySearch(mKeys, mSize, key);
+ if (i >= 0)
+ {
+ checkOverflow(mValues[i], toAdd);
+ mValues[i] += toAdd;
+ newValue = mValues[i];
+ }
+ else
+ {
+ i = ~i;
+ if (mSize >= mKeys.length)
+ {
+ int n = idealIntArraySize(mSize + 1);
+ int[] nkeys = new int[n];
+ int[] nvalues = new int[n];
+ System.arraycopy(mKeys, 0, nkeys, 0, mKeys.length);
+ System.arraycopy(mValues, 0, nvalues, 0, mValues.length);
+ mKeys = nkeys;
+ mValues = nvalues;
+ }
+ if (mSize - i != 0)
+ {
+ System.arraycopy(mKeys, i, mKeys, i + 1, mSize - i);
+ System.arraycopy(mValues, i, mValues, i + 1, mSize - i);
+ }
+ mKeys[i] = key;
+ mValues[i] = toAdd;
+ mSize++;
+ }
+ return newValue;
+ }
+
+ /**
+ * Throws ArithmeticException if adding addend to value would exceed the range
+ * of int
+ *
+ * @param value
+ * @param addend
+ */
+ static void checkOverflow(int value, int addend)
+ {
+ /*
+ * test cases being careful to avoid overflow while testing!
+ */
+ if (addend > 0)
+ {
+ if (value > 0 && Integer.MAX_VALUE - value < addend)
+ {
+ throw new ArithmeticException("Integer overflow adding " + addend
+ + " to " + value);
+ }
+ }
+ else if (addend < 0)
+ {
+ if (value < 0 && Integer.MIN_VALUE - value > addend)
+ {
+ throw new ArithmeticException("Integer underflow adding " + addend
+ + " to " + value);
+ }
+ }
+ }
+}
--- /dev/null
+package jalview.ext.android;
+
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * SparseShortArrays map shorts to shorts. Unlike a normal array of shorts,
+ * there can be gaps in the indices. It is intended to be more memory efficient
+ * than using a HashMap to map Shorts to Shorts, both because it avoids
+ * auto-boxing keys and values and its data structure doesn't rely on an extra
+ * entry object for each mapping.
+ *
+ * <p>
+ * Note that this container keeps its mappings in an array data structure, using
+ * a binary search to find keys. The implementation is not intended to be
+ * appropriate for data structures that may contain large numbers of items. It
+ * is generally slower than a traditional HashMap, since lookups require a
+ * binary search and adds and removes require inserting and deleting entries in
+ * the array. For containers holding up to hundreds of items, the performance
+ * difference is not significant, less than 50%.
+ * </p>
+ *
+ * <p>
+ * It is possible to iterate over the items in this container using
+ * {@link #keyAt(int)} and {@link #valueAt(int)}. Iterating over the keys using
+ * <code>keyAt(int)</code> with ascending values of the index will return the
+ * keys in ascending order, or the values corresponding to the keys in ascending
+ * order in the case of <code>valueAt(int)<code>.
+ * </p>
+ */
+/**
+ * A copy of SparseShortArray designed to store short values (to minimise space
+ * usage).
+ * <p>
+ * Note that operations append, put, add throw ArithmeticException if the
+ * resulting value overflows the range of a short.
+ */
+public class SparseShortArray implements Cloneable
+{
+ private short[] mKeys;
+
+ private short[] mValues;
+
+ private int mSize;
+
+ /**
+ * Creates a new SparseShortArray containing no mappings.
+ */
+ public SparseShortArray()
+ {
+ this(10);
+ }
+
+ /**
+ * Creates a new SparseShortArray containing no mappings that will not require
+ * any additional memory allocation to store the specified number of mappings.
+ * If you supply an initial capacity of 0, the sparse array will be
+ * initialized with a light-weight representation not requiring any additional
+ * array allocations.
+ */
+ public SparseShortArray(int initialCapacity)
+ {
+ if (initialCapacity == 0)
+ {
+ mKeys = new short[0];
+ mValues = new short[0];
+ }
+ else
+ {
+ initialCapacity = idealShortArraySize(initialCapacity);
+ mKeys = new short[initialCapacity];
+ mValues = new short[initialCapacity];
+ }
+ mSize = 0;
+ }
+
+ @Override
+ public SparseShortArray clone()
+ {
+ SparseShortArray clone = null;
+ try
+ {
+ clone = (SparseShortArray) super.clone();
+ clone.mKeys = mKeys.clone();
+ clone.mValues = mValues.clone();
+ } catch (CloneNotSupportedException cnse)
+ {
+ /* ignore */
+ }
+ return clone;
+ }
+
+ /**
+ * Gets the int mapped from the specified key, or <code>0</code> if no such
+ * mapping has been made.
+ */
+ public int get(int key)
+ {
+ return get(key, 0);
+ }
+
+ /**
+ * Gets the int mapped from the specified key, or the specified value if no
+ * such mapping has been made.
+ *
+ * @throws ArithmeticException
+ * if key is outside the range of a short value
+ */
+ public int get(int key, int valueIfKeyNotFound)
+ {
+ checkOverflow(key);
+ int i = ContainerHelpers.binarySearch(mKeys, mSize, (short) key);
+ if (i < 0)
+ {
+ return valueIfKeyNotFound;
+ }
+ else
+ {
+ return mValues[i];
+ }
+ }
+
+ /**
+ * Removes the mapping from the specified key, if there was any.
+ *
+ * @throws ArithmeticException
+ * if key is outside the range of a short value
+ */
+ public void delete(int key)
+ {
+ checkOverflow(key);
+ int i = ContainerHelpers.binarySearch(mKeys, mSize, (short) key);
+ if (i >= 0)
+ {
+ removeAt(i);
+ }
+ }
+
+ /**
+ * Removes the mapping at the given index.
+ */
+ public void removeAt(int index)
+ {
+ System.arraycopy(mKeys, index + 1, mKeys, index, mSize - (index + 1));
+ System.arraycopy(mValues, index + 1, mValues, index, mSize
+ - (index + 1));
+ mSize--;
+ }
+
+ /**
+ * Adds a mapping from the specified key to the specified value, replacing the
+ * previous mapping from the specified key if there was one.
+ *
+ * @throws ArithmeticException
+ * if either argument is outside the range of a short value
+ */
+ public void put(int key, int value)
+ {
+ checkOverflow(key);
+ checkOverflow(value);
+ int i = ContainerHelpers.binarySearch(mKeys, mSize, (short) key);
+ if (i >= 0)
+ {
+ mValues[i] = (short) value;
+ }
+ else
+ {
+ i = ~i;
+ if (mSize >= mKeys.length)
+ {
+ int n = idealShortArraySize(mSize + 1);
+ short[] nkeys = new short[n];
+ short[] nvalues = new short[n];
+ // Log.e("SparseShortArray", "grow " + mKeys.length + " to " + n);
+ System.arraycopy(mKeys, 0, nkeys, 0, mKeys.length);
+ System.arraycopy(mValues, 0, nvalues, 0, mValues.length);
+ mKeys = nkeys;
+ mValues = nvalues;
+ }
+ if (mSize - i != 0)
+ {
+ // Log.e("SparseShortArray", "move " + (mSize - i));
+ System.arraycopy(mKeys, i, mKeys, i + 1, mSize - i);
+ System.arraycopy(mValues, i, mValues, i + 1, mSize - i);
+ }
+ mKeys[i] = (short) key;
+ mValues[i] = (short) value;
+ mSize++;
+ }
+ }
+
+ /**
+ * Returns the number of key-value mappings that this SparseShortArray
+ * currently stores.
+ */
+ public int size()
+ {
+ return mSize;
+ }
+
+ /**
+ * Given an index in the range <code>0...size()-1</code>, returns the key from
+ * the <code>index</code>th key-value mapping that this SparseShortArray
+ * stores.
+ *
+ * <p>
+ * The keys corresponding to indices in ascending order are guaranteed to be
+ * in ascending order, e.g., <code>keyAt(0)</code> will return the smallest
+ * key and <code>keyAt(size()-1)</code> will return the largest key.
+ * </p>
+ */
+ public short keyAt(int index)
+ {
+ return mKeys[index];
+ }
+
+ /**
+ * Given an index in the range <code>0...size()-1</code>, returns the value
+ * from the <code>index</code>th key-value mapping that this SparseShortArray
+ * stores.
+ *
+ * <p>
+ * The values corresponding to indices in ascending order are guaranteed to be
+ * associated with keys in ascending order, e.g., <code>valueAt(0)</code> will
+ * return the value associated with the smallest key and
+ * <code>valueAt(size()-1)</code> will return the value associated with the
+ * largest key.
+ * </p>
+ */
+ public short valueAt(int index)
+ {
+ return mValues[index];
+ }
+
+ /**
+ * Returns the index for which {@link #keyAt} would return the specified key,
+ * or a negative number if the specified key is not mapped.
+ *
+ * @throws ArithmeticException
+ * if key is outside the range of a short value
+ */
+ public int indexOfKey(int key)
+ {
+ checkOverflow(key);
+ return ContainerHelpers.binarySearch(mKeys, mSize, (short) key);
+ }
+
+ /**
+ * Returns an index for which {@link #valueAt} would return the specified key,
+ * or a negative number if no keys map to the specified value. Beware that
+ * this is a linear search, unlike lookups by key, and that multiple keys can
+ * map to the same value and this will find only one of them.
+ */
+ public int indexOfValue(int value)
+ {
+ for (int i = 0; i < mSize; i++)
+ {
+ if (mValues[i] == value)
+ {
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ /**
+ * Removes all key-value mappings from this SparseShortArray.
+ */
+ public void clear()
+ {
+ mSize = 0;
+ }
+
+ /**
+ * Puts a key/value pair into the array, optimizing for the case where the key
+ * is greater than all existing keys in the array.
+ */
+ public void append(int key, int value)
+ {
+ if (mSize != 0 && key <= mKeys[mSize - 1])
+ {
+ put(key, value);
+ return;
+ }
+ int pos = mSize;
+ if (pos >= mKeys.length)
+ {
+ int n = idealShortArraySize(pos + 1);
+ short[] nkeys = new short[n];
+ short[] nvalues = new short[n];
+ // Log.e("SparseShortArray", "grow " + mKeys.length + " to " + n);
+ System.arraycopy(mKeys, 0, nkeys, 0, mKeys.length);
+ System.arraycopy(mValues, 0, nvalues, 0, mValues.length);
+ mKeys = nkeys;
+ mValues = nvalues;
+ }
+ checkOverflow(key);
+ checkOverflow(value);
+ mKeys[pos] = (short) key;
+ mValues[pos] = (short) value;
+ mSize = pos + 1;
+ }
+
+ /**
+ * Throws an exception if the value is outside the range of a short.
+ *
+ * @param value
+ * @throws ArithmeticException
+ */
+ public static void checkOverflow(int value)
+ {
+ if (value > Short.MAX_VALUE || value < Short.MIN_VALUE)
+ {
+ throw new ArithmeticException(String.valueOf(value));
+ }
+ }
+
+ /**
+ * Inlined here by copying from com.android.internal.util.ArrayUtils
+ *
+ * @param i
+ * @return
+ */
+ public static int idealShortArraySize(int need)
+ {
+ return idealByteArraySize(need * 2) / 2;
+ }
+
+ /**
+ * Inlined here by copying from com.android.internal.util.ArrayUtils
+ *
+ * @param i
+ * @return
+ */
+ public static int idealByteArraySize(int need)
+ {
+ for (int i = 4; i < 32; i++)
+ {
+ if (need <= (1 << i) - 12)
+ {
+ return (1 << i) - 12;
+ }
+ }
+
+ return need;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * <p>
+ * This implementation composes a string by iterating over its mappings.
+ */
+ @Override
+ public String toString()
+ {
+ if (size() <= 0)
+ {
+ return "{}";
+ }
+ StringBuilder buffer = new StringBuilder(mSize * 28);
+ buffer.append('{');
+ for (int i = 0; i < mSize; i++)
+ {
+ if (i > 0)
+ {
+ buffer.append(", ");
+ }
+ int key = keyAt(i);
+ buffer.append(key);
+ buffer.append('=');
+ int value = valueAt(i);
+ buffer.append(value);
+ }
+ buffer.append('}');
+ return buffer.toString();
+ }
+
+ /**
+ * Method (copied from put) added for Jalview to efficiently increment a key's
+ * value if present, else add it with the given value. This avoids a double
+ * binary search (once to get the value, again to put the updated value).
+ *
+ * @param key
+ * @oparam toAdd
+ * @return the new value of the count for the key
+ * @throws ArithmeticException
+ * if key, or result of adding toAdd, is outside the range of a
+ * short value
+ */
+ public int add(int key, int toAdd)
+ {
+ int newValue = toAdd;
+ checkOverflow(key);
+ int i = ContainerHelpers.binarySearch(mKeys, mSize, (short) key);
+ if (i >= 0)
+ {
+ checkOverflow(toAdd + mValues[i]);
+ mValues[i] += (short) toAdd;
+ newValue = mValues[i];
+ }
+ else
+ {
+ checkOverflow(toAdd);
+ i = ~i;
+ if (mSize >= mKeys.length)
+ {
+ int n = idealShortArraySize(mSize + 1);
+ short[] nkeys = new short[n];
+ short[] nvalues = new short[n];
+ System.arraycopy(mKeys, 0, nkeys, 0, mKeys.length);
+ System.arraycopy(mValues, 0, nvalues, 0, mValues.length);
+ mKeys = nkeys;
+ mValues = nvalues;
+ }
+ if (mSize - i != 0)
+ {
+ System.arraycopy(mKeys, i, mKeys, i + 1, mSize - i);
+ System.arraycopy(mValues, i, mValues, i + 1, mSize - i);
+ }
+ mKeys[i] = (short) key;
+ mValues[i] = (short) toAdd;
+ mSize++;
+ }
+ return newValue;
+ }
+}
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
package jalview.ext.ensembl;
import jalview.datamodel.SequenceFeature;
*/
private static final Regex ACCESSION_REGEX = new Regex(
"(ENS([A-Z]{3}|)[TG][0-9]{11}$)" + "|" + "(CCDS[0-9.]{3,}$)");
-
+
/*
* fetch exon features on genomic sequence (to identify the cdna regions)
* and cds and variation features (to retain)
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
package jalview.ext.ensembl;
import jalview.datamodel.SequenceFeature;
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
package jalview.ext.ensembl;
import jalview.datamodel.Alignment;
protected URL getUrl(List<String> ids) throws MalformedURLException
{
StringBuffer urlstring = new StringBuffer(128);
- urlstring.append(getDomain()).append("/overlap/id/")
- .append(ids.get(0));
+ urlstring.append(getDomain()).append("/overlap/id/").append(ids.get(0));
// @see https://github.com/Ensembl/ensembl-rest/wiki/Output-formats
urlstring.append("?content-type=text/x-gff3");
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
package jalview.ext.ensembl;
import jalview.api.FeatureColourI;
* fetch the gene sequence(s) with features and xrefs
*/
AlignmentI geneAlignment = super.getSequenceRecords(geneId);
-
+ if (geneAlignment == null)
+ {
+ continue;
+ }
if (geneAlignment.getHeight() == 1)
{
getTranscripts(geneAlignment, geneId);
*/
else
{
- List<String> ids = new EnsemblSymbol(getDomain()).getIds(acc);
+ List<String> ids = new EnsemblSymbol(getDomain(), getDbSource(),
+ getDbVersion()).getIds(acc);
for (String geneId : ids)
{
if (!geneIds.contains(geneId))
*/
protected String getGeneIdentifiersForName(String query)
{
- List<String> ids = new EnsemblSymbol(getDomain()).getIds(query);
+ List<String> ids = new EnsemblSymbol(getDomain(), getDbSource(),
+ getDbVersion()).getIds(query);
if (ids != null)
{
for (String id : ids)
}
}
gene.setSequenceFeatures(filtered
- .toArray(new SequenceFeature[filtered
- .size()]));
+ .toArray(new SequenceFeature[filtered.size()]));
}
}
return new FeatureSettingsAdapter()
{
SequenceOntologyI so = SequenceOntologyFactory.getInstance();
+
@Override
public boolean isFeatureDisplayed(String type)
{
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
package jalview.ext.ensembl;
import jalview.datamodel.SequenceFeature;
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
package jalview.ext.ensembl;
-
/**
* A class to behave much like EnsemblGene but referencing the ensemblgenomes
* domain and data
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
package jalview.ext.ensembl;
/**
/*
* true when http://rest.ensembl.org/info/ping/?content-type=application/json
- * returns response code 200
+ * returns response code 200 and not {"error":"Database is unavailable"}
*/
boolean restAvailable;
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
package jalview.ext.ensembl;
import jalview.datamodel.AlignmentI;
public String getParent(String identifier)
{
List<String> ids = Arrays.asList(new String[] { identifier });
-
+
BufferedReader br = null;
try
{
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
package jalview.ext.ensembl;
import jalview.datamodel.AlignmentI;
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
package jalview.ext.ensembl;
import jalview.io.FileParse;
*/
abstract class EnsemblRestClient extends EnsemblSequenceFetcher
{
+ private static final int DEFAULT_READ_TIMEOUT = 5 * 60 * 1000; // 5 minutes
+
+ private static final int CONNECT_TIMEOUT_MS = 10 * 1000; // 10 seconds
+
/*
* update these constants when Jalview has been checked / updated for
* changes to Ensembl REST API
* @see https://github.com/Ensembl/ensembl-rest/wiki/Change-log
+ * @see http://rest.ensembl.org/info/rest?content-type=application/json
*/
- private static final String LATEST_ENSEMBLGENOMES_REST_VERSION = "4.4";
+ private static final String LATEST_ENSEMBLGENOMES_REST_VERSION = "4.6";
- private static final String LATEST_ENSEMBL_REST_VERSION = "4.5";
+ private static final String LATEST_ENSEMBL_REST_VERSION = "4.7";
+
+ private static final String REST_CHANGE_LOG = "https://github.com/Ensembl/ensembl-rest/wiki/Change-log";
private static Map<String, EnsemblInfo> domainData;
private final static long VERSION_RETEST_INTERVAL = 1000L * 3600; // 1 hr
private static final Regex TRANSCRIPT_REGEX = new Regex(
- "(ENS)([A-Z]{3}|)T[0-9]{11}$");
+ "(ENS)([A-Z]{3}|)T[0-9]{11}$");
private static final Regex GENE_REGEX = new Regex(
- "(ENS)([A-Z]{3}|)G[0-9]{11}$");
+ "(ENS)([A-Z]{3}|)G[0-9]{11}$");
static
{
protected abstract String getResponseMimeType();
/**
- * Tries to connect to Ensembl's REST 'ping' endpoint, and returns true if
- * successful, else false
+ * Checks Ensembl's REST 'ping' endpoint, and returns true if response
+ * indicates available, else false
*
+ * @see http://rest.ensembl.org/documentation/info/ping
* @return
*/
private boolean checkEnsembl()
{
+ BufferedReader br = null;
try
{
// note this format works for both ensembl and ensemblgenomes
// info/ping.json works for ensembl only (March 2016)
URL ping = new URL(getDomain()
+ "/info/ping?content-type=application/json");
- HttpURLConnection conn = (HttpURLConnection) ping.openConnection();
- int rc = conn.getResponseCode();
- conn.disconnect();
- if (rc >= 200 && rc < 300)
- {
- return true;
- }
+
+ /*
+ * expect {"ping":1} if ok
+ * if ping takes more than 2 seconds to respond, treat as if unavailable
+ */
+ br = getHttpResponse(ping, null, 2 * 1000);
+ JSONParser jp = new JSONParser();
+ JSONObject val = (JSONObject) jp.parse(br);
+ String pingString = val.get("ping").toString();
+ return pingString != null;
} catch (Throwable t)
{
System.err.println("Error connecting to " + PING_URL + ": "
+ t.getMessage());
+ } finally
+ {
+ if (br != null)
+ {
+ try
+ {
+ br.close();
+ } catch (IOException e)
+ {
+ // ignore
+ }
+ }
}
return false;
}
throws IOException
{
URL url = getUrl(ids);
-
+
BufferedReader reader = getHttpResponse(url, ids);
+ if (reader == null)
+ {
+ // request failed
+ return null;
+ }
FileParse fp = new FileParse(reader, url.toString(), "HTTP_POST");
return fp;
}
/**
+ * Gets a reader to the HTTP response, using the default read timeout of 5
+ * minutes
+ *
+ * @param url
+ * @param ids
+ * @return
+ * @throws IOException
+ */
+ protected BufferedReader getHttpResponse(URL url, List<String> ids)
+ throws IOException
+ {
+ return getHttpResponse(url, ids, DEFAULT_READ_TIMEOUT);
+ }
+
+ /**
* Writes the HTTP request and gets the response as a reader.
*
* @param url
* @param ids
* written as Json POST body if more than one
+ * @param readTimeout
+ * in milliseconds
* @return
* @throws IOException
* if response code was not 200, or other I/O error
*/
- protected BufferedReader getHttpResponse(URL url, List<String> ids)
- throws IOException
+ protected BufferedReader getHttpResponse(URL url, List<String> ids,
+ int readTimeout) throws IOException
{
// long now = System.currentTimeMillis();
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
-
+
/*
* POST method allows multiple queries in one request; it is supported for
* sequence queries, but not for overlap
connection.setDoInput(true);
connection.setDoOutput(multipleIds);
+ connection.setConnectTimeout(CONNECT_TIMEOUT_MS);
+ connection.setReadTimeout(readTimeout);
+
if (multipleIds)
{
writePostBody(connection, ids);
}
-
- InputStream response = connection.getInputStream();
+
int responseCode = connection.getResponseCode();
-
+
if (responseCode != 200)
{
/*
* note: a GET request for an invalid id returns an error code e.g. 415
* but POST request returns 200 and an empty Fasta response
*/
- throw new IOException(
- "Response code was not 200. Detected response was "
- + responseCode);
+ System.err.println("Response code " + responseCode + " for " + url);
+ return null;
}
+ // get content
+ InputStream response = connection.getInputStream();
+
// System.out.println(getClass().getName() + " took "
// + (System.currentTimeMillis() - now) + "ms to fetch");
checkRateLimits(connection);
-
+
BufferedReader reader = null;
reader = new BufferedReader(new InputStreamReader(response, "UTF-8"));
return reader;
// remaining, limit, reset));
}
}
-
+
/**
* Rechecks if Ensembl is responding, unless the last check was successful and
* the retest interval has not yet elapsed. Returns true if Ensembl is up,
if (laterVersion)
{
System.err.println(String.format(
- "Expected %s REST version %s but found %s", getDbSource(),
- expected,
- version));
+ "Expected %s REST version %s but found %s, see %s",
+ getDbSource(), expected, version, REST_CHANGE_LOG));
}
info.restVersion = version;
} catch (Throwable t)
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
package jalview.ext.ensembl;
import jalview.analysis.AlignmentUtils;
import jalview.analysis.Dna;
+import jalview.bin.Cache;
import jalview.datamodel.Alignment;
import jalview.datamodel.AlignmentI;
import jalview.datamodel.DBRefEntry;
+ " chunks. Unexpected problem (" + r.getLocalizedMessage()
+ ")";
System.err.println(msg);
+ r.printStackTrace();
break;
}
}
proteinSeq.createDatasetSequence();
querySeq.createDatasetSequence();
- MapList mapList = AlignmentUtils.mapCdsToProtein(querySeq, proteinSeq);
+ MapList mapList = AlignmentUtils
+ .mapCdsToProtein(querySeq, proteinSeq);
if (mapList != null)
{
// clunky: ensure Uniprot xref if we have one is on mapped sequence
SequenceI ds = proteinSeq.getDatasetSequence();
- ds.setSourceDBRef(proteinSeq.getSourceDBRef());
-
+ // TODO: Verify ensp primary ref is on proteinSeq.getDatasetSequence()
Mapping map = new Mapping(ds, mapList);
DBRefEntry dbr = new DBRefEntry(getDbSource(),
getEnsemblDataVersion(), proteinSeq.getName(), map);
querySeq.getDatasetSequence().addDBRef(dbr);
-
+ DBRefEntry[] uprots = DBRefUtils.selectRefs(ds.getDBRefs(),
+ new String[] { DBRefSource.UNIPROT });
+ DBRefEntry[] upxrefs = DBRefUtils.selectRefs(querySeq.getDBRefs(),
+ new String[] { DBRefSource.UNIPROT });
+ if (uprots != null)
+ {
+ for (DBRefEntry up : uprots)
+ {
+ // locate local uniprot ref and map
+ List<DBRefEntry> upx = DBRefUtils.searchRefs(upxrefs,
+ up.getAccessionId());
+ DBRefEntry upxref;
+ if (upx.size() != 0)
+ {
+ upxref = upx.get(0);
+
+ if (upx.size() > 1)
+ {
+ Cache.log
+ .warn("Implementation issue - multiple uniprot acc on product sequence.");
+ }
+ }
+ else
+ {
+ upxref = new DBRefEntry(DBRefSource.UNIPROT,
+ getEnsemblDataVersion(), up.getAccessionId());
+ }
+
+ Mapping newMap = new Mapping(ds, mapList);
+ upxref.setVersion(getEnsemblDataVersion());
+ upxref.setMap(newMap);
+ if (upx.size() == 0)
+ {
+ // add the new uniprot ref
+ querySeq.getDatasetSequence().addDBRef(upxref);
+ }
+
+ }
+ }
+
/*
* copy exon features to protein, compute peptide variants from dna
* variants and add as features on the protein sequence ta-da
*/
- AlignmentUtils.computeProteinFeatures(querySeq, proteinSeq, mapList);
+ AlignmentUtils
+ .computeProteinFeatures(querySeq, proteinSeq, mapList);
}
} catch (Exception e)
{
seq = seq.getDatasetSequence();
}
- EnsemblXref xrefFetcher = new EnsemblXref(getDomain());
+ EnsemblXref xrefFetcher = new EnsemblXref(getDomain(), getDbSource(),
+ getEnsemblDataVersion());
List<DBRefEntry> xrefs = xrefFetcher.getCrossReferences(seq.getName());
for (DBRefEntry xref : xrefs)
{
seq.addDBRef(xref);
- /*
- * Save any Uniprot xref to be the reference for SIFTS mapping
- */
- if (DBRefSource.UNIPROT.equals(xref.getSource()))
- {
- seq.setSourceDBRef(xref);
- }
}
/*
throw new JalviewException("ENSEMBL Rest API not available.");
}
FileParse fp = getSequenceReader(ids);
+ if (fp == null)
+ {
+ return alignment;
+ }
+
FastaFile fr = new FastaFile(fp);
if (fr.hasWarningMessage())
{
if (fr.getSeqs().size() > 0)
{
- AlignmentI seqal = new Alignment(
- fr.getSeqsAsArray());
- for (SequenceI sq:seqal.getSequences())
+ AlignmentI seqal = new Alignment(fr.getSeqsAsArray());
+ for (SequenceI sq : seqal.getSequences())
{
if (sq.getDescription() == null)
{
if (ids.contains(name)
|| ids.contains(name.replace("ENSP", "ENST")))
{
- DBRefUtils.parseToDbRef(sq, getDbSource(),
+ DBRefEntry dbref = DBRefUtils.parseToDbRef(sq, getDbSource(),
getEnsemblDataVersion(), name);
+ sq.addDBRef(dbref);
}
}
if (alignment == null)
int mappedLength = 0;
int direction = 1; // forward
boolean directionSet = false;
-
+
for (SequenceFeature sf : sfs)
{
/*
// abort - mix of forward and backward
System.err.println("Error: forward and backward strand for "
+ accId);
- return null;
- }
- direction = strand;
- directionSet = true;
-
- /*
- * add to CDS ranges, semi-sorted forwards/backwards
- */
- if (strand < 0)
- {
- regions.add(0, new int[] { sf.getEnd(), sf.getBegin() });
- }
- else
- {
+ return null;
+ }
+ direction = strand;
+ directionSet = true;
+
+ /*
+ * add to CDS ranges, semi-sorted forwards/backwards
+ */
+ if (strand < 0)
+ {
+ regions.add(0, new int[] { sf.getEnd(), sf.getBegin() });
+ }
+ else
+ {
regions.add(new int[] { sf.getBegin(), sf.getEnd() });
}
mappedLength += Math.abs(sf.getEnd() - sf.getBegin() + 1);
}
}
}
-
+
if (regions.isEmpty())
{
System.out.println("Failed to identify target sequence for " + accId
* (havana / ensembl_havana)
*/
Collections.sort(regions, new RangeSorter(direction == 1));
-
+
List<int[]> to = Arrays.asList(new int[] { start,
start + mappedLength - 1 });
-
+
return new MapList(regions, to, 1, 1);
}
int start = sf.getBegin();
int end = sf.getEnd();
int[] mappedRange = mapping.locateInTo(start, end);
-
+
if (mappedRange != null)
{
SequenceFeature copy = new SequenceFeature(sf);
copy.setBegin(Math.min(mappedRange[0], mappedRange[1]));
copy.setEnd(Math.max(mappedRange[0], mappedRange[1]));
+ if (".".equals(copy.getFeatureGroup()))
+ {
+ copy.setFeatureGroup(getDbSource());
+ }
targetSequence.addSequenceFeature(copy);
/*
// long start = System.currentTimeMillis();
SequenceFeature[] sfs = sourceSequence.getSequenceFeatures();
- MapList mapping = getGenomicRangesFromFeatures(sourceSequence, accessionId,
- targetSequence.getStart());
+ MapList mapping = getGenomicRangesFromFeatures(sourceSequence,
+ accessionId, targetSequence.getStart());
if (mapping == null)
{
return false;
String type, String parentId)
{
List<SequenceFeature> result = new ArrayList<SequenceFeature>();
-
+
SequenceFeature[] sfs = sequence.getSequenceFeatures();
- if (sfs != null) {
+ if (sfs != null)
+ {
SequenceOntologyI so = SequenceOntologyFactory.getInstance();
- for (SequenceFeature sf :sfs) {
+ for (SequenceFeature sf : sfs)
+ {
if (so.isA(sf.getType(), type))
{
String parent = (String) sf.getValue(PARENT);
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
package jalview.ext.ensembl;
import jalview.datamodel.DBRefSource;
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
package jalview.ext.ensembl;
import java.io.BufferedReader;
/**
* Constructor given the target domain to fetch data from
*
- * @param d
+ * @param domain
+ * @param dbName
+ * @param dbVersion
*/
- public EnsemblSymbol(String d)
+ public EnsemblSymbol(String domain, String dbName, String dbVersion)
{
- super(d);
+ super(domain, dbName, dbVersion);
}
/**
protected URL getUrl(String id, Species species)
{
String url = getDomain() + "/xrefs/symbol/" + species.toString() + "/"
- + id
- + "?content-type=application/json";
+ + id + "?content-type=application/json";
try
{
return new URL(url);
List<String> result = new ArrayList<String>();
List<String> ids = new ArrayList<String>();
ids.add(identifier);
-
+
String[] queries = identifier.split(getAccessionSeparator());
BufferedReader br = null;
try
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
package jalview.ext.ensembl;
import jalview.datamodel.AlignmentI;
private static final String GO_GENE_ONTOLOGY = "GO";
+ private String dbName = "ENSEMBL (xref)";
+
/**
* Constructor given the target domain to fetch data from
*
* @param d
*/
- public EnsemblXref(String d)
+ public EnsemblXref(String d, String dbSource, String version)
{
super(d);
+ dbName = dbSource;
+ xrefVersion = dbSource + ":" + version;
+
}
@Override
public String getDbName()
{
- return "ENSEMBL (xref)";
+ return dbName;
}
@Override
if (dbName != null && id != null)
{
dbName = DBRefUtils.getCanonicalName(dbName);
- DBRefEntry dbref = new DBRefEntry(dbName, "0", id);
+ DBRefEntry dbref = new DBRefEntry(dbName, getXRefVersion(), id);
result.add(dbref);
}
}
return result;
}
+ private String xrefVersion = "ENSEMBL:0";
+
+ /**
+ * version string for Xrefs - for 2.10, hardwired for ENSEMBL:0
+ *
+ * @return
+ */
+ public String getXRefVersion()
+ {
+ return xrefVersion;
+ }
+
/**
* Returns the URL for the REST endpoint to fetch all cross-references for an
* identifier. Note this may return protein cross-references for nucleotide.
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
package jalview.ext.ensembl;
/**
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
package jalview.ext.htsjdk;
import htsjdk.samtools.SAMSequenceDictionary;
}
-
SAMSequenceDictionary rrefDict = null;
- private ReferenceSequenceFile initSequenceDictionaryFor(File dbLocation2) throws Exception
+
+ private ReferenceSequenceFile initSequenceDictionaryFor(File dbLocation2)
+ throws Exception
{
rrefDict = getDictionary(dbLocation2, true);
if (rrefDict != null)
{
- ReferenceSequenceFile rrefFile = ReferenceSequenceFileFactory.getReferenceSequenceFile(dbLocation2, true);
+ ReferenceSequenceFile rrefFile = ReferenceSequenceFileFactory
+ .getReferenceSequenceFile(dbLocation2, true);
return rrefFile;
}
return null;
}
+
/**
* code below hacked out from picard ----
*
* broadinstitute/picard/commit/270580d3e28123496576f0b91b3433179bb5d876
*/
-
/*
* The MIT License
*
import java.io.File;
import java.net.URL;
import java.security.AccessControlException;
+import java.util.ArrayList;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
boolean loadedInline;
- /**
- * current set of model filenames loaded in the Jmol instance
- */
- String[] modelFileNames = null;
-
StringBuffer resetLastRes = new StringBuffer();
public Viewer viewer;
{
// remove listeners for all structures in viewer
getSsm().removeStructureViewerListener(this, this.getPdbFile());
- viewer.dispose();
+ viewer.dispose();
lastCommand = null;
viewer = null;
releaseUIResources();
} catch (InterruptedException i)
{
}
- ;
}
+
+ /*
+ * get the distinct structure files modelled
+ * (a file with multiple chains may map to multiple sequences)
+ */
String[] files = getPdbFile();
if (!waitForFileLoad(files))
{
* 'matched' array will hold 'true' for visible alignment columns where
* all sequences have a residue with a mapping to the PDB structure
*/
+ // TODO could use a BitSet for matched
boolean matched[] = new boolean[alignment.getWidth()];
for (int m = 0; m < matched.length; m++)
{
* generate select statements to select regions to superimpose structures
*/
{
+ // TODO extract method to construct selection statements
for (int pdbfnum = 0; pdbfnum < files.length; pdbfnum++)
{
String chainCd = ":" + structures[pdbfnum].chain;
}
}
StringBuilder command = new StringBuilder(256);
+ // command.append("set spinFps 10;\n");
+
for (int pdbfnum = 0; pdbfnum < files.length; pdbfnum++)
{
if (pdbfnum == refStructure || selcom[pdbfnum] == null
}
if (selectioncom.length() > 0)
{
- System.out.println("Select regions:\n" + selectioncom.toString());
+ // TODO is performing selectioncom redundant here? is done later on
+ // System.out.println("Select regions:\n" + selectioncom.toString());
evalStateCommand("select *; cartoons off; backbone; select ("
+ selectioncom.toString() + "); cartoons; ");
// selcom.append("; ribbons; ");
String cmdString = command.toString();
- System.out.println("Superimpose command(s):\n" + cmdString);
+ // System.out.println("Superimpose command(s):\n" + cmdString);
evalStateCommand(cmdString);
}
{
selectioncom.setLength(selectioncom.length() - 1);
}
- System.out.println("Select regions:\n" + selectioncom.toString());
+ // System.out.println("Select regions:\n" + selectioncom.toString());
evalStateCommand("select *; cartoons off; backbone; select ("
+ selectioncom.toString() + "); cartoons; ");
// evalStateCommand("select *; backbone; select "+selcom.toString()+"; cartoons; center "+selcom.toString());
}
if (modelFileNames == null)
{
- String mset[] = new String[viewer.ms.mc];
- _modelFileNameMap = new int[mset.length];
+ List<String> mset = new ArrayList<String>();
+ _modelFileNameMap = new int[viewer.ms.mc];
String m = viewer.ms.getModelFileName(0);
if (m != null)
{
- mset[0] = m;
+ String filePath = m;
try
{
- mset[0] = new File(m).getAbsolutePath();
+ filePath = new File(m).getAbsolutePath();
} catch (AccessControlException x)
{
// usually not allowed to do this in applet
.println("jmolBinding: Using local file string from Jmol: "
+ m);
}
- if (mset[0].indexOf("/file:") != -1)
+ if (filePath.indexOf("/file:") != -1)
{
// applet path with docroot - discard as format won't match pdbfile
- mset[0] = m;
+ filePath = m;
}
+ mset.add(filePath);
_modelFileNameMap[0] = 0; // filename index for first model is always 0.
}
int j = 1;
- for (int i = 1; i < mset.length; i++)
+ for (int i = 1; i < viewer.ms.mc; i++)
{
m = viewer.ms.getModelFileName(i);
- mset[j] = m;
+ String filePath = m;
if (m != null)
{
try
{
- mset[j] = new File(m).getAbsolutePath();
+ filePath = new File(m).getAbsolutePath();
} catch (AccessControlException x)
{
// usually not allowed to do this in applet, so keep raw handle
// System.err.println("jmolBinding: Using local file string from Jmol: "+m);
}
}
- _modelFileNameMap[j] = i; // record the model index for the filename
- // skip any additional models in the same file (NMR structures)
- if ((mset[j] == null ? mset[j] != mset[j - 1]
- : (mset[j - 1] == null || !mset[j].equals(mset[j - 1]))))
+
+ /*
+ * add this model unless it is read from a structure file we have
+ * already seen (example: 2MJW is an NMR structure with 10 models)
+ */
+ if (!mset.contains(filePath))
{
+ mset.add(filePath);
+ _modelFileNameMap[j] = i; // record the model index for the filename
j++;
}
}
- modelFileNames = new String[j];
- System.arraycopy(mset, 0, modelFileNames, 0, j);
+ modelFileNames = mset.toArray(new String[mset.size()]);
}
return modelFileNames;
}
import jalview.datamodel.AlignmentAnnotation;
import jalview.datamodel.Annotation;
-import jalview.datamodel.DBRefSource;
+import jalview.datamodel.PDBEntry;
import jalview.datamodel.SequenceI;
import jalview.io.FileParse;
import jalview.io.StructureFile;
import jalview.schemes.ResidueProperties;
-import jalview.structure.StructureViewSettings;
+import jalview.structure.StructureImportSettings;
+import jalview.util.Format;
import jalview.util.MessageManager;
import java.io.IOException;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Vector;
{
Viewer viewer = null;
- public JmolParser(boolean addAlignmentAnnotations, boolean predictSecStr,
- boolean externalSecStr, String inFile, String type)
- throws IOException
+ public JmolParser(String inFile, String type) throws IOException
{
super(inFile, type);
}
- public JmolParser(boolean addAlignmentAnnotations, boolean predictSecStr,
- boolean externalSecStr, FileParse fp) throws IOException
+ public JmolParser(FileParse fp) throws IOException
{
super(fp);
}
@Override
public void parse() throws IOException
{
- String dataName = getDataName();
- if (dataName.endsWith(".cif"))
- {
- setDbRefType(DBRefSource.MMCIF);
- }
- else
- {
- setDbRefType(DBRefSource.PDB);
- }
setChains(new Vector<PDBChain>());
Viewer jmolModel = getJmolData();
jmolModel.openReader(getDataName(), getDataName(), getReader());
*/
if (jmolModel.ms.mc > 0)
{
+ // ideally we do this
+ // try
+ // {
+ // setStructureFileType(jmolModel.evalString("show _fileType"));
+ // } catch (Exception q)
+ // {
+ // }
+ // ;
+ // instead, we distinguish .cif from non-.cif by filename
+ setStructureFileType(getDataName().toLowerCase().endsWith(".cif") ? PDBEntry.Type.MMCIF
+ .toString() : "PDB");
+
transformJmolModelToJalview(jmolModel.ms);
}
}
{
try
{
+ /*
+ * params -o (output to sysout) -n (nodisplay) -x (exit when finished)
+ * see http://wiki.jmol.org/index.php/Jmol_Application
+ */
viewer = (Viewer) JmolViewer.allocateViewer(null, null, null, null,
null, "-x -o -n", this);
// ensure the 'new' (DSSP) not 'old' (Ramachandran) SS method is used
List<SequenceI> prot = new ArrayList<SequenceI>();
PDBChain tmpchain;
String pdbId = (String) ms.getInfo(0, "title");
- setId(pdbId);
+
+ if (pdbId == null)
+ {
+ setId(safeName(getDataName()));
+ setPDBIdAvailable(false);
+ }
+ else
+ {
+ setId(pdbId);
+ setPDBIdAvailable(true);
+ }
List<Atom> significantAtoms = convertSignificantAtoms(ms);
for (Atom tmpatom : significantAtoms)
{
tmpchain.atoms.addElement(tmpatom);
} catch (Exception e)
{
- tmpchain = new PDBChain(pdbId, tmpatom.chain);
+ tmpchain = new PDBChain(getId(), tmpatom.chain);
getChains().add(tmpchain);
tmpchain.atoms.addElement(tmpatom);
}
// documented and tested
setId(getDataName());
}
+
for (PDBChain chain : getChains())
{
SequenceI chainseq = postProcessChain(chain);
prot.add(chainseq);
}
- if (StructureViewSettings.isPredictSecondaryStructure())
+ if (StructureImportSettings.isProcessSecondaryStructure())
{
createAnnotation(chainseq, chain, ms.at);
}
private List<Atom> convertSignificantAtoms(ModelSet ms)
{
List<Atom> significantAtoms = new ArrayList<Atom>();
+ HashMap<String, org.jmol.modelset.Atom> chainTerMap = new HashMap<String, org.jmol.modelset.Atom>();
+ org.jmol.modelset.Atom prevAtom = null;
for (org.jmol.modelset.Atom atom : ms.at)
{
- // System.out.println("Seq Id : " + atom.getSeqID());
- // System.out.println("To String : " + atom.toString());
- if (atom.isHetero())
- {
- continue;
- }
if (atom.getAtomName().equalsIgnoreCase("CA")
|| atom.getAtomName().equalsIgnoreCase("P"))
{
+ if (!atomValidated(atom, prevAtom, chainTerMap))
+ {
+ continue;
+ }
Atom curAtom = new Atom(atom.x, atom.y, atom.z);
curAtom.atomIndex = atom.getIndex();
curAtom.chain = atom.getChainIDStr();
- curAtom.insCode = atom.group.getInsertionCode();
+ curAtom.insCode = atom.group.getInsertionCode() == '\000' ? ' '
+ : atom.group.getInsertionCode();
curAtom.name = atom.getAtomName();
curAtom.number = atom.getAtomNumber();
curAtom.resName = atom.getGroup3(true);
curAtom.resNumber = atom.getResno();
curAtom.occupancy = ms.occupancies != null ? ms.occupancies[atom
.getIndex()] : Float.valueOf(atom.getOccupancy100());
- curAtom.resNumIns = "" + curAtom.resNumber + curAtom.insCode;
+ String fmt = new Format("%4i").form(curAtom.resNumber);
+ curAtom.resNumIns = (fmt + curAtom.insCode);
curAtom.tfactor = atom.getBfactor100() / 100f;
curAtom.type = 0;
- significantAtoms.add(curAtom);
+ // significantAtoms.add(curAtom);
+ // ignore atoms from subsequent models
+ if (!significantAtoms.contains(curAtom))
+ {
+ significantAtoms.add(curAtom);
+ }
+ prevAtom = atom;
}
}
return significantAtoms;
}
+ private boolean atomValidated(org.jmol.modelset.Atom curAtom,
+ org.jmol.modelset.Atom prevAtom,
+ HashMap<String, org.jmol.modelset.Atom> chainTerMap)
+ {
+ // System.out.println("Atom: " + curAtom.getAtomNumber()
+ // + " Last atom index " + curAtom.group.lastAtomIndex);
+ if (chainTerMap == null || prevAtom == null)
+ {
+ return true;
+ }
+ String curAtomChId = curAtom.getChainIDStr();
+ String prevAtomChId = prevAtom.getChainIDStr();
+ // new chain encoutered
+ if (!prevAtomChId.equals(curAtomChId))
+ {
+ // On chain switch add previous chain termination to xTerMap if not exists
+ if (!chainTerMap.containsKey(prevAtomChId))
+ {
+ chainTerMap.put(prevAtomChId, prevAtom);
+ }
+ // if current atom belongs to an already terminated chain and the resNum
+ // diff < 5 then mark as valid and update termination Atom
+ if (chainTerMap.containsKey(curAtomChId))
+ {
+ if (curAtom.getResno() < chainTerMap.get(curAtomChId).getResno())
+ {
+ return false;
+ }
+ if ((curAtom.getResno() - chainTerMap.get(curAtomChId).getResno()) < 5)
+ {
+ chainTerMap.put(curAtomChId, curAtom);
+ return true;
+ }
+ return false;
+ }
+ }
+ // atom with previously terminated chain encountered
+ else if (chainTerMap.containsKey(curAtomChId))
+ {
+ if (curAtom.getResno() < chainTerMap.get(curAtomChId).getResno())
+ {
+ return false;
+ }
+ if ((curAtom.getResno() - chainTerMap.get(curAtomChId).getResno()) < 5)
+ {
+ chainTerMap.put(curAtomChId, curAtom);
+ return true;
+ }
+ return false;
+ }
+ // HETATM with resNum jump > 2
+ return !(curAtom.isHetero() && ((curAtom.getResno() - prevAtom
+ .getResno()) > 2));
+ }
+
private void createAnnotation(SequenceI sequence, PDBChain chain,
org.jmol.modelset.Atom[] jmolAtoms)
{
{
try
{
- asecstr[p] = new Annotation(String.valueOf(secstr[p]), null,
- secstrcode[p], Float.NaN);
- ssFound = true;
+ asecstr[p] = new Annotation(String.valueOf(secstr[p]), null,
+ secstrcode[p], Float.NaN);
+ ssFound = true;
} catch (Exception e)
{
// e.printStackTrace();
private String lastCommand;
- /*
- * current set of model filenames loaded
- */
- String[] modelFileNames = null;
-
String lastHighlightCommand;
/*
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
package jalview.ext.so;
import jalview.io.gff.SequenceOntologyI;
*/
protected void loadOntologyZipFile(String ontologyFile)
{
+ long now = System.currentTimeMillis();
ZipInputStream zipStream = null;
try
{
String zipFile = ontologyFile + ".zip";
- System.out.println("Loading Sequence Ontology from " + zipFile);
InputStream inStream = this.getClass().getResourceAsStream(
"/" + zipFile);
zipStream = new ZipInputStream(new BufferedInputStream(inStream));
loadOboFile(zipStream);
}
}
+ long elapsed = System.currentTimeMillis() - now;
+ System.out.println("Loaded Sequence Ontology from " + zipFile + " ("
+ + elapsed + "ms)");
} catch (Exception e)
{
e.printStackTrace();
}
else
{
- System.err.println("Warning: " + term.getName()
- + " has replaced " + replaced.getName()
- + " for lookup of '" + description + "'");
+ System.err.println("Warning: " + term.getName()
+ + " has replaced " + replaced.getName()
+ + " for lookup of '" + description + "'");
}
}
termsByDescription.put(description, term);
{
try
{
- if (Boolean.TRUE.equals(ann.getProperty("is_obsolete")))
- {
+ if (Boolean.TRUE.equals(ann.getProperty("is_obsolete")))
+ {
return true;
}
} catch (NoSuchElementException e)
public FTSDataColumnI getDataColumnByNameOrCode(String nameOrCode)
throws Exception;
-
/**
* Convert collection of FTSDataColumnI objects to a comma delimited string of
* the 'code' values
public String getDataColumnsFieldsAsCommaDelimitedString(
Collection<FTSDataColumnI> wantedFields);
-
/**
* Fetch index of the primary key column for the dynamic table
*
public int getPrimaryKeyColumIndex(
Collection<FTSDataColumnI> wantedFields, boolean hasRefSeq)
throws Exception;
-
+
/**
* Fetch the primary key data column object
*
*/
public int getDefaultResponsePageSize();
}
-
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
package jalview.fts.core;
import java.awt.Component;
return super.getTableCellRendererComponent(table, value, isSelected,
hasFocus, row, column);
}
-}
\ No newline at end of file
+}
import javax.swing.table.TableModel;
import javax.swing.table.TableRowSorter;
-
@SuppressWarnings("serial")
public class FTSDataColumnPreferences extends JScrollPane
{
if (source.equals(PreferenceSource.STRUCTURE_CHOOSER)
|| source.equals(PreferenceSource.PREFERENCES))
{
- structSummaryColumns = ((PDBFTSRestClient) ftsRestClient)
+ structSummaryColumns = ((PDBFTSRestClient) ftsRestClient)
.getAllDefaultDisplayedStructureDataColumns();
}
allFTSDataColumns.addAll(ftsRestClient.getAllFTSDataColumns());
{
case SEARCH_SUMMARY:
data[x++] = new Object[] {
- ftsRestClient.getAllDefaultDisplayedFTSDataColumns()
- .contains(field),
- field.getName(), field.getGroup() };
+ ftsRestClient.getAllDefaultDisplayedFTSDataColumns().contains(
+ field), field.getName(), field.getGroup() };
break;
case STRUCTURE_CHOOSER:
data[x++] = new Object[] { structSummaryColumns.contains(field),
field.getName(), field.getGroup() };
break;
case PREFERENCES:
- data[x++] = new Object[] { field.getName(),
- ftsRestClient.getAllDefaultDisplayedFTSDataColumns()
- .contains(field),
- structSummaryColumns.contains(field) };
+ data[x++] = new Object[] {
+ field.getName(),
+ ftsRestClient.getAllDefaultDisplayedFTSDataColumns().contains(
+ field), structSummaryColumns.contains(field) };
break;
default:
break;
map.put(field.getName(), field);
}
- FTSDataColumnPrefsTableModel model = new FTSDataColumnPrefsTableModel(columnNames, data);
+ FTSDataColumnPrefsTableModel model = new FTSDataColumnPrefsTableModel(
+ columnNames, data);
tbl_FTSDataColumnPrefs.setModel(model);
switch (source)
tbl_FTSDataColumnPrefs.getColumnModel().getColumn(1).setMinWidth(150);
tbl_FTSDataColumnPrefs.getColumnModel().getColumn(2)
.setPreferredWidth(150);
- tbl_FTSDataColumnPrefs.getColumnModel().getColumn(2)
-.setMinWidth(150);
+ tbl_FTSDataColumnPrefs.getColumnModel().getColumn(2).setMinWidth(150);
TableRowSorter<TableModel> sorter = new TableRowSorter<>(
tbl_FTSDataColumnPrefs.getModel());
sortKeys.add(new RowSorter.SortKey(columnIndexToSort,
SortOrder.ASCENDING));
sorter.setSortKeys(sortKeys);
- sorter.setComparator(
- columnIndexToSort,
+ sorter.setComparator(columnIndexToSort,
new Comparator<FTSDataColumnGroupI>()
{
@Override
class FTSDataColumnPrefsTableModel extends AbstractTableModel
{
- public FTSDataColumnPrefsTableModel(String[] columnNames, Object[][] data)
+ public FTSDataColumnPrefsTableModel(String[] columnNames,
+ Object[][] data)
{
this.data = data;
this.columnNames = columnNames;
if (currentSource == PreferenceSource.SEARCH_SUMMARY)
{
- updatePrefs(ftsRestClient
- .getAllDefaultDisplayedFTSDataColumns(), ftsDataColumn,
- selected);
+ updatePrefs(ftsRestClient.getAllDefaultDisplayedFTSDataColumns(),
+ ftsDataColumn, selected);
}
else if (currentSource == PreferenceSource.STRUCTURE_CHOOSER)
{
{
if (col == 1)
{
- updatePrefs(ftsRestClient
- .getAllDefaultDisplayedFTSDataColumns(), ftsDataColumn,
- selected);
+ updatePrefs(ftsRestClient.getAllDefaultDisplayedFTSDataColumns(),
+ ftsDataColumn, selected);
}
else if (col == 2)
{
}
}
- private void updatePrefs(
- Collection<FTSDataColumnI> prefConfig,
+ private void updatePrefs(Collection<FTSDataColumnI> prefConfig,
FTSDataColumnI dataColumn, boolean selected)
{
if (prefConfig.contains(dataColumn) && !selected)
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
package jalview.fts.core;
import jalview.fts.api.FTSDataColumnI;
public void parseDataColumnsConfigFile()
{
String fileName = getColumnDataConfigFileName();
-
- InputStream in = getClass().getResourceAsStream(fileName);
-
+
+ InputStream in = getClass().getResourceAsStream(fileName);
+
try (BufferedReader br = new BufferedReader(new InputStreamReader(in)))
{
String line;
this.getGroup());
}
-
@Override
public boolean equals(Object otherObject)
{
&& this.getGroup().equals(that.getGroup());
}
-
};
dataColumns.add(dataCol);
return result;
}
-
@Override
public Collection<FTSDataColumnI> getAllFTSDataColumns()
{
switch (code)
{
case 400:
- message = MessageManager
- .getString("exception.bad_request");
+ message = MessageManager.getString("exception.bad_request");
break;
-
+
case 410:
message = MessageManager.formatMessage(
"exception.fts_rest_service_no_longer_available", service);
case 502:
case 504:
case 505:
- message = MessageManager.getString("exception.fts_server_error");
+ message = MessageManager.formatMessage("exception.fts_server_error",
+ service);
break;
case 503:
message = MessageManager.getString("exception.service_not_available");
return wantedFields;
}
- public void setWantedFields(
- Collection<FTSDataColumnI> wantedFields)
+ public void setWantedFields(Collection<FTSDataColumnI> wantedFields)
{
this.wantedFields = wantedFields;
}
public static DefaultTableModel getTableModel(FTSRestRequest request,
Collection<FTSData> summariesList)
{
- final FTSDataColumnI[] cols = request.getWantedFields()
- .toArray(new FTSDataColumnI[0]);
+ final FTSDataColumnI[] cols = request.getWantedFields().toArray(
+ new FTSDataColumnI[0]);
final int colOffset = request.getAssociatedSequence() == null ? 0 : 1;
DefaultTableModel tableModel = new DefaultTableModel()
{
tableModel.addColumn("Ref Sequence"); // Create sequence column header if
// exists in the request
}
- for (FTSDataColumnI field : request
- .getWantedFields())
+ for (FTSDataColumnI field : request.getWantedFields())
{
tableModel.addColumn(field.getName()); // Create sequence column header if
// exists in the request
}
}
-
}
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
+import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.KeyAdapter;
protected JInternalFrame mainFrame = new JInternalFrame(
getFTSFrameTitle());
- protected IProgressIndicator progressIdicator;
+ protected IProgressIndicator progressIndicator;
protected JComboBox<FTSDataColumnI> cmb_searchTarget = new JComboBox<FTSDataColumnI>();
protected static final DecimalFormat totalNumberformatter = new DecimalFormat(
"###,###");
+
private JTable tbl_summary = new JTable()
{
private boolean inLayout;
return toolTipText;
}
};
+
protected JScrollPane scrl_searchResult = new JScrollPane(tbl_summary);
public GFTSPanel()
try
{
jbInit();
+ mainFrame.addFocusListener(new FocusAdapter()
+ {
+ @Override
+ public void focusGained(FocusEvent e)
+ {
+ txt_search.requestFocusInWindow();
+ }
+ });
mainFrame.invalidate();
mainFrame.pack();
} catch (Exception e)
});
final DeferredTextInputListener listener = new DeferredTextInputListener(
- 1500,
- new ActionListener()
+ 1500, new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
@Override
public void focusLost(FocusEvent e)
{
-// listener.stop();
+ // listener.stop();
}
});
txt_search.setEnabled(false);
cmb_searchTarget.setEnabled(false);
previousWantedFields = getFTSRestClient()
- .getAllDefaultDisplayedFTSDataColumns()
- .toArray(new Object[0]);
+ .getAllDefaultDisplayedFTSDataColumns().toArray(
+ new Object[0]);
}
if (sourceTabbedPane.getTitleAt(index).equals(searchTabTitle))
{
getTempUserPrefs().put("FTSPanel.y", mainFrame.getY());
mainFrame.dispose();
}
+
public class DeferredTextInputListener implements DocumentListener
{
private final Timer swingTimer;
}
return Arrays.equals(getFTSRestClient()
- .getAllDefaultDisplayedFTSDataColumns()
- .toArray(new Object[0]), previousWantedFields) ? false
- : true;
+ .getAllDefaultDisplayedFTSDataColumns().toArray(new Object[0]),
+ previousWantedFields) ? false : true;
}
protected void btn_back_ActionPerformed()
{
closeAction();
- new SequenceFetcher(progressIdicator);
+ new SequenceFetcher(progressIndicator);
}
protected void disableActionButtons()
}
}
-
public void transferToSequenceFetcher(String ids)
{
// mainFrame.dispose();
int[] selectedRows = resultTable.getSelectedRows();
for (int summaryRow : selectedRows)
{
- String idStr = resultTable.getValueAt(summaryRow,
- primaryKeyColIndex).toString();
+ String idStr = resultTable.getValueAt(summaryRow, primaryKeyColIndex)
+ .toString();
paginatorCart.add(idStr);
}
// System.out.println("Paginator shopping cart size : "
}
validateSelection();
}
+
public void refreshPaginatorState()
{
// System.out.println("resultSet count : " + resultSetCount);
setPrevPageButtonEnabled(true);
}
}
+
public void referesh()
{
mainFrame.setTitle(getFTSFrameTitle());
public PDBFTSPanel(SequenceFetcher seqFetcher)
{
+ super();
pageLimit = PDBFTSRestClient.getInstance().getDefaultResponsePageSize();
this.seqFetcher = seqFetcher;
- this.progressIdicator = (seqFetcher == null) ? null : seqFetcher
+ this.progressIndicator = (seqFetcher == null) ? null : seqFetcher
.getProgressIndicator();
}
-
@Override
public void searchAction(boolean isFreshSearch)
{
{
getResultTable().setModel(
FTSRestResponse.getTableModel(request,
- resultList.getSearchSummary()));
+ resultList.getSearchSummary()));
FTSRestResponse.configureTableColumn(getResultTable(),
wantedFields, tempUserPrefs);
getResultTable().setVisible(true);
String result = (resultSetCount > 0) ? MessageManager
.getString("label.results") : MessageManager
.getString("label.result");
-
+
if (isPaginationEnabled() && resultSetCount > 0)
{
- updateSearchFrameTitle(defaultFTSFrameTitle + " - " + result
+ updateSearchFrameTitle(defaultFTSFrameTitle
+ + " - "
+ + result
+ " "
+ totalNumberformatter.format((Number) (offSet + 1))
+ " to "
.format((Number) (offSet + resultSetCount))
+ " of "
+ totalNumberformatter
- .format((Number) totalResultSetCount)
- + " " + " (" + (endTime - startTime) + " milli secs)");
+ .format((Number) totalResultSetCount) + " "
+ + " (" + (endTime - startTime) + " milli secs)");
}
else
{
+ resultSetCount + " " + result + " ("
+ (endTime - startTime) + " milli secs)");
}
-
+
setSearchInProgress(false);
refreshPaginatorState();
updateSummaryTableSelections();
try
{
primaryKeyColIndex = getFTSRestClient().getPrimaryKeyColumIndex(
- wantedFields,
- false);
+ wantedFields, false);
} catch (Exception e)
{
e.printStackTrace();
for (int summaryRow : selectedRows)
{
String idStr = getResultTable().getValueAt(summaryRow,
- primaryKeyColIndex)
- .toString();
+ primaryKeyColIndex).toString();
selectedIdsSet.add(getPDBIdwithSpecifiedChain(idStr, searchTerm));
}
delayAndEnableActionButtons();
}
-
public static String getPDBIdwithSpecifiedChain(String pdbId,
String searchTerm)
{
.queryParam("wt", "json").queryParam("fl", wantedFields)
.queryParam("rows", String.valueOf(responseSize))
.queryParam("start", String.valueOf(offSet))
- .queryParam("q", query)
- .queryParam("sort", sortParam);
+ .queryParam("q", query).queryParam("sort", sortParam);
}
// Execute the REST request
ClientResponse clientResponse = webResource.accept(
}
else
{
- errorMessage = getMessageByHTTPStatusCode(clientResponse
-.getStatus(), "PDB");
+ errorMessage = getMessageByHTTPStatusCode(
+ clientResponse.getStatus(), "PDB");
throw new Exception(errorMessage);
}
}
}
}
-
/**
* Process error response from PDB server if/when one occurs.
*
{
summaryRowData[colCounter++] = (field.getDataType()
.getDataTypeClass() == Integer.class) ? Integer
- .valueOf(fieldData)
- : (field.getDataType()
+ .valueOf(fieldData) : (field.getDataType()
.getDataTypeClass() == Double.class) ? Double
- .valueOf(fieldData)
- : sanitiseData(fieldData);
+ .valueOf(fieldData) : sanitiseData(fieldData);
} catch (Exception e)
{
e.printStackTrace();
- System.out.println("offending value:" + fieldData);
+ System.out.println("offending value:" + fieldData);
}
}
}
return "/fts/pdb_data_columns.txt";
}
-
public static FTSRestClientI getInstance()
{
if (instance == null)
summaryRowData[colCounter++] = (field.getDataType()
.getDataTypeClass() == Integer.class) ? Integer
.valueOf(fieldData.replace(",", ""))
- : (field.getDataType()
- .getDataTypeClass() == Double.class) ? Double
+ : (field.getDataType().getDataTypeClass() == Double.class) ? Double
.valueOf(fieldData) : fieldData;
} catch (Exception e)
{
e.printStackTrace();
- System.out.println("offending value:" + fieldData);
+ System.out.println("offending value:" + fieldData);
}
}
} catch (Exception e)
};
}
-
public static FTSRestClientI getInstance()
{
if (instance == null)
public UniprotFTSPanel(SequenceFetcher seqFetcher)
{
+ super();
pageLimit = UniProtFTSRestClient.getInstance()
.getDefaultResponsePageSize();
this.seqFetcher = seqFetcher;
- this.progressIdicator = (seqFetcher == null) ? null : seqFetcher
+ this.progressIndicator = (seqFetcher == null) ? null : seqFetcher
.getProgressIndicator();
}
offSet = 0;
}
new Thread()
- {
+ {
@Override
public void run()
{
.getString("label.result");
if (isPaginationEnabled() && resultSetCount > 0)
{
- updateSearchFrameTitle(defaultFTSFrameTitle + " - " + result
+ updateSearchFrameTitle(defaultFTSFrameTitle
+ + " - "
+ + result
+ " "
+ totalNumberformatter.format((Number) (offSet + 1))
+ " to "
.format((Number) (offSet + resultSetCount))
+ " of "
+ totalNumberformatter
- .format((Number) totalResultSetCount)
- + " " + " (" + (endTime - startTime) + " milli secs)");
+ .format((Number) totalResultSetCount) + " "
+ + " (" + (endTime - startTime) + " milli secs)");
}
else
{
return foundSearchTerms;
}
-
@Override
public boolean isPaginationEnabled()
{
import jalview.api.AlignViewportI;
import jalview.api.AlignmentViewPanel;
import jalview.api.FeatureSettingsControllerI;
-import jalview.api.FeatureSettingsModelI;
import jalview.api.SplitContainerI;
import jalview.api.ViewStyleI;
import jalview.api.analysis.ScoreModelI;
import jalview.datamodel.AlignmentOrder;
import jalview.datamodel.AlignmentView;
import jalview.datamodel.ColumnSelection;
-import jalview.datamodel.DBRefSource;
import jalview.datamodel.HiddenSequences;
import jalview.datamodel.PDBEntry;
import jalview.datamodel.SeqCigar;
import jalview.io.JnetAnnotationMaker;
import jalview.io.NewickFile;
import jalview.io.TCoffeeScoreFile;
-import jalview.io.gff.SequenceOntologyI;
import jalview.jbgui.GAlignFrame;
import jalview.schemes.Blosum62ColourScheme;
import jalview.schemes.BuriedColourScheme;
import jalview.schemes.TurnColourScheme;
import jalview.schemes.UserColourScheme;
import jalview.schemes.ZappoColourScheme;
-import jalview.structure.StructureSelectionManager;
import jalview.util.MessageManager;
import jalview.viewmodel.AlignmentViewport;
import jalview.ws.DBRefFetcher;
import jalview.ws.DBRefFetcher.FetchFinishedListenerI;
-import jalview.ws.SequenceFetcher;
import jalview.ws.jws1.Discoverer;
import jalview.ws.jws2.Jws2Discoverer;
import jalview.ws.jws2.jabaws2.Jws2Instance;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.StringSelection;
import java.awt.datatransfer.Transferable;
+import java.awt.dnd.DnDConstants;
import java.awt.dnd.DropTargetDragEvent;
import java.awt.dnd.DropTargetDropEvent;
import java.awt.dnd.DropTargetEvent;
showGroupConservation.setEnabled(!nucleotide);
rnahelicesColour.setEnabled(nucleotide);
purinePyrimidineColour.setEnabled(nucleotide);
- showComplementMenuItem.setText(MessageManager
- .getString(nucleotide ? "label.protein" : "label.nucleotide"));
+ showComplementMenuItem.setText(nucleotide ? MessageManager
+ .getString("label.protein") : MessageManager
+ .getString("label.nucleotide"));
setColourSelected(jalview.bin.Cache.getDefault(
nucleotide ? Preferences.DEFAULT_COLOUR_NUC
: Preferences.DEFAULT_COLOUR_PROT, "None"));
public void bioJSMenuItem_actionPerformed(ActionEvent e)
{
BioJsHTMLOutput bjs = new BioJsHTMLOutput(alignPanel, this);
- bjs.exportJalviewAlignmentAsBioJsHtmlFile();
+ bjs.exportJalviewAlignmentAsBioJsHtmlFile(null);
}
public void createImageMap(File file, String image)
sg.setEndRes(viewport.getAlignment().getWidth() - 1);
viewport.setSelectionGroup(sg);
viewport.sendSelection();
- alignPanel.paintAlignment(true);
+ // JAL-2034 - should delegate to
+ // alignPanel to decide if overview needs
+ // updating.
+ alignPanel.paintAlignment(false);
PaintRefresher.Refresh(alignPanel, viewport.getSequenceSetId());
}
viewport.setSelectionGroup(null);
alignPanel.getSeqPanel().seqCanvas.highlightSearchResults(null);
alignPanel.getIdPanel().getIdCanvas().searchResults = null;
- alignPanel.paintAlignment(true);
+ // JAL-2034 - should delegate to
+ // alignPanel to decide if overview needs
+ // updating.
+ alignPanel.paintAlignment(false);
PaintRefresher.Refresh(alignPanel, viewport.getSequenceSetId());
viewport.sendSelection();
}
{
sg.addOrRemove(viewport.getAlignment().getSequenceAt(i), false);
}
+ // JAL-2034 - should delegate to
+ // alignPanel to decide if overview needs
+ // updating.
alignPanel.paintAlignment(true);
PaintRefresher.Refresh(alignPanel, viewport.getSequenceSetId());
@Override
public void expandViews_actionPerformed(ActionEvent e)
{
- Desktop.instance.explodeViews(this);
+ Desktop.explodeViews(this);
}
/**
// Hide everything by the current selection - this is a hack - we do the
// invert and then hide
// first check that there will be visible columns after the invert.
- if ((viewport.getColumnSelection() != null
- && viewport.getColumnSelection().getSelected() != null && viewport
- .getColumnSelection().getSelected().size() > 0)
+ if (viewport.hasSelectedColumns()
|| (sg != null && sg.getSize() > 0 && sg.getStartRes() <= sg
.getEndRes()))
{
hideSelSequences_actionPerformed(null);
hide = true;
}
- else if (!(toggleCols && viewport.getColumnSelection().getSelected()
- .size() > 0))
+ else if (!(toggleCols && viewport.hasSelectedColumns()))
{
showAllSeqs_actionPerformed(null);
}
if (toggleCols)
{
- if (viewport.getColumnSelection().getSelected().size() > 0)
+ if (viewport.hasSelectedColumns())
{
hideSelColumns_actionPerformed(null);
if (!toggleSeqs)
}
/**
- * Set or clear 'Show Sequence Features'
- *
- * @param evt
- * DOCUMENT ME!
- */
- @Override
- public void showSeqFeaturesHeight_actionPerformed(ActionEvent evt)
- {
- viewport.setShowSequenceFeaturesHeight(showSeqFeaturesHeight
- .isSelected());
- if (viewport.isShowSequenceFeaturesHeight())
- {
- // ensure we're actually displaying features
- viewport.setShowSequenceFeatures(true);
- showSeqFeatures.setSelected(true);
- }
- alignPanel.paintAlignment(true);
- if (alignPanel.getOverviewPanel() != null)
- {
- alignPanel.getOverviewPanel().updateOverviewImage();
- }
- }
-
- /**
* Action on toggle of the 'Show annotations' menu item. This shows or hides
* the annotations panel as a whole.
*
@Override
public void mousePressed(MouseEvent evt)
{
- if (evt.isPopupTrigger())
+ if (evt.isPopupTrigger()) // Mac
{
- radioItem.removeActionListener(radioItem.getActionListeners()[0]);
+ offerRemoval(radioItem);
+ }
+ }
- int option = JOptionPane.showInternalConfirmDialog(
- jalview.gui.Desktop.desktop,
- MessageManager
- .getString("label.remove_from_default_list"),
- MessageManager
- .getString("label.remove_user_defined_colour"),
- JOptionPane.YES_NO_OPTION);
- if (option == JOptionPane.YES_OPTION)
- {
- jalview.gui.UserDefinedColours
- .removeColourFromDefaults(radioItem.getText());
- colourMenu.remove(radioItem);
- }
- else
+ @Override
+ public void mouseReleased(MouseEvent evt)
+ {
+ if (evt.isPopupTrigger()) // Windows
+ {
+ offerRemoval(radioItem);
+ }
+ }
+
+ /**
+ * @param radioItem
+ */
+ void offerRemoval(final JRadioButtonMenuItem radioItem)
+ {
+ radioItem.removeActionListener(radioItem.getActionListeners()[0]);
+
+ int option = JOptionPane.showInternalConfirmDialog(
+ jalview.gui.Desktop.desktop, MessageManager
+ .getString("label.remove_from_default_list"),
+ MessageManager
+ .getString("label.remove_user_defined_colour"),
+ JOptionPane.YES_NO_OPTION);
+ if (option == JOptionPane.YES_OPTION)
+ {
+ jalview.gui.UserDefinedColours
+ .removeColourFromDefaults(radioItem.getText());
+ colourMenu.remove(radioItem);
+ }
+ else
+ {
+ radioItem.addActionListener(new ActionListener()
{
- radioItem.addActionListener(new ActionListener()
+ @Override
+ public void actionPerformed(ActionEvent evt)
{
- @Override
- public void actionPerformed(ActionEvent evt)
- {
- userDefinedColour_actionPerformed(evt);
- }
- });
- }
+ userDefinedColour_actionPerformed(evt);
+ }
+ });
}
}
});
// object broker mechanism.
final Vector<JMenu> wsmenu = new Vector<JMenu>();
final IProgressIndicator af = me;
+
+ /*
+ * do not i18n these strings - they are hard-coded in class
+ * compbio.data.msa.Category, Jws2Discoverer.isRecalculable() and
+ * SequenceAnnotationWSClient.initSequenceAnnotationWSClient()
+ */
final JMenu msawsmenu = new JMenu("Alignment");
final JMenu secstrmenu = new JMenu(
"Secondary Structure Prediction");
final JMenu seqsrchmenu = new JMenu("Sequence Database Search");
final JMenu analymenu = new JMenu("Analysis");
final JMenu dismenu = new JMenu("Protein Disorder");
- // final JMenu msawsmenu = new
- // JMenu(MessageManager.getString("label.alignment"));
- // final JMenu secstrmenu = new
- // JMenu(MessageManager.getString("label.secondary_structure_prediction"));
- // final JMenu seqsrchmenu = new
- // JMenu(MessageManager.getString("label.sequence_database_search"));
- // final JMenu analymenu = new
- // JMenu(MessageManager.getString("label.analysis"));
- // final JMenu dismenu = new
- // JMenu(MessageManager.getString("label.protein_disorder"));
// JAL-940 - only show secondary structure prediction services from
// the legacy server
if (// Cache.getDefault("SHOW_JWS1_SERVICES", true)
}
/**
- * Searches selected sequences for xRef products and builds the Show
- * Cross-References menu (formerly called Show Products)
+ * Searches the alignment sequences for xRefs and builds the Show
+ * Cross-References menu (formerly called Show Products), with database
+ * sources for which cross-references are found (protein sources for a
+ * nucleotide alignment and vice versa)
*
- * @return true if Show Cross-references menu should be enabled.
+ * @return true if Show Cross-references menu should be enabled
*/
public boolean canShowProducts()
{
- SequenceI[] selection = viewport.getSequenceSelection();
+ SequenceI[] seqs = viewport.getAlignment().getSequencesArray();
AlignmentI dataset = viewport.getAlignment().getDataset();
+
+ showProducts.removeAll();
+ final boolean dna = viewport.getAlignment().isNucleotide();
+
+ if (seqs == null || seqs.length == 0)
+ {
+ // nothing to see here.
+ return false;
+ }
+
boolean showp = false;
try
{
- showProducts.removeAll();
- final boolean dna = viewport.getAlignment().isNucleotide();
- String[] ptypes = (selection == null || selection.length == 0) ? null
- : CrossRef.findSequenceXrefTypes(dna, selection, dataset);
+ List<String> ptypes = new CrossRef(seqs, dataset)
+ .findXrefSourcesForSequences(dna);
- for (int t = 0; ptypes != null && t < ptypes.length; t++)
+ for (final String source : ptypes)
{
showp = true;
final AlignFrame af = this;
- final String source = ptypes[t];
- JMenuItem xtype = new JMenuItem(ptypes[t]);
+ JMenuItem xtype = new JMenuItem(source);
xtype.addActionListener(new ActionListener()
{
-
@Override
public void actionPerformed(ActionEvent e)
{
showProductsFor(af.viewport.getSequenceSelection(), dna, source);
}
-
});
showProducts.add(xtype);
}
showProducts.setEnabled(showp);
} catch (Exception e)
{
- jalview.bin.Cache.log
+ Cache.log
.warn("canShowProducts threw an exception - please report to help@jalview.org",
e);
return false;
* @param source
* the database to show cross-references for
*/
- protected void showProductsFor(final SequenceI[] sel, final boolean dna,
- final String source)
+ protected void showProductsFor(final SequenceI[] sel,
+ final boolean _odna, final String source)
{
- Runnable foo = new Runnable()
- {
-
- @Override
- public void run()
- {
- final long sttime = System.currentTimeMillis();
- AlignFrame.this.setProgressBar(MessageManager.formatMessage(
- "status.searching_for_sequences_from",
- new Object[] { source }), sttime);
- try
- {
- AlignmentI alignment = AlignFrame.this.getViewport()
- .getAlignment();
- AlignmentI xrefs = CrossRef.findXrefSequences(sel, dna, source,
- alignment);
- if (xrefs != null)
- {
- /*
- * get display scheme (if any) to apply to features
- */
- FeatureSettingsModelI featureColourScheme = new SequenceFetcher()
- .getFeatureColourScheme(source);
-
- AlignmentI al = makeCrossReferencesAlignment(
- alignment.getDataset(), xrefs);
-
- AlignFrame newFrame = new AlignFrame(al, DEFAULT_WIDTH,
- DEFAULT_HEIGHT);
- if (Cache.getDefault("HIDE_INTRONS", true))
- {
- newFrame.hideFeatureColumns(SequenceOntologyI.EXON, false);
- }
- String newtitle = String.format("%s %s %s",
- MessageManager.getString(dna ? "label.proteins"
- : "label.nucleotides"), MessageManager
- .getString("label.for"), getTitle());
- newFrame.setTitle(newtitle);
-
- if (!Cache.getDefault(Preferences.ENABLE_SPLIT_FRAME, true))
- {
- /*
- * split frame display is turned off in preferences file
- */
- Desktop.addInternalFrame(newFrame, newtitle, DEFAULT_WIDTH,
- DEFAULT_HEIGHT);
- return; // via finally clause
- }
-
- /*
- * Make a copy of this alignment (sharing the same dataset
- * sequences). If we are DNA, drop introns and update mappings
- */
- AlignmentI copyAlignment = null;
- final SequenceI[] sequenceSelection = AlignFrame.this.viewport
- .getSequenceSelection();
- List<AlignedCodonFrame> cf = xrefs.getCodonFrames();
- boolean copyAlignmentIsAligned = false;
- if (dna)
- {
- copyAlignment = AlignmentUtils.makeCdsAlignment(
- sequenceSelection, cf, alignment);
- if (copyAlignment.getHeight() == 0)
- {
- System.err.println("Failed to make CDS alignment");
- }
- al.getCodonFrames().clear();
- al.addCodonFrames(copyAlignment.getCodonFrames());
- al.addCodonFrames(cf);
-
- /*
- * pending getting Embl transcripts to 'align',
- * we are only doing this for Ensembl
- */
- // TODO proper criteria for 'can align as cdna'
- if (DBRefSource.ENSEMBL.equalsIgnoreCase(source)
- || AlignmentUtils.looksLikeEnsembl(alignment))
- {
- copyAlignment.alignAs(alignment);
- copyAlignmentIsAligned = true;
- }
- }
- else
- {
- copyAlignment = AlignmentUtils.makeCopyAlignment(
- sequenceSelection, xrefs.getSequencesArray());
- copyAlignment.addCodonFrames(cf);
- al.addCodonFrames(copyAlignment.getCodonFrames());
- al.addCodonFrames(cf);
- }
- copyAlignment.setGapCharacter(AlignFrame.this.viewport
- .getGapCharacter());
-
- StructureSelectionManager ssm = StructureSelectionManager
- .getStructureSelectionManager(Desktop.instance);
- ssm.registerMappings(cf);
-
- if (copyAlignment.getHeight() <= 0)
- {
- System.err.println("No Sequences generated for xRef type "
- + source);
- return;
- }
- /*
- * align protein to dna
- */
- if (dna && copyAlignmentIsAligned)
- {
- al.alignAs(copyAlignment);
- }
- else
- {
- /*
- * align cdna to protein - currently only if
- * fetching and aligning Ensembl transcripts!
- */
- if (DBRefSource.ENSEMBL.equalsIgnoreCase(source))
- {
- copyAlignment.alignAs(al);
- }
- }
-
- AlignFrame copyThis = new AlignFrame(copyAlignment,
- AlignFrame.DEFAULT_WIDTH, AlignFrame.DEFAULT_HEIGHT);
- copyThis.setTitle(AlignFrame.this.getTitle());
-
- boolean showSequenceFeatures = viewport
- .isShowSequenceFeatures();
- newFrame.setShowSeqFeatures(showSequenceFeatures);
- copyThis.setShowSeqFeatures(showSequenceFeatures);
- FeatureRenderer myFeatureStyling = alignPanel.getSeqPanel().seqCanvas
- .getFeatureRenderer();
-
- /*
- * copy feature rendering settings to split frame
- */
- newFrame.alignPanel.getSeqPanel().seqCanvas
- .getFeatureRenderer()
- .transferSettings(myFeatureStyling);
- copyThis.alignPanel.getSeqPanel().seqCanvas
- .getFeatureRenderer()
- .transferSettings(myFeatureStyling);
-
- /*
- * apply 'database source' feature configuration
- * if any was found
- */
- // TODO is this the feature colouring for the original
- // alignment or the fetched xrefs? either could be Ensembl
- newFrame.getViewport().applyFeaturesStyle(featureColourScheme);
- copyThis.getViewport().applyFeaturesStyle(featureColourScheme);
-
- SplitFrame sf = new SplitFrame(dna ? copyThis : newFrame,
- dna ? newFrame : copyThis);
- newFrame.setVisible(true);
- copyThis.setVisible(true);
- String linkedTitle = MessageManager
- .getString("label.linked_view_title");
- Desktop.addInternalFrame(sf, linkedTitle, -1, -1);
- sf.adjustDivider();
- }
- } catch (Exception e)
- {
- Cache.log.error("Exception when finding crossreferences", e);
- } catch (OutOfMemoryError e)
- {
- new OOMWarning("whilst fetching crossreferences", e);
- } catch (Throwable e)
- {
- Cache.log.error("Error when finding crossreferences", e);
- } finally
- {
- AlignFrame.this.setProgressBar(MessageManager.formatMessage(
- "status.finished_searching_for_sequences_from",
- new Object[] { source }), sttime);
- }
- }
-
- /**
- * Makes an alignment containing the given sequences. If this is of the
- * same type as the given dataset (nucleotide/protein), then the new
- * alignment shares the same dataset, and its dataset sequences are added
- * to it. Otherwise a new dataset sequence is created for the
- * cross-references.
- *
- * @param dataset
- * @param seqs
- * @return
- */
- protected AlignmentI makeCrossReferencesAlignment(AlignmentI dataset,
- AlignmentI seqs)
- {
- boolean sameType = dataset.isNucleotide() == seqs.isNucleotide();
-
- SequenceI[] sprods = new SequenceI[seqs.getHeight()];
- for (int s = 0; s < sprods.length; s++)
- {
- sprods[s] = (seqs.getSequenceAt(s)).deriveSequence();
- if (sameType)
- {
- if (dataset.getSequences() == null
- || !dataset.getSequences().contains(
- sprods[s].getDatasetSequence()))
- {
- dataset.addSequence(sprods[s].getDatasetSequence());
- }
- }
- sprods[s].updatePDBIds();
- }
- Alignment al = new Alignment(sprods);
- if (sameType)
- {
- al.setDataset((Alignment) dataset);
- }
- else
- {
- al.createDatasetAlignment();
- }
- return al;
- }
-
- };
- Thread frunner = new Thread(foo);
- frunner.start();
+ new Thread(CrossRefAction.showProductsFor(sel, _odna, source, this))
+ .start();
}
/**
@Override
public void drop(DropTargetDropEvent evt)
{
+ // JAL-1552 - acceptDrop required before getTransferable call for
+ // Java's Transferable for native dnd
+ evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
Transferable t = evt.getTransferable();
java.util.List<String> files = new ArrayList<String>(), protocols = new ArrayList<String>();
}
if (type != null)
{
- if (type.equalsIgnoreCase("PDB"))
+ if (type.equalsIgnoreCase("PDB")
+ || type.equalsIgnoreCase("mmCIF"))
{
filesmatched.add(new Object[] { file, protocol, mtch });
continue;
this,
MessageManager
.formatMessage(
- "label.automatically_associate_pdb_files_with_sequences_same_name",
+ "label.automatically_associate_structure_files_with_sequences_same_name",
new Object[] { Integer
.valueOf(
filesmatched
.size())
.toString() }),
MessageManager
- .getString("label.automatically_associate_pdb_files_by_name"),
+ .getString("label.automatically_associate_structure_files_by_name"),
JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION)
{
* along with Jalview. If not, see <http://www.gnu.org/licenses/>.
* The Jalview Authors are detailed in the 'AUTHORS' file.
*/
-/*
- * Jalview - A Sequence Alignment Editor and Viewer
- * Copyright (C) 2007 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
package jalview.gui;
import jalview.analysis.AlignmentUtils;
* @param align
* DOCUMENT ME!
*/
+ @Override
public void setAlignment(AlignmentI align)
{
replaceMappings(align);
- this.alignment = align;
+ super.setAlignment(align);
}
/**
/**
* DOCUMENT ME!
*
- * @return DOCUMENT ME!
- */
- @Override
- public ColumnSelection getColumnSelection()
- {
- return colSel;
- }
-
- /**
- * DOCUMENT ME!
- *
* @param tree
* DOCUMENT ME!
*/
List<SequenceI> choosenSeqs = new ArrayList<SequenceI>();
for (SequenceI sq : alignment.getSequences())
{
- Vector<PDBEntry> pdbRefEntries = sq.getDatasetSequence().getAllPDBEntries();
+ Vector<PDBEntry> pdbRefEntries = sq.getDatasetSequence()
+ .getAllPDBEntries();
if (pdbRefEntries == null)
{
continue;
}
}
}
- seqvectors.add(choosenSeqs.toArray(new SequenceI[choosenSeqs.size()]));
+ seqvectors
+ .add(choosenSeqs.toArray(new SequenceI[choosenSeqs.size()]));
}
return seqvectors.toArray(new SequenceI[seqvectors.size()][]);
}
*/
private boolean dontScrollComplement;
+ private PropertyChangeListener propertyChangeListener;
+
/**
* Creates a new AlignmentPanel object.
*
vscroll.addAdjustmentListener(this);
final AlignmentPanel ap = this;
- av.addPropertyChangeListener(new PropertyChangeListener()
+ propertyChangeListener = new PropertyChangeListener()
{
@Override
public void propertyChange(PropertyChangeEvent evt)
alignmentChanged();
}
}
- });
+ };
+ av.addPropertyChangeListener(propertyChangeListener);
fontChanged();
adjustAnnotationHeight();
updateLayout();
void makeAlignmentImage(jalview.util.ImageMaker.TYPE type, File file)
{
+ int boarderBottomOffset = 5;
long pSessionId = System.currentTimeMillis();
headless = (System.getProperty("java.awt.headless") != null && System
.getProperty("java.awt.headless").equals("true"));
if (file != null)
{
alignFrame.setProgressBar(MessageManager.formatMessage(
- "status.saving_file", new Object[] { type.getLabel() }),
+ "status.saving_file", new Object[] { type.getLabel() }),
pSessionId);
}
}
}
im = new jalview.util.ImageMaker(this, type, imageAction,
- aDimension.getWidth(), aDimension.getHeight(), file,
- imageTitle, alignFrame, pSessionId, headless);
+ aDimension.getWidth(), aDimension.getHeight()
+ + boarderBottomOffset, file, imageTitle,
+ alignFrame, pSessionId, headless);
if (av.getWrapAlignment())
{
if (im.getGraphics() != null)
{
printWrappedAlignment(im.getGraphics(), aDimension.getWidth(),
- aDimension.getHeight(), 0);
+ aDimension.getHeight() + boarderBottomOffset, 0);
im.writeImage();
}
}
PaintRefresher.RemoveComponent(getSeqPanel().seqCanvas);
PaintRefresher.RemoveComponent(getIdPanel().getIdCanvas());
PaintRefresher.RemoveComponent(this);
+
+ /*
+ * try to ensure references are nulled
+ */
+ if (annotationPanel != null)
+ {
+ annotationPanel.dispose();
+ }
+
if (av != null)
{
+ av.removePropertyChangeListener(propertyChangeListener);
jalview.structure.StructureSelectionManager ssm = av
.getStructureSelectionManager();
ssm.removeStructureViewerListener(getSeqPanel(), null);
ssm.removeCommandListener(av);
ssm.removeStructureViewerListener(getSeqPanel(), null);
ssm.removeSelectionListener(getSeqPanel());
- av.setAlignment(null);
+ av.dispose();
av = null;
}
else
default:
throw new Error(
MessageManager
- .getString("error.implementation_error_dont_know_about_thereshold_setting"));
+ .getString("error.implementation_error_dont_know_about_threshold_setting"));
}
thresholdIsMin.setSelected(acg.thresholdIsMinMax);
thresholdValue.setText("" + acg.getAnnotationThreshold());
@Override
public void actionPerformed(ActionEvent e)
{
- ok_actionPerformed(e);
+ ok_actionPerformed();
}
});
cancel.setOpaque(false);
@Override
public void actionPerformed(ActionEvent e)
{
- cancel_actionPerformed(e);
+ cancel_actionPerformed();
}
});
defColours.setOpaque(false);
@Override
public void actionPerformed(ActionEvent arg0)
{
- resetColours_actionPerformed(arg0);
+ resetColours_actionPerformed();
}
});
@Override
public void actionPerformed(ActionEvent e)
{
- annotations_actionPerformed(e);
+ annotations_actionPerformed();
}
});
getThreshold().addActionListener(new ActionListener()
@Override
public void actionPerformed(ActionEvent e)
{
- threshold_actionPerformed(e);
+ threshold_actionPerformed();
}
});
thresholdValue.addActionListener(new ActionListener()
@Override
public void actionPerformed(ActionEvent e)
{
- thresholdValue_actionPerformed(e);
+ thresholdValue_actionPerformed();
}
});
slider.setPaintLabels(false);
@Override
public void actionPerformed(ActionEvent e)
{
- currentColours_actionPerformed(e);
+ currentColours_actionPerformed();
}
});
thresholdIsMin.setBackground(Color.white);
@Override
public void actionPerformed(ActionEvent actionEvent)
{
- thresholdIsMin_actionPerformed(actionEvent);
+ thresholdIsMin_actionPerformed();
}
});
seqAssociated.setBackground(Color.white);
@Override
public void actionPerformed(ActionEvent arg0)
{
- seqAssociated_actionPerformed(arg0, annotations, seqAssociated);
+ seqAssociated_actionPerformed(annotations);
}
});
this.validate();
}
- protected void resetColours_actionPerformed(ActionEvent arg0)
+ protected void resetColours_actionPerformed()
{
setDefaultMinMax();
updateView();
updateView();
}
+ @Override
public void reset()
{
av.setGlobalColourScheme(oldcs);
}
}
+ @Override
public void valueChanged(boolean updateAllAnnotation)
{
if (slider.isEnabled())
this.threshold = threshold;
}
- public void currentColours_actionPerformed(ActionEvent e)
+ public void currentColours_actionPerformed()
{
if (currentColours.isSelected())
{
@Override
public void actionPerformed(ActionEvent e)
{
- ok_actionPerformed(e);
+ ok_actionPerformed();
}
});
@Override
public void actionPerformed(ActionEvent e)
{
- cancel_actionPerformed(e);
+ cancel_actionPerformed();
}
});
@Override
public void actionPerformed(ActionEvent e)
{
- threshold_actionPerformed(e);
+ threshold_actionPerformed();
}
});
@Override
public void actionPerformed(ActionEvent e)
{
- thresholdValue_actionPerformed(e);
+ thresholdValue_actionPerformed();
}
});
String defaultTtip = MessageManager
.getString("info.change_threshold_mode_to_enable");
- String threshold = getThreshold().getSelectedItem().toString();
- if (threshold.equalsIgnoreCase("No Threshold"))
+ String thresh = getThreshold().getSelectedItem().toString();
+ if (thresh.equalsIgnoreCase("No Threshold"))
{
thresholdValue.setToolTipText(defaultTtip);
slider.setToolTipText(defaultTtip);
}
}
+ @Override
public void reset()
{
if (this.getOldColumnSelection() != null)
}
+ @Override
public void valueChanged(boolean updateAllAnnotation)
{
if (slider.isEnabled())
else
{
text = new FeaturesFile().printJalviewFormat(ap.av.getAlignment()
- .getDataset().getSequencesArray(), displayedFeatureColours, true, ap.av.isShowNPFeats()); // ap.av.featuresDisplayed);
+ .getDataset().getSequencesArray(), displayedFeatureColours,
+ true, ap.av.isShowNPFeats()); // ap.av.featuresDisplayed);
text = formatter.printJalviewFormat(sequences, featureColours,
true, includeNonPositional);
}
AlignmentAnnotation[] aa = ap.av.getAlignment()
.getAlignmentAnnotation();
+ boolean fullRepaint = false;
if (evt.getActionCommand().equals(ADDNEW))
{
AlignmentAnnotation newAnnotation = new AlignmentAnnotation(null,
ap.av.getAlignment().addAnnotation(newAnnotation);
ap.av.getAlignment().setAnnotationIndex(newAnnotation, 0);
+ fullRepaint = true;
}
else if (evt.getActionCommand().equals(EDITNAME))
{
+ String name = aa[selectedRow].label;
editLabelDescription(aa[selectedRow]);
- repaint();
+ if (!name.equalsIgnoreCase(aa[selectedRow].label))
+ {
+ fullRepaint = true;
+ }
}
else if (evt.getActionCommand().equals(HIDE))
{
else if (evt.getActionCommand().equals(DELETE))
{
ap.av.getAlignment().deleteAnnotation(aa[selectedRow]);
+ ap.av.getCalcManager().removeWorkerForAnnotation(aa[selectedRow]);
+ fullRepaint = true;
}
else if (evt.getActionCommand().equals(SHOWALL))
{
aa[i].visible = true;
}
}
+ fullRepaint = true;
}
else if (evt.getActionCommand().equals(OUTPUT_TEXT))
{
aa[selectedRow].scaleColLabel = !aa[selectedRow].scaleColLabel;
}
- refresh();
+ refresh(fullRepaint);
}
/**
* Redraw sensibly.
+ *
+ * @adjustHeight if true, try to recalculate panel height for visible
+ * annotations
*/
- protected void refresh()
+ protected void refresh(boolean adjustHeight)
{
- ap.validateAnnotationDimensions(false);
+ ap.validateAnnotationDimensions(adjustHeight);
ap.addNotify();
- ap.repaint();
+ if (adjustHeight)
+ {
+ // sort, repaint, update overview
+ ap.paintAlignment(true);
+ }
+ else
+ {
+ // lightweight repaint
+ ap.repaint();
+ }
}
/**
*/
boolean editLabelDescription(AlignmentAnnotation annotation)
{
+ // TODO i18n
EditNameDialog dialog = new EditNameDialog(annotation.label,
annotation.description, " Annotation Name ",
"Annotation Description ", "Edit Annotation Name/Description",
{
getSelectedRow(evt.getY() - getScrollOffset());
oldY = evt.getY();
- if (!evt.isPopupTrigger())
+ if (evt.isPopupTrigger())
{
- return;
+ showPopupMenu(evt);
}
+ }
+
+ /**
+ * Build and show the Pop-up menu at the right-click mouse position
+ *
+ * @param evt
+ */
+ void showPopupMenu(MouseEvent evt)
+ {
evt.consume();
- // handle popup menu event
final AlignmentAnnotation[] aa = ap.av.getAlignment()
.getAlignmentAnnotation();
// ann.visible = false;
// }
// }
- refresh();
+ refresh(true);
}
});
pop.add(hideType);
{
ap.av.setIgnoreGapsConsensus(cbmi.getState(), ap);
}
+ ap.alignmentChanged();
}
});
pop.add(cbmi);
}
}
pop.show(this, evt.getX(), evt.getY());
-
}
/**
@Override
public void mouseReleased(MouseEvent evt)
{
+ if (evt.isPopupTrigger())
+ {
+ showPopupMenu(evt);
+ return;
+ }
+
int start = selectedRow;
getSelectedRow(evt.getY() - getScrollOffset());
int end = selectedRow;
import jalview.datamodel.SequenceI;
import jalview.renderer.AnnotationRenderer;
import jalview.renderer.AwtRenderPanelI;
+import jalview.schemes.ResidueProperties;
+import jalview.util.Comparison;
import jalview.util.MessageManager;
import java.awt.AlphaComposite;
import java.awt.event.MouseWheelEvent;
import java.awt.event.MouseWheelListener;
import java.awt.image.BufferedImage;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
import javax.swing.JColorChooser;
import javax.swing.JMenuItem;
boolean mouseDragging = false;
- boolean MAC = false;
-
// for editing cursor
int cursorX = 0;
*/
public AnnotationPanel(AlignmentPanel ap)
{
-
- MAC = jalview.util.Platform.isAMac();
-
ToolTipManager.sharedInstance().registerComponent(this);
ToolTipManager.sharedInstance().setInitialDelay(0);
ToolTipManager.sharedInstance().setDismissDelay(10000);
aa[activeRow].annotations = anot;
}
- if (evt.getActionCommand().equals(REMOVE))
+ String action = evt.getActionCommand();
+ if (action.equals(REMOVE))
{
- for (int sel : av.getColumnSelection().getSelected())
+ for (int index : av.getColumnSelection().getSelected())
{
- anot[sel] = null;
+ if (av.getColumnSelection().isVisible(index))
+ {
+ anot[index] = null;
+ }
}
}
- else if (evt.getActionCommand().equals(LABEL))
+ else if (action.equals(LABEL))
{
String exMesg = collectAnnotVals(anot, LABEL);
String label = JOptionPane.showInputDialog(this,
if (anot[index] == null)
{
- anot[index] = new Annotation(label, "", ' ', 0); // TODO: verify that
- // null exceptions
- // aren't raised
- // elsewhere.
+ anot[index] = new Annotation(label, "", ' ', 0);
}
else
{
}
}
}
- else if (evt.getActionCommand().equals(COLOUR))
+ else if (action.equals(COLOUR))
{
Color col = JColorChooser.showDialog(this,
MessageManager.getString("label.select_foreground_colour"),
}
}
else
- // HELIX OR SHEET
+ // HELIX, SHEET or STEM
{
char type = 0;
- String symbol = "\u03B1";
+ String symbol = "\u03B1"; // alpha
- if (evt.getActionCommand().equals(HELIX))
+ if (action.equals(HELIX))
{
type = 'H';
}
- else if (evt.getActionCommand().equals(SHEET))
+ else if (action.equals(SHEET))
{
type = 'E';
- symbol = "\u03B2";
+ symbol = "\u03B2"; // beta
}
// Added by LML to color stems
- else if (evt.getActionCommand().equals(STEM))
+ else if (action.equals(STEM))
{
type = 'S';
- symbol = "\u03C3";
+ int column = av.getColumnSelection().getSelectedRanges().get(0)[0];
+ symbol = aa[activeRow].getDefaultRnaHelixSymbol(column);
}
if (!aa[activeRow].hasIcons)
if ((label.length() > 0) && !aa[activeRow].hasText)
{
aa[activeRow].hasText = true;
- if (evt.getActionCommand().equals(STEM))
+ if (action.equals(STEM))
{
aa[activeRow].showAllColLabels = true;
}
}
}
+
av.getAlignment().validateAnnotation(aa[activeRow]);
ap.alignmentChanged();
-
+ ap.alignFrame.setMenusForViewport();
adjustPanelHeight();
repaint();
return;
}
- private String collectAnnotVals(Annotation[] anot, String label2)
+ /**
+ * Returns any existing annotation concatenated as a string. For each
+ * annotation, takes the description, if any, else the secondary structure
+ * character (if type is HELIX, SHEET or STEM), else the display character (if
+ * type is LABEL).
+ *
+ * @param anots
+ * @param type
+ * @return
+ */
+ private String collectAnnotVals(Annotation[] anots, String type)
{
- String collatedInput = "";
+ // TODO is this method wanted? why? 'last' is not used
+
+ StringBuilder collatedInput = new StringBuilder(64);
String last = "";
ColumnSelection viscols = av.getColumnSelection();
- // TODO: refactor and save av.getColumnSelection for efficiency
- for (int index : viscols.getSelected())
+
+ /*
+ * the selection list (read-only view) is in selection order, not
+ * column order; make a copy so we can sort it
+ */
+ List<Integer> selected = new ArrayList<Integer>(viscols.getSelected());
+ Collections.sort(selected);
+ for (int index : selected)
{
// always check for current display state - just in case
if (!viscols.isVisible(index))
continue;
}
String tlabel = null;
- if (anot[index] != null)
+ if (anots[index] != null)
{ // LML added stem code
- if (label2.equals(HELIX) || label2.equals(SHEET)
- || label2.equals(STEM) || label2.equals(LABEL))
+ if (type.equals(HELIX) || type.equals(SHEET) || type.equals(STEM)
+ || type.equals(LABEL))
{
- tlabel = anot[index].description;
+ tlabel = anots[index].description;
if (tlabel == null || tlabel.length() < 1)
{
- if (label2.equals(HELIX) || label2.equals(SHEET)
- || label2.equals(STEM))
+ if (type.equals(HELIX) || type.equals(SHEET)
+ || type.equals(STEM))
{
- tlabel = "" + anot[index].secondaryStructure;
+ tlabel = "" + anots[index].secondaryStructure;
}
else
{
- tlabel = "" + anot[index].displayCharacter;
+ tlabel = "" + anots[index].displayCharacter;
}
}
}
{
if (last.length() > 0)
{
- collatedInput += " ";
+ collatedInput.append(" ");
}
- collatedInput += tlabel;
+ collatedInput.append(tlabel);
}
}
}
- return collatedInput;
+ return collatedInput.toString();
}
/**
int height = 0;
activeRow = -1;
+ final int y = evt.getY();
for (int i = 0; i < aa.length; i++)
{
if (aa[i].visible)
height += aa[i].height;
}
- if (evt.getY() < height)
+ if (y < height)
{
if (aa[i].editable)
{
{
// Stretch Graph
graphStretch = i;
- graphStretchY = evt.getY();
+ graphStretchY = y;
}
break;
}
}
+ /*
+ * isPopupTrigger fires in mousePressed on Mac,
+ * not until mouseRelease on Windows
+ */
if (evt.isPopupTrigger() && activeRow != -1)
{
- if (av.getColumnSelection() == null)
- {
- return;
- }
+ showPopupMenu(y, evt.getX());
+ return;
+ }
- JPopupMenu pop = new JPopupMenu(
- MessageManager.getString("label.structure_type"));
- JMenuItem item;
- /*
- * Just display the needed structure options
- */
- if (av.getAlignment().isNucleotide() == true)
- {
- item = new JMenuItem(STEM);
- item.addActionListener(this);
- pop.add(item);
- }
- else
- {
- item = new JMenuItem(HELIX);
- item.addActionListener(this);
- pop.add(item);
- item = new JMenuItem(SHEET);
- item.addActionListener(this);
- pop.add(item);
- }
- item = new JMenuItem(LABEL);
+ ap.getScalePanel().mousePressed(evt);
+ }
+
+ /**
+ * Construct and display a context menu at the right-click position
+ *
+ * @param y
+ * @param x
+ */
+ void showPopupMenu(final int y, int x)
+ {
+ if (av.getColumnSelection() == null
+ || av.getColumnSelection().isEmpty())
+ {
+ return;
+ }
+
+ JPopupMenu pop = new JPopupMenu(
+ MessageManager.getString("label.structure_type"));
+ JMenuItem item;
+ /*
+ * Just display the needed structure options
+ */
+ if (av.getAlignment().isNucleotide())
+ {
+ item = new JMenuItem(STEM);
item.addActionListener(this);
pop.add(item);
- item = new JMenuItem(COLOUR);
+ }
+ else
+ {
+ item = new JMenuItem(HELIX);
item.addActionListener(this);
pop.add(item);
- item = new JMenuItem(REMOVE);
+ item = new JMenuItem(SHEET);
item.addActionListener(this);
pop.add(item);
- pop.show(this, evt.getX(), evt.getY());
-
- return;
}
-
- if (aa == null)
- {
- return;
- }
-
- ap.getScalePanel().mousePressed(evt);
-
+ item = new JMenuItem(LABEL);
+ item.addActionListener(this);
+ pop.add(item);
+ item = new JMenuItem(COLOUR);
+ item.addActionListener(this);
+ pop.add(item);
+ item = new JMenuItem(REMOVE);
+ item.addActionListener(this);
+ pop.add(item);
+ pop.show(this, x, y);
}
/**
graphStretchY = -1;
mouseDragging = false;
ap.getScalePanel().mouseReleased(evt);
+
+ /*
+ * isPopupTrigger is set in mouseReleased on Windows
+ * (in mousePressed on Mac)
+ */
+ if (evt.isPopupTrigger() && activeRow != -1)
+ {
+ showPopupMenu(evt.getY(), evt.getX());
+ }
+
}
/**
}
/**
- * DOCUMENT ME!
+ * Constructs the tooltip, and constructs and displays a status message, for
+ * the current mouse position
*
* @param evt
- * DOCUMENT ME!
*/
@Override
public void mouseMoved(MouseEvent evt)
if (evt.getY() < height)
{
row = i;
-
break;
}
}
return;
}
- int res = (evt.getX() / av.getCharWidth()) + av.getStartRes();
+ int column = (evt.getX() / av.getCharWidth()) + av.getStartRes();
if (av.hasHiddenColumns())
{
- res = av.getColumnSelection().adjustForHiddenColumns(res);
+ column = av.getColumnSelection().adjustForHiddenColumns(column);
}
- if (row > -1 && aa[row].annotations != null
- && res < aa[row].annotations.length)
+ AlignmentAnnotation ann = aa[row];
+ if (row > -1 && ann.annotations != null
+ && column < ann.annotations.length)
+ {
+ buildToolTip(ann, column, aa);
+ setStatusMessage(column, ann);
+ }
+ else
{
- if (aa[row].graphGroup > -1)
+ this.setToolTipText(null);
+ ap.alignFrame.statusBar.setText(" ");
+ }
+ }
+
+ /**
+ * Builds a tooltip for the annotation at the current mouse position.
+ *
+ * @param ann
+ * @param column
+ * @param anns
+ */
+ void buildToolTip(AlignmentAnnotation ann, int column,
+ AlignmentAnnotation[] anns)
+ {
+ if (ann.graphGroup > -1)
+ {
+ StringBuilder tip = new StringBuilder(32);
+ tip.append("<html>");
+ for (int i = 0; i < anns.length; i++)
{
- StringBuffer tip = new StringBuffer("<html>");
- for (int gg = 0; gg < aa.length; gg++)
+ if (anns[i].graphGroup == ann.graphGroup
+ && anns[i].annotations[column] != null)
{
- if (aa[gg].graphGroup == aa[row].graphGroup
- && aa[gg].annotations[res] != null)
+ tip.append(anns[i].label);
+ String description = anns[i].annotations[column].description;
+ if (description != null && description.length() > 0)
{
- tip.append(aa[gg].label + " "
- + aa[gg].annotations[res].description + "<br>");
+ tip.append(" ").append(description);
}
- }
- if (tip.length() != 6)
- {
- tip.setLength(tip.length() - 4);
- this.setToolTipText(tip.toString() + "</html>");
+ tip.append("<br>");
}
}
- else if (aa[row].annotations[res] != null
- && aa[row].annotations[res].description != null
- && aa[row].annotations[res].description.length() > 0)
+ if (tip.length() != 6)
{
- this.setToolTipText(JvSwingUtils.wrapTooltip(true,
- aa[row].annotations[res].description));
+ tip.setLength(tip.length() - 4);
+ this.setToolTipText(tip.toString() + "</html>");
}
- else
+ }
+ else if (ann.annotations[column] != null)
+ {
+ String description = ann.annotations[column].description;
+ if (description != null && description.length() > 0)
{
- // clear the tooltip.
- this.setToolTipText(null);
+ this.setToolTipText(JvSwingUtils.wrapTooltip(true, description));
}
+ }
+ else
+ {
+ // clear the tooltip.
+ this.setToolTipText(null);
+ }
+ }
- if (aa[row].annotations[res] != null)
+ /**
+ * Constructs and displays the status bar message
+ *
+ * @param column
+ * @param ann
+ */
+ void setStatusMessage(int column, AlignmentAnnotation ann)
+ {
+ /*
+ * show alignment column and annotation description if any
+ */
+ StringBuilder text = new StringBuilder(32);
+ text.append(MessageManager.getString("label.column")).append(" ")
+ .append(column + 1);
+
+ if (ann.annotations[column] != null)
+ {
+ String description = ann.annotations[column].description;
+ if (description != null && description.trim().length() > 0)
{
- StringBuffer text = new StringBuffer("Sequence position "
- + (res + 1));
+ text.append(" ").append(description);
+ }
+ }
- if (aa[row].annotations[res].description != null)
+ /*
+ * if the annotation is sequence-specific, show the sequence number
+ * in the alignment, and (if not a gap) the residue and position
+ */
+ SequenceI seqref = ann.sequenceRef;
+ if (seqref != null)
+ {
+ int seqIndex = av.getAlignment().findIndex(seqref);
+ if (seqIndex != -1)
+ {
+ text.append(", ")
+ .append(MessageManager.getString("label.sequence"))
+ .append(" ").append(seqIndex + 1);
+ char residue = seqref.getCharAt(column);
+ if (!Comparison.isGap(residue))
{
- text.append(" " + aa[row].annotations[res].description);
+ text.append(" ");
+ String name;
+ if (av.getAlignment().isNucleotide())
+ {
+ name = ResidueProperties.nucleotideName.get(String
+ .valueOf(residue));
+ text.append(" Nucleotide: ").append(
+ name != null ? name : residue);
+ }
+ else
+ {
+ name = 'X' == residue ? "X" : ('*' == residue ? "STOP"
+ : ResidueProperties.aa2Triplet.get(String
+ .valueOf(residue)));
+ text.append(" Residue: ").append(name != null ? name : residue);
+ }
+ int residuePos = seqref.findPosition(column);
+ text.append(" (").append(residuePos).append(")");
}
-
- ap.alignFrame.statusBar.setText(text.toString());
}
}
- else
- {
- this.setToolTipText(null);
- }
+
+ ap.alignFrame.statusBar.setText(text.toString());
}
/**
return null;
}
}
+
+ /**
+ * Try to ensure any references held are nulled
+ */
+ public void dispose()
+ {
+ av = null;
+ ap = null;
+ image = null;
+ fadedImage = null;
+ gg = null;
+ _mwl = null;
+
+ /*
+ * I created the renderer so I will dispose of it
+ */
+ if (renderer != null)
+ {
+ renderer.dispose();
+ }
+ }
}
import jalview.schemes.AnnotationColourGradient;
import jalview.util.MessageManager;
-import java.awt.event.ActionEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.Vector;
protected boolean enableSeqAss = false;
- private jalview.datamodel.AlignmentAnnotation currentAnnotation;
+ private AlignmentAnnotation currentAnnotation;
protected boolean adjusting = false;
enableSeqAss = true;
}
String label = av.getAlignment().getAlignmentAnnotation()[i].label;
+ // add associated sequence ID if available
+ if (!isSeqAssociated
+ && av.getAlignment().getAlignmentAnnotation()[i].sequenceRef != null)
+ {
+ label = label
+ + "_"
+ + av.getAlignment().getAlignmentAnnotation()[i].sequenceRef
+ .getName();
+ }
+ // make label unique
if (!list.contains(label))
{
anmap[list.size()] = i;
list.add(label);
-
}
else
{
seqAssociated.setEnabled(enableSeqAss);
}
- public void ok_actionPerformed(ActionEvent e)
+ public void ok_actionPerformed()
{
try
{
}
}
- public void cancel_actionPerformed(ActionEvent e)
+ public void cancel_actionPerformed()
{
reset();
ap.paintAlignment(true);
}
}
- public void thresholdCheck_actionPerformed(ActionEvent e)
+ public void thresholdCheck_actionPerformed()
{
updateView();
}
- public void annotations_actionPerformed(ActionEvent e)
+ public void annotations_actionPerformed()
{
updateView();
}
- public void threshold_actionPerformed(ActionEvent e)
+ public void threshold_actionPerformed()
{
updateView();
}
- public void thresholdValue_actionPerformed(ActionEvent e)
+ public void thresholdValue_actionPerformed()
{
try
{
}
}
- public void thresholdIsMin_actionPerformed(ActionEvent actionEvent)
+ public void thresholdIsMin_actionPerformed()
{
updateView();
}
protected void populateThresholdComboBox(JComboBox<String> threshold)
{
threshold.addItem(MessageManager
- .getString("label.threshold_feature_no_thereshold"));
+ .getString("label.threshold_feature_no_threshold"));
threshold.addItem(MessageManager
- .getString("label.threshold_feature_above_thereshold"));
+ .getString("label.threshold_feature_above_threshold"));
threshold.addItem(MessageManager
- .getString("label.threshold_feature_below_thereshold"));
+ .getString("label.threshold_feature_below_threshold"));
}
- protected void seqAssociated_actionPerformed(ActionEvent arg0,
- JComboBox<String> annotations, JCheckBox seqAssociated)
+ protected void seqAssociated_actionPerformed(JComboBox<String> annotations)
{
adjusting = true;
String cursel = (String) annotations.getSelectedItem();
}
}
- protected boolean colorAlignmContaining(
- AlignmentAnnotation currentAnnotation, int selectedThresholdItem)
+ protected boolean colorAlignmContaining(AlignmentAnnotation currentAnn,
+ int selectedThresholdOption)
{
AnnotationColourGradient acg = null;
if (currentColours.isSelected())
{
- acg = new AnnotationColourGradient(currentAnnotation,
- av.getGlobalColourScheme(), selectedThresholdItem);
+ acg = new AnnotationColourGradient(currentAnn,
+ av.getGlobalColourScheme(), selectedThresholdOption);
}
else
{
- acg = new AnnotationColourGradient(currentAnnotation,
+ acg = new AnnotationColourGradient(currentAnn,
minColour.getBackground(), maxColour.getBackground(),
- selectedThresholdItem);
+ selectedThresholdOption);
}
acg.setSeqAssociated(seqAssociated.isSelected());
- if (currentAnnotation.graphMin == 0f
- && currentAnnotation.graphMax == 0f)
+ if (currentAnn.graphMin == 0f && currentAnn.graphMax == 0f)
{
acg.setPredefinedColours(true);
}
if (currentColours.isSelected())
{
- sg.cs = new AnnotationColourGradient(currentAnnotation, sg.cs,
- selectedThresholdItem);
+ sg.cs = new AnnotationColourGradient(currentAnn, sg.cs,
+ selectedThresholdOption);
((AnnotationColourGradient) sg.cs).setSeqAssociated(seqAssociated
.isSelected());
}
else
{
- sg.cs = new AnnotationColourGradient(currentAnnotation,
+ sg.cs = new AnnotationColourGradient(currentAnn,
minColour.getBackground(), maxColour.getBackground(),
- selectedThresholdItem);
+ selectedThresholdOption);
((AnnotationColourGradient) sg.cs).setSeqAssociated(seqAssociated
.isSelected());
}
import jalview.structures.models.AAStructureBindingModel;
import jalview.util.MessageManager;
import jalview.util.Platform;
+import jalview.ws.dbsources.Pdb;
import java.awt.BorderLayout;
import java.awt.Color;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JSplitPane;
+import javax.swing.SwingUtilities;
import javax.swing.event.InternalFrameAdapter;
import javax.swing.event.InternalFrameEvent;
import javax.swing.event.MenuEvent;
public class AppJmol extends StructureViewerBase
{
+ // ms to wait for Jmol to load files
+ private static final int JMOL_LOAD_TIMEOUT = 20000;
+
+ private static final String SPACE = " ";
+
+ private static final String BACKSLASH = "\"";
+
AppJmolBinding jmb;
JPanel scriptWindow;
jmb.setColourBySequence(true);
setSize(400, 400); // probably should be a configurable/dynamic default here
initMenus();
- worker = null;
- {
- addingStructures = false;
- worker = new Thread(this);
- worker.start();
- }
+ addingStructures = false;
+ worker = new Thread(this);
+ worker.start();
+
this.addInternalFrameListener(new InternalFrameAdapter()
{
@Override
scriptWindow.setVisible(false);
}
- jmb.allocateViewer(renderPanel, true, "", null, null, "", scriptWindow,
- null);
+ jmb.allocateViewer(renderPanel, true, "", null, null, "",
+ scriptWindow, null);
// jmb.newJmolPopup("Jmol");
if (command == null)
{
public void run()
{
_started = true;
+ try
+ {
+ List<String> files = fetchPdbFiles();
+ if (files.size() > 0)
+ {
+ showFilesInViewer(files);
+ }
+ } finally
+ {
+ _started = false;
+ worker = null;
+ }
+ }
+
+ /**
+ * Either adds the given files to a structure viewer or opens a new viewer to
+ * show them
+ *
+ * @param files
+ * list of absolute paths to structure files
+ */
+ void showFilesInViewer(List<String> files)
+ {
+ long lastnotify = jmb.getLoadNotifiesHandled();
+ StringBuilder fileList = new StringBuilder();
+ for (String s : files)
+ {
+ fileList.append(SPACE).append(BACKSLASH)
+ .append(Platform.escapeString(s)).append(BACKSLASH);
+ }
+ String filesString = fileList.toString();
+
+ if (!addingStructures)
+ {
+ try
+ {
+ initJmol("load FILES " + filesString);
+ } catch (OutOfMemoryError oomerror)
+ {
+ new OOMWarning("When trying to open the Jmol viewer!", oomerror);
+ Cache.log.debug("File locations are " + filesString);
+ } catch (Exception ex)
+ {
+ Cache.log.error("Couldn't open Jmol viewer!", ex);
+ }
+ }
+ else
+ {
+ StringBuilder cmd = new StringBuilder();
+ cmd.append("loadingJalviewdata=true\nload APPEND ");
+ cmd.append(filesString);
+ cmd.append("\nloadingJalviewdata=null");
+ final String command = cmd.toString();
+ lastnotify = jmb.getLoadNotifiesHandled();
+
+ try
+ {
+ jmb.evalStateCommand(command);
+ } catch (OutOfMemoryError oomerror)
+ {
+ new OOMWarning("When trying to add structures to the Jmol viewer!",
+ oomerror);
+ Cache.log.debug("File locations are " + filesString);
+ } catch (Exception ex)
+ {
+ Cache.log.error("Couldn't add files to Jmol viewer!", ex);
+ }
+ }
+
+ // need to wait around until script has finished
+ int waitMax = JMOL_LOAD_TIMEOUT;
+ int waitFor = 35;
+ int waitTotal = 0;
+ while (addingStructures ? lastnotify >= jmb.getLoadNotifiesHandled()
+ : !(jmb.isFinishedInit() && jmb.getPdbFile() != null && jmb
+ .getPdbFile().length == files.size()))
+ {
+ try
+ {
+ Cache.log.debug("Waiting around for jmb notify.");
+ Thread.sleep(waitFor);
+ waitTotal += waitFor;
+ } catch (Exception e)
+ {
+ }
+ if (waitTotal > waitMax)
+ {
+ System.err
+ .println("Timed out waiting for Jmol to load files after "
+ + waitTotal + "ms");
+// System.err.println("finished: " + jmb.isFinishedInit()
+// + "; loaded: " + Arrays.toString(jmb.getPdbFile())
+// + "; files: " + files.toString());
+ jmb.getPdbFile();
+ break;
+ }
+ }
+
+ // refresh the sequence colours for the new structure(s)
+ for (AlignmentPanel ap : _colourwith)
+ {
+ jmb.updateColours(ap);
+ }
+ // do superposition if asked to
+ if (Cache.getDefault("AUTOSUPERIMPOSE", true) && alignAddedStructures)
+ {
+ alignAddedStructures();
+ }
+ addingStructures = false;
+ }
+
+ /**
+ * Queues a thread to align structures with Jalview alignments
+ */
+ void alignAddedStructures()
+ {
+ javax.swing.SwingUtilities.invokeLater(new Runnable()
+ {
+ @Override
+ public void run()
+ {
+ if (jmb.viewer.isScriptExecuting())
+ {
+ SwingUtilities.invokeLater(this);
+ try
+ {
+ Thread.sleep(5);
+ } catch (InterruptedException q)
+ {
+ }
+ return;
+ }
+ else
+ {
+ alignStructs_withAllAlignPanels();
+ }
+ }
+ });
+ alignAddedStructures = false;
+ }
+
+ /**
+ * Retrieves and saves as file any modelled PDB entries for which we do not
+ * already have a file saved. Returns a list of absolute paths to structure
+ * files which were either retrieved, or already stored but not modelled in
+ * the structure viewer (i.e. files to add to the viewer display).
+ *
+ * @return
+ */
+ List<String> fetchPdbFiles()
+ {
+ // todo - record which pdbids were successfully imported.
+ StringBuilder errormsgs = new StringBuilder();
+
+ List<String> files = new ArrayList<String>();
String pdbid = "";
- // todo - record which pdbids were successfuly imported.
- StringBuffer errormsgs = new StringBuffer(), files = new StringBuffer();
try
{
- String[] curfiles = jmb.getPdbFile(); // files currently in viewer
+ String[] filesInViewer = jmb.getPdbFile();
// TODO: replace with reference fetching/transfer code (validate PDBentry
// as a DBRef?)
- jalview.ws.dbsources.Pdb pdbclient = new jalview.ws.dbsources.Pdb();
+ Pdb pdbclient = new Pdb();
for (int pi = 0; pi < jmb.getPdbCount(); pi++)
{
String file = jmb.getPdbEntry(pi).getFile();
} catch (Exception ex)
{
ex.printStackTrace();
- errormsgs.append("'" + pdbid + "'");
- }
- if (progressBar != null)
+ errormsgs.append("'").append(pdbid).append("'");
+ } finally
{
- progressBar.setProgressBar(
- MessageManager.getString("label.state_completed"), hdl);
+ if (progressBar != null)
+ {
+ progressBar.setProgressBar(
+ MessageManager.getString("label.state_completed"),
+ hdl);
+ }
}
if (pdbseq != null)
{
file = new File(pdbseq.getSequenceAt(0).getAllPDBEntries()
.elementAt(0).getFile()).getAbsolutePath();
jmb.getPdbEntry(pi).setFile(file);
-
- files.append(" \"" + Platform.escapeString(file) + "\"");
+ files.add(file);
}
else
{
- errormsgs.append("'" + pdbid + "' ");
+ errormsgs.append("'").append(pdbid).append("' ");
}
}
else
{
- if (curfiles != null && curfiles.length > 0)
+ if (filesInViewer != null && filesInViewer.length > 0)
{
addingStructures = true; // already files loaded.
- for (int c = 0; c < curfiles.length; c++)
+ for (int c = 0; c < filesInViewer.length; c++)
{
- if (curfiles[c].equals(file))
+ if (filesInViewer[c].equals(file))
{
file = null;
break;
}
if (file != null)
{
- files.append(" \"" + Platform.escapeString(file) + "\"");
+ files.add(file);
}
}
}
} catch (Exception ex)
{
ex.printStackTrace();
- errormsgs.append("When retrieving pdbfiles : current was: '" + pdbid
- + "'");
+ errormsgs.append("When retrieving pdbfiles : current was: '")
+ .append(pdbid).append("'");
}
if (errormsgs.length() > 0)
{
-
JOptionPane.showInternalMessageDialog(Desktop.desktop, MessageManager
.formatMessage("label.pdb_entries_couldnt_be_retrieved",
new String[] { errormsgs.toString() }),
MessageManager.getString("label.couldnt_load_file"),
JOptionPane.ERROR_MESSAGE);
-
- }
- long lastnotify = jmb.getLoadNotifiesHandled();
- if (files.length() > 0)
- {
- if (!addingStructures)
- {
-
- try
- {
- initJmol("load FILES " + files.toString());
- } catch (OutOfMemoryError oomerror)
- {
- new OOMWarning("When trying to open the Jmol viewer!", oomerror);
- Cache.log.debug("File locations are " + files);
- } catch (Exception ex)
- {
- Cache.log.error("Couldn't open Jmol viewer!", ex);
- }
- }
- else
- {
- StringBuffer cmd = new StringBuffer();
- cmd.append("loadingJalviewdata=true\nload APPEND ");
- cmd.append(files.toString());
- cmd.append("\nloadingJalviewdata=null");
- final String command = cmd.toString();
- cmd = null;
- lastnotify = jmb.getLoadNotifiesHandled();
-
- try
- {
- jmb.evalStateCommand(command);
- } catch (OutOfMemoryError oomerror)
- {
- new OOMWarning(
- "When trying to add structures to the Jmol viewer!",
- oomerror);
- Cache.log.debug("File locations are " + files);
- } catch (Exception ex)
- {
- Cache.log.error("Couldn't add files to Jmol viewer!", ex);
- }
- }
-
- // need to wait around until script has finished
- while (addingStructures ? lastnotify >= jmb.getLoadNotifiesHandled()
- : (!jmb.isFinishedInit() && jmb.getPdbFile() != null && jmb
- .getPdbFile().length != jmb.getPdbCount()))
- {
- try
- {
- Cache.log.debug("Waiting around for jmb notify.");
- Thread.sleep(35);
- } catch (Exception e)
- {
- }
- }
-
- // refresh the sequence colours for the new structure(s)
- for (AlignmentPanel ap : _colourwith)
- {
- jmb.updateColours(ap);
- }
- // do superposition if asked to
- if (Cache.getDefault("AUTOSUPERIMPOSE", true) && alignAddedStructures)
- {
- javax.swing.SwingUtilities.invokeLater(new Runnable()
- {
- @Override
- public void run()
- {
- if (jmb.viewer.isScriptExecuting())
- {
- javax.swing.SwingUtilities.invokeLater(this);
- try
- {
- Thread.sleep(5);
- } catch (InterruptedException q)
- {
- }
- ;
- return;
- }
- else
- {
- alignStructs_withAllAlignPanels();
- }
- }
- });
- alignAddedStructures = false;
- }
- addingStructures = false;
-
}
- _started = false;
- worker = null;
+ return files;
}
@Override
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
+import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
/**
* check if the news panel's container is visible
*/
+ @Override
public boolean isVisible()
{
if (parent == null)
xf.setContentPane(me);
xf.addWindowListener(new WindowAdapter()
{
+ @Override
public void windowClosing(WindowEvent e)
{
ActionEvent actionEvent = new ActionEvent(this,
exitAction.actionPerformed(actionEvent);
}
+ @Override
public void windowOpened(WindowEvent e)
{
}
+ " and lastDate is " + lastDate);
for (Item i : (List<Item>) chan.getItems())
{
+ Date published = i.getPublishDate();
boolean isread = lastDate == null ? false
- : (i.getPublishDate() != null && !lastDate.before(i
- .getPublishDate()));
+ : (published != null && !lastDate.before(published));
if (!updating || updateItems)
{
{
i.setRead(isread);
}
- if (i.getPublishDate() != null && !i.isRead())
+ if (published != null && !i.isRead())
{
- if (earliest == null || earliest.after(i.getPublishDate()))
+ if (earliest == null || earliest.after(published))
{
- earliest = i.getPublishDate();
+ earliest = published;
}
}
}
}
if (lastDate != null)
{
- jalview.bin.Cache.setDateProperty("JALVIEW_NEWS_RSS_LASTMODIFIED",
- lastDate);
- jalview.bin.Cache.log.debug("Saved last read date as "
- + jalview.bin.Cache.date_format.format(lastDate));
-
+ String formatted = Cache.setDateProperty(
+ "JALVIEW_NEWS_RSS_LASTMODIFIED", lastDate);
+ Cache.log.debug("Saved last read date as " + formatted);
}
}
}
listItems.addMouseListener(new java.awt.event.MouseAdapter()
{
+ @Override
public void mouseClicked(MouseEvent e)
{
listItems_mouseClicked(e);
}
textDescription.addHyperlinkListener(new HyperlinkListener()
{
+ @Override
public void hyperlinkUpdate(HyperlinkEvent e)
{
if (e.getEventType() == HyperlinkEvent.EventType.ACTIVATED)
listItems.addListSelectionListener(new ListSelectionListener()
{
+ @Override
public void valueChanged(ListSelectionEvent e)
{
if (e.getValueIsAdjusting() == false)
_listItems = listItems;
}
+ @Override
public void actionPerformed(ActionEvent e)
{
Object o = _listItems.getSelectedValue();
}
}
+ @Override
public void update(Object o)
{
setEnabled(true);
lastread.set(1983, 01, 01);
while (lastread.before(today))
{
- Cache.setDateProperty("JALVIEW_NEWS_RSS_LASTMODIFIED",
- lastread.getTime());
+ String formattedDate = Cache.setDateProperty(
+ "JALVIEW_NEWS_RSS_LASTMODIFIED", lastread.getTime());
BlogReader me = new BlogReader();
- System.out.println("Set last date to "
- + jalview.bin.Cache.date_format.format(lastread.getTime()));
+ System.out.println("Set last date to " + formattedDate);
if (me.isNewsNew())
{
Cache.log.debug("There is news to read.");
private final static Icon _icon = new ImageIcon(
Main.class.getResource("image/ComposeMail16.gif"));
+ @Override
public Component getListCellRendererComponent(JList list, Object value,
int index, boolean isSelected, boolean cellHasFocus)
{
private final static Icon _icon = new ImageIcon(
Main.class.getResource("image/ComposeMail16.gif"));
+ @Override
public Component getListCellRendererComponent(JList list, Object value,
int index, boolean isSelected, boolean cellHasFocus)
{
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
-import java.util.Map;
import java.util.Random;
-import java.util.Set;
import java.util.Vector;
import javax.swing.JCheckBoxMenuItem;
public ChimeraViewFrame(PDBEntry pdbentry, SequenceI[] seq,
String[] chains, final AlignmentPanel ap)
{
- super();
+ this();
String pdbId = pdbentry.getId();
/*
SequenceI[][] seqs)
{
createProgressBar();
+ // FIXME extractChains needs pdbentries to match IDs to PDBEntry(s) on seqs
String[][] chains = extractChains(seqs);
jmb = new JalviewChimeraBindingModel(this,
ap.getStructureSelectionManager(), pdbentrys, seqs, chains,
.getAllPDBEntries();
if (pdbrefs != null && pdbrefs.size() > 0)
{
+ // FIXME: SequenceI.PDBEntry[0] chain mapping used for
+ // ChimeraViewFrame. Is this even used ???
+
chain = pdbrefs.get(0).getChainCode();
}
}
SequenceI[][] seqsArray, boolean colourByChimera,
boolean colourBySequence, String newViewId)
{
- super();
+ this();
setViewId(newViewId);
this.chimeraSessionFile = chimeraSessionFile;
openNewChimera(alignPanel, pdbArray, seqsArray);
public ChimeraViewFrame(PDBEntry[] pe, SequenceI[][] seqs,
AlignmentPanel ap)
{
- super();
+ this();
openNewChimera(ap, pe, seqs);
}
- public ChimeraViewFrame(Map<PDBEntry, List<SequenceI>> toView,
- AlignmentPanel alignPanel)
+ /**
+ * Default constructor
+ */
+ public ChimeraViewFrame()
{
super();
/*
- * Convert the map of sequences per pdb entry into the tied arrays expected
- * by openNewChimera
- *
- * TODO pass the Map down to openNewChimera and its callees instead
+ * closeViewer will decide whether or not to close this frame
+ * depending on whether user chooses to Cancel or not
*/
- final Set<PDBEntry> pdbEntries = toView.keySet();
- PDBEntry[] pdbs = pdbEntries.toArray(new PDBEntry[pdbEntries.size()]);
- SequenceI[][] seqsForPdbs = new SequenceI[pdbEntries.size()][];
- for (int i = 0; i < pdbs.length; i++)
- {
- final List<SequenceI> seqsForPdb = toView.get(pdbs[i]);
- seqsForPdbs[i] = seqsForPdb.toArray(new SequenceI[seqsForPdb.size()]);
- }
-
- openNewChimera(alignPanel, pdbs, seqsForPdbs);
+ setDefaultCloseOperation(JInternalFrame.DO_NOTHING_ON_CLOSE);
}
/**
prompt = JvSwingUtils.wrapTooltip(true, prompt);
int confirm = JOptionPane.showConfirmDialog(this, prompt,
MessageManager.getString("label.close_viewer"),
- JOptionPane.YES_NO_OPTION);
+ JOptionPane.YES_NO_CANCEL_OPTION);
+ /*
+ * abort closure if user hits escape or Cancel
+ */
+ if (confirm == JOptionPane.CANCEL_OPTION
+ || confirm == JOptionPane.CLOSED_OPTION)
+ {
+ return;
+ }
closeChimera = confirm == JOptionPane.YES_OPTION;
}
jmb.closeViewer(closeChimera);
// TODO: check for memory leaks where instance isn't finalised because jmb
// holds a reference to the window
jmb = null;
+ dispose();
}
/**
{
int pos = filePDBpos.get(num).intValue();
long startTime = startProgressBar("Chimera "
- + MessageManager.getString("status.opening_file"));
+ + MessageManager.getString("status.opening_file_for")
+ + " " + pe.getId());
jmb.openFile(pe);
jmb.addSequence(pos, jmb.getSequence()[pos]);
File fl = new File(pe.getFile());
*/
private String fetchPdbFile(PDBEntry processingEntry) throws Exception
{
+ // FIXME: this is duplicated code with Jmol frame ?
String filePath = null;
Pdb pdbclient = new Pdb();
AlignmentI pdbseq = null;
--- /dev/null
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
+package jalview.gui;
+
+import jalview.analysis.AlignmentUtils;
+import jalview.analysis.CrossRef;
+import jalview.api.AlignmentViewPanel;
+import jalview.api.FeatureSettingsModelI;
+import jalview.bin.Cache;
+import jalview.datamodel.Alignment;
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.DBRefSource;
+import jalview.datamodel.SequenceI;
+import jalview.io.gff.SequenceOntologyI;
+import jalview.structure.StructureSelectionManager;
+import jalview.util.MessageManager;
+import jalview.ws.SequenceFetcher;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.swing.JOptionPane;
+
+/**
+ * Factory constructor and runnable for discovering and displaying
+ * cross-references for a set of aligned sequences
+ *
+ * @author jprocter
+ *
+ */
+public class CrossRefAction implements Runnable
+{
+ private AlignFrame alignFrame;
+
+ private SequenceI[] sel;
+
+ private boolean _odna;
+
+ private String source;
+
+ List<AlignmentViewPanel> xrefViews = new ArrayList<AlignmentViewPanel>();
+
+ public List<jalview.api.AlignmentViewPanel> getXrefViews()
+ {
+ return xrefViews;
+ }
+
+ @Override
+ public void run()
+ {
+ final long sttime = System.currentTimeMillis();
+ alignFrame.setProgressBar(
+ MessageManager.formatMessage(
+ "status.searching_for_sequences_from",
+ new Object[] { source }), sttime);
+ try
+ {
+ AlignmentI alignment = alignFrame.getViewport().getAlignment();
+ AlignmentI dataset = alignment.getDataset() == null ? alignment
+ : alignment.getDataset();
+ boolean dna = alignment.isNucleotide();
+ if (_odna != dna)
+ {
+ System.err
+ .println("Conflict: showProducts for alignment originally "
+ + "thought to be " + (_odna ? "DNA" : "Protein")
+ + " now searching for " + (dna ? "DNA" : "Protein")
+ + " Context.");
+ }
+ AlignmentI xrefs = new CrossRef(sel, dataset).findXrefSequences(
+ source, dna);
+ if (xrefs == null)
+ {
+ return;
+ }
+ /*
+ * get display scheme (if any) to apply to features
+ */
+ FeatureSettingsModelI featureColourScheme = new SequenceFetcher()
+ .getFeatureColourScheme(source);
+
+ AlignmentI xrefsAlignment = makeCrossReferencesAlignment(dataset,
+ xrefs);
+ if (!dna)
+ {
+ xrefsAlignment = AlignmentUtils.makeCdsAlignment(
+ xrefsAlignment.getSequencesArray(), dataset, sel);
+ xrefsAlignment.alignAs(alignment);
+ }
+
+ /*
+ * If we are opening a splitframe, make a copy of this alignment (sharing the same dataset
+ * sequences). If we are DNA, drop introns and update mappings
+ */
+ AlignmentI copyAlignment = null;
+
+ if (Cache.getDefault(Preferences.ENABLE_SPLIT_FRAME, true))
+ {
+ boolean copyAlignmentIsAligned = false;
+ if (dna)
+ {
+ copyAlignment = AlignmentUtils.makeCdsAlignment(sel, dataset,
+ xrefsAlignment.getSequencesArray());
+ if (copyAlignment.getHeight() == 0)
+ {
+ JOptionPane.showMessageDialog(alignFrame,
+ MessageManager.getString("label.cant_map_cds"),
+ MessageManager.getString("label.operation_failed"),
+ JOptionPane.OK_OPTION);
+ System.err.println("Failed to make CDS alignment");
+ }
+
+ /*
+ * pending getting Embl transcripts to 'align',
+ * we are only doing this for Ensembl
+ */
+ // TODO proper criteria for 'can align as cdna'
+ if (DBRefSource.ENSEMBL.equalsIgnoreCase(source)
+ || AlignmentUtils.looksLikeEnsembl(alignment))
+ {
+ copyAlignment.alignAs(alignment);
+ copyAlignmentIsAligned = true;
+ }
+ }
+ else
+ {
+ copyAlignment = AlignmentUtils.makeCopyAlignment(sel,
+ xrefs.getSequencesArray(), dataset);
+ }
+ copyAlignment
+ .setGapCharacter(alignFrame.viewport.getGapCharacter());
+
+ StructureSelectionManager ssm = StructureSelectionManager
+ .getStructureSelectionManager(Desktop.instance);
+
+ /*
+ * register any new mappings for sequence mouseover etc
+ * (will not duplicate any previously registered mappings)
+ */
+ ssm.registerMappings(dataset.getCodonFrames());
+
+ if (copyAlignment.getHeight() <= 0)
+ {
+ System.err.println("No Sequences generated for xRef type "
+ + source);
+ return;
+ }
+ /*
+ * align protein to dna
+ */
+ if (dna && copyAlignmentIsAligned)
+ {
+ xrefsAlignment.alignAs(copyAlignment);
+ }
+ else
+ {
+ /*
+ * align cdna to protein - currently only if
+ * fetching and aligning Ensembl transcripts!
+ */
+ // TODO: generalise for other sources of locus/transcript/cds data
+ if (dna && DBRefSource.ENSEMBL.equalsIgnoreCase(source))
+ {
+ copyAlignment.alignAs(xrefsAlignment);
+ }
+ }
+ }
+ /*
+ * build AlignFrame(s) according to available alignment data
+ */
+ AlignFrame newFrame = new AlignFrame(xrefsAlignment,
+ AlignFrame.DEFAULT_WIDTH, AlignFrame.DEFAULT_HEIGHT);
+ if (Cache.getDefault("HIDE_INTRONS", true))
+ {
+ newFrame.hideFeatureColumns(SequenceOntologyI.EXON, false);
+ }
+ String newtitle = String.format("%s %s %s",
+ dna ? MessageManager.getString("label.proteins")
+ : MessageManager.getString("label.nucleotides"),
+ MessageManager.getString("label.for"), alignFrame.getTitle());
+ newFrame.setTitle(newtitle);
+
+ if (copyAlignment == null)
+ {
+ /*
+ * split frame display is turned off in preferences file
+ */
+ Desktop.addInternalFrame(newFrame, newtitle,
+ AlignFrame.DEFAULT_WIDTH, AlignFrame.DEFAULT_HEIGHT);
+ xrefViews.add(newFrame.alignPanel);
+ return; // via finally clause
+ }
+ AlignFrame copyThis = new AlignFrame(copyAlignment,
+ AlignFrame.DEFAULT_WIDTH, AlignFrame.DEFAULT_HEIGHT);
+ copyThis.setTitle(alignFrame.getTitle());
+
+ boolean showSequenceFeatures = alignFrame.getViewport()
+ .isShowSequenceFeatures();
+ newFrame.setShowSeqFeatures(showSequenceFeatures);
+ copyThis.setShowSeqFeatures(showSequenceFeatures);
+ FeatureRenderer myFeatureStyling = alignFrame.alignPanel
+ .getSeqPanel().seqCanvas.getFeatureRenderer();
+
+ /*
+ * copy feature rendering settings to split frame
+ */
+ newFrame.alignPanel.getSeqPanel().seqCanvas.getFeatureRenderer()
+ .transferSettings(myFeatureStyling);
+ copyThis.alignPanel.getSeqPanel().seqCanvas.getFeatureRenderer()
+ .transferSettings(myFeatureStyling);
+
+ /*
+ * apply 'database source' feature configuration
+ * if any was found
+ */
+ // TODO is this the feature colouring for the original
+ // alignment or the fetched xrefs? either could be Ensembl
+ newFrame.getViewport().applyFeaturesStyle(featureColourScheme);
+ copyThis.getViewport().applyFeaturesStyle(featureColourScheme);
+
+ SplitFrame sf = new SplitFrame(dna ? copyThis : newFrame,
+ dna ? newFrame : copyThis);
+ newFrame.setVisible(true);
+ copyThis.setVisible(true);
+ String linkedTitle = MessageManager
+ .getString("label.linked_view_title");
+ Desktop.addInternalFrame(sf, linkedTitle, -1, -1);
+ sf.adjustDivider();
+
+ // finally add the top, then bottom frame to the view list
+ xrefViews.add(dna ? copyThis.alignPanel : newFrame.alignPanel);
+ xrefViews.add(!dna ? copyThis.alignPanel : newFrame.alignPanel);
+
+ } catch (OutOfMemoryError e)
+ {
+ new OOMWarning("whilst fetching crossreferences", e);
+ } catch (Throwable e)
+ {
+ Cache.log.error("Error when finding crossreferences", e);
+ } finally
+ {
+ alignFrame.setProgressBar(MessageManager.formatMessage(
+ "status.finished_searching_for_sequences_from",
+ new Object[] { source }), sttime);
+ }
+ }
+
+ /**
+ * Makes an alignment containing the given sequences, and adds them to the
+ * given dataset, which is also set as the dataset for the new alignment
+ *
+ * TODO: refactor to DatasetI method
+ *
+ * @param dataset
+ * @param seqs
+ * @return
+ */
+ protected AlignmentI makeCrossReferencesAlignment(AlignmentI dataset,
+ AlignmentI seqs)
+ {
+ SequenceI[] sprods = new SequenceI[seqs.getHeight()];
+ for (int s = 0; s < sprods.length; s++)
+ {
+ sprods[s] = (seqs.getSequenceAt(s)).deriveSequence();
+ if (dataset.getSequences() == null
+ || !dataset.getSequences().contains(
+ sprods[s].getDatasetSequence()))
+ {
+ dataset.addSequence(sprods[s].getDatasetSequence());
+ }
+ sprods[s].updatePDBIds();
+ }
+ Alignment al = new Alignment(sprods);
+ al.setDataset(dataset);
+ return al;
+ }
+
+ public CrossRefAction(AlignFrame alignFrame, SequenceI[] sel,
+ boolean _odna, String source)
+ {
+ this.alignFrame = alignFrame;
+ this.sel = sel;
+ this._odna = _odna;
+ this.source = source;
+ }
+
+ public static CrossRefAction showProductsFor(final SequenceI[] sel,
+ final boolean _odna, final String source,
+ final AlignFrame alignFrame)
+ {
+ return new CrossRefAction(alignFrame, sel, _odna, source);
+ }
+
+}
@Override
public void textarea_mousePressed(MouseEvent e)
{
+ // isPopupTrigger is on mousePressed (Mac) or mouseReleased (Windows)
if (e.isPopupTrigger())
{
JPopupMenu popup = new JPopupMenu(
@Override
public void textarea_mousePressed(MouseEvent e)
{
+ /*
+ * isPopupTrigger is checked in mousePressed on Mac,
+ * in mouseReleased on Windows
+ */
if (e.isPopupTrigger())
{
JPopupMenu popup = new JPopupMenu(
seqs.setSelected(seqsrc);
JPanel panel = new JPanel(new BorderLayout());
JPanel pane12 = new JPanel(new BorderLayout());
- pane12.add(new JLabel(MessageManager.getString("label.name")),
+ pane12.add(new JLabel(MessageManager.getString("label.name:")),
BorderLayout.CENTER);
pane12.add(nametf, BorderLayout.EAST);
panel.add(pane12, BorderLayout.NORTH);
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
-import java.awt.event.MouseListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
-import java.beans.PropertyVetoException;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileOutputStream;
import javax.swing.SwingUtilities;
import javax.swing.event.HyperlinkEvent;
import javax.swing.event.HyperlinkEvent.EventType;
+import javax.swing.event.InternalFrameAdapter;
+import javax.swing.event.InternalFrameEvent;
import javax.swing.event.MenuEvent;
import javax.swing.event.MenuListener;
@Override
public void mousePressed(MouseEvent evt)
{
- if (evt.isPopupTrigger())
+ if (evt.isPopupTrigger()) // Mac
+ {
+ showPasteMenu(evt.getX(), evt.getY());
+ }
+ }
+
+ @Override
+ public void mouseReleased(MouseEvent evt)
+ {
+ if (evt.isPopupTrigger()) // Windows
{
showPasteMenu(evt.getX(), evt.getY());
}
* ((openFrameCount - 1) % 10) + yOffset);
}
+ /*
+ * add an entry for the new frame in the Window menu
+ * (and remove it when the frame is closed)
+ */
final JMenuItem menuItem = new JMenuItem(title);
- frame.addInternalFrameListener(new javax.swing.event.InternalFrameAdapter()
+ frame.addInternalFrameListener(new InternalFrameAdapter()
{
@Override
- public void internalFrameActivated(
- javax.swing.event.InternalFrameEvent evt)
+ public void internalFrameActivated(InternalFrameEvent evt)
{
JInternalFrame itf = desktop.getSelectedFrame();
if (itf != null)
{
itf.requestFocus();
}
-
}
@Override
- public void internalFrameClosed(
- javax.swing.event.InternalFrameEvent evt)
+ public void internalFrameClosed(InternalFrameEvent evt)
{
PaintRefresher.RemoveComponent(frame);
- openFrameCount--;
+
+ /*
+ * defensive check to prevent frames being
+ * added half off the window
+ */
+ if (openFrameCount > 0)
+ {
+ openFrameCount--;
+ }
+
+ /*
+ * ensure no reference to alignFrame retained by menu item listener
+ */
+ if (menuItem.getActionListeners().length > 0)
+ {
+ menuItem.removeActionListener(menuItem.getActionListeners()[0]);
+ }
windowMenu.remove(menuItem);
JInternalFrame itf = desktop.getSelectedFrame();
if (itf != null)
{
itf.requestFocus();
+ if (itf instanceof AlignFrame)
+ {
+ Jalview.setCurrentAlignFrame((AlignFrame) itf);
+ }
}
System.gc();
};
}
}
});
- menuItem.addMouseListener(new MouseListener()
- {
-
- @Override
- public void mouseReleased(MouseEvent e)
- {
- }
-
- @Override
- public void mousePressed(MouseEvent e)
- {
- }
-
- @Override
- public void mouseExited(MouseEvent e)
- {
- try
- {
- frame.setSelected(false);
- } catch (PropertyVetoException e1)
- {
- }
- }
-
- @Override
- public void mouseEntered(MouseEvent e)
- {
- try
- {
- frame.setSelected(true);
- } catch (PropertyVetoException e1)
- {
- }
- }
-
- @Override
- public void mouseClicked(MouseEvent e)
- {
-
- }
- });
windowMenu.add(menuItem);
public void drop(DropTargetDropEvent evt)
{
boolean success = true;
+ // JAL-1552 - acceptDrop required before getTransferable call for
+ // Java's Transferable for native dnd
+ evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
Transferable t = evt.getTransferable();
java.util.List<String> files = new ArrayList<String>();
java.util.List<String> protocols = new ArrayList<String>();
@Override
public void closeAll_actionPerformed(ActionEvent e)
{
+ // TODO show a progress bar while closing?
JInternalFrame[] frames = desktop.getAllFrames();
for (int i = 0; i < frames.length; i++)
{
{
}
}
+ Jalview.setCurrentAlignFrame(null);
System.out.println("ALL CLOSED");
if (v_client != null)
{
{
ssm.resetAll();
}
+ System.gc();
}
@Override
*
* @param af
*/
- public void explodeViews(AlignFrame af)
+ public static void explodeViews(AlignFrame af)
{
int size = af.alignPanels.size();
if (size < 2)
{
getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
KeyStroke.getKeyStroke(KeyEvent.VK_Q, Toolkit
- .getDefaultToolkit().getMenuShortcutKeyMask()),
- "Quit");
+ .getDefaultToolkit().getMenuShortcutKeyMask()), "Quit");
getRootPane().getActionMap().put("Quit", new AbstractAction()
{
@Override
{
// Works on Windows and MacOSX
Cache.log.debug("Drop handled as javaFileListFlavor");
- evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
for (Object file : (List) t
.getTransferData(DataFlavor.javaFileListFlavor))
{
- files.add(((File)file).toString());
+ files.add(((File) file).toString());
protocols.add(FormatAdapter.FILE);
}
}
{
Cache.log.debug("Drop handled as uriListFlavor");
// This is used by Unix drag system
- evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
data = (String) t.getTransferData(uriListFlavor);
}
if (data == null)
{
Cache.log.debug("Supported transfer dataflavor: "
+ fl.toString());
- evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
Object df = t.getTransferData(fl);
if (df != null)
{
threshold.setToolTipText(MessageManager
.getString("label.threshold_feature_display_by_score"));
threshold.addItem(MessageManager
- .getString("label.threshold_feature_no_thereshold")); // index 0
+ .getString("label.threshold_feature_no_threshold")); // index 0
threshold.addItem(MessageManager
- .getString("label.threshold_feature_above_thereshold")); // index 1
+ .getString("label.threshold_feature_above_threshold")); // index 1
threshold.addItem(MessageManager
- .getString("label.threshold_feature_below_thereshold")); // index 2
+ .getString("label.threshold_feature_below_threshold")); // index 2
jPanel3.setLayout(flowLayout2);
thresholdValue.addActionListener(new ActionListener()
{
slider.setOpaque(false);
slider.setPreferredSize(new Dimension(100, 32));
slider.setToolTipText(MessageManager
- .getString("label.adjust_thereshold"));
+ .getString("label.adjust_threshold"));
thresholdValue.setEnabled(false);
thresholdValue.setColumns(7);
jPanel3.setBackground(Color.white);
*/
public FeatureRenderer(AlignmentPanel ap)
{
- super();
+ super(ap.av);
this.ap = ap;
- this.av = ap.av;
if (ap != null && ap.getSeqPanel() != null
&& ap.getSeqPanel().seqCanvas != null
&& ap.getSeqPanel().seqCanvas.fr != null)
{
panel = new JPanel(new GridLayout(4, 1));
tmp = new JPanel();
- tmp.add(new JLabel(MessageManager.getString("label.select_feature")));
+ tmp.add(new JLabel(MessageManager.getString("label.select_feature")
+ + ":"));
overlaps = new JComboBox();
for (int i = 0; i < features.length; i++)
{
tmp = new JPanel();
panel.add(tmp);
- tmp.add(new JLabel(MessageManager.getString("label.name"), JLabel.RIGHT));
+ tmp.add(new JLabel(MessageManager.getString("label.name:"),
+ JLabel.RIGHT));
tmp.add(name);
tmp = new JPanel();
panel.add(tmp);
- tmp.add(new JLabel(MessageManager.getString("label.group") + ":",
+ tmp.add(new JLabel(MessageManager.getString("label.group:"),
JLabel.RIGHT));
tmp.add(source);
bigPanel.add(panel, BorderLayout.NORTH);
panel = new JPanel();
- panel.add(new JLabel(MessageManager.getString("label.description"),
+ panel.add(new JLabel(MessageManager.getString("label.description:"),
JLabel.RIGHT));
description.setFont(JvSwingUtils.getTextAreaFont());
description.setLineWrap(true);
public void mousePressed(MouseEvent evt)
{
selectedRow = table.rowAtPoint(evt.getPoint());
- if (SwingUtilities.isRightMouseButton(evt))
+ if (evt.isPopupTrigger())
{
popupSort(selectedRow, (String) table.getValueAt(selectedRow, 0),
table.getValueAt(selectedRow, 1), fr.getMinMax(),
}
else if (evt.getClickCount() == 2)
{
+ boolean invertSelection = evt.isAltDown();
+ boolean toggleSelection = Platform.isControlDown(evt);
+ boolean extendSelection = evt.isShiftDown();
fr.ap.alignFrame.avc.markColumnsContainingFeatures(
- evt.isAltDown(), evt.isShiftDown() || evt.isMetaDown(),
- evt.isMetaDown(),
+ invertSelection, extendSelection, toggleSelection,
(String) table.getValueAt(selectedRow, 0));
}
}
- // isPopupTrigger fires on mouseReleased on Mac
+ // isPopupTrigger fires on mouseReleased on Windows
@Override
public void mouseReleased(MouseEvent evt)
{
int newRow = table.rowAtPoint(evt.getPoint());
if (newRow != selectedRow && selectedRow != -1 && newRow != -1)
{
+ /*
+ * reposition 'selectedRow' to 'newRow' (the dragged to location)
+ * this could be more than one row away for a very fast drag action
+ * so just swap it with adjacent rows until we get it there
+ */
Object[][] data = ((FeatureTableModel) table.getModel())
.getData();
- Object[] temp = data[selectedRow];
- data[selectedRow] = data[newRow];
- data[newRow] = temp;
+ int direction = newRow < selectedRow ? -1 : 1;
+ for (int i = selectedRow; i != newRow; i += direction)
+ {
+ Object[] temp = data[i];
+ data[i] = data[i + direction];
+ data[i + direction] = temp;
+ }
updateFeatureRenderer(data);
table.repaint();
selectedRow = newRow;
else
{
// probably the color chooser!
- table.setValueAt(colorChooser.getColor(), selectedRow, 1);
+ table.setValueAt(
+ new FeatureColour(colorChooser.getColor()),
+ selectedRow, 1);
table.validate();
me.updateFeatureRenderer(
((FeatureTableModel) table.getModel()).getData(),
}
else
{
- Color color = new Color(
- Integer.parseInt(jucs.getColour(i).getRGB(), 16));
+ Color color = new Color(Integer.parseInt(jucs.getColour(i)
+ .getRGB(), 16));
fr.setColour(name = jucs.getColour(i).getName(),
new FeatureColour(color));
}
void save()
{
JalviewFileChooser chooser = new JalviewFileChooser(
- Cache.getProperty("LAST_DIRECTORY"),
- new String[] { "fc" },
+ Cache.getProperty("LAST_DIRECTORY"), new String[] { "fc" },
new String[] { "Sequence Feature Colours" },
"Sequence Feature Colours");
chooser.setFileView(new jalview.io.JalviewFileView());
init = false;
}
+ @Override
public void smoothFont_actionPerformed(ActionEvent e)
{
ap.av.antiAlias = smoothFont.isSelected();
* @param e
* DOCUMENT ME!
*/
+ @Override
protected void ok_actionPerformed(ActionEvent e)
{
try
* @param e
* DOCUMENT ME!
*/
+ @Override
protected void cancel_actionPerformed(ActionEvent e)
{
if (ap != null)
double iw = iBounds.getWidth();
if (mw < 1 || iw < 1)
{
- final String messageKey = iBounds.getHeight() < 1 ? "label.font_doesnt_have_letters_defined"
- : "label.font_too_small";
- JOptionPane.showInternalMessageDialog(this,
- MessageManager.getString(messageKey),
+ String message = iBounds.getHeight() < 1 ? MessageManager
+ .getString("label.font_doesnt_have_letters_defined")
+ : MessageManager.getString("label.font_too_small");
+ JOptionPane.showInternalMessageDialog(this, message,
MessageManager.getString("label.invalid_font"),
JOptionPane.WARNING_MESSAGE);
/*
* @param e
* DOCUMENT ME!
*/
+ @Override
protected void fontName_actionPerformed(ActionEvent e)
{
if (init)
* @param e
* DOCUMENT ME!
*/
+ @Override
protected void fontSize_actionPerformed(ActionEvent e)
{
if (init)
* @param e
* DOCUMENT ME!
*/
+ @Override
protected void fontStyle_actionPerformed(ActionEvent e)
{
if (init)
*
* @param e
*/
+ @Override
public void defaultButton_actionPerformed(ActionEvent e)
{
Cache.setProperty("FONT_NAME", fontName.getSelectedItem().toString());
{
public enum HelpId
{
- Home("home"), SequenceFeatureSettings("seqfeatures.settings"), StructureViewer(
- "viewingpdbs");
+ Home("home"), SequenceFeatureSettings("seqfeatures.settings"),
+ StructureViewer("viewingpdbs");
private String id;
import jalview.datamodel.SequenceI;
import jalview.io.SequenceAnnotationReport;
import jalview.util.MessageManager;
+import jalview.util.Platform;
import jalview.util.UrlLink;
import jalview.viewmodel.AlignmentViewport;
return;
}
- int seq = alignPanel.getSeqPanel().findSeq(e);
-
- if (e.isPopupTrigger())
+ if (e.isPopupTrigger()) // Mac reports this in mousePressed
{
- Sequence sq = (Sequence) av.getAlignment().getSequenceAt(seq);
- // build a new links menu based on the current links + any non-positional
- // features
- Vector<String> nlinks = new Vector<String>(
- Preferences.sequenceURLLinks);
- SequenceFeature sfs[] = sq == null ? null : sq.getSequenceFeatures();
- if (sfs != null)
- {
- for (SequenceFeature sf : sfs)
- {
- if (sf.begin == sf.end && sf.begin == 0)
- {
- if (sf.links != null && sf.links.size() > 0)
- {
- for (int l = 0, lSize = sf.links.size(); l < lSize; l++)
- {
- nlinks.addElement(sf.links.elementAt(l));
- }
- }
- }
- }
- }
-
- PopupMenu pop = new PopupMenu(alignPanel, sq, nlinks,
- Preferences.getGroupURLLinks());
- pop.show(this, e.getX(), e.getY());
+ showPopupMenu(e);
+ return;
+ }
+ /*
+ * defer right-mouse click handling to mouseReleased on Windows
+ * (where isPopupTrigger() will answer true)
+ * NB isRightMouseButton is also true for Cmd-click on Mac
+ */
+ if (SwingUtilities.isRightMouseButton(e) && !Platform.isAMac())
+ {
return;
}
+
if ((av.getSelectionGroup() == null)
- || (!jalview.util.Platform.isControlDown(e)
- && !e.isShiftDown() && av.getSelectionGroup() != null))
+ || (!jalview.util.Platform.isControlDown(e) && !e.isShiftDown() && av
+ .getSelectionGroup() != null))
{
av.setSelectionGroup(new SequenceGroup());
av.getSelectionGroup().setStartRes(0);
av.getSelectionGroup().setEndRes(av.getAlignment().getWidth() - 1);
}
+ int seq = alignPanel.getSeqPanel().findSeq(e);
if (e.isShiftDown() && (lastid != -1))
{
selectSeqs(lastid, seq);
{
selectSeq(seq);
}
- // TODO is this addition ok here?
+
av.isSelectionGroupChanged(true);
alignPanel.paintAlignment(true);
}
/**
+ * Build and show the popup-menu at the right-click mouse position
+ *
+ * @param e
+ */
+ void showPopupMenu(MouseEvent e)
+ {
+ int seq2 = alignPanel.getSeqPanel().findSeq(e);
+ Sequence sq = (Sequence) av.getAlignment().getSequenceAt(seq2);
+ // build a new links menu based on the current links + any non-positional
+ // features
+ Vector<String> nlinks = new Vector<String>(Preferences.sequenceURLLinks);
+ SequenceFeature sfs[] = sq == null ? null : sq.getSequenceFeatures();
+ if (sfs != null)
+ {
+ for (SequenceFeature sf : sfs)
+ {
+ if (sf.begin == sf.end && sf.begin == 0)
+ {
+ if (sf.links != null && sf.links.size() > 0)
+ {
+ for (int l = 0, lSize = sf.links.size(); l < lSize; l++)
+ {
+ nlinks.addElement(sf.links.elementAt(l));
+ }
+ }
+ }
+ }
+ }
+
+ PopupMenu pop = new PopupMenu(alignPanel, sq, nlinks,
+ Preferences.getGroupURLLinks());
+ pop.show(this, e.getX(), e.getY());
+ }
+
+ /**
* Toggle whether the sequence is part of the current selection group.
*
* @param seq
PaintRefresher.Refresh(this, av.getSequenceSetId());
// always send selection message when mouse is released
av.sendSelection();
+
+ if (e.isPopupTrigger()) // Windows reports this in mouseReleased
+ {
+ showPopupMenu(e);
+ }
}
/**
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Hashtable;
_setSelectionState();
}
});
+ dbviews.addMouseListener(new MouseAdapter()
+ {
+
+ @Override
+ public void mousePressed(MouseEvent e)
+ {
+ if (e.getClickCount() == 2)
+ {
+ okPressed();
+ closeDialog();
+ }
+ }
+ });
JPanel jc = new JPanel(new BorderLayout()), j = new JPanel(
new FlowLayout());
jc.add(svp, BorderLayout.CENTER);
protected void okPressed()
{
_setSelectionState();
- closeDialog();
}
@Override
{
action = arg0.getKeyCode();
okPressed();
+ closeDialog();
}
if (!arg0.isConsumed() && arg0.getKeyChar() == KeyEvent.VK_ESCAPE)
{
*/
package jalview.gui;
+import jalview.analysis.Conservation;
import jalview.api.FeatureColourI;
import jalview.api.ViewStyleI;
import jalview.api.structures.JalviewStructureDisplayI;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
*/
Map<String, SequenceI> seqRefIds = null;
- Vector<Object[]> frefedSequence = null;
+ Map<String, SequenceI> incompleteSeqs = null;
+
+ List<SeqFref> frefedSequence = null;
boolean raiseGUI = true; // whether errors are raised in dialog boxes or not
{
seqsToIds.clear();
}
+ if (incompleteSeqs != null)
+ {
+ incompleteSeqs.clear();
+ }
// seqRefIds = null;
// seqsToIds = null;
}
{
seqRefIds = new HashMap<String, SequenceI>();
}
+ if (incompleteSeqs == null)
+ {
+ incompleteSeqs = new HashMap<String, SequenceI>();
+ }
+ if (frefedSequence == null)
+ {
+ frefedSequence = new ArrayList<SeqFref>();
+ }
}
public Jalview2XML()
this.raiseGUI = raiseGUI;
}
+ /**
+ * base class for resolving forward references to sequences by their ID
+ *
+ * @author jprocter
+ *
+ */
+ abstract class SeqFref
+ {
+ String sref;
+
+ String type;
+
+ public SeqFref(String _sref, String type)
+ {
+ sref = _sref;
+ this.type = type;
+ }
+
+ public String getSref()
+ {
+ return sref;
+ }
+
+ public SequenceI getSrefSeq()
+ {
+ return seqRefIds.get(sref);
+ }
+
+ public boolean isResolvable()
+ {
+ return seqRefIds.get(sref) != null;
+ }
+
+ public SequenceI getSrefDatasetSeq()
+ {
+ SequenceI sq = seqRefIds.get(sref);
+ if (sq != null)
+ {
+ while (sq.getDatasetSequence() != null)
+ {
+ sq = sq.getDatasetSequence();
+ }
+ }
+ return sq;
+ }
+
+ /**
+ * @return true if the forward reference was fully resolved
+ */
+ abstract boolean resolve();
+
+ @Override
+ public String toString()
+ {
+ return type + " reference to " + sref;
+ }
+ }
+
+ /**
+ * create forward reference for a mapping
+ *
+ * @param sref
+ * @param _jmap
+ * @return
+ */
+ public SeqFref newMappingRef(final String sref,
+ final jalview.datamodel.Mapping _jmap)
+ {
+ SeqFref fref = new SeqFref(sref, "Mapping")
+ {
+ public jalview.datamodel.Mapping jmap = _jmap;
+
+ @Override
+ boolean resolve()
+ {
+ SequenceI seq = getSrefDatasetSeq();
+ if (seq == null)
+ {
+ return false;
+ }
+ jmap.setTo(seq);
+ return true;
+ }
+ };
+ return fref;
+ }
+
+ public SeqFref newAlcodMapRef(final String sref,
+ final AlignedCodonFrame _cf, final jalview.datamodel.Mapping _jmap)
+ {
+
+ SeqFref fref = new SeqFref(sref, "Codon Frame")
+ {
+ AlignedCodonFrame cf = _cf;
+
+ public jalview.datamodel.Mapping mp = _jmap;
+
+ @Override
+ public boolean isResolvable()
+ {
+ return super.isResolvable() && mp.getTo() != null;
+ };
+
+ @Override
+ boolean resolve()
+ {
+ SequenceI seq = getSrefDatasetSeq();
+ if (seq == null)
+ {
+ return false;
+ }
+ cf.addMap(seq, mp.getTo(), mp.getMap());
+ return true;
+ }
+ };
+ return fref;
+ }
+
public void resolveFrefedSequences()
{
- if (frefedSequence.size() > 0)
+ Iterator<SeqFref> nextFref = frefedSequence.iterator();
+ int toresolve = frefedSequence.size();
+ int unresolved = 0, failedtoresolve = 0;
+ while (nextFref.hasNext())
{
- int r = 0, rSize = frefedSequence.size();
- while (r < rSize)
+ SeqFref ref = nextFref.next();
+ if (ref.isResolvable())
{
- Object[] ref = frefedSequence.elementAt(r);
- if (ref != null)
+ try
{
- String sref = (String) ref[0];
- if (seqRefIds.containsKey(sref))
+ if (ref.resolve())
{
- if (ref[1] instanceof jalview.datamodel.Mapping)
- {
- SequenceI seq = seqRefIds.get(sref);
- while (seq.getDatasetSequence() != null)
- {
- seq = seq.getDatasetSequence();
- }
- ((jalview.datamodel.Mapping) ref[1]).setTo(seq);
- }
- else
- {
- if (ref[1] instanceof jalview.datamodel.AlignedCodonFrame)
- {
- SequenceI seq = seqRefIds.get(sref);
- while (seq.getDatasetSequence() != null)
- {
- seq = seq.getDatasetSequence();
- }
- if (ref[2] != null
- && ref[2] instanceof jalview.datamodel.Mapping)
- {
- jalview.datamodel.Mapping mp = (jalview.datamodel.Mapping) ref[2];
- ((jalview.datamodel.AlignedCodonFrame) ref[1]).addMap(
- seq, mp.getTo(), mp.getMap());
- }
- else
- {
- System.err
- .println("IMPLEMENTATION ERROR: Unimplemented forward sequence references for AlcodonFrames involving "
- + ref[2].getClass() + " type objects.");
- }
- }
- else
- {
- System.err
- .println("IMPLEMENTATION ERROR: Unimplemented forward sequence references for "
- + ref[1].getClass() + " type objects.");
- }
- }
- frefedSequence.remove(r);
- rSize--;
+ nextFref.remove();
}
else
{
- System.err
- .println("IMPLEMENTATION WARNING: Unresolved forward reference for hash string "
- + ref[0]
- + " with objecttype "
- + ref[1].getClass());
- r++;
+ failedtoresolve++;
}
+ } catch (Exception x)
+ {
+ System.err
+ .println("IMPLEMENTATION ERROR: Failed to resolve forward reference for sequence "
+ + ref.getSref());
+ x.printStackTrace();
+ failedtoresolve++;
}
- else
+ }
+ else
+ {
+ unresolved++;
+ }
+ }
+ if (unresolved > 0)
+ {
+ System.err.println("Jalview Project Import: There were " + unresolved
+ + " forward references left unresolved on the stack.");
+ }
+ if (failedtoresolve > 0)
+ {
+ System.err.println("SERIOUS! " + failedtoresolve
+ + " resolvable forward references failed to resolve.");
+ }
+ if (incompleteSeqs != null && incompleteSeqs.size() > 0)
+ {
+ System.err.println("Jalview Project Import: There are "
+ + incompleteSeqs.size()
+ + " sequences which may have incomplete metadata.");
+ if (incompleteSeqs.size() < 10)
+ {
+ for (SequenceI s : incompleteSeqs.values())
{
- // empty reference
- frefedSequence.remove(r);
- rSize--;
+ System.err.println(s.toString());
}
}
+ else
+ {
+ System.err
+ .println("Too many to report. Skipping output of incomplete sequences.");
+ }
}
}
{
return;
}
+ saveAllFrames(Arrays.asList(frames), jout);
+ }
+ /**
+ * core method for storing state for a set of AlignFrames.
+ *
+ * @param frames
+ * - frames involving all data to be exported (including containing
+ * splitframes)
+ * @param jout
+ * - project output stream
+ */
+ private void saveAllFrames(List<AlignFrame> frames, JarOutputStream jout)
+ {
Hashtable<String, AlignFrame> dsses = new Hashtable<String, AlignFrame>();
/*
List<String> viewIds = new ArrayList<String>();
// REVERSE ORDER
- for (int i = frames.length - 1; i > -1; i--)
+ for (int i = frames.size() - 1; i > -1; i--)
{
- AlignFrame af = frames[i];
+ AlignFrame af = frames.get(i);
// skip ?
if (skipList != null
&& skipList
{
try
{
- int ap = 0;
- int apSize = af.alignPanels.size();
FileOutputStream fos = new FileOutputStream(jarFile);
JarOutputStream jout = new JarOutputStream(fos);
- Hashtable<String, AlignFrame> dsses = new Hashtable<String, AlignFrame>();
- List<String> viewIds = new ArrayList<String>();
+ List<AlignFrame> frames = new ArrayList<AlignFrame>();
- for (AlignmentPanel apanel : af.alignPanels)
+ // resolve splitframes
+ if (af.getViewport().getCodingComplement() != null)
{
- String jfileName = apSize == 1 ? fileName : fileName + ap;
- ap++;
- if (!jfileName.endsWith(".xml"))
- {
- jfileName = jfileName + ".xml";
- }
- saveState(apanel, jfileName, jout, viewIds);
- String dssid = getDatasetIdRef(af.getViewport().getAlignment()
- .getDataset());
- if (!dsses.containsKey(dssid))
- {
- dsses.put(dssid, af);
- }
+ frames = ((SplitFrame) af.getSplitViewContainer()).getAlignFrames();
}
- writeDatasetFor(dsses, fileName, jout);
+ else
+ {
+ frames.add(af);
+ }
+ saveAllFrames(frames, jout);
try
{
jout.flush();
JSeq jseq;
Set<String> calcIdSet = new HashSet<String>();
-
+ // record the set of vamsas sequence XML POJO we create.
+ HashMap<String, Sequence> vamsasSetIds = new HashMap<String, Sequence>();
// SAVE SEQUENCES
for (final SequenceI jds : rjal.getSequences())
{
final SequenceI jdatasq = jds.getDatasetSequence() == null ? jds
: jds.getDatasetSequence();
String id = seqHash(jds);
-
- if (seqRefIds.get(id) != null)
- {
- // This happens for two reasons: 1. multiple views are being serialised.
- // 2. the hashCode has collided with another sequence's code. This DOES
- // HAPPEN! (PF00072.15.stk does this)
- // JBPNote: Uncomment to debug writing out of files that do not read
- // back in due to ArrayOutOfBoundExceptions.
- // System.err.println("vamsasSeq backref: "+id+"");
- // System.err.println(jds.getName()+"
- // "+jds.getStart()+"-"+jds.getEnd()+" "+jds.getSequenceAsString());
- // System.err.println("Hashcode: "+seqHash(jds));
- // SequenceI rsq = (SequenceI) seqRefIds.get(id + "");
- // System.err.println(rsq.getName()+"
- // "+rsq.getStart()+"-"+rsq.getEnd()+" "+rsq.getSequenceAsString());
- // System.err.println("Hashcode: "+seqHash(rsq));
- }
- else
- {
- vamsasSeq = createVamsasSequence(id, jds);
- vamsasSet.addSequence(vamsasSeq);
- seqRefIds.put(id, jds);
+ if (vamsasSetIds.get(id) == null)
+ {
+ if (seqRefIds.get(id) != null && !storeDS)
+ {
+ // This happens for two reasons: 1. multiple views are being
+ // serialised.
+ // 2. the hashCode has collided with another sequence's code. This
+ // DOES
+ // HAPPEN! (PF00072.15.stk does this)
+ // JBPNote: Uncomment to debug writing out of files that do not read
+ // back in due to ArrayOutOfBoundExceptions.
+ // System.err.println("vamsasSeq backref: "+id+"");
+ // System.err.println(jds.getName()+"
+ // "+jds.getStart()+"-"+jds.getEnd()+" "+jds.getSequenceAsString());
+ // System.err.println("Hashcode: "+seqHash(jds));
+ // SequenceI rsq = (SequenceI) seqRefIds.get(id + "");
+ // System.err.println(rsq.getName()+"
+ // "+rsq.getStart()+"-"+rsq.getEnd()+" "+rsq.getSequenceAsString());
+ // System.err.println("Hashcode: "+seqHash(rsq));
+ }
+ else
+ {
+ vamsasSeq = createVamsasSequence(id, jds);
+ vamsasSet.addSequence(vamsasSeq);
+ vamsasSetIds.put(id, vamsasSeq);
+ seqRefIds.put(id, jds);
+ }
}
-
jseq = new JSeq();
jseq.setStart(jds.getStart());
jseq.setEnd(jds.getEnd());
if (av.isHiddenRepSequence(jds))
{
jalview.datamodel.SequenceI[] reps = av
- .getRepresentedSequences(jds)
- .getSequencesInOrder(rjal);
+ .getRepresentedSequences(jds).getSequencesInOrder(rjal);
for (int h = 0; h < reps.length; h++)
{
}
}
- if (entry.getProperty() != null && !entry.getProperty().isEmpty())
+ Enumeration<String> props = entry.getProperties();
+ if (props.hasMoreElements())
{
PdbentryItem item = new PdbentryItem();
- Hashtable properties = entry.getProperty();
- Enumeration en2 = properties.keys();
- while (en2.hasMoreElements())
+ while (props.hasMoreElements())
{
Property prop = new Property();
- String key = en2.nextElement().toString();
+ String key = props.nextElement();
prop.setName(key);
- prop.setValue(properties.get(key).toString());
+ prop.setValue(entry.getProperty(key).toString());
item.addProperty(prop);
}
pdb.addPdbentryItem(item);
jal = av.getAlignment();
}
// SAVE MAPPINGS
- if (jal.getCodonFrames() != null)
+ // FOR DATASET
+ if (storeDS && jal.getCodonFrames() != null)
{
List<AlignedCodonFrame> jac = jal.getCodonFrames();
for (AlignedCodonFrame acf : jac)
{
AlcodonFrame alc = new AlcodonFrame();
- vamsasSet.addAlcodonFrame(alc);
if (acf.getProtMappings() != null
&& acf.getProtMappings().length > 0)
{
+ boolean hasMap = false;
SequenceI[] dnas = acf.getdnaSeqs();
jalview.datamodel.Mapping[] pmaps = acf.getProtMappings();
for (int m = 0; m < pmaps.length; m++)
alcmap.setMapping(createVamsasMapping(pmaps[m], dnas[m], null,
false));
alc.addAlcodMap(alcmap);
+ hasMap = true;
+ }
+ if (hasMap)
+ {
+ vamsasSet.addAlcodonFrame(alc);
}
}
// TODO: delete this ? dead code from 2.8.3->2.9 ?
for (String featureType : renderOrder)
{
FeatureColourI fcol = ap.getSeqPanel().seqCanvas
- .getFeatureRenderer()
- .getFeatureStyle(featureType);
+ .getFeatureRenderer().getFeatureStyle(featureType);
Setting setting = new Setting();
setting.setType(featureType);
if (!fcol.isSimpleColour())
setting.setAutoScale(fcol.isAutoScaled());
setting.setThreshold(fcol.getThreshold());
// -1 = No threshold, 0 = Below, 1 = Above
- setting.setThreshstate(fcol.isAboveThreshold() ? 1
- : (fcol.isBelowThreshold() ? 0 : -1));
+ setting.setThreshstate(fcol.isAboveThreshold() ? 1 : (fcol
+ .isBelowThreshold() ? 0 : -1));
}
else
{
// is groups actually supposed to be a map here ?
Iterator<String> en = ap.getSeqPanel().seqCanvas
- .getFeatureRenderer()
- .getFeatureGroups().iterator();
+ .getFeatureRenderer().getFeatureGroups().iterator();
Vector<String> groupsAdded = new Vector<String>();
while (en.hasNext())
{
if (jds.getDatasetSequence() != null)
{
vamsasSeq.setDsseqid(seqHash(jds.getDatasetSequence()));
- if (jds.getDatasetSequence().getDBRefs() != null)
- {
- dbrefs = jds.getDatasetSequence().getDBRefs();
- }
}
else
{
- vamsasSeq.setDsseqid(id); // so we can tell which sequences really are
+ // seqId==dsseqid so we can tell which sequences really are
// dataset sequences only
+ vamsasSeq.setDsseqid(id);
dbrefs = jds.getDBRefs();
+ if (parentseq == null)
+ {
+ parentseq = jds;
+ }
}
if (dbrefs != null)
{
if (jmp.getTo() != null)
{
MappingChoice mpc = new MappingChoice();
- if (recurse
- && (parentseq != jmp.getTo() || parentseq
- .getDatasetSequence() != jmp.getTo()))
+
+ // check/create ID for the sequence referenced by getTo()
+
+ String jmpid = "";
+ SequenceI ps = null;
+ if (parentseq != jmp.getTo()
+ && parentseq.getDatasetSequence() != jmp.getTo())
{
- mpc.setSequence(createVamsasSequence(false, seqHash(jmp.getTo()),
- jmp.getTo(), jds));
+ // chaining dbref rather than a handshaking one
+ jmpid = seqHash(ps = jmp.getTo());
}
else
{
- String jmpid = "";
- SequenceI ps = null;
- if (parentseq != jmp.getTo()
- && parentseq.getDatasetSequence() != jmp.getTo())
- {
- // chaining dbref rather than a handshaking one
- jmpid = seqHash(ps = jmp.getTo());
- }
- else
- {
- jmpid = seqHash(ps = parentseq);
- }
- mpc.setDseqFor(jmpid);
- if (!seqRefIds.containsKey(mpc.getDseqFor()))
- {
- jalview.bin.Cache.log.debug("creatign new DseqFor ID");
- seqRefIds.put(mpc.getDseqFor(), ps);
- }
- else
- {
- jalview.bin.Cache.log.debug("reusing DseqFor ID");
- }
+ jmpid = seqHash(ps = parentseq);
}
+ mpc.setDseqFor(jmpid);
+ if (!seqRefIds.containsKey(mpc.getDseqFor()))
+ {
+ jalview.bin.Cache.log.debug("creatign new DseqFor ID");
+ seqRefIds.put(mpc.getDseqFor(), ps);
+ }
+ else
+ {
+ jalview.bin.Cache.log.debug("reusing DseqFor ID");
+ }
+
mp.setMappingChoice(mpc);
}
}
}
if (seqRefIds == null)
{
- seqRefIds = new HashMap<String, SequenceI>();
- }
- if (frefedSequence == null)
- {
- frefedSequence = new Vector<Object[]>();
+ initSeqRefs();
}
-
AlignFrame af = null, _af = null;
+ IdentityHashMap<AlignmentI, AlignmentI> importedDatasets = new IdentityHashMap<AlignmentI, AlignmentI>();
Map<String, AlignFrame> gatherToThisFrame = new HashMap<String, AlignFrame>();
final String file = jprovider.getFilename();
try
if (true) // !skipViewport(object))
{
_af = loadFromObject(object, file, true, jprovider);
- if (object.getJalviewModelSequence().getViewportCount() > 0)
+ if (_af != null
+ && object.getJalviewModelSequence().getViewportCount() > 0)
{
- af = _af;
- if (af.viewport.isGatherViewsHere())
+ if (af == null)
+ {
+ // store a reference to the first view
+ af = _af;
+ }
+ if (_af.viewport.isGatherViewsHere())
{
- gatherToThisFrame.put(af.viewport.getSequenceSetId(), af);
+ // if this is a gathered view, keep its reference since
+ // after gathering views, only this frame will remain
+ af = _af;
+ gatherToThisFrame.put(_af.viewport.getSequenceSetId(), _af);
}
+ // Save dataset to register mappings once all resolved
+ importedDatasets.put(af.viewport.getAlignment().getDataset(),
+ af.viewport.getAlignment().getDataset());
}
}
entryCount++;
e.printStackTrace();
}
- if (Desktop.instance != null)
- {
- Desktop.instance.stopLoading();
- }
-
/*
* Regather multiple views (with the same sequence set id) to the frame (if
* any) that is flagged as the one to gather to, i.e. convert them to tabbed
}
restoreSplitFrames();
-
+ for (AlignmentI ds : importedDatasets.keySet())
+ {
+ if (ds.getCodonFrames() != null)
+ {
+ StructureSelectionManager.getStructureSelectionManager(
+ Desktop.instance).registerMappings(ds.getCodonFrames());
+ }
+ }
if (errorMessage != null)
{
reportErrors();
}
+
+ if (Desktop.instance != null)
+ {
+ Desktop.instance.stopLoading();
+ }
+
return af;
}
SplitFrame sf = createSplitFrame(dnaFrame, af);
addedToSplitFrames.add(dnaFrame);
addedToSplitFrames.add(af);
+ dnaFrame.setMenusForViewport();
+ af.setMenusForViewport();
if (af.viewport.isGatherViewsHere())
{
gatherTo.add(sf);
Viewport view = candidate.getKey();
Desktop.addInternalFrame(af, view.getTitle(), view.getWidth(),
view.getHeight());
+ af.setMenusForViewport();
System.err.println("Failed to restore view " + view.getTitle()
+ " to split frame");
}
* @param pdbId
* @return
*/
- String loadPDBFile(jarInputStreamProvider jprovider, String pdbId)
+ String loadPDBFile(jarInputStreamProvider jprovider, String pdbId,
+ String origFile)
{
if (alreadyLoadedPDB.containsKey(pdbId))
{
return alreadyLoadedPDB.get(pdbId).toString();
}
- String tempFile = copyJarEntry(jprovider, pdbId, "jalview_pdb");
+ String tempFile = copyJarEntry(jprovider, pdbId, "jalview_pdb",
+ origFile);
if (tempFile != null)
{
alreadyLoadedPDB.put(pdbId, tempFile);
* @param prefix
* a prefix for the temporary file name, must be at least three
* characters long
+ * @param origFile
+ * null or original file - so new file can be given the same suffix
+ * as the old one
* @return
*/
protected String copyJarEntry(jarInputStreamProvider jprovider,
- String jarEntryName, String prefix)
+ String jarEntryName, String prefix, String origFile)
{
BufferedReader in = null;
PrintWriter out = null;
-
+ String suffix = ".tmp";
+ if (origFile == null)
+ {
+ origFile = jarEntryName;
+ }
+ int sfpos = origFile.lastIndexOf(".");
+ if (sfpos > -1 && sfpos < (origFile.length() - 3))
+ {
+ suffix = "." + origFile.substring(sfpos + 1);
+ }
try
{
JarInputStream jin = jprovider.getJarInputStream();
if (entry != null)
{
in = new BufferedReader(new InputStreamReader(jin, UTF_8));
- File outFile = File.createTempFile(prefix, ".tmp");
+ File outFile = File.createTempFile(prefix, suffix);
outFile.deleteOnExit();
out = new PrintWriter(new FileOutputStream(outFile));
String data;
// LOAD SEQUENCES
List<SequenceI> hiddenSeqs = null;
- jalview.datamodel.Sequence jseq;
List<SequenceI> tmpseqs = new ArrayList<SequenceI>();
{
String seqId = jseqs[i].getId();
- if (seqRefIds.get(seqId) != null)
+ SequenceI tmpSeq = seqRefIds.get(seqId);
+ if (tmpSeq != null)
{
- tmpseqs.add(seqRefIds.get(seqId));
- multipleView = true;
+ if (!incompleteSeqs.containsKey(seqId))
+ {
+ // may not need this check, but keep it for at least 2.9,1 release
+ if (tmpSeq.getStart() != jseqs[i].getStart()
+ || tmpSeq.getEnd() != jseqs[i].getEnd())
+ {
+ System.err
+ .println("Warning JAL-2154 regression: updating start/end for sequence "
+ + tmpSeq.toString() + " to " + jseqs[i]);
+ }
+ }
+ else
+ {
+ incompleteSeqs.remove(seqId);
+ }
+ if (vamsasSeq.length > vi && vamsasSeq[vi].getId().equals(seqId))
+ {
+ // most likely we are reading a dataset XML document so
+ // update from vamsasSeq section of XML for this sequence
+ tmpSeq.setName(vamsasSeq[vi].getName());
+ tmpSeq.setDescription(vamsasSeq[vi].getDescription());
+ tmpSeq.setSequence(vamsasSeq[vi].getSequence());
+ vi++;
+ }
+ else
+ {
+ // reading multiple views, so vamsasSeq set is a subset of JSeq
+ multipleView = true;
+ }
+ tmpSeq.setStart(jseqs[i].getStart());
+ tmpSeq.setEnd(jseqs[i].getEnd());
+ tmpseqs.add(tmpSeq);
}
else
{
- jseq = new jalview.datamodel.Sequence(vamsasSeq[vi].getName(),
+ tmpSeq = new jalview.datamodel.Sequence(vamsasSeq[vi].getName(),
vamsasSeq[vi].getSequence());
- jseq.setDescription(vamsasSeq[vi].getDescription());
- jseq.setStart(jseqs[i].getStart());
- jseq.setEnd(jseqs[i].getEnd());
- jseq.setVamsasId(uniqueSetSuffix + seqId);
- seqRefIds.put(vamsasSeq[vi].getId(), jseq);
- tmpseqs.add(jseq);
+ tmpSeq.setDescription(vamsasSeq[vi].getDescription());
+ tmpSeq.setStart(jseqs[i].getStart());
+ tmpSeq.setEnd(jseqs[i].getEnd());
+ tmpSeq.setVamsasId(uniqueSetSuffix + seqId);
+ seqRefIds.put(vamsasSeq[vi].getId(), tmpSeq);
+ tmpseqs.add(tmpSeq);
vi++;
}
hiddenSeqs = new ArrayList<SequenceI>();
}
- hiddenSeqs.add(seqRefIds.get(seqId));
+ hiddenSeqs.add(tmpSeq);
}
}
SequenceI[] orderedSeqs = tmpseqs
.toArray(new SequenceI[tmpseqs.size()]);
- Alignment al = new Alignment(orderedSeqs);
+ AlignmentI al = null;
+ // so we must create or recover the dataset alignment before going further
+ // ///////////////////////////////
+ if (vamsasSet.getDatasetId() == null || vamsasSet.getDatasetId() == "")
+ {
+ // older jalview projects do not have a dataset - so creat alignment and
+ // dataset
+ al = new Alignment(orderedSeqs);
+ al.setDataset(null);
+ }
+ else
+ {
+ boolean isdsal = object.getJalviewModelSequence().getViewportCount() == 0;
+ if (isdsal)
+ {
+ // we are importing a dataset record, so
+ // recover reference to an alignment already materialsed as dataset
+ al = getDatasetFor(vamsasSet.getDatasetId());
+ }
+ if (al == null)
+ {
+ // materialse the alignment
+ al = new Alignment(orderedSeqs);
+ }
+ if (isdsal)
+ {
+ addDatasetRef(vamsasSet.getDatasetId(), al);
+ }
+
+ // finally, verify all data in vamsasSet is actually present in al
+ // passing on flag indicating if it is actually a stored dataset
+ recoverDatasetFor(vamsasSet, al, isdsal);
+ }
if (referenceseqForView != null)
{
al.setProperty(ssp.getKey(), ssp.getValue());
}
- // /
- // SequenceFeatures are added to the DatasetSequence,
- // so we must create or recover the dataset before loading features
- // ///////////////////////////////
- if (vamsasSet.getDatasetId() == null || vamsasSet.getDatasetId() == "")
- {
- // older jalview projects do not have a dataset id.
- al.setDataset(null);
- }
- else
- {
- // recover dataset - passing on flag indicating if this a 'viewless'
- // sequence set (a.k.a. a stored dataset for the project)
- recoverDatasetFor(vamsasSet, al, object.getJalviewModelSequence()
- .getViewportCount() == 0);
- }
// ///////////////////////////////
Hashtable pdbloaded = new Hashtable(); // TODO nothing writes to this??
{
// load sequence features, database references and any associated PDB
// structures for the alignment
+ //
+ // prior to 2.10, this part would only be executed the first time a
+ // sequence was encountered, but not afterwards.
+ // now, for 2.10 projects, this is also done if the xml doc includes
+ // dataset sequences not actually present in any particular view.
+ //
for (int i = 0; i < vamsasSeq.length; i++)
{
if (jseqs[i].getFeaturesCount() > 0)
}
}
-
- al.getSequenceAt(i).getDatasetSequence().addSequenceFeature(sf);
+ // adds feature to datasequence's feature set (since Jalview 2.10)
+ al.getSequenceAt(i).addSequenceFeature(sf);
}
}
if (vamsasSeq[i].getDBRefCount() > 0)
{
- addDBRefs(al.getSequenceAt(i).getDatasetSequence(), vamsasSeq[i]);
+ // adds dbrefs to datasequence's set (since Jalview 2.10)
+ addDBRefs(
+ al.getSequenceAt(i).getDatasetSequence() == null ? al.getSequenceAt(i)
+ : al.getSequenceAt(i).getDatasetSequence(),
+ vamsasSeq[i]);
}
if (jseqs[i].getPdbidsCount() > 0)
{
entry.setId(ids[p].getId());
if (ids[p].getType() != null)
{
- if (ids[p].getType().equalsIgnoreCase("PDB"))
+ if (PDBEntry.Type.getType(ids[p].getType()) != null)
{
- entry.setType(PDBEntry.Type.PDB);
+ entry.setType(PDBEntry.Type.getType(ids[p].getType()));
}
else
{
entry.setType(PDBEntry.Type.FILE);
}
}
- if (ids[p].getFile() != null)
+ // jprovider is null when executing 'New View'
+ if (ids[p].getFile() != null && jprovider != null)
{
if (!pdbloaded.containsKey(ids[p].getFile()))
{
- entry.setFile(loadPDBFile(jprovider, ids[p].getId()));
+ entry.setFile(loadPDBFile(jprovider, ids[p].getId(),
+ ids[p].getFile()));
}
else
{
entry.setFile(pdbloaded.get(ids[p].getId()).toString());
}
}
+ if (ids[p].getPdbentryItem() != null)
+ {
+ for (PdbentryItem item : ids[p].getPdbentryItem())
+ {
+ for (Property pr : item.getProperty())
+ {
+ entry.setProperty(pr.getName(), pr.getValue());
+ }
+ }
+ }
StructureSelectionManager.getStructureSelectionManager(
Desktop.instance).registerPDBEntry(entry);
- al.getSequenceAt(i).getDatasetSequence().addPDBId(entry);
+ // adds PDBEntry to datasequence's set (since Jalview 2.10)
+ if (al.getSequenceAt(i).getDatasetSequence() != null)
+ {
+ al.getSequenceAt(i).getDatasetSequence().addPDBId(entry);
+ }
+ else
+ {
+ al.getSequenceAt(i).addPDBId(entry);
+ }
}
}
}
if (maps[m].getMapping() != null)
{
mapping = addMapping(maps[m].getMapping());
- }
- if (dnaseq != null && mapping.getTo() != null)
- {
- cf.addMap(dnaseq, mapping.getTo(), mapping.getMap());
- }
- else
- {
- // defer to later
- frefedSequence.add(new Object[] { maps[m].getDnasq(), cf,
- mapping });
+ if (dnaseq != null && mapping.getTo() != null)
+ {
+ cf.addMap(dnaseq, mapping.getTo(), mapping.getMap());
+ }
+ else
+ {
+ // defer to later
+ frefedSequence.add(newAlcodMapRef(maps[m].getDnasq(), cf,
+ mapping));
+ }
}
}
+ al.addCodonFrame(cf);
}
- al.addCodonFrame(cf);
}
}
}
if (jGroup.getConsThreshold() != 0)
{
- jalview.analysis.Conservation c = new jalview.analysis.Conservation(
- "All", ResidueProperties.propHash, 3,
+ Conservation c = new Conservation("All", 3,
sg.getSequences(null), 0, sg.getWidth() - 1);
c.calculate();
c.verdict(false, 25);
String rnaTitle = ss.getTitle();
String sessionState = ss.getViewerState();
String tempStateFile = copyJarEntry(jprovider, sessionState,
- "varna");
+ "varna", null);
RnaModel rna = new RnaModel(rnaTitle, ann, seq, null, gapped);
appVarna.addModelSession(rna, rnaTitle, tempStateFile);
}
// Originally : ids[p].getFile()
// : TODO: verify external PDB file recovery still works in normal
// jalview project load
- jpdb.setFile(loadPDBFile(jprovider, ids[p].getId()));
+ jpdb.setFile(loadPDBFile(jprovider, ids[p].getId(),
+ ids[p].getFile()));
jpdb.setId(ids[p].getId());
int x = structureState.getXpos();
// Probably don't need to do this anymore...
// Desktop.desktop.getComponentAt(x, y);
// TODO: NOW: check that this recovers the PDB file correctly.
- String pdbFile = loadPDBFile(jprovider, ids[p].getId());
+ String pdbFile = loadPDBFile(jprovider, ids[p].getId(),
+ ids[p].getFile());
jalview.datamodel.SequenceI seq = seqRefIds.get(jseqs[i]
.getId() + "");
if (sviewid == null)
*/
String viewerJarEntryName = getViewerJarEntryName(data.getViewId());
chimeraSessionFile = copyJarEntry(jprovider, viewerJarEntryName,
- "chimera");
+ "chimera", null);
Set<Entry<File, StructureData>> fileData = data.getFileData()
.entrySet();
// filename
// translation differently.
StructureData filedat = oldFiles.get(new File(oldfilenam));
+ if (filedat == null)
+ {
+ String reformatedOldFilename = oldfilenam.replaceAll("/", "\\\\");
+ filedat = oldFiles.get(new File(reformatedOldFilename));
+ }
newFileLoc.append(Platform.escapeString(filedat.getFilePath()));
pdbfilenames.add(filedat.getFilePath());
pdbids.add(filedat.getPdbId());
}
AlignFrame loadViewport(String file, JSeq[] JSEQ,
- List<SequenceI> hiddenSeqs, Alignment al,
+ List<SequenceI> hiddenSeqs, AlignmentI al,
JalviewModelSequence jms, Viewport view, String uniqueSeqSetId,
String viewId, List<JvAnnotRow> autoAlan)
{
}
}
af.setMenusFromViewport(af.viewport);
-
+ af.setTitle(view.getTitle());
// TODO: we don't need to do this if the viewport is aready visible.
/*
* Add the AlignFrame to the desktop (it may be 'gathered' later), unless it
}
private ColourSchemeI constructAnnotationColour(
- AnnotationColours viewAnnColour, AlignFrame af, Alignment al,
+ AnnotationColours viewAnnColour, AlignFrame af, AlignmentI al,
JalviewModelSequence jms, boolean checkGroupAnnColour)
{
boolean propagateAnnColour = false;
return cs;
}
- private void reorderAutoannotation(AlignFrame af, Alignment al,
+ private void reorderAutoannotation(AlignFrame af, AlignmentI al,
List<JvAnnotRow> autoAlan)
{
// copy over visualization settings for autocalculated annotation in the
}
}
- private void recoverDatasetFor(SequenceSet vamsasSet, Alignment al,
+ private void recoverDatasetFor(SequenceSet vamsasSet, AlignmentI al,
boolean ignoreUnrefed)
{
- jalview.datamodel.Alignment ds = getDatasetFor(vamsasSet.getDatasetId());
+ jalview.datamodel.AlignmentI ds = getDatasetFor(vamsasSet
+ .getDatasetId());
Vector dseqs = null;
if (ds == null)
{
for (int i = 0, iSize = vamsasSet.getSequenceCount(); i < iSize; i++)
{
Sequence vamsasSeq = vamsasSet.getSequence(i);
- ensureJalviewDatasetSequence(vamsasSeq, ds, dseqs, ignoreUnrefed);
+ ensureJalviewDatasetSequence(vamsasSeq, ds, dseqs, ignoreUnrefed, i);
}
// create a new dataset
if (ds == null)
* dataset alignment
* @param dseqs
* vector to add new dataset sequence to
+ * @param ignoreUnrefed
+ * - when true, don't create new sequences from vamsasSeq if it's id
+ * doesn't already have an asssociated Jalview sequence.
+ * @param vseqpos
+ * - used to reorder the sequence in the alignment according to the
+ * vamsasSeq array ordering, to preserve ordering of dataset
*/
private void ensureJalviewDatasetSequence(Sequence vamsasSeq,
- AlignmentI ds, Vector dseqs, boolean ignoreUnrefed)
+ AlignmentI ds, Vector dseqs, boolean ignoreUnrefed, int vseqpos)
{
// JBP TODO: Check this is called for AlCodonFrames to support recovery of
// xRef Codon Maps
SequenceI sq = seqRefIds.get(vamsasSeq.getId());
+ boolean reorder = false;
SequenceI dsq = null;
if (sq != null && sq.getDatasetSequence() != null)
{
dsq = sq.getDatasetSequence();
}
+ else
+ {
+ reorder = true;
+ }
if (sq == null && ignoreUnrefed)
{
return;
// + (post ? "appended" : ""));
}
}
+ else
+ {
+ // sequence refs are identical. We may need to update the existing dataset
+ // alignment with this one, though.
+ if (ds != null && dseqs == null)
+ {
+ int opos = ds.findIndex(dsq);
+ SequenceI tseq = null;
+ if (opos != -1 && vseqpos != opos)
+ {
+ // remove from old position
+ ds.deleteSequence(dsq);
+ }
+ if (vseqpos < ds.getHeight())
+ {
+ if (vseqpos != opos)
+ {
+ // save sequence at destination position
+ tseq = ds.getSequenceAt(vseqpos);
+ ds.replaceSequenceAt(vseqpos, dsq);
+ ds.addSequence(tseq);
+ }
+ }
+ else
+ {
+ ds.addSequence(dsq);
+ }
+ }
+ }
}
/*
* TODO use AlignmentI here and in related methods - needs
* AlignmentI.getDataset() changed to return AlignmentI instead of Alignment
*/
- Hashtable<String, Alignment> datasetIds = null;
+ Hashtable<String, AlignmentI> datasetIds = null;
- IdentityHashMap<Alignment, String> dataset2Ids = null;
+ IdentityHashMap<AlignmentI, String> dataset2Ids = null;
- private Alignment getDatasetFor(String datasetId)
+ private AlignmentI getDatasetFor(String datasetId)
{
if (datasetIds == null)
{
- datasetIds = new Hashtable<String, Alignment>();
+ datasetIds = new Hashtable<String, AlignmentI>();
return null;
}
if (datasetIds.containsKey(datasetId))
return null;
}
- private void addDatasetRef(String datasetId, Alignment dataset)
+ private void addDatasetRef(String datasetId, AlignmentI dataset)
{
if (datasetIds == null)
{
- datasetIds = new Hashtable<String, Alignment>();
+ datasetIds = new Hashtable<String, AlignmentI>();
}
datasetIds.put(datasetId, dataset);
}
* @param dataset
* @return
*/
- private String getDatasetIdRef(Alignment dataset)
+ private String getDatasetIdRef(AlignmentI dataset)
{
if (dataset.getDataset() != null)
{
// make a new datasetId and record it
if (dataset2Ids == null)
{
- dataset2Ids = new IdentityHashMap<Alignment, String>();
+ dataset2Ids = new IdentityHashMap<AlignmentI, String>();
}
else
{
}
else
{
- frefedSequence.add(new Object[] { dsfor, jmap });
+ frefedSequence.add(newMappingRef(dsfor, jmap));
}
}
else
djs.setEnd(jmap.getMap().getToHighest());
djs.setVamsasId(uniqueSetSuffix + sqid);
jmap.setTo(djs);
+ incompleteSeqs.put(sqid, djs);
seqRefIds.put(sqid, djs);
}
*/
package jalview.gui;
+import jalview.analysis.Conservation;
import jalview.binding.Annotation;
import jalview.binding.AnnotationElement;
import jalview.binding.Features;
import jalview.datamodel.PDBEntry;
import jalview.schemes.ColourSchemeI;
import jalview.schemes.ColourSchemeProperty;
-import jalview.schemes.ResidueProperties;
import jalview.structure.StructureSelectionManager;
import jalview.util.MessageManager;
import jalview.util.jarInputStreamProvider;
if (groups[i].getConsThreshold() != 0)
{
- jalview.analysis.Conservation c = new jalview.analysis.Conservation(
- "All", ResidueProperties.propHash, 3,
+ Conservation c = new Conservation("All", 3,
sg.getSequences(null), 0, sg.getWidth() - 1);
c.calculate();
c.verdict(false, 25);
new Thread(new Runnable()
{
+ @Override
public void run()
{
frame.setVisible(true);
ok.setText(MessageManager.getString("action.ok"));
ok.addActionListener(new ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
okPressed();
cancel.setText(MessageManager.getString("action.cancel"));
cancel.addActionListener(new ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
cancelPressed();
@Override
public void mouseClicked(MouseEvent e)
{
- if (e.isPopupTrigger())
+ if (e.isPopupTrigger()) // for Windows
{
showUrlPopUp(this, finfo.toString(), e.getX(), e.getY());
}
@Override
public void mousePressed(MouseEvent e)
{
- // TODO Auto-generated method stub
-
+ if (e.isPopupTrigger()) // Mac
+ {
+ showUrlPopUp(this, finfo.toString(), e.getX(), e.getY());
+ }
}
@Override
public void mouseReleased(MouseEvent e)
{
- // TODO Auto-generated method stub
-
}
public void resetToDefault(boolean setDefaultParams)
@Override
public void mouseClicked(MouseEvent e)
{
- if (e.isPopupTrigger())
+ if (e.isPopupTrigger()) // for Windows
{
showUrlPopUp(this, finfo.toString(), e.getX(), e.getY());
}
@Override
public void mousePressed(MouseEvent e)
{
- // TODO Auto-generated method stub
-
+ if (e.isPopupTrigger()) // for Mac
+ {
+ showUrlPopUp(this, finfo.toString(), e.getX(), e.getY());
+ }
}
@Override
if (!adjusting)
{
valueField.setText(""
- + ((integ) ? ("" + slider.getValue())
- : ("" + slider.getValue() / 1000f)));
+ + ((integ) ? ("" + slider.getValue()) : ("" + slider
+ .getValue() / 1000f)));
checkIfModified();
}
final boolean hasHiddenRows = av.hasHiddenRows(), hasHiddenCols = av
.hasHiddenColumns();
boolean hiddenRow = false;
+ // get hidden row and hidden column map once at beginning.
+ // clone featureRenderer settings to avoid race conditions... if state is
+ // updated just need to refresh again
for (row = 0; row < sequencesHeight; row++)
{
+ if (resizeAgain)
+ {
+ break;
+ }
if ((int) (row * sampleRow) == lastrow)
{
// No need to recalculate the colours,
// Just copy from the row above
for (col = 0; col < width; col++)
{
+ if (resizeAgain)
+ {
+ break;
+ }
miniMe.setRGB(col, row, miniMe.getRGB(col, row - 1));
}
continue;
for (col = 0; col < width; col++)
{
+ if (resizeAgain)
+ {
+ break;
+ }
if ((int) (col * sampleCol) == lastcol
&& (int) (row * sampleRow) == lastrow)
{
renderer.updateFromAlignViewport(av);
for (col = 0; col < width; col++)
{
+ if (resizeAgain)
+ {
+ break;
+ }
lastcol = (int) (col * sampleCol);
{
mg.translate(col, sequencesHeight);
resizing = false;
- setBoxPosition();
-
if (resizeAgain)
{
resizeAgain = false;
updateOverviewImage();
}
+ else
+ {
+ lastMiniMe = miniMe;
+ }
+
+ setBoxPosition();
}
/**
repaint();
}
+ private BufferedImage lastMiniMe = null;
+
/**
* DOCUMENT ME!
*
@Override
public void paintComponent(Graphics g)
{
- if (resizing)
+ if (resizing || resizeAgain)
{
- g.setColor(Color.white);
+ if (lastMiniMe == null)
+ {
+ g.setColor(Color.white);
+ g.fillRect(0, 0, getWidth(), getHeight());
+ }
+ else
+ {
+ g.drawImage(lastMiniMe, 0, 0, getWidth(), getHeight(), this);
+ }
+ g.setColor(new Color(100, 100, 100, 25));
g.fillRect(0, 0, getWidth(), getHeight());
}
- else if (miniMe != null)
+ else if (lastMiniMe != null)
{
- g.drawImage(miniMe, 0, 0, this);
+ g.drawImage(lastMiniMe, 0, 0, this);
+ if (lastMiniMe != miniMe)
+ {
+ g.setColor(new Color(100, 100, 100, 25));
+ g.fillRect(0, 0, getWidth(), getHeight());
+ }
}
-
+ // TODO: render selected regions
g.setColor(Color.red);
g.drawRect(boxX, boxY, boxWidth, boxHeight);
g.drawRect(boxX + 1, boxY + 1, boxWidth - 2, boxHeight - 2);
-
}
}
package jalview.gui;
import jalview.datamodel.Alignment;
+import jalview.datamodel.AlignmentI;
import jalview.datamodel.AlignmentView;
import jalview.datamodel.ColumnSelection;
import jalview.datamodel.SeqCigar;
{
// create an entry for this score matrix for use in PCA
JCheckBoxMenuItem jm = new JCheckBoxMenuItem();
- jm.setText(MessageManager
- .getStringOrReturn("label.score_model", sm));
+ jm.setText(MessageManager.getStringOrReturn("label.score_model_",
+ sm));
jm.setSelected(pcaModel.getScore_matrix().equals(sm));
if ((ResidueProperties.scoreMatrices.get(sm).isDNA() && ResidueProperties.scoreMatrices
.get(sm).isProtein())
{
// AlignmentOrder origorder = new AlignmentOrder(alAndColsel[0]);
- Alignment al = new Alignment((SequenceI[]) alAndColsel[0]);
- Alignment dataset = (av != null && av.getAlignment() != null) ? av
+ AlignmentI al = new Alignment((SequenceI[]) alAndColsel[0]);
+ AlignmentI dataset = (av != null && av.getAlignment() != null) ? av
.getAlignment().getDataset() : null;
if (dataset != null)
{
import jalview.schemes.NucleotideColourScheme;
import jalview.schemes.PIDColourScheme;
import jalview.schemes.PurinePyrimidineColourScheme;
-import jalview.schemes.ResidueProperties;
import jalview.schemes.StrandColourScheme;
import jalview.schemes.TaylorColourScheme;
import jalview.schemes.TurnColourScheme;
*/
public class PopupMenu extends JPopupMenu
{
- private static final String ALL_ANNOTATIONS = "All";
-
JMenu groupMenu = new JMenu();
JMenuItem groupName = new JMenuItem();
if (sg != null && sg.getSize() > 0)
{
- groupName.setText(MessageManager.formatMessage("label.name_param",
- new Object[] { sg.getName() }));
groupName.setText(MessageManager
.getString("label.edit_name_and_description_current_group"));
continue;
}
final String label = urlLink.getLabel();
- if (seq != null && urlLink.isDynamic())
+
+ // collect id string too
+ String id = seq.getName();
+ String descr = seq.getDescription();
+ if (descr != null && descr.length() < 1)
{
+ descr = null;
+ }
+ if (seq != null && urlLink.usesSeqId()) // link is ID
+ {
// collect matching db-refs
DBRefEntry[] dbr = DBRefUtils.selectRefs(seq.getDBRefs(),
new String[] { urlLink.getTarget() });
- // collect id string too
- String id = seq.getName();
- String descr = seq.getDescription();
- if (descr != null && descr.length() < 1)
- {
- descr = null;
- }
+ // if there are any dbrefs which match up with the link
if (dbr != null)
{
for (int r = 0; r < dbr.length; r++)
id = null;
}
// create Bare ID link for this URL
- String[] urls = urlLink.makeUrls(dbr[r].getAccessionId(), true);
- if (urls != null)
- {
- for (int u = 0; u < urls.length; u += 2)
- {
- if (!linkset.contains(urls[u] + "|" + urls[u + 1]))
- {
- linkset.add(urls[u] + "|" + urls[u + 1]);
- addshowLink(linkMenu, label + "|" + urls[u], urls[u + 1]);
- }
- }
- }
+ createBareURLLink(urlLink, dbr[r].getAccessionId(), linkset,
+ linkMenu, label, true);
}
}
+
+ // Create urls from description but only for URL links which are regex
+ // links
+ if (descr != null && urlLink.getRegexReplace() != null)
+ {
+ // create link for this URL from description where regex matches
+ createBareURLLink(urlLink, descr, linkset, linkMenu, label, false);
+ }
+
+ }
+ else if (seq != null && !urlLink.usesSeqId()) // link is name
+ {
if (id != null)
{
// create Bare ID link for this URL
- String[] urls = urlLink.makeUrls(id, true);
- if (urls != null)
- {
- for (int u = 0; u < urls.length; u += 2)
- {
- if (!linkset.contains(urls[u] + "|" + urls[u + 1]))
- {
- linkset.add(urls[u] + "|" + urls[u + 1]);
- addshowLink(linkMenu, label, urls[u + 1]);
- }
- }
- }
+ createBareURLLink(urlLink, id, linkset, linkMenu, label, false);
}
// Create urls from description but only for URL links which are regex
// links
if (descr != null && urlLink.getRegexReplace() != null)
{
// create link for this URL from description where regex matches
- String[] urls = urlLink.makeUrls(descr, true);
- if (urls != null)
- {
- for (int u = 0; u < urls.length; u += 2)
- {
- if (!linkset.contains(urls[u] + "|" + urls[u + 1]))
- {
- linkset.add(urls[u] + "|" + urls[u + 1]);
- addshowLink(linkMenu, label, urls[u + 1]);
- }
- }
- }
+ createBareURLLink(urlLink, descr, linkset, linkMenu, label, false);
}
}
else
addshowLink(linkMenu, label, urlLink.getUrl_prefix());
}
}
+
}
if (sequence != null)
{
}
}
+ /*
+ * Create a bare URL Link
+ */
+ private void createBareURLLink(UrlLink urlLink, String id,
+ List<String> linkset, JMenu linkMenu, String label,
+ Boolean addSepToLabel)
+ {
+ String[] urls = urlLink.makeUrls(id, true);
+ if (urls != null)
+ {
+ for (int u = 0; u < urls.length; u += 2)
+ {
+ if (!linkset.contains(urls[u] + "|" + urls[u + 1]))
+ {
+ linkset.add(urls[u] + "|" + urls[u + 1]);
+ if (addSepToLabel)
+ {
+ addshowLink(linkMenu, label + "|" + urls[u], urls[u + 1]);
+ }
+ else
+ {
+ addshowLink(linkMenu, label, urls[u + 1]);
+ }
+ }
+ }
+ }
+ }
+
/**
* Add annotation types to 'Show annotations' and/or 'Hide annotations' menus.
* "All" is added first, followed by a separator. Then add any annotation
showMenu.removeAll();
hideMenu.removeAll();
- final List<String> all = Arrays.asList(ALL_ANNOTATIONS);
+ final List<String> all = Arrays.asList(new String[] { MessageManager
+ .getString("label.all") });
addAnnotationTypeToShowHide(showMenu, forSequences, "", all, true, true);
addAnnotationTypeToShowHide(hideMenu, forSequences, "", all, true,
false);
urlLink = new GroupUrlLink(link);
} catch (Exception foo)
{
- Cache.log.error("Exception for GroupURLLink '" + link
- + "'", foo);
+ Cache.log.error("Exception for GroupURLLink '" + link + "'", foo);
continue;
}
;
*/
private void jbInit() throws Exception
{
- groupMenu.setText(MessageManager.getString("label.group"));
groupMenu.setText(MessageManager.getString("label.selection"));
groupName.setText(MessageManager.getString("label.name"));
groupName.addActionListener(new java.awt.event.ActionListener()
if (conservationMenuItem.isSelected())
{
// JBPNote: Conservation name shouldn't be i18n translated
- Conservation c = new Conservation("Group",
- ResidueProperties.propHash, 3, sg.getSequences(ap.av
- .getHiddenRepSequences()), sg.getStartRes(),
+ Conservation c = new Conservation("Group", 3, sg.getSequences(ap.av
+ .getHiddenRepSequences()), sg.getStartRes(),
sg.getEndRes() + 1);
c.calculate();
*/
package jalview.gui;
+import static jalview.util.UrlConstants.EMBLEBI_STRING;
+import static jalview.util.UrlConstants.OLD_EMBLEBI_STRING;
+import static jalview.util.UrlConstants.SEQUENCE_ID;
+import static jalview.util.UrlConstants.SEQUENCE_NAME;
+import static jalview.util.UrlConstants.SRS_STRING;
+
import jalview.analysis.AnnotationSorter.SequenceAnnotationOrder;
import jalview.bin.Cache;
import jalview.gui.Help.HelpId;
public static List<String> groupURLLinks;
static
{
- String string = Cache
- .getDefault(
- "SEQUENCE_LINKS",
- "EMBL-EBI Search|http://www.ebi.ac.uk/ebisearch/search.ebi?db=allebi&query=$SEQUENCE_ID$");
+ String string = Cache.getDefault("SEQUENCE_LINKS", EMBLEBI_STRING);
sequenceURLLinks = new Vector<String>();
try
String name = st.nextToken();
String url = st.nextToken();
// check for '|' within a regex
- int rxstart = url.indexOf("$SEQUENCE_ID$");
+ int rxstart = url.indexOf("$" + SEQUENCE_ID + "$");
+ if (rxstart == -1)
+ {
+ rxstart = url.indexOf("$" + SEQUENCE_NAME + "$");
+ }
while (rxstart == -1 && url.indexOf("/=$") == -1)
{
url = url + "|" + st.nextToken();
}
{
// upgrade old SRS link
- int srsPos = sequenceURLLinks
- .indexOf("SRS|http://srs.ebi.ac.uk/srsbin/cgi-bin/wgetz?-newId+(([uniprot-all:$SEQUENCE_ID$]))+-view+SwissEntry");
+ int srsPos = sequenceURLLinks.indexOf(SRS_STRING);
if (srsPos > -1)
{
- sequenceURLLinks
- .setElementAt(
- "EMBL-EBI Search|http://www.ebi.ac.uk/ebisearch/search.ebi?db=allebi&query=$SEQUENCE_ID$",
- srsPos);
+ sequenceURLLinks.setElementAt(EMBLEBI_STRING, srsPos);
+ }
+ // upgrade old EMBL-EBI link
+ int emblPos = sequenceURLLinks.indexOf(OLD_EMBLEBI_STRING);
+ if (emblPos > -1)
+ {
+ sequenceURLLinks.setElementAt(EMBLEBI_STRING, emblPos);
}
}
/*
* Save Output settings
*/
- Cache.applicationProperties.setProperty("EPS_RENDERING",
- ((OptionsParam) epsRendering.getSelectedItem()).getCode());
+ Cache.applicationProperties.setProperty("EPS_RENDERING",
+ ((OptionsParam) epsRendering.getSelectedItem()).getCode());
/*
* Save Connections settings
}
@Override
- public int hashCode(){
+ public int hashCode()
+ {
return name.hashCode() + code.hashCode();
}
}
progress = null;
label.setText(MessageManager
- .getString("label.enter_redundancy_thereshold"));
+ .getString("label.enter_redundancy_threshold"));
slider.setVisible(true);
applyButton.setEnabled(true);
valueField.setVisible(true);
import jalview.datamodel.ColumnSelection;
import jalview.datamodel.SequenceGroup;
import jalview.datamodel.SequenceI;
+import jalview.renderer.ScaleRenderer;
+import jalview.renderer.ScaleRenderer.ScaleMark;
import jalview.util.MessageManager;
+import jalview.util.Platform;
import java.awt.Color;
import java.awt.FontMetrics;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
+import javax.swing.SwingUtilities;
import javax.swing.ToolTipManager;
/**
min = res;
max = res;
- if (evt.isPopupTrigger())
+ if (evt.isPopupTrigger()) // Mac: mousePressed
{
rightMouseButtonPressed(evt, res);
}
+ else if (SwingUtilities.isRightMouseButton(evt) && !Platform.isAMac())
+ {
+ /*
+ * defer right-mouse click handling to mouse up on Windows
+ * (where isPopupTrigger() will answer true)
+ * but accept Cmd-click on Mac which passes isRightMouseButton
+ */
+ return;
+ }
else
{
leftMouseButtonPressed(evt, res);
*/
protected void leftMouseButtonPressed(MouseEvent evt, final int res)
{
- if (!evt.isControlDown() && !evt.isShiftDown())
+ /*
+ * Ctrl-click/Cmd-click adds to the selection
+ * Shift-click extends the selection
+ */
+ // TODO Problem: right-click on Windows not reported until mouseReleased?!?
+ if (!Platform.isControlDown(evt) && !evt.isShiftDown())
{
av.getColumnSelection().clear();
}
if (!stretchingGroup)
{
- ap.paintAlignment(false);
-
+ if (evt.isPopupTrigger()) // Windows: mouseReleased
+ {
+ rightMouseButtonPressed(evt, res);
+ }
+ else
+ {
+ ap.paintAlignment(false);
+ }
return;
}
int widthx = 1 + endx - startx;
FontMetrics fm = gg.getFontMetrics(av.getFont());
- int y = avCharHeight, yOf = fm.getDescent();
+ int y = avCharHeight;
+ int yOf = fm.getDescent();
y -= yOf;
if (av.hasHiddenColumns())
{
-1 + res * avCharWidth - avCharHeight / 4,
-1 + res * avCharWidth + avCharHeight / 4,
-1 + res * avCharWidth }, new int[] { y, y, y + 2 * yOf }, 3);
-
}
}
}
gg.setColor(Color.black);
int maxX = 0;
- List<Object[]> marks = jalview.renderer.ScaleRenderer.calculateMarks(
- av, startx, endx);
+ List<ScaleMark> marks = new ScaleRenderer().calculateMarks(av, startx,
+ endx);
- for (Object[] mark : marks)
+ for (ScaleMark mark : marks)
{
- boolean major = Boolean.valueOf((Boolean) mark[0]);
- int mpos = ((Integer) mark[1]).intValue(); // (i - startx - 1)
- String mstring = (String) mark[2];
+ boolean major = mark.major;
+ int mpos = mark.column; // (i - startx - 1)
+ String mstring = mark.text;
if (mstring != null)
{
if (mpos * avCharWidth > maxX)
(mpos * avCharWidth) + (avCharWidth / 2), y + (yOf * 2));
}
}
- if (av.hasHiddenColumns())
- {
- if (reveal != null && reveal[0] > startx && reveal[0] < endx)
- {
- gg.drawString(MessageManager.getString("label.reveal_columns"),
- reveal[0] * avCharWidth, 0);
- }
- }
-
}
}
import jalview.datamodel.SearchResults;
import jalview.datamodel.SequenceGroup;
import jalview.datamodel.SequenceI;
+import jalview.renderer.ScaleRenderer;
+import jalview.renderer.ScaleRenderer.ScaleMark;
import java.awt.BasicStroke;
import java.awt.BorderLayout;
private void drawNorthScale(Graphics g, int startx, int endx, int ypos)
{
updateViewport();
- for (Object[] mark : jalview.renderer.ScaleRenderer.calculateMarks(av,
- startx, endx))
+ for (ScaleMark mark : new ScaleRenderer().calculateMarks(av, startx,
+ endx))
{
- int mpos = ((Integer) mark[1]).intValue(); // (i - startx - 1)
+ int mpos = mark.column; // (i - startx - 1)
if (mpos < 0)
{
continue;
}
- String mstring = (String) mark[2];
+ String mstring = mark.text;
- if (Boolean.valueOf((Boolean) mark[0]))
+ if (mark.major)
{
if (mstring != null)
{
import jalview.util.Comparison;
import jalview.util.MappingUtils;
import jalview.util.MessageManager;
+import jalview.util.Platform;
import jalview.viewmodel.AlignmentViewport;
import java.awt.BorderLayout;
mouseDragging = false;
mouseWheelPressed = false;
+ if (evt.isPopupTrigger()) // Windows: mouseReleased
+ {
+ showPopupMenu(evt);
+ evt.consume();
+ return;
+ }
+
if (!editingSeqs)
{
doMouseReleasedDefineMode(evt);
return;
}
- if (evt.isShiftDown() || evt.isAltDown() || evt.isControlDown())
+ boolean isControlDown = Platform.isControlDown(evt);
+ if (evt.isShiftDown() || isControlDown)
{
- if (evt.isAltDown() || evt.isControlDown())
+ editingSeqs = true;
+ if (isControlDown)
{
groupEditing = true;
}
- editingSeqs = true;
}
else
{
String lastTooltip;
/**
+ * set when the current UI interaction has resulted in a change that requires
+ * overview shading to be recalculated. this could be changed to something
+ * more expressive that indicates what actually has changed, so selective
+ * redraws can be applied
+ */
+ private boolean needOverviewUpdate = false; // TODO: refactor to avcontroller
+
+ /**
+ * set if av.getSelectionGroup() refers to a group that is defined on the
+ * alignment view, rather than a transient selection
+ */
+ // private boolean editingDefinedGroup = false; // TODO: refactor to
+ // avcontroller or viewModel
+
+ /**
* Set status message in alignment panel
*
* @param sequence
* Sequence number (if known), and sequence name.
*/
String seqno = seq == -1 ? "" : " " + (seq + 1);
- text.append("Sequence" + seqno + " ID: " + sequence.getName());
+ text.append("Sequence").append(seqno).append(" ID: ")
+ .append(sequence.getName());
String residue = null;
/*
*/
public void doMousePressedDefineMode(MouseEvent evt)
{
- int res = findRes(evt);
- int seq = findSeq(evt);
+ final int res = findRes(evt);
+ final int seq = findSeq(evt);
oldSeq = seq;
+ needOverviewUpdate = false;
startWrapBlock = wrappedBlock;
}
av.setSelectionGroup(stretchGroup);
-
}
- if (evt.isPopupTrigger())
+ if (evt.isPopupTrigger()) // Mac: mousePressed
{
- List<SequenceFeature> allFeatures = ap.getFeatureRenderer()
- .findFeaturesAtRes(sequence.getDatasetSequence(),
- sequence.findPosition(res));
- List<String> links = new ArrayList<String>();
- for (SequenceFeature sf : allFeatures)
- {
- if (sf.links != null)
- {
- for (String link : sf.links)
- {
- links.add(link);
- }
- }
- }
+ showPopupMenu(evt);
+ return;
+ }
- PopupMenu pop = new PopupMenu(ap, null, links);
- pop.show(this, evt.getX(), evt.getY());
+ /*
+ * defer right-mouse click handling to mouseReleased on Windows
+ * (where isPopupTrigger() will answer true)
+ * NB isRightMouseButton is also true for Cmd-click on Mac
+ */
+ if (SwingUtilities.isRightMouseButton(evt) && !Platform.isAMac())
+ {
return;
}
sg.setEndRes(res);
sg.addSequence(sequence, false);
av.setSelectionGroup(sg);
-
stretchGroup = sg;
if (av.getConservationSelected())
}
/**
+ * Build and show a pop-up menu at the right-click mouse position
+ *
+ * @param evt
+ * @param res
+ * @param sequence
+ */
+ void showPopupMenu(MouseEvent evt)
+ {
+ final int res = findRes(evt);
+ final int seq = findSeq(evt);
+ SequenceI sequence = av.getAlignment().getSequenceAt(seq);
+ List<SequenceFeature> allFeatures = ap.getFeatureRenderer()
+ .findFeaturesAtRes(sequence.getDatasetSequence(),
+ sequence.findPosition(res));
+ List<String> links = new ArrayList<String>();
+ for (SequenceFeature sf : allFeatures)
+ {
+ if (sf.links != null)
+ {
+ for (String link : sf.links)
+ {
+ links.add(link);
+ }
+ }
+ }
+
+ PopupMenu pop = new PopupMenu(ap, null, links);
+ pop.show(this, evt.getX(), evt.getY());
+ }
+
+ /**
* DOCUMENT ME!
*
* @param evt
{
return;
}
-
- stretchGroup.recalcConservation(); // always do this - annotation has own
- // state
+ // always do this - annotation has own state
+ // but defer colourscheme update until hidden sequences are passed in
+ boolean vischange = stretchGroup.recalcConservation(true);
+ needOverviewUpdate |= vischange && av.isSelectionDefinedGroup();
if (stretchGroup.cs != null)
{
stretchGroup.cs.alignmentChanged(stretchGroup,
}
}
PaintRefresher.Refresh(this, av.getSequenceSetId());
- ap.paintAlignment(true);
-
+ ap.paintAlignment(needOverviewUpdate);
+ needOverviewUpdate = false;
changeEndRes = false;
changeStartRes = false;
stretchGroup = null;
if (res > (stretchGroup.getStartRes() - 1))
{
stretchGroup.setEndRes(res);
+ needOverviewUpdate |= av.isSelectionDefinedGroup();
}
}
else if (changeStartRes)
if (res < (stretchGroup.getEndRes() + 1))
{
stretchGroup.setStartRes(res);
+ needOverviewUpdate |= av.isSelectionDefinedGroup();
}
}
if (stretchGroup.getSequences(null).contains(nextSeq))
{
stretchGroup.deleteSequence(seq, false);
+ needOverviewUpdate |= av.isSelectionDefinedGroup();
}
else
{
}
stretchGroup.addSequence(nextSeq, false);
+ needOverviewUpdate |= av.isSelectionDefinedGroup();
}
}
{
if (av.getAlignment() == null)
{
- Cache.log.warn("alignviewport av SeqSetId="
- + av.getSequenceSetId() + " ViewId=" + av.getViewId()
+ Cache.log.warn("alignviewport av SeqSetId=" + av.getSequenceSetId()
+ + " ViewId=" + av.getViewId()
+ " 's alignment is NULL! returning immediately.");
return;
}
import java.awt.event.KeyEvent;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collections;
import java.util.Iterator;
import java.util.List;
private static Thread initingThread = null;
- int debounceTrap = 0;
-
public JTextArea getTextArea()
{
return textArea;
if (sfetch == null
|| dasRegistry != Cache.getDasSourceRegistry()
|| lastDasSourceRegistry != (Cache.getDasSourceRegistry()
- .getDasRegistryURL() + Cache
- .getDasSourceRegistry().getLocalSourceString())
- .hashCode())
+ .getDasRegistryURL() + Cache.getDasSourceRegistry()
+ .getLocalSourceString()).hashCode())
{
_initingFetcher = true;
initingThread = Thread.currentThread();
private IProgressIndicator progressIndicator;
+ private volatile boolean _isConstructing = false;
+
+ private List<AlignFrame> newAlframes = null;
+
public SequenceFetcher(IProgressIndicator guiIndic)
{
+ this(guiIndic, null, null);
+ }
+
+ public SequenceFetcher(IProgressIndicator guiIndic,
+ final String selectedDb, final String queryString)
+ {
+ this._isConstructing = true;
this.progressIndicator = guiIndic;
final SequenceFetcher us = this;
// launch initialiser thread
{
if (getSequenceFetcherSingleton(progressIndicator) != null)
{
- us.initGui(progressIndicator);
+ us.initGui(progressIndicator, selectedDb, queryString);
+ us._isConstructing = false;
}
else
{
sf.start();
}
+ /**
+ * blocking call which creates a new sequence fetcher panel, configures it and
+ * presses the OK button with the given database and query.
+ *
+ * @param database
+ * @param query
+ */
+ public static List<AlignFrame> fetchAndShow(String database, String query)
+ {
+ final SequenceFetcher sf = new SequenceFetcher(Desktop.instance,
+ database, query);
+ while (sf._isConstructing)
+ {
+ try
+ {
+ Thread.sleep(50);
+ } catch (Exception q)
+ {
+ return Collections.emptyList();
+ }
+ }
+ sf.newAlframes = new ArrayList<AlignFrame>();
+ sf.run();
+ return sf.newAlframes;
+ }
+
private class DatabaseAuthority extends DefaultMutableTreeNode
{
};
/**
+ * initialise the database and query for this fetcher panel
+ *
+ * @param selectedDb
+ * - string that should correspond to a sequence fetcher
+ * @param queryString
+ * - string that will be entered in the query dialog
+ * @return true if UI was configured with valid database and query string
+ */
+ protected boolean setInitialQuery(String selectedDb, String queryString)
+ {
+ if (selectedDb == null || selectedDb.trim().length() == 0)
+ {
+ return false;
+ }
+ try
+ {
+ List<DbSourceProxy> sp = sfetch.getSourceProxy(selectedDb);
+ for (DbSourceProxy sourcep : sp)
+ {
+ if (sourcep.getTier() == 0)
+ {
+ database.selection = Arrays
+ .asList(new DbSourceProxy[] { sourcep });
+ break;
+ }
+ }
+ if (database.selection == null || database.selection.size() == 0)
+ {
+ System.err.println("Ignoring fetch parameter db='" + selectedDb
+ + "'");
+ return false;
+ }
+ textArea.setText(queryString);
+ } catch (Exception q)
+ {
+ System.err.println("Ignoring fetch parameter db='" + selectedDb
+ + "' and query='" + queryString + "'");
+ return false;
+ }
+ return true;
+ }
+
+ /**
* called by thread spawned by constructor
*
* @param guiWindow
+ * @param queryString
+ * @param selectedDb
*/
- private void initGui(IProgressIndicator guiWindow)
+ private void initGui(IProgressIndicator guiWindow, String selectedDb,
+ String queryString)
{
this.guiWindow = guiWindow;
if (guiWindow instanceof AlignFrame)
try
{
jbInit();
+ /*
+ * configure the UI with any query parameters we were called with
+ */
+ if (!setInitialQuery(selectedDb, queryString))
+ {
+ /*
+ * none provided, so show the database chooser
+ */
+ database.waitForInput();
+ }
} catch (Exception ex)
{
ex.printStackTrace();
jPanel1.add(example);
jPanel1.add(clear);
jPanel1.add(close);
- jPanel3.add(jPanel2, java.awt.BorderLayout.CENTER);
jPanel2.setLayout(borderLayout3);
databaseButt = /*database.getDatabaseSelectorButton();
final JButton viewdbs =*/new JButton(
@Override
public void actionPerformed(ActionEvent e)
{
- debounceTrap++;
String currentSelection = database.getSelectedItem();
if (currentSelection == null)
{
showPanel();
- if (currentSelection.equalsIgnoreCase("pdb")
- && (database.action == KeyEvent.VK_ENTER || ((debounceTrap % 2) == 0)))
+ if ("pdb".equalsIgnoreCase(currentSelection))
{
pdbSourceAction();
}
- else if (currentSelection.equalsIgnoreCase("uniprot")
- && (database.action == KeyEvent.VK_ENTER || ((debounceTrap % 2) == 0)))
+ else if ("uniprot".equalsIgnoreCase(currentSelection))
{
uniprotSourceAction();
}
this.add(jPanel3, java.awt.BorderLayout.CENTER);
this.add(jPanel2, java.awt.BorderLayout.NORTH);
jScrollPane1.getViewport().add(textArea);
-
- /*
- * open the database tree
- */
- database.waitForInput();
}
private void pdbSourceAction()
new UniprotFTSPanel(this);
frame.dispose();
}
+
private void otherSourceAction()
{
try
} catch (Exception e)
{
Cache.log.info(
- "Error retrieving " + accession
- + " from " + proxy.getDbName(), e);
- } finally
- {
- return success;
+ "Error retrieving " + accession + " from "
+ + proxy.getDbName(), e);
}
+ return success;
}
/**
for (String q : queries)
{
- DBRefEntry[] found = null;
DBRefEntry dbr = new DBRefEntry();
dbr.setSource(proxy.getDbSource());
dbr.setVersion(null);
{
if (rs[r] != null)
{
- found = DBRefUtils.searchRefs(rs[r].getDBRefs(), accId);
- if (found != null && found.length > 0)
+ List<DBRefEntry> found = DBRefUtils.searchRefs(rs[r].getDBRefs(),
+ accId);
+ if (!found.isEmpty())
{
rfound = true;
break;
{
af.hideFeatureColumns(SequenceOntologyI.EXON, false);
}
-
+ if (newAlframes != null)
+ {
+ newAlframes.add(af);
+ }
Desktop.addInternalFrame(af, title, AlignFrame.DEFAULT_WIDTH,
AlignFrame.DEFAULT_HEIGHT);
try
{
- af.setMaximum(Cache.getDefault("SHOW_FULLSCREEN",
- false));
+ af.setMaximum(Cache.getDefault("SHOW_FULLSCREEN", false));
} catch (Exception ex)
{
}
@Override
public Color getResidueBoxColour(SequenceI seq, int i)
{
+ // rate limiting step when rendering overview for lots of groups
allGroups = av.getAlignment().findAllGroups(seq);
if (inCurrentSequenceGroup(i))
pid.cs = cs;
}
- PIDSlider.setTitle(MessageManager
- .formatMessage("label.percentage_identity_thereshold",
+ PIDSlider
+ .setTitle(MessageManager.formatMessage(
+ "label.percentage_identity_threshold",
new String[] { source }));
if (ap.av.getAlignment().getGroups() != null)
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.beans.PropertyVetoException;
+import java.util.Arrays;
+import java.util.List;
import java.util.Map.Entry;
import javax.swing.AbstractAction;
private static final int WINDOWS_INSETS_HEIGHT = 50; // tbc
private static final int MAC_INSETS_HEIGHT = 50;
+
private static final int DESKTOP_DECORATORS_HEIGHT = 65;
+
private static final long serialVersionUID = 1L;
public SplitFrame(GAlignFrame top, GAlignFrame bottom)
final AlignmentI bottomAlignment = bottomViewport.getAlignment();
boolean topAnnotations = topViewport.isShowAnnotation();
boolean bottomAnnotations = bottomViewport.isShowAnnotation();
+ // TODO need number of visible sequences here, not #sequences - how?
int topCount = topAlignment.getHeight();
int bottomCount = bottomAlignment.getHeight();
int topCharHeight = topViewport.getViewStyle().getCharHeight();
+ (bottomAnnotations ? bottomViewport.calcPanelHeight() : 0);
double ratio = ((double) topHeight) / (topHeight + bottomHeight);
+ /*
+ * limit to 0.2 <= ratio <= 0.8 to avoid concealing all sequences
+ */
+ ratio = Math.min(ratio, 0.8d);
+ ratio = Math.max(ratio, 0.2d);
setRelativeDividerLocation(ratio);
}
actioned = true;
e.consume();
}
+ break;
default:
}
return actioned;
}
/**
+ * return the AlignFrames held by this container
+ *
+ * @return { Top alignFrame (Usually CDS), Bottom AlignFrame (Usually
+ * Protein)}
+ */
+ public List<AlignFrame> getAlignFrames()
+ {
+ return Arrays.asList(new AlignFrame[] { (AlignFrame) getTopFrame(),
+ (AlignFrame) getBottomFrame() });
+ }
+
+ /**
* Replace Cmd-F Find action with our version. This is necessary because the
* 'default' Finder searches in the first AlignFrame it finds. We need it to
* search in the half of the SplitFrame that has the mouse.
import jalview.fts.core.FTSRestResponse;
import jalview.fts.service.pdb.PDBFTSRestClient;
import jalview.jbgui.GStructureChooser;
+import jalview.structure.StructureMapping;
import jalview.structure.StructureSelectionManager;
import jalview.util.MessageManager;
import jalview.ws.DBRefFetcher;
public class StructureChooser extends GStructureChooser implements
IProgressIndicator
{
- private boolean structuresDiscovered = false;
-
private SequenceI selectedSequence;
private SequenceI[] selectedSequences;
private boolean isValidPBDEntry;
+ private boolean cachedPDBExists;
+
public StructureChooser(SequenceI[] selectedSeqs, SequenceI selectedSeq,
AlignmentPanel ap)
{
progressBar = new ProgressBar(this.statusPanel, this.statusBar);
}
+ // ensure a filter option is in force for search
+ populateFilterComboBox(true, cachedPDBExists);
Thread discoverPDBStructuresThread = new Thread(new Runnable()
{
@Override
.getString("status.searching_for_pdb_structures"),
startTime);
fetchStructuresMetaData();
- populateFilterComboBox();
+ // revise filter options if no results were found
+ populateFilterComboBox(isStructuresDiscovered(), cachedPDBExists);
updateProgressIndicator(null, startTime);
mainFrame.setVisible(true);
updateCurrentView();
pdbRequest.setAllowEmptySeq(false);
pdbRequest.setResponseSize(500);
pdbRequest.setFieldToSearchBy("(");
+ FilterOption selectedFilterOpt = ((FilterOption) cmb_filterOption
+ .getSelectedItem());
+ pdbRequest.setFieldToSortBy(selectedFilterOpt.getValue(),
+ !chk_invertFilter.isSelected());
pdbRequest.setWantedFields(wantedFields);
pdbRequest.setSearchTerm(buildQuery(seq) + ")");
pdbRequest.setAssociatedSequence(seq);
{
getResultTable().setModel(
FTSRestResponse.getTableModel(lastPdbRequest,
- discoveredStructuresSet));
- structuresDiscovered = true;
+ discoveredStructuresSet));
noOfStructuresFound = discoveredStructuresSet.size();
mainFrame.setTitle(MessageManager.formatMessage(
"label.structure_chooser_no_of_structures",
}
}
}
-
+ cachedPDBExists = !entries.isEmpty();
PDBEntryTableModel tableModelx = new PDBEntryTableModel(entries);
tbl_local_pdb.setModel(tableModelx);
}
if (isValidSeqName(entry.getId()))
{
queryBuilder.append("pdb_id:")
- .append(entry.getId().toLowerCase())
- .append(" OR ");
+ .append(entry.getId().toLowerCase()).append(" OR ");
isPDBRefsFound = true;
// seqRefs.add(entry.getId());
}
if (dbRef.getSource().equalsIgnoreCase(DBRefSource.UNIPROT))
{
queryBuilder.append("uniprot_accession:")
- .append(getDBRefId(dbRef))
- .append(" OR ");
+ .append(getDBRefId(dbRef)).append(" OR ");
queryBuilder.append("uniprot_id:").append(getDBRefId(dbRef))
.append(" OR ");
isUniProtRefsFound = true;
{
queryBuilder.append("pdb_id:")
- .append(getDBRefId(dbRef).toLowerCase())
- .append(" OR ");
+ .append(getDBRefId(dbRef).toLowerCase()).append(" OR ");
isPDBRefsFound = true;
}
else
.replaceAll("[^\\dA-Za-z|_]", "").replaceAll("\\s+", "+");
}
-
/**
* Ensures sequence ref names are not less than 3 characters and does not
* contain a database name
reorderedStructuresSet.addAll(filteredResponse);
reorderedStructuresSet.addAll(discoveredStructuresSet);
getResultTable().setModel(
- FTSRestResponse.getTableModel(
- lastPdbRequest, reorderedStructuresSet));
+ FTSRestResponse.getTableModel(lastPdbRequest,
+ reorderedStructuresSet));
FTSRestResponse.configureTableColumn(getResultTable(),
wantedFields, tempUserPrefs);
* Populates the filter combo-box options dynamically depending on discovered
* structures
*/
- @Override
- protected void populateFilterComboBox()
+ protected void populateFilterComboBox(boolean haveData,
+ boolean cachedPDBExists)
{
- if (isStructuresDiscovered())
+ /*
+ * temporarily suspend the change listener behaviour
+ */
+ cmb_filterOption.removeItemListener(this);
+
+ cmb_filterOption.removeAllItems();
+ if (haveData)
{
cmb_filterOption.addItem(new FilterOption("Best Quality",
"overall_quality", VIEWS_FILTER));
VIEWS_ENTER_ID));
cmb_filterOption.addItem(new FilterOption("From File", "-",
VIEWS_FROM_FILE));
- cmb_filterOption.addItem(new FilterOption("Cached PDB Entries", "-",
- VIEWS_LOCAL_PDB));
+ FilterOption cachedOption = new FilterOption("Cached PDB Entries", "-",
+ VIEWS_LOCAL_PDB);
+ cmb_filterOption.addItem(cachedOption);
+
+ if (/*!haveData &&*/cachedPDBExists)
+ {
+ cmb_filterOption.setSelectedItem(cachedOption);
+ }
+
+ cmb_filterOption.addItemListener(this);
}
/**
* Updates the displayed view based on the selected filter option
*/
- @Override
protected void updateCurrentView()
{
FilterOption selectedFilterOpt = ((FilterOption) cmb_filterOption
{
final long progressSessionId = System.currentTimeMillis();
final StructureSelectionManager ssm = ap.getStructureSelectionManager();
+ final int preferredHeight = pnl_filter.getHeight();
ssm.setProgressIndicator(this);
ssm.setProgressSessionId(progressSessionId);
new Thread(new Runnable()
@Override
public void run()
{
- FilterOption selectedFilterOpt = ((FilterOption) cmb_filterOption
- .getSelectedItem());
- String currentView = selectedFilterOpt.getView();
- if (currentView == VIEWS_FILTER)
- {
+ FilterOption selectedFilterOpt = ((FilterOption) cmb_filterOption
+ .getSelectedItem());
+ String currentView = selectedFilterOpt.getView();
+ if (currentView == VIEWS_FILTER)
+ {
int pdbIdColIndex = getResultTable().getColumn("PDB Id")
.getModelIndex();
int refSeqColIndex = getResultTable().getColumn("Ref Sequence")
- .getModelIndex();
+ .getModelIndex();
int[] selectedRows = getResultTable().getSelectedRows();
- PDBEntry[] pdbEntriesToView = new PDBEntry[selectedRows.length];
- int count = 0;
- ArrayList<SequenceI> selectedSeqsToView = new ArrayList<SequenceI>();
- for (int row : selectedRows)
- {
+ PDBEntry[] pdbEntriesToView = new PDBEntry[selectedRows.length];
+ int count = 0;
+ ArrayList<SequenceI> selectedSeqsToView = new ArrayList<SequenceI>();
+ for (int row : selectedRows)
+ {
String pdbIdStr = getResultTable().getValueAt(row,
- pdbIdColIndex)
- .toString();
+ pdbIdColIndex).toString();
SequenceI selectedSeq = (SequenceI) getResultTable()
- .getValueAt(row,
- refSeqColIndex);
- selectedSeqsToView.add(selectedSeq);
+ .getValueAt(row, refSeqColIndex);
+ selectedSeqsToView.add(selectedSeq);
PDBEntry pdbEntry = selectedSeq.getPDBEntry(pdbIdStr);
if (pdbEntry == null)
{
pdbEntry = getFindEntry(pdbIdStr,
selectedSeq.getAllPDBEntries());
}
- if (pdbEntry == null)
- {
- pdbEntry = new PDBEntry();
- pdbEntry.setId(pdbIdStr);
- pdbEntry.setType(PDBEntry.Type.PDB);
- selectedSeq.getDatasetSequence().addPDBId(pdbEntry);
- }
- pdbEntriesToView[count++] = pdbEntry;
- }
- SequenceI[] selectedSeqs = selectedSeqsToView
- .toArray(new SequenceI[selectedSeqsToView.size()]);
+ if (pdbEntry == null)
+ {
+ pdbEntry = new PDBEntry();
+ pdbEntry.setId(pdbIdStr);
+ pdbEntry.setType(PDBEntry.Type.PDB);
+ selectedSeq.getDatasetSequence().addPDBId(pdbEntry);
+ }
+ pdbEntriesToView[count++] = pdbEntry;
+ }
+ SequenceI[] selectedSeqs = selectedSeqsToView
+ .toArray(new SequenceI[selectedSeqsToView.size()]);
launchStructureViewer(ssm, pdbEntriesToView, ap, selectedSeqs);
- }
- else if (currentView == VIEWS_LOCAL_PDB)
- {
- int[] selectedRows = tbl_local_pdb.getSelectedRows();
- PDBEntry[] pdbEntriesToView = new PDBEntry[selectedRows.length];
- int count = 0;
+ }
+ else if (currentView == VIEWS_LOCAL_PDB)
+ {
+ int[] selectedRows = tbl_local_pdb.getSelectedRows();
+ PDBEntry[] pdbEntriesToView = new PDBEntry[selectedRows.length];
+ int count = 0;
int pdbIdColIndex = tbl_local_pdb.getColumn("PDB Id")
.getModelIndex();
- int refSeqColIndex = tbl_local_pdb.getColumn("Ref Sequence")
- .getModelIndex();
- ArrayList<SequenceI> selectedSeqsToView = new ArrayList<SequenceI>();
- for (int row : selectedRows)
- {
- PDBEntry pdbEntry = (PDBEntry) tbl_local_pdb.getValueAt(row,
- pdbIdColIndex);
- pdbEntriesToView[count++] = pdbEntry;
- SequenceI selectedSeq = (SequenceI) tbl_local_pdb.getValueAt(row,
- refSeqColIndex);
- selectedSeqsToView.add(selectedSeq);
- }
- SequenceI[] selectedSeqs = selectedSeqsToView
- .toArray(new SequenceI[selectedSeqsToView.size()]);
+ int refSeqColIndex = tbl_local_pdb.getColumn("Ref Sequence")
+ .getModelIndex();
+ ArrayList<SequenceI> selectedSeqsToView = new ArrayList<SequenceI>();
+ for (int row : selectedRows)
+ {
+ PDBEntry pdbEntry = (PDBEntry) tbl_local_pdb.getValueAt(row,
+ pdbIdColIndex);
+ pdbEntriesToView[count++] = pdbEntry;
+ SequenceI selectedSeq = (SequenceI) tbl_local_pdb.getValueAt(
+ row, refSeqColIndex);
+ selectedSeqsToView.add(selectedSeq);
+ }
+ SequenceI[] selectedSeqs = selectedSeqsToView
+ .toArray(new SequenceI[selectedSeqsToView.size()]);
launchStructureViewer(ssm, pdbEntriesToView, ap, selectedSeqs);
- }
- else if (currentView == VIEWS_ENTER_ID)
- {
- SequenceI userSelectedSeq = ((AssociateSeqOptions) idInputAssSeqPanel
- .getCmb_assSeq().getSelectedItem()).getSequence();
- if (userSelectedSeq != null)
- {
- selectedSequence = userSelectedSeq;
- }
+ }
+ else if (currentView == VIEWS_ENTER_ID)
+ {
+ SequenceI userSelectedSeq = ((AssociateSeqOptions) idInputAssSeqPanel
+ .getCmb_assSeq().getSelectedItem()).getSequence();
+ if (userSelectedSeq != null)
+ {
+ selectedSequence = userSelectedSeq;
+ }
- String pdbIdStr = txt_search.getText();
- PDBEntry pdbEntry = selectedSequence.getPDBEntry(pdbIdStr);
- if (pdbEntry == null)
- {
- pdbEntry = new PDBEntry();
+ String pdbIdStr = txt_search.getText();
+ PDBEntry pdbEntry = selectedSequence.getPDBEntry(pdbIdStr);
+ if (pdbEntry == null)
+ {
+ pdbEntry = new PDBEntry();
if (pdbIdStr.split(":").length > 1)
{
pdbEntry.setId(pdbIdStr.split(":")[0]);
{
pdbEntry.setId(pdbIdStr);
}
- pdbEntry.setType(PDBEntry.Type.PDB);
- selectedSequence.getDatasetSequence().addPDBId(pdbEntry);
- }
+ pdbEntry.setType(PDBEntry.Type.PDB);
+ selectedSequence.getDatasetSequence().addPDBId(pdbEntry);
+ }
- PDBEntry[] pdbEntriesToView = new PDBEntry[] { pdbEntry };
+ PDBEntry[] pdbEntriesToView = new PDBEntry[] { pdbEntry };
launchStructureViewer(ssm, pdbEntriesToView, ap,
new SequenceI[] { selectedSequence });
- }
- else if (currentView == VIEWS_FROM_FILE)
- {
- SequenceI userSelectedSeq = ((AssociateSeqOptions) fileChooserAssSeqPanel
- .getCmb_assSeq().getSelectedItem()).getSequence();
- if (userSelectedSeq != null)
- {
- selectedSequence = userSelectedSeq;
- }
- PDBEntry fileEntry = new AssociatePdbFileWithSeq()
- .associatePdbWithSeq(selectedPdbFileName,
- jalview.io.AppletFormatAdapter.FILE,
- selectedSequence, true, Desktop.instance);
+ }
+ else if (currentView == VIEWS_FROM_FILE)
+ {
+ SequenceI userSelectedSeq = ((AssociateSeqOptions) fileChooserAssSeqPanel
+ .getCmb_assSeq().getSelectedItem()).getSequence();
+ if (userSelectedSeq != null)
+ {
+ selectedSequence = userSelectedSeq;
+ }
+ PDBEntry fileEntry = new AssociatePdbFileWithSeq()
+ .associatePdbWithSeq(selectedPdbFileName,
+ jalview.io.AppletFormatAdapter.FILE,
+ selectedSequence, true, Desktop.instance);
launchStructureViewer(ssm, new PDBEntry[] { fileEntry }, ap,
new SequenceI[] { selectedSequence });
- }
- closeAction();
+ }
+ closeAction(preferredHeight);
}
}).start();
}
if (SiftsSettings.isMapWithSifts())
{
- ArrayList<SequenceI> seqsWithoutSourceDBRef = new ArrayList<SequenceI>();
+ List<SequenceI> seqsWithoutSourceDBRef = new ArrayList<SequenceI>();
+ int p = 0;
+ // TODO: skip PDBEntry:Sequence pairs where PDBEntry doesn't look like a
+ // real PDB ID. For moment, we can also safely do this if there is already
+ // a known mapping between the PDBEntry and the sequence.
for (SequenceI seq : sequences)
{
- if (seq.getSourceDBRef() == null && seq.getDBRefs() == null)
+ PDBEntry pdbe = pdbEntriesToView[p++];
+ if (pdbe != null && pdbe.getFile() != null)
{
- seqsWithoutSourceDBRef.add(seq);
- continue;
+ StructureMapping[] smm = ssm.getMapping(pdbe.getFile());
+ if (smm != null && smm.length > 0)
+ {
+ for (StructureMapping sm : smm)
+ {
+ if (sm.getSequence() == seq)
+ {
+ continue;
+ }
+ }
}
+ }
+ if (seq.getPrimaryDBRefs().size() == 0)
+ {
+ seqsWithoutSourceDBRef.add(seq);
+ continue;
+ }
}
if (!seqsWithoutSourceDBRef.isEmpty())
{
{
seqWithoutSrcDBRef[x++] = fSeq;
}
- new DBRefFetcher(seqWithoutSrcDBRef).fetchDBRefs(true);
+ DBRefFetcher dbRefFetcher = new DBRefFetcher(seqWithoutSrcDBRef);
+ dbRefFetcher.fetchDBRefs(true);
}
}
if (pdbEntriesToView.length > 1)
public boolean isStructuresDiscovered()
{
- return structuresDiscovered;
- }
-
- public void setStructuresDiscovered(boolean structuresDiscovered)
- {
- this.structuresDiscovered = structuresDiscovered;
+ return discoveredStructuresSet != null
+ && !discoveredStructuresSet.isEmpty();
}
public Collection<FTSData> getDiscoveredStructuresSet()
pdbRequest.setResponseSize(1);
pdbRequest.setFieldToSearchBy("(pdb_id:");
pdbRequest.setWantedFields(wantedFields);
- pdbRequest
-.setSearchTerm(searchTerm + ")");
+ pdbRequest.setSearchTerm(searchTerm + ")");
pdbRequest.setAssociatedSequence(selectedSequence);
pdbRestCleint = PDBFTSRestClient.getInstance();
wantedFields.add(pdbRestCleint.getPrimaryKeyColumn());
protected JalviewStructureDisplayI viewStructures(ViewerType viewerType,
PDBEntry[] pdbs, SequenceI[][] seqsForPdbs, AlignmentPanel ap)
{
+ PDBEntry[] pdbsForFile = getUniquePdbFiles(pdbs);
JalviewStructureDisplayI sview = null;
if (viewerType.equals(ViewerType.JMOL))
{
- sview = new AppJmol(ap, pdbs, ap.av.collateForPDB(pdbs));
+ sview = new AppJmol(ap, pdbsForFile, ap.av.collateForPDB(pdbsForFile));
}
else if (viewerType.equals(ViewerType.CHIMERA))
{
- sview = new ChimeraViewFrame(pdbs, ap.av.collateForPDB(pdbs), ap);
+ sview = new ChimeraViewFrame(pdbsForFile,
+ ap.av.collateForPDB(pdbsForFile), ap);
}
else
{
return sview;
}
+ /**
+ * Convert the array of PDBEntry into an array with no filename repeated
+ *
+ * @param pdbs
+ * @return
+ */
+ static PDBEntry[] getUniquePdbFiles(PDBEntry[] pdbs)
+ {
+ if (pdbs == null)
+ {
+ return null;
+ }
+ List<PDBEntry> uniques = new ArrayList<PDBEntry>();
+ List<String> filesSeen = new ArrayList<String>();
+ for (PDBEntry entry : pdbs)
+ {
+ String file = entry.getFile();
+ if (file == null)
+ {
+ uniques.add(entry);
+ }
+ else if (!filesSeen.contains(file))
+ {
+ uniques.add(entry);
+ filesSeen.add(file);
+ }
+ }
+ return uniques.toArray(new PDBEntry[uniques.size()]);
+ }
+
protected JalviewStructureDisplayI viewStructures(ViewerType viewerType,
PDBEntry pdb, SequenceI[] seqsForPdb, AlignmentPanel ap)
{
new JLabel(
"<html>"
+ MessageManager
- .getString("label.select_dark_light_set_thereshold")
+ .getString("label.select_dark_light_set_threshold")
+ "</html>"), BorderLayout.NORTH);
panel.add(col1);
panel.add(slider);
ap,
bigpanel,
MessageManager
- .getString("label.adjunst_foreground_text_colour_thereshold"),
+ .getString("label.adjunst_foreground_text_colour_threshold"),
JOptionPane.OK_CANCEL_OPTION,
JOptionPane.QUESTION_MESSAGE, null, null, null);
import jalview.datamodel.SequenceNode;
import jalview.schemes.ColourSchemeI;
import jalview.schemes.ColourSchemeProperty;
-import jalview.schemes.ResidueProperties;
import jalview.schemes.UserColourScheme;
import jalview.structure.SelectionSource;
import jalview.util.Format;
import javax.swing.JColorChooser;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
+import javax.swing.SwingUtilities;
import javax.swing.ToolTipManager;
/**
tree.findHeight(tree.getTopNode());
// Now have to calculate longest name based on the leaves
- Vector leaves = tree.findLeaves(tree.getTopNode(), new Vector());
+ Vector<SequenceNode> leaves = tree.findLeaves(tree.getTopNode());
boolean has_placeholders = false;
longestName = "";
for (int i = 0; i < leaves.size(); i++)
{
- SequenceNode lf = (SequenceNode) leaves.elementAt(i);
+ SequenceNode lf = leaves.elementAt(i);
if (lf.isPlaceholder())
{
}
/**
- * DOCUMENT ME!
+ * Empty method to satisfy the MouseListener interface
*
* @param e
- * DOCUMENT ME!
*/
@Override
public void mouseReleased(MouseEvent e)
{
+ /*
+ * isPopupTrigger is set on mouseReleased on Windows
+ */
+ if (e.isPopupTrigger())
+ {
+ chooseSubtreeColour();
+ e.consume(); // prevent mouseClicked happening
+ }
}
/**
- * DOCUMENT ME!
+ * Empty method to satisfy the MouseListener interface
*
* @param e
- * DOCUMENT ME!
*/
@Override
public void mouseEntered(MouseEvent e)
}
/**
- * DOCUMENT ME!
+ * Empty method to satisfy the MouseListener interface
*
* @param e
- * DOCUMENT ME!
*/
@Override
public void mouseExited(MouseEvent e)
}
/**
- * DOCUMENT ME!
+ * Handles a mouse click on a tree node (clicks elsewhere are handled in
+ * mousePressed). Click selects the sub-tree, double-click swaps leaf nodes
+ * order, right-click opens a dialogue to choose colour for the sub-tree.
*
* @param e
- * DOCUMENT ME!
*/
@Override
public void mouseClicked(MouseEvent evt)
{
- if (highlightNode != null)
+ if (highlightNode == null)
{
- if (evt.isPopupTrigger())
- {
- Color col = JColorChooser.showDialog(this,
- MessageManager.getString("label.select_subtree_colour"),
- highlightNode.color);
- if (col != null)
- {
- setColor(highlightNode, col);
- }
- }
- else if (evt.getClickCount() > 1)
+ return;
+ }
+
+ if (evt.getClickCount() > 1)
+ {
+ tree.swapNodes(highlightNode);
+ tree.reCount(tree.getTopNode());
+ tree.findHeight(tree.getTopNode());
+ }
+ else
+ {
+ Vector<SequenceNode> leaves = tree.findLeaves(highlightNode);
+
+ for (int i = 0; i < leaves.size(); i++)
{
- tree.swapNodes(highlightNode);
- tree.reCount(tree.getTopNode());
- tree.findHeight(tree.getTopNode());
+ SequenceI seq = (SequenceI) leaves.elementAt(i).element();
+ treeSelectionChanged(seq);
}
- else
- {
- Vector leaves = new Vector();
- tree.findLeaves(highlightNode, leaves);
+ av.sendSelection();
+ }
- for (int i = 0; i < leaves.size(); i++)
- {
- SequenceI seq = (SequenceI) ((SequenceNode) leaves.elementAt(i))
- .element();
- treeSelectionChanged(seq);
- }
- av.sendSelection();
- }
+ PaintRefresher.Refresh(tp, av.getSequenceSetId());
+ repaint();
+ }
- PaintRefresher.Refresh(tp, av.getSequenceSetId());
+ /**
+ * Offer the user the option to choose a colour for the highlighted node and
+ * its children; this colour is also applied to the corresponding sequence ids
+ * in the alignment
+ */
+ void chooseSubtreeColour()
+ {
+ Color col = JColorChooser.showDialog(this,
+ MessageManager.getString("label.select_subtree_colour"),
+ highlightNode.color);
+ if (col != null)
+ {
+ setColor(highlightNode, col);
+ PaintRefresher.Refresh(tp, ap.av.getSequenceSetId());
repaint();
}
}
}
/**
- * DOCUMENT ME!
+ * Handles a mouse press on a sequence name or the tree background canvas
+ * (click on a node is handled in mouseClicked). The action is to create
+ * groups by partitioning the tree at the mouse position. Colours for the
+ * groups (and sequence names) are generated randomly.
*
* @param e
- * DOCUMENT ME!
*/
@Override
public void mousePressed(MouseEvent e)
{
av.setCurrentTree(tree);
+ /*
+ * isPopupTrigger is set for mousePressed (Mac)
+ * or mouseReleased (Windows)
+ */
+ if (e.isPopupTrigger())
+ {
+ if (highlightNode != null)
+ {
+ chooseSubtreeColour();
+ }
+ return;
+ }
+
+ /*
+ * defer right-click handling on Windows to
+ * mouseClicked; note isRightMouseButton
+ * also matches Cmd-click on Mac which should do
+ * nothing here
+ */
+ if (SwingUtilities.isRightMouseButton(e))
+ {
+ return;
+ }
+
int x = e.getX();
int y = e.getY();
{
Color col = new Color((int) (Math.random() * 255),
(int) (Math.random() * 255), (int) (Math.random() * 255));
- setColor((SequenceNode) tree.getGroups().elementAt(i), col.brighter());
+ setColor(tree.getGroups().elementAt(i), col.brighter());
- Vector l = tree.findLeaves(
- (SequenceNode) tree.getGroups().elementAt(i), new Vector());
+ Vector<SequenceNode> l = tree.findLeaves(tree.getGroups()
+ .elementAt(i));
- Vector sequences = new Vector();
+ Vector<SequenceI> sequences = new Vector<SequenceI>();
for (int j = 0; j < l.size(); j++)
{
- SequenceI s1 = (SequenceI) ((SequenceNode) l.elementAt(j))
- .element();
+ SequenceI s1 = (SequenceI) l.elementAt(j).element();
if (!sequences.contains(s1))
{
if (aps[a].av.getGlobalColourScheme() != null
&& aps[a].av.getGlobalColourScheme().conservationApplied())
{
- Conservation c = new Conservation("Group",
- ResidueProperties.propHash, 3, sg.getSequences(null),
- sg.getStartRes(), sg.getEndRes());
-
+ Conservation c = new Conservation("Group", 3,
+ sg.getSequences(null), sg.getStartRes(), sg.getEndRes());
c.calculate();
c.verdict(false, aps[a].av.getConsPercGaps());
sg.cs.setConservation(c);
.getCodingComplement();
if (codingComplement != null)
{
- if (codingComplement != null)
+ SequenceGroup mappedGroup = MappingUtils.mapSequenceGroup(sg, av,
+ codingComplement);
+ if (mappedGroup.getSequences().size() > 0)
{
- SequenceGroup mappedGroup = MappingUtils.mapSequenceGroup(sg,
- av, codingComplement);
- if (mappedGroup.getSequences().size() > 0)
+ codingComplement.getAlignment().addGroup(mappedGroup);
+ for (SequenceI seq : mappedGroup.getSequences())
{
- codingComplement.getAlignment().addGroup(mappedGroup);
- for (SequenceI seq : mappedGroup.getSequences())
- {
- codingComplement.setSequenceColour(seq, col.brighter());
- }
+ codingComplement.setSequenceColour(seq, col.brighter());
}
}
}
{
((AlignViewport) codingComplement).getAlignPanel()
.updateAnnotation();
-
}
-
}
-
}
/**
{
// AlignmentOrder origorder = new AlignmentOrder(alAndColsel[0]);
- Alignment al = new Alignment((SequenceI[]) alAndColsel[0]);
- Alignment dataset = (av != null && av.getAlignment() != null) ? av
+ AlignmentI al = new Alignment((SequenceI[]) alAndColsel[0]);
+ AlignmentI dataset = (av != null && av.getAlignment() != null) ? av
.getAlignment().getDataset() : null;
if (dataset != null)
{
Thread udthread = new Thread(new Runnable()
{
+ @Override
public void run()
{
Cache.log.info("Jalview updating to the Vamsas Session.");
final VamsasApplication client = this;
vclient.addDocumentUpdateHandler(new PropertyChangeListener()
{
+ @Override
public void propertyChange(PropertyChangeEvent evt)
{
Cache.log.debug("Dealing with document update event.");
uk.ac.vamsas.client.Events.DOCUMENT_REQUESTTOCLOSE,
new PropertyChangeListener()
{
+ @Override
public void propertyChange(PropertyChangeEvent evt)
{
if (client.promptUser)
{
String last = null;
+ @Override
public void handleMessage(Message message)
{
if (vobj2jv == null)
selecter = new SelectionListener()
{
+ @Override
public void selection(SequenceGroup seqsel,
ColumnSelection colsel, SelectionSource source)
{
{
// gather selected columns outwith the sequence positions
// too
- for (Object obj : colsel.getSelected())
+ for (Integer ival : colsel.getSelected())
{
- int ival = ((Integer) obj).intValue();
Pos p = new Pos();
- p.setI(ival + 1);
+ p.setI(ival.intValue() + 1);
range.addPos(p);
}
}
/**
* Constructor which parses the data from a file of some specified type.
*
- * @param inFile
- * Filename to read from.
+ * @param dataObject
+ * Filename, URL or Pasted String to read from.
* @param type
- * What type of file to read from (File, URL)
+ * What type of file to read from (File, URL, Pasted String)
*/
- public AlignFile(String inFile, String type) throws IOException
+ public AlignFile(String dataObject, String type) throws IOException
{
- this(true, inFile, type);
+ this(true, dataObject, type);
}
/**
*
* @param parseImmediately
* if false, need to call 'doParse()' to begin parsing data
- * @param inFile
- * Filename to read from.
+ * @param dataObject
+ * Filename, URL or Pasted String to read from.
* @param type
* What type of file to read from (File, URL)
* @throws IOException
*/
- public AlignFile(boolean parseImmediately, String inFile, String type)
+ public AlignFile(boolean parseImmediately, String dataObject, String type)
throws IOException
{
- super(inFile, type);
+ super(dataObject, type);
initData();
if (parseImmediately)
{
import jalview.datamodel.SequenceI;
import jalview.schemes.ColourSchemeI;
import jalview.schemes.ColourSchemeProperty;
-import jalview.schemes.ResidueProperties;
import jalview.schemes.UserColourScheme;
import jalview.structure.StructureSelectionManager;
else if (key.equalsIgnoreCase("consThreshold"))
{
sg.cs.setConservationInc(Integer.parseInt(value));
- Conservation c = new Conservation("Group",
- ResidueProperties.propHash, 3, sg.getSequences(null),
- sg.getStartRes(), sg.getEndRes() + 1);
+ Conservation c = new Conservation("Group", 3,
+ sg.getSequences(null), sg.getStartRes(),
+ sg.getEndRes() + 1);
c.calculate();
c.verdict(false, 25); // TODO: refer to conservation percent threshold
import jalview.datamodel.AlignmentAnnotation;
import jalview.datamodel.AlignmentI;
import jalview.datamodel.AlignmentView;
-import jalview.structure.StructureViewSettings;
+import jalview.datamodel.PDBEntry.Type;
+import jalview.ext.jmol.JmolParser;
+import jalview.structure.StructureImportSettings;
import jalview.util.MessageManager;
import java.io.File;
{
// TODO obtain config value from preference settings.
// Set value to 'true' to test PDB processing with Jmol: JAL-1213
- boolean isParseWithJMOL = !StructureViewSettings
- .getCurrentDefaultFormat().equalsIgnoreCase("PDB");
+ boolean isParseWithJMOL = StructureImportSettings
+ .getDefaultPDBFileParser().equalsIgnoreCase(
+ StructureImportSettings.StructureParser.JMOL_PARSER
+ .toString());
if (isParseWithJMOL)
{
- StructureViewSettings.addSettings(annotFromStructure,
+ StructureImportSettings.addSettings(annotFromStructure,
localSecondaryStruct, serviceSecondaryStruct);
- alignFile = new jalview.ext.jmol.JmolParser(annotFromStructure,
- localSecondaryStruct, serviceSecondaryStruct, inFile,
- type);
+ alignFile = new jalview.ext.jmol.JmolParser(inFile, type);
}
else
{
- StructureViewSettings.addSettings(annotFromStructure,
+ StructureImportSettings.addSettings(annotFromStructure,
localSecondaryStruct, serviceSecondaryStruct);
- StructureViewSettings.setShowSeqFeatures(true);
+ StructureImportSettings.setShowSeqFeatures(true);
alignFile = new MCview.PDBfile(annotFromStructure,
localSecondaryStruct, serviceSecondaryStruct, inFile,
type);
}
+ ((StructureFile) alignFile).setDbRefType(format);
}
- else if (format.equals("mmCIF"))
+ else if (format.equalsIgnoreCase("mmCIF"))
{
- StructureViewSettings.addSettings(annotFromStructure,
+ StructureImportSettings.addSettings(annotFromStructure,
localSecondaryStruct, serviceSecondaryStruct);
- alignFile = new jalview.ext.jmol.JmolParser(annotFromStructure,
- localSecondaryStruct, serviceSecondaryStruct, inFile, type);
+ alignFile = new jalview.ext.jmol.JmolParser(inFile, type);
+ ((StructureFile) alignFile).setDbRefType(format);
}
else if (format.equals("STH"))
{
boolean isParseWithJMOL = false;
if (isParseWithJMOL)
{
- StructureViewSettings.addSettings(annotFromStructure,
+ StructureImportSettings.addSettings(annotFromStructure,
localSecondaryStruct, serviceSecondaryStruct);
- alignFile = new jalview.ext.jmol.JmolParser(annotFromStructure,
- localSecondaryStruct, serviceSecondaryStruct, source);
+ alignFile = new JmolParser(source);
}
else
{
- StructureViewSettings.setShowSeqFeatures(true);
+ StructureImportSettings.setShowSeqFeatures(true);
alignFile = new MCview.PDBfile(annotFromStructure,
localSecondaryStruct, serviceSecondaryStruct, source);
}
+ ((StructureFile) alignFile).setDbRefType(Type.PDB);
}
- else if (format.equals("mmCIF"))
+ else if (format.equalsIgnoreCase("mmCIF"))
{
- StructureViewSettings.addSettings(annotFromStructure,
+ StructureImportSettings.addSettings(annotFromStructure,
localSecondaryStruct, serviceSecondaryStruct);
- alignFile = new jalview.ext.jmol.JmolParser(annotFromStructure,
- localSecondaryStruct, serviceSecondaryStruct, source);
+ alignFile = new JmolParser(source);
+ ((StructureFile) alignFile).setDbRefType(Type.MMCIF);
}
else if (format.equals("STH"))
{
}
}
- public void exportJalviewAlignmentAsBioJsHtmlFile()
+ public void exportJalviewAlignmentAsBioJsHtmlFile(String outputFile)
{
- String outputFile = null;
+ // String outputFile = null;
try
{
- outputFile = getOutputFile();
+ if (outputFile == null)
+ {
+ outputFile = getOutputFile();
+ }
AlignExportSettingI exportSettings = new AlignExportSettingI()
{
@Override
new OOMWarning("Creating Image for " + outputFile, err);
} catch (Exception e)
{
+ if (pIndicator != null && !headless)
+ {
pIndicator.setProgressBar(MessageManager.formatMessage(
"info.error_creating_file", "HTML"), pSessionId);
+ }
e.printStackTrace();
}
}
addProperties(al);
for (int i = 0; i < annotations.size(); i++)
{
- AlignmentAnnotation aa = annotations
- .elementAt(i);
+ AlignmentAnnotation aa = annotations.elementAt(i);
aa.setPadGaps(true, al.getGapCharacter());
al.addAnnotation(aa);
}
* @return true if features were added
*/
public boolean parse(AlignmentI align,
- Map<String, FeatureColourI> colours,
- boolean removeHTML)
+ Map<String, FeatureColourI> colours, boolean removeHTML)
{
return parse(align, colours, removeHTML, false);
}
* @return true if features were added
*/
public boolean parse(AlignmentI align,
- Map<String, FeatureColourI> colours,
- boolean removeHTML, boolean relaxedIdmatching)
+ Map<String, FeatureColourI> colours, boolean removeHTML,
+ boolean relaxedIdmatching)
{
Map<String, String> gffProps = new HashMap<String, String>();
/*
{
for (SequenceFeature sequenceFeature : features)
{
- isnonpos = sequenceFeature.begin == 0 && sequenceFeature.end == 0;
+ isnonpos = sequenceFeature.begin == 0
+ && sequenceFeature.end == 0;
if ((!nonpos && isnonpos)
|| (!isnonpos && visOnly && !visible
.containsKey(sequenceFeature.type)))
return this.formatSequences(format, alignment, suffix);
}
- public AlignmentI readFile(String inFile, String type, String format)
- throws java.io.IOException
- {
- AlignmentI al = super.readFile(inFile, type, format);
- return al;
- }
-
- public AlignmentI readFromFile(FileParse source, String format)
- throws java.io.IOException
- {
- AlignmentI al = super.readFromFile(source, format);
- return al;
- }
-
/**
* validate format is valid for IO in Application. This is basically the
* AppletFormatAdapter.isValidFormat call with additional checks for
private boolean headless;
-
public HtmlSvgOutput(File file, AlignmentPanel ap)
{
this.av = ap.av;
try
{
setProgressMessage(null);
- setProgressMessage(MessageManager
-.formatMessage(
+ setProgressMessage(MessageManager.formatMessage(
"status.exporting_alignment_as_x_file", "HTML"));
AlignmentDimension aDimension = ap.getAlignmentDimension();
SVGGraphics2D g1 = new SVGGraphics2D(aDimension.getWidth(),
g2.setRenderingHint(SVGHints.KEY_DRAW_STRING_TYPE,
SVGHints.VALUE_DRAW_STRING_TYPE_VECTOR);
}
+ if (av.getWrapAlignment())
+ {
+ printWrapped(aDimension.getWidth(), aDimension.getHeight(), 0,
+ g1, g2);
+ }
+ else
+ {
printUnwrapped(aDimension.getWidth(), aDimension.getHeight(), 0,
g1, g2);
+ }
String titleSvgData = g1.getSVGDocument();
String alignSvgData = g2.getSVGDocument();
exportData.getStartEndPostions(),
av.getColumnSelection());
}
- String htmlData = getHtml(titleSvgData, alignSvgData, jsonData);
+ String htmlData = getHtml(titleSvgData, alignSvgData, jsonData,
+ av.getWrapAlignment());
FileOutputStream out = new FileOutputStream(fileX);
out.write(htmlData.getBytes());
out.flush();
return Printable.PAGE_EXISTS;
}
+ public int printWrapped(int pwidth, int pheight, int pi, Graphics... pg)
+ throws PrinterException
+ {
+ return ap.printWrappedAlignment(pg[1], pwidth, pheight, pi);
+ }
+
private String getHtml(String titleSvg, String alignmentSvg,
- String jsonData)
+ String jsonData, boolean wrapped)
{
StringBuilder htmlSvg = new StringBuilder();
htmlSvg.append("<html>\n");
+ ".facebox_hide { z-index:-100; }\n"
+ ".facebox_overlayBG { background-color: #000; z-index: 99; }");
}
-
htmlSvg.append("</style>");
+ if (!wrapped)
+ {
htmlSvg.append("<div class=\"main-container\" \n>");
htmlSvg.append("<div class=\"titlex\">\n");
htmlSvg.append("<div class=\"sub-category-container\"> \n");
+ "subCatContainer.scrollTop($(this).scrollTop());\n});\n");
htmlSvg.append("</script>\n");
+ }
+ else
+ {
+ htmlSvg.append("<div>\n")
+ .append(alignmentSvg).append("</div>");
+ htmlSvg.append("<script language=\"JavaScript\" type=\"text/javascript\" src=\"http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js\"></script>\n"
+ + "<script language=\"JavaScript\" type=\"text/javascript\" src=\"http://ajax.googleapis.com/ajax/libs/jqueryui/1.11.2/jquery-ui.min.js\"></script>\n");
+
+ }
// javascript for launching file in Jalview
}
int lessThan = data.indexOf("<");
if ((lessThan > -1)) // possible Markup Language data i.e HTML,
- // RNAML, XML
+ // RNAML, XML
{
String upper = data.toUpperCase();
if (upper.substring(lessThan).startsWith("<HTML"))
}
/**
- * Returns true if the data has at least 6 tab-delimited fields _and_
- * fields 4 and 5 are integer (start/end)
+ * Returns true if the data has at least 6 tab-delimited fields _and_ fields 4
+ * and 5 are integer (start/end)
+ *
* @param data
* @return
*/
return false;
}
String[] columns = data.split("\t");
- if (columns.length < 6) {
+ if (columns.length < 6)
+ {
return false;
}
for (int col = 3; col < 5; col++)
{
- try {
+ try
+ {
Integer.parseInt(columns[col]);
- } catch (NumberFormatException e) {
+ } catch (NumberFormatException e)
+ {
return false;
}
}
@Override
public void configureForView(AlignmentViewPanel avpanel)
{
+ if (avpanel == null)
+ {
+ return;
+ }
super.configureForView(avpanel);
AlignViewportI viewport = avpanel.getAlignViewport();
AlignmentI alignment = viewport.getAlignment();
import jalview.datamodel.Sequence;
import jalview.datamodel.SequenceI;
+import jalview.util.Comparison;
import jalview.util.Format;
import java.io.IOException;
+import java.util.ArrayList;
import java.util.Hashtable;
+import java.util.List;
import java.util.StringTokenizer;
-import java.util.Vector;
/**
* DOCUMENT ME!
}
/**
- * DOCUMENT ME!
+ * Read and parse MSF sequence data
*/
@Override
public void parse() throws IOException
{
- int i = 0;
boolean seqFlag = false;
- String key = new String();
- Vector headers = new Vector();
- Hashtable seqhash = new Hashtable();
- String line;
+ List<String> headers = new ArrayList<String>();
+ Hashtable<String, StringBuilder> seqhash = new Hashtable<String, StringBuilder>();
try
{
+ String line;
while ((line = nextLine()) != null)
{
StringTokenizer str = new StringTokenizer(line);
+ String key = null;
while (str.hasMoreTokens())
{
String inStr = str.nextToken();
if (inStr.indexOf("Name:") != -1)
{
key = str.nextToken();
- headers.addElement(key);
+ headers.add(key);
}
- // if line has // set SeqFlag to 1 so we know sequences are coming
+ // if line has // set SeqFlag so we know sequences are coming
if (inStr.indexOf("//") != -1)
{
seqFlag = true;
}
// Process lines as sequence lines if seqFlag is set
- if ((inStr.indexOf("//") == -1) && (seqFlag == true))
+ if ((inStr.indexOf("//") == -1) && seqFlag)
{
- // seqeunce id is the first field
+ // sequence id is the first field
key = inStr;
- StringBuffer tempseq;
+ StringBuilder tempseq;
// Get sequence from hash if it exists
if (seqhash.containsKey(key))
{
- tempseq = (StringBuffer) seqhash.get(key);
+ tempseq = seqhash.get(key);
}
else
{
- tempseq = new StringBuffer();
+ tempseq = new StringBuilder(64);
seqhash.put(key, tempseq);
}
while (str.hasMoreTokens())
{
// append the word to the sequence
- tempseq.append(str.nextToken());
+ String sequenceBlock = str.nextToken();
+ tempseq.append(sequenceBlock);
}
}
}
this.noSeqs = headers.size();
// Add sequences to the hash
- for (i = 0; i < headers.size(); i++)
+ for (int i = 0; i < headers.size(); i++)
{
- if (seqhash.get(headers.elementAt(i)) != null)
+ if (seqhash.get(headers.get(i)) != null)
{
- String head = headers.elementAt(i).toString();
+ String head = headers.get(i);
String seq = seqhash.get(head).toString();
if (maxLength < head.length())
maxLength = head.length();
}
- // Replace ~ with a sensible gap character
- seq = seq.replace('~', '-');
+ /*
+ * replace ~ (leading/trailing positions) with the gap character;
+ * use '.' as this is the internal gap character required by MSF
+ */
+ seq = seq.replace('~', '.');
Sequence newSeq = parseId(head);
else
{
System.err.println("MSFFile Parser: Can't find sequence for "
- + headers.elementAt(i));
+ + headers.get(i));
}
}
}
*
* @return DOCUMENT ME!
*/
- public String print(SequenceI[] seqs)
+ public String print(SequenceI[] sqs)
{
- boolean is_NA = jalview.util.Comparison.isNucleotide(seqs);
+ boolean is_NA = Comparison.isNucleotide(sqs);
- SequenceI[] s = new SequenceI[seqs.length];
+ SequenceI[] s = new SequenceI[sqs.length];
- StringBuffer out = new StringBuffer("!!" + (is_NA ? "NA" : "AA")
- + "_MULTIPLE_ALIGNMENT 1.0");
+ StringBuilder out = new StringBuilder(256);
+ out.append("!!").append(is_NA ? "NA" : "AA")
+ .append("_MULTIPLE_ALIGNMENT 1.0");
// TODO: JBPNote : Jalview doesn't remember NA or AA yet.
out.append(newline);
out.append(newline);
int maxid = 0;
int i = 0;
- while ((i < seqs.length) && (seqs[i] != null))
+ while ((i < sqs.length) && (sqs[i] != null))
{
- // Replace all internal gaps with . and external spaces with ~
- s[i] = new Sequence(seqs[i].getName(), seqs[i].getSequenceAsString()
- .replace('-', '.'), seqs[i].getStart(), seqs[i].getEnd());
+ /*
+ * modify to MSF format: uses '.' for internal gaps,
+ * and '~' for leading or trailing gaps
+ */
+ String seqString = sqs[i].getSequenceAsString().replace('-', '.');
- StringBuffer sb = new StringBuffer();
- sb.append(s[i].getSequence());
+ StringBuilder sb = new StringBuilder(seqString);
for (int ii = 0; ii < sb.length(); ii++)
{
break;
}
}
+ s[i] = new Sequence(sqs[i].getName(), sb.toString(),
+ sqs[i].getStart(), sqs[i].getEnd());
- s[i].setSequence(sb.toString());
-
- if (s[i].getSequence().length > max)
+ if (sb.length() > max)
{
- max = s[i].getSequence().length;
+ max = sb.length();
}
i++;
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
package jalview.io;
import jalview.api.FeatureColourI;
public class PDBFeatureSettings extends FeatureSettingsAdapter
{
+ // TODO find one central place to define feature names
+ private static final String FEATURE_INSERTION = "INSERTION";
- public static final String FEATURE_INSERTION = "INSERTION";
-
- public static final String FEATURE_RES_NUM = "RESNUM";
+ private static final String FEATURE_RES_NUM = "RESNUM";
@Override
public boolean isFeatureDisplayed(String type)
return 0;
}
}
-
}
if (spces + 1 < line.length())
{
- tempseq.append(line.substring(spces + 1));
+ tempseq.append(line.substring(spces + 1).trim());
}
}
{
if (seqhash.get(headers.get(i)) != null)
{
- if (maxLength < seqhash.get(headers.get(i)).toString()
- .length())
+ if (maxLength < seqhash.get(headers.get(i)).toString().length())
{
maxLength = seqhash.get(headers.get(i)).toString().length();
}
*/
package jalview.io;
-import jalview.analysis.SecStrConsensus.SimpleBP;
+import jalview.analysis.Rna;
import jalview.datamodel.AlignmentAnnotation;
import jalview.datamodel.Annotation;
import jalview.datamodel.Sequence;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
+import java.util.List;
import com.stevesoft.pat.Regex;
*
* @see jalview.io.AlignFile#parse()
*/
+ @Override
public void parse() throws IOException
{
if (System.getProperty("java.version").indexOf("1.6") > -1
result = RNAFactory.loadSecStrRNAML(getReader());
- ArrayList<ArrayList> allarray = new ArrayList();
- ArrayList<ArrayList<SimpleBP>> BP = new ArrayList();
- ArrayList strucinarray = new ArrayList();
- SequenceI[] seqs = new SequenceI[result.size()];
+ // ArrayList<ArrayList> allarray = new ArrayList();
+ // ArrayList<ArrayList<SimpleBP>> BP = new ArrayList();
+ // ArrayList strucinarray = new ArrayList();
+ SequenceI[] sqs = new SequenceI[result.size()];
for (int i = 0; i < result.size(); i++)
{
id += "." + i;
}
}
- seqs[i] = new Sequence(id, seq, begin, end);
+ sqs[i] = new Sequence(id, seq, begin, end);
- seqs[i].setEnd(seqs[i].findPosition(seqs[i].getLength()));
+ sqs[i].setEnd(sqs[i].findPosition(sqs[i].getLength()));
String[] annot = new String[rna.length()];
Annotation[] ann = new Annotation[rna.length()];
}
for (int k = 0; k < rna.length(); k++)
{
- ann[k] = new Annotation(annot[k], "",
- jalview.schemes.ResidueProperties.getRNASecStrucState(
- annot[k]).charAt(0), 0f);
+ ann[k] = new Annotation(annot[k], "", Rna.getRNASecStrucState(
+ annot[k]).charAt(0), 0f);
}
AlignmentAnnotation align = new AlignmentAnnotation(
+ current.getID()
: "", ann);
- seqs[i].addAlignmentAnnotation(align);
- seqs[i].setRNA(result.get(i));
+ sqs[i].addAlignmentAnnotation(align);
+ sqs[i].setRNA(result.get(i));
- allarray.add(strucinarray);
+ // allarray.add(strucinarray);
annotations.addElement(align);
- BP.add(align.bps);
+ // BP.add(align.bps);
}
- setSeqs(seqs);
+ setSeqs(sqs);
}
public static String print(SequenceI[] s)
return "not yet implemented";
}
+ @Override
public String print()
{
System.out.print("print :");
return print(getSeqsAsArray());
}
- public ArrayList getRNA()
+ public List<RNA> getRNA()
{
return result;
}
}
else
{
- if (tmpString.indexOf("<") > -1
- || tmpString.indexOf(">") > -1)
+ if (tmpString.indexOf("<") > -1 || tmpString.indexOf(">") > -1)
{
// The description does not specify html is to
// be used, so we must remove < > symbols
.getType());
if (rng != null && rng[0] != null && rng[0][0] != rng[0][1])
{
- sb.append(" Score=").append(
- String.valueOf(feature.getScore()));
+ sb.append(" Score=").append(String.valueOf(feature.getScore()));
}
}
String status = (String) feature.getValue("status");
String unq = urls[u] + "|" + urls[u + 1];
if (!uniques.contains(unq))
{
- result.add(new String[] { target, label, urls[u],
- urls[u + 1] });
+ result.add(new String[] { target, label, urls[u], urls[u + 1] });
uniques.add(unq);
}
}
String unq = urls[u] + "|" + urls[u + 1];
if (!uniques.contains(unq))
{
- result.add(new String[] { target, label, urls[u],
- urls[u + 1] });
+ result.add(new String[] { target, label, urls[u], urls[u + 1] });
uniques.add(unq);
}
}
String unq = urls[u] + "|" + urls[u + 1];
if (!uniques.contains(unq))
{
- result.add(new String[] { target, label, urls[u],
- urls[u + 1] });
+ result.add(new String[] { target, label, urls[u], urls[u + 1] });
uniques.add(unq);
}
}
*/
package jalview.io;
+import jalview.analysis.Rna;
import jalview.datamodel.AlignmentAnnotation;
import jalview.datamodel.AlignmentI;
import jalview.datamodel.Annotation;
import jalview.datamodel.Sequence;
import jalview.datamodel.SequenceFeature;
import jalview.datamodel.SequenceI;
+import jalview.schemes.ResidueProperties;
import jalview.util.Format;
import jalview.util.MessageManager;
*/
public class StockholmFile extends AlignFile
{
- // static Logger logger = Logger.getLogger("jalview.io.StockholmFile");
- protected ArrayList<RNA> result;
+ private static final Regex OPEN_PAREN = new Regex("(<|\\[)", "(");
+
+ private static final Regex CLOSE_PAREN = new Regex("(>|\\])", ")");
+
+ private static final Regex DETECT_BRACKETS = new Regex(
+ "(<|>|\\[|\\]|\\(|\\))");
StringBuffer out; // output buffer
super(source);
}
+ @Override
public void initData()
{
super.initData();
fr = new FileReader(inFile);
BufferedReader r = new BufferedReader(fr);
- result = null;
+ List<RNA> result = null;
try
{
result = RNAFactory.loadSecStrStockholm(r);
for (int k = 0; k < rna.length(); k++)
{
- ann[k] = new Annotation(annot[k], "",
- jalview.schemes.ResidueProperties.getRNASecStrucState(
- annot[k]).charAt(0), 0f);
+ ann[k] = new Annotation(annot[k], "", Rna.getRNASecStrucState(
+ annot[k]).charAt(0), 0f);
}
AlignmentAnnotation align = new AlignmentAnnotation("Sec. str.",
* @throws IOException
* If there is an error with the input file
*/
+ @Override
public void parse() throws IOException
{
StringBuffer treeString = new StringBuffer();
}
else
{
- // throw new IOException(MessageManager.formatMessage(
- // "exception.error_parsing_line", new String[] { line }));
+ // throw new IOException("Error parsing " + line);
System.err.println(">> missing annotation: " + line);
}
}
}
protected static AlignmentAnnotation parseAnnotationRow(
- Vector annotation, String label, String annots)
+ Vector<AlignmentAnnotation> annotation, String label,
+ String annots)
{
String convert1, convert2 = null;
- // Convert all bracket types to parentheses
- Regex openparen = new Regex("(<|\\[)", "(");
- Regex closeparen = new Regex("(>|\\])", ")");
-
- // Detect if file is RNA by looking for bracket types
- Regex detectbrackets = new Regex("(<|>|\\[|\\]|\\(|\\))");
-
- convert1 = openparen.replaceAll(annots);
- convert2 = closeparen.replaceAll(convert1);
+ convert1 = OPEN_PAREN.replaceAll(annots);
+ convert2 = CLOSE_PAREN.replaceAll(convert1);
annots = convert2;
String type = label;
{
// if (" .-_".indexOf(pos) == -1)
{
- if (detectbrackets.search(pos))
+ if (DETECT_BRACKETS.search(pos))
{
- ann.secondaryStructure = jalview.schemes.ResidueProperties
- .getRNASecStrucState(pos).charAt(0);
+ ann.secondaryStructure = Rna.getRNASecStrucState(pos).charAt(0);
}
else
{
- ann.secondaryStructure = jalview.schemes.ResidueProperties
- .getDssp3state(pos).charAt(0);
+ ann.secondaryStructure = ResidueProperties.getDssp3state(pos)
+ .charAt(0);
}
if (ann.secondaryStructure == pos.charAt(0))
els[i] = ann;
}
AlignmentAnnotation annot = null;
- Enumeration e = annotation.elements();
+ Enumeration<AlignmentAnnotation> e = annotation.elements();
while (e.hasMoreElements())
{
- annot = (AlignmentAnnotation) e.nextElement();
+ annot = e.nextElement();
if (annot.label.equals(type))
{
break;
return seq;
}
+ @Override
public String print()
{
out = new StringBuffer();
}
private static Hashtable typeIds = null;
+
static
{
if (typeIds == null)
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
package jalview.io;
import jalview.analysis.AlignSeq;
import jalview.datamodel.DBRefEntry;
import jalview.datamodel.DBRefSource;
import jalview.datamodel.PDBEntry;
+import jalview.datamodel.PDBEntry.Type;
import jalview.datamodel.SequenceI;
-import jalview.structure.StructureViewSettings;
+import jalview.structure.StructureImportSettings;
import java.awt.Color;
import java.io.IOException;
import java.lang.reflect.Constructor;
-import java.util.Hashtable;
import java.util.List;
import java.util.Vector;
private String id;
- private String dbRefType;
+ private PDBEntry.Type dbRefType;
/**
* set to true to add derived sequence annotations (temp factor read from
private Vector<PDBChain> chains;
+ private boolean pdbIdAvailable;
+
public StructureFile(String inFile, String type) throws IOException
{
super(inFile, type);
public void xferSettings()
{
- this.visibleChainAnnotation = StructureViewSettings
+ this.visibleChainAnnotation = StructureImportSettings
.isVisibleChainAnnotation();
- this.predictSecondaryStructure = StructureViewSettings
- .isPredictSecondaryStructure();
- this.externalSecondaryStructure = StructureViewSettings
+ this.predictSecondaryStructure = StructureImportSettings
+ .isProcessSecondaryStructure();
+ this.externalSecondaryStructure = StructureImportSettings
.isExternalSecondaryStructure();
}
- public StructureFile(boolean parseImmediately, String inFile, String type)
- throws IOException
+ public StructureFile(boolean parseImmediately, String dataObject,
+ String type) throws IOException
{
- super(parseImmediately, inFile, type);
+ super(parseImmediately, dataObject, type);
}
public StructureFile(boolean a, FileParse fp) throws IOException
{
}
- @SuppressWarnings("rawtypes")
protected SequenceI postProcessChain(PDBChain chain)
{
SequenceI pdbSequence = chain.sequence;
pdbSequence.setName(getId() + "|" + pdbSequence.getName());
PDBEntry entry = new PDBEntry();
entry.setId(getId());
- entry.setType(this.dbRefType);
- entry.setProperty(new Hashtable());
+ entry.setType(getStructureFileType());
if (chain.id != null)
{
- entry.setChainCode(String.valueOf(chain.id));
+ entry.setChainCode(chain.id);
}
if (inFile != null)
{
DBRefEntry sourceDBRef = new DBRefEntry();
sourceDBRef.setAccessionId(getId());
sourceDBRef.setSource(DBRefSource.PDB);
- sourceDBRef.setStartRes(pdbSequence.getStart());
- sourceDBRef.setEndRes(pdbSequence.getEnd());
- pdbSequence.setSourceDBRef(sourceDBRef);
+ // TODO: specify version for 'PDB' database ref if it is read from a file.
+ // TODO: decide if jalview.io should be creating primary refs!
+ sourceDBRef.setVersion("");
pdbSequence.addPDBId(entry);
pdbSequence.addDBRef(sourceDBRef);
SequenceI chainseq = pdbSequence;
return chainseq;
}
+ /**
+ * filetype of structure file - default is PDB
+ */
+ String structureFileType = PDBEntry.Type.PDB.toString();
+
+ protected void setStructureFileType(String structureFileType)
+ {
+ this.structureFileType = structureFileType;
+ }
+
+ /**
+ * filetype of last file processed
+ *
+ * @return
+ */
+ public String getStructureFileType()
+ {
+ return structureFileType;
+ }
+
@SuppressWarnings({ "unchecked", "rawtypes" })
protected void processPdbFileWithAnnotate3d(List<SequenceI> rna)
throws Exception
Class cl = Class.forName("jalview.ext.jmol.JmolParser");
if (cl != null)
{
- final Constructor constructor = cl.getConstructor(new Class[] {
- boolean.class, boolean.class, boolean.class, FileParse.class });
- final Object[] args = new Object[] { visibleChainAnnotation,
- predictSecondaryStructure, externalSecondaryStructure,
- new FileParse(getDataName(), type) };
-
- StructureViewSettings.setShowSeqFeatures(false);
- StructureViewSettings.setVisibleChainAnnotation(false);
- StructureViewSettings
- .setPredictSecondaryStructure(predictSecondaryStructure);
- StructureViewSettings
+ final Constructor constructor = cl
+ .getConstructor(new Class[] { FileParse.class });
+ final Object[] args = new Object[] { new FileParse(getDataName(),
+ type) };
+
+ StructureImportSettings.setShowSeqFeatures(false);
+ StructureImportSettings.setVisibleChainAnnotation(false);
+ StructureImportSettings
+ .setProcessSecondaryStructure(predictSecondaryStructure);
+ StructureImportSettings
.setExternalSecondaryStructure(externalSecondaryStructure);
Object jmf = constructor.newInstance(args);
AlignmentI al = new Alignment((SequenceI[]) cl.getMethod(
} catch (ClassNotFoundException q)
{
}
- StructureViewSettings.setShowSeqFeatures(true);
+ StructureImportSettings.setShowSeqFeatures(true);
}
public PDBChain findChain(String id) throws Exception
{
for (PDBChain chain : getChains())
{
- if (chain.id.equalsIgnoreCase(id))
+ if (chain.id.equals(id))
{
return chain;
}
this.chains = chains;
}
- public String getDbRefType()
+ public Type getDbRefType()
{
return dbRefType;
}
public void setDbRefType(String dbRefType)
{
+ this.dbRefType = Type.getType(dbRefType);
+ }
+
+ public void setDbRefType(Type dbRefType)
+ {
this.dbRefType = dbRefType;
}
{
return new PDBFeatureSettings();
}
+
+ /**
+ * Answers true if the structure file has a PDBId
+ *
+ * @return
+ */
+ public boolean isPPDBIdAvailable()
+ {
+ return pdbIdAvailable;
+ }
+
+ public void setPDBIdAvailable(boolean pdbIdAvailable)
+ {
+ this.pdbIdAvailable = pdbIdAvailable;
+ }
}
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
package jalview.io.gff;
import jalview.datamodel.AlignedCodonFrame;
try
{
- processGffSimilarity(set, seq, gffColumns,
- align, newseqs, relaxedIdMatching);
+ processGffSimilarity(set, seq, gffColumns, align, newseqs,
+ relaxedIdMatching);
} catch (IOException ivfe)
{
System.err.println(ivfe);
* if true allow fuzzy search for a matching target sequence
* @throws IOException
*/
- protected void processGffSimilarity(
- Map<String, List<String>> set,
+ protected void processGffSimilarity(Map<String, List<String>> set,
SequenceI seq, String[] gff, AlignmentI align,
List<SequenceI> newseqs, boolean relaxedIdMatching)
throws IOException
int alignFromStart;
int alignToStart;
int alignCount;
- try {
+ try
+ {
alignFromStart = Integer.parseInt(tokens[0]);
alignToStart = Integer.parseInt(tokens[1]);
alignCount = Integer.parseInt(tokens[2]);
- } catch (NumberFormatException nfe) {
+ } catch (NumberFormatException nfe)
+ {
System.err.println(nfe.toString());
return null;
}
-
+
int fromStart;
int fromEnd;
int toStart;
{
result = MappingType.PeptideToNucleotide;
}
- else if (model.contains(CODING2CODING)
- || model.contains(CODING2GENOME)
- || model.contains(CDNA2GENOME)
- || model.contains(GENOME2GENOME))
+ else if (model.contains(CODING2CODING) || model.contains(CODING2GENOME)
+ || model.contains(CDNA2GENOME) || model.contains(GENOME2GENOME))
{
result = MappingType.NucleotideToNucleotide;
}
{
String mdl = model.toLowerCase();
if (mdl.contains(PROTEIN2DNA) || mdl.contains(PROTEIN2GENOME)
- || mdl.contains(CODING2CODING)
- || mdl.contains(CODING2GENOME)
- || mdl.contains(CDNA2GENOME)
- || mdl.contains(GENOME2GENOME))
+ || mdl.contains(CODING2CODING) || mdl.contains(CODING2GENOME)
+ || mdl.contains(CDNA2GENOME) || mdl.contains(GENOME2GENOME))
{
return true;
}
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
package jalview.io.gff;
import jalview.datamodel.AlignmentI;
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
package jalview.io.gff;
import jalview.datamodel.AlignedCodonFrame;
}
else if (so.isA(soTerm, SequenceOntologyI.NUCLEOTIDE_MATCH))
{
- sf = processNucleotideMatch(attributes, seq, gff, align,
- newseqs, relaxedIdMatching);
+ sf = processNucleotideMatch(attributes, seq, gff, align, newseqs,
+ relaxedIdMatching);
}
else
{
*/
sf = buildSequenceFeature(gff, null);
}
-
+
return sf;
}
protected SequenceFeature processNucleotideMatch(
Map<String, List<String>> attributes, SequenceI seq,
String[] gffColumns, AlignmentI align, List<SequenceI> newseqs,
- boolean relaxedIdMatching)
- throws IOException
+ boolean relaxedIdMatching) throws IOException
{
String strand = gffColumns[STRAND_COL];
* (new or existing) virtual sequence in the newseqs list
*/
String targetId = findTargetId(tokens[0], attributes);
- SequenceI mappedSequence1 = findSequence(targetId, align,
- newseqs, relaxedIdMatching);
+ SequenceI mappedSequence1 = findSequence(targetId, align, newseqs,
+ relaxedIdMatching);
SequenceI mappedSequence = mappedSequence1;
if (mappedSequence == null)
{
int fromStart = Integer.parseInt(gffColumns[START_COL]);
int fromEnd = Integer.parseInt(gffColumns[END_COL]);
MapList mapping = constructMappingFromAlign(fromStart, fromEnd,
- toStart, toEnd,
- MappingType.NucleotideToNucleotide);
+ toStart, toEnd, MappingType.NucleotideToNucleotide);
if (mapping != null)
{
for (String target : targets)
{
- SequenceI mappedSequence1 = findSequence(findTargetId(target, set), align,
- newseqs, relaxedIdMatching);
+ SequenceI mappedSequence1 = findSequence(findTargetId(target, set),
+ align, newseqs, relaxedIdMatching);
SequenceI mappedSequence = mappedSequence1;
if (mappedSequence == null)
{
/*
* Ensembl returns dna variants as 'alleles'
*/
- desc = StringUtils.listToDelimitedString(
- attributes.get("alleles"), ",");
+ desc = StringUtils.listToDelimitedString(attributes.get("alleles"),
+ ",");
}
/*
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
package jalview.io.gff;
/**
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
package jalview.io.gff;
import jalview.analysis.SequenceIdMatcher;
* @param toSeq
* @return
*/
- protected AlignedCodonFrame getMapping(AlignmentI align, SequenceI fromSeq, SequenceI toSeq)
+ protected AlignedCodonFrame getMapping(AlignmentI align,
+ SequenceI fromSeq, SequenceI toSeq)
{
AlignedCodonFrame acf = align.getMapping(fromSeq, toSeq);
if (acf == null)
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
package jalview.io.gff;
-
/**
* A factory to serve instances of GFF helper classes
*/
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
package jalview.io.gff;
import jalview.datamodel.AlignmentI;
* @throws IOException
*/
SequenceFeature processGff(SequenceI seq, String[] gffColumns,
- AlignmentI align,
- List<SequenceI> newseqs, boolean relaxedIdMatching)
- throws IOException;
+ AlignmentI align, List<SequenceI> newseqs,
+ boolean relaxedIdMatching) throws IOException;
// java 8 will allow static methods in interfaces:
// static boolean recognises(String [] columns);
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
package jalview.io.gff;
import jalview.datamodel.AlignmentI;
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
package jalview.io.gff;
+/**
+ * A factory class that returns a model of the Sequence Ontology. By default a
+ * hard-coded subset is used (for the applet, or testing), or setInstance() can
+ * be used to set full Ontology data.
+ *
+ * @author gmcarstairs
+ *
+ */
public class SequenceOntologyFactory
{
private static SequenceOntologyI instance;
{
if (instance == null)
{
- // instance = new SequenceOntology();
instance = new SequenceOntologyLite();
}
return instance;
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
package jalview.io.gff;
import java.util.List;
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
package jalview.io.gff;
import java.util.ArrayList;
{ "miRNA", "transcript" },
{ "lincRNA", "transcript" },
{ "rRNA", "transcript" },
+ { "mRNA", "transcript" },
// there are many more sub-types of ncRNA...
/*
private void loadStaticData()
{
parents = new HashMap<String, List<String>>();
- for (String [] pair : TERMS) {
+ for (String[] pair : TERMS)
+ {
List<String> p = parents.get(pair[0]);
if (p == null)
{
{
if (!termsNotFound.contains(term))
{
- System.out.println("SO term " + term
- + " not known - may be invalid, or model if needed in "
- + getClass().getName());
+ // suppress logging here as it reports Uniprot sequence features
+ // (which do not use SO terms) when auto-configuring feature colours
+ // System.out.println("SO term " + term
+ // + " not known - add to model if needed in "
+ // + getClass().getName());
termsNotFound.add(term);
}
}
* @param parentAlignment
*/
public JalviewDataset(AlignmentI aldataset,
- Map<String, FeatureColourI> fc,
- Hashtable seqDets)
+ Map<String, FeatureColourI> fc, Hashtable seqDets)
{
// TODO not used - remove?
this(aldataset, fc, seqDets, null);
* with.
*/
public JalviewDataset(AlignmentI aldataset,
- Map<String, FeatureColourI> fc,
- Hashtable seqDets, AlignmentI parentAlignment)
+ Map<String, FeatureColourI> fc, Hashtable seqDets,
+ AlignmentI parentAlignment)
{
this();
parentDataset = aldataset;
return dsregitem;
}
- protected void finalize()
+ @Override
+ protected void finalize() throws Throwable
{
if (dsObjReg != null)
{
{
dsItemReg.clear();
}
+ super.finalize();
}
}
}
}
if (alsq.size() < sequences.length)
+ {
Cache.log
.warn("Not recovered all alignment sequences for given set of input sequence CIGARS");
+ }
return alsq;
}
public void UpdateSequenceTreeMap(TreePanel tp)
{
if (tp == null || tree == null)
+ {
return;
- Vector leaves = new Vector();
+ }
+
if (tp.getTree() == null)
{
Cache.log.warn("Not updating SequenceTreeMap for "
+ tree.getVorbaId());
return;
}
- tp.getTree().findLeaves(tp.getTree().getTopNode(), leaves);
+ Vector<SequenceNode> leaves = tp.getTree().findLeaves(
+ tp.getTree().getTopNode());
Treenode[] tn = tree.getTreenode(); // todo: select nodes for this
// particular tree
int sz = tn.length;
*/
public Treenode[] makeTreeNodes(NJTree ntree, Newick newick)
{
- Vector leaves = new Vector();
- ntree.findLeaves(ntree.getTopNode(), leaves);
+ Vector<SequenceNode> leaves = ntree.findLeaves(ntree.getTopNode());
Vector tnv = new Vector();
Enumeration l = leaves.elements();
Hashtable nodespecs = new Hashtable();
--occurence;
}
else
+ {
bn = null;
+ }
}
return bn;
}
jvlite.setExecutor(this);
}
- public void finalize()
+ @Override
+ protected void finalize() throws Throwable
{
jvlite = null;
executor = null;
jsExecQueue.clear();
}
jsExecQueue = null;
+ super.finalize();
}
private Vector jsExecQueue;
executor = null;
}
+ @Override
public void run()
{
while (jsExecQueue != null)
final Exception[] jsex = new Exception[1];
Runnable exec = new Runnable()
{
+ @Override
public void run()
{
try
if (jex instanceof netscape.javascript.JSException
&& jvlite.jsfallbackEnabled)
{
- jsex[0] = (netscape.javascript.JSException) jex;
+ jsex[0] = jex;
if (jvlite.debug)
{
System.err.println("Falling back to javascript: url call");
return _listenerfn;
}
- public void finalise()
+ public void finalize() throws Throwable
{
jvlite = null;
super.finalize();
public JCheckBoxMenuItem showSeqFeatures = new JCheckBoxMenuItem();
- public JCheckBoxMenuItem showSeqFeaturesHeight = new JCheckBoxMenuItem();
-
JMenuItem copy = new JMenuItem();
JMenuItem cut = new JMenuItem();
@Override
public void mousePressed(MouseEvent evt)
{
- if (evt.isPopupTrigger())
+ if (evt.isPopupTrigger()) // Mac
{
- radioItem.removeActionListener(radioItem.getActionListeners()[0]);
-
- int option = JOptionPane.showInternalConfirmDialog(
- jalview.gui.Desktop.desktop,
- MessageManager
- .getString("label.remove_from_default_list"),
- MessageManager
- .getString("label.remove_user_defined_colour"),
- JOptionPane.YES_NO_OPTION);
- if (option == JOptionPane.YES_OPTION)
- {
- jalview.gui.UserDefinedColours
- .removeColourFromDefaults(radioItem.getText());
- colourMenu.remove(radioItem);
- }
- else
+ offerRemoval(radioItem);
+ }
+ }
+
+ @Override
+ public void mouseReleased(MouseEvent evt)
+ {
+ if (evt.isPopupTrigger()) // Windows
+ {
+ offerRemoval(radioItem);
+ }
+ }
+
+ /**
+ * @param radioItem
+ */
+ void offerRemoval(final JRadioButtonMenuItem radioItem)
+ {
+ radioItem.removeActionListener(radioItem.getActionListeners()[0]);
+
+ int option = JOptionPane.showInternalConfirmDialog(
+ jalview.gui.Desktop.desktop, MessageManager
+ .getString("label.remove_from_default_list"),
+ MessageManager
+ .getString("label.remove_user_defined_colour"),
+ JOptionPane.YES_NO_OPTION);
+ if (option == JOptionPane.YES_OPTION)
+ {
+ jalview.gui.UserDefinedColours
+ .removeColourFromDefaults(radioItem.getText());
+ colourMenu.remove(radioItem);
+ }
+ else
+ {
+ radioItem.addActionListener(new ActionListener()
{
- radioItem.addActionListener(new ActionListener()
+ @Override
+ public void actionPerformed(ActionEvent evt)
{
- @Override
- public void actionPerformed(ActionEvent evt)
- {
- userDefinedColour_actionPerformed(evt);
- }
- });
- }
+ userDefinedColour_actionPerformed(evt);
+ }
+ });
}
}
});
});
JMenuItem modifyPID = new JMenuItem(
- MessageManager.getString("label.modify_identity_thereshold"));
+ MessageManager.getString("label.modify_identity_threshold"));
modifyPID.addActionListener(new ActionListener()
{
@Override
}
});
modifyConservation.setText(MessageManager
- .getString("label.modify_conservation_thereshold"));
+ .getString("label.modify_conservation_threshold"));
modifyConservation.addActionListener(new ActionListener()
{
@Override
showProducts.setText(MessageManager.getString("label.get_cross_refs"));
runGroovy.setText(MessageManager.getString("label.run_groovy"));
- runGroovy.setToolTipText(MessageManager.getString("label.run_groovy_tip"));
+ runGroovy.setToolTipText(MessageManager
+ .getString("label.run_groovy_tip"));
runGroovy.addActionListener(new ActionListener()
{
@Override
@Override
public void mousePressed(MouseEvent e)
{
- tabbedPane_mousePressed(e);
+ if (e.isPopupTrigger()) // Mac
+ {
+ tabbedPane_mousePressed(e);
+ }
+ }
+
+ @Override
+ public void mouseReleased(MouseEvent e)
+ {
+ if (e.isPopupTrigger()) // Windows
+ {
+ tabbedPane_mousePressed(e);
+ }
}
});
tabbedPane.addFocusListener(new FocusAdapter()
{
}
+
/**
* Adds the given action listener and key accelerator to the given menu item.
* Also saves in a lookup table to support lookup of action by key stroke.
}
- protected void showSeqFeaturesHeight_actionPerformed(
- ActionEvent actionEvent)
- {
- // TODO Auto-generated method stub
-
- }
-
protected void justifyRightMenuItem_actionPerformed(ActionEvent e)
{
// TODO Auto-generated method stub
ok.setText(MessageManager.getString("label.new_window"));
ok.addActionListener(new ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
ok_actionPerformed(e);
cancel.setText(MessageManager.getString("action.close"));
cancel.addActionListener(new ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
cancel_actionPerformed(e);
close.setText(MessageManager.getString("action.close"));
close.addActionListener(new ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
cancel_actionPerformed(e);
.getMenuShortcutKeyMask(), false));
selectAll.addActionListener(new ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
selectAll_actionPerformed(e);
.getMenuShortcutKeyMask(), false));
save.addActionListener(new ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
save_actionPerformed(e);
textarea.setFont(new java.awt.Font("Monospaced", Font.PLAIN, 12));
textarea.addMouseListener(new java.awt.event.MouseAdapter()
{
+ @Override
public void mousePressed(MouseEvent e)
{
textarea_mousePressed(e);
}
+
+ @Override
+ public void mouseReleased(MouseEvent e)
+ {
+ textarea_mousePressed(e);
+ }
});
editMenu.setText(MessageManager.getString("action.edit"));
copyItem.setText(MessageManager.getString("action.copy"));
copyItem.addActionListener(new ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
copyItem_actionPerformed(e);
ok.setText(MessageManager.getString("label.new_window"));
ok.addActionListener(new ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
ok_actionPerformed(e);
cancel.setText(MessageManager.getString("action.close"));
cancel.addActionListener(new ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
cancel_actionPerformed(e);
.getMenuShortcutKeyMask(), false));
selectAll.addActionListener(new ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
selectAll_actionPerformed(e);
.getMenuShortcutKeyMask(), false));
save.addActionListener(new ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
save_actionPerformed(e);
textarea.setFont(new java.awt.Font("Monospaced", Font.PLAIN, 12));
textarea.addMouseListener(new java.awt.event.MouseAdapter()
{
+ @Override
public void mousePressed(MouseEvent e)
{
- textarea_mousePressed(e);
+ textarea_mousePressed(e); // on Mac
+ }
+
+ @Override
+ public void mouseReleased(MouseEvent e)
+ {
+ textarea_mousePressed(e); // on Windows
}
});
editMenu.setText(MessageManager.getString("action.edit"));
pasteMenu.setText(MessageManager.getString("action.paste"));
pasteMenu.addActionListener(new ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
pasteMenu_actionPerformed(e);
copyItem.setText(MessageManager.getString("action.copy"));
copyItem.addActionListener(new ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
copyItem_actionPerformed(e);
nameTB.setBounds(new Rectangle(77, 10, 310, 23));
nameTB.addKeyListener(new KeyAdapter()
{
+ @Override
public void keyTyped(KeyEvent e)
{
nameTB_keyTyped(e);
urlTB.setBounds(new Rectangle(78, 40, 309, 23));
urlTB.addKeyListener(new KeyAdapter()
{
+ @Override
public void keyTyped(KeyEvent e)
{
urlTB_keyTyped(e);
jLabel3.setBounds(new Rectangle(21, 72, 351, 15));
jLabel4.setFont(new java.awt.Font("Verdana", Font.ITALIC, 11));
jLabel4.setText(MessageManager.getString("label.use_sequence_id_2"));
- jLabel4.setBounds(new Rectangle(21, 93, 351, 15));
+ jLabel4.setBounds(new Rectangle(21, 88, 351, 15));
+ jLabel5.setFont(new java.awt.Font("Verdana", Font.ITALIC, 11));
+ jLabel5.setText(MessageManager.getString("label.use_sequence_id_3"));
+ jLabel5.setBounds(new Rectangle(21, 106, 351, 15));
+
+ String lastLabel = MessageManager.getString("label.use_sequence_id_4");
+ if (lastLabel.length() > 0)
+ {
+ // e.g. Spanish version has longer text
+ jLabel6.setFont(new java.awt.Font("Verdana", Font.ITALIC, 11));
+ jLabel6.setText(lastLabel);
+ jLabel6.setBounds(new Rectangle(21, 122, 351, 15));
+ }
+
jPanel1.setBorder(BorderFactory.createEtchedBorder());
jPanel1.setLayout(null);
jPanel1.add(jLabel1);
jPanel1.add(jLabel2);
jPanel1.add(jLabel3);
jPanel1.add(jLabel4);
+ jPanel1.add(jLabel5);
+
+ int height = 130;
+ if (lastLabel.length() > 0)
+ {
+ jPanel1.add(jLabel6);
+ height = 146;
+ }
+
this.add(jPanel1, new GridBagConstraints(0, 0, 1, 1, 1.0, 1.0,
GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(
- 5, 4, 6, 5), 390, 130));
+ 5, 4, 6, 5), 390, height));
}
+ @Override
public void setName(String name)
{
nameTB.setText(name);
urlTB.setText(url);
}
+ @Override
public String getName()
{
return nameTB.getText();
JLabel jLabel4 = new JLabel();
+ JLabel jLabel5 = new JLabel();
+
+ JLabel jLabel6 = new JLabel();
+
JPanel jPanel1 = new JPanel();
GridBagLayout gridBagLayout1 = new GridBagLayout();
protected JScrollPane scrl_localPDB = new JScrollPane(tbl_local_pdb);
- private JTabbedPane pnl_filter = new JTabbedPane();
+ protected JTabbedPane pnl_filter = new JTabbedPane();
protected FTSDataColumnPreferences pdbDocFieldPrefs = new FTSDataColumnPreferences(
PreferenceSource.STRUCTURE_CHOOSER,
}
}
evt.consume();
+ break;
default:
return;
}
@Override
public void actionPerformed(ActionEvent e)
{
- closeAction();
+ closeAction(pnl_filter.getHeight());
}
});
btn_cancel.addKeyListener(new KeyAdapter()
{
if (evt.getKeyCode() == KeyEvent.VK_ENTER)
{
- closeAction();
+ closeAction(pnl_filter.getHeight());
}
}
});
@Override
public void internalFrameClosing(InternalFrameEvent e)
{
- closeAction();
+ closeAction(pnl_filter.getHeight());
}
});
mainFrame.setVisible(true);
Desktop.addInternalFrame(mainFrame, frameTitle, width, height);
}
- protected void closeAction()
+ protected void closeAction(int preferredHeight)
{
// System.out.println(">>>>>>>>>> closing internal frame!!!");
// System.out.println("width : " + mainFrame.getWidth());
// System.out.println("x : " + mainFrame.getX());
// System.out.println("y : " + mainFrame.getY());
tempUserPrefs.put("structureChooser.width", pnl_filter.getWidth());
- tempUserPrefs.put("structureChooser.height", pnl_filter.getHeight());
+ tempUserPrefs.put("structureChooser.height", preferredHeight);
tempUserPrefs.put("structureChooser.x", mainFrame.getX());
tempUserPrefs.put("structureChooser.y", mainFrame.getY());
mainFrame.dispose();
}
+
public boolean wantedFieldsUpdated()
{
if (previousWantedFields == null)
{
return true;
}
-
+
FTSDataColumnI[] currentWantedFields = pdbDocFieldPrefs
- .getStructureSummaryFields()
- .toArray(new FTSDataColumnI[0]);
+ .getStructureSummaryFields().toArray(new FTSDataColumnI[0]);
return Arrays.equals(currentWantedFields, previousWantedFields) ? false
: true;
{
return tbl_summary;
}
+
public JComboBox<FilterOption> getCmbFilterOption()
{
return cmb_filterOption;
protected abstract void stateChanged(ItemEvent e);
- protected abstract void updateCurrentView();
-
- protected abstract void populateFilterComboBox();
-
protected abstract void ok_ActionPerformed();
protected abstract void pdbFromFile_actionPerformed();
import jalview.analysis.AAFrequency;
import jalview.analysis.CodingUtils;
+import jalview.analysis.Profile;
+import jalview.analysis.Rna;
import jalview.analysis.StructureFrequency;
import jalview.api.AlignViewportI;
import jalview.datamodel.AlignmentAnnotation;
import jalview.datamodel.ColumnSelection;
import jalview.schemes.ColourSchemeI;
import jalview.schemes.ResidueProperties;
+import jalview.util.Platform;
import java.awt.BasicStroke;
import java.awt.Color;
import java.util.BitSet;
import java.util.Hashtable;
-import com.stevesoft.pat.Regex;
-
public class AnnotationRenderer
{
private static final int UPPER_TO_LOWER = 'a' - 'A'; // 32
*/
private final boolean debugRedraw;
+ private int charWidth, endRes, charHeight;
+
+ private boolean validCharWidth, hasHiddenColumns;
+
+ private FontMetrics fm;
+
+ private final boolean MAC = Platform.isAMac();
+
+ boolean av_renderHistogram = true, av_renderProfile = true,
+ av_normaliseProfile = false;
+
+ ColourSchemeI profcolour = null;
+
+ private ColumnSelection columnSelection;
+
+ private Profile[] hconsensus;
+
+ private Hashtable[] complementConsensus;
+
+ private Hashtable[] hStrucConsensus;
+
+ private boolean av_ignoreGapsConsensus;
+
+ /**
+ * attributes set from AwtRenderPanelI
+ */
+ /**
+ * old image used when data is currently being calculated and cannot be
+ * rendered
+ */
+ private Image fadedImage;
+
+ /**
+ * panel being rendered into
+ */
+ private ImageObserver annotationPanel;
+
+ /**
+ * width of image to render in panel
+ */
+ private int imgWidth;
+
+ /**
+ * offset to beginning of visible area
+ */
+ private int sOffset;
+
+ /**
+ * offset to end of visible area
+ */
+ private int visHeight;
+
+ /**
+ * indicate if the renderer should only render the visible portion of the
+ * annotation given the current view settings
+ */
+ private boolean useClip = true;
+
+ /**
+ * master flag indicating if renderer should ever try to clip. not enabled for
+ * jalview 2.8.1
+ */
+ private boolean canClip = false;
+
public AnnotationRenderer()
{
this(false);
this.debugRedraw = debugRedraw;
}
- public void drawStemAnnot(Graphics g, Annotation[] row_annotations,
- int lastSSX, int x, int y, int iconOffset, int startRes,
- int column, boolean validRes, boolean validEnd)
+ /**
+ * Remove any references and resources when this object is no longer required
+ */
+ public void dispose()
+ {
+ hconsensus = null;
+ complementConsensus = null;
+ hStrucConsensus = null;
+ fadedImage = null;
+ annotationPanel = null;
+ }
+
+ void drawStemAnnot(Graphics g, Annotation[] row_annotations, int lastSSX,
+ int x, int y, int iconOffset, int startRes, int column,
+ boolean validRes, boolean validEnd)
{
g.setColor(STEM_COLOUR);
int sCol = (lastSSX / charWidth) + startRes;
int x1 = lastSSX;
int x2 = (x * charWidth);
- Regex closeparen = new Regex("(\\))");
char dc = (column == 0 || row_annotations[column - 1] == null) ? ' '
: row_annotations[column - 1].secondaryStructure;
boolean diffdownstream = !validRes || !validEnd
|| row_annotations[column] == null
|| dc != row_annotations[column].secondaryStructure;
- // System.out.println("Column "+column+" diff up: "+diffupstream+" down:"+diffdownstream);
- // If a closing base pair half of the stem, display a backward arrow
- if (column > 0 && ResidueProperties.isCloseParenRNA(dc))
- {
+ if (column > 0 && Rna.isClosingParenthesis(dc))
+ {
if (diffupstream)
// if (validRes && column>1 && row_annotations[column-2]!=null &&
// dc.equals(row_annotations[column-2].displayCharacter))
{
+ /*
+ * if new annotation with a closing base pair half of the stem,
+ * display a backward arrow
+ */
g.fillPolygon(new int[] { lastSSX + 5, lastSSX + 5, lastSSX },
new int[] { y + iconOffset, y + 14 + iconOffset,
y + 8 + iconOffset }, 3);
}
else
{
-
// display a forward arrow
if (diffdownstream)
{
+ /*
+ * if annotation ending with an opeing base pair half of the stem,
+ * display a forward arrow
+ */
g.fillPolygon(new int[] { x2 - 5, x2 - 5, x2 }, new int[] {
y + iconOffset, y + 14 + iconOffset, y + 8 + iconOffset }, 3);
x2 -= 5;
g.fillRect(x1, y + 4 + iconOffset, x2 - x1, 7);
}
- private int charWidth, endRes, charHeight;
-
- private boolean validCharWidth, hasHiddenColumns;
-
- private FontMetrics fm;
-
- private final boolean MAC = jalview.util.Platform.isAMac();
-
- boolean av_renderHistogram = true, av_renderProfile = true,
- av_normaliseProfile = false;
-
- ColourSchemeI profcolour = null;
-
- private ColumnSelection columnSelection;
-
- private Hashtable[] hconsensus;
-
- private Hashtable[] complementConsensus;
-
- private Hashtable[] hStrucConsensus;
-
- private boolean av_ignoreGapsConsensus;
-
- /**
- * attributes set from AwtRenderPanelI
- */
- /**
- * old image used when data is currently being calculated and cannot be
- * rendered
- */
- private Image fadedImage;
-
- /**
- * panel being rendered into
- */
- private ImageObserver annotationPanel;
-
- /**
- * width of image to render in panel
- */
- private int imgWidth;
-
- /**
- * offset to beginning of visible area
- */
- private int sOffset;
-
- /**
- * offset to end of visible area
- */
- private int visHeight;
-
- /**
- * indicate if the renderer should only render the visible portion of the
- * annotation given the current view settings
- */
- private boolean useClip = true;
-
- /**
- * master flag indicating if renderer should ever try to clip. not enabled for
- * jalview 2.8.1
- */
- private boolean canClip = false;
-
- public void drawNotCanonicalAnnot(Graphics g, Color nonCanColor,
+ void drawNotCanonicalAnnot(Graphics g, Color nonCanColor,
Annotation[] row_annotations, int lastSSX, int x, int y,
int iconOffset, int startRes, int column, boolean validRes,
boolean validEnd)
int sCol = (lastSSX / charWidth) + startRes;
int x1 = lastSSX;
int x2 = (x * charWidth);
- Regex closeparen = new Regex("}|]|<|[a-z]");
String dc = (column == 0 || row_annotations[column - 1] == null) ? ""
: row_annotations[column - 1].displayCharacter;
|| !dc.equals(row_annotations[column].displayCharacter);
// System.out.println("Column "+column+" diff up: "+diffupstream+" down:"+diffdownstream);
// If a closing base pair half of the stem, display a backward arrow
- if (column > 0 && closeparen.search(dc))// closeletter_b.search(dc)||closeletter_c.search(dc)||closeletter_d.search(dc)||closecrochet.search(dc))
- // )
+ if (column > 0 && Rna.isClosingParenthesis(dc))
{
if (diffupstream)
* @param column
* @return
*/
- public int[] getProfileFor(AlignmentAnnotation aa, int column)
+ int[] getProfileFor(AlignmentAnnotation aa, int column)
{
// TODO : consider refactoring the global alignment calculation
// properties/rendering attributes as a global 'alignment group' which holds
validEnd);
break;
}
-
+ // no break if isRNA - falls through to drawNotCanonicalAnnot!
case 'E':
if (!isRNA)
{
validEnd);
break;
}
+ // no break if isRNA - fall through to drawNotCanonicalAnnot!
case '{':
case '}':
{
validRes = true;
}
-
// x ++;
if (row.hasIcons)
startRes, column, validRes, validEnd);
break;
}
+ // no break if isRNA - fall through to drawNotCanonicalAnnot!
case 'E':
if (!isRNA)
startRes, column, validRes, validEnd);
break;
}
+ // no break if isRNA - fall through to drawNotCanonicalAnnot!
case '(':
case ')': // Stem case for RNA secondary structure
private Color sdNOTCANONICAL_COLOUR;
- public void drawGlyphLine(Graphics g, Annotation[] row, int lastSSX,
- int x, int y, int iconOffset, int startRes, int column,
+ void drawGlyphLine(Graphics g, Annotation[] row, int lastSSX, int x,
+ int y, int iconOffset, int startRes, int column,
boolean validRes, boolean validEnd)
{
g.setColor(GLYPHLINE_COLOR);
g.fillRect(lastSSX, y + 6 + iconOffset, (x * charWidth) - lastSSX, 2);
}
- public void drawSheetAnnot(Graphics g, Annotation[] row,
+ void drawSheetAnnot(Graphics g, Annotation[] row,
int lastSSX, int x, int y, int iconOffset, int startRes, int column,
boolean validRes, boolean validEnd)
}
- public void drawHelixAnnot(Graphics g, Annotation[] row, int lastSSX,
- int x, int y, int iconOffset, int startRes, int column,
+ void drawHelixAnnot(Graphics g, Annotation[] row, int lastSSX, int x,
+ int y, int iconOffset, int startRes, int column,
boolean validRes, boolean validEnd)
{
g.setColor(HELIX_COLOUR);
g.fillRect(x1, y + 4 + iconOffset, x2 - x1, 8);
}
- public void drawLineGraph(Graphics g, AlignmentAnnotation _aa,
+ void drawLineGraph(Graphics g, AlignmentAnnotation _aa,
Annotation[] aa_annotations, int sRes, int eRes, int y,
float min, float max, int graphHeight)
{
}
}
- public void drawBarGraph(Graphics g, AlignmentAnnotation _aa,
+ void drawBarGraph(Graphics g, AlignmentAnnotation _aa,
Annotation[] aa_annotations, int sRes, int eRes, float min,
float max, int y, boolean renderHistogram, boolean renderProfile,
boolean normaliseProfile)
scl = htn * scale * profl[c++];
lm = ofont.getLineMetrics(dc, 0, 1, g.getFontMetrics()
.getFontRenderContext());
- g.setFont(ofont.deriveFont(AffineTransform.getScaleInstance(
- wdth, scl / lm.getAscent())));
+ Font font = ofont.deriveFont(AffineTransform.getScaleInstance(
+ wdth, scl / lm.getAscent()));
+ g.setFont(font);
lm = g.getFontMetrics().getLineMetrics(dc, 0, 1, g);
// Debug - render boxes around characters
*/
public class ScaleRenderer
{
+ public final class ScaleMark
+ {
+ public final boolean major;
+
+ public final int column;
+
+ public final String text;
+
+ ScaleMark(boolean isMajor, int col, String txt)
+ {
+ major = isMajor;
+ column = col;
+ text = txt;
+ }
+ }
+
/**
* calculate positions markers on the alignment ruler
*
* left-most column in visible view
* @param endx
* - right-most column in visible view
- * @return List { Object { .. } } Boolean: true/false for major/minor mark,
- * Integer: marker position in alignment column coords, String: null
- * or a String to be rendered at the position.
+ * @return List of ScaleMark holding boolean: true/false for major/minor mark,
+ * marker position in alignment column coords, a String to be rendered
+ * at the position (or null)
*/
- public static List<Object[]> calculateMarks(AlignViewportI av,
- int startx, int endx)
+ public List<ScaleMark> calculateMarks(AlignViewportI av, int startx,
+ int endx)
{
- new ArrayList<Object[]>();
-
int scalestartx = (startx / 10) * 10;
SequenceI refSeq = av.getAlignment().getSeqrep();
{
scalestartx += 5;
}
- List<Object[]> marks = new ArrayList<Object[]>();
+ List<ScaleMark> marks = new ArrayList<ScaleMark>();
String string;
int refN, iadj;
// todo: add a 'reference origin column' to set column number relative to
for (int i = scalestartx; i < endx; i += 5)
{
- Object[] amark = new Object[3];
if (((i - refSp) % 10) == 0)
{
if (refSeq == null)
string = String.valueOf(refN) + refSeq.getCharAt(iadj);
}
}
- amark[0] = Boolean.TRUE;
- amark[1] = Integer.valueOf(i - startx - 1);
- amark[2] = string;
-
+ marks.add(new ScaleMark(true, i - startx - 1, string));
}
else
{
- amark[0] = Boolean.FALSE;
- amark[1] = Integer.valueOf(i - startx - 1);
- amark[2] = null;
+ marks.add(new ScaleMark(false, i - startx - 1, null));
}
- marks.add(amark);
}
return marks;
}
*/
package jalview.renderer.seqfeatures;
+import jalview.api.AlignViewportI;
import jalview.datamodel.SequenceFeature;
import jalview.datamodel.SequenceI;
import jalview.viewmodel.seqfeatures.FeatureRendererModel;
private Integer currentColour;
+ /**
+ * Constructor given a viewport
+ *
+ * @param viewport
+ */
+ public FeatureRenderer(AlignViewportI viewport)
+ {
+ this.av = viewport;
+ }
+
protected void updateAvConfig()
{
av_charHeight = av.getCharHeight();
*/
package jalview.schemes;
-import jalview.analysis.AAFrequency;
import jalview.datamodel.AnnotatedCollectionI;
import jalview.datamodel.SequenceCollectionI;
import jalview.datamodel.SequenceI;
+import jalview.util.Comparison;
import java.awt.Color;
import java.util.Map;
public class Blosum62ColourScheme extends ResidueColourScheme
{
+ private static final Color LIGHT_BLUE = new Color(204, 204, 255);
+ private static final Color DARK_BLUE = new Color(154, 154, 255);
+
public Blosum62ColourScheme()
{
super();
Color currentColour;
- if (!jalview.util.Comparison.isGap(res))
+ if (!Comparison.isGap(res))
{
- String max = (String) consensus[j].get(AAFrequency.MAXRESIDUE);
+ /*
+ * test if this is the consensus (or joint consensus) residue
+ */
+ String max = consensus[j].getModalResidue();
if (max.indexOf(res) > -1)
{
- // TODO use a constant here?
- currentColour = new Color(154, 154, 255);
+ currentColour = DARK_BLUE;
}
else
{
if (c > 0)
{
- // TODO use a constant here?
- currentColour = new Color(204, 204, 255);
+ currentColour = LIGHT_BLUE;
}
else
{
*/
package jalview.schemes;
+import jalview.analysis.Profile;
import jalview.datamodel.AnnotatedCollectionI;
import jalview.datamodel.SequenceCollectionI;
import jalview.datamodel.SequenceI;
/**
* assign the given consensus profile for the colourscheme
*/
- public void setConsensus(java.util.Hashtable[] h);
+ public void setConsensus(Profile[] hconsensus);
/**
* assign the given conservation to the colourscheme
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
package jalview.schemes;
import jalview.api.FeatureColourI;
setAutoScaled(fc.isAutoScaled());
setColourByLabel(fc.isColourByLabel());
}
-
+
/**
* Copy constructor with new min/max ranges
+ *
* @param fc
* @param min
* @param max
setGraduatedColour(false);
}
}
+
@Override
public boolean isBelowThreshold()
{
{
scl = 1f;
}
- return new Color(minRed + scl * deltaRed, minGreen + scl * deltaGreen, minBlue + scl * deltaBlue);
+ return new Color(minRed + scl * deltaRed, minGreen + scl * deltaGreen,
+ minBlue + scl * deltaBlue);
}
/**
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
package jalview.schemes;
import jalview.api.FeatureColourI;
package jalview.schemes;
import jalview.analysis.Conservation;
-
-import java.util.Hashtable;
+import jalview.analysis.Profile;
/**
* Colourscheme that takes its colours from some other colourscheme
}
@Override
- public void setConsensus(Hashtable[] consensus)
+ public void setConsensus(Profile[] consensus)
{
if (colourScheme != null)
{
*/
package jalview.schemes;
-import jalview.analysis.AAFrequency;
import jalview.datamodel.SequenceGroup;
import jalview.datamodel.SequenceI;
+import jalview.util.Comparison;
import java.awt.Color;
return Color.white;
}
- if ((Integer
- .parseInt(consensus[j].get(AAFrequency.MAXCOUNT).toString()) != -1)
- && consensus[j].contains(String.valueOf(c)))
+ /*
+ * test whether this is the consensus (or joint consensus) residue
+ */
+ boolean matchesConsensus = consensus[j].getModalResidue().contains(
+ String.valueOf(c));
+ if (matchesConsensus)
{
- sc = ((Float) consensus[j].get(ignoreGaps)).floatValue();
+ sc = consensus[j].getPercentageIdentity(ignoreGaps);
- if (!jalview.util.Comparison.isGap(c))
+ if (!Comparison.isGap(c))
{
for (int i = 0; i < thresholds.length; i++)
{
if (sc > thresholds[i])
{
currentColour = pidColours[i];
-
break;
}
}
*/
package jalview.schemes;
-import jalview.analysis.AAFrequency;
import jalview.analysis.Conservation;
+import jalview.analysis.Profile;
import jalview.datamodel.AnnotatedCollectionI;
import jalview.datamodel.SequenceCollectionI;
import jalview.datamodel.SequenceI;
+import jalview.util.ColorUtils;
+import jalview.util.Comparison;
import jalview.util.MessageManager;
import java.awt.Color;
-import java.util.Hashtable;
import java.util.Map;
/**
int threshold = 0;
/* Set when threshold colouring to either pid_gaps or pid_nogaps */
- protected String ignoreGaps = AAFrequency.PID_GAPS;
+ protected boolean ignoreGaps = false;
- /** Consenus as a hashtable array */
- Hashtable[] consensus;
+ /*
+ * Consensus data indexed by column
+ */
+ Profile[] consensus;
- /** Conservation string as a char array */
+ /*
+ * Conservation string as a char array
+ */
char[] conservation;
- int conservationLength = 0;
-
- /** DOCUMENT ME!! */
+ /*
+ * The conservation slider percentage setting
+ */
int inc = 30;
/**
/**
* Find a colour without an index in a sequence
*/
+ @Override
public Color findColour(char c)
{
return colors == null ? Color.white : colors[symbolIndex[c]];
*
* @return Returns the percentage threshold
*/
+ @Override
public int getThreshold()
{
return threshold;
}
/**
- * DOCUMENT ME!
+ * Sets the percentage consensus threshold value, and whether gaps are ignored
+ * in percentage identity calculation
*
- * @param ct
- * DOCUMENT ME!
+ * @param consensusThreshold
+ * @param ignoreGaps
*/
- public void setThreshold(int ct, boolean ignoreGaps)
+ @Override
+ public void setThreshold(int consensusThreshold, boolean ignoreGaps)
{
- threshold = ct;
- if (ignoreGaps)
- {
- this.ignoreGaps = AAFrequency.PID_NOGAPS;
- }
- else
- {
- this.ignoreGaps = AAFrequency.PID_GAPS;
- }
+ threshold = consensusThreshold;
+ this.ignoreGaps = ignoreGaps;
}
/**
- * DOCUMENT ME!
+ * Answers true if there is a consensus profile for the specified column, and
+ * the given residue matches the consensus (or joint consensus) residue for
+ * the column, and the percentage identity for the profile is equal to or
+ * greater than the current threshold; else answers false. The percentage
+ * calculation depends on whether or not we are ignoring gapped sequences.
*
- * @param s
- * DOCUMENT ME!
- * @param j
- * DOCUMENT ME!
+ * @param residue
+ * @param column
+ * (index into consensus profiles)
*
- * @return DOCUMENT ME!
+ * @return
+ * @see #setThreshold(int, boolean)
*/
- public boolean aboveThreshold(char c, int j)
+ public boolean aboveThreshold(char residue, int column)
{
- if ('a' <= c && c <= 'z')
+ if ('a' <= residue && residue <= 'z')
{
// TO UPPERCASE !!!
// Faster than toUpperCase
- c -= ('a' - 'A');
+ residue -= ('a' - 'A');
}
- if (consensus == null || consensus.length < j || consensus[j] == null)
+ if (consensus == null || consensus.length < column
+ || consensus[column] == null)
{
return false;
}
- if ((((Integer) consensus[j].get(AAFrequency.MAXCOUNT)).intValue() != -1)
- && consensus[j].contains(String.valueOf(c)))
+ /*
+ * test whether this is the consensus (or joint consensus) residue
+ */
+ if (consensus[column].getModalResidue().contains(
+ String.valueOf(residue)))
{
- if (((Float) consensus[j].get(ignoreGaps)).floatValue() >= threshold)
+ if (consensus[column].getPercentageIdentity(ignoreGaps) >= threshold)
{
return true;
}
return false;
}
+ @Override
public boolean conservationApplied()
{
return conservationColouring;
conservationColouring = conservationApplied;
}
+ @Override
public void setConservationInc(int i)
{
inc = i;
}
+ @Override
public int getConservationInc()
{
return inc;
* @param consensus
* DOCUMENT ME!
*/
- public void setConsensus(Hashtable[] consensus)
+ @Override
+ public void setConsensus(Profile[] consensus)
{
if (consensus == null)
{
this.consensus = consensus;
}
+ @Override
public void setConservation(Conservation cons)
{
if (cons == null)
else
{
conservationColouring = true;
- int i, iSize = cons.getConsSequence().getLength();
+ int iSize = cons.getConsSequence().getLength();
conservation = new char[iSize];
- for (i = 0; i < iSize; i++)
+ for (int i = 0; i < iSize; i++)
{
conservation[i] = cons.getConsSequence().getCharAt(i);
}
- conservationLength = conservation.length;
}
}
/**
- * DOCUMENT ME!
+ * Applies a combination of column conservation score, and conservation
+ * percentage slider, to 'bleach' out the residue colours towards white.
+ * <p>
+ * If a column is fully conserved (identical residues, conservation score 11,
+ * shown as *), or all 10 physico-chemical properties are conserved
+ * (conservation score 10, shown as +), then the colour is left unchanged.
+ * <p>
+ * Otherwise a 'bleaching' factor is computed and applied to the colour. This
+ * is designed to fade colours for scores of 0-9 completely to white at slider
+ * positions ranging from 18% - 100% respectively.
*
- * @param s
- * DOCUMENT ME!
- * @param i
- * DOCUMENT ME!
+ * @param currentColour
+ * @param column
*
- * @return DOCUMENT ME!
+ * @return bleached (or unmodified) colour
*/
-
- Color applyConservation(Color currentColour, int i)
+ Color applyConservation(Color currentColour, int column)
{
+ if (conservation == null || conservation.length <= column)
+ {
+ return currentColour;
+ }
+ char conservationScore = conservation[column];
+
+ /*
+ * if residues are fully conserved (* or 11), or all properties
+ * are conserved (+ or 10), leave colour unchanged
+ */
+ if (conservationScore == '*' || conservationScore == '+'
+ || conservationScore == (char) 10
+ || conservationScore == (char) 11)
+ {
+ return currentColour;
+ }
- if ((conservationLength > i) && (conservation[i] != '*')
- && (conservation[i] != '+'))
+ if (Comparison.isGap(conservationScore))
{
- if (jalview.util.Comparison.isGap(conservation[i]))
- {
- currentColour = Color.white;
- }
- else
- {
- float t = 11 - (conservation[i] - '0');
- if (t == 0)
- {
- return Color.white;
- }
-
- int red = currentColour.getRed();
- int green = currentColour.getGreen();
- int blue = currentColour.getBlue();
-
- int dr = 255 - red;
- int dg = 255 - green;
- int db = 255 - blue;
-
- dr *= t / 10f;
- dg *= t / 10f;
- db *= t / 10f;
-
- red += (inc / 20f) * dr;
- green += (inc / 20f) * dg;
- blue += (inc / 20f) * db;
-
- if (red > 255 || green > 255 || blue > 255)
- {
- currentColour = Color.white;
- }
- else
- {
- currentColour = new Color(red, green, blue);
- }
- }
+ return Color.white;
}
- return currentColour;
+
+ /*
+ * convert score 0-9 to a bleaching factor 1.1 - 0.2
+ */
+ float bleachFactor = (11 - (conservationScore - '0')) / 10f;
+
+ /*
+ * scale this up by 0-5 (percentage slider / 20)
+ * as a result, scores of: 0 1 2 3 4 5 6 7 8 9
+ * fade to white at slider value: 18 20 22 25 29 33 40 50 67 100%
+ */
+ bleachFactor *= (inc / 20f);
+
+ return ColorUtils.bleachColour(currentColour, bleachFactor);
}
@Override
import java.awt.Color;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Hashtable;
static
{
- aa3Hash.put("ALA", new Integer(0));
- aa3Hash.put("ARG", new Integer(1));
- aa3Hash.put("ASN", new Integer(2));
- aa3Hash.put("ASP", new Integer(3)); // D
- aa3Hash.put("CYS", new Integer(4));
- aa3Hash.put("GLN", new Integer(5)); // Q
- aa3Hash.put("GLU", new Integer(6)); // E
- aa3Hash.put("GLY", new Integer(7));
- aa3Hash.put("HIS", new Integer(8));
- aa3Hash.put("ILE", new Integer(9));
- aa3Hash.put("LEU", new Integer(10));
- aa3Hash.put("LYS", new Integer(11));
- aa3Hash.put("MET", new Integer(12));
- aa3Hash.put("PHE", new Integer(13));
- aa3Hash.put("PRO", new Integer(14));
- aa3Hash.put("SER", new Integer(15));
- aa3Hash.put("THR", new Integer(16));
- aa3Hash.put("TRP", new Integer(17));
- aa3Hash.put("TYR", new Integer(18));
- aa3Hash.put("VAL", new Integer(19));
+ aa3Hash.put("ALA", Integer.valueOf(0));
+ aa3Hash.put("ARG", Integer.valueOf(1));
+ aa3Hash.put("ASN", Integer.valueOf(2));
+ aa3Hash.put("ASP", Integer.valueOf(3)); // D
+ aa3Hash.put("CYS", Integer.valueOf(4));
+ aa3Hash.put("GLN", Integer.valueOf(5)); // Q
+ aa3Hash.put("GLU", Integer.valueOf(6)); // E
+ aa3Hash.put("GLY", Integer.valueOf(7));
+ aa3Hash.put("HIS", Integer.valueOf(8));
+ aa3Hash.put("ILE", Integer.valueOf(9));
+ aa3Hash.put("LEU", Integer.valueOf(10));
+ aa3Hash.put("LYS", Integer.valueOf(11));
+ aa3Hash.put("MET", Integer.valueOf(12));
+ aa3Hash.put("PHE", Integer.valueOf(13));
+ aa3Hash.put("PRO", Integer.valueOf(14));
+ aa3Hash.put("SER", Integer.valueOf(15));
+ aa3Hash.put("THR", Integer.valueOf(16));
+ aa3Hash.put("TRP", Integer.valueOf(17));
+ aa3Hash.put("TYR", Integer.valueOf(18));
+ aa3Hash.put("VAL", Integer.valueOf(19));
// IUB Nomenclature for ambiguous peptides
- aa3Hash.put("ASX", new Integer(20)); // "B";
- aa3Hash.put("GLX", new Integer(21)); // Z
- aa3Hash.put("XAA", new Integer(22)); // X unknown
- aa3Hash.put("-", new Integer(23));
- aa3Hash.put("*", new Integer(23));
- aa3Hash.put(".", new Integer(23));
- aa3Hash.put(" ", new Integer(23));
- aa3Hash.put("Gap", new Integer(23));
- aa3Hash.put("UR3", new Integer(24));
+ aa3Hash.put("ASX", Integer.valueOf(20)); // "B";
+ aa3Hash.put("GLX", Integer.valueOf(21)); // Z
+ aa3Hash.put("XAA", Integer.valueOf(22)); // X unknown
+ aa3Hash.put("-", Integer.valueOf(23));
+ aa3Hash.put("*", Integer.valueOf(23));
+ aa3Hash.put(".", Integer.valueOf(23));
+ aa3Hash.put(" ", Integer.valueOf(23));
+ aa3Hash.put("Gap", Integer.valueOf(23));
+ aa3Hash.put("UR3", Integer.valueOf(24));
}
static
public static final Color midBlue = new Color(100, 100, 255);
- public static final Vector scaleColours = new Vector();
-
- static
- {
- scaleColours.addElement(new Color(114, 0, 147));
- scaleColours.addElement(new Color(156, 0, 98));
- scaleColours.addElement(new Color(190, 0, 0));
- scaleColours.addElement(Color.red);
- scaleColours.addElement(new Color(255, 125, 0));
- scaleColours.addElement(Color.orange);
- scaleColours.addElement(new Color(255, 194, 85));
- scaleColours.addElement(Color.yellow);
- scaleColours.addElement(new Color(255, 255, 181));
- scaleColours.addElement(Color.white);
- }
-
- public static final Color[] taylor = { new Color(204, 255, 0), // A
- // Greenish-yellowy-yellow
+ // not currently in use
+ // public static final Vector<Color> scaleColours = new Vector<Color>();
+ // static
+ // {
+ // scaleColours.addElement(new Color(114, 0, 147));
+ // scaleColours.addElement(new Color(156, 0, 98));
+ // scaleColours.addElement(new Color(190, 0, 0));
+ // scaleColours.addElement(Color.red);
+ // scaleColours.addElement(new Color(255, 125, 0));
+ // scaleColours.addElement(Color.orange);
+ // scaleColours.addElement(new Color(255, 194, 85));
+ // scaleColours.addElement(Color.yellow);
+ // scaleColours.addElement(new Color(255, 255, 181));
+ // scaleColours.addElement(Color.white);
+ // }
+
+ public static final Color[] taylor = { new Color(204, 255, 0),
+ // A Greenish-yellowy-yellow
new Color(0, 0, 255), // R Blueish-bluey-blue
new Color(204, 0, 255), // N Blueish-reddy-blue
new Color(255, 0, 0), // D Reddish-reddy-red
{ -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8,
-8, -8, -8, -8, -8, -8, 1 }, };
- public static final Hashtable ssHash = new Hashtable(); // stores the number
- // value of the aa
-
- static
- {
- ssHash.put("H", Color.magenta);
- ssHash.put("E", Color.yellow);
- ssHash.put("-", Color.white);
- ssHash.put(".", Color.white);
- ssHash.put("S", Color.cyan);
- ssHash.put("T", Color.blue);
- ssHash.put("G", Color.pink);
- ssHash.put("I", Color.pink);
- ssHash.put("B", Color.yellow);
- }
+ // not currently used
+ // public static final Map<String, Color> ssHash = new Hashtable<String,
+ // Color>();
+ // static
+ // {
+ // ssHash.put("H", Color.magenta);
+ // ssHash.put("E", Color.yellow);
+ // ssHash.put("-", Color.white);
+ // ssHash.put(".", Color.white);
+ // ssHash.put("S", Color.cyan);
+ // ssHash.put("T", Color.blue);
+ // ssHash.put("G", Color.pink);
+ // ssHash.put("I", Color.pink);
+ // ssHash.put("B", Color.yellow);
+ // }
/*
* new Color(60, 136, 238), // U Color.white, // I Color.white, // X
scoreMatrices.put("BLOSUM62", new ScoreMatrix("BLOSUM62", BLOSUM62, 0));
scoreMatrices.put("PAM250", new ScoreMatrix("PAM250", PAM250, 0));
scoreMatrices.put("DNA", new ScoreMatrix("DNA", DNA, 1));
-
}
public static final Color[] pidColours = { midBlue,
public static final float[] pidThresholds = { 80, 60, 40, };
- public static Map<String, List<String>> codonHash = new HashMap<String, List<String>>();
-
- private static List<String> Lys = new ArrayList<String>();
-
- private static List<String> Asn = new ArrayList<String>();
-
- private static List<String> Gln = new ArrayList<String>();
-
- private static List<String> His = new ArrayList<String>();
-
- private static List<String> Glu = new ArrayList<String>();
-
- private static List<String> Asp = new ArrayList<String>();
-
- private static List<String> Tyr = new ArrayList<String>();
-
- private static List<String> Thr = new ArrayList<String>();
-
- private static List<String> Pro = new ArrayList<String>();
-
- private static List<String> Ala = new ArrayList<String>();
-
- private static List<String> Ser = new ArrayList<String>();
-
- private static List<String> Arg = new ArrayList<String>();
-
- private static List<String> Gly = new ArrayList<String>();
-
- private static List<String> Trp = new ArrayList<String>();
-
- private static List<String> Cys = new ArrayList<String>();
-
- private static List<String> Ile = new ArrayList<String>();
-
- private static List<String> Met = new ArrayList<String>();
-
- private static List<String> Leu = new ArrayList<String>();
-
- private static List<String> Val = new ArrayList<String>();
-
- private static List<String> Phe = new ArrayList<String>();
-
- public static List<String> STOP = new ArrayList<String>();
+ public static List<String> STOP = Arrays.asList("TGA", "TAA", "TAG");
public static String START = "ATG";
- static
- {
- codonHash.put("K", Lys);
- codonHash.put("N", Asn);
- codonHash.put("Q", Gln);
- codonHash.put("H", His);
- codonHash.put("E", Glu);
- codonHash.put("D", Asp);
- codonHash.put("Y", Tyr);
- codonHash.put("T", Thr);
- codonHash.put("P", Pro);
- codonHash.put("A", Ala);
- codonHash.put("S", Ser);
- codonHash.put("R", Arg);
- codonHash.put("G", Gly);
- codonHash.put("W", Trp);
- codonHash.put("C", Cys);
- codonHash.put("I", Ile);
- codonHash.put("M", Met);
- codonHash.put("L", Leu);
- codonHash.put("V", Val);
- codonHash.put("F", Phe);
- codonHash.put("STOP", STOP);
- }
-
/**
* Nucleotide Ambiguity Codes
*/
// make all codons for this combination
char allres[][] = new char[tpos.length][];
String _acodon = "";
- char _anuc;
for (ipos = 0; ipos < tpos.length; ipos++)
{
if (acodon[ipos].length == 0 || tpos[ipos] < 0)
}
}
}
-
- }
-
- static
- {
- Lys.add("AAA");
- Lys.add("AAG");
- Asn.add("AAC");
- Asn.add("AAT");
-
- Gln.add("CAA");
- Gln.add("CAG");
- His.add("CAC");
- His.add("CAT");
-
- Glu.add("GAA");
- Glu.add("GAG");
- Asp.add("GAC");
- Asp.add("GAT");
-
- Tyr.add("TAC");
- Tyr.add("TAT");
-
- Thr.add("ACA");
- Thr.add("ACG");
- Thr.add("ACC");
- Thr.add("ACT");
-
- Pro.add("CCA");
- Pro.add("CCG");
- Pro.add("CCC");
- Pro.add("CCT");
-
- Ala.add("GCA");
- Ala.add("GCG");
- Ala.add("GCC");
- Ala.add("GCT");
-
- Ser.add("TCA");
- Ser.add("TCG");
- Ser.add("TCC");
- Ser.add("TCT");
- Ser.add("AGC");
- Ser.add("AGT");
-
- Arg.add("AGA");
- Arg.add("AGG");
- Arg.add("CGA");
- Arg.add("CGG");
- Arg.add("CGC");
- Arg.add("CGT");
-
- Gly.add("GGA");
- Gly.add("GGG");
- Gly.add("GGC");
- Gly.add("GGT");
-
- STOP.add("TGA");
- STOP.add("TAA");
- STOP.add("TAG");
-
- Trp.add("TGG");
-
- Cys.add("TGC");
- Cys.add("TGT");
-
- Ile.add("ATA");
- Ile.add("ATC");
- Ile.add("ATT");
-
- Met.add("ATG");
-
- Leu.add("CTA");
- Leu.add("CTG");
- Leu.add("CTC");
- Leu.add("CTT");
- Leu.add("TTA");
- Leu.add("TTG");
-
- Val.add("GTA");
- Val.add("GTG");
- Val.add("GTC");
- Val.add("GTT");
-
- Phe.add("TTC");
- Phe.add("TTT");
}
// Stores residue codes/names and colours and other things
- public static Hashtable propHash = new Hashtable();
+ public static Map<String, Map<String, Integer>> propHash = new Hashtable<String, Map<String, Integer>>();
- public static Hashtable hydrophobic = new Hashtable();
+ public static Map<String, Integer> hydrophobic = new Hashtable<String, Integer>();
- public static Hashtable polar = new Hashtable();
+ public static Map<String, Integer> polar = new Hashtable<String, Integer>();
- public static Hashtable small = new Hashtable();
+ public static Map<String, Integer> small = new Hashtable<String, Integer>();
- public static Hashtable positive = new Hashtable();
+ public static Map<String, Integer> positive = new Hashtable<String, Integer>();
- public static Hashtable negative = new Hashtable();
+ public static Map<String, Integer> negative = new Hashtable<String, Integer>();
- public static Hashtable charged = new Hashtable();
+ public static Map<String, Integer> charged = new Hashtable<String, Integer>();
- public static Hashtable aromatic = new Hashtable();
+ public static Map<String, Integer> aromatic = new Hashtable<String, Integer>();
- public static Hashtable aliphatic = new Hashtable();
+ public static Map<String, Integer> aliphatic = new Hashtable<String, Integer>();
- public static Hashtable tiny = new Hashtable();
+ public static Map<String, Integer> tiny = new Hashtable<String, Integer>();
- public static Hashtable proline = new Hashtable();
+ public static Map<String, Integer> proline = new Hashtable<String, Integer>();
static
{
- hydrophobic.put("I", new Integer(1));
- hydrophobic.put("L", new Integer(1));
- hydrophobic.put("V", new Integer(1));
- hydrophobic.put("C", new Integer(1));
- hydrophobic.put("A", new Integer(1));
- hydrophobic.put("G", new Integer(1));
- hydrophobic.put("M", new Integer(1));
- hydrophobic.put("F", new Integer(1));
- hydrophobic.put("Y", new Integer(1));
- hydrophobic.put("W", new Integer(1));
- hydrophobic.put("H", new Integer(1));
- hydrophobic.put("K", new Integer(1));
- hydrophobic.put("X", new Integer(1));
- hydrophobic.put("-", new Integer(1));
- hydrophobic.put("*", new Integer(1));
- hydrophobic.put("R", new Integer(0));
- hydrophobic.put("E", new Integer(0));
- hydrophobic.put("Q", new Integer(0));
- hydrophobic.put("D", new Integer(0));
- hydrophobic.put("N", new Integer(0));
- hydrophobic.put("S", new Integer(0));
- hydrophobic.put("T", new Integer(0));
- hydrophobic.put("P", new Integer(0));
+ hydrophobic.put("I", Integer.valueOf(1));
+ hydrophobic.put("L", Integer.valueOf(1));
+ hydrophobic.put("V", Integer.valueOf(1));
+ hydrophobic.put("C", Integer.valueOf(1));
+ hydrophobic.put("A", Integer.valueOf(1));
+ hydrophobic.put("G", Integer.valueOf(1));
+ hydrophobic.put("M", Integer.valueOf(1));
+ hydrophobic.put("F", Integer.valueOf(1));
+ hydrophobic.put("Y", Integer.valueOf(1));
+ hydrophobic.put("W", Integer.valueOf(1));
+ hydrophobic.put("H", Integer.valueOf(1));
+ hydrophobic.put("K", Integer.valueOf(1));
+ hydrophobic.put("X", Integer.valueOf(1));
+ hydrophobic.put("-", Integer.valueOf(1));
+ hydrophobic.put("*", Integer.valueOf(1));
+ hydrophobic.put("R", Integer.valueOf(0));
+ hydrophobic.put("E", Integer.valueOf(0));
+ hydrophobic.put("Q", Integer.valueOf(0));
+ hydrophobic.put("D", Integer.valueOf(0));
+ hydrophobic.put("N", Integer.valueOf(0));
+ hydrophobic.put("S", Integer.valueOf(0));
+ hydrophobic.put("T", Integer.valueOf(0));
+ hydrophobic.put("P", Integer.valueOf(0));
}
static
{
- polar.put("Y", new Integer(1));
- polar.put("W", new Integer(1));
- polar.put("H", new Integer(1));
- polar.put("K", new Integer(1));
- polar.put("R", new Integer(1));
- polar.put("E", new Integer(1));
- polar.put("Q", new Integer(1));
- polar.put("D", new Integer(1));
- polar.put("N", new Integer(1));
- polar.put("S", new Integer(1));
- polar.put("T", new Integer(1));
- polar.put("X", new Integer(1));
- polar.put("-", new Integer(1));
- polar.put("*", new Integer(1));
- polar.put("I", new Integer(0));
- polar.put("L", new Integer(0));
- polar.put("V", new Integer(0));
- polar.put("C", new Integer(0));
- polar.put("A", new Integer(0));
- polar.put("G", new Integer(0));
- polar.put("M", new Integer(0));
- polar.put("F", new Integer(0));
- polar.put("P", new Integer(0));
+ polar.put("Y", Integer.valueOf(1));
+ polar.put("W", Integer.valueOf(1));
+ polar.put("H", Integer.valueOf(1));
+ polar.put("K", Integer.valueOf(1));
+ polar.put("R", Integer.valueOf(1));
+ polar.put("E", Integer.valueOf(1));
+ polar.put("Q", Integer.valueOf(1));
+ polar.put("D", Integer.valueOf(1));
+ polar.put("N", Integer.valueOf(1));
+ polar.put("S", Integer.valueOf(1));
+ polar.put("T", Integer.valueOf(1));
+ polar.put("X", Integer.valueOf(1));
+ polar.put("-", Integer.valueOf(1));
+ polar.put("*", Integer.valueOf(1));
+ polar.put("I", Integer.valueOf(0));
+ polar.put("L", Integer.valueOf(0));
+ polar.put("V", Integer.valueOf(0));
+ polar.put("C", Integer.valueOf(0));
+ polar.put("A", Integer.valueOf(0));
+ polar.put("G", Integer.valueOf(0));
+ polar.put("M", Integer.valueOf(0));
+ polar.put("F", Integer.valueOf(0));
+ polar.put("P", Integer.valueOf(0));
}
static
{
- small.put("I", new Integer(0));
- small.put("L", new Integer(0));
- small.put("V", new Integer(1));
- small.put("C", new Integer(1));
- small.put("A", new Integer(1));
- small.put("G", new Integer(1));
- small.put("M", new Integer(0));
- small.put("F", new Integer(0));
- small.put("Y", new Integer(0));
- small.put("W", new Integer(0));
- small.put("H", new Integer(0));
- small.put("K", new Integer(0));
- small.put("R", new Integer(0));
- small.put("E", new Integer(0));
- small.put("Q", new Integer(0));
- small.put("D", new Integer(1));
- small.put("N", new Integer(1));
- small.put("S", new Integer(1));
- small.put("T", new Integer(1));
- small.put("P", new Integer(1));
- small.put("-", new Integer(1));
- small.put("*", new Integer(1));
+ small.put("I", Integer.valueOf(0));
+ small.put("L", Integer.valueOf(0));
+ small.put("V", Integer.valueOf(1));
+ small.put("C", Integer.valueOf(1));
+ small.put("A", Integer.valueOf(1));
+ small.put("G", Integer.valueOf(1));
+ small.put("M", Integer.valueOf(0));
+ small.put("F", Integer.valueOf(0));
+ small.put("Y", Integer.valueOf(0));
+ small.put("W", Integer.valueOf(0));
+ small.put("H", Integer.valueOf(0));
+ small.put("K", Integer.valueOf(0));
+ small.put("R", Integer.valueOf(0));
+ small.put("E", Integer.valueOf(0));
+ small.put("Q", Integer.valueOf(0));
+ small.put("D", Integer.valueOf(1));
+ small.put("N", Integer.valueOf(1));
+ small.put("S", Integer.valueOf(1));
+ small.put("T", Integer.valueOf(1));
+ small.put("P", Integer.valueOf(1));
+ small.put("-", Integer.valueOf(1));
+ small.put("*", Integer.valueOf(1));
}
static
{
- positive.put("I", new Integer(0));
- positive.put("L", new Integer(0));
- positive.put("V", new Integer(0));
- positive.put("C", new Integer(0));
- positive.put("A", new Integer(0));
- positive.put("G", new Integer(0));
- positive.put("M", new Integer(0));
- positive.put("F", new Integer(0));
- positive.put("Y", new Integer(0));
- positive.put("W", new Integer(0));
- positive.put("H", new Integer(1));
- positive.put("K", new Integer(1));
- positive.put("R", new Integer(1));
- positive.put("E", new Integer(0));
- positive.put("Q", new Integer(0));
- positive.put("D", new Integer(0));
- positive.put("N", new Integer(0));
- positive.put("S", new Integer(0));
- positive.put("T", new Integer(0));
- positive.put("P", new Integer(0));
- positive.put("-", new Integer(1));
- positive.put("*", new Integer(1));
+ positive.put("I", Integer.valueOf(0));
+ positive.put("L", Integer.valueOf(0));
+ positive.put("V", Integer.valueOf(0));
+ positive.put("C", Integer.valueOf(0));
+ positive.put("A", Integer.valueOf(0));
+ positive.put("G", Integer.valueOf(0));
+ positive.put("M", Integer.valueOf(0));
+ positive.put("F", Integer.valueOf(0));
+ positive.put("Y", Integer.valueOf(0));
+ positive.put("W", Integer.valueOf(0));
+ positive.put("H", Integer.valueOf(1));
+ positive.put("K", Integer.valueOf(1));
+ positive.put("R", Integer.valueOf(1));
+ positive.put("E", Integer.valueOf(0));
+ positive.put("Q", Integer.valueOf(0));
+ positive.put("D", Integer.valueOf(0));
+ positive.put("N", Integer.valueOf(0));
+ positive.put("S", Integer.valueOf(0));
+ positive.put("T", Integer.valueOf(0));
+ positive.put("P", Integer.valueOf(0));
+ positive.put("-", Integer.valueOf(1));
+ positive.put("*", Integer.valueOf(1));
}
static
{
- negative.put("I", new Integer(0));
- negative.put("L", new Integer(0));
- negative.put("V", new Integer(0));
- negative.put("C", new Integer(0));
- negative.put("A", new Integer(0));
- negative.put("G", new Integer(0));
- negative.put("M", new Integer(0));
- negative.put("F", new Integer(0));
- negative.put("Y", new Integer(0));
- negative.put("W", new Integer(0));
- negative.put("H", new Integer(0));
- negative.put("K", new Integer(0));
- negative.put("R", new Integer(0));
- negative.put("E", new Integer(1));
- negative.put("Q", new Integer(0));
- negative.put("D", new Integer(1));
- negative.put("N", new Integer(0));
- negative.put("S", new Integer(0));
- negative.put("T", new Integer(0));
- negative.put("P", new Integer(0));
- negative.put("-", new Integer(1));
- negative.put("*", new Integer(1));
+ negative.put("I", Integer.valueOf(0));
+ negative.put("L", Integer.valueOf(0));
+ negative.put("V", Integer.valueOf(0));
+ negative.put("C", Integer.valueOf(0));
+ negative.put("A", Integer.valueOf(0));
+ negative.put("G", Integer.valueOf(0));
+ negative.put("M", Integer.valueOf(0));
+ negative.put("F", Integer.valueOf(0));
+ negative.put("Y", Integer.valueOf(0));
+ negative.put("W", Integer.valueOf(0));
+ negative.put("H", Integer.valueOf(0));
+ negative.put("K", Integer.valueOf(0));
+ negative.put("R", Integer.valueOf(0));
+ negative.put("E", Integer.valueOf(1));
+ negative.put("Q", Integer.valueOf(0));
+ negative.put("D", Integer.valueOf(1));
+ negative.put("N", Integer.valueOf(0));
+ negative.put("S", Integer.valueOf(0));
+ negative.put("T", Integer.valueOf(0));
+ negative.put("P", Integer.valueOf(0));
+ negative.put("-", Integer.valueOf(1));
+ negative.put("*", Integer.valueOf(1));
}
static
{
- charged.put("I", new Integer(0));
- charged.put("L", new Integer(0));
- charged.put("V", new Integer(0));
- charged.put("C", new Integer(0));
- charged.put("A", new Integer(0));
- charged.put("G", new Integer(0));
- charged.put("M", new Integer(0));
- charged.put("F", new Integer(0));
- charged.put("Y", new Integer(0));
- charged.put("W", new Integer(0));
- charged.put("H", new Integer(1));
- charged.put("K", new Integer(1));
- charged.put("R", new Integer(1));
- charged.put("E", new Integer(1));
- charged.put("Q", new Integer(0));
- charged.put("D", new Integer(1));
- charged.put("N", new Integer(0)); // Asparagine is polar but not charged.
- // Alternative would be charged and
- // negative (in basic form)?
- charged.put("S", new Integer(0));
- charged.put("T", new Integer(0));
- charged.put("P", new Integer(0));
- charged.put("-", new Integer(1));
- charged.put("*", new Integer(1));
+ charged.put("I", Integer.valueOf(0));
+ charged.put("L", Integer.valueOf(0));
+ charged.put("V", Integer.valueOf(0));
+ charged.put("C", Integer.valueOf(0));
+ charged.put("A", Integer.valueOf(0));
+ charged.put("G", Integer.valueOf(0));
+ charged.put("M", Integer.valueOf(0));
+ charged.put("F", Integer.valueOf(0));
+ charged.put("Y", Integer.valueOf(0));
+ charged.put("W", Integer.valueOf(0));
+ charged.put("H", Integer.valueOf(1));
+ charged.put("K", Integer.valueOf(1));
+ charged.put("R", Integer.valueOf(1));
+ charged.put("E", Integer.valueOf(1));
+ charged.put("Q", Integer.valueOf(0));
+ charged.put("D", Integer.valueOf(1));
+ charged.put("N", Integer.valueOf(0)); // Asparagine is polar but not
+ // charged.
+ // Alternative would be charged and
+ // negative (in basic form)?
+ charged.put("S", Integer.valueOf(0));
+ charged.put("T", Integer.valueOf(0));
+ charged.put("P", Integer.valueOf(0));
+ charged.put("-", Integer.valueOf(1));
+ charged.put("*", Integer.valueOf(1));
}
static
{
- aromatic.put("I", new Integer(0));
- aromatic.put("L", new Integer(0));
- aromatic.put("V", new Integer(0));
- aromatic.put("C", new Integer(0));
- aromatic.put("A", new Integer(0));
- aromatic.put("G", new Integer(0));
- aromatic.put("M", new Integer(0));
- aromatic.put("F", new Integer(1));
- aromatic.put("Y", new Integer(1));
- aromatic.put("W", new Integer(1));
- aromatic.put("H", new Integer(1));
- aromatic.put("K", new Integer(0));
- aromatic.put("R", new Integer(0));
- aromatic.put("E", new Integer(0));
- aromatic.put("Q", new Integer(0));
- aromatic.put("D", new Integer(0));
- aromatic.put("N", new Integer(0));
- aromatic.put("S", new Integer(0));
- aromatic.put("T", new Integer(0));
- aromatic.put("P", new Integer(0));
- aromatic.put("-", new Integer(1));
- aromatic.put("*", new Integer(1));
+ aromatic.put("I", Integer.valueOf(0));
+ aromatic.put("L", Integer.valueOf(0));
+ aromatic.put("V", Integer.valueOf(0));
+ aromatic.put("C", Integer.valueOf(0));
+ aromatic.put("A", Integer.valueOf(0));
+ aromatic.put("G", Integer.valueOf(0));
+ aromatic.put("M", Integer.valueOf(0));
+ aromatic.put("F", Integer.valueOf(1));
+ aromatic.put("Y", Integer.valueOf(1));
+ aromatic.put("W", Integer.valueOf(1));
+ aromatic.put("H", Integer.valueOf(1));
+ aromatic.put("K", Integer.valueOf(0));
+ aromatic.put("R", Integer.valueOf(0));
+ aromatic.put("E", Integer.valueOf(0));
+ aromatic.put("Q", Integer.valueOf(0));
+ aromatic.put("D", Integer.valueOf(0));
+ aromatic.put("N", Integer.valueOf(0));
+ aromatic.put("S", Integer.valueOf(0));
+ aromatic.put("T", Integer.valueOf(0));
+ aromatic.put("P", Integer.valueOf(0));
+ aromatic.put("-", Integer.valueOf(1));
+ aromatic.put("*", Integer.valueOf(1));
}
static
{
- aliphatic.put("I", new Integer(1));
- aliphatic.put("L", new Integer(1));
- aliphatic.put("V", new Integer(1));
- aliphatic.put("C", new Integer(0));
- aliphatic.put("A", new Integer(0));
- aliphatic.put("G", new Integer(0));
- aliphatic.put("M", new Integer(0));
- aliphatic.put("F", new Integer(0));
- aliphatic.put("Y", new Integer(0));
- aliphatic.put("W", new Integer(0));
- aliphatic.put("H", new Integer(0));
- aliphatic.put("K", new Integer(0));
- aliphatic.put("R", new Integer(0));
- aliphatic.put("E", new Integer(0));
- aliphatic.put("Q", new Integer(0));
- aliphatic.put("D", new Integer(0));
- aliphatic.put("N", new Integer(0));
- aliphatic.put("S", new Integer(0));
- aliphatic.put("T", new Integer(0));
- aliphatic.put("P", new Integer(0));
- aliphatic.put("-", new Integer(1));
- aliphatic.put("*", new Integer(1));
+ aliphatic.put("I", Integer.valueOf(1));
+ aliphatic.put("L", Integer.valueOf(1));
+ aliphatic.put("V", Integer.valueOf(1));
+ aliphatic.put("C", Integer.valueOf(0));
+ aliphatic.put("A", Integer.valueOf(0));
+ aliphatic.put("G", Integer.valueOf(0));
+ aliphatic.put("M", Integer.valueOf(0));
+ aliphatic.put("F", Integer.valueOf(0));
+ aliphatic.put("Y", Integer.valueOf(0));
+ aliphatic.put("W", Integer.valueOf(0));
+ aliphatic.put("H", Integer.valueOf(0));
+ aliphatic.put("K", Integer.valueOf(0));
+ aliphatic.put("R", Integer.valueOf(0));
+ aliphatic.put("E", Integer.valueOf(0));
+ aliphatic.put("Q", Integer.valueOf(0));
+ aliphatic.put("D", Integer.valueOf(0));
+ aliphatic.put("N", Integer.valueOf(0));
+ aliphatic.put("S", Integer.valueOf(0));
+ aliphatic.put("T", Integer.valueOf(0));
+ aliphatic.put("P", Integer.valueOf(0));
+ aliphatic.put("-", Integer.valueOf(1));
+ aliphatic.put("*", Integer.valueOf(1));
}
static
{
- tiny.put("I", new Integer(0));
- tiny.put("L", new Integer(0));
- tiny.put("V", new Integer(0));
- tiny.put("C", new Integer(0));
- tiny.put("A", new Integer(1));
- tiny.put("G", new Integer(1));
- tiny.put("M", new Integer(0));
- tiny.put("F", new Integer(0));
- tiny.put("Y", new Integer(0));
- tiny.put("W", new Integer(0));
- tiny.put("H", new Integer(0));
- tiny.put("K", new Integer(0));
- tiny.put("R", new Integer(0));
- tiny.put("E", new Integer(0));
- tiny.put("Q", new Integer(0));
- tiny.put("D", new Integer(0));
- tiny.put("N", new Integer(0));
- tiny.put("S", new Integer(1));
- tiny.put("T", new Integer(0));
- tiny.put("P", new Integer(0));
- tiny.put("-", new Integer(1));
- tiny.put("*", new Integer(1));
+ tiny.put("I", Integer.valueOf(0));
+ tiny.put("L", Integer.valueOf(0));
+ tiny.put("V", Integer.valueOf(0));
+ tiny.put("C", Integer.valueOf(0));
+ tiny.put("A", Integer.valueOf(1));
+ tiny.put("G", Integer.valueOf(1));
+ tiny.put("M", Integer.valueOf(0));
+ tiny.put("F", Integer.valueOf(0));
+ tiny.put("Y", Integer.valueOf(0));
+ tiny.put("W", Integer.valueOf(0));
+ tiny.put("H", Integer.valueOf(0));
+ tiny.put("K", Integer.valueOf(0));
+ tiny.put("R", Integer.valueOf(0));
+ tiny.put("E", Integer.valueOf(0));
+ tiny.put("Q", Integer.valueOf(0));
+ tiny.put("D", Integer.valueOf(0));
+ tiny.put("N", Integer.valueOf(0));
+ tiny.put("S", Integer.valueOf(1));
+ tiny.put("T", Integer.valueOf(0));
+ tiny.put("P", Integer.valueOf(0));
+ tiny.put("-", Integer.valueOf(1));
+ tiny.put("*", Integer.valueOf(1));
}
static
{
- proline.put("I", new Integer(0));
- proline.put("L", new Integer(0));
- proline.put("V", new Integer(0));
- proline.put("C", new Integer(0));
- proline.put("A", new Integer(0));
- proline.put("G", new Integer(0));
- proline.put("M", new Integer(0));
- proline.put("F", new Integer(0));
- proline.put("Y", new Integer(0));
- proline.put("W", new Integer(0));
- proline.put("H", new Integer(0));
- proline.put("K", new Integer(0));
- proline.put("R", new Integer(0));
- proline.put("E", new Integer(0));
- proline.put("Q", new Integer(0));
- proline.put("D", new Integer(0));
- proline.put("N", new Integer(0));
- proline.put("S", new Integer(0));
- proline.put("T", new Integer(0));
- proline.put("P", new Integer(1));
- proline.put("-", new Integer(1));
- proline.put("*", new Integer(1));
+ proline.put("I", Integer.valueOf(0));
+ proline.put("L", Integer.valueOf(0));
+ proline.put("V", Integer.valueOf(0));
+ proline.put("C", Integer.valueOf(0));
+ proline.put("A", Integer.valueOf(0));
+ proline.put("G", Integer.valueOf(0));
+ proline.put("M", Integer.valueOf(0));
+ proline.put("F", Integer.valueOf(0));
+ proline.put("Y", Integer.valueOf(0));
+ proline.put("W", Integer.valueOf(0));
+ proline.put("H", Integer.valueOf(0));
+ proline.put("K", Integer.valueOf(0));
+ proline.put("R", Integer.valueOf(0));
+ proline.put("E", Integer.valueOf(0));
+ proline.put("Q", Integer.valueOf(0));
+ proline.put("D", Integer.valueOf(0));
+ proline.put("N", Integer.valueOf(0));
+ proline.put("S", Integer.valueOf(0));
+ proline.put("T", Integer.valueOf(0));
+ proline.put("P", Integer.valueOf(1));
+ proline.put("-", Integer.valueOf(1));
+ proline.put("*", Integer.valueOf(1));
}
static
propMatrixF[i][j] = 0;
propMatrixPos[i][j] = 0;
propMatrixEpos[i][j] = 0;
- for (Enumeration<String> en = propHash.keys(); en.hasMoreElements();)
+ for (String ph : propHash.keySet())
{
- String ph = en.nextElement();
- Map<String, Integer> pph = (Map<String, Integer>) propHash
- .get(ph);
+ Map<String, Integer> pph = propHash.get(ph);
if (pph.get(ic) != null && pph.get(jc) != null)
{
int icp = pph.get(ic).intValue(), jcp = pph.get(jc).intValue();
return pog;
}
- public static Vector getCodons(String res)
- {
- if (codonHash.containsKey(res))
- {
- return (Vector) codonHash.get(res);
- }
-
- return null;
- }
-
public static String codonTranslate(String lccodon)
{
- if (false)
- {
- return _codonTranslate(lccodon);
- }
String cdn = codonHash2.get(lccodon.toUpperCase());
if ("*".equals(cdn))
{
return cdn;
}
- public static String _codonTranslate(String lccodon)
- {
- String codon = lccodon.toUpperCase();
- // all base ambiguity codes yield an 'X' amino acid residue
- if (codon.indexOf('X') > -1 || codon.indexOf('N') > -1)
- {
- return "X";
- }
- for (String key : codonHash.keySet())
- {
- if (codonHash.get(key).contains(codon))
- {
- return key;
- }
- }
-
- return null;
- }
-
public static int[][] getDefaultPeptideMatrix()
{
return ResidueProperties.getBLOSUM62();
return pog;
}
- public static Hashtable toDssp3State;
+ public static Hashtable<String, String> toDssp3State;
static
{
- toDssp3State = new Hashtable();
+ toDssp3State = new Hashtable<String, String>();
toDssp3State.put("H", "H");
toDssp3State.put("E", "E");
toDssp3State.put("C", " ");
String ssc = ssstring.substring(i, i + 1);
if (toDssp3State.containsKey(ssc))
{
- ss.append((String) toDssp3State.get(ssc));
+ ss.append(toDssp3State.get(ssc));
}
else
{
return ss.toString();
}
- /**
- * Used by getRNASecStrucState
- *
- */
- public static Hashtable<String, String> toRNAssState;
-
- public static boolean RNAcloseParen[] = new boolean[255];
- static
- {
- toRNAssState = new Hashtable<String, String>();
- toRNAssState.put(")", "(");
- toRNAssState.put("(", "(");
- toRNAssState.put("]", "[");
- toRNAssState.put("[", "[");
- toRNAssState.put("{", "{");
- toRNAssState.put("}", "{");
- toRNAssState.put(">", ">");
- toRNAssState.put("<", ">");
- toRNAssState.put("A", "A");
- toRNAssState.put("a", "A");
- toRNAssState.put("B", "B");
- toRNAssState.put("b", "B");
- toRNAssState.put("C", "C");
- toRNAssState.put("c", "C");
- toRNAssState.put("D", "D");
- toRNAssState.put("d", "D");
- toRNAssState.put("E", "E");
- toRNAssState.put("e", "E");
- toRNAssState.put("F", "F");
- toRNAssState.put("f", "F");
- toRNAssState.put("G", "G");
- toRNAssState.put("g", "G");
- toRNAssState.put("H", "H");
- toRNAssState.put("h", "H");
- toRNAssState.put("I", "I");
- toRNAssState.put("i", "I");
- toRNAssState.put("J", "J");
- toRNAssState.put("j", "J");
- toRNAssState.put("K", "K");
- toRNAssState.put("k", "K");
- toRNAssState.put("L", "L");
- toRNAssState.put("l", "L");
- toRNAssState.put("M", "M");
- toRNAssState.put("m", "M");
- toRNAssState.put("N", "N");
- toRNAssState.put("n", "N");
- toRNAssState.put("O", "O");
- toRNAssState.put("o", "O");
- toRNAssState.put("P", "P");
- toRNAssState.put("p", "P");
- toRNAssState.put("Q", "Q");
- toRNAssState.put("q", "Q");
- toRNAssState.put("R", "R");
- toRNAssState.put("r", "R");
- toRNAssState.put("S", "S");
- toRNAssState.put("s", "S");
- toRNAssState.put("T", "T");
- toRNAssState.put("t", "T");
- toRNAssState.put("U", "U");
- toRNAssState.put("u", "U");
- toRNAssState.put("V", "V");
- toRNAssState.put("v", "V");
- toRNAssState.put("W", "W");
- toRNAssState.put("w", "W");
- toRNAssState.put("X", "X");
- toRNAssState.put("x", "X");
- toRNAssState.put("Y", "Y");
- toRNAssState.put("y", "Y");
- toRNAssState.put("Z", "Z");
- toRNAssState.put("z", "Z");
- for (int p = 0; p < RNAcloseParen.length; p++)
- {
- RNAcloseParen[p] = false;
- }
- for (String k : toRNAssState.keySet())
- {
- RNAcloseParen[k.charAt(0)] = k.charAt(0) != toRNAssState.get(k)
- .charAt(0);
- }
- }
-
static
{
modifications.put("MSE", "MET"); // Selenomethionine
}
- public static String getCanonicalAminoAcid(String aa)
- {
- String canonical = modifications.get(aa);
- return canonical == null ? aa : canonical;
- }
-
- /**
- * translate to RNA secondary structure representation
- *
- * @param ssstring
- * @return ssstring as a RNA-state secondary structure assignment.
- */
- public static String getRNASecStrucState(String ssstring)
- {
- if (ssstring == null)
- {
- return null;
- }
- StringBuffer ss = new StringBuffer();
- for (int i = 0; i < ssstring.length(); i++)
- {
- String ssc = ssstring.substring(i, i + 1);
- if (toRNAssState.containsKey(ssc))
- {
- // valid ss character - so return it
- ss.append(ssc); // (String) toRNAssState.get(ssc));
- }
- else
- {
- ss.append(" ");
- }
- }
- return ss.toString();
- }
-
- public static boolean isCloseParenRNA(char dc)
+ public static String getCanonicalAminoAcid(String aA)
{
- return RNAcloseParen[dc];
+ String canonical = modifications.get(aA);
+ return canonical == null ? aA : canonical;
}
// main method generates perl representation of residue property hash
// / cut here
public static void main(String[] args)
{
- Hashtable aa = new Hashtable();
+ Hashtable<String, Vector<String>> aaProps = new Hashtable<String, Vector<String>>();
System.out.println("my %aa = {");
// invert property hashes
- Enumeration prop = propHash.keys();
- while (prop.hasMoreElements())
+ for (String pname : propHash.keySet())
{
- String pname = (String) prop.nextElement();
- Hashtable phash = (Hashtable) propHash.get(pname);
- Enumeration res = phash.keys();
- while (res.hasMoreElements())
+ Map<String, Integer> phash = propHash.get(pname);
+ for (String rname : phash.keySet())
{
- String rname = (String) res.nextElement();
- Vector aprops = (Vector) aa.get(rname);
+ Vector<String> aprops = aaProps.get(rname);
if (aprops == null)
{
- aprops = new Vector();
- aa.put(rname, aprops);
+ aprops = new Vector<String>();
+ aaProps.put(rname, aprops);
}
- Integer hasprop = (Integer) phash.get(rname);
+ Integer hasprop = phash.get(rname);
if (hasprop.intValue() == 1)
{
aprops.addElement(pname);
}
}
}
- Enumeration res = aa.keys();
+ Enumeration<String> res = aaProps.keys();
while (res.hasMoreElements())
{
- String rname = (String) res.nextElement();
+ String rname = res.nextElement();
System.out.print("'" + rname + "' => [");
- Enumeration props = ((Vector) aa.get(rname)).elements();
+ Enumeration<String> props = aaProps.get(rname).elements();
while (props.hasMoreElements())
{
- System.out.print("'" + (String) props.nextElement() + "'");
+ System.out.print("'" + props.nextElement() + "'");
if (props.hasMoreElements())
{
System.out.println(", ");
/**
* Returns a list of residue characters for the specified inputs
*
- * @param nucleotide
+ * @param forNucleotide
* @param includeAmbiguous
* @return
*/
- public static List<String> getResidues(boolean nucleotide,
+ public static List<String> getResidues(boolean forNucleotide,
boolean includeAmbiguous)
{
List<String> result = new ArrayList<String>();
- if (nucleotide)
+ if (forNucleotide)
{
for (String nuc : nucleotideName.keySet())
{
seqMap = new IdentityHashMap<SequenceI, Color[]>();
AnnotatedCollectionI alcontext = alignment instanceof AlignmentI ? alignment
: alignment.getContext();
+ if (alcontext == null)
+ {
+ return;
+ }
int w = 0;
for (AlignmentAnnotation al : alcontext
.findAnnotation(TCoffeeScoreFile.TCOFFEE_SCORE))
--- /dev/null
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
+package jalview.structure;
+
+import jalview.datamodel.PDBEntry;
+import jalview.datamodel.PDBEntry.Type;
+
+/**
+ * bean holding settings for structure IO. TODO: tests for validation of values
+ * TODO: tests for race conditions (all fields are static, is that correct ?)
+ *
+ * @author tcofoegbu
+ *
+ */
+public class StructureImportSettings
+{
+ /**
+ * set to true to add derived sequence annotations (temp factor read from
+ * file, or computed secondary structure) to the alignment
+ */
+ private static boolean visibleChainAnnotation = false;
+
+ /**
+ * Set true to predict secondary structure (using JMol for protein, Annotate3D
+ * for RNA)
+ */
+ private static boolean processSecStr = false;
+
+ /**
+ * Set true (with predictSecondaryStructure=true) to predict secondary
+ * structure using an external service (currently Annotate3D for RNA only)
+ */
+ private static boolean externalSecondaryStructure = false;
+
+ private static boolean showSeqFeatures = true;
+
+ public enum StructureParser
+ {
+ JMOL_PARSER, JALVIEW_PARSER
+ }
+
+ /**
+ * Determines the default file format for structure files to be downloaded
+ * from the PDB sequence fetcher. Possible options include: PDB|mmCIF
+ */
+ private static PDBEntry.Type defaultStructureFileFormat = Type.PDB;
+
+ /**
+ * Determines the parser used for parsing PDB format file. Possible options
+ * are : JMolParser|JalveiwParser
+ */
+ private static StructureParser defaultPDBFileParser = StructureParser.JMOL_PARSER;
+
+ public static void addSettings(boolean addAlignmentAnnotations,
+ boolean processSecStr, boolean externalSecStr)
+ {
+ StructureImportSettings.visibleChainAnnotation = addAlignmentAnnotations;
+ StructureImportSettings.processSecStr = processSecStr;
+ StructureImportSettings.externalSecondaryStructure = externalSecStr;
+ StructureImportSettings.showSeqFeatures = true;
+ }
+
+ public static boolean isVisibleChainAnnotation()
+ {
+ return visibleChainAnnotation;
+ }
+
+ public static void setVisibleChainAnnotation(
+ boolean visibleChainAnnotation)
+ {
+ StructureImportSettings.visibleChainAnnotation = visibleChainAnnotation;
+ }
+
+ public static boolean isProcessSecondaryStructure()
+ {
+ return processSecStr;
+ }
+
+ public static void setProcessSecondaryStructure(
+ boolean processSecondaryStructure)
+ {
+ StructureImportSettings.processSecStr = processSecondaryStructure;
+ }
+
+ public static boolean isExternalSecondaryStructure()
+ {
+ return externalSecondaryStructure;
+ }
+
+ public static void setExternalSecondaryStructure(
+ boolean externalSecondaryStructure)
+ {
+ StructureImportSettings.externalSecondaryStructure = externalSecondaryStructure;
+ }
+
+ public static boolean isShowSeqFeatures()
+ {
+ return showSeqFeatures;
+ }
+
+ public static void setShowSeqFeatures(boolean showSeqFeatures)
+ {
+ StructureImportSettings.showSeqFeatures = showSeqFeatures;
+ }
+
+ public static String getDefaultStructureFileFormat()
+ {
+ return defaultStructureFileFormat.toString();
+ }
+
+ public static void setDefaultStructureFileFormat(
+ String defaultStructureFileFormat)
+ {
+ StructureImportSettings.defaultStructureFileFormat = PDBEntry.Type
+ .valueOf(defaultStructureFileFormat.toUpperCase());
+ }
+
+ public static String getDefaultPDBFileParser()
+ {
+ return defaultPDBFileParser.toString();
+ }
+
+ public static void setDefaultPDBFileParser(
+ StructureParser defaultPDBFileParser)
+ {
+ StructureImportSettings.defaultPDBFileParser = defaultPDBFileParser;
+ }
+
+ public static void setDefaultPDBFileParser(String defaultPDBFileParser)
+ {
+ StructureImportSettings.defaultPDBFileParser = StructureParser
+ .valueOf(defaultPDBFileParser.toUpperCase());
+ }
+
+}
import jalview.datamodel.PDBEntry;
import jalview.datamodel.SearchResults;
import jalview.datamodel.SequenceI;
+import jalview.ext.jmol.JmolParser;
import jalview.gui.IProgressIndicator;
import jalview.io.AppletFormatAdapter;
import jalview.io.StructureFile;
return setMapping(true, sequence, targetChains, pdbFile, protocol);
}
-
/**
* create sequence structure mappings between each sequence and the given
* pdbFile (retrieved via the given protocol).
*/
synchronized public StructureFile setMapping(boolean forStructureView,
SequenceI[] sequenceArray, String[] targetChainIds,
- String pdbFile,
- String protocol)
+ String pdbFile, String protocol)
{
/*
* There will be better ways of doing this in the future, for now we'll use
boolean isMapUsingSIFTs = SiftsSettings.isMapWithSifts();
try
{
-
- if (pdbFile != null && isCIFFile(pdbFile))
- {
- pdb = new jalview.ext.jmol.JmolParser(addTempFacAnnot, parseSecStr,
- secStructServices, pdbFile, protocol);
- }
- else
- {
- pdb = new PDBfile(addTempFacAnnot, parseSecStr, secStructServices,
- pdbFile, protocol);
- }
+ pdb = new JmolParser(pdbFile, protocol);
if (pdb.getId() != null && pdb.getId().trim().length() > 0
&& AppletFormatAdapter.FILE.equals(protocol))
{
registerPDBFile(pdb.getId().trim(), pdbFile);
}
+ // if PDBId is unavailable then skip SIFTS mapping execution path
+ isMapUsingSIFTs = pdb.isPPDBIdAvailable();
+
} catch (Exception ex)
{
ex.printStackTrace();
{
boolean infChain = true;
final SequenceI seq = sequenceArray[s];
+ SequenceI ds = seq;
+ while (ds.getDatasetSequence() != null)
+ {
+ ds = ds.getDatasetSequence();
+ }
+
if (targetChainIds != null && targetChainIds[s] != null)
{
infChain = false;
}
ArrayList<StructureMapping> seqToStrucMapping = new ArrayList<StructureMapping>();
- if (isMapUsingSIFTs)
+ if (isMapUsingSIFTs && seq.isProtein())
{
setProgressBar(null);
setProgressBar(MessageManager
pdb, maxChain, sqmpping, maxAlignseq);
seqToStrucMapping.add(siftsMapping);
maxChain.makeExactMapping(maxAlignseq, seq);
- maxChain.transferRESNUMFeatures(seq, null);
+ maxChain.transferRESNUMFeatures(seq, null);// FIXME: is this
+ // "IEA:SIFTS" ?
maxChain.transferResidueAnnotation(siftsMapping, sqmpping);
+ ds.addPDBId(maxChain.sequence.getAllPDBEntries().get(0));
+
} catch (SiftsException e)
{
// fall back to NW alignment
StructureMapping nwMapping = getNWMappings(seq, pdbFile,
targetChainId, maxChain, pdb, maxAlignseq);
seqToStrucMapping.add(nwMapping);
+ maxChain.makeExactMapping(maxAlignseq, seq);
+ maxChain.transferRESNUMFeatures(seq, null); // FIXME: is this
+ // "IEA:Jalview" ?
+ maxChain.transferResidueAnnotation(nwMapping, sqmpping);
+ ds.addPDBId(maxChain.sequence.getAllPDBEntries().get(0));
}
}
else
try
{
StructureMapping siftsMapping = getStructureMapping(seq,
- pdbFile,
- chain.id, pdb, chain, sqmpping, maxAlignseq);
+ pdbFile, chain.id, pdb, chain, sqmpping, maxAlignseq);
foundSiftsMappings.add(siftsMapping);
} catch (SiftsException e)
{
{
seqToStrucMapping.addAll(foundSiftsMappings);
maxChain.makeExactMapping(maxAlignseq, seq);
- maxChain.transferRESNUMFeatures(seq, null);
+ maxChain.transferRESNUMFeatures(seq, null);// FIXME: is this
+ // "IEA:SIFTS" ?
maxChain.transferResidueAnnotation(foundSiftsMappings.get(0),
sqmpping);
+ ds.addPDBId(sqmpping.getTo().getAllPDBEntries().get(0));
}
else
{
StructureMapping nwMapping = getNWMappings(seq, pdbFile,
maxChainId, maxChain, pdb, maxAlignseq);
seqToStrucMapping.add(nwMapping);
+ maxChain.transferRESNUMFeatures(seq, null); // FIXME: is this
+ // "IEA:Jalview" ?
+ maxChain.transferResidueAnnotation(nwMapping, sqmpping);
+ ds.addPDBId(maxChain.sequence.getAllPDBEntries().get(0));
}
}
}
setProgressBar(null);
setProgressBar(MessageManager
.getString("status.obtaining_mapping_with_nw_alignment"));
- seqToStrucMapping.add(getNWMappings(seq, pdbFile, maxChainId,
- maxChain, pdb, maxAlignseq));
+ StructureMapping nwMapping = getNWMappings(seq, pdbFile,
+ maxChainId, maxChain, pdb, maxAlignseq);
+ seqToStrucMapping.add(nwMapping);
+ ds.addPDBId(maxChain.sequence.getAllPDBEntries().get(0));
+
}
if (forStructureView)
return "cif".equalsIgnoreCase(fileExt);
}
+ /**
+ * retrieve a mapping for seq from SIFTs using associated DBRefEntry for
+ * uniprot or PDB
+ *
+ * @param seq
+ * @param pdbFile
+ * @param targetChainId
+ * @param pdb
+ * @param maxChain
+ * @param sqmpping
+ * @param maxAlignseq
+ * @return
+ * @throws SiftsException
+ */
private StructureMapping getStructureMapping(SequenceI seq,
String pdbFile, String targetChainId, StructureFile pdb,
PDBChain maxChain, jalview.datamodel.Mapping sqmpping,
AlignSeq maxAlignseq) throws SiftsException
{
- StructureMapping curChainMapping = siftsClient
- .getSiftsStructureMapping(seq, pdbFile, targetChainId);
- try
- {
+ StructureMapping curChainMapping = siftsClient
+ .getSiftsStructureMapping(seq, pdbFile, targetChainId);
+ try
+ {
PDBChain chain = pdb.findChain(targetChainId);
if (chain != null)
{
chain.transferResidueAnnotation(curChainMapping, sqmpping);
}
- } catch (Exception e)
- {
- e.printStackTrace();
- }
- return curChainMapping;
+ } catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ return curChainMapping;
}
- private StructureMapping getNWMappings(SequenceI seq,
- String pdbFile,
+ private StructureMapping getNWMappings(SequenceI seq, String pdbFile,
String maxChainId, PDBChain maxChain, StructureFile pdb,
AlignSeq maxAlignseq)
{
+++ /dev/null
-package jalview.structure;
-
-import jalview.datamodel.DBRefSource;
-
-public class StructureViewSettings
-{
- private String dbRefType;
-
- /**
- * set to true to add derived sequence annotations (temp factor read from
- * file, or computed secondary structure) to the alignment
- */
- private static boolean visibleChainAnnotation = false;
-
- /**
- * Set true to predict secondary structure (using JMol for protein, Annotate3D
- * for RNA)
- */
- private static boolean predictSecStr = false;
-
- /**
- * Set true (with predictSecondaryStructure=true) to predict secondary
- * structure using an external service (currently Annotate3D for RNA only)
- */
- private static boolean externalSecondaryStructure = false;
-
- private static boolean showSeqFeatures = true;
-
- private static String currentDefaultFormat = DBRefSource.PDB;
-
- public static void addSettings(boolean addAlignmentAnnotations,
- boolean predictSecStr, boolean externalSecStr)
- {
- StructureViewSettings.visibleChainAnnotation = addAlignmentAnnotations;
- StructureViewSettings.predictSecStr = predictSecStr;
- StructureViewSettings.externalSecondaryStructure = externalSecStr;
- StructureViewSettings.showSeqFeatures = true;
- }
-
- public static boolean isVisibleChainAnnotation()
- {
- return visibleChainAnnotation;
- }
-
- public static void setVisibleChainAnnotation(
- boolean visibleChainAnnotation)
- {
- StructureViewSettings.visibleChainAnnotation = visibleChainAnnotation;
- }
-
- public static boolean isPredictSecondaryStructure()
- {
- return predictSecStr;
- }
-
- public static void setPredictSecondaryStructure(
- boolean predictSecondaryStructure)
- {
- StructureViewSettings.predictSecStr = predictSecondaryStructure;
- }
-
- public static boolean isExternalSecondaryStructure()
- {
- return externalSecondaryStructure;
- }
-
- public static void setExternalSecondaryStructure(
- boolean externalSecondaryStructure)
- {
- StructureViewSettings.externalSecondaryStructure = externalSecondaryStructure;
- }
-
- public static boolean isShowSeqFeatures()
- {
- return showSeqFeatures;
- }
-
- public static void setShowSeqFeatures(boolean showSeqFeatures)
- {
- StructureViewSettings.showSeqFeatures = showSeqFeatures;
- }
-
- public static String getCurrentDefaultFormat()
- {
- return currentDefaultFormat;
- }
-
- public static void setCurrentDefaultFormat(String currentDefaultFormat)
- {
- StructureViewSettings.currentDefaultFormat = currentDefaultFormat;
- }
-
-}
private StructureSelectionManager ssm;
+ /*
+ * distinct PDB entries (pdb files) associated
+ * with sequences
+ */
private PDBEntry[] pdbEntry;
/*
private boolean finishedInit = false;
/**
+ * current set of model filenames loaded in the Jmol instance
+ */
+ protected String[] modelFileNames = null;
+
+ /**
* Data bean class to simplify parameterisation in superposeStructures
*/
protected class SuperposeData
// TODO: give a more informative title when multiple structures are
// displayed.
StringBuilder title = new StringBuilder(64);
- final PDBEntry pdbEntry = getPdbEntry(0);
+ final PDBEntry pdbe = getPdbEntry(0);
title.append(viewerName + " view for " + getSequence()[0][0].getName()
- + ":" + pdbEntry.getId());
+ + ":" + pdbe.getId());
if (verbose)
{
- if (pdbEntry.getProperty() != null)
+ String method = (String) pdbe.getProperty("method");
+ if (method != null)
{
- if (pdbEntry.getProperty().get("method") != null)
- {
- title.append(" Method: ");
- title.append(pdbEntry.getProperty().get("method"));
- }
- if (pdbEntry.getProperty().get("chains") != null)
- {
- title.append(" Chain:");
- title.append(pdbEntry.getProperty().get("chains"));
- }
+ title.append(" Method: ").append(method);
+ }
+ String chain = (String) pdbe.getProperty("chains");
+ if (chain != null)
+ {
+ title.append(" Chain:").append(chain);
}
}
return title.toString();
{
int refStructure = -1;
String[] files = getPdbFile();
+ if (files == null)
+ {
+ return -1;
+ }
for (int pdbfnum = 0; pdbfnum < files.length; pdbfnum++)
{
StructureMapping[] mappings = getSsm().getMapping(files[pdbfnum]);
}
structures[pdbfnum].pdbId = mapping.getPdbId();
structures[pdbfnum].isRna = theSequence.getRNA() != null;
- // move on to next pdb file
+
+ /*
+ * move on to next pdb file (ignore sequences for other chains
+ * for the same structure)
+ */
s = seqCountForPdbFile;
break;
}
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
package jalview.util;
public class ArrayUtils
--- /dev/null
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
+package jalview.util;
+
+/**
+ * A class to wrap a case insensitive string. For use in collections where we
+ * want to preserve case, but do not want to duplicate upper and lower case
+ * variants
+ */
+public final class CaseInsensitiveString
+{
+ String value;
+
+ public CaseInsensitiveString(String s)
+ {
+ this.value = s;
+ }
+
+ @Override
+ public String toString()
+ {
+ return value;
+ }
+
+ /**
+ * Answers true if the object compared to is a CaseInsensitiveString wrapping
+ * the same string value (ignoring case), or if both wrap a null value, else
+ * false
+ */
+ @Override
+ public boolean equals(Object o)
+ {
+ if (o == null)
+ {
+ return false;
+ }
+ if (!(o instanceof CaseInsensitiveString))
+ {
+ return false;
+ }
+ CaseInsensitiveString obj = (CaseInsensitiveString) o;
+ if (value == null)
+ {
+ return obj.value == null;
+ }
+ return value.equalsIgnoreCase(obj.value);
+ }
+
+ /**
+ * hashCode overriden to guarantee that 'equal' objects have the same hash
+ * code
+ */
+ @Override
+ public int hashCode()
+ {
+ return value == null ? super.hashCode() : value.toUpperCase()
+ .hashCode();
+ }
+}
* (maxColour.getBlue() - minColour.getBlue());
return new Color(r / 255, g / 255, b / 255);
}
+
+ /**
+ * 'Fades' the given colour towards white by the specified proportion. A
+ * factor of 1 or more results in White, a factor of 0 leaves the colour
+ * unchanged, and a factor between 0 and 1 results in a proportionate change
+ * of RGB values towards (255, 255, 255).
+ * <p>
+ * A negative bleachFactor can be specified to darken the colour towards Black
+ * (0, 0, 0).
+ *
+ * @param colour
+ * @param bleachFactor
+ * @return
+ */
+ public static Color bleachColour(Color colour, float bleachFactor)
+ {
+ if (bleachFactor >= 1f)
+ {
+ return Color.WHITE;
+ }
+ if (bleachFactor <= -1f)
+ {
+ return Color.BLACK;
+ }
+ if (bleachFactor == 0f)
+ {
+ return colour;
+ }
+
+ int red = colour.getRed();
+ int green = colour.getGreen();
+ int blue = colour.getBlue();
+
+ if (bleachFactor > 0)
+ {
+ red += (255 - red) * bleachFactor;
+ green += (255 - green) * bleachFactor;
+ blue += (255 - blue) * bleachFactor;
+ return new Color(red, green, blue);
+ }
+ else
+ {
+ float factor = 1 + bleachFactor;
+ red *= factor;
+ green *= factor;
+ blue *= factor;
+ return new Color(red, green, blue);
+ }
+ }
}
}
/**
+ * Overloaded method signature to test whether a single sequence is nucleotide
+ * (that is, more than 85% CGTA)
+ *
+ * @param seq
+ * @return
+ */
+ public static final boolean isNucleotide(SequenceI seq)
+ {
+ return isNucleotide(new SequenceI[] { seq });
+ }
+
+ /**
* Answers true if more than 85% of the sequence residues (ignoring gaps) are
* A, G, C, T or U, else false. This is just a heuristic guess and may give a
* wrong answer (as AGCT are also amino acid codes).
import jalview.datamodel.SequenceI;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
-import java.util.Hashtable;
import java.util.List;
import java.util.Map;
+import java.util.Set;
import com.stevesoft.pat.Regex;
canonicalSourceNameLookup.put("pdb", DBRefSource.PDB);
canonicalSourceNameLookup.put("ensembl", DBRefSource.ENSEMBL);
+ // Ensembl Gn and Tr are for Ensembl genomic and transcript IDs as served
+ // from ENA.
+ canonicalSourceNameLookup.put("ensembl-tr", DBRefSource.ENSEMBL);
+ canonicalSourceNameLookup.put("ensembl-gn", DBRefSource.ENSEMBL);
+
+ // Make sure we have lowercase entries for all canonical string lookups
+ Set<String> keys = canonicalSourceNameLookup.keySet();
+ for (String k : keys)
+ {
+ canonicalSourceNameLookup.put(k.toLowerCase(),
+ canonicalSourceNameLookup.get(k));
+ }
dasCoordinateSystemsLookup.put("pdbresnum", DBRefSource.PDB);
dasCoordinateSystemsLookup.put("uniprot", DBRefSource.UNIPROT);
}
/**
+ * Returns those DBRefEntry objects whose source identifier (once converted to
+ * Jalview's canonical form) is in the list of sources to search for. Returns
+ * null if no matches found.
*
* @param dbrefs
- * array of DBRef objects to search
+ * DBRefEntry objects to search
* @param sources
- * String[] array of source DBRef IDs to retrieve
+ * array of sources to select
* @return
*/
public static DBRefEntry[] selectRefs(DBRefEntry[] dbrefs,
}
/**
- * Returns an array of those references that match the given entry, or null if
- * no matches. Currently uses a comparator which matches if
+ * Returns a (possibly empty) list of those references that match the given
+ * entry. Currently uses a comparator which matches if
* <ul>
* <li>database sources are the same</li>
* <li>accession ids are the same</li>
* pattern to match
* @return
*/
- public static DBRefEntry[] searchRefs(DBRefEntry[] ref, DBRefEntry entry)
+ public static List<DBRefEntry> searchRefs(DBRefEntry[] ref,
+ DBRefEntry entry)
{
return searchRefs(ref, entry,
matchDbAndIdAndEitherMapOrEquivalentMapList);
}
/**
- * Returns an array of those references that match the given accession id
+ * Returns a list of those references that match the given accession id
* <ul>
* <li>database sources are the same</li>
* <li>accession ids are the same</li>
* <li>both have no mapping, or the mappings are the same</li>
* </ul>
*
- * @param ref
+ * @param refs
* Set of references to search
- * @param entry
- * pattern to match
+ * @param accId
+ * accession id to match
* @return
*/
- public static DBRefEntry[] searchRefs(DBRefEntry[] ref, String accId)
+ public static List<DBRefEntry> searchRefs(DBRefEntry[] refs, String accId)
{
- return searchRefs(ref, new DBRefEntry("", "", accId), matchId);
+ return searchRefs(refs, new DBRefEntry("", "", accId), matchId);
}
/**
- * Returns an array of those references that match the given entry, according
- * to the given comparator. Returns null if no matches.
+ * Returns a (possibly empty) list of those references that match the given
+ * entry, according to the given comparator.
*
* @param refs
* an array of database references to search
* @param comparator
* @return
*/
- static DBRefEntry[] searchRefs(DBRefEntry[] refs, DBRefEntry entry,
+ static List<DBRefEntry> searchRefs(DBRefEntry[] refs, DBRefEntry entry,
DbRefComp comparator)
{
+ List<DBRefEntry> rfs = new ArrayList<DBRefEntry>();
if (refs == null || entry == null)
{
- return null;
+ return rfs;
}
- List<DBRefEntry> rfs = new ArrayList<DBRefEntry>();
for (int i = 0; i < refs.length; i++)
{
if (comparator.matches(entry, refs[i]))
rfs.add(refs[i]);
}
}
- return rfs.size() == 0 ? null : rfs.toArray(new DBRefEntry[rfs.size()]);
+ return rfs;
}
interface DbRefComp
public boolean matches(DBRefEntry refa, DBRefEntry refb)
{
if (refa.getSource() == null
- || refb.getSource().equals(refa.getSource()))
+ || DBRefUtils.getCanonicalName(refb.getSource()).equals(
+ DBRefUtils.getCanonicalName(refa.getSource())))
{
if (refa.getVersion() == null
|| refb.getVersion().equals(refa.getVersion()))
@Override
public boolean matches(DBRefEntry refa, DBRefEntry refb)
{
- if (nullOrEqual(refa.getSource(), refb.getSource())
+ if (nullOrEqualSource(refa.getSource(), refb.getSource())
&& nullOrEqual(refa.getVersion(), refb.getVersion())
&& nullOrEqual(refa.getAccessionId(), refb.getAccessionId())
&& nullOrEqual(refa.getMap(), refb.getMap()))
@Override
public boolean matches(DBRefEntry refa, DBRefEntry refb)
{
- if (refa.getSource() != null && refb.getSource() != null
- && refb.getSource().equals(refa.getSource()))
+ if (refa.getSource() != null
+ && refb.getSource() != null
+ && DBRefUtils.getCanonicalName(refb.getSource()).equals(
+ DBRefUtils.getCanonicalName(refa.getSource())))
{
// We dont care about version
if (refa.getAccessionId() != null && refb.getAccessionId() != null
@Override
public boolean matches(DBRefEntry refa, DBRefEntry refb)
{
- if (refa.getSource() != null && refb.getSource() != null
- && refb.getSource().equals(refa.getSource()))
+ if (refa.getSource() != null
+ && refb.getSource() != null
+ && DBRefUtils.getCanonicalName(refb.getSource()).equals(
+ DBRefUtils.getCanonicalName(refa.getSource())))
{
// We dont care about version
if (refa.getAccessionId() != null && refb.getAccessionId() != null
@Override
public boolean matches(DBRefEntry refa, DBRefEntry refb)
{
- if (refa.getSource() != null && refb.getSource() != null
- && refb.getSource().equals(refa.getSource()))
+ if (refa.getSource() != null
+ && refb.getSource() != null
+ && DBRefUtils.getCanonicalName(refb.getSource()).equals(
+ DBRefUtils.getCanonicalName(refa.getSource())))
{
// We dont care about version
// if ((refa.getVersion()==null || refb.getVersion()==null)
};
/**
- * accession ID and DB must be identical. Version is ignored. No map on either
- * or map but no maplist on either or maplist of map on a is equivalent to the
- * maplist of map on b.
+ * accession ID and DB must be identical, or null on a. Version is ignored. No
+ * map on either or map but no maplist on either or maplist of map on a is
+ * equivalent to the maplist of map on b.
*/
public static DbRefComp matchDbAndIdAndEitherMapOrEquivalentMapList = new DbRefComp()
{
@Override
public boolean matches(DBRefEntry refa, DBRefEntry refb)
{
- if (refa.getSource() != null && refb.getSource() != null
- && refb.getSource().equals(refa.getSource()))
+ if (refa.getSource() != null
+ && refb.getSource() != null
+ && DBRefUtils.getCanonicalName(refb.getSource()).equals(
+ DBRefUtils.getCanonicalName(refa.getSource())))
{
// We dont care about version
- if (refa.getAccessionId() != null && refb.getAccessionId() != null
- && refb.getAccessionId().equals(refa.getAccessionId()))
+
+ if (refa.getAccessionId() == null
+ || refa.getAccessionId().equals(refb.getAccessionId()))
{
if (refa.getMap() == null || refb.getMap() == null)
{
|| (refb.getMap().getMap() != null
&& refa.getMap().getMap() != null && (refb
.getMap().getMap().equals(refa.getMap().getMap()))))
- { // getMap().getMap().containsEither(false,refa.getMap().getMap())
+ {
return true;
}
}
PDBEntry pdbr = new PDBEntry();
pdbr.setId(pdbid);
pdbr.setType(PDBEntry.Type.PDB);
- pdbr.setProperty(new Hashtable());
pdbr.setChainCode(chaincode);
- // pdbr.getProperty().put("CHAIN", chaincode);
seq.addPDBId(pdbr);
}
else
{
return true;
}
- return (o1 == null ? o2.equals(o1) : o1.equals(o2));
+ return o1.equals(o2);
+ }
+
+ /**
+ * canonicalise source string before comparing. null is always wildcard
+ *
+ * @param o1
+ * - null or source string to compare
+ * @param o2
+ * - null or source string to compare
+ * @return true if either o1 or o2 are null, or o1 equals o2 under
+ * DBRefUtils.getCanonicalName
+ * (o1).equals(DBRefUtils.getCanonicalName(o2))
+ */
+ public static boolean nullOrEqualSource(String o1, String o2)
+ {
+ if (o1 == null || o2 == null)
+ {
+ return true;
+ }
+ return DBRefUtils.getCanonicalName(o1).equals(
+ DBRefUtils.getCanonicalName(o2));
+ }
+
+ /**
+ * Selects just the DNA or protein references from a set of references
+ *
+ * @param selectDna
+ * if true, select references to 'standard' DNA databases, else to
+ * 'standard' peptide databases
+ * @param refs
+ * a set of references to select from
+ * @return
+ */
+ public static DBRefEntry[] selectDbRefs(boolean selectDna,
+ DBRefEntry[] refs)
+ {
+ return selectRefs(refs, selectDna ? DBRefSource.DNACODINGDBS
+ : DBRefSource.PROTEINDBS);
+ // could attempt to find other cross
+ // refs here - ie PDB xrefs
+ // (not dna, not protein seq)
+ }
+
+ /**
+ * Returns the (possibly empty) list of those supplied dbrefs which have the
+ * specified source database, with a case-insensitive match of source name
+ *
+ * @param dbRefs
+ * @param source
+ * @return
+ */
+ public static List<DBRefEntry> searchRefsForSource(DBRefEntry[] dbRefs,
+ String source)
+ {
+ List<DBRefEntry> matches = new ArrayList<DBRefEntry>();
+ if (dbRefs != null && source != null)
+ {
+ for (DBRefEntry dbref : dbRefs)
+ {
+ if (source.equalsIgnoreCase(dbref.getSource()))
+ {
+ matches.add(dbref);
+ }
+ }
+ }
+ return matches;
+ }
+
+ /**
+ * promote direct database references to primary for nucleotide or protein
+ * sequences if they have an appropriate primary ref
+ * <table>
+ * <tr>
+ * <th>Seq Type</th>
+ * <th>Primary DB</th>
+ * <th>Direct which will be promoted</th>
+ * </tr>
+ * <tr align=center>
+ * <td>peptides</td>
+ * <td>Ensembl</td>
+ * <td>Uniprot</td>
+ * </tr>
+ * <tr align=center>
+ * <td>peptides</td>
+ * <td>Ensembl</td>
+ * <td>Uniprot</td>
+ * </tr>
+ * <tr align=center>
+ * <td>dna</td>
+ * <td>Ensembl</td>
+ * <td>ENA</td>
+ * </tr>
+ * </table>
+ *
+ * @param sequence
+ */
+ public static void ensurePrimaries(SequenceI sequence)
+ {
+ List<DBRefEntry> pr = sequence.getPrimaryDBRefs();
+ if (pr.size() == 0)
+ {
+ // nothing to do
+ return;
+ }
+ List<DBRefEntry> selfs = new ArrayList<DBRefEntry>();
+ {
+ DBRefEntry[] selfArray = selectDbRefs(!sequence.isProtein(),
+ sequence.getDBRefs());
+ if (selfArray == null || selfArray.length == 0)
+ {
+ // nothing to do
+ return;
+ }
+ selfs.addAll(Arrays.asList(selfArray));
+ }
+
+ // filter non-primary refs
+ for (DBRefEntry p : pr)
+ {
+ while (selfs.contains(p))
+ {
+ selfs.remove(p);
+ }
+ }
+ List<DBRefEntry> toPromote = new ArrayList<DBRefEntry>();
+
+ for (DBRefEntry p : pr)
+ {
+ List<String> promType = new ArrayList<String>();
+ if (sequence.isProtein())
+ {
+ switch (getCanonicalName(p.getSource()))
+ {
+ case DBRefSource.UNIPROT:
+ // case DBRefSource.UNIPROTKB:
+ // case DBRefSource.UP_NAME:
+ // search for and promote ensembl
+ promType.add(DBRefSource.ENSEMBL);
+ break;
+ case DBRefSource.ENSEMBL:
+ // search for and promote Uniprot
+ promType.add(DBRefSource.UNIPROT);
+ break;
+ }
+ }
+ else
+ {
+ // TODO: promote transcript refs
+ }
+
+ // collate candidates and promote them
+ DBRefEntry[] candidates = selectRefs(
+ selfs.toArray(new DBRefEntry[0]),
+ promType.toArray(new String[0]));
+ if (candidates != null)
+ {
+ for (DBRefEntry cand : candidates)
+ {
+ if (cand.hasMap())
+ {
+ if (cand.getMap().getTo() != null
+ && cand.getMap().getTo() != sequence)
+ {
+ // can't promote refs with mappings to other sequences
+ continue;
+ }
+ if (cand.getMap().getMap().getFromLowest() != sequence
+ .getStart()
+ && cand.getMap().getMap().getFromHighest() != sequence
+ .getEnd())
+ {
+ // can't promote refs with mappings from a region of this sequence
+ // - eg CDS
+ continue;
+ }
+ }
+ // and promote
+ cand.setVersion(p.getVersion() + " (promoted)");
+ selfs.remove(cand);
+ toPromote.add(cand);
+ if (!cand.isPrimaryCandidate())
+ {
+ System.out.println("Warning: Couldn't promote dbref "
+ + cand.toString() + " for sequence "
+ + sequence.toString());
+ }
+ }
+ }
+ }
}
}
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
package jalview.util;
import java.text.ParseException;
{
return formatString;
}
+
+ /**
+ * Bespoke method to format percentage float value to the specified number of
+ * decimal places. Avoids use of general-purpose format parsers as a
+ * processing hotspot.
+ *
+ * @param sb
+ * @param value
+ * @param dp
+ */
+ public static void appendPercentage(StringBuilder sb, float value, int dp)
+ {
+ sb.append((int) value);
+ if (dp > 0)
+ {
+ sb.append(".");
+ while (dp > 0)
+ {
+ value = value - (int) value;
+ value *= 10;
+ sb.append((int) value);
+ dp--;
+ }
+ }
+ }
}
-/*******************************************************************************
+/*
* Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
* Copyright (C) $$Year-Rel$$ The Jalview Authors
*
* You should have received a copy of the GNU General Public License
* along with Jalview. If not, see <http://www.gnu.org/licenses/>.
* The Jalview Authors are detailed in the 'AUTHORS' file.
- ******************************************************************************/
+ */
package jalview.util;
import java.io.IOException;
public enum TYPE
{
- EPS("EPS", MessageManager.getString("label.eps_file"), getEPSChooser()), PNG(
- "PNG", MessageManager.getString("label.png_image"),
- getPNGChooser()), SVG("SVG", "SVG", getSVGChooser());
+ EPS("EPS", MessageManager.getString("label.eps_file"), getEPSChooser()),
+ PNG("PNG", MessageManager.getString("label.png_image"), getPNGChooser()),
+ SVG("SVG", "SVG", getSVGChooser());
private JalviewFileChooser chooser;
--- /dev/null
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
+package jalview.util;
+
+import java.util.AbstractSet;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+
+/**
+ * Order preserving Set based on System.identityHashCode() for an object, which
+ * also supports Object->index lookup.
+ *
+ * @author Jim Procter (2016) based on Evgeniy Dorofeev's response: via
+ * https://stackoverflow.com/questions/17276658/linkedidentityhashset
+ *
+ */
+public class LinkedIdentityHashSet<E> extends AbstractSet<E>
+{
+ LinkedHashMap<IdentityWrapper, IdentityWrapper> set = new LinkedHashMap<IdentityWrapper, IdentityWrapper>();
+
+ static class IdentityWrapper
+ {
+ Object obj;
+
+ public int p;
+
+ IdentityWrapper(Object obj, int p)
+ {
+ this.obj = obj;
+ this.p = p;
+ }
+
+ @Override
+ public boolean equals(Object obj)
+ {
+ return this.obj == obj;
+ }
+
+ @Override
+ public int hashCode()
+ {
+ return System.identityHashCode(obj);
+ }
+ }
+
+ @Override
+ public boolean add(E e)
+ {
+ IdentityWrapper el = (new IdentityWrapper(e, set.size()));
+ // Map.putIfAbsent() from Java 8
+ // return set.putIfAbsent(el, el) == null;
+ return putIfAbsent(el, el) == null;
+ }
+
+ /**
+ * If the specified key is not already associated with a value (or is mapped
+ * to null) associates it with the given value and returns null, else returns
+ * the current value.
+ *
+ * Method added for Java 7 (can remove for Java 8)
+ *
+ * @param key
+ * @param value
+ * @return
+ * @see https
+ * ://docs.oracle.com/javase/8/docs/api/java/util/Map.html#putIfAbsent
+ * -K-V-
+ */
+ private IdentityWrapper putIfAbsent(IdentityWrapper key,
+ IdentityWrapper value)
+ {
+ IdentityWrapper v = set.get(key);
+ if (v == null)
+ {
+ v = set.put(key, value);
+ }
+ return v;
+ }
+
+ @Override
+ public Iterator<E> iterator()
+ {
+ return new Iterator<E>()
+ {
+ final Iterator<IdentityWrapper> se = set.keySet().iterator();
+
+ @Override
+ public boolean hasNext()
+ {
+ return se.hasNext();
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public E next()
+ {
+ return (E) se.next().obj;
+ }
+
+ @Override
+ public void remove()
+ {
+ // Java 8 default behaviour
+ throw new UnsupportedOperationException();
+ }
+ };
+ }
+
+ @Override
+ public int size()
+ {
+ return set.size();
+ }
+
+ /**
+ * Lookup the index for e in the set
+ *
+ * @param e
+ * @return position of e in the set when it was added.
+ */
+ public int indexOf(E e)
+ {
+ return set.get(e).p;
+ }
+}
@Override
public boolean equals(Object o)
{
- // TODO should also override hashCode to ensure equal objects have equal
- // hashcodes
if (o == null || !(o instanceof MapList))
{
return false;
}
/**
+ * Returns a hashcode made from the fromRatio, toRatio, and from/to ranges
+ */
+ @Override
+ public int hashCode()
+ {
+ int hashCode = 31 * fromRatio;
+ hashCode = 31 * hashCode + toRatio;
+ hashCode = 31 * hashCode + fromShifts.toArray().hashCode();
+ hashCode = 31 * hashCode + toShifts.toArray().hashCode();
+ return hashCode;
+ }
+
+ /**
* Returns the 'from' ranges as {[start1, end1], [start2, end2], ...}
*
* @return
{
/*
* note lowest and highest values - bearing in mind the
- * direction may be revesed
+ * direction may be reversed
*/
fromLowest = Math.min(fromLowest, Math.min(from[i], from[i + 1]));
fromHighest = Math.max(fromHighest, Math.max(from[i], from[i + 1]));
*/
public static List<int[]> coalesceRanges(final List<int[]> ranges)
{
- if (ranges == null || ranges.size() < 2) {
+ if (ranges == null || ranges.size() < 2)
+ {
return ranges;
}
lastRange = new int[] { lastRange[0], lastRange[1] };
merged.add(lastRange);
boolean first = true;
-
+
for (final int[] range : ranges)
{
if (first)
* if next range is in the same direction as last and contiguous,
* just update the end position of the last range
*/
- boolean sameDirection = range[1] == range[0] || direction == lastDirection;
+ boolean sameDirection = range[1] == range[0]
+ || direction == lastDirection;
boolean extending = range[0] == lastRange[1] + lastDirection;
boolean overlapping = (lastDirection == 1 && range[0] >= lastRange[0] && range[0] <= lastRange[1])
|| (lastDirection == -1 && range[0] <= lastRange[0] && range[0] >= lastRange[1]);
lastDirection = (range[1] == range[0]) ? lastDirection : direction;
}
}
-
+
return changed ? merged : ranges;
}
*/
public void addMapList(MapList map)
{
+ if (this.equals(map))
+ {
+ return;
+ }
this.fromLowest = Math.min(fromLowest, map.fromLowest);
this.toLowest = Math.min(toLowest, map.toLowest);
this.fromHighest = Math.max(fromHighest, map.fromHighest);
}
return forwardStrand;
}
+
+ /**
+ *
+ * @return true if from, or to is a three to 1 mapping
+ */
+ public boolean isTripletMap()
+ {
+ return (toRatio == 3 && fromRatio == 1)
+ || (fromRatio == 3 && toRatio == 1);
+ }
+
}
/*
* Found a sequence mapping. Locate the start/end mapped residues.
*/
- List<AlignedCodonFrame> mapping = Arrays.asList(new AlignedCodonFrame[] { acf });
+ List<AlignedCodonFrame> mapping = Arrays
+ .asList(new AlignedCodonFrame[] { acf });
SearchResults sr = buildSearchResults(selected,
startResiduePos, mapping);
for (Match m : sr.getResults())
* @param fromGapChar
*/
protected static void mapHiddenColumns(int[] hidden,
- List<AlignedCodonFrame> mappings,
- ColumnSelection mappedColumns, List<SequenceI> fromSequences,
- List<SequenceI> toSequences, char fromGapChar)
+ List<AlignedCodonFrame> mappings, ColumnSelection mappedColumns,
+ List<SequenceI> fromSequences, List<SequenceI> toSequences,
+ char fromGapChar)
{
for (int col = hidden[0]; col <= hidden[1]; col++)
{
* @param fromGapChar
*/
protected static void mapColumn(int col,
- List<AlignedCodonFrame> mappings,
- ColumnSelection mappedColumns, List<SequenceI> fromSequences,
- List<SequenceI> toSequences, char fromGapChar)
+ List<AlignedCodonFrame> mappings, ColumnSelection mappedColumns,
+ List<SequenceI> fromSequences, List<SequenceI> toSequences,
+ char fromGapChar)
{
int[] mappedTo = findMappedColumns(col, mappings, fromSequences,
toSequences, fromGapChar);
* Get the residue position and find the mapped position.
*/
int residuePos = fromSeq.findPosition(col);
- SearchResults sr = buildSearchResults(fromSeq, residuePos,
- mappings);
+ SearchResults sr = buildSearchResults(fromSeq, residuePos, mappings);
for (Match m : sr.getResults())
{
int mappedStartResidue = m.getStart();
public static List<AlignedCodonFrame> findMappingsForSequence(
SequenceI sequence, List<AlignedCodonFrame> mappings)
{
+ return findMappingsForSequenceAndOthers(sequence, mappings, null);
+ }
+
+ /**
+ * Returns a list of any mappings that are from or to the given (aligned or
+ * dataset) sequence, optionally limited to mappings involving one of a given
+ * list of sequences.
+ *
+ * @param sequence
+ * @param mappings
+ * @param filterList
+ * @return
+ */
+ public static List<AlignedCodonFrame> findMappingsForSequenceAndOthers(
+ SequenceI sequence, List<AlignedCodonFrame> mappings,
+ List<SequenceI> filterList)
+ {
List<AlignedCodonFrame> result = new ArrayList<AlignedCodonFrame>();
if (sequence == null || mappings == null)
{
{
if (mapping.involvesSequence(sequence))
{
- result.add(mapping);
+ if (filterList != null)
+ {
+ for (SequenceI otherseq : filterList)
+ {
+ SequenceI otherDataset = otherseq.getDatasetSequence();
+ if (otherseq == sequence
+ || otherseq == sequence.getDatasetSequence()
+ || (otherDataset != null && (otherDataset == sequence || otherDataset == sequence
+ .getDatasetSequence())))
+ {
+ // skip sequences in subset which directly relate to sequence
+ continue;
+ }
+ if (mapping.involvesSequence(otherseq))
+ {
+ // selected a mapping contained in subselect alignment
+ result.add(mapping);
+ break;
+ }
+ }
+ }
+ else
+ {
+ result.add(mapping);
+ }
}
}
return result;
{
return ranges;
}
-
+
int[] copy = Arrays.copyOf(ranges, ranges.length);
int sxpos = -1;
int cdspos = 0;
break;
}
}
-
+
if (sxpos > 0)
{
/*
return f.toString();
}
+ /**
+ * Answers true if the mouse event has Meta-down (Command key on Mac) or
+ * Ctrl-down (on other o/s). Note this answers _false_ if the Ctrl key is
+ * pressed instead of the Meta/Cmd key on Mac. To test for Ctrl-click on Mac,
+ * you can use e.isPopupTrigger().
+ *
+ * @param e
+ * @return
+ */
public static boolean isControlDown(MouseEvent e)
{
- return (jalview.util.Platform.isAMac() ? (Toolkit.getDefaultToolkit()
- .getMenuShortcutKeyMask() & e.getModifiers()) != 0 : e
- .isControlDown());
+ if (isAMac())
+ {
+ return (Toolkit.getDefaultToolkit().getMenuShortcutKeyMask() & e
+ .getModifiers()) != 0;
+ // could we use e.isMetaDown() here?
+ }
+ return e.isControlDown();
}
}
final int length = arr.length;
Integer[] indices = makeIndexArray(length);
Arrays.sort(indices, new IntComparator(arr, ascending));
-
+
/*
* Copy the array values as per the sorted indices
*/
sortedInts[i] = arr[indices[i]];
sortedObjects[i] = s[indices[i]];
}
-
+
/*
* And copy the sorted values back into the arrays
*/
final int length = arr.length;
Integer[] indices = makeIndexArray(length);
Arrays.sort(indices, new ExternalComparator(arr, ascending));
-
+
/*
* Copy the array values as per the sorted indices
*/
sortedStrings[i] = arr[indices[i]];
sortedObjects[i] = s[indices[i]];
}
-
+
/*
* And copy the sorted values back into the arrays
*/
final int length = arr.length;
Integer[] indices = makeIndexArray(length);
Arrays.sort(indices, new DoubleComparator(arr, ascending));
-
+
/*
* Copy the array values as per the sorted indices
*/
sortedDoubles[i] = arr[indices[i]];
sortedObjects[i] = s[indices[i]];
}
-
+
/*
* And copy the sorted values back into the arrays
*/
--- /dev/null
+package jalview.util;
+
+import jalview.ext.android.SparseIntArray;
+import jalview.ext.android.SparseShortArray;
+
+/**
+ * A class to count occurrences of characters with minimal memory footprint.
+ * Sparse arrays of short values are used to hold the counts, with automatic
+ * promotion to arrays of int if any count exceeds the maximum value for a
+ * short.
+ *
+ * @author gmcarstairs
+ *
+ */
+public class SparseCount
+{
+ private static final int DEFAULT_PROFILE_SIZE = 2;
+
+ /*
+ * array of keys (chars) and values (counts)
+ * held either as shorts or (if shorts overflow) as ints
+ */
+ private SparseShortArray shortProfile;
+
+ private SparseIntArray intProfile;
+
+ /*
+ * flag is set true after short overflow occurs
+ */
+ private boolean useInts;
+
+ /**
+ * Constructor which initially creates a new sparse array of short values to
+ * hold counts.
+ *
+ * @param profileSize
+ */
+ public SparseCount(int profileSize)
+ {
+ this.shortProfile = new SparseShortArray(profileSize);
+ }
+
+ /**
+ * Constructor which allocates an initial count array for only two distinct
+ * values (the array will grow if needed)
+ */
+ public SparseCount()
+ {
+ this(DEFAULT_PROFILE_SIZE);
+ }
+
+ /**
+ * Adds the given value for the given key (or sets the initial value), and
+ * returns the new value
+ *
+ * @param key
+ * @param value
+ */
+ public int add(int key, int value)
+ {
+ int newValue = 0;
+ if (useInts)
+ {
+ newValue = intProfile.add(key, value);
+ }
+ else
+ {
+ try {
+ newValue = shortProfile.add(key, value);
+ } catch (ArithmeticException e) {
+ handleOverflow();
+ newValue = intProfile.add(key, value);
+ }
+ }
+ return newValue;
+ }
+
+ /**
+ * Switch from counting shorts to counting ints
+ */
+ synchronized void handleOverflow()
+ {
+ int size = shortProfile.size();
+ intProfile = new SparseIntArray(size);
+ for (int i = 0; i < size; i++)
+ {
+ short key = shortProfile.keyAt(i);
+ short value = shortProfile.valueAt(i);
+ intProfile.put(key, value);
+ }
+ shortProfile = null;
+ useInts = true;
+ }
+
+ /**
+ * Returns the size of the profile (number of distinct items counted)
+ *
+ * @return
+ */
+ public int size()
+ {
+ return useInts ? intProfile.size() : shortProfile.size();
+ }
+
+ /**
+ * Returns the value for the key (zero if no such key)
+ *
+ * @param key
+ * @return
+ */
+ public int get(int key)
+ {
+ return useInts ? intProfile.get(key) : shortProfile.get(key);
+ }
+
+ /**
+ * Sets the value for the given key
+ *
+ * @param key
+ * @param value
+ */
+ public void put(int key, int value)
+ {
+ if (useInts)
+ {
+ intProfile.put(key, value);
+ }
+ else
+ {
+ shortProfile.put(key, value);
+ }
+ }
+
+ public int keyAt(int k)
+ {
+ return useInts ? intProfile.keyAt(k) : shortProfile.keyAt(k);
+ }
+
+ public int valueAt(int k)
+ {
+ return useInts ? intProfile.valueAt(k) : shortProfile.valueAt(k);
+ }
+
+ /**
+ * Answers true if this object wraps arrays of int values, false if using
+ * short values
+ *
+ * @return
+ */
+ boolean isUsingInt()
+ {
+ return useInts;
+ }
+}
}
return "" + separator;
}
-
+
/**
* Converts a list to a string with a delimiter before each term except the
* first. Returns an empty string given a null or zero-length argument. This
--- /dev/null
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
+package jalview.util;
+
+/**
+ * A class to hold constants relating to Url links used in Jalview
+ */
+public class UrlConstants
+{
+
+ /*
+ * Sequence ID string
+ */
+ public static final String SEQUENCE_ID = "SEQUENCE_ID";
+
+ /*
+ * Sequence Name string
+ */
+ public static final String SEQUENCE_NAME = "SEQUENCE_NAME";
+
+ /*
+ * Default sequence URL link string for EMBL-EBI search
+ */
+ public static final String EMBLEBI_STRING = "EMBL-EBI Search|http://www.ebi.ac.uk/ebisearch/search.ebi?db=allebi&query=$SEQUENCE_NAME$";
+
+ /*
+ * Default sequence URL link string for EMBL-EBI search
+ */
+ public static final String OLD_EMBLEBI_STRING = "EMBL-EBI Search|http://www.ebi.ac.uk/ebisearch/search.ebi?db=allebi&query=$SEQUENCE_ID$";
+
+ /*
+ * Default sequence URL link string for SRS
+ */
+ public static final String SRS_STRING = "SRS|http://srs.ebi.ac.uk/srsbin/cgi-bin/wgetz?-newId+(([uniprot-all:$SEQUENCE_ID$]))+-view+SwissEntry";
+
+ /*
+ * not instantiable
+ */
+ private UrlConstants()
+ {
+ }
+}
*/
package jalview.util;
+import static jalview.util.UrlConstants.SEQUENCE_ID;
+import static jalview.util.UrlConstants.SEQUENCE_NAME;
+
import java.util.Vector;
public class UrlLink
private boolean dynamic = false;
+ private boolean uses_seq_id = false;
+
private String invalidMessage = null;
/**
*/
public UrlLink(String link)
{
- int sep = link.indexOf("|"), psqid = link.indexOf("$SEQUENCE_ID");
+ int sep = link.indexOf("|");
+ int psqid = link.indexOf("$" + SEQUENCE_ID);
+ int nsqid = link.indexOf("$" + SEQUENCE_NAME);
if (psqid > -1)
{
dynamic = true;
- int p = sep;
- do
- {
- sep = p;
- p = link.indexOf("|", sep + 1);
- } while (p > sep && p < psqid);
- // Assuming that the URL itself does not contain any '|' symbols
- // sep now contains last pipe symbol position prior to any regex symbols
- label = link.substring(0, sep);
- if (label.indexOf("|") > -1)
- {
- // | terminated database name / www target at start of Label
- target = label.substring(0, label.indexOf("|"));
- }
- else if (label.indexOf(" ") > 2)
- {
- // space separated Label - matches database name
- target = label.substring(0, label.indexOf(" "));
- }
- else
- {
- target = label;
- }
- // Parse URL : Whole URL string first
- url_prefix = link.substring(sep + 1, psqid);
- if (link.indexOf("$SEQUENCE_ID=/") == psqid
- && (p = link.indexOf("/=$", psqid + 14)) > psqid + 14)
- {
- // Extract Regex and suffix
- url_suffix = link.substring(p + 3);
- regexReplace = link.substring(psqid + 14, p);
- try
- {
- com.stevesoft.pat.Regex rg = com.stevesoft.pat.Regex.perlCode("/"
- + regexReplace + "/");
- if (rg == null)
- {
- invalidMessage = "Invalid Regular Expression : '"
- + regexReplace + "'\n";
- }
- } catch (Exception e)
- {
- invalidMessage = "Invalid Regular Expression : '" + regexReplace
- + "'\n";
- }
- }
- else
- {
- regexReplace = null;
- // verify format is really correct.
- if (link.indexOf("$SEQUENCE_ID$") == psqid)
- {
- url_suffix = link.substring(psqid + 13);
- regexReplace = null;
- }
- else
- {
- invalidMessage = "Warning: invalid regex structure for URL link : "
- + link;
- }
- }
+ uses_seq_id = true;
+
+ sep = parseTargetAndLabel(sep, psqid, link);
+
+ parseUrl(link, SEQUENCE_ID, psqid, sep);
+ }
+ else if (nsqid > -1)
+ {
+ dynamic = true;
+ sep = parseTargetAndLabel(sep, nsqid, link);
+
+ parseUrl(link, SEQUENCE_NAME, nsqid, sep);
}
else
{
target = link.substring(0, sep);
- label = link.substring(0, sep = link.lastIndexOf("|"));
+ sep = link.lastIndexOf("|");
+ label = link.substring(0, sep);
url_prefix = link.substring(sep + 1);
regexReplace = null; // implies we trim any prefix if necessary //
// regexReplace=".*\\|?(.*)";
url_suffix = null;
}
+
+ label = label.trim();
+ target = target.trim();
+ target = target.toUpperCase(); // DBRefEntry uppercases DB names
+ // NB getCanonicalName might be better but does not currently change case
}
/**
}
}
+ @Override
public String toString()
{
+ String var = (uses_seq_id ? SEQUENCE_ID : SEQUENCE_NAME);
+
return label
+ "|"
+ url_prefix
- + (dynamic ? ("$SEQUENCE_ID" + ((regexReplace != null) ? "="
+ + (dynamic ? ("$" + var + ((regexReplace != null) ? "="
+ regexReplace + "=$" : "$")) : "")
+ ((url_suffix == null) ? "" : url_suffix);
+ }
+
+ /**
+ *
+ * @param firstSep
+ * Location of first occurrence of separator in link string
+ * @param psqid
+ * Position of sequence id or name in link string
+ * @param link
+ * Link string containing database name and url
+ * @return Position of last separator symbol prior to any regex symbols
+ */
+ protected int parseTargetAndLabel(int firstSep, int psqid, String link)
+ {
+ int p = firstSep;
+ int sep = firstSep;
+ do
+ {
+ sep = p;
+ p = link.indexOf("|", sep + 1);
+ } while (p > sep && p < psqid);
+ // Assuming that the URL itself does not contain any '|' symbols
+ // sep now contains last pipe symbol position prior to any regex symbols
+ label = link.substring(0, sep);
+ if (label.indexOf("|") > -1)
+ {
+ // | terminated database name / www target at start of Label
+ target = label.substring(0, label.indexOf("|"));
+ }
+ else if (label.indexOf(" ") > 2)
+ {
+ // space separated Label - matches database name
+ target = label.substring(0, label.indexOf(" "));
+ }
+ else
+ {
+ target = label;
+ }
+ return sep;
+ }
+
+ /**
+ * Parse the URL part of the link string
+ *
+ * @param link
+ * Link string containing database name and url
+ * @param varName
+ * Name of variable in url string (e.g. SEQUENCE_ID, SEQUENCE_NAME)
+ * @param sqidPos
+ * Position of id or name in link string
+ * @param sep
+ * Position of separator in link string
+ */
+ protected void parseUrl(String link, String varName, int sqidPos, int sep)
+ {
+ url_prefix = link.substring(sep + 1, sqidPos);
+
+ // delimiter at start of regex: e.g. $SEQUENCE_ID=/
+ String startDelimiter = "$" + varName + "=/";
+ // delimiter at end of regex: /=$
+ String endDelimiter = "/=$";
+
+ int startLength = startDelimiter.length();
+
+ // Parse URL : Whole URL string first
+ int p = link.indexOf(endDelimiter, sqidPos + startLength);
+
+ if (link.indexOf(startDelimiter) == sqidPos
+ && (p > sqidPos + startLength))
+ {
+ // Extract Regex and suffix
+ url_suffix = link.substring(p + endDelimiter.length());
+ regexReplace = link.substring(sqidPos + startLength, p);
+ try
+ {
+ com.stevesoft.pat.Regex rg = com.stevesoft.pat.Regex.perlCode("/"
+ + regexReplace + "/");
+ if (rg == null)
+ {
+ invalidMessage = "Invalid Regular Expression : '" + regexReplace
+ + "'\n";
+ }
+ } catch (Exception e)
+ {
+ invalidMessage = "Invalid Regular Expression : '" + regexReplace
+ + "'\n";
+ }
+ }
+ else
+ {
+ // no regex
+ regexReplace = null;
+ // verify format is really correct.
+ if (link.indexOf("$" + varName + "$") == sqidPos)
+ {
+ url_suffix = link.substring(sqidPos + startLength - 1);
+ regexReplace = null;
+ }
+ else
+ {
+ invalidMessage = "Warning: invalid regex structure for URL link : "
+ + link;
+ }
+ }
}
private static void testUrls(UrlLink ul, String idstring, String[] urls)
* "PF3|http://us.expasy.org/cgi-bin/niceprot.pl?$SEQUENCE_ID=/PFAM:(.+)/=$"
* , "NOTFER|http://notfer.org/$SEQUENCE_ID=/(?<!\\s)(.+)/=$",
*/
- "NESTED|http://nested/$SEQUENCE_ID=/^(?:Label:)?(?:(?:gi\\|(\\d+))|([^:]+))/=$/nested" };
+ "NESTED|http://nested/$" + SEQUENCE_ID
+ + "=/^(?:Label:)?(?:(?:gi\\|(\\d+))|([^:]+))/=$/nested" };
String[] idstrings = new String[] {
/*
* //"LGUL_human", //"QWIQW_123123", "uniprot|why_do+_12313_foo",
return dynamic;
}
+ public boolean usesSeqId()
+ {
+ return uses_seq_id;
+ }
+
public void setLabel(String newlabel)
{
this.label = newlabel;
import jalview.analysis.AnnotationSorter.SequenceAnnotationOrder;
import jalview.analysis.Conservation;
+import jalview.analysis.Profile;
import jalview.api.AlignCalcManagerI;
import jalview.api.AlignViewportI;
import jalview.api.AlignmentViewPanel;
import jalview.schemes.Blosum62ColourScheme;
import jalview.schemes.ColourSchemeI;
import jalview.schemes.PIDColourScheme;
-import jalview.schemes.ResidueProperties;
import jalview.structure.CommandListener;
import jalview.structure.StructureSelectionManager;
import jalview.structure.VamsasSource;
import jalview.workers.StrucConsensusThread;
import java.awt.Color;
+import java.beans.PropertyChangeSupport;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.BitSet;
boolean recalc = false;
if (cs != null)
{
- cs.setConservationApplied(recalc = getConservationSelected());
+ recalc = getConservationSelected();
if (getAbovePIDThreshold() || cs instanceof PIDColourScheme
|| cs instanceof Blosum62ColourScheme)
{
cs.setConsensus(hconsensus);
cs.setConservation(hconservation);
}
+ cs.setConservationApplied(getConservationSelected());
cs.alignmentChanged(alignment, hiddenRepSequences);
}
if (getColourAppliesToAllGroups())
/**
* results of alignment consensus analysis for visible portion of view
*/
- protected Hashtable[] hconsensus = null;
+ protected Profile[] hconsensus = null;
/**
* results of cDNA complement consensus visible portion of view
}
@Override
- public void setSequenceConsensusHash(Hashtable[] hconsensus)
+ public void setSequenceConsensusHash(Profile[] hconsensus)
{
this.hconsensus = hconsensus;
}
}
@Override
- public Hashtable[] getSequenceConsensusHash()
+ public Profile[] getSequenceConsensusHash()
{
return hconsensus;
}
public void updateConservation(final AlignmentViewPanel ap)
{
// see note in mantis : issue number 8585
- if (alignment.isNucleotide() || conservation == null
+ if (alignment.isNucleotide()
+ || (conservation == null && quality == null)
|| !autoCalculateConsensus)
{
return;
&& !al.getCodonFrames().isEmpty())
{
/*
- * fudge - check first mapping is protein-to-nucleotide
+ * fudge - check first for protein-to-nucleotide mappings
* (we don't want to do this for protein-to-protein)
*/
- AlignedCodonFrame mapping = al.getCodonFrames().iterator().next();
- // TODO hold mapping type e.g. dna-to-protein in AlignedCodonFrame?
- MapList[] mapLists = mapping.getdnaToProt();
- // mapLists can be empty if project load has not finished resolving seqs
- if (mapLists.length > 0 && mapLists[0].getFromRatio() == 3)
+ boolean doConsensus = false;
+ for (AlignedCodonFrame mapping : al.getCodonFrames())
+ {
+ // TODO hold mapping type e.g. dna-to-protein in AlignedCodonFrame?
+ MapList[] mapLists = mapping.getdnaToProt();
+ // mapLists can be empty if project load has not finished resolving seqs
+ if (mapLists.length > 0 && mapLists[0].getFromRatio() == 3)
+ {
+ doConsensus = true;
+ break;
+ }
+ }
+ if (doConsensus)
{
if (calculator
.getRegisteredWorkersOfClass(ComplementConsensusThread.class) == null)
return false;
}
+ public void setAlignment(AlignmentI align)
+ {
+ this.alignment = align;
+ }
+
+ /**
+ * Clean up references when this viewport is closed
+ */
+ @Override
+ public void dispose()
+ {
+ /*
+ * defensively null out references to large objects in case
+ * this object is not garbage collected (as if!)
+ */
+ consensus = null;
+ complementConsensus = null;
+ strucConsensus = null;
+ conservation = null;
+ quality = null;
+ groupConsensus = null;
+ groupConservation = null;
+ hconsensus = null;
+ hcomplementConsensus = null;
+ // colour scheme may hold reference to consensus
+ globalColourScheme = null;
+ // TODO remove listeners from changeSupport?
+ changeSupport = null;
+ setAlignment(null);
+ }
+
@Override
public boolean isClosed()
{
}
@Override
+ public boolean hasSelectedColumns()
+ {
+ ColumnSelection columnSelection = getColumnSelection();
+ return columnSelection != null && columnSelection.hasSelectedColumns();
+ }
+
+ @Override
public boolean hasHiddenColumns()
{
return colSel != null && colSel.hasHiddenColumns();
return ignoreGapsInConsensusCalculation;
}
- // / property change stuff
-
+ // property change stuff
// JBPNote Prolly only need this in the applet version.
- private final java.beans.PropertyChangeSupport changeSupport = new java.beans.PropertyChangeSupport(
+ private PropertyChangeSupport changeSupport = new PropertyChangeSupport(
this);
protected boolean showConservation = true;
public boolean isHiddenRepSequence(SequenceI seq)
{
return (hiddenRepSequences != null && hiddenRepSequences
- .containsKey(seq));
+ .containsKey(seq));
}
/**
cs.setConsensus(hconsensus);
if (cs.conservationApplied())
{
- cs.setConservation(Conservation.calculateConservation("All",
- ResidueProperties.propHash, 3, alignment.getSequences(), 0,
- alignment.getWidth(), false, getConsPercGaps(), false));
+ cs.setConservation(Conservation.calculateConservation("All", 3,
+ alignment.getSequences(), 0, alignment.getWidth(), false,
+ getConsPercGaps(), false));
}
}
.getCodonFrames();
if (codonMappings != null && !codonMappings.isEmpty())
{
- // fudge: check mappings are not protein-to-protein
- // TODO: nicer
- AlignedCodonFrame mapping = codonMappings.iterator().next();
- MapList[] mapLists = mapping.getdnaToProt();
- // mapLists can be empty if project load has not finished resolving seqs
- if (mapLists.length > 0 && mapLists[0].getFromRatio() == 3)
+ boolean doConsensus = false;
+ for (AlignedCodonFrame mapping : codonMappings)
+ {
+ // TODO hold mapping type e.g. dna-to-protein in AlignedCodonFrame?
+ MapList[] mapLists = mapping.getdnaToProt();
+ // mapLists can be empty if project load has not finished resolving
+ // seqs
+ if (mapLists.length > 0 && mapLists[0].getFromRatio() == 3)
+ {
+ doConsensus = true;
+ break;
+ }
+ }
+ if (doConsensus)
{
complementConsensus = new AlignmentAnnotation("cDNA Consensus",
"PID for cDNA", new Annotation[1], 0f, 100f,
* all gapped visible regions
*/
int lastSeq = alignment.getHeight() - 1;
+ List<AlignedCodonFrame> seqMappings = null;
for (int seqNo = getStartSeq(); seqNo < lastSeq; seqNo++, seqOffset++)
{
sequence = getAlignment().getSequenceAt(seqNo);
{
continue;
}
- List<AlignedCodonFrame> seqMappings = MappingUtils
- .findMappingsForSequence(sequence, mappings);
+ seqMappings = MappingUtils
+ .findMappingsForSequenceAndOthers(sequence, mappings,
+ getCodingComplement().getAlignment().getSequences());
if (!seqMappings.isEmpty())
{
break;
}
}
- if (sequence == null)
+ if (sequence == null || seqMappings == null || seqMappings.isEmpty())
{
/*
* No ungapped mapped sequence in middle column - do nothing
return 0;
}
MappingUtils.addSearchResults(sr, sequence,
- sequence.findPosition(middleColumn), mappings);
+ sequence.findPosition(middleColumn), seqMappings);
return seqOffset;
}
public void expandColSelection(SequenceGroup sg, boolean wholewidth)
{
int sgs, sge;
- if (sg != null
- && (sgs = sg.getStartRes()) >= 0
+ if (sg != null && (sgs = sg.getStartRes()) >= 0
&& sg.getStartRes() <= (sge = sg.getEndRes())
- && (colSel == null || colSel.getSelected() == null || colSel
- .getSelected().size() == 0))
+ && !this.hasSelectedColumns())
{
if (!wholewidth && alignment.getWidth() == (1 + sge - sgs))
{
}
}
+ /**
+ * hold status of current selection group - defined on alignment or not.
+ */
+ private boolean selectionIsDefinedGroup = false;
+ @Override
+ public boolean isSelectionDefinedGroup()
+ {
+ if (selectionGroup == null)
+ {
+ return false;
+ }
+ if (isSelectionGroupChanged(true))
+ {
+ selectionIsDefinedGroup = false;
+ List<SequenceGroup> gps = alignment.getGroups();
+ if (gps == null || gps.size() == 0)
+ {
+ selectionIsDefinedGroup = false;
+ }
+ else
+ {
+ selectionIsDefinedGroup = gps.contains(selectionGroup);
+ }
+ }
+ return selectionGroup.getContext() == alignment
+ || selectionIsDefinedGroup;
+ }
}
import jalview.renderer.seqfeatures.FeatureRenderer;
import jalview.schemes.FeatureColour;
import jalview.schemes.UserColourScheme;
-import jalview.viewmodel.AlignmentViewport;
import java.awt.Color;
import java.beans.PropertyChangeListener;
protected PropertyChangeSupport changeSupport = new PropertyChangeSupport(
this);
- protected AlignmentViewport av;
+ protected AlignViewportI av;
@Override
public AlignViewportI getViewport()
@Override
public void setColour(String featureType, FeatureColourI col)
{
- featureColours.put(featureType, col);
+ featureColours.put(featureType, col);
}
public void setTransparency(float value)
public class AlignCalcManager implements AlignCalcManagerI
{
- private volatile List<AlignCalcWorkerI> restartable = Collections
- .synchronizedList(new ArrayList<AlignCalcWorkerI>());
+ /*
+ * list of registered workers
+ */
+ private volatile List<AlignCalcWorkerI> restartable;
- private volatile List<Class> blackList = Collections
- .synchronizedList(new ArrayList<Class>());
+ /*
+ * types of worker _not_ to run (for example, because they have
+ * previously thrown errors)
+ */
+ private volatile List<Class<? extends AlignCalcWorkerI>> blackList;
- /**
+ /*
* global record of calculations in progress
*/
- private volatile Map<Class, AlignCalcWorkerI> inProgress = Collections
- .synchronizedMap(new Hashtable<Class, AlignCalcWorkerI>());
+ private volatile List<AlignCalcWorkerI> inProgress;
- /**
+ /*
* record of calculations pending or in progress in the current context
*/
- private volatile Map<Class, List<AlignCalcWorkerI>> updating = Collections
- .synchronizedMap(new Hashtable<Class, List<AlignCalcWorkerI>>());
+ private volatile Map<Class<? extends AlignCalcWorkerI>, List<AlignCalcWorkerI>> updating;
+
+ /*
+ * workers that have run to completion so are candidates for visual-only
+ * update of their results
+ */
+ private HashSet<AlignCalcWorkerI> canUpdate;
+
+ /**
+ * Constructor
+ */
+ public AlignCalcManager()
+ {
+ restartable = Collections
+ .synchronizedList(new ArrayList<AlignCalcWorkerI>());
+ blackList = Collections
+ .synchronizedList(new ArrayList<Class<? extends AlignCalcWorkerI>>());
+ inProgress = Collections
+ .synchronizedList(new ArrayList<AlignCalcWorkerI>());
+ updating = Collections
+ .synchronizedMap(new Hashtable<Class<? extends AlignCalcWorkerI>, List<AlignCalcWorkerI>>());
+ canUpdate = new HashSet<AlignCalcWorkerI>();
+ }
@Override
public void notifyStart(AlignCalcWorkerI worker)
}
}
- @Override
- public boolean alreadyDoing(AlignCalcWorkerI worker)
- {
- synchronized (inProgress)
- {
- return inProgress.containsKey(worker.getClass());
- }
- }
-
/*
* (non-Javadoc)
*
}
}
- // TODO make into api method if needed ?
- public int numberLive(AlignCalcWorkerI worker)
- {
- synchronized (updating)
- {
- List<AlignCalcWorkerI> upd = updating.get(worker.getClass());
- if (upd == null)
- {
- return 0;
- }
- ;
- return upd.size();
- }
- }
-
@Override
public boolean notifyWorking(AlignCalcWorkerI worker)
{
synchronized (inProgress)
{
- // TODO: decide if we should throw exceptions here if multiple workers
- // start to work
- if (inProgress.get(worker.getClass()) != null)
+ if (inProgress.contains(worker))
{
- if (false)
- {
- System.err
- .println("Warning: Multiple workers are running of type "
- + worker.getClass());
- }
- return false;
+ return false; // worker is already working, so ask caller to wait around
+ }
+ else
+ {
+ inProgress.add(worker);
}
- inProgress.put(worker.getClass(), worker);
}
return true;
}
- private final HashSet<AlignCalcWorkerI> canUpdate = new HashSet<AlignCalcWorkerI>();
-
@Override
public void workerComplete(AlignCalcWorkerI worker)
{
synchronized (inProgress)
{
- // System.err.println("Worker "+worker.getClass()+" marked as complete.");
- inProgress.remove(worker.getClass());
+ // System.err.println("Worker " + worker + " marked as complete.");
+ inProgress.remove(worker);
List<AlignCalcWorkerI> upd = updating.get(worker.getClass());
if (upd != null)
{
}
@Override
- public void workerCannotRun(AlignCalcWorkerI worker)
+ public void disableWorker(AlignCalcWorkerI worker)
{
synchronized (blackList)
{
}
}
- public boolean isBlackListed(Class workerType)
+ @Override
+ public boolean isDisabled(AlignCalcWorkerI worker)
{
synchronized (blackList)
{
- return blackList.contains(workerType);
+ return blackList.contains(worker.getClass());
}
}
@Override
public void startWorker(AlignCalcWorkerI worker)
{
- // System.err.println("Starting "+worker.getClass());
- // new Exception("").printStackTrace();
- Thread tw = new Thread(worker);
- tw.setName(worker.getClass().toString());
- tw.start();
+ if (!isDisabled(worker))
+ {
+ Thread tw = new Thread(worker);
+ tw.setName(worker.getClass().toString());
+ tw.start();
+ }
}
@Override
synchronized (inProgress)
{// System.err.println("isWorking : worker "+(worker!=null ?
// worker.getClass():"null")+ " "+hashCode());
- return worker != null && inProgress.get(worker.getClass()) == worker;
+ return worker != null && inProgress.contains(worker);
}
}
{
synchronized (inProgress)
{
- for (AlignCalcWorkerI worker : inProgress.values())
+ for (AlignCalcWorkerI worker : inProgress)
{
if (worker.involves(alignmentAnnotation))
{
}
@Override
- public void updateAnnotationFor(Class workerClass)
+ public void updateAnnotationFor(
+ Class<? extends AlignCalcWorkerI> workerClass)
{
AlignCalcWorkerI[] workers;
@Override
public List<AlignCalcWorkerI> getRegisteredWorkersOfClass(
- Class workerClass)
+ Class<? extends AlignCalcWorkerI> workerClass)
{
List<AlignCalcWorkerI> workingClass = new ArrayList<AlignCalcWorkerI>();
- AlignCalcWorkerI[] workers;
synchronized (canUpdate)
{
- workers = canUpdate.toArray(new AlignCalcWorkerI[canUpdate.size()]);
- }
- for (AlignCalcWorkerI worker : workers)
- {
- if (workerClass.equals(worker.getClass()))
+ for (AlignCalcWorkerI worker : canUpdate)
{
- workingClass.add(worker);
+ if (workerClass.equals(worker.getClass()))
+ {
+ workingClass.add(worker);
+ }
}
}
return (workingClass.size() == 0) ? null : workingClass;
}
@Override
- public boolean startRegisteredWorkersOfClass(Class workerClass)
- {
- List<AlignCalcWorkerI> workers = getRegisteredWorkersOfClass(workerClass);
- if (workers == null)
- {
- return false;
- }
- for (AlignCalcWorkerI worker : workers)
- {
- if (!isPending(worker))
- {
- startWorker(worker);
- }
- else
- {
- System.err.println("Pending exists for " + workerClass);
- }
- }
- return true;
- }
-
- @Override
- public void workerMayRun(AlignCalcWorkerI worker)
+ public void enableWorker(AlignCalcWorkerI worker)
{
synchronized (blackList)
{
- if (blackList.contains(worker.getClass()))
- {
- blackList.remove(worker.getClass());
- }
+ blackList.remove(worker.getClass());
}
}
@Override
- public void removeRegisteredWorkersOfClass(Class typeToRemove)
+ public void removeRegisteredWorkersOfClass(
+ Class<? extends AlignCalcWorkerI> typeToRemove)
{
- List<AlignCalcWorkerI> workers = getRegisteredWorkersOfClass(typeToRemove);
List<AlignCalcWorkerI> removable = new ArrayList<AlignCalcWorkerI>();
Set<AlignCalcWorkerI> toremovannot = new HashSet<AlignCalcWorkerI>();
synchronized (restartable)
* else { System.err.println("Pending exists for " + workerClass); } }
*/
}
+
+ /**
+ * Deletes the worker that update the given annotation, provided it is marked
+ * as deletable.
+ */
+ @Override
+ public void removeWorkerForAnnotation(AlignmentAnnotation ann)
+ {
+ /*
+ * first just find those to remove (to avoid
+ * ConcurrentModificationException)
+ */
+ List<AlignCalcWorkerI> toRemove = new ArrayList<AlignCalcWorkerI>();
+ for (AlignCalcWorkerI worker : restartable)
+ {
+ if (worker.involves(ann))
+ {
+ if (worker.isDeletable())
+ {
+ toRemove.add(worker);
+ }
+ }
+ }
+
+ /*
+ * remove all references to deleted workers so any references
+ * they hold to annotation data can be garbage collected
+ */
+ for (AlignCalcWorkerI worker : toRemove)
+ {
+ restartable.remove(worker);
+ blackList.remove(worker.getClass());
+ inProgress.remove(worker);
+ canUpdate.remove(worker);
+ synchronized (updating)
+ {
+ List<AlignCalcWorkerI> upd = updating.get(worker.getClass());
+ if (upd != null)
+ {
+ upd.remove(worker);
+ }
+ }
+ }
+ }
}
import jalview.api.AlignmentViewPanel;
import jalview.datamodel.AlignmentAnnotation;
import jalview.datamodel.AlignmentI;
+import jalview.datamodel.Annotation;
import java.util.List;
ourAnnots.clear();
}
}
+
// TODO: allow GUI to query workers associated with annotation to add items to
// annotation label panel popup menu
+ @Override
+ public boolean isDeletable()
+ {
+ return false;
+ }
+
+ /**
+ * Calculate min and max values of annotations and set as graphMin, graphMax
+ * on the AlignmentAnnotation. This is needed because otherwise, well, bad
+ * things happen.
+ *
+ * @param ann
+ * @param anns
+ */
+ protected void setGraphMinMax(AlignmentAnnotation ann, Annotation[] anns)
+ {
+ // TODO feels like this belongs inside AlignmentAnnotation!
+ float max = Float.MIN_VALUE;
+ float min = Float.MAX_VALUE;
+ boolean set = false;
+ for (Annotation a : anns)
+ {
+ if (a != null)
+ {
+ set = true;
+ float val = a.value;
+ max = Math.max(max, val);
+ min = Math.min(min, val);
+ }
+ }
+ if (set)
+ {
+ ann.graphMin = min;
+ ann.graphMax = max;
+ }
+ }
+
}
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
package jalview.workers;
+import jalview.api.AlignViewportI;
+import jalview.api.AlignmentViewPanel;
import jalview.bin.Jalview;
import jalview.datamodel.AlignmentAnnotation;
import jalview.datamodel.Annotation;
* such as Groovy) to 'register and forget' an alignment annotation calculator. <br>
* Currently supports two flavours of calculator:
* <ul>
- * <li>a 'feature counter' which can count any desired property derivable from
+ * <li>a simple 'feature counter' which counts any desired score derivable from
* residue value and any sequence features at each position of the alignment</li>
- * <li>a 'general purpose' calculator which computes one more complete
+ * <li>a 'general purpose' calculator which computes one or more complete
* AlignmentAnnotation objects</li>
* </ul>
*/
*/
public static void newCalculator(FeatureCounterI counter)
{
- if (Jalview.getCurrentAlignFrame() != null)
+ // TODO need an interface for AlignFrame by which to access
+ // its AlignViewportI and AlignmentViewPanel
+ AlignmentViewPanel currentAlignFrame = Jalview.getCurrentAlignFrame().alignPanel;
+ if (currentAlignFrame != null)
{
- newCalculator(Jalview.getCurrentAlignFrame(), counter);
+ newCalculator(currentAlignFrame.getAlignViewport(),
+ currentAlignFrame, counter);
}
else
{
/**
* Constructs and registers a new alignment annotation worker
*
- * @param af
- * the AlignFrame for which the annotation is to be calculated
+ * @param viewport
+ * @param panel
* @param counter
* provider of feature counts per alignment position
*/
- public static void newCalculator(AlignFrame af, FeatureCounterI counter)
+ public static void newCalculator(AlignViewportI viewport,
+ AlignmentViewPanel panel, FeatureCounterI counter)
{
- new ColumnCounterWorker(af, counter);
+ new ColumnCounterWorker(viewport, panel, counter);
}
/**
*/
public static void newCalculator(AnnotationProviderI calculator)
{
- if (Jalview.getCurrentAlignFrame() != null)
+ // TODO need an interface for AlignFrame by which to access
+ // its AlignViewportI and AlignmentViewPanel
+ AlignFrame currentAlignFrame = Jalview.getCurrentAlignFrame();
+ if (currentAlignFrame != null)
{
- newCalculator(Jalview.getCurrentAlignFrame(), calculator);
+ newCalculator(currentAlignFrame.getViewport(), currentAlignFrame
+ .getAlignPanels().get(0), calculator);
}
else
{
/**
* Constructs and registers a new alignment annotation worker
*
- * @param af
- * the AlignFrame for which the annotation is to be calculated
+ * @param viewport
+ * @param panel
* @param calculator
* provider of AlignmentAnnotation for the alignment
*/
- public static void newCalculator(AlignFrame af,
- AnnotationProviderI calculator)
+ public static void newCalculator(AlignViewportI viewport,
+ AlignmentViewPanel panel, AnnotationProviderI calculator)
{
- new AnnotationWorker(af, calculator);
+ new AnnotationWorker(viewport, panel, calculator);
}
/**
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
package jalview.workers;
+import jalview.api.FeatureRenderer;
import jalview.datamodel.AlignmentAnnotation;
import jalview.datamodel.AlignmentI;
-import jalview.gui.FeatureRenderer;
import java.util.List;
*/
package jalview.workers;
+import jalview.api.AlignViewportI;
+import jalview.api.AlignmentViewPanel;
import jalview.datamodel.AlignmentAnnotation;
import jalview.datamodel.AlignmentI;
-import jalview.gui.AlignFrame;
-import jalview.gui.AlignmentPanel;
-import jalview.gui.FeatureRenderer;
+import jalview.renderer.seqfeatures.FeatureRenderer;
import java.util.ArrayList;
import java.util.List;
/**
* A class to create and update one or more alignment annotations, given a
- * 'calculator'.
- *
+ * 'calculator'. Intended to support a 'plug-in' annotation worker which
+ * implements the AnnotationProviderI interface.
*/
class AnnotationWorker extends AlignCalcWorker
{
* @param af
* @param counter
*/
- public AnnotationWorker(AlignFrame af, AnnotationProviderI counter)
+ public AnnotationWorker(AlignViewportI viewport,
+ AlignmentViewPanel panel, AnnotationProviderI counter)
{
- super(af.getViewport(), af.alignPanel);
+ super(viewport, panel);
ourAnnots = new ArrayList<AlignmentAnnotation>();
this.counter = counter;
calcMan.registerWorker(this);
return;
}
- removeAnnotations();
+ // removeAnnotation();
AlignmentI alignment = alignViewport.getAlignment();
if (alignment != null)
{
try
{
List<AlignmentAnnotation> anns = counter.calculateAnnotation(
- alignment, new FeatureRenderer((AlignmentPanel) ap));
+ alignment, new FeatureRenderer(alignViewport));
for (AlignmentAnnotation ann : anns)
{
- ann.showAllColLabels = true;
- ann.graph = AlignmentAnnotation.BAR_GRAPH;
- ourAnnots.add(ann);
- alignment.addAnnotation(ann);
+ AlignmentAnnotation theAnn = alignment.findOrCreateAnnotation(
+ ann.label, ann.description, false, null, null);
+ theAnn.showAllColLabels = true;
+ theAnn.graph = AlignmentAnnotation.BAR_GRAPH;
+ theAnn.scaleColLabel = true;
+ theAnn.annotations = ann.annotations;
+ setGraphMinMax(theAnn, theAnn.annotations);
+ theAnn.validateRangeAndDisplay();
+ if (!ourAnnots.contains(theAnn))
+ {
+ ourAnnots.add(theAnn);
+ }
+ // alignment.addAnnotation(ann);
}
} catch (IndexOutOfBoundsException x)
{
} catch (OutOfMemoryError error)
{
ap.raiseOOMWarning("calculating annotations", error);
- calcMan.workerCannotRun(this);
+ calcMan.disableWorker(this);
} finally
{
calcMan.workerComplete(this);
ap.adjustAnnotationHeight();
ap.paintAlignment(true);
}
-
}
- /**
- * Remove all our annotations before re-calculating them
- */
- void removeAnnotations()
+ @Override
+ public void updateAnnotation()
{
- for (AlignmentAnnotation ann : ourAnnots)
- {
- alignViewport.getAlignment().deleteAnnotation(ann);
- }
- ourAnnots.clear();
+ // do nothing
}
+ /**
+ * Answers true to indicate that if this worker's annotation is deleted from
+ * the display, the worker should also be removed. This prevents it running
+ * and recreating the annotation when the alignment changes.
+ */
@Override
- public void updateAnnotation()
+ public boolean isDeletable()
{
- // do nothing
+ return true;
}
}
*/
package jalview.workers;
+import jalview.api.AlignViewportI;
+import jalview.api.AlignmentViewPanel;
import jalview.datamodel.AlignmentAnnotation;
import jalview.datamodel.AlignmentI;
import jalview.datamodel.Annotation;
import jalview.datamodel.SequenceFeature;
import jalview.datamodel.SequenceI;
-import jalview.gui.AlignFrame;
-import jalview.gui.AlignmentPanel;
-import jalview.gui.FeatureRenderer;
+import jalview.renderer.seqfeatures.FeatureRenderer;
import jalview.util.ColorUtils;
import jalview.util.Comparison;
* @param af
* @param counter
*/
- public ColumnCounterWorker(AlignFrame af, FeatureCounterI counter)
+ public ColumnCounterWorker(AlignViewportI viewport,
+ AlignmentViewPanel panel, FeatureCounterI counter)
{
- super(af.getViewport(), af.alignPanel);
+ super(viewport, panel);
ourAnnots = new ArrayList<AlignmentAnnotation>();
this.counter = counter;
calcMan.registerWorker(this);
return;
}
- removeAnnotation();
if (alignViewport.getAlignment() != null)
{
try
} catch (OutOfMemoryError error)
{
ap.raiseOOMWarning("calculating feature counts", error);
- calcMan.workerCannotRun(this);
+ calcMan.disableWorker(this);
} finally
{
calcMan.workerComplete(this);
*/
void computeAnnotations()
{
- FeatureRenderer fr = new FeatureRenderer((AlignmentPanel) ap);
+ FeatureRenderer fr = new FeatureRenderer(alignViewport);
// TODO use the commented out code once JAL-2075 is fixed
// to get adequate performance on genomic length sequence
AlignmentI alignment = alignViewport.getAlignment();
{
Color color = ColorUtils.getGraduatedColour(count, 0, Color.cyan,
max, Color.blue);
- anns[i] = new Annotation(String.valueOf(count),
- String.valueOf(count), '0', count, color);
+ String str = String.valueOf(count);
+ anns[i] = new Annotation(str, str, '0', count, color);
}
}
/*
- * construct the annotation, save it and add it to the displayed alignment
+ * construct or update the annotation
*/
- AlignmentAnnotation ann = new AlignmentAnnotation(counter.getName(),
- counter.getDescription(), anns);
+ AlignmentAnnotation ann = alignViewport.getAlignment()
+ .findOrCreateAnnotation(counter.getName(),
+ counter.getDescription(), false, null, null);
+ ann.description = counter.getDescription();
ann.showAllColLabels = true;
+ ann.scaleColLabel = true;
ann.graph = AlignmentAnnotation.BAR_GRAPH;
- ourAnnots.add(ann);
- alignViewport.getAlignment().addAnnotation(ann);
+ ann.annotations = anns;
+ setGraphMinMax(ann, anns);
+ ann.validateRangeAndDisplay();
+ if (!ourAnnots.contains(ann))
+ {
+ ourAnnots.add(ann);
+ }
}
/**
{
// do nothing
}
+
+ /**
+ * Answers true to indicate that if this worker's annotation is deleted from
+ * the display, the worker should also be removed. This prevents it running
+ * and recreating the annotation when the alignment changes.
+ */
+ @Override
+ public boolean isDeletable()
+ {
+ return true;
+ }
}
* @param consensusData
* the computed consensus data
*/
- @Override
protected void deriveConsensus(AlignmentAnnotation consensusAnnotation,
Hashtable[] consensusData)
{
alignViewport.isShowSequenceLogo(), getSequences().length);
}
+ @Override
+ public void updateResultAnnotation(boolean immediate)
+ {
+ AlignmentAnnotation consensus = getConsensusAnnotation();
+ Hashtable[] hconsensus = getViewportConsensus();
+ if (immediate || !calcMan.isWorking(this) && consensus != null
+ && hconsensus != null)
+ {
+ deriveConsensus(consensus, hconsensus);
+ }
+ }
+
}
package jalview.workers;
import jalview.analysis.AAFrequency;
+import jalview.analysis.Profile;
import jalview.api.AlignViewportI;
import jalview.api.AlignmentViewPanel;
import jalview.datamodel.AlignmentAnnotation;
import jalview.datamodel.SequenceI;
import jalview.schemes.ColourSchemeI;
-import java.util.Hashtable;
-
public class ConsensusThread extends AlignCalcWorker
{
public ConsensusThread(AlignViewportI alignViewport,
}
} catch (OutOfMemoryError error)
{
- calcMan.workerCannotRun(this);
+ calcMan.disableWorker(this);
ap.raiseOOMWarning("calculating consensus", error);
} finally
{
*/
protected void computeConsensus(AlignmentI alignment)
{
- Hashtable[] hconsensus = new Hashtable[alignment.getWidth()];
+ Profile[] hconsensus = new Profile[alignment.getWidth()];
SequenceI[] aseqs = getSequences();
AAFrequency.calculate(aseqs, 0, alignment.getWidth(), hconsensus, true);
/**
* @param hconsensus
*/
- protected void setColourSchemeConsensus(Hashtable[] hconsensus)
+ protected void setColourSchemeConsensus(Profile[] hconsensus)
{
ColourSchemeI globalColourScheme = alignViewport
.getGlobalColourScheme();
public void updateResultAnnotation(boolean immediate)
{
AlignmentAnnotation consensus = getConsensusAnnotation();
- Hashtable[] hconsensus = getViewportConsensus();
+ Profile[] hconsensus = (Profile[]) getViewportConsensus();
if (immediate || !calcMan.isWorking(this) && consensus != null
&& hconsensus != null)
{
*
* @param consensusAnnotation
* the annotation to be populated
- * @param consensusData
+ * @param hconsensus
* the computed consensus data
*/
protected void deriveConsensus(AlignmentAnnotation consensusAnnotation,
- Hashtable[] consensusData)
+ Profile[] hconsensus)
{
long nseq = getSequences().length;
- AAFrequency.completeConsensus(consensusAnnotation, consensusData, 0,
- consensusData.length, alignViewport.isIgnoreGapsConsensus(),
+ AAFrequency.completeConsensus(consensusAnnotation, hconsensus, 0,
+ hconsensus.length, alignViewport.isIgnoreGapsConsensus(),
alignViewport.isShowSequenceLogo(), nseq);
}
*
* @return
*/
- protected Hashtable[] getViewportConsensus()
+ protected Object[] getViewportConsensus()
{
+ // TODO convert ComplementConsensusThread to use Profile
return alignViewport.getSequenceConsensusHash();
}
}
}
try
{
- cons = Conservation.calculateConservation("All",
- jalview.schemes.ResidueProperties.propHash, 3,
+ cons = Conservation.calculateConservation("All", 3,
alignment.getSequences(), 0, alWidth - 1, false,
ConsPercGaps, quality != null);
} catch (IndexOutOfBoundsException x)
} catch (OutOfMemoryError error)
{
ap.raiseOOMWarning("calculating conservation", error);
- calcMan.workerCannotRun(this);
+ calcMan.disableWorker(this);
// alignViewport.conservation = null;
// this.alignViewport.quality = null;
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
package jalview.workers;
import jalview.datamodel.SequenceFeature;
updateResultAnnotation(true);
} catch (OutOfMemoryError error)
{
- calcMan.workerCannotRun(this);
+ calcMan.disableWorker(this);
// consensus = null;
// hconsensus = null;
import jalview.util.MessageManager;
import jalview.viewmodel.seqfeatures.FeatureRendererSettings;
-import java.util.LinkedHashSet;
+import java.util.ArrayList;
import java.util.List;
-import java.util.Set;
public abstract class AWSThread extends Thread
{
/**
* dataset sequence relationships to be propagated onto new results
*/
- protected Set<AlignedCodonFrame> codonframe = null;
+ protected List<AlignedCodonFrame> codonframe = null;
/**
* are there jobs still running in this thread.
.getCodonFrames();
if (cf != null)
{
- codonframe = new LinkedHashSet<AlignedCodonFrame>();
+ codonframe = new ArrayList<AlignedCodonFrame>();
codonframe.addAll(cf);
}
}
import jalview.datamodel.SequenceFeature;
import jalview.datamodel.SequenceI;
import jalview.gui.CutAndPasteTransfer;
+import jalview.gui.DasSourceBrowser;
import jalview.gui.Desktop;
import jalview.gui.FeatureSettings;
import jalview.gui.IProgressIndicator;
import jalview.gui.OOMWarning;
+import jalview.util.DBRefUtils;
import jalview.util.MessageManager;
import jalview.ws.dbsources.das.api.jalviewSourceI;
+import jalview.ws.dbsources.das.datamodel.DasSequenceSource;
import jalview.ws.seqfetcher.DbSourceProxy;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.List;
import java.util.Vector;
import uk.ac.ebi.picr.model.UPEntry;
+import uk.ac.ebi.www.picr.AccessionMappingService.AccessionMapperServiceLocator;
/**
* Implements a runnable for validating a sequence against external databases
*/
public class DBRefFetcher implements Runnable
{
+ private static final String NEWLINE = System.lineSeparator();
+
public interface FetchFinishedListenerI
{
void finished();
}
- private List<FetchFinishedListenerI> listeners;
-
SequenceI[] dataset;
IProgressIndicator progressWindow;
CutAndPasteTransfer output = new CutAndPasteTransfer();
- StringBuffer sbuffer = new StringBuffer();
-
boolean running = false;
/**
*/
uk.ac.ebi.www.picr.AccessionMappingService.AccessionMapperInterface picrClient = null;
- // /This will be a collection of Vectors of sequenceI refs.
+ // This will be a collection of Vectors of sequenceI refs.
// The key will be the seq name or accession id of the seq
- Hashtable seqRefs;
+ Hashtable<String, Vector<SequenceI>> seqRefs;
DbSourceProxy[] dbSources;
SequenceFetcher sfetcher;
+ private List<FetchFinishedListenerI> listeners;
+
private SequenceI[] alseqs;
- /**
+ /*
* when true - retrieved sequences will be trimmed to cover longest derived
* alignment sequence
*/
*/
public DBRefFetcher(SequenceI[] seqs,
IProgressIndicator progressIndicatorFrame,
- DbSourceProxy[] sources, FeatureSettings featureSettings, boolean isNucleotide)
+ DbSourceProxy[] sources, FeatureSettings featureSettings,
+ boolean isNucleotide)
{
listeners = new ArrayList<FetchFinishedListenerI>();
this.progressWindow = progressIndicatorFrame;
trimDsSeqs = Cache.getDefault("TRIM_FETCHED_DATASET_SEQS", true);
if (sources == null)
{
- // af.featureSettings_actionPerformed(null);
- String[] defdb = null, otherdb = sfetcher
- .getDbInstances(jalview.ws.dbsources.das.datamodel.DasSequenceSource.class);
- List<DbSourceProxy> selsources = new ArrayList<DbSourceProxy>();
- Vector<jalviewSourceI> dasselsrc = (featureSettings != null) ? featureSettings
- .getSelectedSources() : new jalview.gui.DasSourceBrowser()
- .getSelectedSources();
- Enumeration<jalviewSourceI> en = dasselsrc.elements();
- while (en.hasMoreElements())
+ setDatabaseSources(featureSettings, isNucleotide);
+ }
+ else
+ {
+ // we assume the caller knows what they're doing and ensured that all the
+ // db source names are valid
+ dbSources = sources;
+ }
+ }
+
+ /**
+ * Helper method to configure the list of database sources to query
+ *
+ * @param featureSettings
+ * @param forNucleotide
+ */
+ void setDatabaseSources(FeatureSettings featureSettings,
+ boolean forNucleotide)
+ {
+ // af.featureSettings_actionPerformed(null);
+ String[] defdb = null;
+ List<DbSourceProxy> selsources = new ArrayList<DbSourceProxy>();
+ Vector<jalviewSourceI> dasselsrc = (featureSettings != null) ? featureSettings
+ .getSelectedSources() : new DasSourceBrowser()
+ .getSelectedSources();
+
+ for (jalviewSourceI src : dasselsrc)
+ {
+ List<DbSourceProxy> sp = src.getSequenceSourceProxies();
+ if (sp != null)
{
- jalviewSourceI src = en.nextElement();
- List<DbSourceProxy> sp = src.getSequenceSourceProxies();
- if (sp != null)
+ selsources.addAll(sp);
+ if (sp.size() > 1)
{
- selsources.addAll(sp);
- if (sp.size() > 1)
- {
- Cache.log.debug("Added many Db Sources for :" + src.getTitle());
- }
+ Cache.log.debug("Added many Db Sources for :" + src.getTitle());
}
}
- // select appropriate databases based on alignFrame context.
- if (isNucleotide)
- {
- defdb = DBRefSource.DNACODINGDBS;
- }
- else
- {
- defdb = DBRefSource.PROTEINDBS;
- }
- List<DbSourceProxy> srces = new ArrayList<DbSourceProxy>();
- for (String ddb : defdb)
+ }
+ // select appropriate databases based on alignFrame context.
+ if (forNucleotide)
+ {
+ defdb = DBRefSource.DNACODINGDBS;
+ }
+ else
+ {
+ defdb = DBRefSource.PROTEINDBS;
+ }
+ List<DbSourceProxy> srces = new ArrayList<DbSourceProxy>();
+ for (String ddb : defdb)
+ {
+ List<DbSourceProxy> srcesfordb = sfetcher.getSourceProxy(ddb);
+ if (srcesfordb != null)
{
- List<DbSourceProxy> srcesfordb = sfetcher.getSourceProxy(ddb);
- if (srcesfordb != null)
+ for (DbSourceProxy src : srcesfordb)
{
- srces.addAll(srcesfordb);
+ if (!srces.contains(src))
+ {
+ srces.addAll(srcesfordb);
+ }
}
}
-
- // append the selected sequence sources to the default dbs
- srces.addAll(selsources);
- dbSources = srces.toArray(new DbSourceProxy[0]);
- }
- else
- {
- // we assume the caller knows what they're doing and ensured that all the
- // db source names are valid
- dbSources = sources;
}
+ // append the PDB data source, since it is 'special', catering for both
+ // nucleotide and protein
+ // srces.addAll(sfetcher.getSourceProxy(DBRefSource.PDB));
+
+ srces.addAll(selsources);
+ dbSources = srces.toArray(new DbSourceProxy[srces.size()]);
}
/**
}
// append additional sources
DbSourceProxy[] otherdb = sfetcher
- .getDbSourceProxyInstances(jalview.ws.dbsources.das.datamodel.DasSequenceSource.class);
+ .getDbSourceProxyInstances(DasSequenceSource.class);
if (otherdb != null && otherdb.length > 0)
{
DbSourceProxy[] newsrc = new DbSourceProxy[dbSources.length
*/
public void fetchDBRefs(boolean waitTillFinished)
{
+ // TODO can we not simply write
+ // if (waitTillFinished) { run(); } else { new Thread(this).start(); }
+
Thread thread = new Thread(this);
thread.start();
running = true;
{
key = key.toUpperCase();
- Vector seqs;
+ Vector<SequenceI> seqs;
if (seqRefs.containsKey(key))
{
- seqs = (Vector) seqRefs.get(key);
+ seqs = seqRefs.get(key);
if (seqs != null && !seqs.contains(seq))
{
}
else if (seqs == null)
{
- seqs = new Vector();
+ seqs = new Vector<SequenceI>();
seqs.addElement(seq);
}
}
else
{
- seqs = new Vector();
+ seqs = new Vector<SequenceI>();
seqs.addElement(seq);
}
{
progressWindow.setProgressBar(
MessageManager.getString("status.fetching_db_refs"),
- startTime);
+ startTime);
}
try
{
if (Cache.getDefault("DBREFFETCH_USEPICR", false))
{
- picrClient = new uk.ac.ebi.www.picr.AccessionMappingService.AccessionMapperServiceLocator()
+ picrClient = new AccessionMapperServiceLocator()
.getAccessionMapperPort();
}
} catch (Exception e)
System.err.println("Couldn't locate PICR service instance.\n");
e.printStackTrace();
}
+
+ Vector<SequenceI> sdataset = new Vector<SequenceI>(
+ Arrays.asList(dataset));
+ List<String> warningMessages = new ArrayList<String>();
+
int db = 0;
- Vector sdataset = new Vector();
- for (int s = 0; s < dataset.length; s++)
- {
- sdataset.addElement(dataset[s]);
- }
while (sdataset.size() > 0 && db < dbSources.length)
{
- int maxqlen = 1; // default number of queries made to at one time
- System.err.println("Verifying against " + dbSources[db].getDbName());
- boolean dn = false;
+ int maxqlen = 1; // default number of queries made at one time
+ System.out.println("Verifying against " + dbSources[db].getDbName());
// iterate through db for each remaining un-verified sequence
SequenceI[] currSeqs = new SequenceI[sdataset.size()];
sdataset.copyInto(currSeqs);// seqs that are to be validated against
// dbSources[db]
- Vector queries = new Vector(); // generated queries curSeq
- seqRefs = new Hashtable();
+ Vector<String> queries = new Vector<String>(); // generated queries curSeq
+ seqRefs = new Hashtable<String, Vector<SequenceI>>();
int seqIndex = 0;
- jalview.ws.seqfetcher.DbSourceProxy dbsource = dbSources[db];
+ DbSourceProxy dbsource = dbSources[db];
+ // for moment, we dumbly iterate over all retrieval sources for a
+ // particular database
+ // TODO: introduce multithread multisource queries and logic to remove a
+ // query from other sources if any source for a database returns a
+ // record
+ maxqlen = dbsource.getMaximumQueryCount();
+
+ while (queries.size() > 0 || seqIndex < currSeqs.length)
{
- // for moment, we dumbly iterate over all retrieval sources for a
- // particular database
- // TODO: introduce multithread multisource queries and logic to remove a
- // query from other sources if any source for a database returns a
- // record
- maxqlen = dbsource.getMaximumQueryCount();
-
- while (queries.size() > 0 || seqIndex < currSeqs.length)
+ if (queries.size() > 0)
{
- if (queries.size() > 0)
- {
- // Still queries to make for current seqIndex
- StringBuffer queryString = new StringBuffer("");
- int numq = 0, nqSize = (maxqlen > queries.size()) ? queries
- .size() : maxqlen;
+ // Still queries to make for current seqIndex
+ StringBuffer queryString = new StringBuffer("");
+ int numq = 0;
+ int nqSize = (maxqlen > queries.size()) ? queries.size()
+ : maxqlen;
- while (queries.size() > 0 && numq < nqSize)
- {
- String query = (String) queries.elementAt(0);
- if (dbsource.isValidReference(query))
- {
- queryString.append((numq == 0) ? "" : dbsource
- .getAccessionSeparator());
- queryString.append(query);
- numq++;
- }
- // remove the extracted query string
- queries.removeElementAt(0);
- }
- // make the queries and process the response
- AlignmentI retrieved = null;
- try
- {
- if (jalview.bin.Cache.log.isDebugEnabled())
- {
- jalview.bin.Cache.log.debug("Querying "
- + dbsource.getDbName() + " with : '"
- + queryString.toString() + "'");
- }
- retrieved = dbsource.getSequenceRecords(queryString
- .toString());
- } catch (Exception ex)
- {
- ex.printStackTrace();
- } catch (OutOfMemoryError err)
+ while (queries.size() > 0 && numq < nqSize)
+ {
+ String query = queries.elementAt(0);
+ if (dbsource.isValidReference(query))
{
- new OOMWarning("retrieving database references ("
- + queryString.toString() + ")", err);
+ queryString.append((numq == 0) ? "" : dbsource
+ .getAccessionSeparator());
+ queryString.append(query);
+ numq++;
}
- if (retrieved != null)
+ // remove the extracted query string
+ queries.removeElementAt(0);
+ }
+ // make the queries and process the response
+ AlignmentI retrieved = null;
+ try
+ {
+ if (Cache.log.isDebugEnabled())
{
- transferReferences(sdataset, dbsource.getDbSource(),
- retrieved, trimDsSeqs);
+ Cache.log.debug("Querying " + dbsource.getDbName()
+ + " with : '" + queryString.toString() + "'");
}
+ retrieved = dbsource.getSequenceRecords(queryString.toString());
+ } catch (Exception ex)
+ {
+ ex.printStackTrace();
+ } catch (OutOfMemoryError err)
+ {
+ new OOMWarning("retrieving database references ("
+ + queryString.toString() + ")", err);
}
- else
+ if (retrieved != null)
{
- // make some more strings for use as queries
- for (int i = 0; (seqIndex < dataset.length) && (i < 50); seqIndex++, i++)
+ transferReferences(sdataset, dbsource.getDbSource(), retrieved,
+ trimDsSeqs, warningMessages);
+ }
+ }
+ else
+ {
+ // make some more strings for use as queries
+ for (int i = 0; (seqIndex < dataset.length) && (i < 50); seqIndex++, i++)
+ {
+ SequenceI sequence = dataset[seqIndex];
+ DBRefEntry[] uprefs = DBRefUtils.selectRefs(
+ sequence.getDBRefs(),
+ new String[] { dbsource.getDbSource() }); // jalview.datamodel.DBRefSource.UNIPROT
+ // });
+ // check for existing dbrefs to use
+ if (uprefs != null && uprefs.length > 0)
{
- SequenceI sequence = dataset[seqIndex];
- DBRefEntry[] uprefs = jalview.util.DBRefUtils.selectRefs(
- sequence.getDBRefs(),
- new String[] { dbsource.getDbSource() }); // jalview.datamodel.DBRefSource.UNIPROT
- // });
- // check for existing dbrefs to use
- if (uprefs != null && uprefs.length > 0)
+ for (int j = 0; j < uprefs.length; j++)
{
- for (int j = 0; j < uprefs.length; j++)
- {
- addSeqId(sequence, uprefs[j].getAccessionId());
- queries.addElement(uprefs[j].getAccessionId()
- .toUpperCase());
- }
+ addSeqId(sequence, uprefs[j].getAccessionId());
+ queries.addElement(uprefs[j].getAccessionId().toUpperCase());
}
- else
+ }
+ else
+ {
+ // generate queries from sequence ID string
+ StringTokenizer st = new StringTokenizer(sequence.getName(),
+ "|");
+ while (st.hasMoreTokens())
{
- // generate queries from sequence ID string
- StringTokenizer st = new StringTokenizer(
- sequence.getName(), "|");
- while (st.hasMoreTokens())
+ String token = st.nextToken();
+ UPEntry[] presp = null;
+ if (picrClient != null)
{
- String token = st.nextToken();
- UPEntry[] presp = null;
- if (picrClient != null)
+ // resolve the string against PICR to recover valid IDs
+ try
{
- // resolve the string against PICR to recover valid IDs
- try
- {
- presp = picrClient.getUPIForAccession(token, null,
- picrClient.getMappedDatabaseNames(), null,
- true);
- } catch (Exception e)
- {
- System.err.println("Exception with Picr for '"
- + token + "'\n");
- e.printStackTrace();
- }
- }
- if (presp != null && presp.length > 0)
+ presp = picrClient
+ .getUPIForAccession(token, null,
+ picrClient.getMappedDatabaseNames(),
+ null, true);
+ } catch (Exception e)
{
- for (int id = 0; id < presp.length; id++)
- {
- // construct sequences from response if sequences are
- // present, and do a transferReferences
- // otherwise transfer non sequence x-references directly.
- }
- System.out
- .println("Validated ID against PICR... (for what its worth):"
- + token);
- addSeqId(sequence, token);
- queries.addElement(token.toUpperCase());
+ System.err.println("Exception with Picr for '" + token
+ + "'\n");
+ e.printStackTrace();
}
- else
+ }
+ if (presp != null && presp.length > 0)
+ {
+ for (int id = 0; id < presp.length; id++)
{
- // if ()
- // System.out.println("Not querying source with token="+token+"\n");
- addSeqId(sequence, token);
- queries.addElement(token.toUpperCase());
+ // construct sequences from response if sequences are
+ // present, and do a transferReferences
+ // otherwise transfer non sequence x-references directly.
}
+ System.out
+ .println("Validated ID against PICR... (for what its worth):"
+ + token);
+ addSeqId(sequence, token);
+ queries.addElement(token.toUpperCase());
+ }
+ else
+ {
+ // if ()
+ // System.out.println("Not querying source with token="+token+"\n");
+ addSeqId(sequence, token);
+ queries.addElement(token.toUpperCase());
}
}
}
}
// advance to next database
db++;
- } // all databases have been queries.
- if (sbuffer.length() > 0)
+ } // all databases have been queried
+ if (!warningMessages.isEmpty())
{
- output.setText(MessageManager
- .getString("label.your_sequences_have_been_verified")
- + sbuffer.toString());
+ StringBuilder sb = new StringBuilder(warningMessages.size() * 30);
+ sb.append(MessageManager
+ .getString("label.your_sequences_have_been_verified"));
+ for (String msg : warningMessages)
+ {
+ sb.append(msg).append(NEWLINE);
+ }
+ output.setText(sb.toString());
+
Desktop.addInternalFrame(output,
- MessageManager.getString("label.sequence_names_updated"),
- 600, 300);
+ MessageManager.getString("label.sequences_updated"), 600, 300);
// The above is the dataset, we must now find out the index
// of the viewed sequence
/**
* Verify local sequences in seqRefs against the retrieved sequence database
- * records.
+ * records. Returns true if any sequence was modified as a result (start/end
+ * changed and/or sequence enlarged), else false.
*
+ * @param sdataset
+ * dataset sequences we are retrieving for
+ * @param dbSource
+ * database source we are retrieving from
+ * @param retrievedAl
+ * retrieved sequences as alignment
* @param trimDatasetSeqs
- *
+ * if true, sequences will not be enlarged to match longer retrieved
+ * sequences, only their start/end adjusted
+ * @param warningMessages
+ * a list of messages to add to
*/
- void transferReferences(Vector sdataset, String dbSource,
- AlignmentI retrievedAl, boolean trimDatasetSeqs) // File
- // file)
+ boolean transferReferences(Vector<SequenceI> sdataset, String dbSource,
+ AlignmentI retrievedAl, boolean trimDatasetSeqs,
+ List<String> warningMessages)
{
- System.out.println("trimming ? " + trimDatasetSeqs);
+ // System.out.println("trimming ? " + trimDatasetSeqs);
if (retrievedAl == null || retrievedAl.getHeight() == 0)
{
- return;
+ return false;
}
+
+ boolean modified = false;
SequenceI[] retrieved = recoverDbSequences(retrievedAl
.getSequencesArray());
SequenceI sequence = null;
- boolean transferred = false;
- StringBuffer messages = new StringBuffer();
-
- // Vector entries = new Uniprot().getUniprotEntries(file);
- int i, iSize = retrieved.length; // entries == null ? 0 : entries.size();
- // UniprotEntry entry;
- for (i = 0; i < iSize; i++)
+ for (SequenceI retrievedSeq : retrieved)
{
- SequenceI entry = retrieved[i]; // (UniprotEntry) entries.elementAt(i);
-
// Work out which sequences this sequence matches,
// taking into account all accessionIds and names in the file
- Vector sequenceMatches = new Vector();
+ Vector<SequenceI> sequenceMatches = new Vector<SequenceI>();
// look for corresponding accession ids
- DBRefEntry[] entryRefs = jalview.util.DBRefUtils.selectRefs(
- entry.getDBRefs(), new String[] { dbSource });
+ DBRefEntry[] entryRefs = DBRefUtils.selectRefs(
+ retrievedSeq.getDBRefs(), new String[] { dbSource });
if (entryRefs == null)
{
System.err
.println("Dud dbSource string ? no entryrefs selected for "
- + dbSource + " on " + entry.getName());
+ + dbSource + " on " + retrievedSeq.getName());
continue;
}
for (int j = 0; j < entryRefs.length; j++)
{
- String accessionId = entryRefs[j].getAccessionId(); // .getAccession().elementAt(j).toString();
+ String accessionId = entryRefs[j].getAccessionId();
// match up on accessionId
if (seqRefs.containsKey(accessionId.toUpperCase()))
{
- Vector seqs = (Vector) seqRefs.get(accessionId);
+ Vector<SequenceI> seqs = seqRefs.get(accessionId);
for (int jj = 0; jj < seqs.size(); jj++)
{
- sequence = (SequenceI) seqs.elementAt(jj);
+ sequence = seqs.elementAt(jj);
if (!sequenceMatches.contains(sequence))
{
sequenceMatches.addElement(sequence);
}
}
}
- if (sequenceMatches.size() == 0)
+ if (sequenceMatches.isEmpty())
{
// failed to match directly on accessionId==query so just compare all
// sequences to entry
- Enumeration e = seqRefs.keys();
+ Enumeration<String> e = seqRefs.keys();
while (e.hasMoreElements())
{
- Vector sqs = (Vector) seqRefs.get(e.nextElement());
+ Vector<SequenceI> sqs = seqRefs.get(e.nextElement());
if (sqs != null && sqs.size() > 0)
{
- Enumeration sqe = sqs.elements();
+ Enumeration<SequenceI> sqe = sqs.elements();
while (sqe.hasMoreElements())
{
sequenceMatches.addElement(sqe.nextElement());
*/
// sequenceMatches now contains the set of all sequences associated with
// the returned db record
- String entrySeq = entry.getSequenceAsString().toUpperCase();
+ final String retrievedSeqString = retrievedSeq.getSequenceAsString();
+ String entrySeq = retrievedSeqString.toUpperCase();
for (int m = 0; m < sequenceMatches.size(); m++)
{
- sequence = (SequenceI) sequenceMatches.elementAt(m);
+ sequence = sequenceMatches.elementAt(m);
// only update start and end positions and shift features if there are
// no existing references
// TODO: test for legacy where uniprot or EMBL refs exist but no
// TODO:
// verify sequence against the entry sequence
+ Mapping mp;
+ final int sequenceStart = sequence.getStart();
+
+ boolean remoteEnclosesLocal = false;
String nonGapped = AlignSeq.extractGaps("-. ",
sequence.getSequenceAsString()).toUpperCase();
-
int absStart = entrySeq.indexOf(nonGapped);
- Mapping mp;
-
- final int sequenceStart = sequence.getStart();
if (absStart == -1)
{
- // Is local sequence contained in dataset sequence?
+ // couldn't find local sequence in sequence from database, so check if
+ // the database sequence is a subsequence of local sequence
absStart = nonGapped.indexOf(entrySeq);
if (absStart == -1)
- { // verification failed.
- messages.append(sequence.getName()
- + " SEQUENCE NOT %100 MATCH \n");
+ {
+ // verification failed. couldn't find any relationship between
+ // entrySeq and local sequence
+ // messages suppressed as many-to-many matches are confusing
+ // String msg = sequence.getName()
+ // + " Sequence not 100% match with "
+ // + retrievedSeq.getName();
+ // addWarningMessage(warningMessages, msg);
continue;
}
- transferred = true;
- sbuffer.append(sequence.getName() + " HAS " + absStart
- + " PREFIXED RESIDUES COMPARED TO " + dbSource + "\n");
- //
- // + " - ANY SEQUENCE FEATURES"
- // + " HAVE BEEN ADJUSTED ACCORDINGLY \n");
- // absStart = 0;
- // create valid mapping between matching region of local sequence and
- // the mapped sequence
+ /*
+ * retrieved sequence is a proper subsequence of local sequence
+ */
+ String msg = sequence.getName() + " has " + absStart
+ + " prefixed residues compared to "
+ + retrievedSeq.getName();
+ addWarningMessage(warningMessages, msg);
+
+ /*
+ * So create a mapping to the external entry from the matching region of
+ * the local sequence, and leave local start/end untouched.
+ */
mp = new Mapping(null, new int[] { sequenceStart + absStart,
sequenceStart + absStart + entrySeq.length() - 1 }, new int[]
- { entry.getStart(), entry.getStart() + entrySeq.length() - 1 },
- 1, 1);
- updateRefFrame = false; // mapping is based on current start/end so
- // don't modify start and end
+ { retrievedSeq.getStart(),
+ retrievedSeq.getStart() + entrySeq.length() - 1 }, 1, 1);
+ updateRefFrame = false;
}
else
{
- transferred = true;
- // update start and end of local sequence to place it in entry's
- // reference frame.
- // apply identity map map from whole of local sequence to matching
- // region of database
- // sequence
- mp = null; // Mapping.getIdentityMap();
- // new Mapping(null,
- // new int[] { absStart+sequence.getStart(),
- // absStart+sequence.getStart()+entrySeq.length()-1},
- // new int[] { entry.getStart(), entry.getEnd() }, 1, 1);
- // relocate local features for updated start
+ /*
+ * local sequence is a subsequence of (or matches) retrieved sequence
+ */
+ remoteEnclosesLocal = true;
+ mp = null;
+
if (updateRefFrame)
{
- if (sequence.getSequenceFeatures() != null)
+ SequenceFeature[] sfs = sequence.getSequenceFeatures();
+ if (sfs != null)
{
- SequenceFeature[] sf = sequence.getSequenceFeatures();
+ /*
+ * relocate existing sequence features by offset
+ */
int start = sequenceStart;
int end = sequence.getEnd();
- int startShift = 1 - absStart - start; // how much the features
- // are
- // to be shifted by
- for (int sfi = 0; sfi < sf.length; sfi++)
+ int startShift = 1 - absStart - start;
+
+ if (startShift != 0)
{
- if (sf[sfi].getBegin() >= start && sf[sfi].getEnd() <= end)
+ for (SequenceFeature sf : sfs)
{
- // shift feature along by absstart
- sf[sfi].setBegin(sf[sfi].getBegin() + startShift);
- sf[sfi].setEnd(sf[sfi].getEnd() + startShift);
+ if (sf.getBegin() >= start && sf.getEnd() <= end)
+ {
+ sf.setBegin(sf.getBegin() + startShift);
+ sf.setEnd(sf.getEnd() + startShift);
+ modified = true;
+ }
}
}
}
}
System.out.println("Adding dbrefs to " + sequence.getName()
- + " from " + dbSource + " sequence : " + entry.getName());
- sequence.transferAnnotation(entry, mp);
- // unknownSequences.remove(sequence);
- absStart += entry.getStart();
+ + " from " + dbSource + " sequence : "
+ + retrievedSeq.getName());
+ sequence.transferAnnotation(retrievedSeq, mp);
+
+ absStart += retrievedSeq.getStart();
int absEnd = absStart + nonGapped.length() - 1;
if (!trimDatasetSeqs)
{
- // insert full length sequence from record
- sequence.setSequence(entry.getSequenceAsString());
- sequence.setStart(entry.getStart());
+ /*
+ * update start position and/or expand to longer retrieved sequence
+ */
+ if (!retrievedSeqString.equals(sequence.getSequenceAsString())
+ && remoteEnclosesLocal)
+ {
+ sequence.setSequence(retrievedSeqString);
+ modified = true;
+ addWarningMessage(warningMessages,
+ "Sequence for " + sequence.getName()
+ + " expanded from " + retrievedSeq.getName());
+ }
+ if (sequence.getStart() != retrievedSeq.getStart())
+ {
+ sequence.setStart(retrievedSeq.getStart());
+ modified = true;
+ if (absStart != sequenceStart)
+ {
+ addWarningMessage(warningMessages, "Start/end position for "
+ + sequence.getName() + " updated from "
+ + retrievedSeq.getName());
+ }
+ }
}
if (updateRefFrame)
{
if (trimDatasetSeqs)
{
// just fix start/end
- sequence.setStart(absStart);
- sequence.setEnd(absEnd);
+ if (sequence.getStart() != absStart
+ || sequence.getEnd() != absEnd)
+ {
+ sequence.setStart(absStart);
+ sequence.setEnd(absEnd);
+ modified = true;
+ addWarningMessage(warningMessages, "Start/end for "
+ + sequence.getName() + " updated from "
+ + retrievedSeq.getName());
+ }
}
// search for alignment sequences to update coordinate frame for
for (int alsq = 0; alsq < alseqs.length; alsq++)
{
alseqs[alsq].setEnd(ngAlsq.length()
+ alseqs[alsq].getStart() - 1);
+ modified = true;
}
}
}
// ids, so we can query all enabled DAS servers for them ?
}
}
- if (!transferred)
+ return modified;
+ }
+
+ /**
+ * Adds the message to the list unless it already contains it
+ *
+ * @param messageList
+ * @param msg
+ */
+ void addWarningMessage(List<String> messageList, String msg)
+ {
+ if (!messageList.contains(msg))
{
- // report the ID/sequence mismatches
- sbuffer.append(messages);
+ messageList.add(msg);
}
}
*/
private SequenceI[] recoverDbSequences(SequenceI[] sequencesArray)
{
- Vector nseq = new Vector();
+ Vector<SequenceI> nseq = new Vector<SequenceI>();
for (int i = 0; sequencesArray != null && i < sequencesArray.length; i++)
{
nseq.addElement(sequencesArray[i]);
- DBRefEntry dbr[] = sequencesArray[i].getDBRefs();
- jalview.datamodel.Mapping map = null;
+ DBRefEntry[] dbr = sequencesArray[i].getDBRefs();
+ Mapping map = null;
for (int r = 0; (dbr != null) && r < dbr.length; r++)
{
if ((map = dbr[r].getMap()) != null)
public void run()
{
running = true;
- boolean isNucleotide = af.getViewport().getAlignment()
- .isNucleotide();
+ boolean isNucleotide = af.getViewport().getAlignment().isNucleotide();
new DBRefFetcher(sequences, af, null, af.featureSettings,
isNucleotide).fetchDBRefs(true);
{
jalviewSourceI[] sources = sourceRegistry.getSources().toArray(
new jalviewSourceI[0]);
- String active = Cache.getDefault("DAS_ACTIVE_SOURCE",
- "uniprot");
+ String active = Cache.getDefault("DAS_ACTIVE_SOURCE", "uniprot");
StringTokenizer st = new StringTokenizer(active, "\t");
selectedSources = new Vector();
String token;
{
return null;
}
- DBRefEntry[] uprefs = DBRefUtils.selectRefs(
- seq.getDBRefs(), new String[] {
+ DBRefEntry[] uprefs = DBRefUtils.selectRefs(seq.getDBRefs(),
+ new String[] {
// jalview.datamodel.DBRefSource.PDB,
DBRefSource.UNIPROT,
// jalview.datamodel.DBRefSource.EMBL - not tested on any EMBL coord
for (COORDINATES csys : dasSource.getVersion().getCOORDINATES())
{
- if (DBRefUtils.isDasCoordinateSystem(
- csys.getAuthority(), uprefs[j]))
+ if (DBRefUtils.isDasCoordinateSystem(csys.getAuthority(),
+ uprefs[j]))
{
debug("Launched fetcher for coordinate system "
+ csys.getAuthority());
import jalview.ws.dbsources.Pdb;
import jalview.ws.dbsources.PfamFull;
import jalview.ws.dbsources.PfamSeed;
-import jalview.ws.dbsources.RfamFull;
import jalview.ws.dbsources.RfamSeed;
import jalview.ws.dbsources.Uniprot;
-import jalview.ws.dbsources.UniprotName;
import jalview.ws.dbsources.das.api.jalviewSourceI;
import jalview.ws.seqfetcher.ASequenceFetcher;
import jalview.ws.seqfetcher.DbSourceProxy;
addDBRefSourceImpl(EmblSource.class);
addDBRefSourceImpl(EmblCdsSource.class);
addDBRefSourceImpl(Uniprot.class);
- addDBRefSourceImpl(UniprotName.class);
addDBRefSourceImpl(Pdb.class);
addDBRefSourceImpl(PfamFull.class);
addDBRefSourceImpl(PfamSeed.class);
addDBRefSourceImpl(RfamSeed.class);
+
if (addDas)
{
registerDasSequenceSources();
--- /dev/null
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
+package jalview.ws;
+
+import jalview.ws.seqfetcher.ASequenceFetcher;
+
+public class SequenceFetcherFactory
+{
+
+ private static SequenceFetcher instance;
+
+ /**
+ * Returns a new SequenceFetcher object, or a mock object if one has been set
+ *
+ * @return
+ */
+ public static ASequenceFetcher getSequenceFetcher()
+ {
+ return instance == null ? new SequenceFetcher() : instance;
+ }
+
+ /**
+ * Set the instance object to use (intended for unit testing with mock
+ * objects).
+ *
+ * Be sure to reset to null in the tearDown method of any tests!
+ *
+ * @param sf
+ */
+ public static void setSequenceFetcher(SequenceFetcher sf)
+ {
+ instance = sf;
+ }
+}
}
}
+ /*
+ * invalid accession gets a reply with no <entry> elements, text content of
+ * EmbFile reads something like (e.g.) this ungrammatical phrase
+ * Entry: <acc> display type is either not supported or entry is not found.
+ */
List<SequenceI> peptides = new ArrayList<SequenceI>();
- if (efile != null)
+ if (efile != null && efile.getEntries() != null)
{
for (EmblEntry entry : efile.getEntries())
{
-
/*
* Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
* Copyright (C) $$Year-Rel$$ The Jalview Authors
import jalview.datamodel.DBRefEntry;
import jalview.datamodel.DBRefSource;
import jalview.datamodel.PDBEntry;
+import jalview.datamodel.PDBEntry.Type;
import jalview.datamodel.SequenceI;
import jalview.io.FormatAdapter;
import jalview.io.PDBFeatureSettings;
-import jalview.structure.StructureViewSettings;
+import jalview.structure.StructureImportSettings;
import jalview.util.MessageManager;
import jalview.ws.ebi.EBIFetchClient;
import java.util.ArrayList;
import java.util.List;
-import java.util.Vector;
import com.stevesoft.pat.Regex;
*/
public class Pdb extends EbiFileRetrievedProxy
{
+ private static final String SEPARATOR = "|";
+
+ private static final String COLON = ":";
+
+ private static final int PDB_ID_LENGTH = 4;
+
public Pdb()
{
super();
}
- public static final String FEATURE_INSERTION = "INSERTION";
-
- public static final String FEATURE_RES_NUM = "RESNUM";
-
/*
* (non-Javadoc)
*
@Override
public String getAccessionSeparator()
{
- // TODO Auto-generated method stub
return null;
}
public AlignmentI getSequenceRecords(String queries) throws Exception
{
AlignmentI pdbAlignment = null;
- Vector result = new Vector();
String chain = null;
String id = null;
- if (queries.indexOf(":") > -1)
+ if (queries.indexOf(COLON) > -1)
{
- chain = queries.substring(queries.indexOf(":") + 1);
- id = queries.substring(0, queries.indexOf(":"));
+ chain = queries.substring(queries.indexOf(COLON) + 1);
+ id = queries.substring(0, queries.indexOf(COLON));
}
else
{
id = queries;
}
- if (queries.length() > 4 && chain == null)
+
+ /*
+ * extract chain code if it is appended to the id and we
+ * don't already have one
+ */
+ if (queries.length() > PDB_ID_LENGTH && chain == null)
{
- chain = queries.substring(4, 5);
- id = queries.substring(0, 4);
+ chain = queries.substring(PDB_ID_LENGTH, PDB_ID_LENGTH + 1);
+ id = queries.substring(0, PDB_ID_LENGTH);
}
+
if (!isValidReference(id))
{
System.err.println("Ignoring invalid pdb query: '" + id + "'");
stopQuery();
return null;
}
- String ext = StructureViewSettings.getCurrentDefaultFormat()
- .equalsIgnoreCase("mmcif") ? ".cif"
- : ".xml";
+ String ext = StructureImportSettings.getDefaultStructureFileFormat()
+ .equalsIgnoreCase(Type.MMCIF.toString()) ? ".cif" : ".xml";
EBIFetchClient ebi = new EBIFetchClient();
- file = ebi.fetchDataAsFile("pdb:" + id,
- StructureViewSettings.getCurrentDefaultFormat().toLowerCase(),
- ext)
- .getAbsolutePath();
+ file = ebi.fetchDataAsFile(
+ "pdb:" + id,
+ StructureImportSettings.getDefaultStructureFileFormat()
+ .toLowerCase(), ext).getAbsolutePath();
stopQuery();
if (file == null)
{
pdbAlignment = new FormatAdapter().readFile(file,
jalview.io.AppletFormatAdapter.FILE,
- StructureViewSettings.getCurrentDefaultFormat());
+ StructureImportSettings.getDefaultStructureFileFormat());
if (pdbAlignment != null)
{
List<SequenceI> toremove = new ArrayList<SequenceI>();
chid = pid.getChainCode();
}
- ;
-
}
if (chain == null
|| (chid != null && (chid.equals(chain)
|| chid.trim().equals(chain.trim()) || (chain
.trim().length() == 0 && chid.equals("_")))))
{
- pdbcs.setName(jalview.datamodel.DBRefSource.PDB + "|" + id
- + "|" + pdbcs.getName());
+ // FIXME seems to result in 'PDB|1QIP|1qip|A' - 1QIP is redundant.
+ // TODO: suggest simplify naming to 1qip|A as default name defined
+ pdbcs.setName(jalview.datamodel.DBRefSource.PDB + SEPARATOR
+ + id + SEPARATOR + pdbcs.getName());
// Might need to add more metadata to the PDBEntry object
// like below
/*
return 0;
}
-
/**
* Returns a descriptor for suitable feature display settings with
* <ul>
"STH");
for (int s = 0, sNum = rcds.getHeight(); s < sNum; s++)
{
- rcds.getSequenceAt(s).addDBRef(
-new DBRefEntry(DBRefSource.PFAM,
- // getDbSource(),
- getDbVersion(), queries.trim().toUpperCase()));
+ rcds.getSequenceAt(s).addDBRef(new DBRefEntry(DBRefSource.PFAM,
+ // getDbSource(),
+ getDbVersion(), queries.trim().toUpperCase()));
if (!getDbSource().equals(DBRefSource.PFAM))
{ // add the specific ref too
rcds.getSequenceAt(s).addDBRef(
*/
package jalview.ws.dbsources;
-
/**
* flyweight class specifying retrieval of Full family alignments from PFAM
*
*/
package jalview.ws.dbsources;
-
/**
* flyweight class specifying retrieval of Seed alignments from PFAM
*
*/
package jalview.ws.dbsources;
-
/**
* Flyweight class specifying retrieval of Full family alignments from RFAM
*
*/
package jalview.ws.dbsources;
-
/**
* Flyweight class specifying retrieval of Seed family alignments from RFAM
*
{
return "/alignment";
}
+
/*
* (non-Javadoc)
*
* UniprotEntry
* @return SequenceI instance created from the UniprotEntry instance
*/
- public SequenceI uniprotEntryToSequenceI(UniprotEntry entry){
+ public SequenceI uniprotEntryToSequenceI(UniprotEntry entry)
+ {
String id = getUniprotEntryId(entry);
SequenceI sequence = new Sequence(id, entry.getUniprotSequence()
.getContent());
{
DBRefEntry dbRef = new DBRefEntry(DBRefSource.UNIPROT, dbVersion,
accessionId);
+
+ // mark dbRef as a primary reference for this sequence
dbRefs.add(dbRef);
}
- sequence.setSourceDBRef((dbRefs != null && dbRefs.size() > 0) ? dbRefs
- .get(0) : null);
Vector<PDBEntry> onlyPdbEntries = new Vector<PDBEntry>();
for (PDBEntry pdb : entry.getDbReference())
{
onlyPdbEntries.addElement(pdb);
}
+ if ("EMBL".equals(pdb.getType()))
+ {
+ // look for a CDS reference and add it, too.
+ String cdsId = (String) pdb.getProperty("protein sequence ID");
+ if (cdsId != null && cdsId.trim().length() > 0)
+ {
+ // remove version
+ String[] vrs = cdsId.split("\\.");
+ dbr = new DBRefEntry(DBRefSource.EMBLCDS, vrs.length > 1 ? vrs[1]
+ : DBRefSource.UNIPROT + ":" + dbVersion, vrs[0]);
+ dbRefs.add(dbr);
+ }
+ }
+ if ("Ensembl".equals(pdb.getType()))
+ {
+ /*UniprotXML
+ * <dbReference type="Ensembl" id="ENST00000321556">
+ * <molecule id="Q9BXM7-1"/>
+ * <property type="protein sequence ID" value="ENSP00000364204"/>
+ * <property type="gene ID" value="ENSG00000158828"/>
+ * </dbReference>
+ */
+ String cdsId = (String) pdb.getProperty("protein sequence ID");
+ if (cdsId != null && cdsId.trim().length() > 0)
+ {
+ dbr = new DBRefEntry(DBRefSource.ENSEMBL, DBRefSource.UNIPROT
+ + ":" + dbVersion, cdsId.trim());
+ dbRefs.add(dbr);
+
+ }
+ }
+
}
sequence.setPDBId(onlyPdbEntries);
sequence.addSequenceFeature(sf);
}
}
- sequence.setDBRefs(dbRefs.toArray(new DBRefEntry[0]));
+ for (DBRefEntry dbr : dbRefs)
+ {
+ sequence.addDBRef(dbr);
+ }
return sequence;
}
// TODO: trap HTTP 404 exceptions and return null
AlignmentI rcds = new FormatAdapter().readFile(getXFAMURL()
+ queries.trim().toUpperCase() + getXFAMURLSUFFIX(),
- jalview.io.FormatAdapter.URL,
- "STH");
+ jalview.io.FormatAdapter.URL, "STH");
for (int s = 0, sNum = rcds.getHeight(); s < sNum; s++)
{
rcds.getSequenceAt(s).addDBRef(new DBRefEntry(getXfamSource(),
}
/*
- *
- */
+ *
+ */
@Override
public jalviewSourceI createLocalSource(String url, String name,
}
// note: outFile is currently always specified, so return value is null
- String[] rslt = fetchBatch(querystring.toString(), database, format, outFile);
+ String[] rslt = fetchBatch(querystring.toString(), database, format,
+ outFile);
return (rslt != null && rslt.length > 0 ? rslt : null);
}
return null;
}
System.err.println("Unexpected exception when retrieving from "
- + database
- + "\nQuery was : '" + ids + "'");
+ + database + "\nQuery was : '" + ids + "'");
ex.printStackTrace(System.err);
return null;
} finally
*/
package jalview.ws.jws1;
-import jalview.datamodel.Alignment;
+import jalview.datamodel.AlignmentI;
import jalview.datamodel.AlignmentView;
import jalview.gui.AlignFrame;
import jalview.gui.Desktop;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
-import ext.vamsas.MuscleWS;
import ext.vamsas.MuscleWSServiceLocator;
import ext.vamsas.MuscleWSSoapBindingStub;
import ext.vamsas.ServiceHandle;
public MsaWSClient(ext.vamsas.ServiceHandle sh, String altitle,
jalview.datamodel.AlignmentView msa, boolean submitGaps,
- boolean preserveOrder, Alignment seqdataset,
+ boolean preserveOrder, AlignmentI seqdataset,
AlignFrame _alignFrame)
{
super();
}
private void startMsaWSClient(String altitle, AlignmentView msa,
- boolean submitGaps, boolean preserveOrder, Alignment seqdataset)
+ boolean submitGaps, boolean preserveOrder, AlignmentI seqdataset)
{
if (!locateWebService())
{
try
{
- this.server = (MuscleWS) loc.getMuscleWS(new java.net.URL(WsURL));
+ this.server = loc.getMuscleWS(new java.net.URL(WsURL));
((MuscleWSSoapBindingStub) this.server).setTimeout(60000); // One minute
// timeout
} catch (Exception ex)
return (WebServiceName.indexOf("lustal") > -1); // cheat!
}
+ @Override
public void attachWSMenuEntry(JMenu msawsmenu,
final ServiceHandle serviceHandle, final AlignFrame alignFrame)
{
method.setToolTipText(WsURL);
method.addActionListener(new ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
AlignmentView msa = alignFrame.gatherSequencesForAlignment();
methodR.setToolTipText(WsURL);
methodR.addActionListener(new ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
AlignmentView msa = alignFrame.gatherSequencesForAlignment();
import jalview.analysis.AlignSeq;
import jalview.bin.Cache;
import jalview.datamodel.Alignment;
+import jalview.datamodel.AlignmentI;
import jalview.datamodel.AlignmentOrder;
import jalview.datamodel.AlignmentView;
import jalview.datamodel.ColumnSelection;
*
* @return true if getAlignment will return a valid alignment result.
*/
+ @Override
public boolean hasResults()
{
if (subjobComplete && result != null && result.isFinished()
*
* @return boolean true if job can be submitted.
*/
+ @Override
public boolean hasValidInput()
{
if (seqs.getSeqs() != null)
String alTitle; // name which will be used to form new alignment window.
- Alignment dataset; // dataset to which the new alignment will be
+ AlignmentI dataset; // dataset to which the new alignment will be
// associated.
MsaWSThread(ext.vamsas.MuscleWS server, String wsUrl,
WebserviceInfo wsinfo, jalview.gui.AlignFrame alFrame,
String wsname, String title, AlignmentView _msa, boolean subgaps,
- boolean presorder, Alignment seqset)
+ boolean presorder, AlignmentI seqset)
{
this(server, wsUrl, wsinfo, alFrame, _msa, wsname, subgaps, presorder);
OutputHeader = wsInfo.getProgressText();
}
}
+ @Override
public boolean isCancellable()
{
return true;
}
+ @Override
public void cancelJob()
{
if (!jobComplete && jobs != null)
}
}
+ @Override
public void pollJob(AWsJob job) throws Exception
{
((MsaWSJob) job).result = server.getResult(((MsaWSJob) job).getJobId());
}
+ @Override
public void StartJob(AWsJob job)
{
if (!(job instanceof MsaWSJob))
return msa;
}
+ @Override
public void parseResult()
{
int results = 0; // number of result sets received
wsInfo.showResultsNewFrame
.addActionListener(new java.awt.event.ActionListener()
{
+ @Override
public void actionPerformed(java.awt.event.ActionEvent evt)
{
displayResults(true);
wsInfo.mergeResults
.addActionListener(new java.awt.event.ActionListener()
{
+ @Override
public void actionPerformed(java.awt.event.ActionEvent evt)
{
displayResults(false);
while (j < l)
{
- if (((AlignmentOrder) alorders.get(i))
- .equals(((AlignmentOrder) alorders.get(j))))
+ if (((AlignmentOrder) alorders.get(i)).equals((alorders
+ .get(j))))
{
alorders.remove(j);
l--;
}
}
+ @Override
public boolean canMergeResults()
{
return false;
*/
package jalview.ws.jws1;
-import jalview.datamodel.Alignment;
+import jalview.datamodel.AlignmentI;
import jalview.datamodel.AlignmentView;
import jalview.gui.AlignFrame;
import jalview.gui.Desktop;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
-import ext.vamsas.SeqSearchI;
import ext.vamsas.SeqSearchServiceLocator;
import ext.vamsas.SeqSearchServiceSoapBindingStub;
import ext.vamsas.ServiceHandle;
public SeqSearchWSClient(ext.vamsas.ServiceHandle sh, String altitle,
jalview.datamodel.AlignmentView msa, String db,
- Alignment seqdataset, AlignFrame _alignFrame)
+ AlignmentI seqdataset, AlignFrame _alignFrame)
{
super();
alignFrame = _alignFrame;
}
private void startSeqSearchClient(String altitle, AlignmentView msa,
- String db, Alignment seqdataset)
+ String db, AlignmentI seqdataset)
{
if (!locateWebService())
{
try
{
- this.server = (SeqSearchI) loc.getSeqSearchService(new java.net.URL(
- WsURL));
+ this.server = loc.getSeqSearchService(new java.net.URL(WsURL));
((SeqSearchServiceSoapBindingStub) this.server).setTimeout(60000); // One
// minute
// timeout
return dbs;
}
+ @Override
public void attachWSMenuEntry(JMenu wsmenu, final ServiceHandle sh,
final AlignFrame af)
{
method.setToolTipText(sh.getEndpointURL());
method.addActionListener(new ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
// use same input gatherer as for secondary structure prediction
final String searchdb = dbs[db];
method.addActionListener(new ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
AlignmentView msa = af.gatherSeqOrMsaForSecStrPrediction();
import jalview.api.FeatureColourI;
import jalview.bin.Cache;
import jalview.datamodel.Alignment;
+import jalview.datamodel.AlignmentI;
import jalview.datamodel.AlignmentView;
import jalview.datamodel.SequenceI;
import jalview.gui.AlignFrame;
*
* @return null or { Alignment(+features and annotation), NewickFile)}
*/
- public Object[] getAlignment(Alignment dataset,
+ public Object[] getAlignment(AlignmentI dataset,
Map<String, FeatureColourI> featureColours)
{
String alTitle; // name which will be used to form new alignment window.
- Alignment dataset; // dataset to which the new alignment will be
+ AlignmentI dataset; // dataset to which the new alignment will be
// associated.
SeqSearchWSThread(ext.vamsas.SeqSearchI server, String wsUrl,
WebserviceInfo wsinfo, jalview.gui.AlignFrame alFrame,
String wsname, String title, AlignmentView _msa, String db,
- Alignment seqset)
+ AlignmentI seqset)
{
this(server, wsUrl, wsinfo, alFrame, _msa, wsname, db);
OutputHeader = wsInfo.getProgressText();
System.err.println("submission error with " + getServiceActionText()
+ " :");
x.printStackTrace();
- calcMan.workerCannotRun(this);
+ calcMan.disableWorker(this);
} catch (ResultNotAvailableException x)
{
System.err.println("collection error:\nJob ID: " + rslt);
x.printStackTrace();
- calcMan.workerCannotRun(this);
+ calcMan.disableWorker(this);
} catch (OutOfMemoryError error)
{
- calcMan.workerCannotRun(this);
+ calcMan.disableWorker(this);
// consensus = null;
// hconsensus = null;
ap.raiseOOMWarning(getServiceActionText(), error);
} catch (Exception x)
{
- calcMan.workerCannotRun(this);
+ calcMan.disableWorker(this);
// consensus = null;
// hconsensus = null;
*/
package jalview.ws.jws2;
-import jalview.datamodel.Alignment;
+import jalview.datamodel.AlignmentI;
import jalview.datamodel.AlignmentView;
import jalview.gui.AlignFrame;
import jalview.gui.Desktop;
public MsaWSClient(Jws2Instance sh, String altitle,
jalview.datamodel.AlignmentView msa, boolean submitGaps,
- boolean preserveOrder, Alignment seqdataset,
+ boolean preserveOrder, AlignmentI seqdataset,
AlignFrame _alignFrame)
{
this(sh, null, null, false, altitle, msa, submitGaps, preserveOrder,
public MsaWSClient(Jws2Instance sh, WsParamSetI preset, String altitle,
jalview.datamodel.AlignmentView msa, boolean submitGaps,
- boolean preserveOrder, Alignment seqdataset,
+ boolean preserveOrder, AlignmentI seqdataset,
AlignFrame _alignFrame)
{
this(sh, preset, null, false, altitle, msa, submitGaps, preserveOrder,
public MsaWSClient(Jws2Instance sh, WsParamSetI preset,
List<Argument> arguments, boolean editParams, String altitle,
jalview.datamodel.AlignmentView msa, boolean submitGaps,
- boolean preserveOrder, Alignment seqdataset,
+ boolean preserveOrder, AlignmentI seqdataset,
AlignFrame _alignFrame)
{
super(_alignFrame, preset, arguments);
}
private void startMsaWSClient(String altitle, AlignmentView msa,
- boolean submitGaps, boolean preserveOrder, Alignment seqdataset)
+ boolean submitGaps, boolean preserveOrder, AlignmentI seqdataset)
{
// if (!locateWebService())
// {
}
});
- String tooltip = JvSwingUtils.wrapTooltip(
- true,
+ String tooltip = JvSwingUtils
+ .wrapTooltip(
+ true,
"<strong>"
- + (preset.isModifiable() ? MessageManager
- .getString("label.user_preset")
- : MessageManager
- .getString("label.service_preset"))
+ + (preset.isModifiable() ? MessageManager
+ .getString("label.user_preset")
+ : MessageManager
+ .getString("label.service_preset"))
+ "</strong><br/>"
+ preset.getDescription());
methodR.setToolTipText(tooltip);
*
* @return true if getAlignment will return a valid alignment result.
*/
+ @Override
public boolean hasResults()
{
if (subjobComplete
*
* @return boolean true if job can be submitted.
*/
+ @Override
public boolean hasValidInput()
{
// TODO: get attributes for this MsaWS instance to check if it can do two
String alTitle; // name which will be used to form new alignment window.
- Alignment dataset; // dataset to which the new alignment will be
+ AlignmentI dataset; // dataset to which the new alignment will be
// associated.
String wsUrl, WebserviceInfo wsinfo,
jalview.gui.AlignFrame alFrame, String wsname, String title,
AlignmentView _msa, boolean subgaps, boolean presorder,
- Alignment seqset)
+ AlignmentI seqset)
{
this(server2, wsUrl, wsinfo, alFrame, _msa, wsname, subgaps, presorder);
OutputHeader = wsInfo.getProgressText();
return validInput;
}
+ @Override
public boolean isCancellable()
{
return true;
}
+ @Override
public void cancelJob()
{
if (!jobComplete && jobs != null)
}
}
+ @Override
public void pollJob(AWsJob job) throws Exception
{
// TODO: investigate if we still need to cast here in J1.6
return changed;
}
+ @Override
public void StartJob(AWsJob job)
{
Exception lex = null;
}
}
+ @Override
public void parseResult()
{
long progbar = System.currentTimeMillis();
wsInfo.showResultsNewFrame
.addActionListener(new java.awt.event.ActionListener()
{
+ @Override
public void actionPerformed(java.awt.event.ActionEvent evt)
{
displayResults(true);
wsInfo.mergeResults
.addActionListener(new java.awt.event.ActionListener()
{
+ @Override
public void actionPerformed(java.awt.event.ActionEvent evt)
{
displayResults(false);
// becomes null if the alignment window was closed before the alignment
// job finished.
AlignmentI copyComplement = new Alignment(complement);
+ // todo should this be done by copy constructor?
+ copyComplement.setGapCharacter(complement.getGapCharacter());
+ // share the same dataset (and the mappings it holds)
+ copyComplement.setDataset(complement.getDataset());
copyComplement.alignAs(al);
if (copyComplement.getHeight() > 0)
{
}
}
+ @Override
public boolean canMergeResults()
{
return false;
}
// reinstate worker if it was blacklisted (might have happened due to
// invalid parameters)
- alignFrame.getViewport().getCalcManager().workerMayRun(worker);
+ alignFrame.getViewport().getCalcManager().enableWorker(worker);
worker.updateParameters(this.preset, paramset);
}
}
/**
* Constructor
*/
- public ASequenceFetcher()
+ protected ASequenceFetcher()
{
super();
return true;
}
}
- Cache.log.warn("isFetchable doesn't know about '" + source
- + "'");
+ Cache.log.warn("isFetchable doesn't know about '" + source + "'");
return false;
}
* if true, only fetch from nucleotide data sources, else peptide
* @return
*/
- public SequenceI[] getSequences(DBRefEntry[] refs, boolean dna)
+ public SequenceI[] getSequences(List<DBRefEntry> refs, boolean dna)
{
Vector<SequenceI> rseqs = new Vector<SequenceI>();
Hashtable<String, List<String>> queries = new Hashtable<String, List<String>>();
- for (int r = 0; r < refs.length; r++)
+ for (DBRefEntry ref : refs)
{
- if (!queries.containsKey(refs[r].getSource()))
+ if (!queries.containsKey(ref.getSource()))
{
- queries.put(refs[r].getSource(), new ArrayList<String>());
+ queries.put(ref.getSource(), new ArrayList<String>());
}
- List<String> qset = queries.get(refs[r].getSource());
- if (!qset.contains(refs[r].getAccessionId()))
+ List<String> qset = queries.get(ref.getSource());
+ if (!qset.contains(ref.getAccessionId()))
{
- qset.add(refs[r].getAccessionId());
+ qset.add(ref.getAccessionId());
}
}
Enumeration<String> e = queries.keys();
for (int is = 0; is < seqs.length; is++)
{
rseqs.addElement(seqs[is]);
- DBRefEntry[] frefs = DBRefUtils.searchRefs(seqs[is]
+ List<DBRefEntry> frefs = DBRefUtils.searchRefs(seqs[is]
.getDBRefs(), new DBRefEntry(db, null, null));
- if (frefs != null)
+ for (DBRefEntry dbr : frefs)
{
- for (DBRefEntry dbr : frefs)
- {
- queriesFound.add(dbr.getAccessionId());
- queriesMade.remove(dbr.getAccessionId());
- }
+ queriesFound.add(dbr.getAccessionId());
+ queriesMade.remove(dbr.getAccessionId());
}
seqs[is] = null;
}
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
package jalview.ws.sifts;
public class MappingOutputPojo
this.type = type;
}
-
}
import jalview.io.StructureFile;
import jalview.schemes.ResidueProperties;
import jalview.structure.StructureMapping;
+import jalview.util.DBRefUtils;
import jalview.util.Format;
import jalview.xml.binding.sifts.Entry;
import jalview.xml.binding.sifts.Entry.Entity;
siftsEntry = parseSIFTs(siftsFile);
}
-
/**
* Parse the given SIFTs File and return a JAXB POJO of parsed data
*
{
siftsDownloadDir.mkdirs();
}
- // System.out.println(">> Download ftp url : " + siftsFileFTPURL);
- URL url = new URL(siftsFileFTPURL);
- URLConnection conn = url.openConnection();
- InputStream inputStream = conn.getInputStream();
- FileOutputStream outputStream = new FileOutputStream(
- downloadedSiftsFile);
- byte[] buffer = new byte[BUFFER_SIZE];
- int bytesRead = -1;
- while ((bytesRead = inputStream.read(buffer)) != -1)
- {
- outputStream.write(buffer, 0, bytesRead);
- }
- outputStream.close();
- inputStream.close();
- // System.out.println(">>> File downloaded : " + downloadedSiftsFile);
+ // System.out.println(">> Download ftp url : " + siftsFileFTPURL);
+ URL url = new URL(siftsFileFTPURL);
+ URLConnection conn = url.openConnection();
+ InputStream inputStream = conn.getInputStream();
+ FileOutputStream outputStream = new FileOutputStream(
+ downloadedSiftsFile);
+ byte[] buffer = new byte[BUFFER_SIZE];
+ int bytesRead = -1;
+ while ((bytesRead = inputStream.read(buffer)) != -1)
+ {
+ outputStream.write(buffer, 0, bytesRead);
+ }
+ outputStream.close();
+ inputStream.close();
+ // System.out.println(">>> File downloaded : " + downloadedSiftsFile);
return new File(downloadedSiftsFile);
}
public DBRefEntryI getValidSourceDBRef(SequenceI seq)
throws SiftsException
{
- DBRefEntryI sourceDBRef = null;
- sourceDBRef = seq.getSourceDBRef();
- if (sourceDBRef != null && isValidDBRefEntry(sourceDBRef))
+ List<DBRefEntry> dbRefs = seq.getPrimaryDBRefs();
+ if (dbRefs == null || dbRefs.size() < 1)
{
- return sourceDBRef;
+ throw new SiftsException(
+ "Source DBRef could not be determined. DBRefs might not have been retrieved.");
}
- else
+
+ for (DBRefEntry dbRef : dbRefs)
{
- DBRefEntry[] dbRefs = seq.getDBRefs();
- if (dbRefs == null || dbRefs.length < 1)
+ if (dbRef == null || dbRef.getAccessionId() == null
+ || dbRef.getSource() == null)
{
- throw new SiftsException(
- "Source DBRef could not be determined. DBRefs might not have been retrieved.");
+ continue;
}
-
- for (DBRefEntryI dbRef : dbRefs)
+ String canonicalSource = DBRefUtils.getCanonicalName(dbRef
+ .getSource());
+ if (isValidDBRefEntry(dbRef)
+ && (canonicalSource.equalsIgnoreCase(DBRefSource.UNIPROT) || canonicalSource
+ .equalsIgnoreCase(DBRefSource.PDB)))
{
- if (dbRef == null || dbRef.getAccessionId() == null
- || dbRef.getSource() == null)
- {
- continue;
- }
- if (isFoundInSiftsEntry(dbRef.getAccessionId())
- && (dbRef.getSource().equalsIgnoreCase(DBRefSource.UNIPROT) || dbRef
- .getSource().equalsIgnoreCase(DBRefSource.PDB)))
- {
- seq.setSourceDBRef(dbRef);
- return dbRef;
- }
+ return dbRef;
}
}
- if (sourceDBRef != null && isValidDBRefEntry(sourceDBRef))
- {
- return sourceDBRef;
- }
throw new SiftsException("Could not get source DB Ref");
}
String pdbFile, String chain) throws SiftsException
{
structId = (chain == null) ? pdbId : pdbId + "|" + chain;
- System.out.println("Getting mapping for: " + pdbId + "|" + chain
- + " : seq- " + seq.getName());
+ System.out.println("Getting SIFTS mapping for " + structId + ": seq "
+ + seq.getName());
final StringBuilder mappingDetails = new StringBuilder(128);
PrintStream ps = new PrintStream(System.out)
String originalSeq = AlignSeq.extractGaps(
jalview.util.Comparison.GapChars, seq.getSequenceAsString());
HashMap<Integer, int[]> mapping = new HashMap<Integer, int[]>();
- DBRefEntryI sourceDBRef = seq.getSourceDBRef();
+ DBRefEntryI sourceDBRef;
sourceDBRef = getValidSourceDBRef(seq);
// TODO ensure sequence start/end is in the same coordinate system and
// consistent with the choosen sourceDBRef
int pdbStart = UNASSIGNED;
int pdbEnd = UNASSIGNED;
- Integer[] keys = mapping.keySet().toArray(new Integer[0]);
- Arrays.sort(keys);
- if (keys.length < 1)
+ if (mapping.isEmpty())
{
- throw new SiftsException(">>> Empty SIFTS mapping generated!!");
+ throw new SiftsException("SIFTS mapping failed");
}
+
+ Integer[] keys = mapping.keySet().toArray(new Integer[0]);
+ Arrays.sort(keys);
seqStart = keys[0];
seqEnd = keys[keys.length - 1];
}
}
}
+
/**
*
* @param chainId
}
}
-
-
@Override
public Entity getEntityById(String id) throws SiftsException
{
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
package jalview.ws.sifts;
public class SiftsException extends Exception
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
package jalview.ws.sifts;
import java.util.Objects;
assertEquals("GLN", a.resName);
assertEquals("A", a.chain);
assertEquals(48, a.resNumber);
- assertEquals(" 48 ", a.resNumIns);
+ assertEquals("48", a.resNumIns);
assertEquals(' ', a.insCode);
assertEquals(22.290, a.x, 0.00001);
assertEquals(8.595, a.y, 0.00001);
import jalview.datamodel.SequenceI;
import jalview.schemes.ColourSchemeI;
import jalview.schemes.TaylorColourScheme;
-import jalview.structure.StructureViewSettings;
+import jalview.structure.StructureImportSettings;
import java.awt.Color;
import java.util.Vector;
public void setUp()
{
System.out.println("setup");
- StructureViewSettings.setShowSeqFeatures(true);
+ StructureImportSettings.setShowSeqFeatures(true);
c = new PDBChain("1GAQ", "A");
}
import static org.testng.AssertJUnit.assertSame;
import static org.testng.AssertJUnit.assertTrue;
+import jalview.bin.Cache;
import jalview.datamodel.Alignment;
import jalview.datamodel.AlignmentAnnotation;
import jalview.datamodel.AlignmentI;
import jalview.datamodel.Sequence;
import jalview.datamodel.SequenceI;
import jalview.io.AppletFormatAdapter;
+import jalview.structure.StructureImportSettings;
import java.io.IOException;
import java.util.List;
+import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
public class PDBfileTest
pf.addAnnotations(al);
return al.getAlignmentAnnotation();
}
+
+ // @formatter:on
+
+ @BeforeMethod(alwaysRun = true)
+ public void setUp()
+ {
+ Cache.loadProperties("test/jalview/io/testProps.jvprops");
+ Cache.applicationProperties.setProperty("STRUCT_FROM_PDB",
+ Boolean.TRUE.toString());
+ Cache.applicationProperties.setProperty("ADD_TEMPFACT_ANN",
+ Boolean.TRUE.toString());
+ Cache.applicationProperties.setProperty("ADD_SS_ANN",
+ Boolean.TRUE.toString());
+ StructureImportSettings.setDefaultStructureFileFormat("PDB");
+ }
}
import static org.testng.AssertJUnit.assertEquals;
import static org.testng.AssertJUnit.assertNull;
+import jalview.datamodel.AlignmentAnnotation;
+import jalview.datamodel.Annotation;
import jalview.datamodel.Sequence;
import jalview.datamodel.SequenceI;
-import java.util.Hashtable;
-
import org.testng.annotations.Test;
public class AAFrequencyTest
{
- private static final String C = AAFrequency.MAXCOUNT;
-
- private static final String R = AAFrequency.MAXRESIDUE;
-
- private static final String G = AAFrequency.PID_GAPS;
-
- private static final String N = AAFrequency.PID_NOGAPS;
-
- private static final String P = AAFrequency.PROFILE;
-
@Test(groups = { "Functional" })
public void testCalculate_noProfile()
{
- SequenceI seq1 = new Sequence("Seq1", "CAGT");
- SequenceI seq2 = new Sequence("Seq2", "CACT");
- SequenceI seq3 = new Sequence("Seq3", "C--G");
- SequenceI seq4 = new Sequence("Seq4", "CA-t");
+ SequenceI seq1 = new Sequence("Seq1", "CAG-T");
+ SequenceI seq2 = new Sequence("Seq2", "CAC-T");
+ SequenceI seq3 = new Sequence("Seq3", "C---G");
+ SequenceI seq4 = new Sequence("Seq4", "CA--t");
SequenceI[] seqs = new SequenceI[] { seq1, seq2, seq3, seq4 };
- Hashtable[] result = new Hashtable[seq1.getLength()];
+ Profile[] result = new Profile[seq1.getLength()];
AAFrequency.calculate(seqs, 0, seq1.getLength(), result, false);
// col 0 is 100% C
- Hashtable col = result[0];
- assertEquals(100f, (Float) col.get(G), 0.0001f);
- assertEquals(100f, (Float) col.get(N), 0.0001f);
- assertEquals(4, col.get(C));
- assertEquals("C", col.get(R));
- assertNull(col.get(P));
+ Profile col = result[0];
+ assertEquals(100f, col.getPercentageIdentity(false));
+ assertEquals(100f, col.getPercentageIdentity(true));
+ assertEquals(4, col.getMaxCount());
+ assertEquals("C", col.getModalResidue());
+ assertNull(col.getCounts());
// col 1 is 75% A
col = result[1];
- assertEquals(75f, (Float) col.get(G), 0.0001f);
- assertEquals(100f, (Float) col.get(N), 0.0001f);
- assertEquals(3, col.get(C));
- assertEquals("A", col.get(R));
+ assertEquals(75f, col.getPercentageIdentity(false));
+ assertEquals(100f, col.getPercentageIdentity(true));
+ assertEquals(3, col.getMaxCount());
+ assertEquals("A", col.getModalResidue());
// col 2 is 50% G 50% C or 25/25 counting gaps
col = result[2];
- assertEquals(25f, (Float) col.get(G), 0.0001f);
- assertEquals(50f, (Float) col.get(N), 0.0001f);
- assertEquals(1, col.get(C));
- assertEquals("CG", col.get(R));
+ assertEquals(25f, col.getPercentageIdentity(false));
+ assertEquals(50f, col.getPercentageIdentity(true));
+ assertEquals(1, col.getMaxCount());
+ assertEquals("CG", col.getModalResidue());
- // col 3 is 75% T 25% G
+ // col 3 is all gaps
col = result[3];
- assertEquals(75f, (Float) col.get(G), 0.0001f);
- assertEquals(75f, (Float) col.get(N), 0.0001f);
- assertEquals(3, col.get(C));
- assertEquals("T", col.get(R));
+ assertEquals(0f, col.getPercentageIdentity(false));
+ assertEquals(0f, col.getPercentageIdentity(true));
+ assertEquals(0, col.getMaxCount());
+ assertEquals("", col.getModalResidue());
+
+ // col 4 is 75% T 25% G
+ col = result[4];
+ assertEquals(75f, col.getPercentageIdentity(false));
+ assertEquals(75f, col.getPercentageIdentity(true));
+ assertEquals(3, col.getMaxCount());
+ assertEquals("T", col.getModalResidue());
}
@Test(groups = { "Functional" })
SequenceI seq3 = new Sequence("Seq3", "C--G");
SequenceI seq4 = new Sequence("Seq4", "CA-t");
SequenceI[] seqs = new SequenceI[] { seq1, seq2, seq3, seq4 };
- Hashtable[] result = new Hashtable[seq1.getLength()];
+ Profile[] result = new Profile[seq1.getLength()];
AAFrequency.calculate(seqs, 0, seq1.getLength(), result, true);
- int[][] profile = (int[][]) result[0].get(P);
- assertEquals(4, profile[0]['C']);
- assertEquals(4, profile[1][0]); // no of seqs
- assertEquals(4, profile[1][1]); // nongapped in column
-
- profile = (int[][]) result[1].get(P);
- assertEquals(3, profile[0]['A']);
- assertEquals(4, profile[1][0]);
- assertEquals(3, profile[1][1]);
-
- profile = (int[][]) result[2].get(P);
- assertEquals(1, profile[0]['G']);
- assertEquals(1, profile[0]['C']);
- assertEquals(4, profile[1][0]);
- assertEquals(2, profile[1][1]);
-
- profile = (int[][]) result[3].get(P);
- assertEquals(3, profile[0]['T']);
- assertEquals(1, profile[0]['G']);
- assertEquals(4, profile[1][0]);
- assertEquals(4, profile[1][1]);
+ Profile profile = result[0];
+ assertEquals(4, profile.getCounts().getCount('C'));
+ assertEquals(4, profile.getHeight());
+ assertEquals(4, profile.getNonGapped());
+
+ profile = result[1];
+ assertEquals(3, profile.getCounts().getCount('A'));
+ assertEquals(4, profile.getHeight());
+ assertEquals(3, profile.getNonGapped());
+
+ profile = result[2];
+ assertEquals(1, profile.getCounts().getCount('C'));
+ assertEquals(1, profile.getCounts().getCount('G'));
+ assertEquals(4, profile.getHeight());
+ assertEquals(2, profile.getNonGapped());
+
+ profile = result[3];
+ assertEquals(3, profile.getCounts().getCount('T'));
+ assertEquals(1, profile.getCounts().getCount('G'));
+ assertEquals(4, profile.getHeight());
+ assertEquals(4, profile.getNonGapped());
}
- @Test(groups = { "Functional" })
+ @Test(groups = { "Functional" }, enabled = false)
public void testCalculate_withProfileTiming()
{
SequenceI seq1 = new Sequence("Seq1", "CAGT");
SequenceI seq3 = new Sequence("Seq3", "C--G");
SequenceI seq4 = new Sequence("Seq4", "CA-t");
SequenceI[] seqs = new SequenceI[] { seq1, seq2, seq3, seq4 };
- Hashtable[] result = new Hashtable[seq1.getLength()];
+ Profile[] result = new Profile[seq1.getLength()];
// ensure class loaded and initialized
AAFrequency.calculate(seqs, 0, seq1.getLength(), result, true);
System.out.println(System.currentTimeMillis() - start);
}
+ /**
+ * Test generation of consensus annotation with options 'include gaps'
+ * (profile percentages are of all sequences, whether gapped or not), and
+ * 'show logo' (the full profile with all residue percentages is reported in
+ * the description for the tooltip)
+ */
+ @Test(groups = { "Functional" })
+ public void testCompleteConsensus_includeGaps_showLogo()
+ {
+ /*
+ * first compute the profiles
+ */
+ SequenceI seq1 = new Sequence("Seq1", "CAG-T");
+ SequenceI seq2 = new Sequence("Seq2", "CAC-T");
+ SequenceI seq3 = new Sequence("Seq3", "C---G");
+ SequenceI seq4 = new Sequence("Seq4", "CA--t");
+ SequenceI[] seqs = new SequenceI[] { seq1, seq2, seq3, seq4 };
+ Profile[] profiles = new Profile[seq1.getLength()];
+ AAFrequency.calculate(seqs, 0, seq1.getLength(), profiles, true);
+
+ AlignmentAnnotation consensus = new AlignmentAnnotation("Consensus",
+ "PID", new Annotation[seq1.getLength()]);
+ AAFrequency
+ .completeConsensus(consensus, profiles, 0, 5, false, true, 4);
+
+ Annotation ann = consensus.annotations[0];
+ assertEquals("C 100%", ann.description);
+ assertEquals("C", ann.displayCharacter);
+ ann = consensus.annotations[1];
+ assertEquals("A 75%", ann.description);
+ assertEquals("A", ann.displayCharacter);
+ ann = consensus.annotations[2];
+ assertEquals("C 25%; G 25%", ann.description);
+ assertEquals("+", ann.displayCharacter);
+ ann = consensus.annotations[3];
+ assertEquals("", ann.description);
+ assertEquals("-", ann.displayCharacter);
+ ann = consensus.annotations[4];
+ assertEquals("T 75%; G 25%", ann.description);
+ assertEquals("T", ann.displayCharacter);
+ }
+
+ /**
+ * Test generation of consensus annotation with options 'ignore gaps' (profile
+ * percentages are of the non-gapped sequences) and 'no logo' (only the modal
+ * residue[s] percentage is reported in the description for the tooltip)
+ */
@Test(groups = { "Functional" })
- public void testGetPercentageFormat()
+ public void testCompleteConsensus_ignoreGaps_noLogo()
{
- assertNull(AAFrequency.getPercentageFormat(0));
- assertNull(AAFrequency.getPercentageFormat(99));
- assertEquals("%3.1f", AAFrequency.getPercentageFormat(100).toString());
- assertEquals("%3.1f", AAFrequency.getPercentageFormat(999).toString());
- assertEquals("%3.2f", AAFrequency.getPercentageFormat(1000).toString());
- assertEquals("%3.2f", AAFrequency.getPercentageFormat(9999).toString());
+ /*
+ * first compute the profiles
+ */
+ SequenceI seq1 = new Sequence("Seq1", "CAG-T");
+ SequenceI seq2 = new Sequence("Seq2", "CAC-T");
+ SequenceI seq3 = new Sequence("Seq3", "C---G");
+ SequenceI seq4 = new Sequence("Seq4", "CA--t");
+ SequenceI[] seqs = new SequenceI[] { seq1, seq2, seq3, seq4 };
+ Profile[] profiles = new Profile[seq1.getLength()];
+ AAFrequency.calculate(seqs, 0, seq1.getLength(), profiles, true);
+
+ AlignmentAnnotation consensus = new AlignmentAnnotation("Consensus",
+ "PID", new Annotation[seq1.getLength()]);
+ AAFrequency
+ .completeConsensus(consensus, profiles, 0, 5, true, false, 4);
+
+ Annotation ann = consensus.annotations[0];
+ assertEquals("C 100%", ann.description);
+ assertEquals("C", ann.displayCharacter);
+ ann = consensus.annotations[1];
+ assertEquals("A 100%", ann.description);
+ assertEquals("A", ann.displayCharacter);
+ ann = consensus.annotations[2];
+ assertEquals("[CG] 50%", ann.description);
+ assertEquals("+", ann.displayCharacter);
+ ann = consensus.annotations[3];
+ assertEquals("", ann.description);
+ assertEquals("-", ann.displayCharacter);
+ ann = consensus.annotations[4];
+ assertEquals("T 75%", ann.description);
+ assertEquals("T", ann.displayCharacter);
}
}
import static org.testng.AssertJUnit.assertEquals;
import static org.testng.AssertJUnit.assertFalse;
+import static org.testng.AssertJUnit.assertNotNull;
import static org.testng.AssertJUnit.assertNull;
import static org.testng.AssertJUnit.assertSame;
import static org.testng.AssertJUnit.assertTrue;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
-import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
SequenceI alignFrom = new Sequence("Seq2", alignModel);
alignFrom.createDatasetSequence();
AlignedCodonFrame acf = new AlignedCodonFrame();
- acf.addMap(alignMe.getDatasetSequence(), alignFrom.getDatasetSequence(), map);
+ acf.addMap(alignMe.getDatasetSequence(),
+ alignFrom.getDatasetSequence(), map);
AlignmentUtils.alignSequenceAs(alignMe, alignFrom, acf, "---", '-',
preserveMappedGaps, preserveUnmappedGaps);
@Test(groups = { "Functional" })
public void testMakeCdsAlignment()
{
+ /*
+ * scenario:
+ * dna1 --> [4, 6] [10,12] --> pep1
+ * dna2 --> [1, 3] [7, 9] [13,15] --> pep2
+ */
SequenceI dna1 = new Sequence("dna1", "aaaGGGcccTTTaaa");
SequenceI dna2 = new Sequence("dna2", "GGGcccTTTaaaCCC");
SequenceI pep1 = new Sequence("pep1", "GF");
SequenceI pep2 = new Sequence("pep2", "GFP");
+ pep1.addDBRef(new DBRefEntry("UNIPROT", "0", "pep1"));
+ pep2.addDBRef(new DBRefEntry("UNIPROT", "0", "pep2"));
dna1.createDatasetSequence();
dna2.createDatasetSequence();
pep1.createDatasetSequence();
pep2.createDatasetSequence();
- dna1.addSequenceFeature(new SequenceFeature("CDS", "cds1", 4, 6, 0f,
- null));
- dna1.addSequenceFeature(new SequenceFeature("CDS", "cds2", 10, 12, 0f,
- null));
- dna2.addSequenceFeature(new SequenceFeature("CDS", "cds3", 1, 3, 0f,
- null));
- dna2.addSequenceFeature(new SequenceFeature("CDS", "cds4", 7, 9, 0f,
- null));
- dna2.addSequenceFeature(new SequenceFeature("CDS", "cds5", 13, 15, 0f,
- null));
AlignmentI dna = new Alignment(new SequenceI[] { dna1, dna2 });
dna.setDataset(null);
- List<AlignedCodonFrame> mappings = new ArrayList<AlignedCodonFrame>();
- MapList map = new MapList(new int[] { 4, 6, 10, 12 },
- new int[] { 1, 2 }, 3, 1);
+ /*
+ * put a variant feature on dna2 base 8
+ * - should transfer to cds2 base 5
+ */
+ dna2.addSequenceFeature(new SequenceFeature("variant", "hgmd", 8, 8,
+ 0f, null));
+
+ /*
+ * need a sourceDbRef if we are to construct dbrefs to the CDS
+ * sequence from the dna contig sequences
+ */
+ DBRefEntry dbref = new DBRefEntry("ENSEMBL", "0", "dna1");
+ dna1.getDatasetSequence().addDBRef(dbref);
+ org.testng.Assert.assertEquals(dbref, dna1.getPrimaryDBRefs().get(0));
+ dbref = new DBRefEntry("ENSEMBL", "0", "dna2");
+ dna2.getDatasetSequence().addDBRef(dbref);
+ org.testng.Assert.assertEquals(dbref, dna2.getPrimaryDBRefs().get(0));
+
+ /*
+ * CDS sequences are 'discovered' from dna-to-protein mappings on the alignment
+ * dataset (e.g. added from dbrefs by CrossRef.findXrefSequences)
+ */
+ MapList mapfordna1 = new MapList(new int[] { 4, 6, 10, 12 }, new int[] {
+ 1, 2 }, 3, 1);
AlignedCodonFrame acf = new AlignedCodonFrame();
- acf.addMap(dna1.getDatasetSequence(), pep1.getDatasetSequence(), map);
- mappings.add(acf);
- map = new MapList(new int[] { 1, 3, 7, 9, 13, 15 }, new int[] { 1, 3 },
- 3, 1);
+ acf.addMap(dna1.getDatasetSequence(), pep1.getDatasetSequence(),
+ mapfordna1);
+ dna.addCodonFrame(acf);
+ MapList mapfordna2 = new MapList(new int[] { 1, 3, 7, 9, 13, 15 },
+ new int[] { 1, 3 }, 3, 1);
acf = new AlignedCodonFrame();
- acf.addMap(dna2.getDatasetSequence(), pep2.getDatasetSequence(), map);
- mappings.add(acf);
+ acf.addMap(dna2.getDatasetSequence(), pep2.getDatasetSequence(),
+ mapfordna2);
+ dna.addCodonFrame(acf);
+
+ /*
+ * In this case, mappings originally came from matching Uniprot accessions - so need an xref on dna involving those regions. These are normally constructed from CDS annotation
+ */
+ DBRefEntry dna1xref = new DBRefEntry("UNIPROT", "ENSEMBL", "pep1",
+ new Mapping(mapfordna1));
+ dna1.getDatasetSequence().addDBRef(dna1xref);
+ DBRefEntry dna2xref = new DBRefEntry("UNIPROT", "ENSEMBL", "pep2",
+ new Mapping(mapfordna2));
+ dna2.getDatasetSequence().addDBRef(dna2xref);
/*
* execute method under test:
*/
AlignmentI cds = AlignmentUtils.makeCdsAlignment(new SequenceI[] {
- dna1, dna2 }, mappings, dna);
+ dna1, dna2 }, dna.getDataset(), null);
+ /*
+ * verify cds sequences
+ */
assertEquals(2, cds.getSequences().size());
- assertEquals("GGGTTT", cds.getSequenceAt(0)
- .getSequenceAsString());
- assertEquals("GGGTTTCCC", cds.getSequenceAt(1)
- .getSequenceAsString());
+ assertEquals("GGGTTT", cds.getSequenceAt(0).getSequenceAsString());
+ assertEquals("GGGTTTCCC", cds.getSequenceAt(1).getSequenceAsString());
/*
* verify shared, extended alignment dataset
*/
assertSame(dna.getDataset(), cds.getDataset());
- assertTrue(dna.getDataset().getSequences()
- .contains(cds.getSequenceAt(0).getDatasetSequence()));
- assertTrue(dna.getDataset().getSequences()
- .contains(cds.getSequenceAt(1).getDatasetSequence()));
+ SequenceI cds1Dss = cds.getSequenceAt(0).getDatasetSequence();
+ SequenceI cds2Dss = cds.getSequenceAt(1).getDatasetSequence();
+ assertTrue(dna.getDataset().getSequences().contains(cds1Dss));
+ assertTrue(dna.getDataset().getSequences().contains(cds2Dss));
+
+ /*
+ * verify CDS has a dbref with mapping to peptide
+ */
+ assertNotNull(cds1Dss.getDBRefs());
+ assertEquals(2, cds1Dss.getDBRefs().length);
+ dbref = cds1Dss.getDBRefs()[0];
+ assertEquals(dna1xref.getSource(), dbref.getSource());
+ // version is via ensembl's primary ref
+ assertEquals(dna1xref.getVersion(), dbref.getVersion());
+ assertEquals(dna1xref.getAccessionId(), dbref.getAccessionId());
+ assertNotNull(dbref.getMap());
+ assertSame(pep1.getDatasetSequence(), dbref.getMap().getTo());
+ MapList cdsMapping = new MapList(new int[] { 1, 6 },
+ new int[] { 1, 2 }, 3, 1);
+ assertEquals(cdsMapping, dbref.getMap().getMap());
/*
- * Verify mappings from CDS to peptide and cDNA to CDS
+ * verify peptide has added a dbref with reverse mapping to CDS
+ */
+ assertNotNull(pep1.getDBRefs());
+ // FIXME pep1.getDBRefs() is 1 - is that the correct behaviour ?
+ assertEquals(2, pep1.getDBRefs().length);
+ dbref = pep1.getDBRefs()[1];
+ assertEquals("ENSEMBL", dbref.getSource());
+ assertEquals("0", dbref.getVersion());
+ assertEquals("CDS|dna1", dbref.getAccessionId());
+ assertNotNull(dbref.getMap());
+ assertSame(cds1Dss, dbref.getMap().getTo());
+ assertEquals(cdsMapping.getInverse(), dbref.getMap().getMap());
+
+ /*
+ * Verify mappings from CDS to peptide, cDNA to CDS, and cDNA to peptide
* the mappings are on the shared alignment dataset
+ * 6 mappings, 2*(DNA->CDS), 2*(DNA->Pep), 2*(CDS->Pep)
*/
- assertSame(dna.getCodonFrames(), cds.getCodonFrames());
- List<AlignedCodonFrame> cdsMappings = cds.getCodonFrames();
- assertEquals(2, cdsMappings.size());
-
+ List<AlignedCodonFrame> cdsMappings = cds.getDataset().getCodonFrames();
+ assertEquals(6, cdsMappings.size());
+
/*
+ * verify that mapping sets for dna and cds alignments are different
+ * [not current behaviour - all mappings are on the alignment dataset]
+ */
+ // select -> subselect type to test.
+ // Assert.assertNotSame(dna.getCodonFrames(), cds.getCodonFrames());
+ // assertEquals(4, dna.getCodonFrames().size());
+ // assertEquals(4, cds.getCodonFrames().size());
+
+ /*
+ * Two mappings involve pep1 (dna to pep1, cds to pep1)
* Mapping from pep1 to GGGTTT in first new exon sequence
*/
- List<AlignedCodonFrame> pep1Mapping = MappingUtils
+ List<AlignedCodonFrame> pep1Mappings = MappingUtils
.findMappingsForSequence(pep1, cdsMappings);
- assertEquals(1, pep1Mapping.size());
+ assertEquals(2, pep1Mappings.size());
+ List<AlignedCodonFrame> mappings = MappingUtils
+ .findMappingsForSequence(cds.getSequenceAt(0), pep1Mappings);
+ assertEquals(1, mappings.size());
+
// map G to GGG
- SearchResults sr = MappingUtils
- .buildSearchResults(pep1, 1, cdsMappings);
+ SearchResults sr = MappingUtils.buildSearchResults(pep1, 1, mappings);
assertEquals(1, sr.getResults().size());
Match m = sr.getResults().get(0);
- assertSame(cds.getSequenceAt(0).getDatasetSequence(),
- m.getSequence());
+ assertSame(cds1Dss, m.getSequence());
assertEquals(1, m.getStart());
assertEquals(3, m.getEnd());
// map F to TTT
- sr = MappingUtils.buildSearchResults(pep1, 2, cdsMappings);
+ sr = MappingUtils.buildSearchResults(pep1, 2, mappings);
m = sr.getResults().get(0);
- assertSame(cds.getSequenceAt(0).getDatasetSequence(),
- m.getSequence());
+ assertSame(cds1Dss, m.getSequence());
assertEquals(4, m.getStart());
assertEquals(6, m.getEnd());
/*
- * Mapping from pep2 to GGGTTTCCC in second new exon sequence
+ * Two mappings involve pep2 (dna to pep2, cds to pep2)
+ * Verify mapping from pep2 to GGGTTTCCC in second new exon sequence
*/
- List<AlignedCodonFrame> pep2Mapping = MappingUtils
+ List<AlignedCodonFrame> pep2Mappings = MappingUtils
.findMappingsForSequence(pep2, cdsMappings);
- assertEquals(1, pep2Mapping.size());
+ assertEquals(2, pep2Mappings.size());
+ mappings = MappingUtils.findMappingsForSequence(cds.getSequenceAt(1),
+ pep2Mappings);
+ assertEquals(1, mappings.size());
// map G to GGG
- sr = MappingUtils.buildSearchResults(pep2, 1, cdsMappings);
+ sr = MappingUtils.buildSearchResults(pep2, 1, mappings);
assertEquals(1, sr.getResults().size());
m = sr.getResults().get(0);
- assertSame(cds.getSequenceAt(1).getDatasetSequence(),
- m.getSequence());
+ assertSame(cds2Dss, m.getSequence());
assertEquals(1, m.getStart());
assertEquals(3, m.getEnd());
// map F to TTT
- sr = MappingUtils.buildSearchResults(pep2, 2, cdsMappings);
+ sr = MappingUtils.buildSearchResults(pep2, 2, mappings);
m = sr.getResults().get(0);
- assertSame(cds.getSequenceAt(1).getDatasetSequence(),
- m.getSequence());
+ assertSame(cds2Dss, m.getSequence());
assertEquals(4, m.getStart());
assertEquals(6, m.getEnd());
// map P to CCC
- sr = MappingUtils.buildSearchResults(pep2, 3, cdsMappings);
+ sr = MappingUtils.buildSearchResults(pep2, 3, mappings);
m = sr.getResults().get(0);
- assertSame(cds.getSequenceAt(1).getDatasetSequence(),
- m.getSequence());
+ assertSame(cds2Dss, m.getSequence());
assertEquals(7, m.getStart());
assertEquals(9, m.getEnd());
+
+ /*
+ * check cds2 acquired a variant feature in position 5
+ */
+ SequenceFeature[] sfs = cds2Dss.getSequenceFeatures();
+ assertNotNull(sfs);
+ assertEquals(1, sfs.length);
+ assertEquals("variant", sfs[0].type);
+ assertEquals(5, sfs[0].begin);
+ assertEquals(5, sfs[0].end);
}
/**
pep1.createDatasetSequence();
pep2.createDatasetSequence();
pep3.createDatasetSequence();
- dna1.addSequenceFeature(new SequenceFeature("CDS", "cds1", 4, 6, 0f,
- null));
- dna1.addSequenceFeature(new SequenceFeature("CDS", "cds2", 10, 12, 0f,
- null));
- dna1.addSequenceFeature(new SequenceFeature("CDS", "cds3", 1, 3, 0f,
- null));
- dna1.addSequenceFeature(new SequenceFeature("CDS", "cds4", 7, 9, 0f,
- null));
- dna1.addSequenceFeature(new SequenceFeature("CDS", "cds5", 1, 3, 0f,
- null));
- dna1.addSequenceFeature(new SequenceFeature("CDS", "cds6", 10, 12, 0f,
- null));
pep1.getDatasetSequence().addDBRef(
new DBRefEntry("EMBLCDS", "2", "A12345"));
pep2.getDatasetSequence().addDBRef(
new DBRefEntry("EMBLCDS", "4", "A12347"));
/*
+ * Create the CDS alignment
+ */
+ AlignmentI dna = new Alignment(new SequenceI[] { dna1 });
+ dna.setDataset(null);
+
+ /*
* Make the mappings from dna to protein
*/
- List<AlignedCodonFrame> mappings = new ArrayList<AlignedCodonFrame>();
// map ...GGG...TTT to GF
MapList map = new MapList(new int[] { 4, 6, 10, 12 },
new int[] { 1, 2 }, 3, 1);
AlignedCodonFrame acf = new AlignedCodonFrame();
acf.addMap(dna1.getDatasetSequence(), pep1.getDatasetSequence(), map);
- mappings.add(acf);
+ dna.addCodonFrame(acf);
// map aaa...ccc to KP
map = new MapList(new int[] { 1, 3, 7, 9 }, new int[] { 1, 2 }, 3, 1);
acf = new AlignedCodonFrame();
acf.addMap(dna1.getDatasetSequence(), pep2.getDatasetSequence(), map);
- mappings.add(acf);
+ dna.addCodonFrame(acf);
// map aaa......TTT to KF
map = new MapList(new int[] { 1, 3, 10, 12 }, new int[] { 1, 2 }, 3, 1);
acf = new AlignedCodonFrame();
acf.addMap(dna1.getDatasetSequence(), pep3.getDatasetSequence(), map);
- mappings.add(acf);
-
- /*
- * Create the CDS alignment; also augments the dna-to-protein mappings with
- * exon-to-protein and exon-to-dna mappings
- */
- AlignmentI dna = new Alignment(new SequenceI[] { dna1 });
- dna.setDataset(null);
+ dna.addCodonFrame(acf);
/*
* execute method under test
*/
AlignmentI cdsal = AlignmentUtils.makeCdsAlignment(
- new SequenceI[] { dna1 }, mappings, dna);
+ new SequenceI[] { dna1 }, dna.getDataset(), null);
/*
* Verify we have 3 cds sequences, mapped to pep1/2/3 respectively
SequenceI cdsSeq = cds.get(0);
assertEquals("GGGTTT", cdsSeq.getSequenceAsString());
// assertEquals("dna1|A12345", cdsSeq.getName());
- assertEquals("dna1|pep1", cdsSeq.getName());
+ assertEquals("CDS|dna1", cdsSeq.getName());
// assertEquals(1, cdsSeq.getDBRefs().length);
// DBRefEntry cdsRef = cdsSeq.getDBRefs()[0];
// assertEquals("EMBLCDS", cdsRef.getSource());
cdsSeq = cds.get(1);
assertEquals("aaaccc", cdsSeq.getSequenceAsString());
// assertEquals("dna1|A12346", cdsSeq.getName());
- assertEquals("dna1|pep2", cdsSeq.getName());
+ assertEquals("CDS|dna1", cdsSeq.getName());
// assertEquals(1, cdsSeq.getDBRefs().length);
// cdsRef = cdsSeq.getDBRefs()[0];
// assertEquals("EMBLCDS", cdsRef.getSource());
cdsSeq = cds.get(2);
assertEquals("aaaTTT", cdsSeq.getSequenceAsString());
// assertEquals("dna1|A12347", cdsSeq.getName());
- assertEquals("dna1|pep3", cdsSeq.getName());
+ assertEquals("CDS|dna1", cdsSeq.getName());
// assertEquals(1, cdsSeq.getDBRefs().length);
// cdsRef = cdsSeq.getDBRefs()[0];
// assertEquals("EMBLCDS", cdsRef.getSource());
* Verify there are mappings from each cds sequence to its protein product
* and also to its dna source
*/
- Iterator<AlignedCodonFrame> newMappingsIterator = cdsal
- .getCodonFrames().iterator();
-
- // mappings for dna1 - exon1 - pep1
- AlignedCodonFrame cdsMapping = newMappingsIterator.next();
- List<Mapping> dnaMappings = cdsMapping.getMappingsFromSequence(dna1);
- assertEquals(3, dnaMappings.size());
- assertSame(cds.get(0).getDatasetSequence(), dnaMappings.get(0)
- .getTo());
- assertEquals("G(1) in CDS should map to G(4) in DNA", 4, dnaMappings
- .get(0).getMap().getToPosition(1));
- List<Mapping> peptideMappings = cdsMapping.getMappingsFromSequence(cds
- .get(0).getDatasetSequence());
- assertEquals(1, peptideMappings.size());
- assertSame(pep1.getDatasetSequence(), peptideMappings.get(0).getTo());
-
- // mappings for dna1 - cds2 - pep2
- assertSame(cds.get(1).getDatasetSequence(), dnaMappings.get(1)
- .getTo());
- assertEquals("c(4) in CDS should map to c(7) in DNA", 7, dnaMappings
- .get(1).getMap().getToPosition(4));
- peptideMappings = cdsMapping.getMappingsFromSequence(cds.get(1)
- .getDatasetSequence());
- assertEquals(1, peptideMappings.size());
- assertSame(pep2.getDatasetSequence(), peptideMappings.get(0).getTo());
-
- // mappings for dna1 - cds3 - pep3
- assertSame(cds.get(2).getDatasetSequence(), dnaMappings.get(2)
- .getTo());
- assertEquals("T(4) in CDS should map to T(10) in DNA", 10, dnaMappings
- .get(2).getMap().getToPosition(4));
- peptideMappings = cdsMapping.getMappingsFromSequence(cds.get(2)
- .getDatasetSequence());
- assertEquals(1, peptideMappings.size());
- assertSame(pep3.getDatasetSequence(), peptideMappings.get(0).getTo());
+ List<AlignedCodonFrame> newMappings = cdsal.getCodonFrames();
+
+ /*
+ * 6 mappings involve dna1 (to pep1/2/3, cds1/2/3)
+ */
+ List<AlignedCodonFrame> dnaMappings = MappingUtils
+ .findMappingsForSequence(dna1, newMappings);
+ assertEquals(6, dnaMappings.size());
+
+ /*
+ * dna1 to pep1
+ */
+ List<AlignedCodonFrame> mappings = MappingUtils
+ .findMappingsForSequence(pep1, dnaMappings);
+ assertEquals(1, mappings.size());
+ assertEquals(1, mappings.get(0).getMappings().size());
+ assertSame(pep1.getDatasetSequence(), mappings.get(0).getMappings()
+ .get(0).getMapping().getTo());
+
+ /*
+ * dna1 to cds1
+ */
+ List<AlignedCodonFrame> dnaToCds1Mappings = MappingUtils
+ .findMappingsForSequence(cds.get(0), dnaMappings);
+ Mapping mapping = dnaToCds1Mappings.get(0).getMappings().get(0)
+ .getMapping();
+ assertSame(cds.get(0).getDatasetSequence(), mapping.getTo());
+ assertEquals("G(1) in CDS should map to G(4) in DNA", 4, mapping
+ .getMap().getToPosition(1));
+
+ /*
+ * dna1 to pep2
+ */
+ mappings = MappingUtils.findMappingsForSequence(pep2, dnaMappings);
+ assertEquals(1, mappings.size());
+ assertEquals(1, mappings.get(0).getMappings().size());
+ assertSame(pep2.getDatasetSequence(), mappings.get(0).getMappings()
+ .get(0).getMapping().getTo());
+
+ /*
+ * dna1 to cds2
+ */
+ List<AlignedCodonFrame> dnaToCds2Mappings = MappingUtils
+ .findMappingsForSequence(cds.get(1), dnaMappings);
+ mapping = dnaToCds2Mappings.get(0).getMappings().get(0).getMapping();
+ assertSame(cds.get(1).getDatasetSequence(), mapping.getTo());
+ assertEquals("c(4) in CDS should map to c(7) in DNA", 7, mapping
+ .getMap().getToPosition(4));
+
+ /*
+ * dna1 to pep3
+ */
+ mappings = MappingUtils.findMappingsForSequence(pep3, dnaMappings);
+ assertEquals(1, mappings.size());
+ assertEquals(1, mappings.get(0).getMappings().size());
+ assertSame(pep3.getDatasetSequence(), mappings.get(0).getMappings()
+ .get(0).getMapping().getTo());
+
+ /*
+ * dna1 to cds3
+ */
+ List<AlignedCodonFrame> dnaToCds3Mappings = MappingUtils
+ .findMappingsForSequence(cds.get(2), dnaMappings);
+ mapping = dnaToCds3Mappings.get(0).getMappings().get(0).getMapping();
+ assertSame(cds.get(2).getDatasetSequence(), mapping.getTo());
+ assertEquals("T(4) in CDS should map to T(10) in DNA", 10, mapping
+ .getMap().getToPosition(4));
}
@Test(groups = { "Functional" })
* @throws IOException
*/
@Test(groups = { "Functional" })
- public void testMapCdnaToProtein_forSubsequence()
- throws IOException
+ public void testMapCdnaToProtein_forSubsequence() throws IOException
{
SequenceI prot = new Sequence("UNIPROT|V12345", "E-I--Q", 10, 12);
prot.createDatasetSequence();
@Test(groups = { "Functional" })
public void testAlignSequenceAs_mappedProteinProtein()
{
-
+
SequenceI alignMe = new Sequence("Match", "MGAASEV");
alignMe.createDatasetSequence();
SequenceI alignFrom = new Sequence("Query", "LQTGYMGAASEVMFSPTRR");
MapList map = new MapList(new int[] { 6, 12 }, new int[] { 1, 7 }, 1, 1);
acf.addMap(alignFrom.getDatasetSequence(),
alignMe.getDatasetSequence(), map);
-
+
AlignmentUtils.alignSequenceAs(alignMe, alignFrom, acf, "-", '-', true,
true);
assertEquals("-----MGAASEV-------", alignMe.getSequenceAsString());
{
// map first 3 codons to KPF; G is a trailing unmapped residue
MapList map = new MapList(new int[] { 1, 9 }, new int[] { 1, 3 }, 3, 1);
-
+
checkAlignSequenceAs("AAACCCTTT", "K-PFG", true, true, map,
"AAA---CCCTTT---");
}
MapList map = new MapList(new int[] { 4, 6, 10, 12 },
new int[] { 1, 6 }, 1, 1);
-
+
// [5, 11] maps to [2, 5]
dna.addSequenceFeature(new SequenceFeature("type4", "desc4", 5, 11, 4f,
null));
// [12, 12] maps to [6, 6]
dna.addSequenceFeature(new SequenceFeature("type8", "desc8", 12, 12,
8f, null));
-
+
// desc4 and desc8 are the 'omit these' varargs
AlignmentUtils.transferFeatures(dna, cds, map, null, "type4", "type8");
SequenceFeature[] sfs = cds.getSequenceFeatures();
assertEquals(1, sfs.length);
-
+
SequenceFeature sf = sfs[0];
assertEquals("type5", sf.getType());
assertEquals(1, sf.getBegin());
{
SequenceI dna = new Sequence("dna/20-34", "acgTAGcaaGCCcgt");
SequenceI cds = new Sequence("cds/10-15", "TAGGCC");
-
+
MapList map = new MapList(new int[] { 4, 6, 10, 12 },
new int[] { 1, 6 }, 1, 1);
-
+
// [5, 11] maps to [2, 5]
dna.addSequenceFeature(new SequenceFeature("type4", "desc4", 5, 11, 4f,
null));
// [12, 12] maps to [6, 6]
dna.addSequenceFeature(new SequenceFeature("type8", "desc8", 12, 12,
8f, null));
-
+
// "type5" is the 'select this type' argument
AlignmentUtils.transferFeatures(dna, cds, map, "type5");
SequenceFeature[] sfs = cds.getSequenceFeatures();
assertEquals(1, sfs.length);
-
+
SequenceFeature sf = sfs[0];
assertEquals("type5", sf.getType());
assertEquals(1, sf.getBegin());
dna3.createDatasetSequence();
pep1.createDatasetSequence();
pep2.createDatasetSequence();
- dna1.addSequenceFeature(new SequenceFeature("CDS", "cds1", 4, 8, 0f,
- null));
- dna1.addSequenceFeature(new SequenceFeature("CDS", "cds2", 9, 12, 0f,
- null));
- dna1.addSequenceFeature(new SequenceFeature("CDS", "cds3", 16, 18, 0f,
- null));
- dna2.addSequenceFeature(new SequenceFeature("CDS", "cds", 4, 8, 0f,
- null));
- dna2.addSequenceFeature(new SequenceFeature("CDS", "cds", 12, 12, 0f,
- null));
- dna2.addSequenceFeature(new SequenceFeature("CDS", "cds", 16, 18, 0f,
- null));
-
- List<AlignedCodonFrame> mappings = new ArrayList<AlignedCodonFrame>();
+
+ AlignmentI dna = new Alignment(new SequenceI[] { dna1, dna2, dna3 });
+ dna.setDataset(null);
+
MapList map = new MapList(new int[] { 4, 12, 16, 18 },
new int[] { 1, 4 }, 3, 1);
AlignedCodonFrame acf = new AlignedCodonFrame();
acf.addMap(dna1.getDatasetSequence(), pep1.getDatasetSequence(), map);
- mappings.add(acf);
+ dna.addCodonFrame(acf);
map = new MapList(new int[] { 4, 8, 12, 12, 16, 18 },
- new int[] { 1, 3 },
- 3, 1);
+ new int[] { 1, 3 }, 3, 1);
acf = new AlignedCodonFrame();
acf.addMap(dna2.getDatasetSequence(), pep2.getDatasetSequence(), map);
- mappings.add(acf);
-
- AlignmentI dna = new Alignment(new SequenceI[] { dna1, dna2, dna3 });
- dna.setDataset(null);
+ dna.addCodonFrame(acf);
+
AlignmentI cds = AlignmentUtils.makeCdsAlignment(new SequenceI[] {
- dna1, dna2, dna3 }, mappings, dna);
+ dna1, dna2, dna3 }, dna.getDataset(), null);
List<SequenceI> cdsSeqs = cds.getSequences();
assertEquals(2, cdsSeqs.size());
assertEquals("GGGCCCTTTGGG", cdsSeqs.get(0).getSequenceAsString());
assertEquals("GGGCCTGGG", cdsSeqs.get(1).getSequenceAsString());
-
+
/*
* verify shared, extended alignment dataset
*/
.contains(cdsSeqs.get(1).getDatasetSequence()));
/*
- * Verify updated mappings
+ * Verify 6 mappings: dna1 to cds1, cds1 to pep1, dna1 to pep1
+ * and the same for dna2/cds2/pep2
*/
- List<AlignedCodonFrame> cdsMappings = cds.getCodonFrames();
- assertEquals(2, cdsMappings.size());
-
+ List<AlignedCodonFrame> mappings = cds.getCodonFrames();
+ assertEquals(6, mappings.size());
+
/*
- * Mapping from pep1 to GGGTTT in first new CDS sequence
+ * 2 mappings involve pep1
*/
- List<AlignedCodonFrame> pep1Mapping = MappingUtils
- .findMappingsForSequence(pep1, cdsMappings);
- assertEquals(1, pep1Mapping.size());
+ List<AlignedCodonFrame> pep1Mappings = MappingUtils
+ .findMappingsForSequence(pep1, mappings);
+ assertEquals(2, pep1Mappings.size());
+
/*
+ * Get mapping of pep1 to cds1 and verify it
* maps GPFG to 1-3,4-6,7-9,10-12
*/
- SearchResults sr = MappingUtils
- .buildSearchResults(pep1, 1, cdsMappings);
+ List<AlignedCodonFrame> pep1CdsMappings = MappingUtils
+ .findMappingsForSequence(cds.getSequenceAt(0), pep1Mappings);
+ assertEquals(1, pep1CdsMappings.size());
+ SearchResults sr = MappingUtils.buildSearchResults(pep1, 1,
+ pep1CdsMappings);
assertEquals(1, sr.getResults().size());
Match m = sr.getResults().get(0);
- assertEquals(cds.getSequenceAt(0).getDatasetSequence(),
- m.getSequence());
+ assertEquals(cds.getSequenceAt(0).getDatasetSequence(), m.getSequence());
assertEquals(1, m.getStart());
assertEquals(3, m.getEnd());
- sr = MappingUtils.buildSearchResults(pep1, 2, cdsMappings);
+ sr = MappingUtils.buildSearchResults(pep1, 2, pep1CdsMappings);
m = sr.getResults().get(0);
assertEquals(4, m.getStart());
assertEquals(6, m.getEnd());
- sr = MappingUtils.buildSearchResults(pep1, 3, cdsMappings);
+ sr = MappingUtils.buildSearchResults(pep1, 3, pep1CdsMappings);
m = sr.getResults().get(0);
assertEquals(7, m.getStart());
assertEquals(9, m.getEnd());
- sr = MappingUtils.buildSearchResults(pep1, 4, cdsMappings);
+ sr = MappingUtils.buildSearchResults(pep1, 4, pep1CdsMappings);
m = sr.getResults().get(0);
assertEquals(10, m.getStart());
assertEquals(12, m.getEnd());
-
+
/*
- * GPG in pep2 map to 1-3,4-6,7-9 in second CDS sequence
+ * Get mapping of pep2 to cds2 and verify it
+ * maps GPG in pep2 to 1-3,4-6,7-9 in second CDS sequence
*/
- List<AlignedCodonFrame> pep2Mapping = MappingUtils
- .findMappingsForSequence(pep2, cdsMappings);
- assertEquals(1, pep2Mapping.size());
- sr = MappingUtils.buildSearchResults(pep2, 1, cdsMappings);
+ List<AlignedCodonFrame> pep2Mappings = MappingUtils
+ .findMappingsForSequence(pep2, mappings);
+ assertEquals(2, pep2Mappings.size());
+ List<AlignedCodonFrame> pep2CdsMappings = MappingUtils
+ .findMappingsForSequence(cds.getSequenceAt(1), pep2Mappings);
+ assertEquals(1, pep2CdsMappings.size());
+ sr = MappingUtils.buildSearchResults(pep2, 1, pep2CdsMappings);
assertEquals(1, sr.getResults().size());
m = sr.getResults().get(0);
- assertEquals(cds.getSequenceAt(1).getDatasetSequence(),
- m.getSequence());
+ assertEquals(cds.getSequenceAt(1).getDatasetSequence(), m.getSequence());
assertEquals(1, m.getStart());
assertEquals(3, m.getEnd());
- sr = MappingUtils.buildSearchResults(pep2, 2, cdsMappings);
+ sr = MappingUtils.buildSearchResults(pep2, 2, pep2CdsMappings);
m = sr.getResults().get(0);
assertEquals(4, m.getStart());
assertEquals(6, m.getEnd());
- sr = MappingUtils.buildSearchResults(pep2, 3, cdsMappings);
+ sr = MappingUtils.buildSearchResults(pep2, 3, pep2CdsMappings);
m = sr.getResults().get(0);
assertEquals(7, m.getStart());
assertEquals(9, m.getEnd());
SequenceI dna3 = new Sequence("Seq3", "ccaaa-ttt-GGG-");
AlignmentI dna = new Alignment(new SequenceI[] { dna1, dna2, dna3 });
dna.setDataset(null);
-
+
// prot1 has 'X' for incomplete start codon (not mapped)
SequenceI prot1 = new Sequence("Seq1", "XKFG"); // X for incomplete start
SequenceI prot2 = new Sequence("Seq2", "NG");
AlignmentI protein = new Alignment(new SequenceI[] { prot1, prot2,
prot3 });
protein.setDataset(null);
-
+
// map dna1 [3, 11] to prot1 [2, 4] KFG
MapList map = new MapList(new int[] { 3, 11 }, new int[] { 2, 4 }, 3, 1);
AlignedCodonFrame acf = new AlignedCodonFrame();
SequenceI dnaSeq = new Sequence("dna", "aaagGGCCCaaaTTTttt");
dnaSeq.createDatasetSequence();
SequenceI ds = dnaSeq.getDatasetSequence();
-
+
// CDS for dna 5-6 (incomplete codon), 7-9
SequenceFeature sf = new SequenceFeature("CDS", "", 5, 9, 0f, null);
sf.setPhase("2"); // skip 2 bases to start of next codon
// CDS for dna 13-15
sf = new SequenceFeature("CDS_predicted", "", 13, 15, 0f, null);
ds.addSequenceFeature(sf);
-
+
List<int[]> ranges = AlignmentUtils.findCdsPositions(dnaSeq);
-
+
/*
* check the mapping starts with the first complete codon
*/
SequenceI dnaSeq = new Sequence("dna", "aaaGGGcccAAATTTttt");
dnaSeq.createDatasetSequence();
SequenceI ds = dnaSeq.getDatasetSequence();
-
+
// CDS for dna 10-12
SequenceFeature sf = new SequenceFeature("CDS_predicted", "", 10, 12,
0f, null);
// exon feature should be ignored here
sf = new SequenceFeature("exon", "", 7, 9, 0f, null);
ds.addSequenceFeature(sf);
-
+
List<int[]> ranges = AlignmentUtils.findCdsPositions(dnaSeq);
/*
* verify ranges { [4-6], [12-10] }
public void testComputePeptideVariants()
{
/*
- * scenario: AAATTTCCC codes for KFP, with variants
- * GAA -> E
- * CAA -> Q
- * AAG synonymous
- * AAT -> N
- * TTC synonymous
- * CAC,CGC -> H,R (as one variant)
+ * scenario: AAATTTCCC codes for KFP
+ * variants:
+ * GAA -> E source: Ensembl
+ * CAA -> Q source: dbSNP
+ * AAG synonymous source: COSMIC
+ * AAT -> N source: Ensembl
+ * ...TTC synonymous source: dbSNP
+ * ......CAC,CGC -> H,R source: COSMIC
+ * (one variant with two alleles)
*/
SequenceI peptide = new Sequence("pep/10-12", "KFP");
* two distinct variants for codon 1 position 1
* second one has clinical significance
*/
+ String ensembl = "Ensembl";
+ String dbSnp = "dbSNP";
+ String cosmic = "COSMIC";
SequenceFeature sf1 = new SequenceFeature("sequence_variant", "", 1, 1,
- 0f, null);
+ 0f, ensembl);
sf1.setValue("alleles", "A,G"); // GAA -> E
sf1.setValue("ID", "var1.125A>G");
SequenceFeature sf2 = new SequenceFeature("sequence_variant", "", 1, 1,
- 0f, null);
+ 0f, dbSnp);
sf2.setValue("alleles", "A,C"); // CAA -> Q
sf2.setValue("ID", "var2");
sf2.setValue("clinical_significance", "Dodgy");
SequenceFeature sf3 = new SequenceFeature("sequence_variant", "", 3, 3,
- 0f, null);
+ 0f, cosmic);
sf3.setValue("alleles", "A,G"); // synonymous
sf3.setValue("ID", "var3");
sf3.setValue("clinical_significance", "None");
SequenceFeature sf4 = new SequenceFeature("sequence_variant", "", 3, 3,
- 0f, null);
+ 0f, ensembl);
sf4.setValue("alleles", "A,T"); // AAT -> N
sf4.setValue("ID", "sequence_variant:var4"); // prefix gets stripped off
sf4.setValue("clinical_significance", "Benign");
SequenceFeature sf5 = new SequenceFeature("sequence_variant", "", 6, 6,
- 0f, null);
+ 0f, dbSnp);
sf5.setValue("alleles", "T,C"); // synonymous
sf5.setValue("ID", "var5");
sf5.setValue("clinical_significance", "Bad");
SequenceFeature sf6 = new SequenceFeature("sequence_variant", "", 8, 8,
- 0f, null);
+ 0f, cosmic);
sf6.setValue("alleles", "C,A,G"); // CAC,CGC -> H,R
sf6.setValue("ID", "var6");
sf6.setValue("clinical_significance", "Good");
/*
* verify added sequence features for
- * var1 K -> E
- * var2 K -> Q
- * var4 K -> N
- * var6 P -> H
- * var6 P -> R
+ * var1 K -> E Ensembl
+ * var2 K -> Q dbSNP
+ * var4 K -> N Ensembl
+ * var6 P -> H COSMIC
+ * var6 P -> R COSMIC
*/
SequenceFeature[] sfs = peptide.getSequenceFeatures();
assertEquals(5, sfs.length);
+
SequenceFeature sf = sfs[0];
assertEquals(1, sf.getBegin());
assertEquals(1, sf.getEnd());
assertEquals(
"p.Lys1Glu var1.125A>G|http://www.ensembl.org/Homo_sapiens/Variation/Summary?v=var1.125A%3EG",
sf.links.get(0));
- assertEquals("Jalview", sf.getFeatureGroup());
+ assertEquals(ensembl, sf.getFeatureGroup());
+
sf = sfs[1];
assertEquals(1, sf.getBegin());
assertEquals(1, sf.getEnd());
assertEquals(
"p.Lys1Gln var2|http://www.ensembl.org/Homo_sapiens/Variation/Summary?v=var2",
sf.links.get(0));
- assertEquals("Jalview", sf.getFeatureGroup());
+ assertEquals(dbSnp, sf.getFeatureGroup());
+
sf = sfs[2];
assertEquals(1, sf.getBegin());
assertEquals(1, sf.getEnd());
assertEquals(
"p.Lys1Asn var4|http://www.ensembl.org/Homo_sapiens/Variation/Summary?v=var4",
sf.links.get(0));
- assertEquals("Jalview", sf.getFeatureGroup());
+ assertEquals(ensembl, sf.getFeatureGroup());
+
+ // var5 generates two distinct protein variant features
sf = sfs[3];
assertEquals(3, sf.getBegin());
assertEquals(3, sf.getEnd());
assertEquals(
"p.Pro3His var6|http://www.ensembl.org/Homo_sapiens/Variation/Summary?v=var6",
sf.links.get(0));
- // var5 generates two distinct protein variant features
- assertEquals("Jalview", sf.getFeatureGroup());
+ assertEquals(cosmic, sf.getFeatureGroup());
+
sf = sfs[4];
assertEquals(3, sf.getBegin());
assertEquals(3, sf.getEnd());
assertEquals(
"p.Pro3Arg var6|http://www.ensembl.org/Homo_sapiens/Variation/Summary?v=var6",
sf.links.get(0));
- assertEquals("Jalview", sf.getFeatureGroup());
+ assertEquals(cosmic, sf.getFeatureGroup());
}
/**
SequenceI dnaSeq = new Sequence("dna", "aaaGGGcccAAATTTttt");
dnaSeq.createDatasetSequence();
SequenceI ds = dnaSeq.getDatasetSequence();
-
+
// CDS for dna 4-6
SequenceFeature sf = new SequenceFeature("CDS", "", 4, 6, 0f, null);
sf.setStrand("-");
sf = new SequenceFeature("CDS_predicted", "", 10, 12, 0f, null);
sf.setStrand("-");
ds.addSequenceFeature(sf);
-
+
List<int[]> ranges = AlignmentUtils.findCdsPositions(dnaSeq);
/*
* verify ranges { [12-10], [6-4] }
SequenceI dnaSeq = new Sequence("dna", "aaagGGCCCaaaTTTttt");
dnaSeq.createDatasetSequence();
SequenceI ds = dnaSeq.getDatasetSequence();
-
+
// CDS for dna 5-9
SequenceFeature sf = new SequenceFeature("CDS", "", 5, 9, 0f, null);
sf.setStrand("-");
sf.setStrand("-");
sf.setPhase("2"); // skip 2 bases to start of next codon
ds.addSequenceFeature(sf);
-
+
List<int[]> ranges = AlignmentUtils.findCdsPositions(dnaSeq);
-
+
/*
* check the mapping starts with the first complete codon
* expect ranges [13, 13], [9, 5]
from.createDatasetSequence();
seq1.createDatasetSequence();
Mapping mapping = new Mapping(seq1, new MapList(
- new int[] { 3, 6, 9, 10 },
- new int[] { 1, 6 }, 1, 1));
+ new int[] { 3, 6, 9, 10 }, new int[] { 1, 6 }, 1, 1));
Map<Integer, Map<SequenceI, Character>> map = new TreeMap<Integer, Map<SequenceI, Character>>();
AlignmentUtils.addMappedPositions(seq1, from, mapping, map);
from.createDatasetSequence();
seq1.createDatasetSequence();
Mapping mapping = new Mapping(seq1, new MapList(
- new int[] { 3, 6, 9, 10 },
- new int[] { 1, 6 }, 1, 1));
+ new int[] { 3, 6, 9, 10 }, new int[] { 1, 6 }, 1, 1));
Map<Integer, Map<SequenceI, Character>> map = new TreeMap<Integer, Map<SequenceI, Character>>();
AlignmentUtils.addMappedPositions(seq1, from, mapping, map);
-
+
/*
* verify map has seq1 residues in columns 3,4,6,7,11,12
*/
assertEquals('T', map.get(11).get(seq1).charValue());
assertEquals('T', map.get(12).get(seq1).charValue());
}
+
+ /**
+ * Test for the case where the products for which we want CDS are specified.
+ * This is to represent the case where EMBL has CDS mappings to both Uniprot
+ * and EMBLCDSPROTEIN. makeCdsAlignment() should only return the mappings for
+ * the protein sequences specified.
+ */
+ @Test(groups = { "Functional" })
+ public void testMakeCdsAlignment_filterProducts()
+ {
+ SequenceI dna1 = new Sequence("dna1", "aaaGGGcccTTTaaa");
+ SequenceI dna2 = new Sequence("dna2", "GGGcccTTTaaaCCC");
+ SequenceI pep1 = new Sequence("Uniprot|pep1", "GF");
+ SequenceI pep2 = new Sequence("Uniprot|pep2", "GFP");
+ SequenceI pep3 = new Sequence("EMBL|pep3", "GF");
+ SequenceI pep4 = new Sequence("EMBL|pep4", "GFP");
+ dna1.createDatasetSequence();
+ dna2.createDatasetSequence();
+ pep1.createDatasetSequence();
+ pep2.createDatasetSequence();
+ pep3.createDatasetSequence();
+ pep4.createDatasetSequence();
+ AlignmentI dna = new Alignment(new SequenceI[] { dna1, dna2 });
+ dna.setDataset(null);
+ AlignmentI emblPeptides = new Alignment(new SequenceI[] { pep3, pep4 });
+ emblPeptides.setDataset(null);
+
+ AlignedCodonFrame acf = new AlignedCodonFrame();
+ MapList map = new MapList(new int[] { 4, 6, 10, 12 },
+ new int[] { 1, 2 }, 3, 1);
+ acf.addMap(dna1.getDatasetSequence(), pep1.getDatasetSequence(), map);
+ acf.addMap(dna1.getDatasetSequence(), pep3.getDatasetSequence(), map);
+ dna.addCodonFrame(acf);
+
+ acf = new AlignedCodonFrame();
+ map = new MapList(new int[] { 1, 3, 7, 9, 13, 15 }, new int[] { 1, 3 },
+ 3, 1);
+ acf.addMap(dna2.getDatasetSequence(), pep2.getDatasetSequence(), map);
+ acf.addMap(dna2.getDatasetSequence(), pep4.getDatasetSequence(), map);
+ dna.addCodonFrame(acf);
+
+ /*
+ * execute method under test to find CDS for EMBL peptides only
+ */
+ AlignmentI cds = AlignmentUtils.makeCdsAlignment(new SequenceI[] {
+ dna1, dna2 }, dna.getDataset(), emblPeptides.getSequencesArray());
+
+ assertEquals(2, cds.getSequences().size());
+ assertEquals("GGGTTT", cds.getSequenceAt(0).getSequenceAsString());
+ assertEquals("GGGTTTCCC", cds.getSequenceAt(1).getSequenceAsString());
+
+ /*
+ * verify shared, extended alignment dataset
+ */
+ assertSame(dna.getDataset(), cds.getDataset());
+ assertTrue(dna.getDataset().getSequences()
+ .contains(cds.getSequenceAt(0).getDatasetSequence()));
+ assertTrue(dna.getDataset().getSequences()
+ .contains(cds.getSequenceAt(1).getDatasetSequence()));
+
+ /*
+ * Verify mappings from CDS to peptide, cDNA to CDS, and cDNA to peptide
+ * the mappings are on the shared alignment dataset
+ */
+ List<AlignedCodonFrame> cdsMappings = cds.getDataset().getCodonFrames();
+ /*
+ * 6 mappings, 2*(DNA->CDS), 2*(DNA->Pep), 2*(CDS->Pep)
+ */
+ assertEquals(6, cdsMappings.size());
+
+ /*
+ * verify that mapping sets for dna and cds alignments are different
+ * [not current behaviour - all mappings are on the alignment dataset]
+ */
+ // select -> subselect type to test.
+ // Assert.assertNotSame(dna.getCodonFrames(), cds.getCodonFrames());
+ // assertEquals(4, dna.getCodonFrames().size());
+ // assertEquals(4, cds.getCodonFrames().size());
+
+ /*
+ * Two mappings involve pep3 (dna to pep3, cds to pep3)
+ * Mapping from pep3 to GGGTTT in first new exon sequence
+ */
+ List<AlignedCodonFrame> pep3Mappings = MappingUtils
+ .findMappingsForSequence(pep3, cdsMappings);
+ assertEquals(2, pep3Mappings.size());
+ List<AlignedCodonFrame> mappings = MappingUtils
+ .findMappingsForSequence(cds.getSequenceAt(0), pep3Mappings);
+ assertEquals(1, mappings.size());
+
+ // map G to GGG
+ SearchResults sr = MappingUtils.buildSearchResults(pep3, 1, mappings);
+ assertEquals(1, sr.getResults().size());
+ Match m = sr.getResults().get(0);
+ assertSame(cds.getSequenceAt(0).getDatasetSequence(), m.getSequence());
+ assertEquals(1, m.getStart());
+ assertEquals(3, m.getEnd());
+ // map F to TTT
+ sr = MappingUtils.buildSearchResults(pep3, 2, mappings);
+ m = sr.getResults().get(0);
+ assertSame(cds.getSequenceAt(0).getDatasetSequence(), m.getSequence());
+ assertEquals(4, m.getStart());
+ assertEquals(6, m.getEnd());
+
+ /*
+ * Two mappings involve pep4 (dna to pep4, cds to pep4)
+ * Verify mapping from pep4 to GGGTTTCCC in second new exon sequence
+ */
+ List<AlignedCodonFrame> pep4Mappings = MappingUtils
+ .findMappingsForSequence(pep4, cdsMappings);
+ assertEquals(2, pep4Mappings.size());
+ mappings = MappingUtils.findMappingsForSequence(cds.getSequenceAt(1),
+ pep4Mappings);
+ assertEquals(1, mappings.size());
+ // map G to GGG
+ sr = MappingUtils.buildSearchResults(pep4, 1, mappings);
+ assertEquals(1, sr.getResults().size());
+ m = sr.getResults().get(0);
+ assertSame(cds.getSequenceAt(1).getDatasetSequence(), m.getSequence());
+ assertEquals(1, m.getStart());
+ assertEquals(3, m.getEnd());
+ // map F to TTT
+ sr = MappingUtils.buildSearchResults(pep4, 2, mappings);
+ m = sr.getResults().get(0);
+ assertSame(cds.getSequenceAt(1).getDatasetSequence(), m.getSequence());
+ assertEquals(4, m.getStart());
+ assertEquals(6, m.getEnd());
+ // map P to CCC
+ sr = MappingUtils.buildSearchResults(pep4, 3, mappings);
+ m = sr.getResults().get(0);
+ assertSame(cds.getSequenceAt(1).getDatasetSequence(), m.getSequence());
+ assertEquals(7, m.getStart());
+ assertEquals(9, m.getEnd());
+ }
+
+ /**
+ * Test the method that just copies aligned sequences, provided all sequences
+ * to be aligned share the aligned sequence's dataset
+ */
+ @Test(groups = "Functional")
+ public void testAlignAsSameSequences()
+ {
+ SequenceI dna1 = new Sequence("dna1", "cccGGGTTTaaa");
+ SequenceI dna2 = new Sequence("dna2", "CCCgggtttAAA");
+ AlignmentI al1 = new Alignment(new SequenceI[] { dna1, dna2 });
+ ((Alignment) al1).createDatasetAlignment();
+
+ SequenceI dna3 = new Sequence(dna1);
+ SequenceI dna4 = new Sequence(dna2);
+ assertSame(dna3.getDatasetSequence(), dna1.getDatasetSequence());
+ assertSame(dna4.getDatasetSequence(), dna2.getDatasetSequence());
+ String seq1 = "-cc-GG-GT-TT--aaa";
+ dna3.setSequence(seq1);
+ String seq2 = "C--C-Cgg--gtt-tAA-A-";
+ dna4.setSequence(seq2);
+ AlignmentI al2 = new Alignment(new SequenceI[] { dna3, dna4 });
+ ((Alignment) al2).createDatasetAlignment();
+
+ assertTrue(AlignmentUtils.alignAsSameSequences(al1, al2));
+ assertEquals(seq1, al1.getSequenceAt(0).getSequenceAsString());
+ assertEquals(seq2, al1.getSequenceAt(1).getSequenceAsString());
+
+ /*
+ * add another sequence to 'aligned' - should still succeed, since
+ * unaligned sequences still share a dataset with aligned sequences
+ */
+ SequenceI dna5 = new Sequence("dna5", "CCCgggtttAAA");
+ dna5.createDatasetSequence();
+ al2.addSequence(dna5);
+ assertTrue(AlignmentUtils.alignAsSameSequences(al1, al2));
+ assertEquals(seq1, al1.getSequenceAt(0).getSequenceAsString());
+ assertEquals(seq2, al1.getSequenceAt(1).getSequenceAsString());
+
+ /*
+ * add another sequence to 'unaligned' - should fail, since now not
+ * all unaligned sequences share a dataset with aligned sequences
+ */
+ SequenceI dna6 = new Sequence("dna6", "CCCgggtttAAA");
+ dna6.createDatasetSequence();
+ al1.addSequence(dna6);
+ // JAL-2110 JBP Comment: what's the use case for this behaviour ?
+ assertFalse(AlignmentUtils.alignAsSameSequences(al1, al2));
+ }
+
+ @Test(groups = "Functional")
+ public void testAlignAsSameSequencesMultipleSubSeq()
+ {
+ SequenceI dna1 = new Sequence("dna1", "cccGGGTTTaaa");
+ SequenceI dna2 = new Sequence("dna2", "CCCgggtttAAA");
+ SequenceI as1 = dna1.deriveSequence();
+ SequenceI as2 = dna1.deriveSequence().getSubSequence(3, 7);
+ SequenceI as3 = dna2.deriveSequence();
+ as1.insertCharAt(6, 5, '-');
+ String s_as1 = as1.getSequenceAsString();
+ as2.insertCharAt(6, 5, '-');
+ String s_as2 = as2.getSequenceAsString();
+ as3.insertCharAt(6, 5, '-');
+ String s_as3 = as3.getSequenceAsString();
+ AlignmentI aligned = new Alignment(new SequenceI[] { as1, as2, as3 });
+
+ // why do we need to cast this still ?
+ ((Alignment) aligned).createDatasetAlignment();
+ SequenceI uas1 = dna1.deriveSequence();
+ SequenceI uas2 = dna1.deriveSequence().getSubSequence(3, 7);
+ SequenceI uas3 = dna2.deriveSequence();
+ AlignmentI tobealigned = new Alignment(new SequenceI[] { uas1, uas2,
+ uas3 });
+ ((Alignment) tobealigned).createDatasetAlignment();
+
+ assertTrue(AlignmentUtils.alignAsSameSequences(tobealigned, aligned));
+ assertEquals(s_as1, uas1.getSequenceAsString());
+ assertEquals(s_as2, uas2.getSequenceAsString());
+ assertEquals(s_as3, uas3.getSequenceAsString());
+ }
+
}
package jalview.analysis;
import static org.testng.AssertJUnit.assertEquals;
+import static org.testng.AssertJUnit.assertFalse;
+import static org.testng.AssertJUnit.assertNotNull;
+import static org.testng.AssertJUnit.assertNotSame;
+import static org.testng.AssertJUnit.assertNull;
import static org.testng.AssertJUnit.assertSame;
+import static org.testng.AssertJUnit.assertTrue;
+import jalview.datamodel.AlignedCodonFrame;
+import jalview.datamodel.AlignedCodonFrame.SequenceToSequenceMapping;
+import jalview.datamodel.Alignment;
+import jalview.datamodel.AlignmentI;
import jalview.datamodel.DBRefEntry;
+import jalview.datamodel.Mapping;
+import jalview.datamodel.Sequence;
+import jalview.datamodel.SequenceFeature;
+import jalview.datamodel.SequenceI;
+import jalview.util.DBRefUtils;
+import jalview.util.MapList;
+import jalview.ws.SequenceFetcher;
+import jalview.ws.SequenceFetcherFactory;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.testng.annotations.AfterClass;
import org.testng.annotations.Test;
public class CrossRefTest
DBRefEntry ref6 = new DBRefEntry("emblCDS", "1", "A123");
DBRefEntry ref7 = new DBRefEntry("GeneDB", "1", "A123");
DBRefEntry ref8 = new DBRefEntry("PFAM", "1", "A123");
+ // ENSEMBL is a source of either dna or protein sequence data
+ DBRefEntry ref9 = new DBRefEntry("ENSEMBL", "1", "A123");
DBRefEntry[] refs = new DBRefEntry[] { ref1, ref2, ref3, ref4, ref5,
- ref6, ref7, ref8 };
+ ref6, ref7, ref8, ref9 };
/*
* Just the DNA refs:
*/
- DBRefEntry[] found = CrossRef.findXDbRefs(false, refs);
- assertEquals(3, found.length);
+ DBRefEntry[] found = DBRefUtils.selectDbRefs(true, refs);
+ assertEquals(4, found.length);
assertSame(ref5, found[0]);
assertSame(ref6, found[1]);
assertSame(ref7, found[2]);
+ assertSame(ref9, found[3]);
/*
* Just the protein refs:
*/
- found = CrossRef.findXDbRefs(true, refs);
+ found = DBRefUtils.selectDbRefs(false, refs);
assertEquals(4, found.length);
assertSame(ref1, found[0]);
assertSame(ref2, found[1]);
- assertSame(ref3, found[2]);
- assertSame(ref4, found[3]);
+ assertSame(ref4, found[2]);
+ assertSame(ref9, found[3]);
+ }
+
+ /**
+ * Test the method that finds a sequence's "product" xref source databases,
+ * which may be direct (dbrefs on the sequence), or indirect (dbrefs on
+ * sequences which share a dbref with the sequence
+ */
+ @Test(groups = { "Functional" }, enabled = true)
+ public void testFindXrefSourcesForSequence_proteinToDna()
+ {
+ SequenceI seq = new Sequence("Seq1", "MGKYQARLSS");
+ List<String> sources = new ArrayList<String>();
+ AlignmentI al = new Alignment(new SequenceI[] {});
+
+ /*
+ * first with no dbrefs to search
+ */
+ sources = new CrossRef(new SequenceI[] { seq }, al)
+ .findXrefSourcesForSequences(false);
+ assertTrue(sources.isEmpty());
+
+ /*
+ * add some dbrefs to sequence
+ */
+ // protein db is not a candidate for findXrefSources
+ seq.addDBRef(new DBRefEntry("UNIPROT", "0", "A1234"));
+ // dna coding databatases are
+ seq.addDBRef(new DBRefEntry("EMBL", "0", "E2345"));
+ // a second EMBL xref should not result in a duplicate
+ seq.addDBRef(new DBRefEntry("EMBL", "0", "E2346"));
+ seq.addDBRef(new DBRefEntry("EMBLCDS", "0", "E2347"));
+ seq.addDBRef(new DBRefEntry("GENEDB", "0", "E2348"));
+ seq.addDBRef(new DBRefEntry("ENSEMBL", "0", "E2349"));
+ seq.addDBRef(new DBRefEntry("ENSEMBLGENOMES", "0", "E2350"));
+ sources = new CrossRef(new SequenceI[] { seq }, al)
+ .findXrefSourcesForSequences(false);
+ // method is patched to remove EMBL from the sources to match
+ assertEquals(3, sources.size());
+ assertEquals("[EMBLCDS, GENEDB, ENSEMBL]", sources.toString());
+
+ /*
+ * add a sequence to the alignment which has a dbref to UNIPROT|A1234
+ * and others to dna coding databases
+ */
+ sources.clear();
+ seq.setDBRefs(null);
+ seq.addDBRef(new DBRefEntry("UNIPROT", "0", "A1234"));
+ seq.addDBRef(new DBRefEntry("EMBLCDS", "0", "E2347"));
+ SequenceI seq2 = new Sequence("Seq2", "MGKYQARLSS");
+ seq2.addDBRef(new DBRefEntry("UNIPROT", "0", "A1234"));
+ seq2.addDBRef(new DBRefEntry("EMBL", "0", "E2345"));
+ seq2.addDBRef(new DBRefEntry("GENEDB", "0", "E2348"));
+ // TODO include ENSEMBLGENOMES in DBRefSource.DNACODINGDBS ?
+ al.addSequence(seq2);
+ sources = new CrossRef(new SequenceI[] { seq, seq2 }, al)
+ .findXrefSourcesForSequences(false);
+ // method removed EMBL from sources to match
+ assertEquals(2, sources.size());
+ assertEquals("[EMBLCDS, GENEDB]", sources.toString());
+ }
+
+ /**
+ * Test for finding 'product' sequences for the case where only an indirect
+ * xref is found - not on the nucleotide sequence but on a peptide sequence in
+ * the alignment which which it shares a nucleotide dbref
+ */
+ @Test(groups = { "Functional" }, enabled = true)
+ public void testFindXrefSequences_indirectDbrefToProtein()
+ {
+ /*
+ * Alignment setup:
+ * - nucleotide dbref EMBL|AF039662
+ * - peptide dbrefs EMBL|AF039662, UNIPROT|Q9ZTS2
+ */
+ SequenceI emblSeq = new Sequence("AF039662", "GGGGCAGCACAAGAAC");
+ emblSeq.addDBRef(new DBRefEntry("EMBL", "0", "AF039662"));
+ SequenceI uniprotSeq = new Sequence("Q9ZTS2", "MASVSATMISTS");
+ uniprotSeq.addDBRef(new DBRefEntry("EMBL", "0", "AF039662"));
+ uniprotSeq.addDBRef(new DBRefEntry("UNIPROT", "0", "Q9ZTS2"));
+
+ /*
+ * Find UNIPROT xrefs for nucleotide
+ * - it has no UNIPROT dbref of its own
+ * - but peptide with matching nucleotide dbref does, so is returned
+ */
+ AlignmentI al = new Alignment(new SequenceI[] { emblSeq, uniprotSeq });
+ Alignment xrefs = new CrossRef(new SequenceI[] { emblSeq }, al)
+ .findXrefSequences("UNIPROT", true);
+ assertEquals(1, xrefs.getHeight());
+ assertSame(uniprotSeq, xrefs.getSequenceAt(0));
+ }
+
+ /**
+ * Test for finding 'product' sequences for the case where only an indirect
+ * xref is found - not on the peptide sequence but on a nucleotide sequence in
+ * the alignment which which it shares a protein dbref
+ */
+ @Test(groups = { "Functional" }, enabled = true)
+ public void testFindXrefSequences_indirectDbrefToNucleotide()
+ {
+ /*
+ * Alignment setup:
+ * - peptide dbref UNIPROT|Q9ZTS2
+ * - nucleotide dbref EMBL|AF039662, UNIPROT|Q9ZTS2
+ */
+ SequenceI uniprotSeq = new Sequence("Q9ZTS2", "MASVSATMISTS");
+ uniprotSeq.addDBRef(new DBRefEntry("UNIPROT", "0", "Q9ZTS2"));
+ SequenceI emblSeq = new Sequence("AF039662", "GGGGCAGCACAAGAAC");
+ emblSeq.addDBRef(new DBRefEntry("EMBL", "0", "AF039662"));
+ emblSeq.addDBRef(new DBRefEntry("UNIPROT", "0", "Q9ZTS2"));
+
+ /*
+ * find EMBL xrefs for peptide sequence - it has no direct
+ * dbrefs, but the 'corresponding' nucleotide sequence does, so is returned
+ */
+ /*
+ * Find EMBL xrefs for peptide
+ * - it has no EMBL dbref of its own
+ * - but nucleotide with matching peptide dbref does, so is returned
+ */
+ AlignmentI al = new Alignment(new SequenceI[] { emblSeq, uniprotSeq });
+ Alignment xrefs = new CrossRef(new SequenceI[] { uniprotSeq }, al)
+ .findXrefSequences("EMBL", false);
+ assertEquals(1, xrefs.getHeight());
+ assertSame(emblSeq, xrefs.getSequenceAt(0));
+ }
+
+ /**
+ * Test for finding 'product' sequences for the case where the selected
+ * sequence has no dbref to the desired source, and there are no indirect
+ * references via another sequence in the alignment
+ */
+ @Test(groups = { "Functional" })
+ public void testFindXrefSequences_noDbrefs()
+ {
+ /*
+ * two nucleotide sequences, one with UNIPROT dbref
+ */
+ SequenceI dna1 = new Sequence("AF039662", "GGGGCAGCACAAGAAC");
+ dna1.addDBRef(new DBRefEntry("UNIPROT", "0", "Q9ZTS2"));
+ SequenceI dna2 = new Sequence("AJ307031", "AAACCCTTT");
+
+ /*
+ * find UNIPROT xrefs for peptide sequence - it has no direct
+ * dbrefs, and the other sequence (which has a UNIPROT dbref) is not
+ * equatable to it, so no results found
+ */
+ AlignmentI al = new Alignment(new SequenceI[] { dna1, dna2 });
+ Alignment xrefs = new CrossRef(new SequenceI[] { dna2 }, al)
+ .findXrefSequences("UNIPROT", true);
+ assertNull(xrefs);
+ }
+
+ /**
+ * Tests for the method that searches an alignment (with one sequence
+ * excluded) for protein/nucleotide sequences with a given cross-reference
+ */
+ @Test(groups = { "Functional" }, enabled = true)
+ public void testSearchDataset()
+ {
+ /*
+ * nucleotide sequence with UNIPROT AND EMBL dbref
+ * peptide sequence with UNIPROT dbref
+ */
+ SequenceI dna1 = new Sequence("AF039662", "GGGGCAGCACAAGAAC");
+ Mapping map = new Mapping(new Sequence("pep2", "MLAVSRG"), new MapList(
+ new int[] { 1, 21 }, new int[] { 1, 7 }, 3, 1));
+ DBRefEntry dbref = new DBRefEntry("UNIPROT", "0", "Q9ZTS2", map);
+ dna1.addDBRef(dbref);
+ dna1.addDBRef(new DBRefEntry("EMBL", "0", "AF039662"));
+ SequenceI pep1 = new Sequence("Q9ZTS2", "MLAVSRGQ");
+ dbref = new DBRefEntry("UNIPROT", "0", "Q9ZTS2");
+ pep1.addDBRef(new DBRefEntry("UNIPROT", "0", "Q9ZTS2"));
+ AlignmentI al = new Alignment(new SequenceI[] { dna1, pep1 });
+
+ List<SequenceI> result = new ArrayList<SequenceI>();
+
+ /*
+ * first search for a dbref nowhere on the alignment:
+ */
+ dbref = new DBRefEntry("UNIPROT", "0", "P30419");
+ CrossRef testee = new CrossRef(al.getSequencesArray(), al);
+ AlignedCodonFrame acf = new AlignedCodonFrame();
+ boolean found = testee.searchDataset(true, dna1, dbref, result, acf,
+ true);
+ assertFalse(found);
+ assertTrue(result.isEmpty());
+ assertTrue(acf.isEmpty());
+
+ /*
+ * search for a protein sequence with dbref UNIPROT:Q9ZTS2
+ */
+ acf = new AlignedCodonFrame();
+ dbref = new DBRefEntry("UNIPROT", "0", "Q9ZTS2");
+ found = testee.searchDataset(!dna1.isProtein(), dna1, dbref, result,
+ acf, false); // search dataset with a protein xref from a dna
+ // sequence to locate the protein product
+ assertTrue(found);
+ assertEquals(1, result.size());
+ assertSame(pep1, result.get(0));
+ assertTrue(acf.isEmpty());
+
+ /*
+ * search for a nucleotide sequence with dbref UNIPROT:Q9ZTS2
+ */
+ result.clear();
+ acf = new AlignedCodonFrame();
+ dbref = new DBRefEntry("UNIPROT", "0", "Q9ZTS2");
+ found = testee.searchDataset(!pep1.isProtein(), pep1, dbref, result,
+ acf, false); // search dataset with a protein's direct dbref to
+ // locate dna sequences with matching xref
+ assertTrue(found);
+ assertEquals(1, result.size());
+ assertSame(dna1, result.get(0));
+ // should now have a mapping from dna to pep1
+ List<SequenceToSequenceMapping> mappings = acf.getMappings();
+ assertEquals(1, mappings.size());
+ SequenceToSequenceMapping mapping = mappings.get(0);
+ assertSame(dna1, mapping.getFromSeq());
+ assertSame(pep1, mapping.getMapping().getTo());
+ MapList mapList = mapping.getMapping().getMap();
+ assertEquals(1, mapList.getToRatio());
+ assertEquals(3, mapList.getFromRatio());
+ assertEquals(1, mapList.getFromRanges().size());
+ assertEquals(1, mapList.getFromRanges().get(0)[0]);
+ assertEquals(21, mapList.getFromRanges().get(0)[1]);
+ assertEquals(1, mapList.getToRanges().size());
+ assertEquals(1, mapList.getToRanges().get(0)[0]);
+ assertEquals(7, mapList.getToRanges().get(0)[1]);
+ }
+
+ /**
+ * Test for finding 'product' sequences for the case where the selected
+ * sequence has a dbref with a mapping to a sequence. This represents the case
+ * where either
+ * <ul>
+ * <li>a fetched sequence is already decorated with its cross-reference (e.g.
+ * EMBL + translation), or</li>
+ * <li>Get Cross-References has been done once resulting in instantiated
+ * cross-reference mappings</li>
+ * </ul>
+ */
+ @Test(groups = { "Functional" })
+ public void testFindXrefSequences_fromDbRefMap()
+ {
+ /*
+ * scenario: nucleotide sequence AF039662
+ * with dbref + mapping to Q9ZTS2 and P30419
+ * which themselves each have a dbref and feature
+ */
+ SequenceI dna1 = new Sequence("AF039662", "GGGGCAGCACAAGAAC");
+ SequenceI pep1 = new Sequence("Q9ZTS2", "MALFQRSV");
+ SequenceI pep2 = new Sequence("P30419", "MTRRSQIF");
+ dna1.createDatasetSequence();
+ pep1.createDatasetSequence();
+ pep2.createDatasetSequence();
+
+ pep1.getDatasetSequence().addDBRef(
+ new DBRefEntry("Pfam", "0", "PF00111"));
+ pep1.addSequenceFeature(new SequenceFeature("type", "desc", 12, 14, 1f,
+ "group"));
+ pep2.getDatasetSequence().addDBRef(new DBRefEntry("PDB", "0", "3JTK"));
+ pep2.addSequenceFeature(new SequenceFeature("type2", "desc2", 13, 15,
+ 12f, "group2"));
+
+ MapList mapList = new MapList(new int[] { 1, 24 }, new int[] { 1, 3 },
+ 3, 1);
+ Mapping map = new Mapping(pep1, mapList);
+ DBRefEntry dbRef1 = new DBRefEntry("UNIPROT", "0", "Q9ZTS2", map);
+ dna1.getDatasetSequence().addDBRef(dbRef1);
+ mapList = new MapList(new int[] { 1, 24 }, new int[] { 1, 3 }, 3, 1);
+ map = new Mapping(pep2, mapList);
+ DBRefEntry dbRef2 = new DBRefEntry("UNIPROT", "0", "P30419", map);
+ dna1.getDatasetSequence().addDBRef(dbRef2);
+
+ /*
+ * find UNIPROT xrefs for nucleotide sequence - it should pick up
+ * mapped sequences
+ */
+ AlignmentI al = new Alignment(new SequenceI[] { dna1 });
+ Alignment xrefs = new CrossRef(new SequenceI[] { dna1 }, al)
+ .findXrefSequences("UNIPROT", true);
+ assertEquals(2, xrefs.getHeight());
+
+ /*
+ * cross-refs alignment holds copies of the mapped sequences
+ * including copies of their dbrefs and features
+ */
+ checkCopySequence(pep1, xrefs.getSequenceAt(0));
+ checkCopySequence(pep2, xrefs.getSequenceAt(1));
+ }
+
+ /**
+ * Helper method that verifies that 'copy' has the same name, start, end,
+ * sequence and dataset sequence object as 'original' (but is not the same
+ * object)
+ *
+ * @param copy
+ * @param original
+ */
+ private void checkCopySequence(SequenceI copy, SequenceI original)
+ {
+ assertNotSame(copy, original);
+ assertSame(copy.getDatasetSequence(), original.getDatasetSequence());
+ assertEquals(copy.getName(), original.getName());
+ assertEquals(copy.getStart(), original.getStart());
+ assertEquals(copy.getEnd(), original.getEnd());
+ assertEquals(copy.getSequenceAsString(), original.getSequenceAsString());
+ }
+
+ /**
+ * Test for finding 'product' sequences for the case where the selected
+ * sequence has a dbref with no mapping, triggering a fetch from database
+ */
+ @Test(groups = { "Functional" })
+ public void testFindXrefSequences_withFetch()
+ {
+ SequenceI dna1 = new Sequence("AF039662", "GGGGCAGCACAAGAAC");
+ dna1.addDBRef(new DBRefEntry("UNIPROT", "ENA:0", "Q9ZTS2"));
+ dna1.addDBRef(new DBRefEntry("UNIPROT", "ENA:0", "P30419"));
+ dna1.addDBRef(new DBRefEntry("UNIPROT", "ENA:0", "P00314"));
+ final SequenceI pep1 = new Sequence("Q9ZTS2", "MYQLIRSSW");
+ pep1.addDBRef(new DBRefEntry("UNIPROT", "0", "Q9ZTS2"));
+
+ final SequenceI pep2 = new Sequence("P00314", "MRKLLAASG");
+ pep2.addDBRef(new DBRefEntry("UNIPROT", "0", "P00314"));
+
+ /*
+ * argument false suppresses adding DAS sources
+ * todo: define an interface type SequenceFetcherI and mock that
+ */
+ SequenceFetcher mockFetcher = new SequenceFetcher(false)
+ {
+ @Override
+ public boolean isFetchable(String source)
+ {
+ return true;
+ }
+
+ @Override
+ public SequenceI[] getSequences(List<DBRefEntry> refs, boolean dna)
+ {
+ return new SequenceI[] { pep1, pep2 };
+ }
+ };
+ SequenceFetcherFactory.setSequenceFetcher(mockFetcher);
+
+ /*
+ * find UNIPROT xrefs for nucleotide sequence
+ */
+ AlignmentI al = new Alignment(new SequenceI[] { dna1 });
+ Alignment xrefs = new CrossRef(new SequenceI[] { dna1 }, al)
+ .findXrefSequences("UNIPROT", true);
+ assertEquals(2, xrefs.getHeight());
+ assertSame(pep1, xrefs.getSequenceAt(0));
+ assertSame(pep2, xrefs.getSequenceAt(1));
+ }
+
+ @AfterClass
+ public void tearDown()
+ {
+ SequenceFetcherFactory.setSequenceFetcher(null);
+ }
+
+ /**
+ * Test for finding 'product' sequences for the case where both gene and
+ * transcript sequences have dbrefs to Uniprot.
+ */
+ @Test(groups = { "Functional" })
+ public void testFindXrefSequences_forGeneAndTranscripts()
+ {
+ /*
+ * 'gene' sequence
+ */
+ SequenceI gene = new Sequence("ENSG00000157764", "CGCCTCCCTTCCCC");
+ gene.addDBRef(new DBRefEntry("UNIPROT", "0", "P15056"));
+ gene.addDBRef(new DBRefEntry("UNIPROT", "0", "H7C5K3"));
+
+ /*
+ * 'transcript' with CDS feature (supports mapping to protein)
+ */
+ SequenceI braf001 = new Sequence("ENST00000288602", "taagATGGCGGCGCTGa");
+ braf001.addDBRef(new DBRefEntry("UNIPROT", "0", "P15056"));
+ braf001.addSequenceFeature(new SequenceFeature("CDS", "", 5, 16, 0f,
+ null));
+
+ /*
+ * 'spliced transcript' with CDS ranges
+ */
+ SequenceI braf002 = new Sequence("ENST00000497784", "gCAGGCtaTCTGTTCaa");
+ braf002.addDBRef(new DBRefEntry("UNIPROT", "ENSEMBL|0", "H7C5K3"));
+ braf002.addSequenceFeature(new SequenceFeature("CDS", "", 2, 6, 0f,
+ null));
+ braf002.addSequenceFeature(new SequenceFeature("CDS", "", 9, 15, 0f,
+ null));
+
+ /*
+ * TODO code is fragile - use of SequenceIdMatcher depends on fetched
+ * sequences having a name starting Source|Accession
+ * which happens to be true for Uniprot,PDB,EMBL but not Pfam,Rfam,Ensembl
+ */
+ final SequenceI pep1 = new Sequence("UNIPROT|P15056", "MAAL");
+ pep1.addDBRef(new DBRefEntry("UNIPROT", "0", "P15056"));
+ final SequenceI pep2 = new Sequence("UNIPROT|H7C5K3", "QALF");
+ pep2.addDBRef(new DBRefEntry("UNIPROT", "0", "H7C5K3"));
+ /*
+ * argument false suppresses adding DAS sources
+ * todo: define an interface type SequenceFetcherI and mock that
+ */
+ SequenceFetcher mockFetcher = new SequenceFetcher(false)
+ {
+ @Override
+ public boolean isFetchable(String source)
+ {
+ return true;
+ }
+
+ @Override
+ public SequenceI[] getSequences(List<DBRefEntry> refs, boolean dna)
+ {
+ return new SequenceI[] { pep1, pep2 };
+ }
+ };
+ SequenceFetcherFactory.setSequenceFetcher(mockFetcher);
+
+ /*
+ * find UNIPROT xrefs for gene and transcripts
+ * verify that
+ * - the two proteins are retrieved but not duplicated
+ * - mappings are built from transcript (CDS) to proteins
+ * - no mappings from gene to proteins
+ */
+ SequenceI[] seqs = new SequenceI[] { gene, braf001, braf002 };
+ AlignmentI al = new Alignment(seqs);
+ Alignment xrefs = new CrossRef(seqs, al).findXrefSequences("UNIPROT",
+ true);
+ assertEquals(2, xrefs.getHeight());
+ assertSame(pep1, xrefs.getSequenceAt(0));
+ assertSame(pep2, xrefs.getSequenceAt(1));
+ }
+
+ /**
+ * <pre>
+ * Test that emulates this (real but simplified) case:
+ * Alignment: DBrefs
+ * UNIPROT|P0CE19 EMBL|J03321, EMBL|X06707, EMBL|M19487
+ * UNIPROT|P0CE20 EMBL|J03321, EMBL|X06707, EMBL|X07547
+ * Find cross-references for EMBL. These are mocked here as
+ * EMBL|J03321 with mappings to P0CE18, P0CE19, P0CE20
+ * EMBL|X06707 with mappings to P0CE17, P0CE19, P0CE20
+ * EMBL|M19487 with mappings to P0CE19, Q46432
+ * EMBL|X07547 with mappings to P0CE20, B0BCM4
+ * EMBL sequences are first 'fetched' (mocked here) for P0CE19.
+ * The 3 EMBL sequences are added to the alignment dataset.
+ * Their dbrefs to Uniprot products P0CE19 and P0CE20 should be matched in the
+ * alignment dataset and updated to reference the original Uniprot sequences.
+ * For the second Uniprot sequence, the J03321 and X06707 xrefs should be
+ * resolved from the dataset, and only the X07547 dbref fetched.
+ * So the end state to verify is:
+ * - 4 cross-ref sequences returned: J03321, X06707, M19487, X07547
+ * - P0CE19/20 dbrefs to EMBL sequences now have mappings
+ * - J03321 dbrefs to P0CE19/20 mapped to original Uniprot sequences
+ * - X06707 dbrefs to P0CE19/20 mapped to original Uniprot sequences
+ * </pre>
+ */
+ @Test(groups = { "Functional" })
+ public void testFindXrefSequences_uniprotEmblManyToMany()
+ {
+ /*
+ * Uniprot sequences, both with xrefs to EMBL|J03321
+ * and EMBL|X07547
+ */
+ SequenceI p0ce19 = new Sequence("UNIPROT|P0CE19", "KPFG");
+ p0ce19.addDBRef(new DBRefEntry("EMBL", "0", "J03321"));
+ p0ce19.addDBRef(new DBRefEntry("EMBL", "0", "X06707"));
+ p0ce19.addDBRef(new DBRefEntry("EMBL", "0", "M19487"));
+ SequenceI p0ce20 = new Sequence("UNIPROT|P0CE20", "PFGK");
+ p0ce20.addDBRef(new DBRefEntry("EMBL", "0", "J03321"));
+ p0ce20.addDBRef(new DBRefEntry("EMBL", "0", "X06707"));
+ p0ce20.addDBRef(new DBRefEntry("EMBL", "0", "X07547"));
+
+ /*
+ * EMBL sequences to be 'fetched', complete with dbrefs and mappings
+ * to their protein products (CDS location and translations are provided
+ * in EMBL XML); these should be matched to, and replaced with,
+ * the corresponding uniprot sequences after fetching
+ */
+
+ /*
+ * J03321 with mappings to P0CE19 and P0CE20
+ */
+ final SequenceI j03321 = new Sequence("EMBL|J03321", "AAACCCTTTGGGAAAA");
+ DBRefEntry dbref1 = new DBRefEntry("UNIPROT", "0", "P0CE19");
+ MapList mapList = new MapList(new int[] { 1, 12 }, new int[] { 1, 4 },
+ 3, 1);
+ Mapping map = new Mapping(new Sequence("UNIPROT|P0CE19", "KPFG"),
+ mapList);
+ // add a dbref to the mapped to sequence - should get copied to p0ce19
+ map.getTo().addDBRef(new DBRefEntry("PIR", "0", "S01875"));
+ dbref1.setMap(map);
+ j03321.addDBRef(dbref1);
+ DBRefEntry dbref2 = new DBRefEntry("UNIPROT", "0", "P0CE20");
+ mapList = new MapList(new int[] { 4, 15 }, new int[] { 2, 5 }, 3, 1);
+ dbref2.setMap(new Mapping(new Sequence("UNIPROT|P0CE20", "PFGK"),
+ new MapList(mapList)));
+ j03321.addDBRef(dbref2);
+
+ /*
+ * X06707 with mappings to P0CE19 and P0CE20
+ */
+ final SequenceI x06707 = new Sequence("EMBL|X06707", "atgAAACCCTTTGGG");
+ DBRefEntry dbref3 = new DBRefEntry("UNIPROT", "0", "P0CE19");
+ MapList map2 = new MapList(new int[] { 4, 15 }, new int[] { 1, 4 }, 3,
+ 1);
+ dbref3.setMap(new Mapping(new Sequence("UNIPROT|P0CE19", "KPFG"), map2));
+ x06707.addDBRef(dbref3);
+ DBRefEntry dbref4 = new DBRefEntry("UNIPROT", "0", "P0CE20");
+ MapList map3 = new MapList(new int[] { 4, 15 }, new int[] { 1, 4 }, 3,
+ 1);
+ dbref4.setMap(new Mapping(new Sequence("UNIPROT|P0CE20", "PFGK"), map3));
+ x06707.addDBRef(dbref4);
+
+ /*
+ * M19487 with mapping to P0CE19 and Q46432
+ */
+ final SequenceI m19487 = new Sequence("EMBL|M19487", "AAACCCTTTGGG");
+ DBRefEntry dbref5 = new DBRefEntry("UNIPROT", "0", "P0CE19");
+ dbref5.setMap(new Mapping(new Sequence("UNIPROT|P0CE19", "KPFG"),
+ new MapList(mapList)));
+ m19487.addDBRef(dbref5);
+ DBRefEntry dbref6 = new DBRefEntry("UNIPROT", "0", "Q46432");
+ dbref6.setMap(new Mapping(new Sequence("UNIPROT|Q46432", "KPFG"),
+ new MapList(mapList)));
+ m19487.addDBRef(dbref6);
+
+ /*
+ * X07547 with mapping to P0CE20 and B0BCM4
+ */
+ final SequenceI x07547 = new Sequence("EMBL|X07547", "cccAAACCCTTTGGG");
+ DBRefEntry dbref7 = new DBRefEntry("UNIPROT", "0", "P0CE20");
+ dbref7.setMap(new Mapping(new Sequence("UNIPROT|P0CE20", "PFGK"),
+ new MapList(map2)));
+ x07547.addDBRef(dbref7);
+ DBRefEntry dbref8 = new DBRefEntry("UNIPROT", "0", "B0BCM4");
+ dbref8.setMap(new Mapping(new Sequence("UNIPROT|B0BCM4", "KPFG"),
+ new MapList(map2)));
+ x07547.addDBRef(dbref8);
+
+ /*
+ * mock sequence fetcher to 'return' the EMBL sequences
+ * TODO: Mockito would allow .thenReturn().thenReturn() here,
+ * and also capture and verification of the parameters
+ * passed in calls to getSequences() - important to verify that
+ * duplicate sequence fetches are not requested
+ */
+ SequenceFetcher mockFetcher = new SequenceFetcher(false)
+ {
+ int call = 0;
+
+ @Override
+ public boolean isFetchable(String source)
+ {
+ return true;
+ }
+
+ @Override
+ public SequenceI[] getSequences(List<DBRefEntry> refs, boolean dna)
+ {
+ call++;
+ if (call == 1)
+ {
+ assertEquals("Expected 3 embl seqs in first fetch", 3,
+ refs.size());
+ return new SequenceI[] { j03321, x06707, m19487 };
+ }
+ else
+ {
+ assertEquals("Expected 1 embl seq in second fetch", 1,
+ refs.size());
+ return new SequenceI[] { x07547 };
+ }
+ }
+ };
+ SequenceFetcherFactory.setSequenceFetcher(mockFetcher);
+
+ /*
+ * find EMBL xrefs for Uniprot seqs and verify that
+ * - the EMBL xref'd sequences are retrieved without duplicates
+ * - mappings are added to the Uniprot dbrefs
+ * - mappings in the EMBL-to-Uniprot dbrefs are updated to the
+ * alignment sequences
+ * - dbrefs on the EMBL sequences are added to the original dbrefs
+ */
+ SequenceI[] seqs = new SequenceI[] { p0ce19, p0ce20 };
+ AlignmentI al = new Alignment(seqs);
+ Alignment xrefs = new CrossRef(seqs, al).findXrefSequences("EMBL",
+ false);
+
+ /*
+ * verify retrieved sequences
+ */
+ assertNotNull(xrefs);
+ assertEquals(4, xrefs.getHeight());
+ assertSame(j03321, xrefs.getSequenceAt(0));
+ assertSame(x06707, xrefs.getSequenceAt(1));
+ assertSame(m19487, xrefs.getSequenceAt(2));
+ assertSame(x07547, xrefs.getSequenceAt(3));
+
+ /*
+ * verify mappings added to Uniprot-to-EMBL dbrefs
+ */
+ Mapping mapping = p0ce19.getDBRefs()[0].getMap();
+ assertSame(j03321, mapping.getTo());
+ mapping = p0ce19.getDBRefs()[1].getMap();
+ assertSame(x06707, mapping.getTo());
+ mapping = p0ce20.getDBRefs()[0].getMap();
+ assertSame(j03321, mapping.getTo());
+ mapping = p0ce20.getDBRefs()[1].getMap();
+ assertSame(x06707, mapping.getTo());
+
+ /*
+ * verify dbrefs on EMBL are mapped to alignment seqs
+ */
+ assertSame(p0ce19, j03321.getDBRefs()[0].getMap().getTo());
+ assertSame(p0ce20, j03321.getDBRefs()[1].getMap().getTo());
+ assertSame(p0ce19, x06707.getDBRefs()[0].getMap().getTo());
+ assertSame(p0ce20, x06707.getDBRefs()[1].getMap().getTo());
+
+ /*
+ * verify new dbref on EMBL dbref mapping is copied to the
+ * original Uniprot sequence
+ */
+ assertEquals(4, p0ce19.getDBRefs().length);
+ assertEquals("PIR", p0ce19.getDBRefs()[3].getSource());
+ assertEquals("S01875", p0ce19.getDBRefs()[3].getAccessionId());
}
+ @Test(groups = "Functional")
+ public void testSameSequence()
+ {
+ assertTrue(CrossRef.sameSequence(null, null));
+ SequenceI seq1 = new Sequence("seq1", "ABCDEF");
+ assertFalse(CrossRef.sameSequence(seq1, null));
+ assertFalse(CrossRef.sameSequence(null, seq1));
+ assertTrue(CrossRef.sameSequence(seq1, new Sequence("seq2", "ABCDEF")));
+ assertTrue(CrossRef.sameSequence(seq1, new Sequence("seq2", "abcdef")));
+ assertFalse(CrossRef
+ .sameSequence(seq1, new Sequence("seq2", "ABCDE-F")));
+ assertFalse(CrossRef.sameSequence(seq1, new Sequence("seq2", "BCDEF")));
+ }
}
import jalview.datamodel.Alignment;
import jalview.datamodel.AlignmentI;
import jalview.datamodel.ColumnSelection;
+import jalview.datamodel.Sequence;
import jalview.datamodel.SequenceI;
import jalview.gui.AlignViewport;
import jalview.io.FormatAdapter;
@Test(groups = "Functional")
public void testReverseSequence()
{
- String seq = "AcGtUrYkMbVdHNX";
+ String seq = "-Ac-GtU--rYkMbVdHNX-";
+ String seqRev = new StringBuilder(seq).reverse().toString();
// reverse:
SequenceI reversed = Dna.reverseSequence("Seq1", seq, false);
- assertEquals(new StringBuilder(seq).reverse()
- .toString(), reversed.getSequenceAsString());
+ assertEquals(1, reversed.getStart());
+ assertEquals(15, reversed.getEnd());
+ assertEquals(20, reversed.getLength());
+ assertEquals(seqRev, reversed.getSequenceAsString());
assertEquals("Seq1|rev", reversed.getName());
// reverse complement:
SequenceI revcomp = Dna.reverseSequence("Seq1", seq, true);
- assertEquals("XNDhBvKmRyAaCgT", revcomp.getSequenceAsString());
+ assertEquals("-XNDhBvKmRy--AaC-gT-", revcomp.getSequenceAsString());
assertEquals("Seq1|revcomp", revcomp.getName());
}
+
+ @Test(groups = "Functional")
+ public void testReverseCdna()
+ {
+ String seq = "-Ac-GtU--rYkMbVdHNX-";
+ String seqRev = new StringBuilder(seq).reverse().toString();
+ String seqDs = seq.replaceAll("-", "");
+ String seqDsRev = new StringBuilder(seqDs).reverse().toString();
+
+ SequenceI dna = new Sequence("Seq1", seq);
+ Alignment al = new Alignment(new SequenceI[] { dna });
+ al.createDatasetAlignment();
+ assertEquals(seqDs, al.getSequenceAt(0).getDatasetSequence()
+ .getSequenceAsString());
+
+ ColumnSelection cs = new ColumnSelection();
+ AlignViewportI av = new AlignViewport(al, cs);
+ Dna testee = new Dna(av, new int[] { 0, al.getWidth() - 1 });
+ AlignmentI reversed = testee.reverseCdna(false);
+ assertEquals(1, reversed.getHeight());
+ assertEquals(seqRev, reversed.getSequenceAt(0).getSequenceAsString());
+ assertEquals(seqDsRev, reversed.getSequenceAt(0).getDatasetSequence()
+ .getSequenceAsString());
+ }
}
import jalview.datamodel.SequenceGroup;
import jalview.datamodel.SequenceI;
-import java.util.ArrayList;
import java.util.Arrays;
import org.testng.AssertJUnit;
Sequence s5 = new Sequence("s5", "AAAADDEDTTEE");
- SequenceGroup sg1 = new SequenceGroup(Arrays.asList(new SequenceI[] { s1,
- s2 }), "Group1", null, false, false, false, 0, 5);
+ SequenceGroup sg_12 = new SequenceGroup(Arrays.asList(new SequenceI[] {
+ s1, s2 }), "Group1", null, false, false, false, 0, 5);
- SequenceGroup sg2 = new SequenceGroup(Arrays.asList(new SequenceI[] { s3,
- s4, s5 }), "Group2", null, false, false, false, 0, 5);
+ SequenceGroup sg_345 = new SequenceGroup(Arrays.asList(new SequenceI[] {
+ s3, s4, s5 }), "Group2", null, false, false, false, 0, 5);
AlignmentI alignment = new Alignment(
new SequenceI[] { s1, s2, s3, s4, s5 });
- int[] positions = new int[] { 1, 7, 9 };
+ /*
+ * test for the case where column selections are not added in
+ * left to right order
+ */
+ int[] positions = new int[] { 7, 9, 1 };
@Test(groups = { "Functional" })
public void testMakeGroupsWithBoth()
{
- ArrayList<String> str = new ArrayList<String>();
+ String[] str = new String[alignment.getHeight()];
+ int seq = 0;
for (SequenceI s : alignment.getSequences())
{
StringBuilder sb = new StringBuilder();
{
sb.append(s.getCharAt(p));
}
- str.add(sb.toString());
+ str[seq++] = sb.toString();
}
SequenceGroup[] seqgroupsString = Grouping.makeGroupsFrom(
- alignment.getSequencesArray(),
- str.toArray(new String[str.size()]),
- Arrays.asList(new SequenceGroup[] { sg1, sg2 }));
+ alignment.getSequencesArray(), str,
+ Arrays.asList(new SequenceGroup[] { sg_12, sg_345 }));
+
ColumnSelection cs = new ColumnSelection();
for (int p : positions)
{
}
SequenceGroup[] seqgroupsColSel = Grouping.makeGroupsFromCols(
alignment.getSequencesArray(), cs,
- Arrays.asList(new SequenceGroup[] { sg1, sg2 }));
+ Arrays.asList(new SequenceGroup[] { sg_12, sg_345 }));
AssertJUnit
.assertEquals(seqgroupsString.length, seqgroupsColSel.length);
for (int p = 0; p < seqgroupsString.length; p++)
--- /dev/null
+package jalview.analysis;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertTrue;
+
+import jalview.analysis.ResidueCount.SymbolCounts;
+
+import org.junit.Assert;
+import org.testng.annotations.Test;
+
+public class ResidueCountTest
+{
+ /**
+ * Test a mix of add and put for nucleotide counting
+ */
+ @Test(groups = "Functional")
+ public void test_countNucleotide()
+ {
+ ResidueCount rc = new ResidueCount(true);
+ assertEquals(rc.getCount('A'), 0);
+ assertEquals(rc.getGapCount(), 0);
+ // add then add
+ assertEquals(rc.add('A'), 1);
+ assertEquals(rc.add('a'), 2);
+ // put then add
+ rc.put('g', 3);
+ assertEquals(rc.add('G'), 4);
+ // add then put
+ assertEquals(rc.add('c'), 1);
+ rc.put('C', 4);
+ assertEquals(rc.add('N'), 1);
+
+ assertEquals(rc.getCount('a'), 2);
+ assertEquals(rc.getCount('A'), 2);
+ assertEquals(rc.getCount('G'), 4);
+ assertEquals(rc.getCount('c'), 4);
+ assertEquals(rc.getCount('T'), 0); // never seen
+ assertEquals(rc.getCount('N'), 1);
+ assertEquals(rc.getCount('?'), 0);
+ assertEquals(rc.getCount('-'), 0);
+
+ assertFalse(rc.isCountingInts());
+ assertFalse(rc.isUsingOtherData());
+ }
+
+ /**
+ * Test adding to gap count (either using addGap or add)
+ */
+ @Test(groups = "Functional")
+ public void testAddGap()
+ {
+ ResidueCount rc = new ResidueCount(true);
+ rc.addGap();
+ rc.add('-');
+ rc.add('.');
+ rc.add(' ');
+
+ assertEquals(rc.getGapCount(), 4);
+ assertEquals(rc.getCount(' '), 4);
+ assertEquals(rc.getCount('-'), 4);
+ assertEquals(rc.getCount('.'), 4);
+ assertFalse(rc.isUsingOtherData());
+ assertFalse(rc.isCountingInts());
+ }
+
+ @Test(groups = "Functional")
+ public void testOverflow()
+ {
+ /*
+ * overflow from add
+ */
+ ResidueCount rc = new ResidueCount(true);
+ rc.addGap();
+ rc.put('A', Short.MAX_VALUE - 1);
+ assertFalse(rc.isCountingInts());
+ rc.add('A');
+ assertFalse(rc.isCountingInts());
+ rc.add('A');
+ assertTrue(rc.isCountingInts());
+ assertEquals(rc.getCount('a'), Short.MAX_VALUE + 1);
+ rc.add('A');
+ assertTrue(rc.isCountingInts());
+ assertEquals(rc.getCount('a'), Short.MAX_VALUE + 2);
+ assertEquals(rc.getGapCount(), 1);
+ rc.addGap();
+ assertEquals(rc.getGapCount(), 2);
+
+ /*
+ * overflow from put
+ */
+ rc = new ResidueCount(true);
+ rc.put('G', Short.MAX_VALUE + 1);
+ assertTrue(rc.isCountingInts());
+ assertEquals(rc.getCount('g'), Short.MAX_VALUE + 1);
+ rc.put('G', 1);
+ assertTrue(rc.isCountingInts());
+ assertEquals(rc.getCount('g'), 1);
+
+ /*
+ * underflow from put
+ */
+ rc = new ResidueCount(true);
+ rc.put('G', Short.MIN_VALUE - 1);
+ assertTrue(rc.isCountingInts());
+ assertEquals(rc.getCount('g'), Short.MIN_VALUE - 1);
+ }
+
+ /**
+ * Test a mix of add and put for peptide counting
+ */
+ @Test(groups = "Functional")
+ public void test_countPeptide()
+ {
+ ResidueCount rc = new ResidueCount(false);
+ rc.put('q', 4);
+ rc.add('Q');
+ rc.add('X');
+ rc.add('x');
+ rc.add('W');
+ rc.put('w', 7);
+ rc.put('m', 12);
+ rc.put('M', 13);
+
+ assertEquals(rc.getCount('q'), 5);
+ assertEquals(rc.getCount('X'), 2);
+ assertEquals(rc.getCount('W'), 7);
+ assertEquals(rc.getCount('m'), 13);
+ assertEquals(rc.getCount('G'), 0);
+ assertEquals(rc.getCount('-'), 0);
+
+ assertFalse(rc.isCountingInts());
+ assertFalse(rc.isUsingOtherData());
+ }
+
+ @Test(groups = "Functional")
+ public void test_unexpectedPeptide()
+ {
+ ResidueCount rc = new ResidueCount(false);
+ // expected characters (upper or lower case):
+ String aas = "ACDEFGHIKLMNPQRSTVWXY";
+ String lower = aas.toLowerCase();
+ for (int i = 0; i < aas.length(); i++)
+ {
+ rc.put(aas.charAt(i), i);
+ rc.add(lower.charAt(i));
+ }
+ for (int i = 0; i < aas.length(); i++)
+ {
+ assertEquals(rc.getCount(aas.charAt(i)), i + 1);
+ }
+ assertFalse(rc.isUsingOtherData());
+
+ rc.put('J', 4);
+ assertTrue(rc.isUsingOtherData());
+ assertEquals(rc.getCount('J'), 4);
+ rc.add('j');
+ assertEquals(rc.getCount('J'), 5);
+ }
+
+ @Test(groups = "Functional")
+ public void test_unexpectedNucleotide()
+ {
+ ResidueCount rc = new ResidueCount(true);
+ // expected characters (upper or lower case):
+ String nucs = "ACGTUN";
+ String lower = nucs.toLowerCase();
+ for (int i = 0; i < nucs.length(); i++)
+ {
+ rc.put(nucs.charAt(i), i);
+ rc.add(lower.charAt(i));
+ }
+ for (int i = 0; i < nucs.length(); i++)
+ {
+ assertEquals(rc.getCount(nucs.charAt(i)), i + 1);
+ }
+ assertFalse(rc.isUsingOtherData());
+
+ rc.add('J');
+ assertTrue(rc.isUsingOtherData());
+ }
+
+ @Test(groups = "Functional")
+ public void testGetModalCount()
+ {
+ ResidueCount rc = new ResidueCount(true);
+ rc.add('c');
+ rc.add('g');
+ rc.add('c');
+ assertEquals(rc.getModalCount(), 2);
+
+ // modal count is in the 'short overflow' counts
+ rc = new ResidueCount();
+ rc.add('c');
+ rc.put('g', Short.MAX_VALUE);
+ rc.add('G');
+ assertEquals(rc.getModalCount(), Short.MAX_VALUE + 1);
+
+ // modal count is in the 'other data' counts
+ rc = new ResidueCount(false);
+ rc.add('Q');
+ rc.add('{');
+ rc.add('{');
+ assertEquals(rc.getModalCount(), 2);
+
+ // verify modal count excludes gap
+ rc = new ResidueCount();
+ rc.add('Q');
+ rc.add('P');
+ rc.add('Q');
+ rc.addGap();
+ rc.addGap();
+ rc.addGap();
+ assertEquals(rc.getModalCount(), 2);
+ }
+
+ @Test(groups = "Functional")
+ public void testGetResiduesForCount()
+ {
+ ResidueCount rc = new ResidueCount(true);
+ rc.add('c');
+ rc.add('g');
+ rc.add('c');
+ assertEquals(rc.getResiduesForCount(2), "C");
+ assertEquals(rc.getResiduesForCount(1), "G");
+ assertEquals(rc.getResiduesForCount(3), "");
+ assertEquals(rc.getResiduesForCount(0), "");
+ assertEquals(rc.getResiduesForCount(-1), "");
+
+ // modal count is in the 'short overflow' counts
+ rc = new ResidueCount(true);
+ rc.add('c');
+ rc.put('g', Short.MAX_VALUE);
+ rc.add('G');
+ assertEquals(rc.getResiduesForCount(Short.MAX_VALUE + 1), "G");
+ assertEquals(rc.getResiduesForCount(1), "C");
+
+ // peptide modal count is in the 'short overflow' counts
+ rc = new ResidueCount(false);
+ rc.add('c');
+ rc.put('p', Short.MAX_VALUE);
+ rc.add('P');
+ assertEquals(rc.getResiduesForCount(Short.MAX_VALUE + 1), "P");
+ assertEquals(rc.getResiduesForCount(1), "C");
+
+ // modal count is in the 'other data' counts
+ rc = new ResidueCount();
+ rc.add('Q');
+ rc.add('{');
+ rc.add('{');
+ assertEquals(rc.getResiduesForCount(1), "Q");
+ assertEquals(rc.getResiduesForCount(2), "{");
+
+ // residues share modal count
+ rc = new ResidueCount();
+ rc.add('G');
+ rc.add('G');
+ rc.add('c');
+ rc.add('C');
+ rc.add('U');
+ assertEquals(rc.getResiduesForCount(1), "U");
+ assertEquals(rc.getResiduesForCount(2), "CG");
+
+ // expected and unexpected symbols share modal count
+ rc = new ResidueCount();
+ rc.add('G');
+ rc.add('t');
+ rc.add('[');
+ rc.add('[');
+ rc.add('t');
+ rc.add('G');
+ rc.add('c');
+ rc.add('C');
+ rc.add('U');
+ assertEquals(rc.getResiduesForCount(1), "U");
+ assertEquals(rc.getResiduesForCount(2), "CGT[");
+ }
+
+ @Test(groups = "Functional")
+ public void testGetSymbolCounts_nucleotide()
+ {
+ ResidueCount rc = new ResidueCount(true);
+ rc.add('g');
+ rc.add('c');
+ rc.add('G');
+ rc.add('J'); // 'otherData'
+ rc.add('g');
+ rc.add('N');
+ rc.put('[', 0); // 'otherdata'
+
+ SymbolCounts sc = rc.getSymbolCounts();
+ Assert.assertArrayEquals(new char[] { 'C', 'G', 'N', 'J', '[' },
+ sc.symbols);
+ Assert.assertArrayEquals(new int[] { 1, 3, 1, 1, 0 }, sc.values);
+
+ // now with overflow to int counts
+ rc.put('U', Short.MAX_VALUE);
+ rc.add('u');
+ sc = rc.getSymbolCounts();
+ Assert.assertArrayEquals(new char[] { 'C', 'G', 'N', 'U', 'J', '[' },
+ sc.symbols);
+ Assert.assertArrayEquals(new int[] { 1, 3, 1, 32768, 1, 0 }, sc.values);
+ }
+
+ @Test(groups = "Functional")
+ public void testGetSymbolCounts_peptide()
+ {
+ ResidueCount rc = new ResidueCount(false);
+ rc.add('W');
+ rc.add('q');
+ rc.add('W');
+ rc.add('Z'); // 'otherData'
+ rc.add('w');
+ rc.add('L');
+
+ SymbolCounts sc = rc.getSymbolCounts();
+ Assert.assertArrayEquals(new char[] { 'L', 'Q', 'W', 'Z' }, sc.symbols);
+ Assert.assertArrayEquals(new int[] { 1, 1, 3, 1 }, sc.values);
+
+ // now with overflow to int counts
+ rc.put('W', Short.MAX_VALUE);
+ rc.add('W');
+ sc = rc.getSymbolCounts();
+ Assert.assertArrayEquals(new char[] { 'L', 'Q', 'W', 'Z' }, sc.symbols);
+ Assert.assertArrayEquals(new int[] { 1, 1, 32768, 1 }, sc.values);
+ }
+
+ @Test(groups = "Functional")
+ public void testToString()
+ {
+ ResidueCount rc = new ResidueCount();
+ rc.add('q');
+ rc.add('c');
+ rc.add('Q');
+ assertEquals(rc.toString(), "[ C:1 Q:2 ]");
+
+ // add 'other data'
+ rc.add('{');
+ assertEquals(rc.toString(), "[ C:1 Q:2 {:1 ]");
+
+ // switch from short to int counting:
+ rc.put('G', Short.MAX_VALUE);
+ rc.add('g');
+ assertEquals(rc.toString(), "[ C:1 G:32768 Q:2 {:1 ]");
+ }
+
+ @Test(groups = "Functional")
+ public void testGetTooltip()
+ {
+ ResidueCount rc = new ResidueCount();
+
+ // no counts!
+ assertEquals(rc.getTooltip(20, 1), "");
+
+ /*
+ * count 7 C, 6 K, 7 Q, 10 P, 9 W, 1 F (total 40)
+ */
+ for (int i = 0; i < 7; i++)
+ {
+ rc.add('c');
+ rc.add('q');
+ }
+ for (int i = 0; i < 10; i++)
+ {
+ rc.add('p');
+ }
+ for (int i = 0; i < 9; i++)
+ {
+ rc.add('W');
+ }
+ for (int i = 0; i < 6; i++)
+ {
+ rc.add('K');
+ }
+ rc.add('F');
+
+ assertEquals(rc.getTooltip(40, 0),
+ "P 25%; W 22%; C 17%; Q 17%; K 15%; F 2%");
+
+ assertEquals(rc.getTooltip(30, 1),
+ "P 33.3%; W 30.0%; C 23.3%; Q 23.3%; K 20.0%; F 3.3%");
+ }
+
+ @Test(groups = "Functional")
+ public void testPut()
+ {
+ ResidueCount rc = new ResidueCount();
+ rc.put('q', 3);
+ assertEquals(rc.getCount('Q'), 3);
+ rc.put(' ', 4);
+ assertEquals(rc.getGapCount(), 4);
+ rc.put('.', 5);
+ assertEquals(rc.getGapCount(), 5);
+ rc.put('-', 6);
+ assertEquals(rc.getGapCount(), 6);
+
+ rc.put('?', 5);
+ assertEquals(rc.getCount('?'), 5);
+ rc.put('?', 6);
+ rc.put('!', 7);
+ assertEquals(rc.getCount('?'), 6);
+ assertEquals(rc.getCount('!'), 7);
+ }
+}
package jalview.analysis;
import static org.testng.AssertJUnit.assertEquals;
+import static org.testng.AssertJUnit.assertFalse;
+import static org.testng.AssertJUnit.assertNull;
+import static org.testng.AssertJUnit.assertTrue;
import static org.testng.AssertJUnit.fail;
import jalview.analysis.SecStrConsensus.SimpleBP;
public void testGetSimpleBPs() throws WUSSParseException
{
String rna = "([{})]"; // JAL-1081 example
- Vector<SimpleBP> bps = Rna.GetSimpleBPs(rna);
+ Vector<SimpleBP> bps = Rna.getSimpleBPs(rna);
assertEquals(3, bps.size());
/*
* the base pairs are added in the order in which the matching base is found
+ * (popping the stack of unmatched opening brackets)
*/
assertEquals(2, bps.get(0).bp5); // {
assertEquals(3, bps.get(0).bp3); // }
String rna = "(([{})]";
try
{
- Rna.GetSimpleBPs(rna);
+ Rna.getSimpleBPs(rna);
fail("expected exception");
} catch (WUSSParseException e)
{
- // expected
+ // error reported as after end of input string
+ assertEquals(rna.length(), e.getProblemPos());
}
}
@Test(groups = { "Functional" })
public void testGetSimpleBPs_unmatchedCloser()
{
- String rna = "([{})]]";
+ String rna = "([{})]]]";
try
{
- Rna.GetSimpleBPs(rna);
+ Rna.getSimpleBPs(rna);
fail("expected exception");
} catch (WUSSParseException e)
{
- // expected
+ // error reported as at first unmatched close
+ assertEquals(6, e.getProblemPos());
+ }
+
+ /*
+ * a variant where we have no opening bracket of the same type
+ * as the unmatched closing bracket (no stack rather than empty stack)
+ */
+ rna = "((()])";
+ try
+ {
+ Rna.getSimpleBPs(rna);
+ fail("expected exception");
+ } catch (WUSSParseException e)
+ {
+ assertEquals(4, e.getProblemPos());
+ }
+ }
+
+ @Test(groups = { "Functional" })
+ public void testGetRNASecStrucState()
+ {
+ assertNull(Rna.getRNASecStrucState(null));
+ for (int i = 0; i <= 255; i++)
+ {
+ String s = String.valueOf((char) i);
+ String ss = Rna.getRNASecStrucState(s);
+
+ /*
+ * valid SS chars are a-z, A-Z, and various brackets;
+ * anything else is returned as a space
+ */
+ if ((i >= 'a' && i <= 'z') || (i >= 'A' && i <= 'Z')
+ || "()[]{}<>".indexOf(s) > -1)
+ {
+ assertEquals("" + i, s, ss);
+ }
+ else
+ {
+ assertEquals(" ", ss);
+ }
+ }
+
+ /*
+ * a string is processed character by character
+ */
+ assertEquals("a [K ]z} {Q b(w)p><i",
+ Rna.getRNASecStrucState("a.[K-]z}?{Q b(w)p><i"));
+ }
+
+ /**
+ * Tests for isClosingParenthesis with char or String argument
+ */
+ @Test(groups = { "Functional" })
+ public void testIsClosingParenthesis()
+ {
+ assertFalse(Rna.isClosingParenthesis(null));
+
+ /*
+ * only a-z, )]}> are closing bracket symbols
+ */
+ for (int i = 0; i <= 255; i++)
+ {
+ boolean isClosingChar = Rna.isClosingParenthesis((char) i);
+ boolean isClosingString = Rna.isClosingParenthesis(String
+ .valueOf((char) i));
+ if ((i >= 'a' && i <= 'z') || i == ')' || i == '}' || i == ']'
+ || i == '>')
+ {
+ assertTrue(String.format("close base pair %c", i), isClosingChar);
+ assertTrue(String.format("close base pair %c", i), isClosingString);
+ }
+ else
+ {
+ assertFalse(String.format("close base pair %c", i), isClosingChar);
+ assertFalse(String.format("close base pair %c", i), isClosingString);
+ }
+ assertFalse(Rna.isClosingParenthesis(String.valueOf((char) i) + " "));
+ }
+ }
+
+ @Test(groups = { "Functional" })
+ public void testIsCanonicalOrWobblePair()
+ {
+ String bases = "acgtuACGTU";
+ for (int i = 0; i < bases.length(); i++)
+ {
+ for (int j = 0; j < bases.length(); j++)
+ {
+ char first = bases.charAt(i);
+ char second = bases.charAt(j);
+ boolean result = Rna.isCanonicalOrWobblePair(first, second);
+ String pair = new String(new char[] { first, second })
+ .toUpperCase();
+ if (pair.equals("AT") || pair.equals("TA") || pair.equals("AU")
+ || pair.equals("UA") || pair.equals("GC")
+ || pair.equals("CG") || pair.equals("GT")
+ || pair.equals("TG") || pair.equals("GU")
+ || pair.equals("UG"))
+ {
+ assertTrue(pair + " should be valid", result);
+ }
+ else
+ {
+ assertFalse(pair + " should be invalid", result);
+ }
+ }
+ }
+ }
+
+ @Test(groups = { "Functional" })
+ public void testIsCanonicalPair()
+ {
+ String bases = "acgtuACGTU";
+ for (int i = 0; i < bases.length(); i++)
+ {
+ for (int j = 0; j < bases.length(); j++)
+ {
+ char first = bases.charAt(i);
+ char second = bases.charAt(j);
+ boolean result = Rna.isCanonicalPair(first, second);
+ String pair = new String(new char[] { first, second })
+ .toUpperCase();
+ if (pair.equals("AT") || pair.equals("TA") || pair.equals("AU")
+ || pair.equals("UA") || pair.equals("GC")
+ || pair.equals("CG"))
+ {
+ assertTrue(pair + " should be valid", result);
+ }
+ else
+ {
+ assertFalse(pair + " should be invalid", result);
+ }
+ }
+ }
+ }
+
+ /**
+ * Tests for isOpeningParenthesis with char or String argument
+ */
+ @Test(groups = { "Functional" })
+ public void testIsOpeningParenthesis()
+ {
+ /*
+ * only A-Z, ([{< are opening bracket symbols
+ */
+ for (int i = 0; i <= 255; i++)
+ {
+ boolean isOpeningChar = Rna.isOpeningParenthesis((char) i);
+ boolean isOpeningString = Rna.isOpeningParenthesis(String
+ .valueOf((char) i));
+ if ((i >= 'A' && i <= 'Z') || i == '(' || i == '{' || i == '['
+ || i == '<')
+ {
+ assertTrue(String.format("Open base pair %c", i), isOpeningChar);
+ assertTrue(String.format("Open base pair %c", i), isOpeningString);
+ }
+ else
+ {
+ assertFalse(String.format("Open base pair %c", i), isOpeningChar);
+ assertFalse(String.format("Open base pair %c", i), isOpeningString);
+ }
+ assertFalse(Rna.isOpeningParenthesis(String.valueOf((char) i) + " "));
+ }
+ }
+
+ @Test(groups = { "Functional" })
+ public void testGetMatchingOpeningParenthesis() throws WUSSParseException
+ {
+ for (int i = 0; i <= 255; i++)
+ {
+ boolean isClosing = Rna.isClosingParenthesis((char) i);
+ if (isClosing)
+ {
+ char opening = Rna.getMatchingOpeningParenthesis((char) i);
+ if (i >= 'a' && i <= 'z')
+ {
+ assertEquals(i + 'A' - 'a', opening);
+ }
+ else if (i == ')' && opening == '(' || i == ']' && opening == '['
+ || i == '}' && opening == '{' || i == '>' && opening == '<')
+ {
+ // ok
+ }
+ else
+ {
+ fail("Got " + opening + " as opening bracket pair for "
+ + ((char) i));
+ }
+ }
+ }
+ }
+
+ /**
+ * Tests for isRnaSecondaryStructureSymbol with char or String argument
+ */
+ @Test(groups = { "Functional" })
+ public void testIsRnaSecondaryStructureSymbol()
+ {
+ assertFalse(Rna.isRnaSecondaryStructureSymbol(null));
+
+ /*
+ * only A-Z, a-z, ()[]{}<> are valid symbols
+ */
+ for (int i = 0; i <= 255; i++)
+ {
+ boolean isValidChar = Rna.isRnaSecondaryStructureSymbol((char) i);
+ boolean isValidString = Rna.isRnaSecondaryStructureSymbol(String
+ .valueOf((char) i));
+ if ((i >= 'A' && i <= 'Z') || (i >= 'a' && i <= 'z') || i == '('
+ || i == ')' || i == '{' || i == '}' || i == '[' || i == ']'
+ || i == '<' || i == '>')
+ {
+ assertTrue(String.format("close base pair %c", i), isValidChar);
+ assertTrue(String.format("close base pair %c", i), isValidString);
+ }
+ else
+ {
+ assertFalse(String.format("close base pair %c", i), isValidChar);
+ assertFalse(String.format("close base pair %c", i), isValidString);
+ }
+ assertFalse(Rna.isRnaSecondaryStructureSymbol(String
+ .valueOf((char) i) + " "));
}
}
}
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
package jalview.analysis;
import static org.testng.AssertJUnit.assertFalse;
* case insensitive matching
*/
assertTrue(testee.equals("a12345"));
+
+ testee = sequenceIdMatcher.new SeqIdName("UNIPROT|A12345");
+ assertFalse(testee.equals("A12345"));
+ assertFalse(testee.equals("UNIPROT|B98765"));
+ assertFalse(testee.equals("UNIPROT|"));
+ assertTrue(testee.equals("UNIPROT"));
}
}
{
AlignFrame alf = getTestAlignmentFrame();
FeatureScoreModel fsm = new FeatureScoreModel();
- Assert.assertTrue(fsm.configureFromAlignmentView(alf
- .getCurrentView().getAlignPanel()));
+ Assert.assertTrue(fsm.configureFromAlignmentView(alf.getCurrentView()
+ .getAlignPanel()));
alf.selectAllSequenceMenuItem_actionPerformed(null);
float[][] dm = fsm.findDistances(alf.getViewport().getAlignmentView(
true));
alf.selectAllSequenceMenuItem_actionPerformed(null);
float[][] dm = fsm.findDistances(alf.getViewport().getAlignmentView(
true));
- Assert.assertTrue(dm[0][2] == 0f,
+ Assert.assertTrue(
+ dm[0][2] == 0f,
"After hiding last two columns FER1_MESCR (0) should still be identical with RAPSA (2)");
- Assert.assertTrue(dm[0][1] == 0f,
+ Assert.assertTrue(
+ dm[0][1] == 0f,
"After hiding last two columns FER1_MESCR (0) should now also be identical with SPIOL (1)");
- for (int s=0;s<3;s++)
+ for (int s = 0; s < 3; s++)
{
Assert.assertTrue(dm[s][3] > 0f, "After hiding last two columns "
+ alf.getViewport().getAlignment().getSequenceAt(s).getName()
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
package jalview.bin;
import static org.testng.AssertJUnit.assertEquals;
--- /dev/null
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
+package jalview.bin;
+
+import static org.testng.AssertJUnit.assertEquals;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Locale;
+
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+public class CacheTest
+{
+ private Locale locale;
+
+ @BeforeClass(alwaysRun = true)
+ public void setUpBeforeClass()
+ {
+ locale = Locale.getDefault();
+ }
+
+ @AfterClass(alwaysRun = true)
+ public void tearDownAfterClass()
+ {
+ Locale.setDefault(locale);
+ }
+
+ /**
+ * Test that saved date format does not vary with current locale
+ */
+ @Test(groups = "Functional")
+ public void testSetDateProperty()
+ {
+ Date now = new Date();
+ Locale.setDefault(Locale.FRENCH);
+ String formattedDate = Cache.setDateProperty("test", now);
+ Locale.setDefault(Locale.UK);
+ String formattedDate2 = Cache.setDateProperty("test", now);
+ assertEquals(formattedDate, formattedDate2);
+
+ // currently using Locale.UK to format dates:
+ assertEquals(
+ formattedDate2,
+ SimpleDateFormat.getDateTimeInstance(SimpleDateFormat.MEDIUM,
+ SimpleDateFormat.MEDIUM, Locale.UK).format(now));
+ }
+}
public void testReplace()
{
// seem to need a dataset sequence on the edited sequence here
- seqs[1].setDatasetSequence(seqs[1]);
+ seqs[1].createDatasetSequence();
new EditCommand("", Action.REPLACE, "ZXY", new SequenceI[] { seqs[1] },
4, 8, al);
assertEquals("abcdefghjk", seqs[0].getSequenceAsString());
--- /dev/null
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
+package jalview.controller;
+
+import static org.testng.AssertJUnit.assertEquals;
+import static org.testng.AssertJUnit.assertTrue;
+
+import jalview.datamodel.Sequence;
+import jalview.datamodel.SequenceFeature;
+import jalview.datamodel.SequenceGroup;
+import jalview.datamodel.SequenceI;
+
+import java.util.BitSet;
+
+import org.testng.annotations.Test;
+
+public class AlignViewControllerTest
+{
+ @Test(groups = "Functional")
+ public void testFindColumnsWithFeature()
+ {
+ SequenceI seq1 = new Sequence("seq1", "aMMMaaaaaaaaaaaaaaaa");
+ SequenceI seq2 = new Sequence("seq2", "aaaMMMMMMMaaaaaaaaaa");
+ SequenceI seq3 = new Sequence("seq3", "aaaaaaaaaaMMMMMaaaaa");
+ SequenceI seq4 = new Sequence("seq3", "aaaaaaaaaaaaaaaaaaaa");
+
+ /*
+ * features start/end are base 1
+ */
+ seq1.addSequenceFeature(new SequenceFeature("Metal", "desc", 2, 4, 0f,
+ null));
+ seq1.addSequenceFeature(new SequenceFeature("Helix", "desc", 1, 15, 0f,
+ null));
+ seq2.addSequenceFeature(new SequenceFeature("Metal", "desc", 4, 10, 0f,
+ null));
+ seq3.addSequenceFeature(new SequenceFeature("Metal", "desc", 11, 15,
+ 0f, null));
+
+ /*
+ * select the first three columns --> Metal in seq1 2-3
+ */
+ SequenceGroup sg = new SequenceGroup();
+ sg.setStartRes(0); // base 0
+ sg.setEndRes(2);
+ sg.addSequence(seq1, false);
+ sg.addSequence(seq2, false);
+ sg.addSequence(seq3, false);
+ sg.addSequence(seq4, false);
+
+ BitSet bs = new BitSet();
+ int seqCount = AlignViewController.findColumnsWithFeature("Metal", sg,
+ bs);
+ assertEquals(1, seqCount);
+ assertEquals(2, bs.cardinality());
+ assertTrue(bs.get(1));
+ assertTrue(bs.get(2));
+
+ /*
+ * select the first four columns: Metal in seq1 2:4, seq2 4:4
+ */
+ sg.setEndRes(3);
+ bs.clear();
+ seqCount = AlignViewController.findColumnsWithFeature("Metal", sg, bs);
+ assertEquals(2, seqCount);
+ assertEquals(3, bs.cardinality());
+ assertTrue(bs.get(1));
+ assertTrue(bs.get(2));
+ assertTrue(bs.get(3));
+
+ /*
+ * select column 11: Metal in seq3 only
+ */
+ sg.setStartRes(10);
+ sg.setEndRes(10);
+ bs.clear();
+ seqCount = AlignViewController.findColumnsWithFeature("Metal", sg, bs);
+ assertEquals(1, seqCount);
+ assertEquals(1, bs.cardinality());
+ assertTrue(bs.get(10));
+
+ /*
+ * select columns 16-20: no Metal feature
+ */
+ sg.setStartRes(15);
+ sg.setEndRes(19);
+ bs.clear();
+ seqCount = AlignViewController.findColumnsWithFeature("Metal", sg, bs);
+ assertEquals(0, seqCount);
+ assertEquals(0, bs.cardinality());
+
+ /*
+ * look for a feature that isn't there
+ */
+ sg.setStartRes(0);
+ sg.setEndRes(19);
+ bs.clear();
+ seqCount = AlignViewController.findColumnsWithFeature("Pfam", sg, bs);
+ assertEquals(0, seqCount);
+ assertEquals(0, bs.cardinality());
+ }
+}
assertArrayEquals(new int[] { 2, 2 },
acf.getMappedRegion(seq2, seq1, 6));
}
+
+ /**
+ * Tests for addMap. See also tests for MapList.addMapList
+ */
+ @Test(groups = { "Functional" })
+ public void testAddMap()
+ {
+ final Sequence seq1 = new Sequence("Seq1", "c-G-TA-gC-gT-T");
+ seq1.createDatasetSequence();
+ final Sequence aseq1 = new Sequence("Seq1", "-V-L");
+ aseq1.createDatasetSequence();
+
+ AlignedCodonFrame acf = new AlignedCodonFrame();
+ MapList map = new MapList(new int[] { 2, 4, 6, 6, 8, 9 }, new int[] {
+ 1, 2 }, 3, 1);
+ acf.addMap(seq1.getDatasetSequence(), aseq1.getDatasetSequence(), map);
+ assertEquals(1, acf.getMappingsFromSequence(seq1).size());
+ Mapping before = acf.getMappingsFromSequence(seq1).get(0);
+
+ /*
+ * add the same map again, verify it doesn't get duplicated
+ */
+ acf.addMap(seq1.getDatasetSequence(), aseq1.getDatasetSequence(), map);
+ assertEquals(1, acf.getMappingsFromSequence(seq1).size());
+ assertSame(before, acf.getMappingsFromSequence(seq1).get(0));
+ }
}
assertEquals(1, ann.annotations[1].value, 0.001);
assertEquals(2, ann.annotations[2].value, 0.001);
}
-}
+
+ /**
+ * Test the method that defaults rna symbol to the one matching the preceding
+ * unmatched opening bracket (if any)
+ */
+ @Test(groups = { "Functional" })
+ public void testGetDefaultRnaHelixSymbol()
+ {
+ AlignmentAnnotation ann = new AlignmentAnnotation("SS",
+ "secondary structure", null);
+ assertEquals("(", ann.getDefaultRnaHelixSymbol(4));
+
+ Annotation[] anns = new Annotation[20];
+ ann.annotations = anns;
+ assertEquals("(", ann.getDefaultRnaHelixSymbol(4));
+
+ anns[1] = new Annotation("(", "S", '(', 0f);
+ assertEquals("(", ann.getDefaultRnaHelixSymbol(0));
+ assertEquals("(", ann.getDefaultRnaHelixSymbol(1));
+ assertEquals(")", ann.getDefaultRnaHelixSymbol(2));
+ assertEquals(")", ann.getDefaultRnaHelixSymbol(3));
+
+ /*
+ * .(.[.{.<.}.>.).].
+ */
+ anns[1] = new Annotation("(", "S", '(', 0f);
+ anns[3] = new Annotation("[", "S", '[', 0f);
+ anns[5] = new Annotation("{", "S", '{', 0f);
+ anns[7] = new Annotation("<", "S", '<', 0f);
+ anns[9] = new Annotation("}", "S", '}', 0f);
+ anns[11] = new Annotation(">", "S", '>', 0f);
+ anns[13] = new Annotation(")", "S", ')', 0f);
+ anns[15] = new Annotation("]", "S", ']', 0f);
+
+ String expected = "(())]]}}>>>>]]]](";
+ for (int i = 0; i < expected.length(); i++)
+ {
+ assertEquals("column " + i, String.valueOf(expected.charAt(i)),
+ ann.getDefaultRnaHelixSymbol(i));
+ }
+
+ /*
+ * .(.[.(.).{.}.<.].D.
+ */
+ anns[1] = new Annotation("(", "S", '(', 0f);
+ anns[3] = new Annotation("[", "S", '[', 0f);
+ anns[5] = new Annotation("(", "S", '(', 0f);
+ anns[7] = new Annotation(")", "S", ')', 0f);
+ anns[9] = new Annotation("{", "S", '{', 0f);
+ anns[11] = new Annotation("}", "S", '}', 0f);
+ anns[13] = new Annotation("<", "S", '>', 0f);
+ anns[15] = new Annotation("]", "S", ']', 0f);
+ anns[17] = new Annotation("D", "S", 'D', 0f);
+
+ expected = "(())]]))]]}}]]>>>>dd";
+ for (int i = 0; i < expected.length(); i++)
+ {
+ assertEquals("column " + i, String.valueOf(expected.charAt(i)),
+ ann.getDefaultRnaHelixSymbol(i));
+ }
+ }
+}
\ No newline at end of file
import static org.testng.AssertJUnit.assertSame;
import static org.testng.AssertJUnit.assertTrue;
+import jalview.datamodel.AlignedCodonFrame.SequenceToSequenceMapping;
import jalview.io.AppletFormatAdapter;
import jalview.io.FormatAdapter;
import jalview.util.MapList;
import java.util.Iterator;
import java.util.List;
+import org.testng.Assert;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
return a;
}
+ /**
+ * assert wrapper: tests all references in the given alignment are consistent
+ *
+ * @param alignment
+ */
+ public static void assertAlignmentDatasetRefs(AlignmentI alignment)
+ {
+ verifyAlignmentDatasetRefs(alignment, true, null);
+ }
+
+ /**
+ * assert wrapper: tests all references in the given alignment are consistent
+ *
+ * @param alignment
+ * @param message
+ * - prefixed to any assert failed messages
+ */
+ public static void assertAlignmentDatasetRefs(AlignmentI alignment,
+ String message)
+ {
+ verifyAlignmentDatasetRefs(alignment, true, message);
+ }
+
+ /**
+ * verify sequence and dataset references are properly contained within
+ * dataset
+ *
+ * @param alignment
+ * - the alignmentI object to verify (either alignment or dataset)
+ * @param raiseAssert
+ * - when set, testng assertions are raised.
+ * @param message
+ * - null or a string message to prepend to the assert failed
+ * messages.
+ * @return true if alignment references were in order, otherwise false.
+ */
+ public static boolean verifyAlignmentDatasetRefs(AlignmentI alignment,
+ boolean raiseAssert, String message)
+ {
+ if (message == null)
+ {
+ message = "";
+ }
+ if (alignment == null)
+ {
+ if (raiseAssert)
+ {
+ Assert.fail(message + "Alignment for verification was null.");
+ }
+ return false;
+ }
+ if (alignment.getDataset() != null)
+ {
+ AlignmentI dataset = alignment.getDataset();
+ // check all alignment sequences have their dataset within the dataset
+ for (SequenceI seq : alignment.getSequences())
+ {
+ SequenceI seqds = seq.getDatasetSequence();
+ if (seqds.getDatasetSequence() != null)
+ {
+ if (raiseAssert)
+ {
+ Assert.fail(message
+ + " Alignment contained a sequence who's dataset sequence has a second dataset reference.");
+ }
+ return false;
+ }
+ if (dataset.findIndex(seqds) == -1)
+ {
+ if (raiseAssert)
+ {
+ Assert.fail(message
+ + " Alignment contained a sequence who's dataset sequence was not in the dataset.");
+ }
+ return false;
+ }
+ }
+ return verifyAlignmentDatasetRefs(alignment.getDataset(),
+ raiseAssert, message);
+ }
+ else
+ {
+ int dsp = -1;
+ // verify all dataset sequences
+ for (SequenceI seqds : alignment.getSequences())
+ {
+ dsp++;
+ if (seqds.getDatasetSequence() != null)
+ {
+ if (raiseAssert)
+ {
+ Assert.fail(message
+ + " Dataset contained a sequence with non-null dataset reference (ie not a dataset sequence!)");
+ }
+ return false;
+ }
+ int foundp = alignment.findIndex(seqds);
+ if (foundp != dsp)
+ {
+ if (raiseAssert)
+ {
+ Assert.fail(message
+ + " Dataset sequence array contains a reference at "
+ + dsp + " to a sequence first seen at " + foundp + " ("
+ + seqds.toString() + ")");
+ }
+ return false;
+ }
+ if (seqds.getDBRefs() != null)
+ {
+ for (DBRefEntry dbr : seqds.getDBRefs())
+ {
+ if (dbr.getMap() != null)
+ {
+ SequenceI seqdbrmapto = dbr.getMap().getTo();
+ if (seqdbrmapto != null)
+ {
+ if (seqdbrmapto.getDatasetSequence() != null)
+ {
+ if (raiseAssert)
+ {
+ Assert.fail(message
+ + " DBRefEntry for sequence in alignment had map to sequence which was not a dataset sequence");
+ }
+ return false;
+
+ }
+ if (alignment.findIndex(dbr.getMap().getTo()) == -1)
+ {
+ if (raiseAssert)
+ {
+ Assert.fail(message
+ + " DBRefEntry for sequence in alignment had map to sequence not in dataset");
+ }
+ return false;
+ }
+ }
+ }
+ }
+ }
+ }
+ // finally, verify codonmappings involve only dataset sequences.
+ if (alignment.getCodonFrames() != null)
+ {
+ for (AlignedCodonFrame alc : alignment.getCodonFrames())
+ {
+ for (SequenceToSequenceMapping ssm : alc.getMappings())
+ {
+ if (ssm.getFromSeq().getDatasetSequence() != null)
+ {
+ if (raiseAssert)
+ {
+ Assert.fail(message
+ + " CodonFrame-SSM-FromSeq is not a dataset sequence");
+ }
+ return false;
+ }
+ if (alignment.findIndex(ssm.getFromSeq()) == -1)
+ {
+
+ if (raiseAssert)
+ {
+ Assert.fail(message
+ + " CodonFrame-SSM-FromSeq is not contained in dataset");
+ }
+ return false;
+ }
+ if (ssm.getMapping().getTo().getDatasetSequence() != null)
+ {
+ if (raiseAssert)
+ {
+ Assert.fail(message
+ + " CodonFrame-SSM-Mapping-ToSeq is not a dataset sequence");
+ }
+ return false;
+ }
+ if (alignment.findIndex(ssm.getMapping().getTo()) == -1)
+ {
+
+ if (raiseAssert)
+ {
+ Assert.fail(message
+ + " CodonFrame-SSM-Mapping-ToSeq is not contained in dataset");
+ }
+ return false;
+ }
+ }
+ }
+ }
+ }
+ return true; // all relationships verified!
+ }
+
+ /**
+ * call verifyAlignmentDatasetRefs with and without assertion raising enabled,
+ * to check expected pass/fail actually occurs in both conditions
+ *
+ * @param al
+ * @param expected
+ * @param msg
+ */
+ private void assertVerifyAlignment(AlignmentI al, boolean expected,
+ String msg)
+ {
+ if (expected)
+ {
+ try
+ {
+
+ Assert.assertTrue(verifyAlignmentDatasetRefs(al, true, null),
+ "Valid test alignment failed when raiseAsserts enabled:"
+ + msg);
+ } catch (AssertionError ae)
+ {
+ ae.printStackTrace();
+ Assert.fail(
+ "Valid test alignment raised assertion errors when raiseAsserts enabled: "
+ + msg, ae);
+ }
+ // also check validation passes with asserts disabled
+ Assert.assertTrue(verifyAlignmentDatasetRefs(al, false, null),
+ "Valid test alignment tested false when raiseAsserts disabled:"
+ + msg);
+ }
+ else
+ {
+ boolean assertRaised = false;
+ try
+ {
+ verifyAlignmentDatasetRefs(al, true, null);
+ } catch (AssertionError ae)
+ {
+ // expected behaviour
+ assertRaised = true;
+ }
+ if (!assertRaised)
+ {
+ Assert.fail("Invalid test alignment passed when raiseAsserts enabled:"
+ + msg);
+ }
+ // also check validation passes with asserts disabled
+ Assert.assertFalse(verifyAlignmentDatasetRefs(al, false, null),
+ "Invalid test alignment tested true when raiseAsserts disabled:"
+ + msg);
+ }
+ }
+
+ @Test(groups = { "Functional" })
+ public void testVerifyAlignmentDatasetRefs()
+ {
+ SequenceI sq1 = new Sequence("sq1", "ASFDD"), sq2 = new Sequence("sq2",
+ "TTTTTT");
+
+ // construct simple valid alignment dataset
+ Alignment al = new Alignment(new SequenceI[] { sq1, sq2 });
+ // expect this to pass
+ assertVerifyAlignment(al, true, "Simple valid alignment didn't verify");
+
+ // check test for sequence->datasetSequence validity
+ sq1.setDatasetSequence(sq2);
+ assertVerifyAlignment(al, false,
+ "didn't detect dataset sequence with a dataset sequence reference.");
+
+ sq1.setDatasetSequence(null);
+ assertVerifyAlignment(
+ al,
+ true,
+ "didn't reinstate validity after nulling dataset sequence dataset reference");
+
+ // now create dataset and check again
+ al.createDatasetAlignment();
+ assertNotNull(al.getDataset());
+
+ assertVerifyAlignment(al, true,
+ "verify failed after createDatasetAlignment");
+
+ // create a dbref on sq1 with a sequence ref to sq2
+ DBRefEntry dbrs1tos2 = new DBRefEntry("UNIPROT", "1", "Q111111");
+ dbrs1tos2.setMap(new Mapping(sq2.getDatasetSequence(),
+ new int[] { 1, 5 }, new int[] { 2, 6 }, 1, 1));
+ sq1.getDatasetSequence().addDBRef(dbrs1tos2);
+ assertVerifyAlignment(al, true,
+ "verify failed after addition of valid DBRefEntry/map");
+ // now create a dbref on a new sequence which maps to another sequence
+ // outside of the dataset
+ SequenceI sqout = new Sequence("sqout", "ututututucagcagcag"), sqnew = new Sequence(
+ "sqnew", "EEERRR");
+ DBRefEntry sqnewsqout = new DBRefEntry("ENAFOO", "1", "R000001");
+ sqnewsqout.setMap(new Mapping(sqout, new int[] { 1, 6 }, new int[] { 1,
+ 18 }, 1, 3));
+ al.getDataset().addSequence(sqnew);
+
+ assertVerifyAlignment(al, true,
+ "verify failed after addition of new sequence to dataset");
+ // now start checking exception conditions
+ sqnew.addDBRef(sqnewsqout);
+ assertVerifyAlignment(
+ al,
+ false,
+ "verify passed when a dbref with map to sequence outside of dataset was added");
+ // make the verify pass by adding the outsider back in
+ al.getDataset().addSequence(sqout);
+ assertVerifyAlignment(al, true,
+ "verify should have passed after adding dbref->to sequence in to dataset");
+ // and now the same for a codon mapping...
+ SequenceI sqanotherout = new Sequence("sqanotherout",
+ "aggtutaggcagcagcag");
+
+ AlignedCodonFrame alc = new AlignedCodonFrame();
+ alc.addMap(sqanotherout, sqnew, new MapList(new int[] { 1, 6 },
+ new int[] { 1, 18 }, 3, 1));
+
+ al.addCodonFrame(alc);
+ Assert.assertEquals(al.getDataset().getCodonFrames().size(), 1);
+
+ assertVerifyAlignment(
+ al,
+ false,
+ "verify passed when alCodonFrame mapping to sequence outside of dataset was added");
+ // make the verify pass by adding the outsider back in
+ al.getDataset().addSequence(sqanotherout);
+ assertVerifyAlignment(
+ al,
+ true,
+ "verify should have passed once all sequences involved in alCodonFrame were added to dataset");
+ al.getDataset().addSequence(sqanotherout);
+ assertVerifyAlignment(al, false,
+ "verify should have failed when a sequence was added twice to the dataset");
+ al.getDataset().deleteSequence(sqanotherout);
+ assertVerifyAlignment(al, true,
+ "verify should have passed after duplicate entry for sequence was removed");
+ }
+
+ /**
+ * checks that the sequence data for an alignment's dataset is non-redundant.
+ * Fails if there are sequences with same id, sequence, start, and.
+ */
+
+ public static void assertDatasetIsNormalised(AlignmentI al)
+ {
+ assertDatasetIsNormalised(al, null);
+ }
+
+ /**
+ * checks that the sequence data for an alignment's dataset is non-redundant.
+ * Fails if there are sequences with same id, sequence, start, and.
+ *
+ * @param al
+ * - alignment to verify
+ * @param message
+ * - null or message prepended to exception message.
+ */
+ public static void assertDatasetIsNormalised(AlignmentI al, String message)
+ {
+ if (al.getDataset() != null)
+ {
+ assertDatasetIsNormalised(al.getDataset(), message);
+ return;
+ }
+ /*
+ * look for pairs of sequences with same ID, start, end, and sequence
+ */
+ List<SequenceI> seqSet = al.getSequences();
+ for (int p = 0; p < seqSet.size(); p++)
+ {
+ SequenceI pSeq = seqSet.get(p);
+ for (int q = p + 1; q < seqSet.size(); q++)
+ {
+ SequenceI qSeq = seqSet.get(q);
+ if (pSeq.getStart() != qSeq.getStart())
+ {
+ continue;
+ }
+ if (pSeq.getEnd() != qSeq.getEnd())
+ {
+ continue;
+ }
+ if (!pSeq.getName().equals(qSeq.getName()))
+ {
+ continue;
+ }
+ if (!Arrays.equals(pSeq.getSequence(), qSeq.getSequence()))
+ {
+ continue;
+ }
+ Assert.fail((message == null ? "" : message + " :")
+ + "Found similar sequences at position " + p + " and " + q
+ + "\n" + pSeq.toString());
+ }
+ }
+ }
+
+ @Test(groups = { "Functional", "Asserts" })
+ public void testAssertDatasetIsNormalised()
+ {
+ Sequence sq1 = new Sequence("s1/1-4", "asdf");
+ Sequence sq1shift = new Sequence("s1/2-5", "asdf");
+ Sequence sq1seqd = new Sequence("s1/1-4", "asdt");
+ Sequence sq2 = new Sequence("s2/1-4", "asdf");
+ Sequence sq1dup = new Sequence("s1/1-4", "asdf");
+
+ Alignment al = new Alignment(new SequenceI[] { sq1 });
+ al.setDataset(null);
+
+ try
+ {
+ assertDatasetIsNormalised(al);
+ } catch (AssertionError ae)
+ {
+ Assert.fail("Single sequence should be valid normalised dataset.");
+ }
+ al.addSequence(sq2);
+ try
+ {
+ assertDatasetIsNormalised(al);
+ } catch (AssertionError ae)
+ {
+ Assert.fail("Two different sequences should be valid normalised dataset.");
+ }
+ /*
+ * now change sq2's name in the alignment. should still be valid
+ */
+ al.findName(sq2.getName()).setName("sq1");
+ try
+ {
+ assertDatasetIsNormalised(al);
+ } catch (AssertionError ae)
+ {
+ Assert.fail("Two different sequences in dataset, but same name in alignment, should be valid normalised dataset.");
+ }
+
+ al.addSequence(sq1seqd);
+ try
+ {
+ assertDatasetIsNormalised(al);
+ } catch (AssertionError ae)
+ {
+ Assert.fail("sq1 and sq1 with different sequence should be distinct.");
+ }
+
+ al.addSequence(sq1shift);
+ try
+ {
+ assertDatasetIsNormalised(al);
+ } catch (AssertionError ae)
+ {
+ Assert.fail("sq1 and sq1 with different start/end should be distinct.");
+ }
+ /*
+ * finally, the failure case
+ */
+ al.addSequence(sq1dup);
+ boolean ssertRaised = false;
+ try
+ {
+ assertDatasetIsNormalised(al);
+
+ } catch (AssertionError ae)
+ {
+ ssertRaised = true;
+ }
+ if (!ssertRaised)
+ {
+ Assert.fail("Expected identical sequence to raise exception.");
+ }
+ }
+
/*
* Read in Stockholm format test data including secondary structure
* annotations.
*
* @throws IOException
*/
- @Test(groups = { "Functional" }, enabled = false)
+ @Test(groups = { "Functional" }, enabled = true)
// TODO review / update this test after redesign of alignAs method
public void testAlignAs_cdnaAsProtein() throws IOException
{
* Realign DNA; currently keeping existing gaps in introns only
*/
((Alignment) al1).alignAs(al2, false, true);
- assertEquals("ACG---GCUCCA------ACT", al1.getSequenceAt(0)
+ assertEquals("ACG---GCUCCA------ACT---", al1.getSequenceAt(0)
.getSequenceAsString());
assertEquals("---CGT---TAACGA---AGT---", al1.getSequenceAt(1)
.getSequenceAsString());
*
* @throws IOException
*/
- @Test(groups = { "Functional" }, enabled = false)
+ @Test(groups = { "Functional" }, enabled = true)
// TODO review / update this test after redesign of alignAs method
public void testAlignAs_cdnaAsProtein_singleSequence() throws IOException
{
acf.addMap(seqFrom, seqTo, ml);
}
+ /*
+ * not sure whether mappings 'belong' or protein or nucleotide
+ * alignment, so adding to both ;~)
+ */
alFrom.addCodonFrame(acf);
+ alTo.addCodonFrame(acf);
}
/**
// TODO should the copy constructor copy the dataset?
// or make a new one referring to the same dataset sequences??
assertNull(copy.getDataset());
+ // TODO test metadata is copied when AlignmentI is a dataset
+
// assertArrayEquals(copy.getDataset().getSequencesArray(), protein
// .getDataset().getSequencesArray());
}
// TODO promote this method to AlignmentI
((Alignment) protein).createDatasetAlignment();
- // TODO this method should return AlignmentI not Alignment !!
- Alignment ds = protein.getDataset();
+ AlignmentI ds = protein.getDataset();
// side-effect: dataset created on second sequence
assertNotNull(protein.getSequenceAt(1).getDatasetSequence());
assertTrue(ds.getCodonFrames().contains(acf));
}
+ /**
+ * tests the addition of *all* sequences referred to by a sequence being added
+ * to the dataset
+ */
+ @Test(groups = "Functional")
+ public void testCreateDatasetAlignmentWithMappedToSeqs()
+ {
+ // Alignment with two sequences, gapped.
+ SequenceI sq1 = new Sequence("sq1", "A--SDF");
+ SequenceI sq2 = new Sequence("sq2", "G--TRQ");
+
+ // cross-references to two more sequences.
+ DBRefEntry dbr = new DBRefEntry("SQ1", "", "sq3");
+ SequenceI sq3 = new Sequence("sq3", "VWANG");
+ dbr.setMap(new Mapping(sq3, new MapList(new int[] { 1, 4 }, new int[] {
+ 2, 5 }, 1, 1)));
+ sq1.addDBRef(dbr);
+
+ SequenceI sq4 = new Sequence("sq4", "ERKWI");
+ DBRefEntry dbr2 = new DBRefEntry("SQ2", "", "sq4");
+ dbr2.setMap(new Mapping(sq4, new MapList(new int[] { 1, 4 }, new int[] {
+ 2, 5 }, 1, 1)));
+ sq2.addDBRef(dbr2);
+ // and a 1:1 codonframe mapping between them.
+ AlignedCodonFrame alc = new AlignedCodonFrame();
+ alc.addMap(sq1, sq2, new MapList(new int[] { 1, 4 },
+ new int[] { 1, 4 }, 1, 1));
+
+ AlignmentI protein = new Alignment(new SequenceI[] { sq1, sq2 });
+
+ /*
+ * create the alignment dataset
+ * note this creates sequence datasets where missing
+ * as a side-effect (in this case, on seq2
+ */
+
+ // TODO promote this method to AlignmentI
+ ((Alignment) protein).createDatasetAlignment();
+
+ AlignmentI ds = protein.getDataset();
+
+ // should be 4 sequences in dataset - two materialised, and two propagated
+ // from dbref
+ assertEquals(4, ds.getHeight());
+ assertTrue(ds.getSequences().contains(sq1.getDatasetSequence()));
+ assertTrue(ds.getSequences().contains(sq2.getDatasetSequence()));
+ assertTrue(ds.getSequences().contains(sq3));
+ assertTrue(ds.getSequences().contains(sq4));
+ // Should have one codon frame mapping between sq1 and sq2 via dataset
+ // sequences
+ assertEquals(ds.getCodonFrame(sq1.getDatasetSequence()),
+ ds.getCodonFrame(sq2.getDatasetSequence()));
+ }
+
@Test(groups = "Functional")
public void testAddCodonFrame()
{
}
@Test(groups = "Functional")
+ public void testAddSequencePreserveDatasetIntegrity()
+ {
+ Sequence seq = new Sequence("testSeq", "ABCDEFGHIJKLMNOPQRSTUVWXYZ");
+ Alignment align = new Alignment(new SequenceI[] { seq });
+ align.createDatasetAlignment();
+ AlignmentI ds = align.getDataset();
+ SequenceI copy = new Sequence(seq);
+ copy.insertCharAt(3, 5, '-');
+ align.addSequence(copy);
+ Assert.assertEquals(align.getDataset().getHeight(), 1,
+ "Dataset shouldn't have more than one sequence.");
+
+ Sequence seq2 = new Sequence("newtestSeq", "ABCDEFGHIJKLMNOPQRSTUVWXYZ");
+ align.addSequence(seq2);
+ Assert.assertEquals(align.getDataset().getHeight(), 2,
+ "Dataset should now have two sequences.");
+
+ assertAlignmentDatasetRefs(align,
+ "addSequence broke dataset reference integrity");
+ }
+
+ @Test(groups = "Functional")
public void getVisibleStartAndEndIndexTest()
{
Sequence seq = new Sequence("testSeq", "ABCDEFGHIJKLMNOPQRSTUVWXYZ");
assertEquals(1, startEnd[0]);
assertEquals(23, startEnd[1]);
}
+
+ /**
+ * Tests that dbrefs with mappings to sequence get updated if the sequence
+ * acquires a dataset sequence
+ */
+ @Test(groups = "Functional")
+ public void testCreateDataset_updateDbrefMappings()
+ {
+ SequenceI pep = new Sequence("pep", "ASD");
+ SequenceI dna = new Sequence("dna", "aaaGCCTCGGATggg");
+ SequenceI cds = new Sequence("cds", "GCCTCGGAT");
+
+ // add dbref from dna to peptide
+ DBRefEntry dbr = new DBRefEntry("UNIPROT", "", "pep");
+ dbr.setMap(new Mapping(pep, new MapList(new int[] { 4, 15 }, new int[] {
+ 1, 4 }, 3, 1)));
+ dna.addDBRef(dbr);
+
+ // add dbref from dna to peptide
+ DBRefEntry dbr2 = new DBRefEntry("UNIPROT", "", "pep");
+ dbr2.setMap(new Mapping(pep, new MapList(new int[] { 1, 12 }, new int[]
+ { 1, 4 }, 3, 1)));
+ cds.addDBRef(dbr2);
+
+ // add dbref from peptide to dna
+ DBRefEntry dbr3 = new DBRefEntry("EMBL", "", "dna");
+ dbr3.setMap(new Mapping(dna, new MapList(new int[] { 1, 4 }, new int[] {
+ 4, 15 }, 1, 3)));
+ pep.addDBRef(dbr3);
+
+ // add dbref from peptide to cds
+ DBRefEntry dbr4 = new DBRefEntry("EMBLCDS", "", "cds");
+ dbr4.setMap(new Mapping(cds, new MapList(new int[] { 1, 4 }, new int[] {
+ 1, 12 }, 1, 3)));
+ pep.addDBRef(dbr4);
+
+ AlignmentI protein = new Alignment(new SequenceI[] { pep });
+
+ /*
+ * create the alignment dataset
+ */
+ ((Alignment) protein).createDatasetAlignment();
+
+ AlignmentI ds = protein.getDataset();
+
+ // should be 3 sequences in dataset
+ assertEquals(3, ds.getHeight());
+ assertTrue(ds.getSequences().contains(pep.getDatasetSequence()));
+ assertTrue(ds.getSequences().contains(dna));
+ assertTrue(ds.getSequences().contains(cds));
+
+ /*
+ * verify peptide.cdsdbref.peptidedbref is now mapped to peptide dataset
+ */
+ DBRefEntry[] dbRefs = pep.getDBRefs();
+ assertEquals(2, dbRefs.length);
+ assertSame(dna, dbRefs[0].map.to);
+ assertSame(cds, dbRefs[1].map.to);
+ assertEquals(1, dna.getDBRefs().length);
+ assertSame(pep.getDatasetSequence(), dna.getDBRefs()[0].map.to);
+ assertEquals(1, cds.getDBRefs().length);
+ assertSame(pep.getDatasetSequence(), cds.getDBRefs()[0].map.to);
+ }
+
}
import static org.testng.AssertJUnit.assertFalse;
import static org.testng.AssertJUnit.assertSame;
import static org.testng.AssertJUnit.assertTrue;
+import static org.testng.AssertJUnit.fail;
import java.util.Arrays;
+import java.util.BitSet;
+import java.util.Collections;
+import java.util.ConcurrentModificationException;
import java.util.List;
import org.testng.annotations.Test;
// removing an element in the list removes it
cs.removeElement(2);
+ // ...and also from the read-only view
+ assertEquals(1, sel.size());
+ sel = cs.getSelected();
assertEquals(1, sel.size());
assertEquals(new Integer(5), sel.get(0));
}
}
- @Test(groups={"Functional"})
+ @Test(groups = { "Functional" })
public void testLocateVisibleBoundsPathologicals()
{
// test some pathological cases we missed
- AlignmentI al = new Alignment(new SequenceI[] { new Sequence("refseqGaptest","KTDVTI----------NFI-----G----L")});
+ AlignmentI al = new Alignment(new SequenceI[] { new Sequence(
+ "refseqGaptest", "KTDVTI----------NFI-----G----L") });
ColumnSelection cs = new ColumnSelection();
cs.hideInsertionsFor(al.getSequenceAt(0));
assertEquals(
+ al.getSequenceAt(0).getCharAt(
cs.adjustForHiddenColumns(9)));
-
}
+
@Test(groups = { "Functional" })
public void testHideColumns()
{
* this fails, HideSelectedColumns may also fail
*/
@Test(groups = { "Functional" })
- public void testgetSelectedRanges()
+ public void testGetSelectedRanges()
{
+ /*
+ * getSelectedRanges returns ordered columns regardless
+ * of the order in which they are added
+ */
ColumnSelection cs = new ColumnSelection();
- int[] sel = { 2, 3, 4, 7, 8, 9, 20, 21, 22 };
+ int[] sel = { 4, 3, 7, 21, 9, 20, 8, 22, 2 };
for (int col : sel)
{
cs.addElement(col);
cs.addElement(1);
cs.hideColumns(3);
cs.hideColumns(7);
- cs.hideColumns(5,9);
+ cs.hideColumns(5, 9);
// same selections added in a different order
ColumnSelection cs2 = new ColumnSelection();
cs2.hideColumns(6, 9);
cs2.hideColumns(5, 8);
cs2.hideColumns(3);
-
+
assertTrue(cs.equals(cs2));
assertTrue(cs.equals(cs));
assertTrue(cs2.equals(cs));
cs.addElement(88);
assertTrue(cs.equals(cs2));
}
+
+ /**
+ * Test the method that returns selected columns, in the order in which they
+ * were added
+ */
+ @Test(groups = { "Functional" })
+ public void testGetSelected()
+ {
+ ColumnSelection cs = new ColumnSelection();
+ int[] sel = { 4, 3, 7, 21 };
+ for (int col : sel)
+ {
+ cs.addElement(col);
+ }
+
+ List<Integer> selected = cs.getSelected();
+ assertEquals(4, selected.size());
+ assertEquals("[4, 3, 7, 21]", selected.toString());
+
+ /*
+ * getSelected returns a read-only view of the list
+ * verify the view follows any changes in it
+ */
+ cs.removeElement(7);
+ cs.addElement(1);
+ cs.removeElement(4);
+ assertEquals("[3, 21, 1]", selected.toString());
+ }
+
+ /**
+ * Test to verify that the list returned by getSelection cannot be modified
+ */
+ @Test(groups = { "Functional" })
+ public void testGetSelected_isReadOnly()
+ {
+ ColumnSelection cs = new ColumnSelection();
+ cs.addElement(3);
+
+ List<Integer> selected = cs.getSelected();
+ try
+ {
+ selected.clear();
+ fail("expected exception");
+ } catch (UnsupportedOperationException e)
+ {
+ // expected
+ }
+ try
+ {
+ selected.add(1);
+ fail("expected exception");
+ } catch (UnsupportedOperationException e)
+ {
+ // expected
+ }
+ try
+ {
+ selected.remove(3);
+ fail("expected exception");
+ } catch (UnsupportedOperationException e)
+ {
+ // expected
+ }
+ try
+ {
+ Collections.sort(selected);
+ fail("expected exception");
+ } catch (UnsupportedOperationException e)
+ {
+ // expected
+ }
+ }
+
+ /**
+ * Test that demonstrates a ConcurrentModificationException is thrown if you
+ * change the selection while iterating over it
+ */
+ @Test(
+ groups = "Functional",
+ expectedExceptions = { ConcurrentModificationException.class })
+ public void testGetSelected_concurrentModification()
+ {
+ ColumnSelection cs = new ColumnSelection();
+ cs.addElement(0);
+ cs.addElement(1);
+ cs.addElement(2);
+
+ /*
+ * simulate changing the list under us (e.g. in a separate
+ * thread) while iterating over it -> ConcurrentModificationException
+ */
+ List<Integer> selected = cs.getSelected();
+ for (Integer col : selected)
+ {
+ if (col.intValue() == 0)
+ {
+ cs.removeElement(1);
+ }
+ }
+ }
+
+ @Test(groups = "Functional")
+ public void testMarkColumns()
+ {
+ ColumnSelection cs = new ColumnSelection();
+ cs.addElement(5); // this will be cleared
+ BitSet toMark = new BitSet();
+ toMark.set(1);
+ toMark.set(3);
+ toMark.set(6);
+ toMark.set(9);
+
+ assertTrue(cs.markColumns(toMark, 3, 8, false, false, false));
+ List<Integer> selected = cs.getSelected();
+ assertEquals(2, selected.size());
+ assertTrue(selected.contains(3));
+ assertTrue(selected.contains(6));
+ }
+
+ @Test(groups = "Functional")
+ public void testMarkColumns_extend()
+ {
+ ColumnSelection cs = new ColumnSelection();
+ cs.addElement(1);
+ cs.addElement(5);
+ BitSet toMark = new BitSet();
+ toMark.set(1);
+ toMark.set(3);
+ toMark.set(6);
+ toMark.set(9);
+
+ /*
+ * extending selection of {3, 6} should leave {1, 3, 5, 6} selected
+ */
+ assertTrue(cs.markColumns(toMark, 3, 8, false, true, false));
+ List<Integer> selected = cs.getSelected();
+ assertEquals(4, selected.size());
+ assertTrue(selected.contains(1));
+ assertTrue(selected.contains(3));
+ assertTrue(selected.contains(5));
+ assertTrue(selected.contains(6));
+ }
+
+ @Test(groups = "Functional")
+ public void testMarkColumns_invert()
+ {
+ ColumnSelection cs = new ColumnSelection();
+ cs.addElement(5); // this will be cleared
+ BitSet toMark = new BitSet();
+ toMark.set(1);
+ toMark.set(3);
+ toMark.set(6);
+ toMark.set(9);
+
+ /*
+ * inverted selection of {3, 6} should select {4, 5, 7, 8}
+ */
+ assertTrue(cs.markColumns(toMark, 3, 8, true, false, false));
+ List<Integer> selected = cs.getSelected();
+ assertEquals(4, selected.size());
+ assertTrue(selected.contains(4));
+ assertTrue(selected.contains(5));
+ assertTrue(selected.contains(7));
+ assertTrue(selected.contains(8));
+ }
+
+ @Test(groups = "Functional")
+ public void testMarkColumns_toggle()
+ {
+ ColumnSelection cs = new ColumnSelection();
+ cs.addElement(1); // outside change range
+ cs.addElement(3);
+ cs.addElement(4);
+ cs.addElement(10); // outside change range
+ BitSet toMark = new BitSet();
+ toMark.set(1);
+ toMark.set(3);
+ toMark.set(6);
+ toMark.set(9);
+
+ /*
+ * toggling state of {3, 6} should leave {1, 4, 6, 10} selected
+ */
+ assertTrue(cs.markColumns(toMark, 3, 8, false, false, true));
+ List<Integer> selected = cs.getSelected();
+ assertEquals(4, selected.size());
+ assertTrue(selected.contains(1));
+ assertTrue(selected.contains(4));
+ assertTrue(selected.contains(6));
+ assertTrue(selected.contains(10));
+ }
+
+ @Test(groups = "Functional")
+ public void testCopyConstructor()
+ {
+ ColumnSelection cs = new ColumnSelection();
+ cs.addElement(3);
+ cs.addElement(1);
+ cs.hideColumns(10, 11);
+ cs.hideColumns(5, 7);
+ assertEquals("[5, 7]", Arrays.toString(cs.getHiddenColumns().get(0)));
+
+ ColumnSelection cs2 = new ColumnSelection(cs);
+ assertTrue(cs2.hasSelectedColumns());
+ assertTrue(cs2.hasHiddenColumns());
+ // order of column selection is preserved
+ assertEquals("[3, 1]", cs2.getSelected().toString());
+ assertEquals(2, cs2.getHiddenColumns().size());
+ // hidden columns are held in column order
+ assertEquals("[5, 7]", Arrays.toString(cs2.getHiddenColumns().get(0)));
+ assertEquals("[10, 11]", Arrays.toString(cs2.getHiddenColumns().get(1)));
+ }
}
assertTrue(ref1.updateFrom(ref2));
assertEquals("UNIPROT", ref1.getSource()); // unchanged
assertEquals("V71633", ref1.getAccessionId()); // unchanged
-
+
/*
* ref1 has no mapping, acquires mapping from ref2
*/
assertFalse(ref1.updateFrom(ref2));
assertEquals("10", ref1.getVersion());
}
+
+ @Test(groups = { "Functional" })
+ public void testIsPrimaryCandidate()
+ {
+ DBRefEntry dbr = new DBRefEntry(DBRefSource.UNIPROT, "", "Q12345");
+ assertTrue(dbr.isPrimaryCandidate());
+
+ /*
+ * 1:1 mapping - ok
+ */
+ dbr.setMap(new Mapping(null, new int[] { 1, 3 }, new int[] { 1, 3 }, 1,
+ 1));
+ assertTrue(dbr.isPrimaryCandidate());
+
+ /*
+ * 1:1 mapping of identical split ranges - not ok
+ */
+ dbr.setMap(new Mapping(null, new int[] { 1, 3, 6, 9 }, new int[] { 1,
+ 3, 6, 9 }, 1, 1));
+ assertFalse(dbr.isPrimaryCandidate());
+
+ /*
+ * 1:1 mapping of different ranges - not ok
+ */
+ dbr.setMap(new Mapping(null, new int[] { 1, 4 }, new int[] { 2, 5 }, 1,
+ 1));
+ assertFalse(dbr.isPrimaryCandidate());
+
+ /*
+ * 1:1 mapping of 'isoform' ranges - not ok
+ */
+ dbr.setMap(new Mapping(null, new int[] { 1, 2, 6, 9 }, new int[] { 1,
+ 3, 7, 9 }, 1, 1));
+ assertFalse(dbr.isPrimaryCandidate());
+ dbr.setMap(null);
+ assertTrue(dbr.isPrimaryCandidate());
+
+ /*
+ * Version string is prefixed with another dbref source string (fail)
+ */
+ dbr.setVersion(DBRefSource.EMBL + ":0");
+ assertFalse(dbr.isPrimaryCandidate());
+
+ /*
+ * Version string is alphanumeric
+ */
+ dbr.setVersion("0.1.b");
+ assertTrue(dbr.isPrimaryCandidate());
+
+ /*
+ * null version string can't be primary ref
+ */
+ dbr.setVersion(null);
+ assertFalse(dbr.isPrimaryCandidate());
+ dbr.setVersion("");
+ assertTrue(dbr.isPrimaryCandidate());
+
+ /*
+ * 1:1 mapping and sequenceRef (fail)
+ */
+ dbr.setMap(new Mapping(new Sequence("foo", "ASDF"), new int[] { 1, 3 },
+ new int[] { 1, 3 }, 1, 1));
+ assertFalse(dbr.isPrimaryCandidate());
+
+ /*
+ * 1:3 mapping (fail)
+ */
+ dbr.setMap(new Mapping(null, new int[] { 1, 3 }, new int[] { 1, 3 }, 1,
+ 3));
+ assertFalse(dbr.isPrimaryCandidate());
+
+ /*
+ * 2:2 mapping with shift (expected fail, but maybe use case for a pass)
+ */
+ dbr.setMap(new Mapping(null, new int[] { 1, 4 }, new int[] { 1, 4 }, 2,
+ 2));
+ assertFalse(dbr.isPrimaryCandidate());
+ }
}
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
package jalview.datamodel;
import static org.testng.AssertJUnit.assertEquals;
static int SEQ_COUNT = 10;
SequenceI[] seqs;
-
+
/**
* Set up an alignment of 10 sequences
*/
package jalview.datamodel;
import static org.testng.AssertJUnit.assertEquals;
+import static org.testng.AssertJUnit.assertSame;
import jalview.util.MapList;
m = new Mapping(seq, fk);
assertEquals("[ [1, 6] [8, 13] ] 3:1 to [ [4, 7] ] Seq1", m.toString());
}
+
+ @Test(groups = { "Functional" })
+ public void testCopyConstructor()
+ {
+ MapList ml = new MapList(new int[] { 1, 6, 8, 13 }, new int[] { 4, 7 },
+ 3, 1);
+ SequenceI seq = new Sequence("seq1", "agtacg");
+ Mapping m = new Mapping(seq, ml);
+ m.setMappedFromId("abc");
+ Mapping copy = new Mapping(m);
+ assertEquals("abc", copy.getMappedFromId());
+ assertEquals(ml, copy.getMap());
+ assertSame(seq, copy.getTo());
+ }
}
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
package jalview.datamodel;
import static org.testng.AssertJUnit.assertEquals;
/*
+ assertEquals(case7, case9);
* Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
* Copyright (C) $$Year-Rel$$ The Jalview Authors
*
*/
package jalview.datamodel;
-import static org.testng.AssertJUnit.assertTrue;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertNotEquals;
+import static org.testng.Assert.assertNotSame;
+import static org.testng.Assert.assertNull;
+import static org.testng.Assert.assertSame;
+import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.fail;
+import jalview.datamodel.PDBEntry.Type;
+
+//import org.testng.Assert;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
}
@Test(groups = { "Functional" })
- public void test()
+ public void testEquals()
+ {
+ PDBEntry pdbEntry = new PDBEntry("1xyz", "A", PDBEntry.Type.PDB,
+ "x/y/z/File");
+
+ // id comparison is not case sensitive
+ PDBEntry case1 = new PDBEntry("1XYZ", "A", PDBEntry.Type.PDB,
+ "x/y/z/File");
+ // chain code comparison is not case sensitive
+ PDBEntry case2 = new PDBEntry("1xyz", "a", PDBEntry.Type.PDB,
+ "x/y/z/File");
+ // different type
+ PDBEntry case3 = new PDBEntry("1xyz", "A", PDBEntry.Type.FILE,
+ "x/y/z/File");
+ // different everything
+ PDBEntry case4 = new PDBEntry(null, null, null, null);
+ // null id
+ PDBEntry case5 = new PDBEntry(null, "A", PDBEntry.Type.PDB,
+ "x/y/z/File");
+ // null chain
+ PDBEntry case6 = new PDBEntry("1xyz", null, PDBEntry.Type.PDB,
+ "x/y/z/File");
+ // null type
+ PDBEntry case7 = new PDBEntry("1xyz", "A", null, "x/y/z/File");
+ // null file
+ PDBEntry case8 = new PDBEntry("1xyz", "A", PDBEntry.Type.PDB, null);
+ // identical to case7
+ PDBEntry case9 = new PDBEntry("1xyz", "A", null, "x/y/z/File");
+ // different file only
+ PDBEntry case10 = new PDBEntry("1xyz", "A", null, "a/b/c/File");
+
+ /*
+ * assertEquals will invoke PDBEntry.equals()
+ */
+ assertFalse(pdbEntry.equals(null));
+ assertFalse(pdbEntry.equals("a"));
+ assertEquals(case1, pdbEntry);
+ assertEquals(case2, pdbEntry);
+ assertNotEquals(case3, pdbEntry);
+ assertNotEquals(case4, pdbEntry);
+ assertNotEquals(case5, pdbEntry);
+ assertNotEquals(case6, pdbEntry);
+ assertNotEquals(case7, pdbEntry);
+ assertNotEquals(case8, pdbEntry);
+ assertEquals(case7, case9);
+ assertNotEquals(case9, case10);
+
+ // add properties
+ case7.setProperty("hello", "world");
+ assertNotEquals(case7, case9);
+ case9.setProperty("hello", "world");
+ assertEquals(case7, case9);
+ case9.setProperty("hello", "WORLD");
+ assertNotEquals(case7, case9);
+
+ /*
+ * change string wrapper property to string...
+ */
+ case1.setProperty("chain_code", "a");
+ assertFalse(pdbEntry.equals(case1));
+ assertFalse(case1.equals(pdbEntry));
+ }
+
+ @Test(groups = { "Functional" })
+ public void testSetChainCode()
+ {
+ PDBEntry pdbEntry = new PDBEntry("1xyz", null, PDBEntry.Type.PDB,
+ "x/y/z/File");
+ assertNull(pdbEntry.getChainCode());
+
+ pdbEntry.setChainCode("a");
+ assertEquals("a", pdbEntry.getChainCode());
+
+ pdbEntry.setChainCode(null);
+ assertNull(pdbEntry.getChainCode());
+ }
+
+ @Test(groups = { "Functional" })
+ public void testGetType()
+ {
+ assertSame(PDBEntry.Type.FILE, PDBEntry.Type.getType("FILE"));
+ assertSame(PDBEntry.Type.FILE, PDBEntry.Type.getType("File"));
+ assertSame(PDBEntry.Type.FILE, PDBEntry.Type.getType("file"));
+ assertNotSame(PDBEntry.Type.FILE, PDBEntry.Type.getType("file "));
+ }
+
+ @Test(groups = { "Functional" })
+ public void testTypeMatches()
+ {
+ // TODO Type.matches() is not used - delete?
+ assertTrue(PDBEntry.Type.FILE.matches("FILE"));
+ assertTrue(PDBEntry.Type.FILE.matches("File"));
+ assertTrue(PDBEntry.Type.FILE.matches("file"));
+ assertFalse(PDBEntry.Type.FILE.matches("FILE "));
+ }
+
+ @Test(groups = { "Functional" })
+ public void testUpdateFrom()
+ {
+ PDBEntry pdb1 = new PDBEntry("3A6S", null, null, null);
+ PDBEntry pdb2 = new PDBEntry("3A6S", null, null, null);
+ assertTrue(pdb1.updateFrom(pdb2));
+
+ /*
+ * mismatch of pdb id not allowed
+ */
+ pdb2 = new PDBEntry("1A70", "A", null, null);
+ assertFalse(pdb1.updateFrom(pdb2));
+ assertNull(pdb1.getChainCode());
+
+ /*
+ * match of pdb id is not case sensitive
+ */
+ pdb2 = new PDBEntry("3a6s", "A", null, null);
+ assertTrue(pdb1.updateFrom(pdb2));
+ assertEquals(pdb1.getChainCode(), "A");
+ assertEquals(pdb1.getId(), "3A6S");
+
+ /*
+ * add chain - with differing case for id
+ */
+ pdb1 = new PDBEntry("3A6S", null, null, null);
+ pdb2 = new PDBEntry("3a6s", "A", null, null);
+ assertTrue(pdb1.updateFrom(pdb2));
+ assertEquals(pdb1.getChainCode(), "A");
+
+ /*
+ * change of chain is not allowed
+ */
+ pdb2 = new PDBEntry("3A6S", "B", null, null);
+ assertFalse(pdb1.updateFrom(pdb2));
+ assertEquals(pdb1.getChainCode(), "A");
+
+ /*
+ * change chain from null
+ */
+ pdb1 = new PDBEntry("3A6S", null, null, null);
+ pdb2 = new PDBEntry("3A6S", "B", null, null);
+ assertTrue(pdb1.updateFrom(pdb2));
+ assertEquals(pdb1.getChainCode(), "B");
+
+ /*
+ * set file and type
+ */
+ pdb2 = new PDBEntry("3A6S", "B", Type.FILE, "filePath");
+ assertTrue(pdb1.updateFrom(pdb2));
+ assertEquals(pdb1.getFile(), "filePath");
+ assertEquals(pdb1.getType(), Type.FILE.toString());
+
+ /*
+ * change of file is not allowed
+ */
+ pdb1 = new PDBEntry("3A6S", null, null, "file1");
+ pdb2 = new PDBEntry("3A6S", "A", null, "file2");
+ assertFalse(pdb1.updateFrom(pdb2));
+ assertNull(pdb1.getChainCode());
+ assertEquals(pdb1.getFile(), "file1");
+
+ /*
+ * set type without change of file
+ */
+ pdb1 = new PDBEntry("3A6S", null, null, "file1");
+ pdb2 = new PDBEntry("3A6S", null, Type.PDB, "file1");
+ assertTrue(pdb1.updateFrom(pdb2));
+ assertEquals(pdb1.getType(), Type.PDB.toString());
+
+ /*
+ * set file with differing case of id and chain code
+ */
+ pdb1 = new PDBEntry("3A6S", "A", null, null);
+ pdb2 = new PDBEntry("3a6s", "a", Type.PDB, "file1");
+ assertTrue(pdb1.updateFrom(pdb2));
+ assertEquals(pdb1.getType(), Type.PDB.toString());
+ assertEquals(pdb1.getId(), "3A6S"); // unchanged
+ assertEquals(pdb1.getFile(), "file1"); // updated
+ assertEquals(pdb1.getChainCode(), "A"); // unchanged
+
+ /*
+ * changing nothing returns true
+ */
+ pdb1 = new PDBEntry("3A6S", "A", Type.PDB, "file1");
+ pdb2 = new PDBEntry("3A6S", null, null, null);
+ assertTrue(pdb1.updateFrom(pdb2));
+ assertEquals(pdb1.getChainCode(), "A");
+ assertEquals(pdb1.getType(), Type.PDB.toString());
+ assertEquals(pdb1.getFile(), "file1");
+
+ /*
+ * add and update properties only
+ */
+ pdb1 = new PDBEntry("3A6S", null, null, null);
+ pdb2 = new PDBEntry("3A6S", null, null, null);
+ pdb1.setProperty("destination", "mars");
+ pdb1.setProperty("hello", "world");
+ pdb2.setProperty("hello", "moon");
+ pdb2.setProperty("goodbye", "world");
+ assertTrue(pdb1.updateFrom(pdb2));
+ assertEquals(pdb1.getProperty("destination"), "mars");
+ assertEquals(pdb1.getProperty("hello"), "moon");
+ assertEquals(pdb1.getProperty("goodbye"), "world");
+
+ /*
+ * add properties only
+ */
+ pdb1 = new PDBEntry("3A6S", null, null, null);
+ pdb2 = new PDBEntry("3A6S", null, null, null);
+ pdb2.setProperty("hello", "moon");
+ assertTrue(pdb1.updateFrom(pdb2));
+ assertEquals(pdb1.getProperty("hello"), "moon");
+ }
+
+ @Test(groups = { "Functional" })
+ public void testConstructor_fromDbref()
{
+ PDBEntry pdb = new PDBEntry(new DBRefEntry("PDB", "0", "1A70"));
+ assertEquals(pdb.getId(), "1A70");
+ assertNull(pdb.getChainCode());
+ assertNull(pdb.getType());
+ assertNull(pdb.getFile());
+
+ /*
+ * from dbref with chain code appended
+ */
+ pdb = new PDBEntry(new DBRefEntry("PDB", "0", "1A70B"));
+ assertEquals(pdb.getId(), "1A70");
+ assertEquals(pdb.getChainCode(), "B");
+
+ /*
+ * from dbref with overlong accession
+ */
+ pdb = new PDBEntry(new DBRefEntry("PDB", "0", "1A70BC"));
+ assertEquals(pdb.getId(), "1A70BC");
+ assertNull(pdb.getChainCode());
+
+ /*
+ * from dbref which is not for PDB
+ */
try
{
-
- PDBEntry pdbEntry = new PDBEntry("1xyz", "A", PDBEntry.Type.PDB,
- "x/y/z/File");
-
- PDBEntry case1 = new PDBEntry("1XYZ", "A", PDBEntry.Type.PDB,
- "x/y/z/File");
- PDBEntry case2 = new PDBEntry("1xyz", "a", PDBEntry.Type.PDB,
- "x/y/z/File");
- PDBEntry case3 = new PDBEntry("1xyz", "A", PDBEntry.Type.FILE,
- "x/y/z/File");
- PDBEntry case4 = new PDBEntry(null, null, null, null);
- PDBEntry case5 = new PDBEntry(null, "A", PDBEntry.Type.PDB,
- "x/y/z/File");
- PDBEntry case6 = new PDBEntry("1xyz", null, PDBEntry.Type.PDB,
- "x/y/z/File");
- PDBEntry case7 = new PDBEntry("1xyz", "A", null, "x/y/z/File");
- PDBEntry case8 = new PDBEntry("1xyz", "A", PDBEntry.Type.PDB, null);
- PDBEntry case9 = new PDBEntry("1xyz", "A", null, "x/y/z/File");
-
- // System.out.println(">>>> Testing case 1");
- assertTrue(pdbEntry.equals(case1));
- // System.out.println(">>>> Testing case 2");
- assertTrue(pdbEntry.equals(case2));
- // System.out.println(">>>> Testing case 3");
- assertTrue(!pdbEntry.equals(case3));
- // System.out.println(">>>> Testing case 4");
- assertTrue(!pdbEntry.equals(case4));
- // System.out.println(">>>> Testing case 5");
- assertTrue(!pdbEntry.equals(case5));
- // System.out.println(">>>> Testing case 6");
- assertTrue(!pdbEntry.equals(case6));
- // System.out.println(">>>> Testing case 7");
- assertTrue(!pdbEntry.equals(case7));
- // System.out.println(">>>> Testing case 8");
- assertTrue(pdbEntry.equals(case8));
- assertTrue(pdbEntry.equals(case8));
- assertTrue(case7.equals(case9));
- } catch (Exception e)
+ pdb = new PDBEntry(new DBRefEntry("PDBe", "0", "1A70"));
+ fail("Expected exception");
+ } catch (IllegalArgumentException e)
{
- e.printStackTrace();
+ // expected;
}
-
}
}
sr2.addResult(seq1, 6, 8);
assertEquals(sr1.hashCode(), sr2.hashCode());
}
-
+
/**
* Verify that SearchResults$Match constructor normalises start/end to the
* 'forwards' direction
}
}
}
+
/*
* refactored 'as is' from main method
*
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
package jalview.datamodel;
import static org.testng.AssertJUnit.assertEquals;
import jalview.datamodel.PDBEntry.Type;
import jalview.util.MapList;
+import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
assertEquals("Gap interval 2 end wrong", 8, gapInt.get(1)[1]);
}
+ @Test(groups = ("Functional"))
+ public void testIsProtein()
+ {
+ // test Protein
+ assertTrue(new Sequence("prot", "ASDFASDFASDF").isProtein());
+ // test DNA
+ assertFalse(new Sequence("prot", "ACGTACGTACGT").isProtein());
+ // test RNA
+ SequenceI sq = new Sequence("prot", "ACGUACGUACGU");
+ assertFalse(sq.isProtein());
+ // change sequence, should trigger an update of cached result
+ sq.setSequence("ASDFASDFADSF");
+ assertTrue(sq.isProtein());
+ /*
+ * in situ change of sequence doesn't change hashcode :-O
+ * (sequence should not expose internal implementation)
+ */
+ for (int i = 0; i < sq.getSequence().length; i++)
+ {
+ sq.getSequence()[i] = "acgtu".charAt(i % 5);
+ }
+ assertTrue(sq.isProtein()); // but it isn't
+ }
+
@Test(groups = { "Functional" })
public void testGetAnnotation()
{
{
AlignmentAnnotation ann1 = addAnnotation("label1", "desc1", "calcId1",
1f);
- AlignmentAnnotation ann2 = addAnnotation("label2", "desc2", "calcId2",
- 1f);
+ addAnnotation("label2", "desc2", "calcId2", 1f);
AlignmentAnnotation ann3 = addAnnotation("label1", "desc3", "calcId3",
1f);
AlignmentAnnotation[] anns = seq.getAnnotation("label1");
@Test(groups = { "Functional" })
public void testGetAlignmentAnnotations_forCalcIdAndLabel()
{
- AlignmentAnnotation ann1 = addAnnotation("label1", "desc1", "calcId1",
- 1f);
+ addAnnotation("label1", "desc1", "calcId1", 1f);
AlignmentAnnotation ann2 = addAnnotation("label2", "desc2", "calcId2",
1f);
- AlignmentAnnotation ann3 = addAnnotation("label2", "desc3", "calcId3",
- 1f);
+ addAnnotation("label2", "desc3", "calcId3", 1f);
AlignmentAnnotation ann4 = addAnnotation("label2", "desc3", "calcId2",
1f);
- AlignmentAnnotation ann5 = addAnnotation("label5", "desc3", null, 1f);
- AlignmentAnnotation ann6 = addAnnotation(null, "desc3", "calcId3", 1f);
+ addAnnotation("label5", "desc3", null, 1f);
+ addAnnotation(null, "desc3", "calcId3", 1f);
+
List<AlignmentAnnotation> anns = seq.getAlignmentAnnotations("calcId2",
"label2");
assertEquals(2, anns.size());
assertEquals(1, sfs.length);
assertSame(sf, sfs[0]);
-
/*
* SequenceFeature on sequence and dataset sequence; returns that on
* sequence
* is there a usecase for this ? setDatasetSequence should throw an error if
* this actually occurs.
*/
- sq.getDatasetSequence().setDatasetSequence(sq); // loop!
+ try
+ {
+ sq.getDatasetSequence().setDatasetSequence(sq); // loop!
+ Assert.fail("Expected Error to be raised when calling setDatasetSequence with self reference");
+ } catch (IllegalArgumentException e)
+ {
+ // TODO Jalview error/exception class for raising implementation errors
+ assertTrue(e.getMessage().toLowerCase()
+ .contains("implementation error"));
+ }
assertNull(sq.getSequenceFeatures());
}
}
/**
+ * test createDatasetSequence behaves to doc
+ */
+ @Test(groups = { "Functional" })
+ public void testCreateDatasetSequence()
+ {
+ SequenceI sq = new Sequence("my", "ASDASD");
+ assertNull(sq.getDatasetSequence());
+ SequenceI rds = sq.createDatasetSequence();
+ assertNotNull(rds);
+ assertNull(rds.getDatasetSequence());
+ assertEquals(sq.getDatasetSequence(), rds);
+ }
+
+ /**
* Test for deriveSequence applied to a sequence with a dataset
*/
@Test(groups = { "Functional" })
sq.setDescription("Test sequence description..");
sq.setVamsasId("TestVamsasId");
- sq.setSourceDBRef(new DBRefEntry("PDB", "version0", "1TST"));
+ sq.addDBRef(new DBRefEntry("PDB", "version0", "1TST"));
- sq.addDBRef(new DBRefEntry("PDB", "version1", "1Tst"));
- sq.addDBRef(new DBRefEntry("PDB", "version2", "2Tst"));
- sq.addDBRef(new DBRefEntry("PDB", "version3", "3Tst"));
- sq.addDBRef(new DBRefEntry("PDB", "version4", "4Tst"));
+ sq.addDBRef(new DBRefEntry("PDB", "version1", "1PDB"));
+ sq.addDBRef(new DBRefEntry("PDB", "version2", "2PDB"));
+ sq.addDBRef(new DBRefEntry("PDB", "version3", "3PDB"));
+ sq.addDBRef(new DBRefEntry("PDB", "version4", "4PDB"));
sq.addPDBId(new PDBEntry("1PDB", "A", Type.PDB, "filePath/test1"));
sq.addPDBId(new PDBEntry("1PDB", "B", Type.PDB, "filePath/test1"));
sq.addPDBId(new PDBEntry("2PDB", "A", Type.MMCIF, "filePath/test2"));
sq.addPDBId(new PDBEntry("2PDB", "B", Type.MMCIF, "filePath/test2"));
+ // these are the same as ones already added
+ DBRefEntry pdb1pdb = new DBRefEntry("PDB", "version1", "1PDB");
+ DBRefEntry pdb2pdb = new DBRefEntry("PDB", "version2", "2PDB");
+
+ List<DBRefEntry> primRefs = Arrays.asList(new DBRefEntry[] { pdb1pdb,
+ pdb2pdb });
+
+ sq.getDatasetSequence().addDBRef(pdb1pdb); // should do nothing
+ sq.getDatasetSequence().addDBRef(pdb2pdb); // should do nothing
sq.getDatasetSequence().addDBRef(
- new DBRefEntry("PDB", "version1", "1Tst"));
- sq.getDatasetSequence().addDBRef(
- new DBRefEntry("PDB", "version2", "2Tst"));
- sq.getDatasetSequence().addDBRef(
- new DBRefEntry("PDB", "version3", "3Tst"));
+ new DBRefEntry("PDB", "version3", "3PDB")); // should do nothing
sq.getDatasetSequence().addDBRef(
- new DBRefEntry("PDB", "version4", "4Tst"));
+ new DBRefEntry("PDB", "version4", "4PDB")); // should do nothing
+
+ PDBEntry pdbe1a = new PDBEntry("1PDB", "A", Type.PDB, "filePath/test1");
+ PDBEntry pdbe1b = new PDBEntry("1PDB", "B", Type.PDB, "filePath/test1");
+ PDBEntry pdbe2a = new PDBEntry("2PDB", "A", Type.MMCIF,
+ "filePath/test2");
+ PDBEntry pdbe2b = new PDBEntry("2PDB", "B", Type.MMCIF,
+ "filePath/test2");
+ sq.getDatasetSequence().addPDBId(pdbe1a);
+ sq.getDatasetSequence().addPDBId(pdbe1b);
+ sq.getDatasetSequence().addPDBId(pdbe2a);
+ sq.getDatasetSequence().addPDBId(pdbe2b);
- sq.getDatasetSequence().addPDBId(
- new PDBEntry("1PDB", "A", Type.PDB, "filePath/test1"));
- sq.getDatasetSequence().addPDBId(
- new PDBEntry("1PDB", "B", Type.PDB, "filePath/test1"));
- sq.getDatasetSequence().addPDBId(
- new PDBEntry("2PDB", "A", Type.MMCIF, "filePath/test2"));
- sq.getDatasetSequence().addPDBId(
- new PDBEntry("2PDB", "B", Type.MMCIF, "filePath/test2"));
+ /*
+ * test we added pdb entries to the dataset sequence
+ */
+ Assert.assertEquals(sq.getDatasetSequence().getAllPDBEntries(), Arrays
+ .asList(new PDBEntry[] { pdbe1a, pdbe1b, pdbe2a, pdbe2b }),
+ "PDB Entries were not found on dataset sequence.");
+ /*
+ * we should recover a pdb entry that is on the dataset sequence via PDBEntry
+ */
+ Assert.assertEquals(pdbe1a,
+ sq.getDatasetSequence().getPDBEntry("1PDB"),
+ "PDB Entry '1PDB' not found on dataset sequence via getPDBEntry.");
ArrayList<Annotation> annotsList = new ArrayList<Annotation>();
System.out.println(">>>>>> " + sq.getSequenceAsString().length());
annotsList.add(new Annotation("A", "A", 'X', 0.1f));
new AlignmentAnnotation("Test annot", "Test annot description",
annots));
Assert.assertEquals(sq.getDescription(), "Test sequence description..");
- Assert.assertEquals(sq.getDBRefs().length, 4);
+ Assert.assertEquals(sq.getDBRefs().length, 5); // DBRefs are on dataset
+ // sequence
Assert.assertEquals(sq.getAllPDBEntries().size(), 4);
Assert.assertNotNull(sq.getAnnotation());
Assert.assertEquals(sq.getAnnotation()[0].annotations.length, 2);
- Assert.assertEquals(sq.getDatasetSequence().getDBRefs().length, 4);
+ Assert.assertEquals(sq.getDatasetSequence().getDBRefs().length, 5); // same
+ // as
+ // sq.getDBRefs()
Assert.assertEquals(sq.getDatasetSequence().getAllPDBEntries().size(),
4);
Assert.assertNotNull(sq.getDatasetSequence().getAnnotation());
Assert.assertEquals(derived.getDescription(),
"Test sequence description..");
- Assert.assertEquals(derived.getDBRefs().length, 4);
+ Assert.assertEquals(derived.getDBRefs().length, 5); // come from dataset
Assert.assertEquals(derived.getAllPDBEntries().size(), 4);
Assert.assertNotNull(derived.getAnnotation());
Assert.assertEquals(derived.getAnnotation()[0].annotations.length, 2);
- Assert.assertEquals(derived.getDatasetSequence().getDBRefs().length, 4);
+ Assert.assertEquals(derived.getDatasetSequence().getDBRefs().length, 5);
Assert.assertEquals(derived.getDatasetSequence().getAllPDBEntries()
.size(), 4);
Assert.assertNotNull(derived.getDatasetSequence().getAnnotation());
assertNotNull(sq.getSequenceFeatures());
assertArrayEquals(sq.getSequenceFeatures(),
derived.getSequenceFeatures());
+
+ /*
+ * verify we have primary db refs *just* for PDB IDs with associated
+ * PDBEntry objects
+ */
+
+ assertEquals(primRefs, sq.getPrimaryDBRefs());
+ assertEquals(primRefs, sq.getDatasetSequence().getPrimaryDBRefs());
+
+ assertEquals(sq.getPrimaryDBRefs(), derived.getPrimaryDBRefs());
+
}
/**
12.4f, "group"));
seq1.addPDBId(new PDBEntry("1A70", "B", Type.PDB, "File"));
seq1.addDBRef(new DBRefEntry("EMBL", "1.2", "AZ12345"));
-
+
SequenceI copy = new Sequence(seq1);
assertNull(copy.getDatasetSequence());
// copy has a copy of the sequence feature:
SequenceFeature[] sfs = copy.getSequenceFeatures();
assertEquals(1, sfs.length);
- if (seq1.getDatasetSequence()!=null && copy.getDatasetSequence()==seq1.getDatasetSequence()) {
+ if (seq1.getDatasetSequence() != null
+ && copy.getDatasetSequence() == seq1.getDatasetSequence())
+ {
assertTrue(sfs[0] == seq1.getSequenceFeatures()[0]);
- } else {
+ }
+ else
+ {
assertFalse(sfs[0] == seq1.getSequenceFeatures()[0]);
}
assertTrue(sfs[0].equals(seq1.getSequenceFeatures()[0]));
assertSame(dbref3, sq.getDBRefs()[2]);
assertEquals("3", dbref2.getVersion());
}
+
+ @Test(groups = { "Functional" })
+ public void testGetPrimaryDBRefs_peptide()
+ {
+ SequenceI sq = new Sequence("aseq", "ASDFKYLMQPRST", 10, 22);
+
+ // no dbrefs
+ List<DBRefEntry> primaryDBRefs = sq.getPrimaryDBRefs();
+ assertTrue(primaryDBRefs.isEmpty());
+
+ // empty dbrefs
+ sq.setDBRefs(new DBRefEntry[] {});
+ primaryDBRefs = sq.getPrimaryDBRefs();
+ assertTrue(primaryDBRefs.isEmpty());
+
+ // primary - uniprot
+ DBRefEntry upentry1 = new DBRefEntry("UNIPROT", "0", "Q04760");
+ sq.addDBRef(upentry1);
+
+ // primary - uniprot with congruent map
+ DBRefEntry upentry2 = new DBRefEntry("UNIPROT", "0", "Q04762");
+ upentry2.setMap(new Mapping(null, new MapList(new int[] { 10, 22 },
+ new int[] { 10, 22 }, 1, 1)));
+ sq.addDBRef(upentry2);
+
+ // primary - uniprot with map of enclosing sequence
+ DBRefEntry upentry3 = new DBRefEntry("UNIPROT", "0", "Q04763");
+ upentry3.setMap(new Mapping(null, new MapList(new int[] { 8, 24 },
+ new int[] { 8, 24 }, 1, 1)));
+ sq.addDBRef(upentry3);
+
+ // not primary - uniprot with map of sub-sequence (5')
+ DBRefEntry upentry4 = new DBRefEntry("UNIPROT", "0", "Q04764");
+ upentry4.setMap(new Mapping(null, new MapList(new int[] { 10, 18 },
+ new int[] { 10, 18 }, 1, 1)));
+ sq.addDBRef(upentry4);
+
+ // not primary - uniprot with map that overlaps 3'
+ DBRefEntry upentry5 = new DBRefEntry("UNIPROT", "0", "Q04765");
+ upentry5.setMap(new Mapping(null, new MapList(new int[] { 12, 22 },
+ new int[] { 12, 22 }, 1, 1)));
+ sq.addDBRef(upentry5);
+
+ // not primary - uniprot with map to different coordinates frame
+ DBRefEntry upentry6 = new DBRefEntry("UNIPROT", "0", "Q04766");
+ upentry6.setMap(new Mapping(null, new MapList(new int[] { 12, 18 },
+ new int[] { 112, 118 }, 1, 1)));
+ sq.addDBRef(upentry6);
+
+ // not primary - dbref to 'non-core' database
+ DBRefEntry upentry7 = new DBRefEntry("Pfam", "0", "PF00903");
+ sq.addDBRef(upentry7);
+
+ // primary - type is PDB
+ DBRefEntry pdbentry = new DBRefEntry("PDB", "0", "1qip");
+ sq.addDBRef(pdbentry);
+
+ // not primary - PDBEntry has no file
+ sq.addDBRef(new DBRefEntry("PDB", "0", "1AAA"));
+
+ // not primary - no PDBEntry
+ sq.addDBRef(new DBRefEntry("PDB", "0", "1DDD"));
+
+ // add corroborating PDB entry for primary DBref -
+ // needs to have a file as well as matching ID
+ // note PDB ID is not treated as case sensitive
+ sq.addPDBId(new PDBEntry("1QIP", null, Type.PDB, new File("/blah")
+ .toString()));
+
+ // not valid DBRef - no file..
+ sq.addPDBId(new PDBEntry("1AAA", null, null, null));
+
+ primaryDBRefs = sq.getPrimaryDBRefs();
+ assertEquals(4, primaryDBRefs.size());
+ assertTrue("Couldn't find simple primary reference (UNIPROT)",
+ primaryDBRefs.contains(upentry1));
+ assertTrue("Couldn't find mapped primary reference (UNIPROT)",
+ primaryDBRefs.contains(upentry2));
+ assertTrue("Couldn't find mapped context reference (UNIPROT)",
+ primaryDBRefs.contains(upentry3));
+ assertTrue("Couldn't find expected PDB primary reference",
+ primaryDBRefs.contains(pdbentry));
+ }
+
+ @Test(groups = { "Functional" })
+ public void testGetPrimaryDBRefs_nucleotide()
+ {
+ SequenceI sq = new Sequence("aseq", "TGATCACTCGACTAGCATCAGCATA", 10, 34);
+
+ // primary - Ensembl
+ DBRefEntry dbr1 = new DBRefEntry("ENSEMBL", "0", "ENSG1234");
+ sq.addDBRef(dbr1);
+
+ // not primary - Ensembl 'transcript' mapping of sub-sequence
+ DBRefEntry dbr2 = new DBRefEntry("ENSEMBL", "0", "ENST1234");
+ dbr2.setMap(new Mapping(null, new MapList(new int[] { 15, 25 },
+ new int[] { 1, 11 }, 1, 1)));
+ sq.addDBRef(dbr2);
+
+ // primary - EMBL with congruent map
+ DBRefEntry dbr3 = new DBRefEntry("EMBL", "0", "J1234");
+ dbr3.setMap(new Mapping(null, new MapList(new int[] { 10, 34 },
+ new int[] { 10, 34 }, 1, 1)));
+ sq.addDBRef(dbr3);
+
+ // not primary - to non-core database
+ DBRefEntry dbr4 = new DBRefEntry("CCDS", "0", "J1234");
+ sq.addDBRef(dbr4);
+
+ // not primary - to protein
+ DBRefEntry dbr5 = new DBRefEntry("UNIPROT", "0", "Q87654");
+ sq.addDBRef(dbr5);
+
+ List<DBRefEntry> primaryDBRefs = sq.getPrimaryDBRefs();
+ assertEquals(2, primaryDBRefs.size());
+ assertTrue(primaryDBRefs.contains(dbr1));
+ assertTrue(primaryDBRefs.contains(dbr3));
+ }
+
+ /**
+ * Test the method that updates the list of PDBEntry from any new DBRefEntry
+ * for PDB
+ */
+ @Test(groups = { "Functional" })
+ public void testUpdatePDBIds()
+ {
+ PDBEntry pdbe1 = new PDBEntry("3A6S", null, null, null);
+ seq.addPDBId(pdbe1);
+ seq.addDBRef(new DBRefEntry("Ensembl", "8", "ENST1234"));
+ seq.addDBRef(new DBRefEntry("PDB", "0", "1A70"));
+ seq.addDBRef(new DBRefEntry("PDB", "0", "4BQGa"));
+ seq.addDBRef(new DBRefEntry("PDB", "0", "3a6sB"));
+ // 7 is not a valid chain code:
+ seq.addDBRef(new DBRefEntry("PDB", "0", "2GIS7"));
+
+ seq.updatePDBIds();
+ List<PDBEntry> pdbIds = seq.getAllPDBEntries();
+ assertEquals(4, pdbIds.size());
+ assertSame(pdbe1, pdbIds.get(0));
+ // chain code got added to 3A6S:
+ assertEquals("B", pdbe1.getChainCode());
+ assertEquals("1A70", pdbIds.get(1).getId());
+ // 4BQGA is parsed into id + chain
+ assertEquals("4BQG", pdbIds.get(2).getId());
+ assertEquals("a", pdbIds.get(2).getChainCode());
+ assertEquals("2GIS7", pdbIds.get(3).getId());
+ assertNull(pdbIds.get(3).getChainCode());
+ }
+
+ /**
+ * Test the method that either adds a pdbid or updates an existing one
+ */
+ @Test(groups = { "Functional" })
+ public void testAddPDBId()
+ {
+ PDBEntry pdbe = new PDBEntry("3A6S", null, null, null);
+ seq.addPDBId(pdbe);
+ assertEquals(1, seq.getAllPDBEntries().size());
+ assertSame(pdbe, seq.getPDBEntry("3A6S"));
+ assertSame(pdbe, seq.getPDBEntry("3a6s")); // case-insensitive
+
+ // add the same entry
+ seq.addPDBId(pdbe);
+ assertEquals(1, seq.getAllPDBEntries().size());
+ assertSame(pdbe, seq.getPDBEntry("3A6S"));
+
+ // add an identical entry
+ seq.addPDBId(new PDBEntry("3A6S", null, null, null));
+ assertEquals(1, seq.getAllPDBEntries().size());
+ assertSame(pdbe, seq.getPDBEntry("3A6S"));
+
+ // add a different entry
+ PDBEntry pdbe2 = new PDBEntry("1A70", null, null, null);
+ seq.addPDBId(pdbe2);
+ assertEquals(2, seq.getAllPDBEntries().size());
+ assertSame(pdbe, seq.getAllPDBEntries().get(0));
+ assertSame(pdbe2, seq.getAllPDBEntries().get(1));
+
+ // update pdbe with chain code, file, type
+ PDBEntry pdbe3 = new PDBEntry("3a6s", "A", Type.PDB, "filepath");
+ seq.addPDBId(pdbe3);
+ assertEquals(2, seq.getAllPDBEntries().size());
+ assertSame(pdbe, seq.getAllPDBEntries().get(0)); // updated in situ
+ assertEquals("3A6S", pdbe.getId()); // unchanged
+ assertEquals("A", pdbe.getChainCode()); // updated
+ assertEquals(Type.PDB.toString(), pdbe.getType()); // updated
+ assertEquals("filepath", pdbe.getFile()); // updated
+ assertSame(pdbe2, seq.getAllPDBEntries().get(1));
+
+ // add with a different file path
+ PDBEntry pdbe4 = new PDBEntry("3a6s", "A", Type.PDB, "filepath2");
+ seq.addPDBId(pdbe4);
+ assertEquals(3, seq.getAllPDBEntries().size());
+ assertSame(pdbe4, seq.getAllPDBEntries().get(2));
+
+ // add with a different chain code
+ PDBEntry pdbe5 = new PDBEntry("3a6s", "B", Type.PDB, "filepath");
+ seq.addPDBId(pdbe5);
+ assertEquals(4, seq.getAllPDBEntries().size());
+ assertSame(pdbe5, seq.getAllPDBEntries().get(3));
+ }
+
+ @Test(
+ groups = { "Functional" },
+ expectedExceptions = { IllegalArgumentException.class })
+ public void testSetDatasetSequence_toSelf()
+ {
+ seq.setDatasetSequence(seq);
+ }
+
+ @Test(
+ groups = { "Functional" },
+ expectedExceptions = { IllegalArgumentException.class })
+ public void testSetDatasetSequence_cascading()
+ {
+ SequenceI seq2 = new Sequence("Seq2", "xyz");
+ seq2.createDatasetSequence();
+ seq.setDatasetSequence(seq2);
+ }
}
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
package jalview.datamodel.xdb.embl;
import static org.testng.AssertJUnit.assertEquals;
+import static org.testng.AssertJUnit.assertNull;
import static org.testng.AssertJUnit.assertSame;
import jalview.analysis.SequenceIdMatcher;
import jalview.datamodel.DBRefEntry;
-import jalview.datamodel.Sequence;
+import jalview.datamodel.DBRefSource;
import jalview.datamodel.SequenceI;
+import jalview.util.MapList;
import java.util.ArrayList;
import java.util.Arrays;
EmblEntry testee = new EmblEntry();
/*
- * Make a (CDS) Feature with 4 locations
+ * Make a (CDS) Feature with 5 locations
*/
EmblFeature cds = new EmblFeature();
cds.setLocation("join(10..20,complement(30..40),50..60,70..80,complement(110..120))");
public void testParseCodingFeature()
{
// not the whole sequence but enough for this test...
- SequenceI dna = new Sequence("J03321", "GGATCCGTAAGTTAGACGAAATT");
List<SequenceI> peptides = new ArrayList<SequenceI>();
SequenceIdMatcher matcher = new SequenceIdMatcher(peptides);
EmblFile ef = EmblTestHelper.getEmblFile();
+ assertEquals(1, ef.getEntries().size());
+ EmblEntry testee = ef.getEntries().get(0);
+ String sourceDb = "EMBL";
+ SequenceI dna = testee.makeSequence(sourceDb);
/*
- * parse two CDS features, one with two Uniprot cross-refs,
- * the other with one
+ * parse three CDS features, with two/one/no Uniprot cross-refs
*/
- EmblEntry testee = new EmblEntry();
for (EmblFeature feature : ef.getEntries().get(0).getFeatures())
{
if ("CDS".equals(feature.getName()))
{
- testee.parseCodingFeature(feature, "EMBL", dna, peptides, matcher);
+ testee.parseCodingFeature(feature, sourceDb, dna, peptides, matcher);
}
}
/*
* peptides should now have five entries:
* EMBL product and two Uniprot accessions for the first CDS / translation
- * EMBL product and one Uniprot accession for the second CDS / translation
+ * EMBL product and one Uniprot accession for the second CDS / "
+ * EMBL product only for the third
*/
- assertEquals(5, peptides.size());
+ assertEquals(6, peptides.size());
assertEquals("CAA30420.1", peptides.get(0).getName());
assertEquals("MLCF", peptides.get(0).getSequenceAsString());
assertEquals("UNIPROT|B0BCM4", peptides.get(1).getName());
assertEquals("MSSS", peptides.get(3).getSequenceAsString());
assertEquals("UNIPROT|B0BCM3", peptides.get(4).getName());
assertEquals("MSSS", peptides.get(4).getSequenceAsString());
+ assertEquals("CAA12345.6", peptides.get(5).getName());
+ assertEquals("MSS", peptides.get(5).getSequenceAsString());
/*
- * verify dna sequence has dbrefs with mappings to the peptide 'products'
+ * verify dna sequence has dbrefs with CDS mappings to the peptide 'products'
*/
+ MapList cds1Map = new MapList(new int[] { 57, 46 }, new int[] { 1, 4 },
+ 3, 1);
+ MapList cds2Map = new MapList(new int[] { 4, 15 }, new int[] { 1, 4 },
+ 3, 1);
+ MapList cds3Map = new MapList(new int[] { 4, 6, 10, 15 }, new int[] {
+ 1, 3 }, 3, 1);
DBRefEntry[] dbrefs = dna.getDBRefs();
- assertEquals(3, dbrefs.length);
+ assertEquals(4, dbrefs.length);
DBRefEntry dbRefEntry = dbrefs[0];
assertEquals("UNIPROT", dbRefEntry.getSource());
assertEquals("B0BCM4", dbRefEntry.getAccessionId());
assertSame(peptides.get(1), dbRefEntry.getMap().getTo());
- List<int[]> fromRanges = dbRefEntry.getMap().getMap().getFromRanges();
- assertEquals(1, fromRanges.size());
- assertEquals(57, fromRanges.get(0)[0]);
- assertEquals(46, fromRanges.get(0)[1]);
- List<int[]> toRanges = dbRefEntry.getMap().getMap().getToRanges();
- assertEquals(1, toRanges.size());
- assertEquals(1, toRanges.get(0)[0]);
- assertEquals(4, toRanges.get(0)[1]);
+ assertEquals(cds1Map, dbRefEntry.getMap().getMap());
dbRefEntry = dbrefs[1];
assertEquals("UNIPROT", dbRefEntry.getSource());
assertEquals("P0CE20", dbRefEntry.getAccessionId());
assertSame(peptides.get(2), dbRefEntry.getMap().getTo());
- fromRanges = dbRefEntry.getMap().getMap().getFromRanges();
- assertEquals(1, fromRanges.size());
- assertEquals(57, fromRanges.get(0)[0]);
- assertEquals(46, fromRanges.get(0)[1]);
- toRanges = dbRefEntry.getMap().getMap().getToRanges();
- assertEquals(1, toRanges.size());
- assertEquals(1, toRanges.get(0)[0]);
- assertEquals(4, toRanges.get(0)[1]);
+ assertEquals(cds1Map, dbRefEntry.getMap().getMap());
dbRefEntry = dbrefs[2];
assertEquals("UNIPROT", dbRefEntry.getSource());
assertEquals("B0BCM3", dbRefEntry.getAccessionId());
assertSame(peptides.get(4), dbRefEntry.getMap().getTo());
- fromRanges = dbRefEntry.getMap().getMap().getFromRanges();
- assertEquals(1, fromRanges.size());
- assertEquals(4, fromRanges.get(0)[0]);
- assertEquals(15, fromRanges.get(0)[1]);
- toRanges = dbRefEntry.getMap().getMap().getToRanges();
- assertEquals(1, toRanges.size());
- assertEquals(1, toRanges.get(0)[0]);
- assertEquals(4, toRanges.get(0)[1]);
+ assertEquals(cds2Map, dbRefEntry.getMap().getMap());
+
+ dbRefEntry = dbrefs[3];
+ assertEquals("EMBLCDSPROTEIN", dbRefEntry.getSource());
+ assertEquals("CAA12345.6", dbRefEntry.getAccessionId());
+ assertSame(peptides.get(5), dbRefEntry.getMap().getTo());
+ assertEquals(cds3Map, dbRefEntry.getMap().getMap());
+
+ /*
+ * verify peptides have dbrefs
+ * - to EMBL sequence (with inverse 1:3 cds mapping)
+ * - to EMBLCDS (with 1:3 mapping)
+ * - direct (no mapping) to other protein accessions
+ */
+ MapList proteinToCdsMap1 = new MapList(new int[] { 1, 4 }, new int[] {
+ 1, 12 }, 1, 3);
+ MapList proteinToCdsMap2 = new MapList(new int[] { 1, 3 }, new int[] {
+ 1, 9 }, 1, 3);
+
+ // dbrefs for first CDS EMBL product CAA30420.1
+ dbrefs = peptides.get(0).getDBRefs();
+ assertEquals(5, dbrefs.length);
+ assertEquals(DBRefSource.EMBL, dbrefs[0].getSource());
+ assertEquals("CAA30420.1", dbrefs[0].getAccessionId());
+ // TODO: verify getPrimaryDBRefs() for peptide products
+ assertEquals(cds1Map.getInverse(), dbrefs[0].getMap().getMap());
+ assertEquals(DBRefSource.EMBLCDS, dbrefs[1].getSource());
+ assertEquals("CAA30420.1", dbrefs[1].getAccessionId());
+ assertEquals(proteinToCdsMap1, dbrefs[1].getMap().getMap());
+ assertEquals(DBRefSource.EMBLCDSProduct, dbrefs[2].getSource());
+ assertEquals("CAA30420.1", dbrefs[2].getAccessionId());
+ assertNull(dbrefs[2].getMap());
+ assertEquals(new DBRefEntry(DBRefSource.UNIPROT, "2.1", "B0BCM4"),
+ dbrefs[3]);
+ assertNull(dbrefs[3].getMap());
+ assertEquals(new DBRefEntry(DBRefSource.UNIPROT, "0", "P0CE20"),
+ dbrefs[4]);
+ assertNull(dbrefs[4].getMap());
+
+ // dbrefs for first CDS first Uniprot xref
+ dbrefs = peptides.get(1).getDBRefs();
+ assertEquals(2, dbrefs.length);
+ assertEquals(new DBRefEntry(DBRefSource.UNIPROT, "2.1", "B0BCM4"),
+ dbrefs[0]);
+ assertNull(dbrefs[0].getMap());
+ assertEquals(DBRefSource.EMBL, dbrefs[1].getSource());
+ assertEquals("X07547", dbrefs[1].getAccessionId());
+ assertEquals(cds1Map.getInverse(), dbrefs[1].getMap().getMap());
+
+ // dbrefs for first CDS second Uniprot xref
+ dbrefs = peptides.get(2).getDBRefs();
+ assertEquals(2, dbrefs.length);
+ assertEquals(new DBRefEntry(DBRefSource.UNIPROT, "0", "P0CE20"),
+ dbrefs[0]);
+ assertNull(dbrefs[0].getMap());
+ assertEquals(DBRefSource.EMBL, dbrefs[1].getSource());
+ assertEquals("X07547", dbrefs[1].getAccessionId());
+ assertEquals(cds1Map.getInverse(), dbrefs[1].getMap().getMap());
+
+ // dbrefs for second CDS EMBL product CAA30421.1
+ dbrefs = peptides.get(3).getDBRefs();
+ assertEquals(4, dbrefs.length);
+ assertEquals(DBRefSource.EMBL, dbrefs[0].getSource());
+ assertEquals("CAA30421.1", dbrefs[0].getAccessionId());
+ assertEquals(cds2Map.getInverse(), dbrefs[0].getMap().getMap());
+ assertEquals(DBRefSource.EMBLCDS, dbrefs[1].getSource());
+ assertEquals("CAA30421.1", dbrefs[1].getAccessionId());
+ assertEquals(proteinToCdsMap1, dbrefs[1].getMap().getMap());
+ assertEquals(DBRefSource.EMBLCDSProduct, dbrefs[2].getSource());
+ assertEquals("CAA30421.1", dbrefs[2].getAccessionId());
+ assertNull(dbrefs[2].getMap());
+ assertEquals(new DBRefEntry(DBRefSource.UNIPROT, "0", "B0BCM3"),
+ dbrefs[3]);
+ assertNull(dbrefs[3].getMap());
+
+ // dbrefs for second CDS second Uniprot xref
+ dbrefs = peptides.get(4).getDBRefs();
+ assertEquals(2, dbrefs.length);
+ assertEquals(new DBRefEntry(DBRefSource.UNIPROT, "0", "B0BCM3"),
+ dbrefs[0]);
+ assertNull(dbrefs[0].getMap());
+ assertEquals(DBRefSource.EMBL, dbrefs[1].getSource());
+ assertEquals("X07547", dbrefs[1].getAccessionId());
+ assertEquals(cds2Map.getInverse(), dbrefs[1].getMap().getMap());
+
+ // dbrefs for third CDS inferred EMBL product CAA12345.6
+ dbrefs = peptides.get(5).getDBRefs();
+ assertEquals(3, dbrefs.length);
+ assertEquals(DBRefSource.EMBL, dbrefs[0].getSource());
+ assertEquals("CAA12345.6", dbrefs[0].getAccessionId());
+ assertEquals(cds3Map.getInverse(), dbrefs[0].getMap().getMap());
+ assertEquals(DBRefSource.EMBLCDS, dbrefs[1].getSource());
+ assertEquals("CAA12345.6", dbrefs[1].getAccessionId());
+ assertEquals(proteinToCdsMap2, dbrefs[1].getMap().getMap());
+ assertEquals(DBRefSource.EMBLCDSProduct, dbrefs[2].getSource());
+ assertEquals("CAA12345.6", dbrefs[2].getAccessionId());
+ assertNull(dbrefs[2].getMap());
+ }
+
+ @Test(groups = "Functional")
+ public void testAdjustForProteinLength()
+ {
+ int[] exons = new int[] { 11, 15, 21, 25, 31, 38 }; // 18 bp
+
+ // exact length match:
+ assertSame(exons, EmblEntry.adjustForProteinLength(6, exons));
+
+ // match if we assume exons include stop codon not in protein:
+ assertSame(exons, EmblEntry.adjustForProteinLength(5, exons));
+
+ // truncate last exon by 6bp
+ int[] truncated = EmblEntry.adjustForProteinLength(4, exons);
+ assertEquals("[11, 15, 21, 25, 31, 32]", Arrays.toString(truncated));
+
+ // remove last exon and truncate preceding by 1bp
+ truncated = EmblEntry.adjustForProteinLength(3, exons);
+ assertEquals("[11, 15, 21, 24]", Arrays.toString(truncated));
+
+ // exact removal of exon case:
+ exons = new int[] { 11, 15, 21, 27, 33, 38 }; // 18 bp
+ truncated = EmblEntry.adjustForProteinLength(4, exons);
+ assertEquals("[11, 15, 21, 27]", Arrays.toString(truncated));
+
+ // what if exons are too short for protein?
+ truncated = EmblEntry.adjustForProteinLength(7, exons);
+ assertSame(exons, truncated);
}
}
assertEquals("0", dbref.getVersion());
/*
- * two sequence features for CDS
+ * three sequence features for CDS
*/
- assertEquals(2, entry.getFeatures().size());
+ assertEquals(3, entry.getFeatures().size());
/*
* first CDS
*/
assertEquals("MSSS", q.getValues()[0]);
/*
+ * third CDS
+ */
+ ef = entry.getFeatures().get(2);
+ assertEquals("CDS", ef.getName());
+ assertEquals("join(4..6,10..15)", ef.getLocation());
+ assertNull(ef.getDbRefs());
+ assertEquals(2, ef.getQualifiers().size());
+ q = ef.getQualifiers().get(0);
+ assertEquals("protein_id", q.getName());
+ assertEquals(1, q.getValues().length);
+ assertEquals("CAA12345.6", q.getValues()[0]);
+ q = ef.getQualifiers().get(1);
+ assertEquals("translation", q.getName());
+ assertEquals(1, q.getValues().length);
+ assertEquals("MSS", q.getValues()[0]);
+
+ /*
* Sequence - verify newline not converted to space (JAL-2029)
*/
EmblSequence seq = entry.getSequence();
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
package jalview.datamodel.xdb.embl;
import java.io.StringReader;
+ "<qualifier name=\"translation\"><value>MSSS</value></qualifier>"
+ "</feature>"
/*
+ * third CDS is made up - has no xref - code should synthesize
+ * one to an assumed EMBLCDSPROTEIN accession
+ */
+ + "<feature name=\"CDS\" location=\"join(4..6,10..15)\">"
+ + "<qualifier name=\"protein_id\"><value>CAA12345.6</value></qualifier>"
+ + "<qualifier name=\"translation\"><value>MSS</value></qualifier>"
+ + "</feature>"
+ /*
* sequence (modified for test purposes)
* emulates EMBL XML 1.2 which splits sequence data every 60 characters
* see EmblSequence.setSequence
--- /dev/null
+package jalview.ext.android;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.fail;
+
+import org.testng.annotations.Test;
+
+/*
+ * Tests for SparseIntArray. Unlike SparseShortArray, SparseIntArray does not throw
+ * any exception for overflow.
+ */
+public class SparseIntArrayTest
+{
+ @Test(groups = "Functional")
+ public void testPut()
+ {
+ SparseIntArray counter = new SparseIntArray();
+
+ /*
+ * either key or value may be in the range of int
+ */
+ counter.put(Integer.MAX_VALUE, Integer.MIN_VALUE);
+ counter.put(Integer.MIN_VALUE, Integer.MAX_VALUE);
+ assertEquals(counter.get(Integer.MAX_VALUE), Integer.MIN_VALUE);
+ assertEquals(counter.get(Integer.MIN_VALUE), Integer.MAX_VALUE);
+ }
+
+ @Test(groups = "Functional")
+ public void testAdd()
+ {
+ SparseIntArray counter = new SparseIntArray();
+
+ assertEquals(counter.add('P', 2), 2);
+ assertEquals(counter.add('P', 3), 5);
+ counter.put('Q', 7);
+ assertEquals(counter.add('Q', 4), 11);
+
+ counter.put('x', Integer.MAX_VALUE);
+ try
+ {
+ counter.add('x', 1);
+ fail("expected exception");
+ } catch (ArithmeticException e)
+ {
+ // expected
+ }
+
+ counter.put('y', Integer.MIN_VALUE);
+ try
+ {
+ counter.add('y', -1);
+ fail("expected exception");
+ } catch (ArithmeticException e)
+ {
+ // expected
+ }
+ }
+
+ @Test(groups = "Functional")
+ public void testCheckOverflow()
+ {
+ // things that don't overflow:
+ SparseIntArray.checkOverflow(Integer.MAX_VALUE, 0);
+ SparseIntArray.checkOverflow(Integer.MAX_VALUE, -1);
+ SparseIntArray.checkOverflow(Integer.MAX_VALUE, Integer.MIN_VALUE);
+ SparseIntArray.checkOverflow(Integer.MAX_VALUE, -Integer.MAX_VALUE);
+ SparseIntArray.checkOverflow(0, -Integer.MAX_VALUE);
+ SparseIntArray.checkOverflow(0, Integer.MIN_VALUE);
+ SparseIntArray.checkOverflow(Integer.MIN_VALUE, 0);
+ SparseIntArray.checkOverflow(Integer.MIN_VALUE, 1);
+ SparseIntArray.checkOverflow(Integer.MIN_VALUE, Integer.MAX_VALUE);
+
+ // and some that do
+ try
+ {
+ SparseIntArray.checkOverflow(Integer.MAX_VALUE, 1);
+ fail("expected exception");
+ } catch (ArithmeticException e)
+ {
+ // expected
+ }
+ try
+ {
+ SparseIntArray.checkOverflow(Integer.MAX_VALUE - 1, 2);
+ fail("expected exception");
+ } catch (ArithmeticException e)
+ {
+ // expected
+ }
+ try
+ {
+ SparseIntArray.checkOverflow(1, Integer.MAX_VALUE);
+ fail("expected exception");
+ } catch (ArithmeticException e)
+ {
+ // expected
+ }
+ try
+ {
+ SparseIntArray.checkOverflow(Integer.MIN_VALUE, -1);
+ fail("expected exception");
+ } catch (ArithmeticException e)
+ {
+ // expected
+ }
+ try
+ {
+ SparseIntArray.checkOverflow(Integer.MIN_VALUE + 1, -2);
+ fail("expected exception");
+ } catch (ArithmeticException e)
+ {
+ // expected
+ }
+ try
+ {
+ SparseIntArray.checkOverflow(-1, Integer.MIN_VALUE);
+ fail("expected exception");
+ } catch (ArithmeticException e)
+ {
+ // expected
+ }
+ }
+
+}
--- /dev/null
+package jalview.ext.android;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.fail;
+
+import org.testng.annotations.Test;
+
+public class SparseShortArrayTest
+{
+ @Test(groups = "Functional")
+ public void testPut()
+ {
+ SparseShortArray counter = new SparseShortArray();
+
+ /*
+ * either key or value may be in the range of short
+ */
+ counter.put(Short.MAX_VALUE, Short.MIN_VALUE);
+ counter.put(Short.MIN_VALUE, Short.MAX_VALUE);
+
+ // put a too large value
+ try
+ {
+ counter.put(0, Short.MAX_VALUE + 1);
+ fail("Expected exception");
+ } catch (ArithmeticException e)
+ {
+ // expected;
+ }
+
+ // put a too small value
+ try
+ {
+ counter.put(1, Short.MIN_VALUE - 1);
+ fail("Expected exception");
+ } catch (ArithmeticException e)
+ {
+ // expected;
+ }
+
+ // put a too large key
+ try
+ {
+ counter.put(Short.MAX_VALUE + 1, 0);
+ fail("Expected exception");
+ } catch (ArithmeticException e)
+ {
+ // expected;
+ }
+
+ // put a too small key
+ try
+ {
+ counter.put(Short.MIN_VALUE - 1, 2);
+ fail("Expected exception");
+ } catch (ArithmeticException e)
+ {
+ // expected;
+ }
+ }
+
+ @Test(groups = "Functional")
+ public void testAdd()
+ {
+ SparseShortArray counter = new SparseShortArray();
+
+ assertEquals(counter.add('P', 2), 2);
+ assertEquals(counter.add('P', 3), 5);
+ counter.put('Q', 7);
+ assertEquals(counter.add('Q', 4), 11);
+
+ // increment giving overflow
+ counter.put('x', Short.MAX_VALUE);
+ try
+ {
+ counter.add('x', 1);
+ fail("Expected exception");
+ } catch (ArithmeticException e)
+ {
+ // expected;
+ }
+
+ // decrement giving underflow
+ counter.put('y', Short.MIN_VALUE);
+ try
+ {
+ counter.add('y', -1);
+ fail("Expected exception");
+ } catch (ArithmeticException e)
+ {
+ // expected;
+ }
+ }
+}
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
package jalview.ext.ensembl;
import static org.testng.AssertJUnit.assertEquals;
{
SequenceOntologyFactory.setInstance(null);
}
+
/**
* Test that the cdna part of genomic sequence is correctly identified by
* 'exon' features (or subtypes) - reverse strand case.
genomic.setStart(10000);
genomic.setEnd(50000);
String transcriptId = "ABC123";
-
+
// exon at (start+10000) length 501
SequenceFeature sf = new SequenceFeature("exon", "", 20000, 20500, 0f,
null);
sf.setValue("Parent", "transcript:" + transcriptId);
sf.setStrand("+");
genomic.addSequenceFeature(sf);
-
+
// exon (sub-type) at (start + exon_variant) length 101
sf = new SequenceFeature("coding_exon", "", 10500, 10600, 0f, null);
sf.setValue("Parent", "transcript:" + transcriptId);
sf.setStrand("+");
genomic.addSequenceFeature(sf);
-
+
// exon belonging to a different transcript doesn't count
sf = new SequenceFeature("exon", "", 11500, 12600, 0f, null);
sf.setValue("Parent", "transcript:anotherOne");
genomic.addSequenceFeature(sf);
-
+
// transcript feature doesn't count
sf = new SequenceFeature("transcript", "", 10000, 50000, 0f, null);
sf.setStrand("-"); // weird but ignored
genomic.addSequenceFeature(sf);
-
+
MapList ranges = testee.getGenomicRangesFromFeatures(genomic,
transcriptId, 23);
List<int[]> fromRanges = ranges.getFromRanges();
genomic.setStart(10000);
genomic.setEnd(50000);
String transcriptId = "ABC123";
-
+
SequenceFeature sf = new SequenceFeature("exon", "", 20000, 20500, 0f,
null);
sf.setValue("Parent", "transcript:" + transcriptId);
sf.setStrand("-");
genomic.addSequenceFeature(sf);
-
+
sf = new SequenceFeature("coding_exon", "", 10500, 10600, 0f, null);
sf.setValue("Parent", "transcript:" + transcriptId);
sf.setStrand("+");
genomic.addSequenceFeature(sf);
-
+
MapList ranges = testee.getGenomicRangesFromFeatures(genomic,
transcriptId, 23);
assertNull(ranges);
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
package jalview.ext.ensembl;
import static org.testng.AssertJUnit.assertEquals;
genomic.setStart(10000);
genomic.setEnd(50000);
String transcriptId = "ABC123";
-
+
// CDS at (start+10000) length 501
SequenceFeature sf = new SequenceFeature("CDS", "", 20000, 20500, 0f,
null);
sf.setValue("Parent", "transcript:" + transcriptId);
sf.setStrand("+");
genomic.addSequenceFeature(sf);
-
+
// CDS (sub-type) at (start + 10500) length 101
sf = new SequenceFeature("CDS_predicted", "", 10500, 10600, 0f, null);
sf.setValue("Parent", "transcript:" + transcriptId);
sf.setStrand("+");
genomic.addSequenceFeature(sf);
-
+
// CDS belonging to a different transcript doesn't count
sf = new SequenceFeature("CDS", "", 11500, 12600, 0f, null);
sf.setValue("Parent", "transcript:anotherOne");
genomic.addSequenceFeature(sf);
-
+
// exon feature doesn't count
sf = new SequenceFeature("exon", "", 10000, 50000, 0f, null);
genomic.addSequenceFeature(sf);
// mRNA_region feature doesn't count (parent of CDS)
sf = new SequenceFeature("mRNA_region", "", 10000, 50000, 0f, null);
genomic.addSequenceFeature(sf);
-
+
MapList ranges = testee.getGenomicRangesFromFeatures(genomic,
transcriptId, 23);
List<int[]> fromRanges = ranges.getFromRanges();
{
String accId = "ABC123";
EnsemblCds testee = new EnsemblCds();
-
- SequenceFeature sf = new SequenceFeature("CDS", "", 20000,
- 20500, 0f, null);
+
+ SequenceFeature sf = new SequenceFeature("CDS", "", 20000, 20500, 0f,
+ null);
assertFalse(testee.retainFeature(sf, accId));
-
+
sf.setType("CDS_predicted");
assertFalse(testee.retainFeature(sf, accId));
-
+
// other feature with no parent is retained
sf.setType("sequence_variant");
assertTrue(testee.retainFeature(sf, accId));
-
+
// other feature with desired parent is retained
sf.setValue("Parent", "transcript:" + accId);
assertTrue(testee.retainFeature(sf, accId));
-
+
// feature with wrong parent is not retained
sf.setValue("Parent", "transcript:XYZ");
assertFalse(testee.retainFeature(sf, accId));
{
String accId = "ABC123";
EnsemblCds testee = new EnsemblCds();
-
+
// cds with no parent not valid
SequenceFeature sf = new SequenceFeature("CDS", "", 1, 2, 0f, null);
assertFalse(testee.identifiesSequence(sf, accId));
-
+
// cds with wrong parent not valid
sf.setValue("Parent", "transcript:XYZ");
assertFalse(testee.identifiesSequence(sf, accId));
-
+
// cds with right parent is valid
sf.setValue("Parent", "transcript:" + accId);
assertTrue(testee.identifiesSequence(sf, accId));
-
+
// cds sub-type with right parent is valid
sf.setType("CDS_predicted");
assertTrue(testee.identifiesSequence(sf, accId));
-
+
// transcript not valid:
sf.setType("transcript");
assertFalse(testee.identifiesSequence(sf, accId));
-
+
// exon not valid:
sf.setType("exon");
assertFalse(testee.identifiesSequence(sf, accId));
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
package jalview.ext.ensembl;
import static org.testng.AssertJUnit.assertEquals;
genomic.addSequenceFeature(sf1);
// transcript sub-type feature
- SequenceFeature sf2 = new SequenceFeature("snRNA", "", 20000,
- 20500, 0f, null);
+ SequenceFeature sf2 = new SequenceFeature("snRNA", "", 20000, 20500,
+ 0f, null);
sf2.setValue("Parent", "gene:" + geneId);
sf2.setValue("transcript_id", "transcript2");
genomic.addSequenceFeature(sf2);
{
String geneId = "ABC123";
EnsemblGene testee = new EnsemblGene();
- SequenceFeature sf = new SequenceFeature("gene", "", 20000,
- 20500, 0f, null);
+ SequenceFeature sf = new SequenceFeature("gene", "", 20000, 20500, 0f,
+ null);
sf.setValue("ID", "gene:" + geneId);
assertFalse(testee.retainFeature(sf, geneId));
{
String accId = "ABC123";
EnsemblGene testee = new EnsemblGene();
-
+
// gene with no ID not valid
SequenceFeature sf = new SequenceFeature("gene", "", 1, 2, 0f, null);
assertFalse(testee.identifiesSequence(sf, accId));
-
+
// gene with wrong ID not valid
sf.setValue("ID", "gene:XYZ");
assertFalse(testee.identifiesSequence(sf, accId));
-
+
// gene with right ID is valid
sf.setValue("ID", "gene:" + accId);
assertTrue(testee.identifiesSequence(sf, accId));
-
+
// gene sub-type with right ID is valid
sf.setType("snRNA_gene");
assertTrue(testee.identifiesSequence(sf, accId));
-
+
// transcript not valid:
sf.setType("transcript");
assertFalse(testee.identifiesSequence(sf, accId));
-
+
// exon not valid:
sf.setType("exon");
assertFalse(testee.identifiesSequence(sf, accId));
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
package jalview.ext.ensembl;
import static org.testng.AssertJUnit.assertEquals;
genomic.setStart(10000);
genomic.setEnd(50000);
String transcriptId = "ABC123";
-
+
// transcript at (start+10000) length 501
SequenceFeature sf = new SequenceFeature("transcript", "", 20000,
- 20500, 0f,
- null);
+ 20500, 0f, null);
sf.setValue("ID", "transcript:" + transcriptId);
sf.setStrand("+");
genomic.addSequenceFeature(sf);
-
+
// transcript (sub-type) at (start + 10500) length 101
sf = new SequenceFeature("ncRNA", "", 10500, 10600, 0f, null);
sf.setValue("ID", "transcript:" + transcriptId);
sf.setValue("ID", "transcript:" + transcriptId);
sf.setStrand("+");
genomic.addSequenceFeature(sf);
-
+
// transcript with a different ID doesn't count
sf = new SequenceFeature("transcript", "", 11500, 12600, 0f, null);
sf.setValue("ID", "transcript:anotherOne");
genomic.addSequenceFeature(sf);
-
+
// parent of transcript feature doesn't count
sf = new SequenceFeature("gene_member_region", "", 10000, 50000, 0f,
null);
SequenceFeature sf = new SequenceFeature("transcript", "", 20000,
20500, 0f, null);
assertFalse(testee.retainFeature(sf, accId));
-
+
sf.setType("mature_transcript");
assertFalse(testee.retainFeature(sf, accId));
-
+
sf.setType("NMD_transcript_variant");
assertFalse(testee.retainFeature(sf, accId));
-
+
// other feature with no parent is kept
sf.setType("anything");
assertTrue(testee.retainFeature(sf, accId));
{
String accId = "ABC123";
EnsemblGenome testee = new EnsemblGenome();
-
+
// transcript with no ID not valid
SequenceFeature sf = new SequenceFeature("transcript", "", 1, 2, 0f,
null);
assertFalse(testee.identifiesSequence(sf, accId));
-
+
// transcript with wrong ID not valid
sf.setValue("ID", "transcript");
assertFalse(testee.identifiesSequence(sf, accId));
-
+
// transcript with right ID is valid
sf.setValue("ID", "transcript:" + accId);
assertTrue(testee.identifiesSequence(sf, accId));
-
+
// transcript sub-type with right ID is valid
sf.setType("ncRNA");
assertTrue(testee.identifiesSequence(sf, accId));
// Ensembl treats NMD_transcript_variant as if a transcript
sf.setType("NMD_transcript_variant");
assertTrue(testee.identifiesSequence(sf, accId));
-
+
// gene not valid:
sf.setType("gene");
assertFalse(testee.identifiesSequence(sf, accId));
-
+
// exon not valid:
sf.setType("exon");
assertFalse(testee.identifiesSequence(sf, accId));
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
package jalview.ext.ensembl;
import static org.testng.AssertJUnit.assertEquals;
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
package jalview.ext.ensembl;
import jalview.datamodel.AlignmentI;
{
EnsemblRestClient sf = new EnsemblRestClient()
{
-
+
@Override
public String getDbName()
{
return null;
}
-
+
@Override
public AlignmentI getSequenceRecords(String queries) throws Exception
{
return null;
}
-
+
@Override
protected URL getUrl(List<String> ids) throws MalformedURLException
{
return null;
}
-
+
@Override
protected boolean useGetRequest()
{
return false;
}
-
+
@Override
protected String getRequestMimeType(boolean b)
{
return null;
}
-
+
@Override
protected String getResponseMimeType()
{
return null;
}
-
+
};
boolean isAvailable = sf.isEnsemblAvailable();
if (isAvailable)
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
package jalview.ext.ensembl;
import jalview.datamodel.SequenceFeature;
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
package jalview.ext.ensembl;
import static org.testng.AssertJUnit.assertEquals;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
-
public class EnsemblSeqProxyTest
{
private static final Object[][] allSeqs = new Object[][] {
}
@Test(dataProvider = "ens_seqs", suiteName = "live")
- public void testGetOneSeqs(EnsemblRestClient proxy, String sq, String fastasq)
- throws Exception
+ public void testGetOneSeqs(EnsemblRestClient proxy, String sq,
+ String fastasq) throws Exception
{
FileParse fp = proxy.getSequenceReader(Arrays
- .asList(new String[]
- { sq }));
+ .asList(new String[] { sq }));
SequenceI[] sqs = new FastaFile(fp).getSeqsAsArray();
FastaFile trueRes = new FastaFile(fastasq, AppletFormatAdapter.PASTE);
SequenceI[] trueSqs = trueRes.getSeqsAsArray();
"Sequences differ for " + tr.getName() + "\n" + "Exp:"
+ tr.getSequenceAsString() + "\n" + "Got:"
+ rseq[0].getSequenceAsString());
-
+
}
}
EnsemblSeqProxy.sortFeatures(sfs, false);
assertArrayEquals(new SequenceFeature[] { sf1, sf3, sf2, sf4 }, sfs);
}
-}
\ No newline at end of file
+}
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
package jalview.ext.ensembl;
import static org.testng.AssertJUnit.assertEquals;
+import static org.testng.AssertJUnit.assertFalse;
import jalview.datamodel.DBRefEntry;
@Test(groups = "Functional")
public void testGetCrossReferences()
{
+ String dbName = "ENSEMBL";
+ String dbVers = "0.6.2b1";
System.out.println(JSON);
- EnsemblXref testee = new EnsemblXref("http://rest.ensembl.org")
+ EnsemblXref testee = new EnsemblXref("http://rest.ensembl.org", dbName,
+ dbVers)
{
@Override
protected BufferedReader getHttpResponse(URL url, List<String> ids)
assertEquals(2, dbrefs.size());
assertEquals("CCDS", dbrefs.get(0).getSource());
assertEquals("CCDS5863", dbrefs.get(0).getAccessionId());
+ assertFalse(dbrefs.get(0).isPrimaryCandidate());
+ assertEquals(dbName + ":" + dbVers, dbrefs.get(0).getVersion());
// Uniprot name should get converted to Jalview canonical form
assertEquals("UNIPROT", dbrefs.get(1).getSource());
assertEquals("P15056", dbrefs.get(1).getAccessionId());
+ assertEquals(dbName + ":" + dbVers, dbrefs.get(1).getVersion());
+ assertFalse(dbrefs.get(1).isPrimaryCandidate());
}
}
-/**
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
*
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
*/
package jalview.ext.htsjdk;
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
package jalview.ext.jmol;
import jalview.datamodel.Alignment;
package jalview.ext.jmol;
import static org.testng.AssertJUnit.assertEquals;
+import static org.testng.AssertJUnit.assertNotNull;
import static org.testng.AssertJUnit.assertTrue;
import jalview.bin.Cache;
import jalview.gui.AlignFrame;
import jalview.io.AppletFormatAdapter;
import jalview.io.FileLoader;
+import jalview.structure.StructureImportSettings;
+import jalview.structure.StructureImportSettings.StructureParser;
import java.util.Vector;
//@formatter:off
// a modified and very cut-down extract of 4UJ4
- String pdbWithChainBreak =
+ String pastePDBDataWithChainBreak =
"HEADER TRANSPORT PROTEIN 08-APR-15 4UJ4\n" +
// chain B has missing residues; these should all go in the same sequence:
"ATOM 1909 CA VAL B 358 21.329 -19.739 -67.740 1.00201.05 C\n" +
@BeforeMethod(alwaysRun = true)
public void setUp()
{
+ Cache.loadProperties("test/jalview/io/testProps.jvprops");
Cache.applicationProperties.setProperty("STRUCT_FROM_PDB",
Boolean.TRUE.toString());
+ Cache.applicationProperties.setProperty("ADD_TEMPFACT_ANN",
+ Boolean.FALSE.toString());
Cache.applicationProperties.setProperty("ADD_SS_ANN",
Boolean.TRUE.toString());
+ StructureImportSettings.setDefaultStructureFileFormat("PDB");
+ StructureImportSettings
+ .setDefaultPDBFileParser(StructureParser.JALVIEW_PARSER);
}
@Test(groups = { "Functional" })
{
PDBfile mctest = new PDBfile(false, false, false, pdbStr,
AppletFormatAdapter.FILE);
- JmolParser jtest = new JmolParser(false, false, false, pdbStr,
- jalview.io.AppletFormatAdapter.FILE);
+ JmolParser jtest = new JmolParser(pdbStr, AppletFormatAdapter.FILE);
Vector<SequenceI> seqs = jtest.getSeqs(), mcseqs = mctest.getSeqs();
assertTrue(
validateSecStrRows(al);
}
}
+
}
private void validateSecStrRows(AlignmentI al)
private void checkFirstAAIsAssoc(SequenceI sq)
{
- assertTrue("No secondary structure assigned for protein sequence.",
+ assertTrue("No secondary structure assigned for protein sequence for "
+ + sq.getName(),
sq.getAnnotation() != null && sq.getAnnotation().length >= 1
&& sq.getAnnotation()[0].hasIcons);
assertTrue(
@Test(groups = { "Functional" })
public void testParse_missingResidues() throws Exception
{
- PDBfile mctest = new PDBfile(false, false, false, pdbWithChainBreak,
+ PDBfile mctest = new PDBfile(false, false, false,
+ pastePDBDataWithChainBreak, AppletFormatAdapter.PASTE);
+ JmolParser jtest = new JmolParser(pastePDBDataWithChainBreak,
AppletFormatAdapter.PASTE);
- boolean annotFromStructure = false;
- boolean localSecondaryStruct = false;
- boolean serviceSecondaryStruct = false;
- JmolParser jtest = new JmolParser(annotFromStructure,
- localSecondaryStruct, serviceSecondaryStruct,
- pdbWithChainBreak,
- jalview.io.AppletFormatAdapter.PASTE);
Vector<SequenceI> seqs = jtest.getSeqs();
Vector<SequenceI> mcseqs = mctest.getSeqs();
{
PDBfile mctest = new PDBfile(false, false, false, pdbWithAltLoc,
AppletFormatAdapter.PASTE);
- boolean annotFromStructure = false;
- boolean localSecondaryStruct = false;
- boolean serviceSecondaryStruct = false;
- JmolParser jtest = new JmolParser(annotFromStructure,
- localSecondaryStruct, serviceSecondaryStruct, pdbWithAltLoc,
- jalview.io.AppletFormatAdapter.PASTE);
+ JmolParser jtest = new JmolParser(pdbWithAltLoc,
+ AppletFormatAdapter.PASTE);
Vector<SequenceI> seqs = jtest.getSeqs();
Vector<SequenceI> mcseqs = mctest.getSeqs();
-
+
assertEquals("Failed to find 1 sequence\n", 1, seqs.size());
assertEquals("Failed to find 1 sequence\n", 1, mcseqs.size());
assertEquals("ALC", seqs.get(0).getSequenceAsString());
assertEquals('H', structCode[4]);
assertEquals('E', structCode[5]);
}
+
+ @Test(groups = "Functional")
+ public void testLocalPDBId() throws Exception
+ {
+ JmolParser structureData;
+ /*
+ * reads a local structure
+ */
+ structureData = new JmolParser("examples/testdata/localstruct.pdb",
+ AppletFormatAdapter.FILE);
+ assertNotNull(structureData);
+ /*
+ * local structure files should yield a false ID based on the filename
+ */
+ assertNotNull(structureData.getId());
+ assertEquals(structureData.getId(), "localstruct.pdb");
+ assertNotNull(structureData.getSeqs());
+ /*
+ * the ID is also the group for features derived from structure data
+ */
+ assertNotNull(structureData.getSeqs().get(0).getSequenceFeatures()[0].featureGroup);
+ assertEquals(
+ structureData.getSeqs().get(0).getSequenceFeatures()[0].featureGroup,
+ "localstruct.pdb");
+
+ }
}
--- /dev/null
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
+package jalview.ext.jmol;
+
+import jalview.datamodel.SequenceI;
+import jalview.io.AppletFormatAdapter;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.Vector;
+
+import MCview.PDBfile;
+
+/**
+ * This is not a unit test, rather it is a bulk End-to-End scan for sequences
+ * consistency for PDB files parsed with JmolParser vs. Jalview's PDBfile
+ * parser. The directory of PDB files to test must be provided in the launch
+ * args.
+ *
+ * @author tcnofoegbu
+ *
+ */
+public class JmolVsJalviewPDBParserEndToEndTest
+{
+
+ public static void main(String[] args)
+ {
+ if (args == null || args[0] == null)
+ {
+ System.err
+ .println("You must provide a PDB directory in the launch argument");
+ return;
+ }
+
+ // args[0] must provide the directory of PDB files to run the test with
+ String testDir = args[0];
+ System.out.println("PDB directory : " + testDir);
+ File pdbDir = new File(testDir);
+ String testFiles[] = pdbDir.list();
+ testFileParser(testDir, testFiles);
+ }
+
+ public static void testFileParser(String testDir, String[] testFiles)
+ {
+ Set<String> failedFiles = new HashSet<String>();
+ int totalSeqScanned = 0, totalFail = 0;
+ for (String pdbStr : testFiles)
+ {
+ String testFile = testDir + "/" + pdbStr;
+ PDBfile mctest = null;
+ JmolParser jtest = null;
+ try
+ {
+ mctest = new PDBfile(false, false, false, testFile,
+ AppletFormatAdapter.FILE);
+ jtest = new JmolParser(testFile, AppletFormatAdapter.FILE);
+ } catch (IOException e)
+ {
+ System.err.println("Exception thrown while parsing : " + pdbStr);
+ }
+ Vector<SequenceI> seqs = jtest.getSeqs();
+ Vector<SequenceI> mcseqs = mctest.getSeqs();
+
+ for (SequenceI sq : seqs)
+ {
+ try
+ {
+ String testSeq = mcseqs.remove(0).getSequenceAsString();
+ if (!sq.getSequenceAsString().equals(testSeq))
+ {
+ ++totalFail;
+ System.err.println("Test Failed for " + pdbStr + ". Diff:");
+ System.err.println(sq.getSequenceAsString());
+ System.err.println(testSeq);
+ failedFiles.add(pdbStr);
+ }
+ ++totalSeqScanned;
+ } catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ }
+ }
+ int count = 0;
+
+ System.out.println("\n\nTotal sequence Scanned : " + totalSeqScanned);
+ System.out.println("Total sequence passed : "
+ + (totalSeqScanned - totalFail));
+ System.out.println("Total sequence failed : " + totalFail);
+ System.out
+ .println("Success rate: "
+ + ((totalSeqScanned - totalFail) * 100)
+ / totalSeqScanned + "%");
+ System.out.println("\nList of " + failedFiles.size()
+ + " file(s) with sequence diffs:");
+ for (String problemFile : failedFiles)
+ {
+ System.out.println(++count + ". " + problemFile);
+ }
+ }
+}
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
package jalview.ext.so;
import static org.testng.AssertJUnit.assertFalse;
private SequenceOntologyI so;
@BeforeClass(alwaysRun = true)
- public void setUp() {
+ public void setUp()
+ {
long now = System.currentTimeMillis();
try
{
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
package jalview.fts.core;
import jalview.fts.api.FTSDataColumnI;
@Test(groups = { "Functional" })
public void getAllDefaulDisplayedDataColumns()
{
- Assert.assertNotNull(ftsRestClient.getAllDefaultDisplayedFTSDataColumns());
+ Assert.assertNotNull(ftsRestClient
+ .getAllDefaultDisplayedFTSDataColumns());
Assert.assertTrue(!ftsRestClient.getAllDefaultDisplayedFTSDataColumns()
.isEmpty());
- Assert.assertEquals(ftsRestClient.getAllDefaultDisplayedFTSDataColumns()
- .size(), 7);
+ Assert.assertEquals(ftsRestClient
+ .getAllDefaultDisplayedFTSDataColumns().size(), 7);
}
@Test(groups = { "Functional" })
"id,entry name,protein names,genes,organism,reviewed,length");
}
-
@Test(groups = { "Functional" })
public void getAllFTSDataColumns()
{
{
wantedFields.add(PDBFTSRestClient.getInstance()
.getDataColumnByNameOrCode("molecule_type"));
- wantedFields
-.add(PDBFTSRestClient.getInstance()
+ wantedFields.add(PDBFTSRestClient.getInstance()
.getDataColumnByNameOrCode("pdb_id"));
wantedFields.add(PDBFTSRestClient.getInstance()
.getDataColumnByNameOrCode("genus"));
- wantedFields
-.add(PDBFTSRestClient.getInstance()
+ wantedFields.add(PDBFTSRestClient.getInstance()
.getDataColumnByNameOrCode("gene_name"));
wantedFields.add(PDBFTSRestClient.getInstance()
.getDataColumnByNameOrCode("title"));
{
wantedFields.add(PDBFTSRestClient.getInstance()
.getDataColumnByNameOrCode("molecule_type"));
- wantedFields
-.add(PDBFTSRestClient.getInstance()
+ wantedFields.add(PDBFTSRestClient.getInstance()
.getDataColumnByNameOrCode("pdb_id"));
wantedFields.add(PDBFTSRestClient.getInstance()
.getDataColumnByNameOrCode("genus"));
- wantedFields
-.add(PDBFTSRestClient.getInstance()
+ wantedFields.add(PDBFTSRestClient.getInstance()
.getDataColumnByNameOrCode("gene_name"));
wantedFields.add(PDBFTSRestClient.getInstance()
.getDataColumnByNameOrCode("title"));
{
wantedFields.add(PDBFTSRestClient.getInstance()
.getDataColumnByNameOrCode("molecule_type"));
- wantedFields
-.add(PDBFTSRestClient.getInstance()
+ wantedFields.add(PDBFTSRestClient.getInstance()
.getDataColumnByNameOrCode("pdb_id"));
wantedFields.add(PDBFTSRestClient.getInstance()
.getDataColumnByNameOrCode("genus"));
- wantedFields
-.add(PDBFTSRestClient.getInstance()
+ wantedFields.add(PDBFTSRestClient.getInstance()
.getDataColumnByNameOrCode("gene_name"));
wantedFields.add(PDBFTSRestClient.getInstance()
.getDataColumnByNameOrCode("title"));
assertEquals(expectedErrorMsg, parsedErrorResponse);
}
- @Test(
- groups = { "External" },
- expectedExceptions = Exception.class)
+ @Test(groups = { "External" }, expectedExceptions = Exception.class)
public void testForExpectedRuntimeException() throws Exception
{
List<FTSDataColumnI> wantedFields = new ArrayList<FTSDataColumnI>();
PDBFTSRestClient.getInstance().executeRequest(request);
}
- // JBP: Is this actually external ? Looks like it is mocked
+ // JBP: Is this actually external ? Looks like it is mocked
@Test(groups = { "External" })
public void parsePDBJsonResponseTest()
{
{
wantedFields.add(PDBFTSRestClient.getInstance()
.getDataColumnByNameOrCode("molecule_type"));
- wantedFields
-.add(PDBFTSRestClient.getInstance()
+ wantedFields.add(PDBFTSRestClient.getInstance()
.getDataColumnByNameOrCode("pdb_id"));
wantedFields.add(PDBFTSRestClient.getInstance()
.getDataColumnByNameOrCode("genus"));
- wantedFields
-.add(PDBFTSRestClient.getInstance()
+ wantedFields.add(PDBFTSRestClient.getInstance()
.getDataColumnByNameOrCode("gene_name"));
wantedFields.add(PDBFTSRestClient.getInstance()
.getDataColumnByNameOrCode("title"));
.getDataColumnByNameOrCode("molecule_type"));
wantedFields.add(PDBFTSRestClient.getInstance()
.getDataColumnByNameOrCode("genus"));
- wantedFields
-.add(PDBFTSRestClient.getInstance()
+ wantedFields.add(PDBFTSRestClient.getInstance()
.getDataColumnByNameOrCode("gene_name"));
wantedFields.add(PDBFTSRestClient.getInstance()
.getDataColumnByNameOrCode("title"));
- wantedFields
-.add(PDBFTSRestClient.getInstance()
+ wantedFields.add(PDBFTSRestClient.getInstance()
.getDataColumnByNameOrCode("pdb_id"));
} catch (Exception e)
{
}
try
{
- assertEquals(5,
- PDBFTSRestClient.getInstance()
+ assertEquals(5, PDBFTSRestClient.getInstance()
.getPrimaryKeyColumIndex(wantedFields, true));
- assertEquals(4,
- PDBFTSRestClient.getInstance()
+ assertEquals(4, PDBFTSRestClient.getInstance()
.getPrimaryKeyColumIndex(wantedFields, false));
} catch (Exception e)
{
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
package jalview.gui;
import static org.testng.AssertJUnit.assertEquals;
* [1-3], [6-8] base zero
*/
assertTrue(af.hideFeatureColumns("Turn", true));
- hidden = af.getViewport().getColumnSelection()
- .getHiddenColumns();
+ hidden = af.getViewport().getColumnSelection().getHiddenColumns();
assertEquals(2, hidden.size());
assertEquals(1, hidden.get(0)[0]);
assertEquals(3, hidden.get(0)[1]);
import static org.testng.AssertJUnit.assertSame;
import static org.testng.AssertJUnit.assertTrue;
+import jalview.bin.Cache;
+import jalview.bin.Jalview;
import jalview.datamodel.AlignedCodonFrame;
import jalview.datamodel.Alignment;
+import jalview.datamodel.AlignmentAnnotation;
import jalview.datamodel.AlignmentI;
+import jalview.datamodel.Annotation;
import jalview.datamodel.PDBEntry;
import jalview.datamodel.PDBEntry.Type;
import jalview.datamodel.Sequence;
import jalview.datamodel.SequenceI;
import jalview.io.FileLoader;
import jalview.io.FormatAdapter;
+import jalview.schemes.ColourSchemeI;
+import jalview.schemes.PIDColourScheme;
import jalview.structure.StructureSelectionManager;
+import jalview.util.MapList;
import java.util.ArrayList;
import java.util.List;
@BeforeClass(alwaysRun = true)
public static void setUpBeforeClass() throws Exception
{
- jalview.bin.Jalview.main(new String[] { "-props",
- "test/jalview/testProps.jvprops" });
+ Jalview.main(new String[] { "-props", "test/jalview/testProps.jvprops" });
}
@BeforeMethod(alwaysRun = true)
@Test(groups = { "Functional" })
public void testCollateForPdb()
{
+ // JBP: What behaviour is this supposed to test ?
/*
* Set up sequence pdb ids
*/
- PDBEntry pdb1 = new PDBEntry("1ABC", "A", Type.PDB, "1ABC.pdb");
- PDBEntry pdb2 = new PDBEntry("2ABC", "A", Type.PDB, "2ABC.pdb");
- PDBEntry pdb3 = new PDBEntry("3ABC", "A", Type.PDB, "3ABC.pdb");
+ PDBEntry pdb1 = new PDBEntry("1ABC", "B", Type.PDB, "1ABC.pdb");
+ PDBEntry pdb2 = new PDBEntry("2ABC", "C", Type.PDB, "2ABC.pdb");
+ PDBEntry pdb3 = new PDBEntry("3ABC", "D", Type.PDB, "3ABC.pdb");
/*
- * seq1 and seq3 refer to 1ABC, seq2 to 2ABC, none to 3ABC
+ * seq1 and seq3 refer to 1abcB, seq2 to 2abcC, none to 3abcD
*/
al.getSequenceAt(0).getDatasetSequence()
.addPDBId(new PDBEntry("1ABC", "B", Type.PDB, "1ABC.pdb"));
AlignFrame af1 = new FileLoader().LoadFileWaitTillLoaded(
">Seq1\nCAGT\n", FormatAdapter.PASTE);
+ SequenceI s1 = af1.getViewport().getAlignment().getSequenceAt(0);
AlignedCodonFrame acf1 = new AlignedCodonFrame();
+ acf1.addMap(s1, s1, new MapList(new int[] { 1, 4 }, new int[] { 1, 4 },
+ 1, 1));
AlignedCodonFrame acf2 = new AlignedCodonFrame();
+ acf2.addMap(s1, s1, new MapList(new int[] { 1, 4 }, new int[] { 4, 1 },
+ 1, 1));
List<AlignedCodonFrame> mappings = new ArrayList<AlignedCodonFrame>();
mappings.add(acf1);
">Seq1\nRSVQ\n", FormatAdapter.PASTE);
AlignFrame af2 = new FileLoader().LoadFileWaitTillLoaded(
">Seq2\nDGEL\n", FormatAdapter.PASTE);
-
+ SequenceI cs1 = new Sequence("cseq1", "CCCGGGTTTAAA");
+ SequenceI cs2 = new Sequence("cseq2", "CTTGAGTCTAGA");
+ SequenceI s1 = af1.getViewport().getAlignment().getSequenceAt(0);
+ SequenceI s2 = af2.getViewport().getAlignment().getSequenceAt(0);
+ // need to be distinct
AlignedCodonFrame acf1 = new AlignedCodonFrame();
+ acf1.addMap(cs1, s1, new MapList(new int[] { 1, 4 },
+ new int[] { 1, 12 }, 1, 3));
AlignedCodonFrame acf2 = new AlignedCodonFrame();
+ acf2.addMap(cs2, s2, new MapList(new int[] { 1, 4 },
+ new int[] { 1, 12 }, 1, 3));
AlignedCodonFrame acf3 = new AlignedCodonFrame();
+ acf3.addMap(cs2, cs2, new MapList(new int[] { 1, 12 }, new int[] { 1,
+ 12 }, 1, 1));
List<AlignedCodonFrame> mappings1 = new ArrayList<AlignedCodonFrame>();
mappings1.add(acf1);
">Seq1\nRSVQ\n", FormatAdapter.PASTE);
AlignFrame af2 = new FileLoader().LoadFileWaitTillLoaded(
">Seq2\nDGEL\n", FormatAdapter.PASTE);
-
+ SequenceI cs1 = new Sequence("cseq1", "CCCGGGTTTAAA");
+ SequenceI cs2 = new Sequence("cseq2", "CTTGAGTCTAGA");
+ SequenceI s1 = af1.getViewport().getAlignment().getSequenceAt(0);
+ SequenceI s2 = af2.getViewport().getAlignment().getSequenceAt(0);
+ // need to be distinct
AlignedCodonFrame acf1 = new AlignedCodonFrame();
+ acf1.addMap(cs1, s1, new MapList(new int[] { 1, 4 },
+ new int[] { 1, 12 }, 1, 3));
AlignedCodonFrame acf2 = new AlignedCodonFrame();
+ acf2.addMap(cs2, s2, new MapList(new int[] { 1, 4 },
+ new int[] { 1, 12 }, 1, 3));
AlignedCodonFrame acf3 = new AlignedCodonFrame();
+ acf3.addMap(cs2, cs2, new MapList(new int[] { 1, 12 }, new int[] { 1,
+ 12 }, 1, 1));
List<AlignedCodonFrame> mappings1 = new ArrayList<AlignedCodonFrame>();
mappings1.add(acf1);
assertTrue(ssmMappings.contains(acf2));
assertFalse(ssmMappings.contains(acf3));
}
+
+ /**
+ * Test for JAL-1306 - conservation thread should run even when only Quality
+ * (and not Conservation) is enabled in Preferences
+ */
+ @Test(groups = { "Functional" })
+ public void testUpdateConservation_qualityOnly()
+ {
+ Cache.applicationProperties.setProperty("SHOW_ANNOTATIONS",
+ Boolean.TRUE.toString());
+ Cache.applicationProperties.setProperty("SHOW_QUALITY",
+ Boolean.TRUE.toString());
+ Cache.applicationProperties.setProperty("SHOW_CONSERVATION",
+ Boolean.FALSE.toString());
+ Cache.applicationProperties.setProperty("SHOW_IDENTITY",
+ Boolean.FALSE.toString());
+ AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
+ "examples/uniref50.fa", FormatAdapter.FILE);
+ AlignmentAnnotation[] anns = af.viewport.getAlignment()
+ .getAlignmentAnnotation();
+ assertNotNull("No annotations found", anns);
+ assertEquals("More than one annotation found", 1, anns.length);
+ assertTrue("Annotation is not Quality",
+ anns[0].description.startsWith("Alignment Quality"));
+ Annotation[] annotations = anns[0].annotations;
+ assertNotNull("Quality annotations are null", annotations);
+ assertNotNull("Quality in column 1 is null", annotations[0]);
+ assertTrue("No quality value in column 1", annotations[0].value > 10f);
+ }
+
+ @Test(groups = { "Functional" })
+ public void testSetGlobalColourScheme()
+ {
+ /*
+ * test for JAL-2283 don't inadvertently turn on colour by conservation
+ */
+ Cache.applicationProperties.setProperty("DEFAULT_COLOUR_PROT", "NONE");
+ Cache.applicationProperties.setProperty("SHOW_CONSERVATION",
+ Boolean.TRUE.toString());
+ AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
+ "examples/uniref50.fa", FormatAdapter.FILE);
+ ColourSchemeI cs = new PIDColourScheme();
+ af.getViewport().setGlobalColourScheme(cs);
+ assertFalse(cs.conservationApplied());
+ }
}
@BeforeMethod(alwaysRun = true)
public void setUp() throws IOException
{
+ Cache.loadProperties("test/jalview/io/testProps.jvprops");
// pin down annotation sort order for test
Cache.applicationProperties.setProperty(Preferences.SORT_ANNOTATIONS,
SequenceAnnotationOrder.NONE.name());
import jalview.bin.Cache;
import java.awt.Dimension;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
+import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
-import java.awt.event.MouseListener;
import javax.swing.JDesktopPane;
import javax.swing.JFrame;
import javax.swing.JInternalFrame;
-import javax.swing.JMenu;
-import javax.swing.JMenuItem;
import javax.swing.JTextArea;
import org.testng.annotations.AfterClass;
foo.setPreferredSize(new Dimension(600, 800));
cfoo.setSize(600, 800);
final JInternalFrame cont = new JInternalFrame("My Frame");
- JTextArea evt;
- cont.setPreferredSize(new Dimension(400, 300));
- cont.add(evt = new JTextArea(
- "Click here and drag text over this window to freeze java.\n\nThis is a dummy string. See teh dummy string go.\nThis is a dummy string. See teh dummy string go.\nThis is a dummy string. See teh dummy string go.\nThis is a dummy string. See teh dummy string go.\nThis is a dummy string. See teh dummy string go.\nThis is a dummy string. See teh dummy string go.\nThis is a dummy string. See teh dummy string go.\nThis is a dummy string. See teh dummy string go.\nThis is a dummy string. See teh dummy string go.\nThis is a dummy string. See teh dummy string go.\nThis is a dummy string. See teh dummy string go.\nThis is a dummy string. See teh dummy string go.\nThis is a dummy string. See teh dummy string go.\n"));
+ cont.setPreferredSize(new Dimension(400, 400));
+ String msg = "This is a dummy string. See the dummy string go.\n";
+ msg += msg; // 2
+ msg += msg; // 4
+ msg += msg; // 8
+ msg += msg; // 16
+ JTextArea evt = new JTextArea(
+ "Click here and drag text over this window to freeze java.\n\n"
+ + msg);
+ cont.add(evt);
cont.pack();
foo.add("A frame", cont);
foo.setVisible(true);
foo.setEnabled(true);
foo.doLayout();
cfoo.add(foo);
- final JMenu jm = new JMenu("Do");
- JMenuItem jmi = new JMenuItem("this");
- jm.add(jmi);
- evt.addMouseListener(new MouseListener()
+ // final JMenu jm = new JMenu("Do");
+ // JMenuItem jmi = new JMenuItem("this");
+ // jm.add(jmi);
+ evt.addMouseListener(new MouseAdapter()
{
@Override
- public void mouseReleased(MouseEvent e)
- {
- }
-
- @Override
- public void mousePressed(MouseEvent e)
- {
- // TODO Auto-generated method stub
-
- }
-
- @Override
- public void mouseExited(MouseEvent e)
- {
- // TODO Auto-generated method stub
-
- }
-
- @Override
- public void mouseEntered(MouseEvent e)
- {
- // TODO Auto-generated method stub
-
- }
-
- @Override
public void mouseClicked(MouseEvent e)
{
// JFrame parent = new JFrame();
});
cont.setVisible(true);
- jmi.addActionListener(new ActionListener()
- {
-
- @Override
- public void actionPerformed(ActionEvent arg0)
- {
- EditNameDialog end = new EditNameDialog("Sequence Name",
- "Sequence Description", "label 1", "Label 2",
- "Try and drag between the two text fields", cont);
- assert (end != null);
- finish = true;
- }
- });
+ // jmi.addActionListener(new ActionListener()
+ // {
+ //
+ // @Override
+ // public void actionPerformed(ActionEvent arg0)
+ // {
+ // EditNameDialog end = new EditNameDialog("Sequence Name",
+ // "Sequence Description", "label 1", "Label 2",
+ // "Try and drag between the two text fields", cont);
+ // assert (end != null);
+ // finish = true;
+ // }
+ // });
foo.setVisible(true);
cfoo.setVisible(true);
while (!finish)
--- /dev/null
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
+package jalview.gui;
+
+/*
+ * Copyright (c) 1995, 2008, Oracle and/or its affiliates. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * - Neither the name of Oracle or the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+* MouseEventDemo.java
+*/
+
+import jalview.util.Platform;
+
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.GridLayout;
+import java.awt.event.ActionEvent;
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseListener;
+
+import javax.swing.AbstractAction;
+import javax.swing.BorderFactory;
+import javax.swing.InputMap;
+import javax.swing.JComponent;
+import javax.swing.JFrame;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JSplitPane;
+import javax.swing.JTextArea;
+import javax.swing.KeyStroke;
+import javax.swing.SwingUtilities;
+
+/**
+ * Sourced from Oracle and adapted
+ *
+ * @see https
+ * ://docs.oracle.com/javase/tutorial/uiswing/events/mouselistener.html
+ */
+public class MouseEventDemo extends JPanel implements MouseListener
+{
+ private class BlankArea extends JLabel
+ {
+ Dimension minSize = new Dimension(200, 100);
+
+ public BlankArea(Color color)
+ {
+ setBackground(color);
+ setOpaque(true);
+ setBorder(BorderFactory.createLineBorder(Color.black));
+ }
+
+ @Override
+ public Dimension getMinimumSize()
+ {
+ return minSize;
+ }
+
+ @Override
+ public Dimension getPreferredSize()
+ {
+ return minSize;
+ }
+ }
+
+ static int counter = 0;
+
+ BlankArea blankArea;
+
+ JTextArea textArea;
+
+ static final String NEWLINE = System.getProperty("line.separator");
+
+ public static void main(String[] args)
+ {
+ // Schedule a job for the event dispatch thread:
+ // creating and showing this application's GUI.
+ javax.swing.SwingUtilities.invokeLater(new Runnable()
+ {
+ @Override
+ public void run()
+ {
+ createAndShowGUI();
+ }
+ });
+ }
+
+ /**
+ * Create the GUI and show it. For thread safety, this method should be
+ * invoked from the event dispatch thread.
+ */
+ private static void createAndShowGUI()
+ {
+ // Create and set up the window.
+ JFrame frame = new JFrame("MouseEventDemo (C to clear)");
+ frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
+
+ // Create and set up the content pane.
+ JComponent newContentPane = new MouseEventDemo();
+ newContentPane.setOpaque(true); // content panes must be opaque
+ frame.setContentPane(newContentPane);
+
+ // Display the window.
+ frame.pack();
+ frame.setVisible(true);
+ }
+
+ public MouseEventDemo()
+ {
+ super(new GridLayout(0, 1));
+
+ textArea = new JTextArea();
+ textArea.setEditable(false);
+ JScrollPane scrollPane = new JScrollPane(textArea);
+ scrollPane
+ .setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
+ scrollPane.setPreferredSize(new Dimension(400, 75));
+
+ blankArea = new BlankArea(Color.YELLOW);
+ JSplitPane splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT,
+ blankArea, scrollPane);
+ splitPane.setVisible(true);
+ splitPane.setDividerLocation(0.2d);
+ splitPane.setResizeWeight(0.5d);
+ add(splitPane);
+
+ addKeyBinding();
+
+ blankArea.addMouseListener(this);
+ addMouseListener(this);
+ setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));
+ }
+
+ private void addKeyBinding()
+ {
+ addKeyBinding(KeyStroke.getKeyStroke('C'));
+ addKeyBinding(KeyStroke.getKeyStroke('c'));
+ }
+
+ /**
+ * @param ks
+ */
+ void addKeyBinding(final KeyStroke ks)
+ {
+ InputMap inputMap = this.getInputMap(JComponent.WHEN_FOCUSED);
+ inputMap.put(ks, ks);
+ this.getActionMap().put(ks, new AbstractAction()
+ {
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ textArea.setText("");
+ log("");
+ }
+ });
+ }
+
+ void logEvent(String eventDescription, MouseEvent e)
+ {
+ log("------- " + counter++ + ": " + eventDescription);
+ log("e.isPopupTrigger: " + e.isPopupTrigger());
+ log("SwingUtilities.isRightMouseButton: "
+ + SwingUtilities.isRightMouseButton(e));
+ log("SwingUtilities.isLeftMouseButton: "
+ + SwingUtilities.isLeftMouseButton(e));
+ log("Platform.isControlDown: " + Platform.isControlDown(e));
+ log("e.isControlDown: " + e.isControlDown());
+ log("e.isAltDown: " + e.isAltDown());
+ log("e.isMetaDown: " + e.isMetaDown());
+ log("e.isShiftDown: " + e.isShiftDown());
+ log("e.getClickCount: " + e.getClickCount());
+ }
+
+ /**
+ * @param msg
+ */
+ void log(String msg)
+ {
+ textArea.append(msg + NEWLINE);
+ textArea.setCaretPosition(textArea.getDocument().getLength());
+ }
+
+ @Override
+ public void mousePressed(MouseEvent e)
+ {
+ logEvent("Mouse pressed", e);
+ }
+
+ @Override
+ public void mouseReleased(MouseEvent e)
+ {
+ logEvent("Mouse released", e);
+ }
+
+ @Override
+ public void mouseEntered(MouseEvent e)
+ {
+ }
+
+ @Override
+ public void mouseExited(MouseEvent e)
+ {
+ }
+
+ @Override
+ public void mouseClicked(MouseEvent e)
+ {
+ logEvent("Mouse clicked", e);
+ }
+}
import jalview.datamodel.AlignmentAnnotation;
import jalview.datamodel.AlignmentI;
import jalview.datamodel.Annotation;
+import jalview.datamodel.DBRefEntry;
+import jalview.datamodel.DBRefSource;
+import jalview.datamodel.Sequence;
import jalview.datamodel.SequenceI;
import jalview.io.AppletFormatAdapter;
import jalview.io.FormatAdapter;
assertEquals(JSeparator.HORIZONTAL,
((JSeparator) hideOptions[1]).getOrientation());
}
+
+ /**
+ * Test for adding feature links
+ */
+ @Test(groups = { "Functional" })
+ public void testAddFeatureLinks()
+ {
+ // sequences from the alignment
+ List<SequenceI> seqs = parentPanel.getAlignment().getSequences();
+
+ // create list of links and list of DBRefs
+ List<String> links = new ArrayList<String>();
+ List<DBRefEntry> refs = new ArrayList<DBRefEntry>();
+
+ // links as might be added into Preferences | Connections dialog
+ links.add("EMBL-EBI Search | http://www.ebi.ac.uk/ebisearch/search.ebi?db=allebi&query=$SEQUENCE_NAME$");
+ links.add("UNIPROT | http://www.uniprot.org/uniprot/$SEQUENCE_ID$");
+ links.add("INTERPRO | http://www.ebi.ac.uk/interpro/entry/$SEQUENCE_ID$");
+ // Gene3D entry tests for case (in)sensitivity
+ links.add("Gene3D | http://gene3d.biochem.ucl.ac.uk/Gene3D/search?sterm=$SEQUENCE_ID$&mode=protein");
+
+ // make seq0 dbrefs
+ refs.add(new DBRefEntry(DBRefSource.UNIPROT, "1", "P83527"));
+ refs.add(new DBRefEntry("INTERPRO", "1", "IPR001041"));
+ refs.add(new DBRefEntry("INTERPRO", "1", "IPR006058"));
+ refs.add(new DBRefEntry("INTERPRO", "1", "IPR012675"));
+
+ // make seq1 dbrefs
+ refs.add(new DBRefEntry(DBRefSource.UNIPROT, "1", "Q9ZTS2"));
+ refs.add(new DBRefEntry("GENE3D", "1", "3.10.20.30"));
+
+ // add all the dbrefs to the sequences: Uniprot 1 each, Interpro all 3 to
+ // seq0, Gene3D to seq1
+ seqs.get(0).addDBRef(refs.get(0));
+
+ seqs.get(0).addDBRef(refs.get(1));
+ seqs.get(0).addDBRef(refs.get(2));
+ seqs.get(0).addDBRef(refs.get(3));
+
+ seqs.get(1).addDBRef(refs.get(4));
+ seqs.get(1).addDBRef(refs.get(5));
+
+ // get the Popup Menu for first sequence
+ testee = new PopupMenu(parentPanel, (Sequence) seqs.get(0), links);
+ Component[] seqItems = testee.sequenceMenu.getMenuComponents();
+ JMenu linkMenu = (JMenu) seqItems[6];
+ Component[] linkItems = linkMenu.getMenuComponents();
+
+ // check the number of links are the expected number
+ assertEquals(5, linkItems.length);
+
+ // first entry is EMBL-EBI which just uses sequence id not accession id?
+ assertEquals("EMBL-EBI Search", ((JMenuItem) linkItems[0]).getText());
+
+ // sequence id for each link should match corresponding DB accession id
+ for (int i = 1; i < 4; i++)
+ {
+ assertEquals(refs.get(i - 1).getSource(), ((JMenuItem) linkItems[i])
+ .getText().split("\\|")[0]);
+ assertEquals(refs.get(i - 1).getAccessionId(),
+ ((JMenuItem) linkItems[i])
+ .getText().split("\\|")[1]);
+ }
+
+ // get the Popup Menu for second sequence
+ testee = new PopupMenu(parentPanel, (Sequence) seqs.get(1), links);
+ seqItems = testee.sequenceMenu.getMenuComponents();
+ linkMenu = (JMenu) seqItems[6];
+ linkItems = linkMenu.getMenuComponents();
+
+ // check the number of links are the expected number
+ assertEquals(3, linkItems.length);
+
+ // first entry is EMBL-EBI which just uses sequence id not accession id?
+ assertEquals("EMBL-EBI Search", ((JMenuItem) linkItems[0]).getText());
+
+ // sequence id for each link should match corresponding DB accession id
+ for (int i = 1; i < 3; i++)
+ {
+ assertEquals(refs.get(i + 3).getSource(), ((JMenuItem) linkItems[i])
+ .getText().split("\\|")[0].toUpperCase());
+ assertEquals(refs.get(i + 3).getAccessionId(),
+ ((JMenuItem) linkItems[i]).getText().split("\\|")[1]);
+ }
+
+
+ }
}
import jalview.datamodel.PDBEntry;
import jalview.datamodel.Sequence;
import jalview.datamodel.SequenceI;
+import jalview.jbgui.GStructureChooser.FilterOption;
import java.util.Vector;
{
seq = new Sequence("PDB|4kqy|4KQY|A", "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 1,
26);
- seq.setDatasetSequence(seq);
+ seq.createDatasetSequence();
for (int x = 1; x < 5; x++)
{
DBRefEntry dbRef = new DBRefEntry();
}
@Test(groups = { "Functional" })
- public void populateFilterComboBoxTest()
+ public void populateFilterComboBoxTest() throws InterruptedException
{
SequenceI[] selectedSeqs = new SequenceI[] { seq };
StructureChooser sc = new StructureChooser(selectedSeqs, seq, null);
- sc.populateFilterComboBox();
+ sc.populateFilterComboBox(false, false);
int optionsSize = sc.getCmbFilterOption().getItemCount();
assertEquals(3, optionsSize); // if structures are not discovered then don't
// populate filter options
- sc.setStructuresDiscovered(true);
- sc.populateFilterComboBox();
- try
- {
- Thread.sleep(2000);
- } catch (InterruptedException e)
- {
- e.printStackTrace();
- }
+ sc.populateFilterComboBox(true, false);
optionsSize = sc.getCmbFilterOption().getItemCount();
assertTrue(optionsSize > 3); // if structures are found, filter options
// should be populated
+
+ sc.populateFilterComboBox(true, true);
+ assertTrue(sc.getCmbFilterOption().getSelectedItem() != null);
+ FilterOption filterOpt = (FilterOption) sc.getCmbFilterOption()
+ .getSelectedItem();
+ assertEquals("Cached PDB Entries", filterOpt.getName());
}
@Test(groups = { "Functional" })
--- /dev/null
+package jalview.gui;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNull;
+
+import jalview.datamodel.PDBEntry;
+import jalview.datamodel.PDBEntry.Type;
+
+import org.testng.annotations.Test;
+
+public class StructureViewerTest
+{
+ @Test(groups = "Functional")
+ public void testGetUniquePdbFiles()
+ {
+ assertNull(StructureViewer.getUniquePdbFiles(null));
+
+ PDBEntry pdbe1 = new PDBEntry("1A70", "A", Type.PDB, "path1");
+ PDBEntry pdbe2 = new PDBEntry("3A6S", "A", Type.PDB, "path2");
+ PDBEntry pdbe3 = new PDBEntry("1A70", "B", Type.PDB, "path1");
+ PDBEntry pdbe4 = new PDBEntry("1GAQ", "A", Type.PDB, null);
+ PDBEntry pdbe5 = new PDBEntry("3A6S", "B", Type.PDB, "path2");
+ PDBEntry pdbe6 = new PDBEntry("1GAQ", "B", Type.PDB, null);
+
+ /*
+ * pdbe2 and pdbe5 get removed as having a duplicate file path
+ */
+ PDBEntry[] uniques = StructureViewer.getUniquePdbFiles(new PDBEntry[] {
+ pdbe1, pdbe2, pdbe3, pdbe4, pdbe5, pdbe6 });
+ assertEquals(uniques,
+ new PDBEntry[] { pdbe1, pdbe2, pdbe4, pdbe6 });
+ }
+}
import jalview.datamodel.SequenceFeature;
import jalview.datamodel.SequenceI;
import jalview.gui.AlignFrame;
+import jalview.structure.StructureImportSettings;
+import jalview.structure.StructureImportSettings.StructureParser;
import java.io.File;
al = af.getViewport().getAlignment();
pdbId = al.getSequenceAt(0).getDatasetSequence().getAllPDBEntries()
.get(0).getId();
+ StructureImportSettings.setDefaultStructureFileFormat("PDB");
+ // StructureImportSettings
+ // .setDefaultPDBFileParser(StructureParser.JALVIEW_PARSER);
}
@Test(groups = { "Functional" })
{
for (int q = p + 1; q < avec.length; q++)
{
- assertTrue("Found a duplicate annotation row "
- + avec[p].label, avec[p] != avec[q]);
+ assertTrue("Found a duplicate annotation row " + avec[p].label,
+ avec[p] != avec[q]);
}
}
}
{
System.out.println("CalcId: " + aa.getCalcId());
- assertTrue(MCview.PDBfile.isCalcIdForFile(aa, pdbId));
+ if (StructureImportSettings.getDefaultPDBFileParser().equals(
+ StructureParser.JALVIEW_PARSER))
+ {
+ assertTrue(MCview.PDBfile.isCalcIdForFile(aa, pdbId));
+ }
}
}
}
sq = sq.getDatasetSequence();
}
assertNotNull(sq.getAllPDBEntries());
- assertEquals("Expected only one PDB ID",
- sq.getAllPDBEntries().size(), 1);
+ assertEquals("Expected only one PDB ID", 1, sq.getAllPDBEntries()
+ .size());
for (PDBEntry pdbentry : sq.getAllPDBEntries())
{
System.err.println("PDB Entry " + pdbentry.getId() + " "
// make sure dataset is initialised ? not sure about this
for (int i = 0; i < al.getSequencesArray().length; ++i)
{
- al.getSequenceAt(i).setDatasetSequence(
- al.getSequenceAt(i).createDatasetSequence());
+ al.getSequenceAt(i).createDatasetSequence();
}
assertNotNull("Couldn't read supplied alignment data.", al);
return al;
--- /dev/null
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
+package jalview.io;
+
+import jalview.analysis.CrossRef;
+import jalview.api.AlignmentViewPanel;
+import jalview.datamodel.AlignedCodonFrame;
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.AlignmentTest;
+import jalview.datamodel.SequenceI;
+import jalview.gui.AlignFrame;
+import jalview.gui.CrossRefAction;
+import jalview.gui.Desktop;
+import jalview.gui.Jalview2XML;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+@Test(singleThreaded = true)
+public class CrossRef2xmlTests extends Jalview2xmlBase
+{
+
+ /**
+ * test store and recovery of all reachable cross refs from all reachable
+ * crossrefs for one or more fetched db refs. Currently, this test has a known
+ * failure case.
+ *
+ * @throws Exception
+ */
+ @Test(groups = { "Operational" }, enabled = true)
+ public void testRetrieveAndShowCrossref() throws Exception
+ {
+
+ List<String> failedDBRetr = new ArrayList<String>();
+ List<String> failedXrefMenuItems = new ArrayList<String>();
+ List<String> failedProjectRecoveries = new ArrayList<String>();
+
+ // for every set of db queries
+ // retrieve db query
+ // verify presence of expected xrefs
+ // show xrefs - verify expected type of frame is shown for each xref
+ // show xrefs again
+ // - verify original -> xref -> xref(original) recovers frame containing at
+ // least the first retrieved sequence
+ // store
+ // 1. whole project
+ // 2. individual frames
+ // 3. load each one back and verify
+ // . aligned sequences (.toString() )
+ // . xrefs (.toString() )
+ // . codonframes
+ //
+ //
+ HashMap<String, String> dbtoviewBit = new HashMap<String, String>();
+ List<String> keyseq = new ArrayList<String>();
+ HashMap<String, File> savedProjects = new HashMap<String, File>();
+
+ for (String[] did : new String[][] { { "ENSEMBL", "ENSG00000157764" },
+ { "UNIPROT", "P01731" } })
+ {
+ // pass counters - 0 - first pass, 1 means retrieve project rather than
+ // perform action
+ int pass1 = 0, pass2 = 0, pass3 = 0;
+ // each do loop performs two iterations in the first outer loop pass, but
+ // only performs one iteration on the second outer loop
+ // ie. pass 1 = 0 {pass 2= 0 { pass 3 = 0,1 }, pass 2=1 { pass 3 = 0 }}, 1
+ // { pass 2 = 0 { pass 3 = 0 } }
+ do
+ {
+ String first = did[0] + " " + did[1];
+ AlignFrame af = null;
+ boolean dna;
+ AlignmentI retral;
+ AlignmentI dataset;
+ SequenceI[] seqs;
+ List<String> ptypes = null;
+ if (pass1 == 0)
+ {
+ // retrieve dbref
+
+ List<AlignFrame> afs = jalview.gui.SequenceFetcher.fetchAndShow(
+ did[0], did[1]);
+ if (afs.size() == 0)
+ {
+ failedDBRetr.add("Didn't retrieve " + first);
+ break;
+ }
+ keyseq.add(first);
+ af = afs.get(0);
+
+ // verify references for retrieved data
+ AlignmentTest.assertAlignmentDatasetRefs(af.getViewport()
+ .getAlignment(), "Pass (" + pass1 + "," + pass2 + ","
+ + pass3 + "): Fetch " + first + ":");
+ assertDatasetIsNormalisedKnownDefect(af.getViewport()
+ .getAlignment(), "Pass (" + pass1 + "," + pass2 + ","
+ + pass3 + "): Fetch " + first + ":");
+ dna = af.getViewport().getAlignment().isNucleotide();
+ retral = af.getViewport().getAlignment();
+ dataset = retral.getDataset();
+ seqs = retral.getSequencesArray();
+
+ }
+ else
+ {
+ Desktop.instance.closeAll_actionPerformed(null);
+ // recover stored project
+ af = new FileLoader(false).LoadFileWaitTillLoaded(savedProjects
+ .get(first).toString(), FormatAdapter.FILE);
+ System.out.println("Recovered view for '" + first + "' from '"
+ + savedProjects.get(first).toString() + "'");
+ dna = af.getViewport().getAlignment().isNucleotide();
+ retral = af.getViewport().getAlignment();
+ dataset = retral.getDataset();
+ seqs = retral.getSequencesArray();
+
+ // verify references for recovered data
+ AlignmentTest.assertAlignmentDatasetRefs(af.getViewport()
+ .getAlignment(), "Pass (" + pass1 + "," + pass2 + ","
+ + pass3 + "): Recover " + first + ":");
+ assertDatasetIsNormalisedKnownDefect(af.getViewport()
+ .getAlignment(), "Pass (" + pass1 + "," + pass2 + ","
+ + pass3 + "): Recover " + first + ":");
+
+ }
+
+ // store project on first pass, compare next pass
+ stringify(dbtoviewBit, savedProjects, first, af.alignPanel);
+
+ ptypes = (seqs == null || seqs.length == 0) ? null : new CrossRef(
+ seqs, dataset).findXrefSourcesForSequences(dna);
+
+ // start of pass2: retrieve each cross-ref for fetched or restored
+ // project.
+ do // first cross ref and recover crossref loop
+ {
+
+ for (String db : ptypes)
+ {
+ // counter for splitframe views retrieved via crossref
+ int firstcr_ap = 0;
+ // build next key so we an retrieve all views
+ String nextxref = first + " -> " + db + "{" + firstcr_ap + "}";
+ // perform crossref action, or retrieve stored project
+ List<AlignmentViewPanel> cra_views = new ArrayList<AlignmentViewPanel>();
+ CrossRefAction cra = null;
+
+ if (pass2 == 0)
+ { // retrieve and show cross-refs in this thread
+ cra = new CrossRefAction(af, seqs, dna, db);
+ cra.run();
+ if (cra.getXrefViews().size() == 0)
+ {
+ failedXrefMenuItems.add("No crossrefs retrieved for "
+ + first + " -> " + db);
+ continue;
+ }
+ cra_views = cra.getXrefViews();
+ assertNucleotide(cra_views.get(0),
+ "Nucleotide panel included proteins for " + first
+ + " -> " + db);
+ assertProtein(cra_views.get(1),
+ "Protein panel included nucleotides for " + first
+ + " -> " + db);
+ }
+ else
+ {
+ Desktop.instance.closeAll_actionPerformed(null);
+ pass3 = 0;
+ // recover stored project
+ File storedProject = savedProjects.get(nextxref);
+ if (storedProject == null)
+ {
+ failedProjectRecoveries.add("Failed to store a view for '"
+ + nextxref + "'");
+ continue;
+ }
+
+ // recover stored project
+ AlignFrame af2 = new FileLoader(false)
+ .LoadFileWaitTillLoaded(savedProjects.get(nextxref)
+ .toString(), FormatAdapter.FILE);
+ System.out.println("Recovered view for '" + nextxref
+ + "' from '" + savedProjects.get(nextxref).toString()
+ + "'");
+ // gymnastics to recover the alignPanel/Complementary alignPanel
+ if (af2.getViewport().isNucleotide())
+ {
+ // top view, then bottom
+ cra_views.add(af2.getViewport().getAlignPanel());
+ cra_views.add(((jalview.gui.AlignViewport) af2
+ .getViewport().getCodingComplement())
+ .getAlignPanel());
+
+ }
+ else
+ {
+ // bottom view, then top
+ cra_views.add(((jalview.gui.AlignViewport) af2
+ .getViewport().getCodingComplement())
+ .getAlignPanel());
+ cra_views.add(af2.getViewport().getAlignPanel());
+
+ }
+ }
+ HashMap<String, List<String>> xrptypes = new HashMap<String, List<String>>();
+ // first save/verify views.
+ for (AlignmentViewPanel avp : cra_views)
+ {
+ nextxref = first + " -> " + db + "{" + firstcr_ap++ + "}";
+ // verify references for this panel
+ AlignmentTest.assertAlignmentDatasetRefs(avp.getAlignment(),
+ "Pass (" + pass1 + "," + pass2 + "," + pass3
+ + "): before start of pass3: " + nextxref
+ + ":");
+ assertDatasetIsNormalisedKnownDefect(avp.getAlignment(),
+ "Pass (" + pass1 + "," + pass2 + "," + pass3
+ + "): before start of pass3: " + nextxref
+ + ":");
+
+ SequenceI[] xrseqs = avp.getAlignment().getSequencesArray();
+
+ List<String> _xrptypes = (seqs == null || seqs.length == 0) ? null
+ : new CrossRef(xrseqs, dataset)
+ .findXrefSourcesForSequences(avp
+ .getAlignViewport().isNucleotide());
+
+ stringify(dbtoviewBit, savedProjects, nextxref, avp);
+ xrptypes.put(nextxref, _xrptypes);
+
+ }
+
+ // now do the second xref pass starting from either saved or just
+ // recovered split pane, in sequence
+ do // retrieve second set of cross refs or recover and verify
+ {
+ firstcr_ap = 0;
+ for (AlignmentViewPanel avp : cra_views)
+ {
+ nextxref = first + " -> " + db + "{" + firstcr_ap++ + "}";
+ for (String xrefdb : xrptypes.get(nextxref))
+ {
+ List<AlignmentViewPanel> cra_views2 = new ArrayList<AlignmentViewPanel>();
+ int q = 0;
+ String nextnextxref = nextxref + " -> " + xrefdb + "{"
+ + q + "}";
+
+ if (pass3 == 0)
+ {
+
+ SequenceI[] xrseqs = avp.getAlignment()
+ .getSequencesArray();
+ AlignFrame nextaf = Desktop.getAlignFrameFor(avp
+ .getAlignViewport());
+
+ cra = new CrossRefAction(nextaf, xrseqs, avp
+ .getAlignViewport().isNucleotide(), xrefdb);
+ cra.run();
+ if (cra.getXrefViews().size() == 0)
+ {
+ failedXrefMenuItems
+ .add("No crossrefs retrieved for '"
+ + nextxref + "' to " + xrefdb
+ + " via '" + nextaf.getTitle() + "'");
+ continue;
+ }
+ cra_views2 = cra.getXrefViews();
+ assertNucleotide(cra_views2.get(0),
+ "Nucleotide panel included proteins for '"
+ + nextxref + "' to " + xrefdb
+ + " via '" + nextaf.getTitle() + "'");
+ assertProtein(cra_views2.get(1),
+ "Protein panel included nucleotides for '"
+ + nextxref + "' to " + xrefdb
+ + " via '" + nextaf.getTitle() + "'");
+
+ }
+ else
+ {
+ Desktop.instance.closeAll_actionPerformed(null);
+ // recover stored project
+ File storedProject = savedProjects.get(nextnextxref);
+ if (storedProject == null)
+ {
+ failedProjectRecoveries
+ .add("Failed to store a view for '"
+ + nextnextxref + "'");
+ continue;
+ }
+ AlignFrame af2 = new FileLoader(false)
+ .LoadFileWaitTillLoaded(
+ savedProjects.get(nextnextxref)
+ .toString(), FormatAdapter.FILE);
+ System.out.println("Recovered view for '"
+ + nextnextxref + "' from '"
+ + savedProjects.get(nextnextxref).toString()
+ + "'");
+ // gymnastics to recover the alignPanel/Complementary
+ // alignPanel
+ if (af2.getViewport().isNucleotide())
+ {
+ // top view, then bottom
+ cra_views2.add(af2.getViewport().getAlignPanel());
+ cra_views2.add(((jalview.gui.AlignViewport) af2
+ .getViewport().getCodingComplement())
+ .getAlignPanel());
+
+ }
+ else
+ {
+ // bottom view, then top
+ cra_views2.add(((jalview.gui.AlignViewport) af2
+ .getViewport().getCodingComplement())
+ .getAlignPanel());
+ cra_views2.add(af2.getViewport().getAlignPanel());
+ }
+ Assert.assertEquals(cra_views2.size(), 2);
+ Assert.assertNotNull(cra_views2.get(0));
+ Assert.assertNotNull(cra_views2.get(1));
+ }
+
+ for (AlignmentViewPanel nextavp : cra_views2)
+ {
+ nextnextxref = nextxref + " -> " + xrefdb + "{" + q++
+ + "}";
+
+ // verify references for this panel
+ AlignmentTest.assertAlignmentDatasetRefs(
+ nextavp.getAlignment(), "" + "Pass (" + pass1
+ + "," + pass2 + "): For "
+ + nextnextxref + ":");
+ assertDatasetIsNormalisedKnownDefect(
+ nextavp.getAlignment(), "" + "Pass (" + pass1
+ + "," + pass2 + "): For "
+ + nextnextxref + ":");
+
+ stringify(dbtoviewBit, savedProjects, nextnextxref,
+ nextavp);
+ keyseq.add(nextnextxref);
+ }
+ } // end of loop around showing all xrefdb for crossrf2
+
+ } // end of loop around all viewpanels from crossrf1
+ } while (pass2 == 2 && pass3++ < 2);
+ // fetchdb->crossref1->crossref-2->verify for xrefs we
+ // either loop twice when pass2=0, or just once when pass2=1
+ // (recovered project from previous crossref)
+
+ } // end of loop over db-xrefs for crossref-2
+
+ // fetchdb-->crossref1
+ // for each xref we try to retrieve xref, store and verify when
+ // pass1=0, or just retrieve and verify when pass1=1
+ } while (pass1 == 1 && pass2++ < 2);
+ // fetchdb
+ // for each ref we
+ // loop twice: first, do the retrieve, second recover from saved project
+
+ // increment pass counters, so we repeat traversal starting from the
+ // oldest saved project first.
+ if (pass1 == 0)
+ {
+ // verify stored projects for first set of cross references
+ pass1 = 1;
+ // and verify cross-references retrieved from stored projects
+ pass2 = 0;
+ pass3 = 0;
+ }
+ else
+ {
+ pass1++;
+ }
+ } while (pass1 < 3);
+ }
+ if (failedXrefMenuItems.size() > 0)
+ {
+ for (String s : failedXrefMenuItems)
+ {
+ System.err.println(s);
+ }
+ Assert.fail("Faulty xref menu (" + failedXrefMenuItems.size()
+ + " counts)");
+ }
+ if (failedProjectRecoveries.size() > 0)
+ {
+
+ for (String s : failedProjectRecoveries)
+ {
+ System.err.println(s);
+ }
+ Assert.fail("Didn't recover projects for some retrievals (did they retrieve ?) ("
+ + failedProjectRecoveries.size() + " counts)");
+ }
+ if (failedDBRetr.size() > 0)
+ {
+ for (String s : failedProjectRecoveries)
+ {
+ System.err.println(s);
+ }
+ Assert.fail("Didn't retrieve some db refs for checking cross-refs ("
+ + failedDBRetr.size() + " counts)");
+ }
+ }
+
+ /**
+ * wrapper to trap known defect for AH002001 testcase
+ *
+ * @param alignment
+ * @param string
+ */
+ private void assertDatasetIsNormalisedKnownDefect(AlignmentI al,
+ String message)
+ {
+ try
+ {
+ AlignmentTest.assertDatasetIsNormalised(al, message);
+ } catch (AssertionError ae)
+ {
+ if (!ae.getMessage().endsWith("EMBL|AH002001"))
+ {
+ throw ae;
+ }
+ else
+ {
+ System.out
+ .println("Ignored exception for known defect: JAL-2179 : "
+ + message);
+ }
+
+ }
+ }
+
+ private void assertProtein(AlignmentViewPanel alignmentViewPanel,
+ String message)
+ {
+ assertType(true, alignmentViewPanel, message);
+ }
+
+ private void assertNucleotide(AlignmentViewPanel alignmentViewPanel,
+ String message)
+ {
+ assertType(false, alignmentViewPanel, message);
+ }
+
+ private void assertType(boolean expectProtein,
+ AlignmentViewPanel alignmentViewPanel, String message)
+ {
+ List<SequenceI> nonType = new ArrayList<SequenceI>();
+ for (SequenceI sq : alignmentViewPanel.getAlignViewport()
+ .getAlignment().getSequences())
+ {
+ if (sq.isProtein() != expectProtein)
+ {
+ nonType.add(sq);
+ }
+ }
+ if (nonType.size() > 0)
+ {
+ Assert.fail(message + " [ "
+ + (expectProtein ? "nucleotides were " : "proteins were ")
+ + nonType.toString() + " ]");
+ }
+ }
+
+ /**
+ * first time called, record strings derived from alignment and
+ * alignedcodonframes, and save view to a project file. Second time called,
+ * compare strings to existing ones. org.testng.Assert.assertTrue on
+ * stringmatch
+ *
+ * @param dbtoviewBit
+ * map between xrefpath and view string
+ * @param savedProjects
+ * - map from xrefpath to saved project filename (createTempFile)
+ * @param xrefpath
+ * - xrefpath - unique ID for this context (composed of sequence of
+ * db-fetch/cross-ref actions preceeding state)
+ * @param avp
+ * - viewpanel to store (for viewpanels in splitframe, the same
+ * project should be written for both panels, only one needs
+ * recovering for comparison on the next stringify call, but each
+ * viewpanel needs to be called with a distinct xrefpath to ensure
+ * each one's strings are compared)
+ */
+ private void stringify(HashMap<String, String> dbtoviewBit,
+ HashMap<String, File> savedProjects, String xrefpath,
+ AlignmentViewPanel avp)
+ {
+ if (savedProjects != null)
+ {
+ if (savedProjects.get(xrefpath) == null)
+ {
+ // write a project file for this view. On the second pass, this will be
+ // recovered and cross-references verified
+ try
+ {
+ File prfile = File.createTempFile("crossRefTest", ".jvp");
+ AlignFrame af = Desktop.getAlignFrameFor(avp.getAlignViewport());
+ new Jalview2XML(false).saveAlignment(af, prfile.toString(),
+ af.getTitle());
+ System.out.println("Written view from '" + xrefpath + "' as '"
+ + prfile.getAbsolutePath() + "'");
+ savedProjects.put(xrefpath, prfile);
+ } catch (IOException q)
+ {
+ Assert.fail("Unexpected IO Exception", q);
+ }
+ }
+ else
+ {
+ System.out.println("Stringify check on view from '" + xrefpath
+ + "' [ possibly retrieved from '"
+ + savedProjects.get(xrefpath).getAbsolutePath() + "' ]");
+
+ }
+ }
+
+ StringBuilder sbr = new StringBuilder();
+ sbr.append(avp.getAlignment().toString());
+ sbr.append("\n");
+ sbr.append("<End of alignment>");
+ sbr.append("\n");
+ sbr.append(avp.getAlignment().getDataset());
+ sbr.append("\n");
+ sbr.append("<End of dataset>");
+ sbr.append("\n");
+ int p = 0;
+ if (avp.getAlignment().getCodonFrames() != null)
+ {
+ for (AlignedCodonFrame ac : avp.getAlignment().getCodonFrames())
+ {
+ sbr.append("<AlignedCodonFrame " + p++ + ">");
+ sbr.append("\n");
+ sbr.append(ac.toString());
+ sbr.append("\n");
+ }
+ }
+ String dbt = dbtoviewBit.get(xrefpath);
+ if (dbt == null)
+ {
+ dbtoviewBit.put(xrefpath, sbr.toString());
+ }
+ else
+ {
+ Assert.assertEquals(sbr.toString(), dbt, "stringify mismatch for "
+ + xrefpath);
+ }
+ }
+}
Map<String, FeatureColourI> colours = af.getFeatureRenderer()
.getFeatureColours();
// GFF2 uses space as name/value separator in column 9
- String gffData = "METAL\tcc9900\n" + "GFF\n"
+ String gffData = "METAL\tcc9900\n"
+ + "GFF\n"
+ "FER_CAPAA\tuniprot\tMETAL\t44\t45\t4.0\t.\t.\tNote Iron-sulfur; Note 2Fe-2S\n"
+ "FER1_SOLLC\tuniprot\tPfam\t55\t130\t2.0\t.\t.";
FeaturesFile featuresFile = new FeaturesFile(gffData,
{
assertEquals("no sequences extracted from GFF3 file", 2,
dataset.getHeight());
-
+
SequenceI seq1 = dataset.findName("seq1");
SequenceI seq2 = dataset.findName("seq2");
assertNotNull(seq1);
"Expected at least one CDNA/Protein mapping for seq1",
dataset.getCodonFrame(seq1) != null
&& dataset.getCodonFrame(seq1).size() > 0);
-
+
}
@Test(groups = { "Functional" })
public void simpleGff3FileClass() throws IOException
{
AlignmentI dataset = new Alignment(new SequenceI[] {});
- FeaturesFile ffile = new FeaturesFile(simpleGffFile,
- FormatAdapter.FILE);
-
+ FeaturesFile ffile = new FeaturesFile(simpleGffFile, FormatAdapter.FILE);
+
boolean parseResult = ffile.parse(dataset, null, false, false);
assertTrue("return result should be true", parseResult);
checkDatasetfromSimpleGff3(dataset);
public void simpleGff3RelaxedIdMatching() throws IOException
{
AlignmentI dataset = new Alignment(new SequenceI[] {});
- FeaturesFile ffile = new FeaturesFile(simpleGffFile,
- FormatAdapter.FILE);
-
+ FeaturesFile ffile = new FeaturesFile(simpleGffFile, FormatAdapter.FILE);
+
boolean parseResult = ffile.parse(dataset, null, false, true);
assertTrue("return result (relaxedID matching) should be true",
parseResult);
* first with no features displayed
*/
FeatureRenderer fr = af.alignPanel.getFeatureRenderer();
- Map<String, FeatureColourI> visible = fr
- .getDisplayedFeatureCols();
+ Map<String, FeatureColourI> visible = fr.getDisplayedFeatureCols();
String exported = featuresFile.printJalviewFormat(
al.getSequencesArray(), visible);
String expected = "No Features Visible";
--- /dev/null
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
+package jalview.io;
+
+import static org.testng.AssertJUnit.assertEquals;
+import static org.testng.AssertJUnit.assertNotNull;
+import static org.testng.AssertJUnit.fail;
+
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.SequenceI;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+public class FormatAdapterTest
+{
+
+ /**
+ * Test saving and re-reading in a specified format
+ *
+ * @throws IOException
+ */
+ @Test(groups = { "Functional" }, dataProvider = "formats")
+ public void testRoundTrip(String format) throws IOException
+ {
+ try
+ {
+ AlignmentI al = new FormatAdapter().readFile("examples/uniref50.fa",
+ FormatAdapter.FILE, "FASTA");
+
+ /*
+ * 'gap' is the gap character used in the alignment data file here,
+ * not the user preferred gap character
+ */
+ char gap = al.getGapCharacter();
+ assertNotNull(al);
+
+ SequenceI[] seqs = al.getSequencesArray();
+ String formatted = new FormatAdapter().formatSequences(format, al,
+ false);
+
+ AlignmentI reloaded = new FormatAdapter().readFile(formatted,
+ FormatAdapter.PASTE, format);
+ List<SequenceI> reread = reloaded.getSequences();
+ assertEquals("Wrong number of reloaded sequences", seqs.length,
+ reread.size());
+
+ int i = 0;
+ for (SequenceI seq : reread)
+ {
+ String sequenceString = seq.getSequenceAsString();
+
+ /*
+ * special case: MSF always uses '.' as gap character
+ */
+ sequenceString = adjustForGapTreatment(sequenceString, gap, format);
+ assertEquals(
+ String.format("Sequence %d: %s", i, seqs[i].getName()),
+ seqs[i].getSequenceAsString(), sequenceString);
+ i++;
+ }
+ } catch (IOException e)
+ {
+ fail(String
+ .format("Format %s failed with %s", format, e.getMessage()));
+ }
+ }
+
+ /**
+ * Optionally change the gap character in the string to the given character,
+ * depending on the sequence file format
+ *
+ * @param sequenceString
+ * a sequence (as written in 'format' format)
+ * @param gap
+ * the sequence's original gap character
+ * @param format
+ * @return
+ */
+ String adjustForGapTreatment(String sequenceString, char gap,
+ String format)
+ {
+ if ("MSF".equals(format))
+ {
+ /*
+ * MSF forces gap character to '.', so change it back
+ * for comparison purposes
+ */
+ sequenceString = sequenceString.replace('.', gap);
+ }
+ return sequenceString;
+ }
+
+ /**
+ * Data provider that serves alignment formats that are both readable and
+ * writable
+ *
+ * @return
+ */
+ @DataProvider(name = "formats")
+ static Object[][] getFormats()
+ {
+ List<String> both = new ArrayList<String>();
+ String[] readable = FormatAdapter.READABLE_FORMATS;
+ List<String> writeable = Arrays.asList(FormatAdapter.WRITEABLE_FORMATS);
+ for (String r : readable)
+ {
+ if (writeable.contains(r))
+ {
+ both.add(r);
+ }
+ }
+
+ Object[][] formats = new Object[both.size()][];
+ int i = 0;
+ for (String format : both)
+ {
+ formats[i] = new Object[] { format };
+ i++;
+ }
+ return formats;
+ }
+
+ /**
+ * Enable this to isolate testing to a single file format
+ *
+ * @throws IOException
+ */
+ @Test(groups = { "Functional" }, enabled = false)
+ public void testOneFormatRoundTrip() throws IOException
+ {
+ testRoundTrip("JSON");
+ }
+}
for (Sequence seq : seqs)
{
- seq.setDatasetSequence(seq);
+ seq.createDatasetSequence();
expectedSeqs.put(seq.getName(), seq);
}
--- /dev/null
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
+package jalview.io;
+
+import jalview.bin.Cache;
+import jalview.bin.Jalview;
+import jalview.datamodel.AlignmentAnnotation;
+import jalview.datamodel.SequenceI;
+import jalview.gui.Desktop;
+
+import java.util.Date;
+
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.BeforeTest;
+
+public class Jalview2xmlBase
+{
+
+ /**
+ * @throws java.lang.Exception
+ */
+ @BeforeClass(alwaysRun = true)
+ public static void setUpBeforeClass() throws Exception
+ {
+ /*
+ * use read-only test properties file
+ */
+ Cache.loadProperties("test/jalview/io/testProps.jvprops");
+
+ /*
+ * set news feed last read to a future time to ensure no
+ * 'unread' news item is displayed
+ */
+ Date oneHourFromNow = new Date(System.currentTimeMillis() + 3600 * 1000);
+ Cache.setDateProperty("JALVIEW_NEWS_RSS_LASTMODIFIED", oneHourFromNow);
+
+ Jalview.main(new String[] {});
+ }
+
+ /**
+ * @throws java.lang.Exception
+ */
+ @AfterClass(alwaysRun = true)
+ public static void tearDownAfterClass() throws Exception
+ {
+ jalview.gui.Desktop.instance.closeAll_actionPerformed(null);
+ }
+
+ @BeforeTest(alwaysRun = true)
+ public static void clearDesktop()
+ {
+ if (Desktop.instance != null && Desktop.getAlignFrames() != null)
+ {
+ Desktop.instance.closeAll_actionPerformed(null);
+ }
+ }
+
+ public int countDsAnn(jalview.viewmodel.AlignmentViewport avp)
+ {
+ int numdsann = 0;
+ for (SequenceI sq : avp.getAlignment().getDataset().getSequences())
+ {
+ if (sq.getAnnotation() != null)
+ {
+ for (AlignmentAnnotation dssa : sq.getAnnotation())
+ {
+ if (dssa.isValidStruc())
+ {
+ numdsann++;
+ }
+ }
+ }
+ }
+ return numdsann;
+ }
+
+}
import jalview.api.AlignViewportI;
import jalview.api.AlignmentViewPanel;
import jalview.api.ViewStyleI;
-import jalview.bin.Cache;
import jalview.datamodel.AlignmentAnnotation;
import jalview.datamodel.AlignmentI;
import jalview.datamodel.HiddenSequences;
+import jalview.datamodel.PDBEntry;
+import jalview.datamodel.PDBEntry.Type;
import jalview.datamodel.SequenceCollectionI;
import jalview.datamodel.SequenceGroup;
import jalview.datamodel.SequenceI;
import jalview.gui.AlignFrame;
+import jalview.gui.AlignmentPanel;
import jalview.gui.Desktop;
import jalview.gui.Jalview2XML;
import jalview.schemes.AnnotationColourGradient;
import jalview.schemes.ColourSchemeI;
+import jalview.schemes.ColourSchemeProperty;
+import jalview.schemes.TCoffeeColourScheme;
+import jalview.structure.StructureImportSettings;
import jalview.viewmodel.AlignmentViewport;
import java.io.File;
import org.testng.Assert;
import org.testng.AssertJUnit;
-import org.testng.annotations.AfterClass;
-import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
@Test(singleThreaded = true)
-public class Jalview2xmlTests
+public class Jalview2xmlTests extends Jalview2xmlBase
{
- /**
- * @throws java.lang.Exception
- */
- @BeforeClass(alwaysRun = true)
- public static void setUpBeforeClass() throws Exception
- {
- jalview.bin.Jalview.main(new String[] { "-props",
- "test/jalview/io/testProps.jvprops" });
- }
-
- /**
- * @throws java.lang.Exception
- */
- @AfterClass(alwaysRun = true)
- public static void tearDownAfterClass() throws Exception
- {
- jalview.gui.Desktop.instance.closeAll_actionPerformed(null);
- }
-
- int countDsAnn(jalview.viewmodel.AlignmentViewport avp)
- {
- int numdsann = 0;
- for (SequenceI sq : avp.getAlignment().getDataset().getSequences())
- {
- if (sq.getAnnotation() != null)
- {
- for (AlignmentAnnotation dssa : sq.getAnnotation())
- {
- if (dssa.isValidStruc())
- {
- numdsann++;
- }
- }
- }
- }
- return numdsann;
- }
-
@Test(groups = { "Functional" })
public void testRNAStructureRecovery() throws Exception
{
String inFile = "examples/RF00031_folded.stk";
String tfile = File.createTempFile("JalviewTest", ".jvp")
.getAbsolutePath();
- AlignFrame af = new jalview.io.FileLoader().LoadFileWaitTillLoaded(
- inFile, FormatAdapter.FILE);
- assertTrue("Didn't read input file " + inFile, af != null);
+ AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(inFile,
+ FormatAdapter.FILE);
+ assertNotNull("Didn't read input file " + inFile, af);
int olddsann = countDsAnn(af.getViewport());
assertTrue("Didn't find any dataset annotations", olddsann > 0);
af.rnahelicesColour_actionPerformed(null);
af.saveAlignment(tfile, "Jalview"));
af.closeMenuItem_actionPerformed(true);
af = null;
- af = new jalview.io.FileLoader().LoadFileWaitTillLoaded(tfile,
- FormatAdapter.FILE);
- assertTrue("Failed to import new project", af != null);
+ af = new FileLoader().LoadFileWaitTillLoaded(tfile, FormatAdapter.FILE);
+ assertNotNull("Failed to import new project", af);
int newdsann = countDsAnn(af.getViewport());
assertTrue(
"Differing numbers of dataset sequence annotation\nOriginally "
String inFile = "examples/uniref50.fa", inAnnot = "examples/uniref50.score_ascii";
String tfile = File.createTempFile("JalviewTest", ".jvp")
.getAbsolutePath();
- AlignFrame af = new jalview.io.FileLoader().LoadFileWaitTillLoaded(
- inFile, FormatAdapter.FILE);
- assertTrue("Didn't read input file " + inFile, af != null);
+ AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(inFile,
+ FormatAdapter.FILE);
+ assertNotNull("Didn't read input file " + inFile, af);
af.loadJalviewDataFile(inAnnot, FormatAdapter.FILE, null, null);
- assertTrue(
- "Didn't set T-coffee colourscheme",
- af.getViewport().getGlobalColourScheme().getClass()
- .equals(jalview.schemes.TCoffeeColourScheme.class));
- assertTrue(
- "Recognise T-Coffee score from string",
+ assertSame("Didn't set T-coffee colourscheme", af.getViewport()
+ .getGlobalColourScheme().getClass(), TCoffeeColourScheme.class);
+ assertNotNull("Recognise T-Coffee score from string",
jalview.schemes.ColourSchemeProperty.getColour(af.getViewport()
- .getAlignment(),
- jalview.schemes.ColourSchemeProperty.getColourName(af
- .getViewport().getGlobalColourScheme())) != null);
+ .getAlignment(), ColourSchemeProperty.getColourName(af
+ .getViewport().getGlobalColourScheme())));
assertTrue("Failed to store as a project.",
af.saveAlignment(tfile, "Jalview"));
af.closeMenuItem_actionPerformed(true);
af = null;
- af = new jalview.io.FileLoader().LoadFileWaitTillLoaded(tfile,
- FormatAdapter.FILE);
- assertTrue("Failed to import new project", af != null);
- assertTrue(
- "Didn't set T-coffee colourscheme for imported project.",
- af.getViewport().getGlobalColourScheme().getClass()
- .equals(jalview.schemes.TCoffeeColourScheme.class));
+ af = new FileLoader().LoadFileWaitTillLoaded(tfile, FormatAdapter.FILE);
+ assertNotNull("Failed to import new project", af);
+ assertSame("Didn't set T-coffee colourscheme for imported project.", af
+ .getViewport().getGlobalColourScheme().getClass(),
+ TCoffeeColourScheme.class);
System.out
.println("T-Coffee score shading successfully recovered from project.");
}
String inFile = "examples/uniref50.fa", inAnnot = "examples/testdata/uniref50_iupred.jva";
String tfile = File.createTempFile("JalviewTest", ".jvp")
.getAbsolutePath();
- AlignFrame af = new jalview.io.FileLoader().LoadFileWaitTillLoaded(
- inFile, FormatAdapter.FILE);
- assertTrue("Didn't read input file " + inFile, af != null);
+ AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(inFile,
+ FormatAdapter.FILE);
+ assertNotNull("Didn't read input file " + inFile, af);
af.loadJalviewDataFile(inAnnot, FormatAdapter.FILE, null, null);
AlignmentAnnotation[] aa = af.getViewport().getAlignment()
.getSequenceAt(0).getAnnotation("IUPredWS (Short)");
assertTrue(
"Didn't find any IUPred annotation to use to shade alignment.",
aa != null && aa.length > 0);
- AnnotationColourGradient cs = new jalview.schemes.AnnotationColourGradient(
- aa[0], null, AnnotationColourGradient.ABOVE_THRESHOLD);
- AnnotationColourGradient gcs = new jalview.schemes.AnnotationColourGradient(
- aa[0], null, AnnotationColourGradient.BELOW_THRESHOLD);
+ AnnotationColourGradient cs = new AnnotationColourGradient(aa[0], null,
+ AnnotationColourGradient.ABOVE_THRESHOLD);
+ AnnotationColourGradient gcs = new AnnotationColourGradient(aa[0],
+ null, AnnotationColourGradient.BELOW_THRESHOLD);
cs.setSeqAssociated(true);
gcs.setSeqAssociated(true);
af.changeColour(cs);
af.saveAlignment(tfile, "Jalview"));
af.closeMenuItem_actionPerformed(true);
af = null;
- af = new jalview.io.FileLoader().LoadFileWaitTillLoaded(tfile,
- FormatAdapter.FILE);
- assertTrue("Failed to import new project", af != null);
+ af = new FileLoader().LoadFileWaitTillLoaded(tfile, FormatAdapter.FILE);
+ assertNotNull("Failed to import new project", af);
// check for group and alignment colourschemes
ColourSchemeI _rcs = af.getViewport().getGlobalColourScheme();
ColourSchemeI _rgcs = af.getViewport().getAlignment().getGroups()
.get(0).cs;
- assertTrue("Didn't recover global colourscheme", _rcs != null);
+ assertNotNull("Didn't recover global colourscheme", _rcs);
assertTrue("Didn't recover annotation colour global scheme",
_rcs instanceof AnnotationColourGradient);
AnnotationColourGradient __rcs = (AnnotationColourGradient) _rcs;
System.out
.println("Per sequence colourscheme (Background) successfully applied and recovered.");
- assertTrue("Didn't recover group colourscheme", _rgcs != null);
+ assertNotNull("Didn't recover group colourscheme", _rgcs);
assertTrue("Didn't recover annotation colour group colourscheme",
_rgcs instanceof AnnotationColourGradient);
__rcs = (AnnotationColourGradient) _rgcs;
{
int origCount = Desktop.getAlignFrames() == null ? 0 : Desktop
.getAlignFrames().length;
- AlignFrame af = new jalview.io.FileLoader().LoadFileWaitTillLoaded(
+ AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
"examples/exampleFile_2_7.jar", FormatAdapter.FILE);
- assertTrue("Didn't read in the example file correctly.", af != null);
+ assertNotNull("Didn't read in the example file correctly.", af);
assertTrue("Didn't gather the views in the example file.",
Desktop.getAlignFrames().length == 1 + origCount);
@Test(groups = { "Functional" })
public void viewRefPdbAnnotation() throws Exception
{
- Cache.applicationProperties.setProperty("STRUCT_FROM_PDB",
- Boolean.TRUE.toString());
- Cache.applicationProperties.setProperty("ADD_SS_ANN",
- Boolean.TRUE.toString());
- AlignFrame af = new jalview.io.FileLoader().LoadFileWaitTillLoaded(
+ StructureImportSettings.setProcessSecondaryStructure(true);
+ StructureImportSettings.setVisibleChainAnnotation(true);
+ AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
"examples/exampleFile_2_7.jar", FormatAdapter.FILE);
- assertTrue("Didn't read in the example file correctly.", af != null);
+ assertNotNull("Didn't read in the example file correctly.", af);
AlignmentViewPanel sps = null;
for (AlignmentViewPanel ap : af.alignPanel.alignFrame.getAlignPanels())
{
break;
}
}
- assertTrue("Couldn't find the structure view", sps != null);
- SequenceI sq = sps.getAlignment().findName("1A70|");
+ assertNotNull("Couldn't find the structure view", sps);
AlignmentAnnotation refan = null;
for (AlignmentAnnotation ra : sps.getAlignment()
.getAlignmentAnnotation())
break;
}
}
- assertTrue("Annotation secondary structure not found.", refan != null);
- assertTrue("Couldn't find 1a70 null chain", sq != null);
+ assertNotNull("Annotation secondary structure not found.", refan);
+ SequenceI sq = sps.getAlignment().findName("1A70|");
+ assertNotNull("Couldn't find 1a70 null chain", sq);
// compare the manually added temperature factor annotation
// to the track automatically transferred from the pdb structure on load
+ assertNotNull("1a70 has no annotation", sq.getDatasetSequence()
+ .getAnnotation());
for (AlignmentAnnotation ala : sq.getDatasetSequence().getAnnotation())
{
AlignmentAnnotation alaa;
@Test(groups = { "Functional" })
public void testCopyViewSettings() throws Exception
{
- AlignFrame af = new jalview.io.FileLoader().LoadFileWaitTillLoaded(
+ AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
"examples/exampleFile_2_7.jar", FormatAdapter.FILE);
- assertTrue("Didn't read in the example file correctly.", af != null);
+ assertNotNull("Didn't read in the example file correctly.", af);
AlignmentViewPanel sps = null, groups = null;
for (AlignmentViewPanel ap : af.alignPanel.alignFrame.getAlignPanels())
{
groups = ap;
}
}
- assertTrue("Couldn't find the structure view", sps != null);
- assertTrue("Couldn't find the MAFFT view", groups != null);
+ assertNotNull("Couldn't find the structure view", sps);
+ assertNotNull("Couldn't find the MAFFT view", groups);
ViewStyleI structureStyle = sps.getAlignViewport().getViewStyle();
ViewStyleI groupStyle = groups.getAlignViewport().getViewStyle();
}
/**
- * test store and recovery of expanded views - currently this is disabled
- * since the Desktop.explodeViews method doesn't seem to result in the views
- * being expanded to distinct align frames when executed programmatically.
+ * test store and recovery of expanded views
*
* @throws Exception
*/
@Test(groups = { "Functional" }, enabled = true)
public void testStoreAndRecoverExpandedviews() throws Exception
{
- AlignFrame af = new jalview.io.FileLoader().LoadFileWaitTillLoaded(
+ Desktop.instance.closeAll_actionPerformed(null);
+
+ AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
"examples/exampleFile_2_7.jar", FormatAdapter.FILE);
- assertTrue("Didn't read in the example file correctly.", af != null);
+ Assert.assertEquals(Desktop.getAlignFrames().length, 1);
String afid = af.getViewport().getSequenceSetId();
- {
- final AlignFrame xaf = af;
- af = null;
- new Thread(new Runnable()
- {
- @Override
- public void run()
- {
- Desktop.instance.explodeViews(xaf);
- }
- }).start();
- Thread.sleep(1000);
- }
- // int times = 0;
- // while (++times < 5 && Desktop.getAlignFrames().length < )
- // {
- // Thread.sleep(300);
- // }
+
+ // check FileLoader returned a reference to the one alignFrame that is
+ // actually on the Desktop
+ assertTrue(
+ "Jalview2XML.loadAlignFrame() didn't return correct AlignFrame reference for multiple view window",
+ af == Desktop.getAlignFrameFor(af.getViewport()));
+
+ Desktop.explodeViews(af);
+
int oldviews = Desktop.getAlignFrames().length;
Assert.assertEquals(Desktop.getAlignFrames().length,
Desktop.getAlignmentPanels(afid).length);
{
Assert.assertEquals(Desktop.getAlignFrames().length, 0);
}
- af = new jalview.io.FileLoader().LoadFileWaitTillLoaded(
- tfile.getAbsolutePath(), FormatAdapter.FILE);
+ af = new FileLoader().LoadFileWaitTillLoaded(tfile.getAbsolutePath(),
+ FormatAdapter.FILE);
Assert.assertNotNull(af);
Assert.assertEquals(
Desktop.getAlignFrames().length,
Desktop.instance.closeAll_actionPerformed(null);
AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
"examples/exampleFile_2_7.jar", FormatAdapter.FILE);
- assertTrue("Didn't read in the example file correctly.", af != null);
+ assertNotNull("Didn't read in the example file correctly.", af);
String afid = af.getViewport().getSequenceSetId();
// remember reference sequence for each panel
Assert.assertEquals(Desktop.getAlignFrames().length, 0);
}
- af = new FileLoader().LoadFileWaitTillLoaded(
- tfile.getAbsolutePath(), FormatAdapter.FILE);
+ af = new FileLoader().LoadFileWaitTillLoaded(tfile.getAbsolutePath(),
+ FormatAdapter.FILE);
afid = af.getViewport().getSequenceSetId();
for (AlignmentViewPanel ap : Desktop.getAlignmentPanels(afid))
Desktop.instance.closeAll_actionPerformed(null);
AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
"examples/uniref50.fa", FormatAdapter.FILE);
- assertTrue("Didn't read in the example file correctly.", af != null);
+ assertNotNull("Didn't read in the example file correctly.", af);
String afid = af.getViewport().getSequenceSetId();
// make a second view of the alignment
af.newView_actionPerformed(null);
-
+
/*
* remember representative and hidden sequences marked
* on each panel
*/
Map<String, SequenceI> repSeqs = new HashMap<String, SequenceI>();
Map<String, List<String>> hiddenSeqNames = new HashMap<String, List<String>>();
-
+
/*
* mark sequence 2, 3, 4.. in panels 1, 2, 3...
* as reference sequence for itself and the preceding sequence
repSeqs.put(ap.getViewName(), repSeq);
List<String> hiddenNames = new ArrayList<String>();
hiddenSeqNames.put(ap.getViewName(), hiddenNames);
-
+
/*
* have rep sequence represent itself and the one before it
* this hides the group (except for the rep seq)
assertTrue(sg.getSequences().contains(repSeq));
assertTrue(sg.getSequences().contains(precedingSeq));
assertTrue("alignment has groups", alignment.getGroups().isEmpty());
- Map<SequenceI, SequenceCollectionI> hiddenRepSeqsMap = av.getHiddenRepSequences();
+ Map<SequenceI, SequenceCollectionI> hiddenRepSeqsMap = av
+ .getHiddenRepSequences();
assertNotNull(hiddenRepSeqsMap);
assertEquals(1, hiddenRepSeqsMap.size());
assertSame(sg, hiddenRepSeqsMap.get(repSeq));
n++;
}
File tfile = File
- .createTempFile("testStoreAndRecoverGroupReps",
- ".jvp");
+ .createTempFile("testStoreAndRecoverGroupReps", ".jvp");
try
{
new Jalview2XML(false).saveState(tfile);
{
Assert.assertEquals(Desktop.getAlignFrames().length, 0);
}
-
- af = new FileLoader().LoadFileWaitTillLoaded(
- tfile.getAbsolutePath(), FormatAdapter.FILE);
+
+ af = new FileLoader().LoadFileWaitTillLoaded(tfile.getAbsolutePath(),
+ FormatAdapter.FILE);
afid = af.getViewport().getSequenceSetId();
-
+
for (AlignmentViewPanel ap : Desktop.getAlignmentPanels(afid))
{
String viewName = ap.getViewName();
HiddenSequences hs = alignment.getHiddenSequences();
assertEquals(
"wrong number of restored hidden sequences in "
- + ap.getViewName(),
- hidden.size(), hs.getSize());
+ + ap.getViewName(), hidden.size(), hs.getSize());
+ }
+ }
+
+ /**
+ * Test save and reload of PDBEntry in Jalview project
+ *
+ * @throws Exception
+ */
+ @Test(groups = { "Functional" })
+ public void testStoreAndRecoverPDBEntry() throws Exception
+ {
+ Desktop.instance.closeAll_actionPerformed(null);
+ String exampleFile = "examples/3W5V.pdb";
+ AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(exampleFile,
+ FormatAdapter.FILE);
+ assertNotNull("Didn't read in the example file correctly.", af);
+ String afid = af.getViewport().getSequenceSetId();
+
+ AlignmentPanel[] alignPanels = Desktop.getAlignmentPanels(afid);
+ System.out.println();
+ AlignmentViewPanel ap = alignPanels[0];
+ String tfileBase = new File(".").getAbsolutePath().replace(".", "");
+ String testFile = tfileBase + exampleFile;
+ AlignmentI alignment = ap.getAlignment();
+ System.out.println("blah");
+ SequenceI[] seqs = alignment.getSequencesArray();
+ Assert.assertNotNull(seqs[0]);
+ Assert.assertNotNull(seqs[1]);
+ Assert.assertNotNull(seqs[2]);
+ Assert.assertNotNull(seqs[3]);
+ Assert.assertNotNull(seqs[0].getDatasetSequence());
+ Assert.assertNotNull(seqs[1].getDatasetSequence());
+ Assert.assertNotNull(seqs[2].getDatasetSequence());
+ Assert.assertNotNull(seqs[3].getDatasetSequence());
+ PDBEntry[] pdbEntries = new PDBEntry[4];
+ pdbEntries[0] = new PDBEntry("3W5V", "A", Type.PDB, testFile);
+ pdbEntries[1] = new PDBEntry("3W5V", "B", Type.PDB, testFile);
+ pdbEntries[2] = new PDBEntry("3W5V", "C", Type.PDB, testFile);
+ pdbEntries[3] = new PDBEntry("3W5V", "D", Type.PDB, testFile);
+ Assert.assertEquals(seqs[0].getDatasetSequence().getAllPDBEntries()
+ .get(0), pdbEntries[0]);
+ Assert.assertEquals(seqs[1].getDatasetSequence().getAllPDBEntries()
+ .get(0), pdbEntries[1]);
+ Assert.assertEquals(seqs[2].getDatasetSequence().getAllPDBEntries()
+ .get(0), pdbEntries[2]);
+ Assert.assertEquals(seqs[3].getDatasetSequence().getAllPDBEntries()
+ .get(0), pdbEntries[3]);
+
+ File tfile = File.createTempFile("testStoreAndRecoverPDBEntry", ".jvp");
+ try
+ {
+ new Jalview2XML(false).saveState(tfile);
+ } catch (Throwable e)
+ {
+ Assert.fail("Didn't save the state", e);
+ }
+ Desktop.instance.closeAll_actionPerformed(null);
+ if (Desktop.getAlignFrames() != null)
+ {
+ Assert.assertEquals(Desktop.getAlignFrames().length, 0);
+ }
+
+ AlignFrame restoredFrame = new FileLoader().LoadFileWaitTillLoaded(
+ tfile.getAbsolutePath(), FormatAdapter.FILE);
+ String rfid = restoredFrame.getViewport().getSequenceSetId();
+ AlignmentPanel[] rAlignPanels = Desktop.getAlignmentPanels(rfid);
+ AlignmentViewPanel rap = rAlignPanels[0];
+ AlignmentI rAlignment = rap.getAlignment();
+ System.out.println("blah");
+ SequenceI[] rseqs = rAlignment.getSequencesArray();
+ Assert.assertNotNull(rseqs[0]);
+ Assert.assertNotNull(rseqs[1]);
+ Assert.assertNotNull(rseqs[2]);
+ Assert.assertNotNull(rseqs[3]);
+ Assert.assertNotNull(rseqs[0].getDatasetSequence());
+ Assert.assertNotNull(rseqs[1].getDatasetSequence());
+ Assert.assertNotNull(rseqs[2].getDatasetSequence());
+ Assert.assertNotNull(rseqs[3].getDatasetSequence());
+
+ // The Asserts below are expected to fail until the PDB chainCode is
+ // recoverable from a Jalview projects
+ for (int chain = 0; chain < 4; chain++)
+ {
+ PDBEntry recov = rseqs[chain].getDatasetSequence().getAllPDBEntries()
+ .get(0);
+ PDBEntry expected = pdbEntries[chain];
+ Assert.assertEquals(recov.getId(), expected.getId(),
+ "Mismatch PDB ID");
+ Assert.assertEquals(recov.getChainCode(), expected.getChainCode(),
+ "Mismatch PDB ID");
+ Assert.assertEquals(recov.getType(), expected.getType(),
+ "Mismatch PDBEntry 'Type'");
+ Assert.assertNotNull(recov.getFile(),
+ "Recovered PDBEntry should have a non-null file entry");
}
}
}
AssertJUnit.assertTrue(stage + "Null Tree", tree_regen != null);
stage = "Compare original and generated tree" + treename;
- Vector oseqs, nseqs;
- oseqs = new NJTree(new SequenceI[0], nf).findLeaves(nf.getTree(),
- new Vector());
+ Vector<SequenceNode> oseqs, nseqs;
+ oseqs = new NJTree(new SequenceI[0], nf).findLeaves(nf.getTree());
AssertJUnit.assertTrue(stage + "No nodes in original tree.",
oseqs.size() > 0);
SequenceI[] olsqs = new SequenceI[oseqs.size()];
for (int i = 0, iSize = oseqs.size(); i < iSize; i++)
{
- olsqs[i] = (SequenceI) ((SequenceNode) oseqs.get(i)).element();
+ olsqs[i] = (SequenceI) oseqs.get(i).element();
}
- nseqs = new NJTree(new SequenceI[0], nf_regen).findLeaves(
- nf_regen.getTree(), new Vector());
+ nseqs = new NJTree(new SequenceI[0], nf_regen).findLeaves(nf_regen
+ .getTree());
AssertJUnit.assertTrue(stage + "No nodes in regerated tree.",
nseqs.size() > 0);
SequenceI[] nsqs = new SequenceI[nseqs.size()];
for (int i = 0, iSize = nseqs.size(); i < iSize; i++)
{
- nsqs[i] = (SequenceI) ((SequenceNode) nseqs.get(i)).element();
+ nsqs[i] = (SequenceI) nseqs.get(i).element();
}
AssertJUnit.assertTrue(stage
+ " Different number of leaves (original " + olsqs.length
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
package jalview.io;
import jalview.datamodel.AlignmentI;
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
package jalview.io;
import static org.testng.AssertJUnit.assertEquals;
SequenceFeature sf = new SequenceFeature("METAL", "Fe2-S", 1, 3,
Float.NaN, "group");
sf.setStatus("Confirmed");
-
+
sar.appendFeature(sb, 1, null, sf);
assertEquals("METAL 1 3; Fe2-S; (Confirmed)", sb.toString());
}
StringBuffer sb = new StringBuffer();
SequenceFeature sf = new SequenceFeature("METAL", "Fe2-S", 1, 3,
Float.NaN, "group");
-
+
sar.appendFeature(sb, 1, null, sf);
assertEquals("METAL 1 3; Fe2-S", sb.toString());
}
SequenceFeature sf = new SequenceFeature("METAL", "Fe2-S", 1, 3,
Float.NaN, "group");
sf.setValue("clinical_significance", "Benign");
-
+
sar.appendFeature(sb, 1, null, sf);
assertEquals("METAL 1 3; Fe2-S; Benign", sb.toString());
}
StringBuffer sb = new StringBuffer();
SequenceFeature sf = new SequenceFeature("METAL", "METAL", 1, 3,
Float.NaN, "group");
-
+
// description is not included if it duplicates type:
sar.appendFeature(sb, 1, null, sf);
assertEquals("METAL 1 3", sb.toString());
SequenceFeature sf = new SequenceFeature("METAL",
"<html><body>hello<em>world</em></body></html>", 1, 3,
Float.NaN, "group");
-
+
sar.appendFeature(sb, 1, null, sf);
// !! strips off </body> but not <body> ??
- assertEquals("METAL 1 3; <body>hello<em>world</em>",
- sb.toString());
+ assertEquals("METAL 1 3; <body>hello<em>world</em>", sb.toString());
sb.setLength(0);
sf.setDescription("<br>&kHD>6");
import static org.testng.AssertJUnit.assertEquals;
import static org.testng.AssertJUnit.assertNotNull;
import static org.testng.AssertJUnit.assertTrue;
+import static org.testng.AssertJUnit.fail;
import jalview.datamodel.AlignmentAnnotation;
import jalview.datamodel.AlignmentI;
// make sure dataset is initialised ? not sure about this
for (int i = 0; i < al.getSequencesArray().length; ++i)
{
- al.getSequenceAt(i).setDatasetSequence(al.getSequenceAt(i));
+ al.getSequenceAt(i).createDatasetSequence();
}
String outputfile = rf.formatSequences(ioformat, al, true);
System.out.println("Output file in '" + ioformat + "':\n"
* 'secondary' or generated alignment from some datapreserving
* transformation
* @param ignoreFeatures
- * when true, differences in seuqence feature annotation are ignored.
+ * when true, differences in sequence feature annotation are ignored
*/
public static void testAlignmentEquivalence(AlignmentI al,
AlignmentI al_input, boolean ignoreFeatures)
assertNotNull("Original alignment was null", al);
assertNotNull("Generated alignment was null", al_input);
- assertTrue(
- "Alignment dimension mismatch: originl contains "
- + al.getHeight() + " and generated has "
- + al_input.getHeight() + " sequences; original has "
- + al.getWidth() + " and generated has "
- + al_input.getWidth() + " columns.",
+ assertTrue("Alignment dimension mismatch: original: " + al.getHeight()
+ + "x" + al.getWidth() + ", generated: " + al_input.getHeight()
+ + "x" + al_input.getWidth(),
al.getHeight() == al_input.getHeight()
&& al.getWidth() == al_input.getWidth());
// note - at moment we do not distinguish between alignment without any
// annotation rows and alignment with no annotation row vector
// we might want to revise this in future
- int aa_new_size = (aa_new == null ? 0 : aa_new.length), aa_original_size = (aa_original == null ? 0
- : aa_original.length);
- Map<Integer, java.util.BitSet> orig_groups = new HashMap<Integer, java.util.BitSet>(), new_groups = new HashMap<Integer, java.util.BitSet>();
+ 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>();
if (aa_new != null && aa_original != null)
{
assertTrue("Different alignment annotation at position " + i,
equalss(aa_original[i], aa_new[i]));
// compare graphGroup or graph properties - needed to verify JAL-1299
- assertTrue("Graph type not identical.",
- aa_original[i].graph == aa_new[i].graph);
- assertTrue("Visibility not identical.",
- aa_original[i].visible == aa_new[i].visible);
- assertTrue(
- "Threshold line not identical.",
- aa_original[i].threshold == null ? aa_new[i].threshold == null
- : aa_original[i].threshold
- .equals(aa_new[i].threshold));
+ assertEquals("Graph type not identical.", aa_original[i].graph,
+ aa_new[i].graph);
+ assertEquals("Visibility not identical.", aa_original[i].visible,
+ aa_new[i].visible);
+ assertEquals("Threshold line not identical.",
+ aa_original[i].threshold, aa_new[i].threshold);
// graphGroup may differ, but pattern should be the same
- Integer o_ggrp = new Integer(aa_original[i].graphGroup + 2), n_ggrp = new Integer(
- aa_new[i].graphGroup + 2);
- BitSet orig_g = orig_groups.get(o_ggrp), new_g = new_groups
- .get(n_ggrp);
+ Integer o_ggrp = new Integer(aa_original[i].graphGroup + 2);
+ Integer n_ggrp = new Integer(aa_new[i].graphGroup + 2);
+ BitSet orig_g = orig_groups.get(o_ggrp);
+ BitSet new_g = new_groups.get(n_ggrp);
if (orig_g == null)
{
orig_groups.put(o_ggrp, orig_g = new BitSet());
{
new_groups.put(n_ggrp, new_g = new BitSet());
}
- assertTrue("Graph Group pattern differs at annotation " + i,
- orig_g.equals(new_g));
+ assertEquals("Graph Group pattern differs at annotation " + i,
+ orig_g, new_g);
orig_g.set(i);
new_g.set(i);
}
}
}
}
- assertTrue(
- "Generated and imported alignment have different annotation sets ("
- + aa_new_size + " != " + aa_original_size + ")",
- aa_new_size == aa_original_size);
+ assertEquals(
+ "Generated and imported alignment have different annotation sets",
+ aa_original_size, aa_new_size);
// check sequences, annotation and features
SequenceI[] seq_original = new SequenceI[al.getSequencesArray().length];
{
String ss_original = seq_original[i].getSequenceAsString();
String ss_new = seq_new[in].getSequenceAsString();
- assertTrue("The sequences " + name + "/" + start + "-" + end
- + " are not equal", ss_original.equals(ss_new));
+ assertEquals("The sequences " + name + "/" + start + "-" + end
+ + " are not equal", ss_original, ss_new);
assertTrue(
"Sequence Features were not equivalent"
.getSequenceFeatures().length];
sequenceFeatures_new = seq_new[in].getSequenceFeatures();
- assertTrue("different number of features", seq_original[i]
- .getSequenceFeatures().length == seq_new[in]
- .getSequenceFeatures().length);
+ assertEquals("different number of features",
+ seq_original[i].getSequenceFeatures().length,
+ seq_new[in].getSequenceFeatures().length);
for (int feat = 0; feat < seq_original[i].getSequenceFeatures().length; feat++)
{
- assertTrue("Different features",
- sequenceFeatures_original[feat]
- .equals(sequenceFeatures_new[feat]));
+ assertEquals("Different features",
+ sequenceFeatures_original[feat],
+ sequenceFeatures_new[feat]);
}
}
// compare alignment annotation
else if (al.getSequenceAt(i).getAnnotation() != null
&& al_input.getSequenceAt(in).getAnnotation() == null)
{
- assertTrue("Annotations differed between sequences ("
+ fail("Annotations differed between sequences ("
+ al.getSequenceAt(i).getName() + ") and ("
- + al_input.getSequenceAt(i).getName() + ")", false);
+ + al_input.getSequenceAt(i).getName() + ")");
}
break;
}
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
package jalview.io.gff;
import static org.testng.AssertJUnit.assertEquals;
{
FileLoader loader = new FileLoader(false);
AlignFrame af = loader.LoadFileWaitTillLoaded(
- "examples/testdata/exonerateseqs.fa",
- FormatAdapter.FILE);
-
+ "examples/testdata/exonerateseqs.fa", FormatAdapter.FILE);
+
af.loadJalviewDataFile("examples/testdata/exonerateoutput.gff",
FormatAdapter.FILE, null, null);
-
+
/*
* verify one mapping to a dummy sequence, one to a real one
*/
- List<AlignedCodonFrame> mappings = af
- .getViewport().getAlignment().getDataset().getCodonFrames();
+ List<AlignedCodonFrame> mappings = af.getViewport().getAlignment()
+ .getDataset().getCodonFrames();
assertEquals(2, mappings.size());
Iterator<AlignedCodonFrame> iter = mappings.iterator();
-
+
// first mapping is to dummy sequence
AlignedCodonFrame mapping = iter.next();
Mapping[] mapList = mapping.getProtMappings();
// 143 in protein should map to codon [11270, 11269, 11268] in dna
int[] mappedRegion = mapList[0].getMap().locateInFrom(143, 143);
assertArrayEquals(new int[] { 11270, 11268 }, mappedRegion);
-
+
// second mapping is to a sequence in the alignment
mapping = iter.next();
mapList = mapping.getProtMappings();
.findName("DDB_G0280897");
assertSame(proteinSeq.getDatasetSequence(), mapList[0].getTo());
assertEquals(1, mapping.getdnaToProt().length);
-
+
// 143 in protein should map to codon [11270, 11269, 11268] in dna
mappedRegion = mapList[0].getMap().locateInFrom(143, 143);
assertArrayEquals(new int[] { 11270, 11268 }, mappedRegion);
-
+
// 182 in protein should map to codon [11153, 11152, 11151] in dna
mappedRegion = mapList[0].getMap().locateInFrom(182, 182);
assertArrayEquals(new int[] { 11153, 11151 }, mappedRegion);
-
+
// and the reverse mapping:
mappedRegion = mapList[0].getMap().locateInTo(11151, 11153);
assertArrayEquals(new int[] { 182, 182 }, mappedRegion);
-
+
// 11150 in dna should _not_ map to protein
mappedRegion = mapList[0].getMap().locateInTo(11150, 11150);
assertNull(mappedRegion);
-
+
// similarly 183 in protein should _not_ map to dna
mappedRegion = mapList[0].getMap().locateInFrom(183, 183);
assertNull(mappedRegion);
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
package jalview.io.gff;
import static org.testng.AssertJUnit.assertEquals;
"GAATTCGTTCATGTAGGTTGATTTTTATT");
seq.createDatasetSequence();
AlignmentI align = new Alignment(new SequenceI[] {});
-
+
// mapping from gi|68711 12923-13060 to gi|N37351 1-138
String[] gff = "gi|68711\tblat-pasa\tcDNA_match\t12923\t13060\t98.55\t+\t.\tID=align_68;Target=gi|N37351 1 138 +"
.split("\\t");
// (this is important for 'align cdna to genome' to work correctly)
assertEquals(1, align.getCodonFrames().size());
AlignedCodonFrame mapping = align.getCodonFrames().get(0);
-
+
/*
* 'dnaseqs' (map from) is here [gi|68711]
* 'aaseqs' (map to) is here [gi|N37351]
assertEquals(1, mapping.getdnaToProt().length);
assertEquals(2, mapping.getdnaToProt()[0].getFromRanges().size());
// the two spliced dna ranges are combined in one MapList
- assertArrayEquals(new int[] { 12923, 13060 },
- mapping.getdnaToProt()[0]
+ assertArrayEquals(new int[] { 12923, 13060 }, mapping.getdnaToProt()[0]
.getFromRanges().get(0));
assertArrayEquals(new int[] { 13411, 13550 }, mapping.getdnaToProt()[0]
.getFromRanges().get(1));
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
package jalview.io.gff;
import static org.testng.AssertJUnit.assertEquals;
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
package jalview.io.gff;
import static org.testng.AssertJUnit.assertNull;
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
package jalview.io.gff;
import static org.testng.AssertJUnit.assertEquals;
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
package jalview.io.gff;
import static org.testng.AssertJUnit.assertEquals;
seq.createDatasetSequence();
AlignmentI align = new Alignment(new SequenceI[] {});
Map<String, List<String>> set = Gff3Helper.parseNameValuePairs(gff[8]);
-
+
/*
* this should create a mapping from Prot1/5-30 to virtual sequence
* match$17_5_30 (added to newseqs) positions 1-26
--- /dev/null
+#---JalviewX Properties File---
+#Fri Apr 25 09:54:25 BST 2014
+SCREEN_Y=768
+SCREEN_X=936
+SHOW_WSDISCOVERY_ERRORS=true
+LATEST_VERSION=2.8.0b1
+SHOW_CONSERVATION=true
+JALVIEW_RSS_WINDOW_SCREEN_WIDTH=550
+JAVA_CONSOLE_SCREEN_WIDTH=450
+LAST_DIRECTORY=/Volumes/Data/Users/jimp/Documents/testing/Jalview/examples
+ID_ITALICS=true
+SORT_ALIGNMENT=No sort
+SHOW_IDENTITY=true
+WSMENU_BYHOST=false
+SEQUENCE_LINKS=EMBL-EBI Search|http\://www.ebi.ac.uk/ebisearch/search.ebi?db\=allebi&query\=$SEQUENCE_ID$
+SHOW_FULLSCREEN=false
+RECENT_URL=http\://www.jalview.org/examples/exampleFile_2_7.jar
+FONT_NAME=SansSerif
+BLC_JVSUFFIX=true
+VERSION_CHECK=false
+YEAR=2011
+SHOW_DBREFS_TOOLTIP=true
+MSF_JVSUFFIX=true
+SCREENGEOMETRY_HEIGHT=1600
+JAVA_CONSOLE_SCREEN_Y=475
+JAVA_CONSOLE_SCREEN_X=830
+PFAM_JVSUFFIX=true
+PIR_JVSUFFIX=true
+STARTUP_FILE=http\://www.jalview.org/examples/exampleFile_2_3.jar
+JAVA_CONSOLE_SCREEN_HEIGHT=162
+PIR_MODELLER=false
+GAP_SYMBOL=-
+SHOW_QUALITY=true
+SHOW_GROUP_CONSERVATION=false
+SHOW_JWS2_SERVICES=true
+SHOW_NPFEATS_TOOLTIP=true
+FONT_STYLE=plain
+ANTI_ALIAS=false
+SORT_BY_TREE=false
+RSBS_SERVICES=|Multi-Harmony|Analysis|Sequence Harmony and Multi-Relief (Brandt et al. 2010)|hseparable,gapCharacter\='-',returns\='ANNOTATION'|?tool\=jalview|http\://zeus.few.vu.nl/programs/shmrwww/index.php?tool\=jalview&groups\=$PARTITION\:min\='2',minsize\='2',sep\=' '$&ali_file\=$ALIGNMENT\:format\='FASTA',writeasfile$
+AUTHORFNAMES=Jim Procter, Andrew Waterhouse, Jan Engelhardt, Lauren Lui, Michele Clamp, James Cuff, Steve Searle, David Martin & Geoff Barton
+JALVIEW_RSS_WINDOW_SCREEN_HEIGHT=328
+SHOW_GROUP_CONSENSUS=false
+SHOW_CONSENSUS_HISTOGRAM=true
+SHOW_OVERVIEW=false
+AUTHORS=J Procter, AM Waterhouse, LM Lui, J Engelhardt, G Barton, M Clamp, S Searle
+FIGURE_AUTOIDWIDTH=false
+SCREEN_WIDTH=900
+ANNOTATIONCOLOUR_MIN=ffc800
+SHOW_STARTUP_FILE=false
+RECENT_FILE=examples/uniref50.fa\t/Volumes/Data/Users/jimp/Documents/testing/Jalview/examples/RF00031_folded.stk\t/Volumes/Data/Users/jimp/bs_ig_mult.out
+DEFAULT_FILE_FORMAT=FASTA
+SHOW_JAVA_CONSOLE=false
+VERSION=2.8b1
+FIGURE_USERIDWIDTH=
+WSMENU_BYTYPE=false
+DEFAULT_COLOUR=None
+NOQUESTIONNAIRES=true
+JALVIEW_NEWS_RSS_LASTMODIFIED=Apr 23, 2014 2\:53\:26 PM
+BUILD_DATE=01 November 2013
+PILEUP_JVSUFFIX=true
+SHOW_CONSENSUS_LOGO=false
+SCREENGEOMETRY_WIDTH=2560
+SHOW_ANNOTATIONS=true
+JALVIEW_RSS_WINDOW_SCREEN_Y=0
+USAGESTATS=false
+JALVIEW_RSS_WINDOW_SCREEN_X=0
+SHOW_UNCONSERVED=false
+SHOW_JVSUFFIX=true
+SCREEN_HEIGHT=650
+ANNOTATIONCOLOUR_MAX=ff0000
+AUTO_CALC_CONSENSUS=true
+FASTA_JVSUFFIX=true
+DAS_ACTIVE_SOURCE=
+JWS2HOSTURLS=http\://www.compbio.dundee.ac.uk/jabaws
+PAD_GAPS=false
+CLUSTAL_JVSUFFIX=true
+SHOW_ENFIN_SERVICES=true
+FONT_SIZE=10
+RIGHT_ALIGN_IDS=false
+USE_PROXY=false
+WRAP_ALIGNMENT=false
+DAS_REGISTRY_URL=http\://www.nowhere/
+ codon.getKey() + "\", \"" + codon.getValue() + "\");");
}
}
-
- @Test(groups = { "Functional" })
- public void checkOldCodonagainstNewCodonTable()
- {
- // note - this test will be removed once the old codon table (including
- // Vectors) is removed
- String additional = "", failtrans = "", differentTr = "";
- for (String amacid : ResidueProperties.codonHash.keySet())
- {
- for (String codon : ResidueProperties.codonHash.get(amacid))
- {
- String trans = ResidueProperties.codonTranslate(codon);
- String oldtrans = ResidueProperties._codonTranslate(codon);
- if (trans == null)
- {
- additional += "\nOld translation table includes additional codons for "
- + amacid + " : " + codon;
- }
- if (oldtrans == null)
- {
- failtrans += ("\nold translation routine failed for old translation entry (aa was "
- + amacid + " codon was " + codon + ")");
- }
- if (!oldtrans.equals(trans))
- {
- differentTr += ("\nDifferent translation for old and new routines: "
- + amacid
- + " "
- + codon
- + " => expected "
- + oldtrans
- + " and got " + trans);
- }
- }
- }
- assertTrue("" + additional + "\n" + failtrans + "\n" + differentTr,
- additional.length() == 0 && failtrans.length() == 0
- && differentTr.length() == 0);
- }
}
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
package jalview.schemes;
import static org.testng.AssertJUnit.assertEquals;
@Test(groups = { "Functional" })
public void testGetColor_Graduated()
{
- // graduated colour from score 0 to 100, gray(128, 128, 128) to red(255, 0, 0)
+ // graduated colour from score 0 to 100, gray(128, 128, 128) to red(255, 0,
+ // 0)
FeatureColour fc = new FeatureColour(Color.GRAY, Color.RED, 0f, 100f);
// feature score is 75 which is 3/4 of the way from GRAY to RED
SequenceFeature sf = new SequenceFeature("type", "desc", 0, 20, 75f,
String redHex = Format.getHexString(Color.RED);
String hexColour = redHex;
assertEquals("domain\t" + hexColour, fc.toJalviewFormat("domain"));
-
+
/*
* colour by label (no threshold)
*/
--- /dev/null
+package jalview.schemes;
+
+import static org.testng.AssertJUnit.assertEquals;
+import static org.testng.AssertJUnit.assertFalse;
+import static org.testng.AssertJUnit.assertTrue;
+
+import jalview.analysis.Profile;
+
+import java.awt.Color;
+
+import org.testng.annotations.Test;
+
+public class ResidueColourSchemeTest
+{
+ @Test(groups = "Functional")
+ public void testAboveThreshold()
+ {
+ /*
+ * make up profiles for this alignment:
+ * AR-Q
+ * AR--
+ * SR-T
+ * SR-T
+ */
+ Profile[] profiles = new Profile[4];
+ profiles[0] = new Profile(4, 0, 2, "AS");
+ profiles[1] = new Profile(4, 0, 4, "R");
+ profiles[2] = new Profile(4, 4, 0, "");
+ profiles[3] = new Profile(4, 1, 2, "T");
+ ResidueColourScheme rcs = new ResidueColourScheme();
+ rcs.setConsensus(profiles);
+
+ /*
+ * no threshold
+ */
+ rcs.setThreshold(0, true);
+ assertTrue(rcs.aboveThreshold('a', 0));
+ assertTrue(rcs.aboveThreshold('S', 0));
+ assertFalse(rcs.aboveThreshold('W', 0));
+ assertTrue(rcs.aboveThreshold('R', 1));
+ assertFalse(rcs.aboveThreshold('W', 2));
+ assertTrue(rcs.aboveThreshold('t', 3));
+ assertFalse(rcs.aboveThreshold('Q', 3));
+
+ /*
+ * with threshold, include gaps
+ */
+ rcs.setThreshold(60, false);
+ assertFalse(rcs.aboveThreshold('a', 0));
+ assertFalse(rcs.aboveThreshold('S', 0));
+ assertTrue(rcs.aboveThreshold('R', 1));
+ assertFalse(rcs.aboveThreshold('W', 2));
+ assertFalse(rcs.aboveThreshold('t', 3)); // 50% < 60%
+
+ /*
+ * with threshold, ignore gaps
+ */
+ rcs.setThreshold(60, true);
+ assertFalse(rcs.aboveThreshold('a', 0));
+ assertFalse(rcs.aboveThreshold('S', 0));
+ assertTrue(rcs.aboveThreshold('R', 1));
+ assertFalse(rcs.aboveThreshold('W', 2));
+ assertTrue(rcs.aboveThreshold('t', 3)); // 67% > 60%
+ }
+
+ /**
+ * Test colour bleaching based on conservation score and conservation slider.
+ * Scores of 10 or 11 should leave colours unchanged. Gap is always white.
+ */
+ @Test(groups = "Functional")
+ public void testApplyConservation()
+ {
+ ResidueColourScheme rcs = new ResidueColourScheme();
+
+ // no conservation present - no fading
+ assertEquals(Color.RED, rcs.applyConservation(Color.RED, 12));
+
+ // cheat by setting conservation sequence directly
+ // rather than calculating it - good enough for this test
+ String consensus = "0123456789+*-";
+ rcs.conservation = consensus.toCharArray();
+
+ // column out of range:
+ assertEquals(Color.RED,
+ rcs.applyConservation(Color.RED, consensus.length()));
+
+ /*
+ * with 100% threshold, 'fade factor' is
+ * (11-score)/10 * 100/20 = (11-score)/2
+ * which is >= 1 for all scores i.e. all fade to white except +, *
+ */
+ rcs.setConservationInc(100);
+ assertEquals(Color.WHITE, rcs.applyConservation(Color.RED, 0));
+ assertEquals(Color.WHITE, rcs.applyConservation(Color.RED, 1));
+ assertEquals(Color.WHITE, rcs.applyConservation(Color.RED, 2));
+ assertEquals(Color.WHITE, rcs.applyConservation(Color.RED, 3));
+ assertEquals(Color.WHITE, rcs.applyConservation(Color.RED, 4));
+ assertEquals(Color.WHITE, rcs.applyConservation(Color.RED, 5));
+ assertEquals(Color.WHITE, rcs.applyConservation(Color.RED, 6));
+ assertEquals(Color.WHITE, rcs.applyConservation(Color.RED, 7));
+ assertEquals(Color.WHITE, rcs.applyConservation(Color.RED, 8));
+ assertEquals(Color.WHITE, rcs.applyConservation(Color.RED, 9));
+ assertEquals(Color.RED, rcs.applyConservation(Color.RED, 10));
+ assertEquals(Color.RED, rcs.applyConservation(Color.RED, 11));
+ assertEquals(Color.WHITE, rcs.applyConservation(Color.RED, 12));
+
+ /*
+ * with 0% threshold, there should be no fading
+ */
+ rcs.setConservationInc(0);
+ assertEquals(Color.RED, rcs.applyConservation(Color.RED, 0));
+ assertEquals(Color.RED, rcs.applyConservation(Color.RED, 1));
+ assertEquals(Color.RED, rcs.applyConservation(Color.RED, 2));
+ assertEquals(Color.RED, rcs.applyConservation(Color.RED, 3));
+ assertEquals(Color.RED, rcs.applyConservation(Color.RED, 4));
+ assertEquals(Color.RED, rcs.applyConservation(Color.RED, 5));
+ assertEquals(Color.RED, rcs.applyConservation(Color.RED, 6));
+ assertEquals(Color.RED, rcs.applyConservation(Color.RED, 7));
+ assertEquals(Color.RED, rcs.applyConservation(Color.RED, 8));
+ assertEquals(Color.RED, rcs.applyConservation(Color.RED, 9));
+ assertEquals(Color.RED, rcs.applyConservation(Color.RED, 10));
+ assertEquals(Color.RED, rcs.applyConservation(Color.RED, 11));
+ assertEquals(Color.WHITE, rcs.applyConservation(Color.RED, 12)); // gap
+
+ /*
+ * with 40% threshold, 'fade factor' is
+ * (11-score)/10 * 40/20 = (11-score)/5
+ * which is {>1, >1, >1, >1, >1, >1, 1, 0.8, 0.6, 0.4} for score 0-9
+ * e.g. score 7 colour fades 80% of the way to white (255, 255, 255)
+ */
+ rcs.setConservationInc(40);
+ Color colour = new Color(155, 105, 55);
+ assertEquals(Color.WHITE, rcs.applyConservation(colour, 0));
+ assertEquals(Color.WHITE, rcs.applyConservation(colour, 1));
+ assertEquals(Color.WHITE, rcs.applyConservation(colour, 2));
+ assertEquals(Color.WHITE, rcs.applyConservation(colour, 3));
+ assertEquals(Color.WHITE, rcs.applyConservation(colour, 4));
+ assertEquals(Color.WHITE, rcs.applyConservation(colour, 5));
+ assertEquals(Color.WHITE, rcs.applyConservation(colour, 6));
+ assertEquals(new Color(235, 225, 215), rcs.applyConservation(colour, 7));
+ assertEquals(new Color(215, 195, 175), rcs.applyConservation(colour, 8));
+ assertEquals(new Color(195, 165, 135), rcs.applyConservation(colour, 9));
+ assertEquals(colour, rcs.applyConservation(colour, 10));
+ assertEquals(colour, rcs.applyConservation(colour, 11));
+ assertEquals(Color.WHITE, rcs.applyConservation(colour, 12));
+ }
+}
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
package jalview.schemes;
import static org.testng.AssertJUnit.assertEquals;
import java.awt.Color;
import org.testng.annotations.Test;
+
public class UserColourSchemeTest
{
- @Test(groups = "functional")
+ @Test(groups = "Functional")
public void testGetColourFromString()
{
/*
// Associate the 1GAQ pdb file with the subsequence 'imported' from another
// source
StructureFile pde = ssm.setMapping(true, new SequenceI[] { sq },
- new String[]
- { "A" }, inFile = "examples/1gaq.txt", jalview.io.FormatAdapter.FILE);
+ new String[] { "A" }, inFile = "examples/1gaq.txt",
+ jalview.io.FormatAdapter.FILE);
assertTrue("PDB File couldn't be found", pde != null);
StructureMapping[] mp = ssm.getMapping(inFile);
assertTrue("No mappings made.", mp != null && mp.length > 0);
@Test(groups = { "Functional" })
public void compareTransferredToRefPDBAnnot() throws Exception
{
- StructureViewSettings.setShowSeqFeatures(true);
+ StructureImportSettings.setShowSeqFeatures(true);
AlignFrame ref = new FileLoader(false)
.LoadFileWaitTillLoaded("test/jalview/ext/jmol/1QCF.pdb",
jalview.io.FormatAdapter.FILE);
import jalview.datamodel.SequenceI;
import jalview.io.FormatAdapter;
import jalview.io.StructureFile;
+import jalview.util.MapList;
import java.util.ArrayList;
import java.util.List;
@BeforeMethod(alwaysRun = true)
public void setUp()
{
- StructureViewSettings.setShowSeqFeatures(true);
+ StructureImportSettings.setShowSeqFeatures(true);
ssm = new StructureSelectionManager();
}
public void testRegisterMapping()
{
AlignedCodonFrame acf1 = new AlignedCodonFrame();
+ acf1.addMap(new Sequence("s1", "ttt"), new Sequence("p1", "p"),
+ new MapList(new int[] { 1, 3 }, new int[] { 1, 1 }, 1, 1));
AlignedCodonFrame acf2 = new AlignedCodonFrame();
+ acf2.addMap(new Sequence("s2", "ttt"), new Sequence("p2", "p"),
+ new MapList(new int[] { 1, 3 }, new int[] { 1, 1 }, 1, 1));
ssm.registerMapping(acf1);
assertEquals(1, ssm.getSequenceMappings().size());
public void testRegisterMappings()
{
AlignedCodonFrame acf1 = new AlignedCodonFrame();
+ acf1.addMap(new Sequence("s1", "ttt"), new Sequence("p1", "p"),
+ new MapList(new int[] { 1, 3 }, new int[] { 1, 1 }, 1, 1));
AlignedCodonFrame acf2 = new AlignedCodonFrame();
+ acf2.addMap(new Sequence("s2", "ttt"), new Sequence("p2", "p"),
+ new MapList(new int[] { 1, 3 }, new int[] { 1, 1 }, 1, 1));
AlignedCodonFrame acf3 = new AlignedCodonFrame();
+ acf3.addMap(new Sequence("s3", "ttt"), new Sequence("p3", "p"),
+ new MapList(new int[] { 1, 3 }, new int[] { 1, 1 }, 1, 1));
List<AlignedCodonFrame> set1 = new ArrayList<AlignedCodonFrame>();
set1.add(acf1);
*/
public class AAStructureBindingModelTest
{
+ /*
+ * Scenario: Jalview has 4 sequences, corresponding to 1YCS (chains A and B), 3A6S|B, 1OOT|A
+ */
private static final String PDB_1 = "HEADER COMPLEX (ANTI-ONCOGENE/ANKYRIN REPEATS) 30-SEP-96 1YCS \n"
+ "ATOM 2 CA VAL A 97 24.134 4.926 45.821 1.00 47.43 C \n"
+ "ATOM 9 CA PRO A 98 25.135 8.584 46.217 1.00 41.60 C \n"
+ "ATOM 16 CA SER A 99 28.243 9.596 44.271 1.00 39.63 C \n"
+ "ATOM 22 CA GLN A 100 31.488 10.133 46.156 1.00 35.60 C \n"
- + "ATOM 31 CA LYS A 101 33.323 11.587 43.115 1.00 41.69 C \n";
+ // artificial jump in residue numbering to prove it is correctly
+ // mapped:
+ + "ATOM 31 CA LYS A 102 33.323 11.587 43.115 1.00 41.69 C \n"
+ + "ATOM 1857 CA GLU B 374 9.193 -16.005 95.870 1.00 54.22 C \n"
+ + "ATOM 1866 CA ILE B 375 7.101 -14.921 92.847 1.00 46.82 C \n"
+ + "ATOM 1874 CA VAL B 376 10.251 -13.625 91.155 1.00 47.80 C \n"
+ + "ATOM 1881 CA LYS B 377 11.767 -17.068 91.763 1.00 50.21 C \n"
+ + "ATOM 1890 CA PHE B 378 8.665 -18.948 90.632 1.00 44.85 C \n";
private static final String PDB_2 = "HEADER HYDROLASE 09-SEP-09 3A6S \n"
- + "ATOM 2 CA MET A 1 15.366 -11.648 24.854 1.00 32.05 C \n"
- + "ATOM 10 CA LYS A 2 16.846 -9.215 22.340 1.00 25.68 C \n"
- + "ATOM 19 CA LYS A 3 15.412 -6.335 20.343 1.00 19.42 C \n"
- + "ATOM 28 CA LEU A 4 15.629 -5.719 16.616 1.00 15.49 C \n"
- + "ATOM 36 CA GLN A 5 14.412 -2.295 15.567 1.00 12.19 C \n";
+ + "ATOM 2 CA MET B 1 15.366 -11.648 24.854 1.00 32.05 C \n"
+ + "ATOM 10 CA LYS B 2 16.846 -9.215 22.340 1.00 25.68 C \n"
+ + "ATOM 19 CA LYS B 3 15.412 -6.335 20.343 1.00 19.42 C \n"
+ + "ATOM 28 CA LEU B 4 15.629 -5.719 16.616 1.00 15.49 C \n"
+ + "ATOM 36 CA GLN B 5 14.412 -2.295 15.567 1.00 12.19 C \n";
private static final String PDB_3 = "HEADER STRUCTURAL GENOMICS 04-MAR-03 1OOT \n"
- + "ATOM 2 CA SER A 1 29.427 3.330 -6.578 1.00 32.50 C \n"
- + "ATOM 8 CA PRO A 2 29.975 3.340 -2.797 1.00 17.62 C \n"
- + "ATOM 16 CA ALYS A 3 26.958 3.024 -0.410 0.50 8.78 C \n"
- + "ATOM 33 CA ALA A 4 26.790 4.320 3.172 1.00 11.98 C \n"
- + "ATOM 39 CA AVAL A 5 24.424 3.853 6.106 0.50 13.83 C \n";
+ + "ATOM 2 CA SER A 7 29.427 3.330 -6.578 1.00 32.50 C \n"
+ + "ATOM 8 CA PRO A 8 29.975 3.340 -2.797 1.00 17.62 C \n"
+ + "ATOM 16 CA ALYS A 9 26.958 3.024 -0.410 0.50 8.78 C \n"
+ + "ATOM 33 CA ALA A 10 26.790 4.320 3.172 1.00 11.98 C \n"
+ + "ATOM 39 CA AVAL A 12 24.424 3.853 6.106 0.50 13.83 C \n";
AAStructureBindingModel testee;
@BeforeMethod(alwaysRun = true)
public void setUp()
{
- SequenceI seq1 = new Sequence("1YCS", "-VPSQK");
+ SequenceI seq1a = new Sequence("1YCS|A", "-VPSQK");
+ SequenceI seq1b = new Sequence("1YCS|B", "EIVKF-");
SequenceI seq2 = new Sequence("3A6S", "MK-KLQ");
SequenceI seq3 = new Sequence("1OOT", "SPK-AV");
- al = new Alignment(new SequenceI[] { seq1, seq2, seq3 });
+ al = new Alignment(new SequenceI[] { seq1a, seq1b, seq2, seq3 });
al.setDataset(null);
+ /*
+ * give pdb files the name generated by Jalview for PASTE source
+ */
PDBEntry[] pdbFiles = new PDBEntry[3];
- pdbFiles[0] = new PDBEntry("1YCS", "A", Type.PDB, "1YCS.pdb");
- pdbFiles[1] = new PDBEntry("3A6S", "B", Type.PDB, "3A6S.pdb");
- pdbFiles[2] = new PDBEntry("1OOT", "A", Type.PDB, "1OOT.pdb");
+ pdbFiles[0] = new PDBEntry("1YCS", "A", Type.PDB, "INLINE1YCS");
+ pdbFiles[1] = new PDBEntry("3A6S", "B", Type.PDB, "INLINE3A6S");
+ pdbFiles[2] = new PDBEntry("1OOT", "A", Type.PDB, "INLINE1OOT");
String[][] chains = new String[3][];
SequenceI[][] seqs = new SequenceI[3][];
- seqs[0] = new SequenceI[] { seq1 };
+ seqs[0] = new SequenceI[] { seq1a, seq1b };
seqs[1] = new SequenceI[] { seq2 };
seqs[2] = new SequenceI[] { seq3 };
StructureSelectionManager ssm = new StructureSelectionManager();
- ssm.setMapping(new SequenceI[] { seq1 }, null, PDB_1,
+ ssm.setMapping(new SequenceI[] { seq1a, seq1b }, null, PDB_1,
AppletFormatAdapter.PASTE);
ssm.setMapping(new SequenceI[] { seq2 }, null, PDB_2,
AppletFormatAdapter.PASTE);
@Override
public String[] getPdbFile()
{
- /*
- * fudge 'filenames' to match those generated when PDBFile parses PASTE
- * data
- */
return new String[] { "INLINE1YCS", "INLINE3A6S", "INLINE1OOT" };
}
@Test(groups = { "Functional" })
public void testFindSuperposableResidues()
{
- SuperposeData[] structs = new SuperposeData[al.getHeight()];
+ /*
+ * create a data bean to hold data per structure file
+ */
+ SuperposeData[] structs = new SuperposeData[testee.getPdbFile().length];
for (int i = 0; i < structs.length; i++)
{
structs[i] = testee.new SuperposeData(al.getWidth());
*/
assertFalse(matched[0]); // gap in first sequence
assertTrue(matched[1]);
- assertFalse(matched[2]); // gap in second sequence
- assertFalse(matched[3]); // gap in third sequence
+ assertFalse(matched[2]); // gap in third sequence
+ assertFalse(matched[3]); // gap in fourth sequence
assertTrue(matched[4]);
- assertTrue(matched[5]);
+ assertTrue(matched[5]); // gap in second sequence
+
+ assertEquals("1YCS", structs[0].pdbId);
+ assertEquals("3A6S", structs[1].pdbId);
+ assertEquals("1OOT", structs[2].pdbId);
+ assertEquals("A", structs[0].chain); // ? struct has chains A _and_ B
+ assertEquals("B", structs[1].chain);
+ assertEquals("A", structs[2].chain);
+ // the 0's for unsuperposable positions propagate down the columns:
+ assertEquals("[0, 97, 98, 99, 100, 102]",
+ Arrays.toString(structs[0].pdbResNo));
+ assertEquals("[0, 2, 0, 3, 4, 5]", Arrays.toString(structs[1].pdbResNo));
+ assertEquals("[0, 8, 0, 0, 10, 12]",
+ Arrays.toString(structs[2].pdbResNo));
}
@Test(groups = { "Functional" })
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
package jalview.util;
import static org.testng.AssertJUnit.assertEquals;
public class ArrayUtilsTest
{
- @Test(groups="Functional")
- public void testReverseIntArray() {
+ @Test(groups = "Functional")
+ public void testReverseIntArray()
+ {
// null value: should be no exception
ArrayUtils.reverseIntArray((int[]) null);
--- /dev/null
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
+package jalview.util;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertNotEquals;
+import static org.testng.Assert.assertTrue;
+
+import org.testng.annotations.Test;
+
+public class CaseInsensitiveStringTest
+{
+ @Test(groups = "Functional")
+ public void testEquals()
+ {
+ CaseInsensitiveString s1 = new CaseInsensitiveString(null);
+ CaseInsensitiveString s2 = new CaseInsensitiveString("a");
+ CaseInsensitiveString s3 = new CaseInsensitiveString("A");
+ CaseInsensitiveString s4 = new CaseInsensitiveString("b");
+
+ assertFalse(s1.equals(null));
+ assertTrue(s1.equals(s1));
+ assertFalse(s1.equals(s2));
+ assertTrue(s2.equals(s2));
+ assertFalse(s2.equals(s1));
+ assertTrue(s2.equals(s3));
+ assertTrue(s3.equals(s2));
+ assertFalse(s3.equals(s4));
+ assertFalse(s4.equals(s3));
+ }
+
+ @Test(groups = "Functional")
+ public void testHashcode()
+ {
+ CaseInsensitiveString s1 = new CaseInsensitiveString(null);
+ CaseInsensitiveString s2 = new CaseInsensitiveString("a");
+ CaseInsensitiveString s3 = new CaseInsensitiveString("A");
+ CaseInsensitiveString s4 = new CaseInsensitiveString("b");
+
+ assertNotEquals(s1.hashCode(), s2.hashCode());
+ assertEquals(s2.hashCode(), s3.hashCode());
+ assertNotEquals(s3.hashCode(), s4.hashCode());
+ }
+}
import static org.testng.AssertJUnit.assertEquals;
import static org.testng.AssertJUnit.assertNull;
+import static org.testng.AssertJUnit.assertSame;
import java.awt.Color;
* value > max
*/
col = ColorUtils
- .getGraduatedColour(40f, 10f, minColour, 30f,
- maxColour);
+ .getGraduatedColour(40f, 10f, minColour, 30f, maxColour);
assertEquals(maxColour, col);
/*
.getGraduatedColour(40f, 10f, minColour, 10f, maxColour);
assertEquals(minColour, col);
}
+
+ @Test(groups = { "Functional" })
+ public void testBleachColour()
+ {
+ Color colour = new Color(155, 105, 55);
+ assertSame(colour, ColorUtils.bleachColour(colour, 0));
+ assertEquals(Color.WHITE, ColorUtils.bleachColour(colour, 1));
+ assertEquals(Color.WHITE, ColorUtils.bleachColour(colour, 2));
+ assertEquals(new Color(175, 135, 95),
+ ColorUtils.bleachColour(colour, 0.2f));
+ assertEquals(new Color(225, 210, 195),
+ ColorUtils.bleachColour(colour, 0.7f));
+
+ /*
+ * and some 'negative fade'
+ */
+ assertEquals(Color.BLACK, ColorUtils.bleachColour(colour, -1));
+ assertEquals(Color.BLACK, ColorUtils.bleachColour(colour, -2));
+ assertEquals(new Color(124, 84, 44),
+ ColorUtils.bleachColour(colour, -0.2f));
+ assertEquals(new Color(46, 31, 16), // with rounding down
+ ColorUtils.bleachColour(colour, -0.7f));
+ }
}
import jalview.datamodel.Sequence;
import jalview.datamodel.SequenceI;
+import java.util.List;
+
import org.testng.annotations.Test;
public class DBRefUtilsTest
assertEquals("UNIPROTKB/SWISS-CHEESE",
DBRefUtils.getCanonicalName("UNIPROTKB/SWISS-CHEESE"));
assertEquals("ENSEMBL", DBRefUtils.getCanonicalName("Ensembl"));
+
+ // these are not 'known' to Jalview
+ assertEquals("PFAM", DBRefUtils.getCanonicalName("PFAM"));
+ assertEquals("pfam", DBRefUtils.getCanonicalName("pfam"));
+
}
@Test(groups = { "Functional" })
SequenceI seq = new Sequence("Seq1", "ABCD");
DBRefEntry ref = DBRefUtils.parseToDbRef(seq, "pdb", "1.2",
"1WRI A; 7-80;");
+ // TODO: correct PDBEntry and PDB DBRef accessions need to be generated for
+ // PDB ref in Stockholm
+
DBRefEntry[] refs = seq.getDBRefs();
assertEquals(1, refs.length);
assertSame(ref, refs[0]);
ref5.setMap(new Mapping(new MapList(new int[] { 1, 1 }, new int[] { 1,
1 }, 1, 1)));
- DBRefEntry[] matches = DBRefUtils.searchRefs(new DBRefEntry[] { ref1,
- ref2, ref3, ref4, ref5 }, target);
- assertEquals(3, matches.length);
- assertSame(ref1, matches[0]);
- assertSame(ref2, matches[1]);
- assertSame(ref5, matches[2]);
+ List<DBRefEntry> matches = DBRefUtils.searchRefs(new DBRefEntry[] {
+ ref1, ref2, ref3, ref4, ref5 }, target);
+ assertEquals(3, matches.size());
+ assertSame(ref1, matches.get(0));
+ assertSame(ref2, matches.get(1));
+ assertSame(ref5, matches.get(2));
}
/**
new int[] { 1, 1 }, 2, 2));
ref3.setMap(map3);
- DBRefEntry[] matches = DBRefUtils.searchRefs(new DBRefEntry[] { ref1,
- ref2, ref3 }, target);
- assertEquals(2, matches.length);
- assertSame(ref1, matches[0]);
- assertSame(ref2, matches[1]);
+ List<DBRefEntry> matches = DBRefUtils.searchRefs(new DBRefEntry[] {
+ ref1, ref2, ref3 }, target);
+ assertEquals(2, matches.size());
+ assertSame(ref1, matches.get(0));
+ assertSame(ref2, matches.get(1));
}
/**
@Test(groups = { "Functional" })
public void testSearchRefs_accessionid()
{
-
+
DBRefEntry ref1 = new DBRefEntry("Uniprot", "1", "A1234"); // matches
DBRefEntry ref2 = new DBRefEntry("embl", "1", "A1234"); // matches
// constructor does not upper-case accession id
DBRefEntry ref5 = new DBRefEntry("EMBL", "1", "A1234");
ref5.setMap(new Mapping(new MapList(new int[] { 1, 1 }, new int[] { 1,
1 }, 1, 1)));
-
- DBRefEntry[] matches = DBRefUtils.searchRefs(new DBRefEntry[] { ref1,
- ref2, ref3, ref4, ref5 }, "A1234");
- assertEquals(3, matches.length);
- assertSame(ref1, matches[0]);
- assertSame(ref2, matches[1]);
- assertSame(ref5, matches[2]);
+
+ DBRefEntry[] dbrefs = new DBRefEntry[] { ref1, ref2, ref3, ref4, ref5 };
+ List<DBRefEntry> matches = DBRefUtils.searchRefs(dbrefs, "A1234");
+ assertEquals(3, matches.size());
+ assertSame(ref1, matches.get(0));
+ assertSame(ref2, matches.get(1));
+ assertSame(ref5, matches.get(2));
+ }
+
+ /**
+ * Test the method that searches for matches references - case when we are
+ * matching a reference with null (any) accession id
+ */
+ @Test(groups = { "Functional" })
+ public void testSearchRefs_wildcardAccessionid()
+ {
+ DBRefEntry target = new DBRefEntry("EMBL", "2", null);
+
+ DBRefEntry ref1 = new DBRefEntry("EMBL", "1", "A1234"); // matches
+ // constructor changes embl to EMBL
+ DBRefEntry ref2 = new DBRefEntry("embl", "1", "A1235"); // matches
+ // constructor does not upper-case accession id
+ DBRefEntry ref3 = new DBRefEntry("EMBL", "1", "A1236"); // matches
+ DBRefEntry ref4 = new DBRefEntry("EMBLCDS", "1", "A1234"); // no match
+ // ref5 matches although it has a mapping - ignored
+ DBRefEntry ref5 = new DBRefEntry("EMBL", "1", "A1237");
+ ref5.setMap(new Mapping(new MapList(new int[] { 1, 1 }, new int[] { 1,
+ 1 }, 1, 1)));
+
+ List<DBRefEntry> matches = DBRefUtils.searchRefs(new DBRefEntry[] {
+ ref1, ref2, ref3, ref4, ref5 }, target);
+ assertEquals(4, matches.size());
+ assertSame(ref1, matches.get(0));
+ assertSame(ref2, matches.get(1));
+ assertSame(ref3, matches.get(2));
+ assertSame(ref5, matches.get(3));
}
}
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
package jalview.util;
import static org.testng.AssertJUnit.assertEquals;
--- /dev/null
+package jalview.util;
+
+import static org.testng.Assert.assertEquals;
+
+import org.testng.annotations.Test;
+
+public class FormatTest
+{
+ @Test(groups = "Functional")
+ public void testAppendPercentage()
+ {
+ StringBuilder sb = new StringBuilder();
+ Format.appendPercentage(sb, 123.456f, 0);
+ assertEquals(sb.toString(), "123");
+
+ sb.setLength(0);
+ Format.appendPercentage(sb, 123.456f, 1);
+ assertEquals(sb.toString(), "123.4");
+
+ sb.setLength(0);
+ Format.appendPercentage(sb, 123.456f, 2);
+ assertEquals(sb.toString(), "123.45");
+
+ sb.setLength(0);
+ Format.appendPercentage(sb, 123.456f, 3);
+ assertEquals(sb.toString(), "123.456");
+
+ sb.setLength(0);
+ Format.appendPercentage(sb, 123.456f, 4);
+ assertEquals(sb.toString(), "123.4560");
+ }
+}
MapList ml = new MapList(new int[] { 1, 5, 10, 15, 25, 20 }, new int[] {
51, 1 }, 1, 3);
String s = ml.toString();
- assertEquals("[ [1, 5] [10, 15] [25, 20] ] 1:3 to [ [51, 1] ]",
- s);
+ assertEquals("[ [1, 5] [10, 15] [25, 20] ] 1:3 to [ [51, 1] ]", s);
}
@Test(groups = { "Functional" })
s);
}
+ /**
+ * Test that confirms adding a map twice does nothing
+ */
+ @Test(groups = { "Functional" })
+ public void testAddMapList_sameMap()
+ {
+ MapList ml = new MapList(new int[] { 11, 15, 20, 25, 35, 30 },
+ new int[] { 72, 22 }, 1, 3);
+ String before = ml.toString();
+ ml.addMapList(ml);
+ assertEquals(before, ml.toString());
+ ml.addMapList(new MapList(ml));
+ assertEquals(before, ml.toString());
+ }
+
@Test(groups = { "Functional" })
public void testAddMapList_contiguous()
{
public void testIsFromForwardStrand()
{
// [3-9] declares forward strand
- MapList ml = new MapList(new int[] { 2, 2, 3, 9, 12, 11 },
- new int[] { 20, 11 }, 1, 1);
+ MapList ml = new MapList(new int[] { 2, 2, 3, 9, 12, 11 }, new int[] {
+ 20, 11 }, 1, 1);
assertTrue(ml.isFromForwardStrand());
// [11-5] declares reverse strand ([13-14] is ignored)
assertEquals(0, result.size());
}
+ /**
+ * just like the one above, but this time, we provide a set of sequences to
+ * subselect the mapping search
+ */
+ @Test(groups = { "Functional" })
+ public void testFindMappingsForSequenceAndOthers()
+ {
+ SequenceI seq1 = new Sequence("Seq1", "ABC");
+ SequenceI seq2 = new Sequence("Seq2", "ABC");
+ SequenceI seq3 = new Sequence("Seq3", "ABC");
+ SequenceI seq4 = new Sequence("Seq4", "ABC");
+ seq1.createDatasetSequence();
+ seq2.createDatasetSequence();
+ seq3.createDatasetSequence();
+ seq4.createDatasetSequence();
+
+ /*
+ * Create mappings from seq1 to seq2, seq2 to seq1, seq3 to seq1, seq3 to seq4
+ */
+ AlignedCodonFrame acf1 = new AlignedCodonFrame();
+ MapList map = new MapList(new int[] { 1, 3 }, new int[] { 1, 3 }, 1, 1);
+ acf1.addMap(seq1.getDatasetSequence(), seq2.getDatasetSequence(), map);
+ AlignedCodonFrame acf2 = new AlignedCodonFrame();
+ acf2.addMap(seq2.getDatasetSequence(), seq1.getDatasetSequence(), map);
+ AlignedCodonFrame acf3 = new AlignedCodonFrame();
+ acf3.addMap(seq3.getDatasetSequence(), seq1.getDatasetSequence(), map);
+ AlignedCodonFrame acf4 = new AlignedCodonFrame();
+ acf4.addMap(seq3.getDatasetSequence(), seq4.getDatasetSequence(), map);
+
+ List<AlignedCodonFrame> mappings = new ArrayList<AlignedCodonFrame>();
+ mappings.add(acf1);
+ mappings.add(acf2);
+ mappings.add(acf3);
+ mappings.add(acf4);
+
+ /*
+ * test for null args
+ */
+ List<AlignedCodonFrame> result = MappingUtils
+ .findMappingsForSequenceAndOthers(null, mappings,
+ Arrays.asList(new SequenceI[] { seq1, seq2 }));
+ assertTrue(result.isEmpty());
+
+ result = MappingUtils.findMappingsForSequenceAndOthers(seq1, null,
+ Arrays.asList(new SequenceI[] { seq1, seq2 }));
+ assertTrue(result.isEmpty());
+
+ /*
+ * Seq1 has three mappings, but filter argument will only accept
+ * those to seq2
+ */
+ result = MappingUtils.findMappingsForSequenceAndOthers(
+ seq1,
+ mappings,
+ Arrays.asList(new SequenceI[] { seq1, seq2,
+ seq1.getDatasetSequence() }));
+ assertEquals(2, result.size());
+ assertTrue(result.contains(acf1));
+ assertTrue(result.contains(acf2));
+ assertFalse("Did not expect to find mapping acf3 - subselect failed",
+ result.contains(acf3));
+ assertFalse(
+ "Did not expect to find mapping acf4 - doesn't involve sequence",
+ result.contains(acf4));
+
+ /*
+ * and verify the no filter case
+ */
+ result = MappingUtils.findMappingsForSequenceAndOthers(seq1, mappings,
+ null);
+ assertEquals(3, result.size());
+ assertTrue(result.contains(acf1));
+ assertTrue(result.contains(acf2));
+ assertTrue(result.contains(acf3));
+ }
+
@Test(groups = { "Functional" })
public void testMapEditCommand()
{
public void testMapColumnSelection_hiddenColumns() throws IOException
{
setupMappedAlignments();
-
+
ColumnSelection proteinSelection = new ColumnSelection();
/*
* in dna respectively, overall 0-4
*/
proteinSelection.hideColumns(0);
- ColumnSelection dnaSelection = MappingUtils.mapColumnSelection(proteinSelection,
- proteinView, dnaView);
+ ColumnSelection dnaSelection = MappingUtils.mapColumnSelection(
+ proteinSelection, proteinView, dnaView);
assertEquals("[]", dnaSelection.getSelected().toString());
List<int[]> hidden = dnaSelection.getHiddenColumns();
assertEquals(1, hidden.size());
// deselect these or hideColumns will be expanded to include 0
proteinSelection.clear();
proteinSelection.hideColumns(1);
- dnaSelection = MappingUtils.mapColumnSelection(proteinSelection, proteinView, dnaView);
+ dnaSelection = MappingUtils.mapColumnSelection(proteinSelection,
+ proteinView, dnaView);
hidden = dnaSelection.getHiddenColumns();
assertEquals(1, hidden.size());
assertEquals("[0, 3]", Arrays.toString(hidden.get(0)));
proteinSelection.revealAllHiddenColumns();
proteinSelection.clear();
proteinSelection.hideColumns(2);
- dnaSelection = MappingUtils.mapColumnSelection(proteinSelection, proteinView, dnaView);
+ dnaSelection = MappingUtils.mapColumnSelection(proteinSelection,
+ proteinView, dnaView);
assertTrue(dnaSelection.getHiddenColumns().isEmpty());
/*
proteinSelection.clear();
proteinSelection.hideColumns(3); // 5-10 hidden in dna
proteinSelection.addElement(1); // 0-3 selected in dna
- dnaSelection = MappingUtils.mapColumnSelection(proteinSelection, proteinView, dnaView);
+ dnaSelection = MappingUtils.mapColumnSelection(proteinSelection,
+ proteinView, dnaView);
assertEquals("[0, 1, 2, 3]", dnaSelection.getSelected().toString());
hidden = dnaSelection.getHiddenColumns();
assertEquals(1, hidden.size());
proteinSelection.clear();
proteinSelection.hideColumns(1);
proteinSelection.hideColumns(3);
- dnaSelection = MappingUtils.mapColumnSelection(proteinSelection, proteinView, dnaView);
+ dnaSelection = MappingUtils.mapColumnSelection(proteinSelection,
+ proteinView, dnaView);
hidden = dnaSelection.getHiddenColumns();
assertEquals(2, hidden.size());
assertEquals("[0, 3]", Arrays.toString(hidden.get(0)));
int[] adjusted = MappingUtils.removeStartPositions(0, ranges);
assertEquals("[10, 1]", Arrays.toString(adjusted));
assertEquals("[10, 1]", Arrays.toString(ranges));
-
+
ranges = adjusted;
adjusted = MappingUtils.removeStartPositions(1, ranges);
assertEquals("[9, 1]", Arrays.toString(adjusted));
assertEquals("[10, 1]", Arrays.toString(ranges));
-
+
ranges = adjusted;
adjusted = MappingUtils.removeStartPositions(1, ranges);
assertEquals("[8, 1]", Arrays.toString(adjusted));
assertEquals("[9, 1]", Arrays.toString(ranges));
-
+
ranges = new int[] { 12, 11, 9, 6 };
adjusted = MappingUtils.removeStartPositions(1, ranges);
assertEquals("[11, 11, 9, 6]", Arrays.toString(adjusted));
assertEquals("[12, 11, 9, 6]", Arrays.toString(ranges));
-
+
ranges = new int[] { 12, 12, 8, 4 };
adjusted = MappingUtils.removeStartPositions(1, ranges);
assertEquals("[8, 4]", Arrays.toString(adjusted));
assertEquals("[12, 12, 8, 4]", Arrays.toString(ranges));
-
+
ranges = new int[] { 12, 12, 8, 4 };
adjusted = MappingUtils.removeStartPositions(2, ranges);
assertEquals("[7, 4]", Arrays.toString(adjusted));
assertEquals("[12, 12, 8, 4]", Arrays.toString(ranges));
-
+
ranges = new int[] { 12, 12, 10, 10, 8, 4 };
adjusted = MappingUtils.removeStartPositions(1, ranges);
assertEquals("[10, 10, 8, 4]", Arrays.toString(adjusted));
assertEquals("[12, 12, 10, 10, 8, 4]", Arrays.toString(ranges));
-
+
ranges = new int[] { 12, 12, 10, 10, 8, 4 };
adjusted = MappingUtils.removeStartPositions(2, ranges);
assertEquals("[8, 4]", Arrays.toString(adjusted));
assertEquals("[12, 12, 10, 10, 8, 4]", Arrays.toString(ranges));
-
+
ranges = new int[] { 12, 11, 8, 4 };
adjusted = MappingUtils.removeStartPositions(3, ranges);
assertEquals("[7, 4]", Arrays.toString(adjusted));
"ALISON" };
QuickSort.sort(values, things);
assertTrue(Arrays.equals(new String[] { "lucy", "henry", "henry",
- "JOHN",
- "ALISON" }, values));
+ "JOHN", "ALISON" }, values));
assertTrue(Arrays.equals(new Object[] { c3, c2, c4, c1, c5 }, things));
}
--- /dev/null
+package jalview.util;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertTrue;
+
+import org.testng.annotations.Test;
+public class SparseCountTest
+{
+ @Test(groups = "Functional")
+ public void testAdd()
+ {
+ SparseCount p = new SparseCount(8);
+ p.add('a', 1);
+ p.add('b', 2);
+ p.add('a', 3);
+ p.add('b', -4);
+ assertEquals(p.size(), 2);
+ assertEquals(p.get('a'), 4);
+ assertEquals(p.get('b'), -2);
+ }
+
+ @Test(groups = "Functional")
+ public void testPut()
+ {
+ SparseCount p = new SparseCount(8);
+ p.put('a', 3);
+ p.add('b', 2);
+ p.put('b', 4);
+ assertEquals(p.size(), 2);
+ assertEquals(p.get('a'), 3);
+ assertEquals(p.get('b'), 4);
+ }
+
+ /**
+ * Test handling overflow of short by switching to counting ints
+ */
+ @Test(groups = "Functional")
+ public void testOverflow()
+ {
+ SparseCount p = new SparseCount(8);
+ p.put('a', Short.MAX_VALUE - 1);
+ p.add('a', 1);
+ assertFalse(p.isUsingInt());
+ p.add('a', 1);
+ assertTrue(p.isUsingInt());
+ }
+
+ /**
+ * Test handling underflow of short by switching to counting ints
+ */
+ @Test(groups = "Functional")
+ public void testUnderflow()
+ {
+ SparseCount p = new SparseCount(8);
+ p.put('a', Short.MIN_VALUE + 1);
+ p.add('a', -1);
+ assertFalse(p.isUsingInt());
+ p.add('a', -1);
+ assertTrue(p.isUsingInt());
+ }
+
+ @Test(groups = "Functional")
+ public void testKeyAt_ValueAt()
+ {
+ SparseCount p = new SparseCount(8);
+ p.put('W', 12);
+ p.put('K', 9);
+ p.put('R', 6);
+ assertEquals(p.size(), 3);
+ assertEquals(p.keyAt(0), 'K');
+ assertEquals(p.valueAt(0), 9);
+ assertEquals(p.keyAt(1), 'R');
+ assertEquals(p.valueAt(1), 6);
+ assertEquals(p.keyAt(2), 'W');
+ assertEquals(p.valueAt(2), 12);
+ }
+
+}
--- /dev/null
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
+package jalview.util;
+
+import static jalview.util.UrlConstants.SEQUENCE_ID;
+import static jalview.util.UrlConstants.SEQUENCE_NAME;
+import static org.testng.AssertJUnit.assertEquals;
+import static org.testng.AssertJUnit.assertFalse;
+import static org.testng.AssertJUnit.assertNull;
+import static org.testng.AssertJUnit.assertTrue;
+
+import org.testng.annotations.Test;
+
+public class UrlLinkTest
+{
+
+ final static String DB = "Test";
+
+ final static String URL_PREFIX = "http://www.jalview.org/";
+
+ final static String URL_SUFFIX = "/blah";
+
+ final static String SEP = "|";
+
+ final static String DELIM = "$";
+
+ final static String REGEX_NESTED = "=/^(?:Label:)?(?:(?:gi\\|(\\d+))|([^:]+))/=";
+
+ final static String REGEX_RUBBISH = "=/[0-9]++/=";
+
+ /**
+ * Test URL link creation when the input string has no regex
+ */
+ @Test(groups = { "Functional" })
+ public void testUrlLinkCreationNoRegex()
+ {
+ // SEQUENCE_NAME
+ UrlLink ul = new UrlLink(DB + SEP + URL_PREFIX + DELIM + SEQUENCE_NAME
+ + DELIM + URL_SUFFIX);
+ assertEquals(DB.toUpperCase(), ul.getTarget());
+ assertEquals(DB, ul.getLabel());
+ assertEquals(URL_PREFIX, ul.getUrl_prefix());
+ assertEquals(URL_SUFFIX, ul.getUrl_suffix());
+ assertTrue(ul.isDynamic());
+ assertFalse(ul.usesSeqId());
+ assertNull(ul.getRegexReplace());
+ assertTrue(ul.isValid());
+ assertNull(ul.getInvalidMessage());
+
+ // SEQUENCE_ID
+ ul = new UrlLink(DB + SEP + URL_PREFIX + DELIM + SEQUENCE_ID + DELIM
+ + URL_SUFFIX);
+ assertEquals(DB.toUpperCase(), ul.getTarget());
+ assertEquals(DB, ul.getLabel());
+ assertEquals(URL_PREFIX, ul.getUrl_prefix());
+ assertEquals(URL_SUFFIX, ul.getUrl_suffix());
+ assertTrue(ul.isDynamic());
+ assertTrue(ul.usesSeqId());
+ assertNull(ul.getRegexReplace());
+ assertTrue(ul.isValid());
+ assertNull(ul.getInvalidMessage());
+
+ // Not dynamic
+ ul = new UrlLink(DB + SEP + URL_PREFIX + URL_SUFFIX.substring(1));
+ assertEquals(DB.toUpperCase(), ul.getTarget());
+ assertEquals(DB, ul.getLabel());
+ assertEquals(URL_PREFIX + URL_SUFFIX.substring(1), ul.getUrl_prefix());
+ assertFalse(ul.isDynamic());
+ assertFalse(ul.usesSeqId());
+ assertNull(ul.getRegexReplace());
+ assertTrue(ul.isValid());
+ assertNull(ul.getInvalidMessage());
+ }
+
+ /**
+ * Test URL link creation when the input string has regex
+ */
+ @Test(groups = { "Functional" })
+ public void testUrlLinkCreationWithRegex()
+ {
+ // SEQUENCE_NAME
+ UrlLink ul = new UrlLink(DB + SEP + URL_PREFIX + DELIM + SEQUENCE_NAME
+ + REGEX_NESTED + DELIM + URL_SUFFIX);
+ assertEquals(DB.toUpperCase(), ul.getTarget());
+ assertEquals(DB, ul.getLabel());
+ assertEquals(URL_PREFIX, ul.getUrl_prefix());
+ assertEquals(URL_SUFFIX, ul.getUrl_suffix());
+ assertTrue(ul.isDynamic());
+ assertFalse(ul.usesSeqId());
+ assertEquals(REGEX_NESTED.substring(2, REGEX_NESTED.length() - 2),
+ ul.getRegexReplace());
+ assertTrue(ul.isValid());
+ assertNull(ul.getInvalidMessage());
+
+ // SEQUENCE_ID
+ ul = new UrlLink(DB + SEP + URL_PREFIX + DELIM + SEQUENCE_ID
+ + REGEX_NESTED + DELIM + URL_SUFFIX);
+ assertEquals(DB.toUpperCase(), ul.getTarget());
+ assertEquals(DB, ul.getLabel());
+ assertEquals(URL_PREFIX, ul.getUrl_prefix());
+ assertEquals(URL_SUFFIX, ul.getUrl_suffix());
+ assertTrue(ul.isDynamic());
+ assertTrue(ul.usesSeqId());
+ assertEquals(REGEX_NESTED.substring(2, REGEX_NESTED.length() - 2),
+ ul.getRegexReplace());
+ assertTrue(ul.isValid());
+ assertNull(ul.getInvalidMessage());
+
+ // invalid regex
+ ul = new UrlLink(DB + SEP + URL_PREFIX + DELIM + SEQUENCE_ID
+ + REGEX_RUBBISH + DELIM + URL_SUFFIX);
+ assertEquals(DB.toUpperCase(), ul.getTarget());
+ assertEquals(DB, ul.getLabel());
+ assertEquals(URL_PREFIX, ul.getUrl_prefix());
+ assertEquals(URL_SUFFIX, ul.getUrl_suffix());
+ assertTrue(ul.isDynamic());
+ assertTrue(ul.usesSeqId());
+ assertEquals(REGEX_RUBBISH.substring(2, REGEX_RUBBISH.length() - 2),
+ ul.getRegexReplace());
+ assertFalse(ul.isValid());
+ assertEquals(
+ "Invalid Regular Expression : '"
+ + REGEX_RUBBISH.substring(2, REGEX_RUBBISH.length() - 2)
+ + "'\n",
+ ul.getInvalidMessage());
+ }
+
+ /**
+ * Test construction of link by substituting sequence id or name
+ */
+ @Test(groups = { "Functional" })
+ public void testMakeUrlNoRegex()
+ {
+ // Single non-regex
+ UrlLink ul = new UrlLink(DB + SEP + URL_PREFIX + DELIM + SEQUENCE_NAME
+ + DELIM + URL_SUFFIX);
+ String idstring = "FER_CAPAA";
+ String[] urls = ul.makeUrls(idstring, true);
+
+ assertEquals(2, urls.length);
+ assertEquals(idstring, urls[0]);
+ assertEquals(URL_PREFIX + idstring + URL_SUFFIX, urls[1]);
+
+ urls = ul.makeUrls(idstring, false);
+
+ assertEquals(2, urls.length);
+ assertEquals(idstring, urls[0]);
+ assertEquals(URL_PREFIX + idstring + URL_SUFFIX, urls[1]);
+ }
+
+ /**
+ * Test construction of link by substituting sequence id or name
+ */
+ @Test(groups = { "Functional" })
+ public void testMakeUrlWithRegex()
+ {
+ // Unused regex
+ UrlLink ul = new UrlLink(DB + SEP + URL_PREFIX + DELIM + SEQUENCE_ID
+ + REGEX_NESTED + DELIM + URL_SUFFIX);
+ String idstring = "FER_CAPAA";
+ String[] urls = ul.makeUrls(idstring, true);
+
+ assertEquals(2, urls.length);
+ assertEquals(idstring, urls[0]);
+ assertEquals(URL_PREFIX + idstring + URL_SUFFIX, urls[1]);
+ assertTrue(ul.isValid());
+ assertNull(ul.getInvalidMessage());
+
+ urls = ul.makeUrls(idstring, false);
+
+ assertEquals(2, urls.length);
+ assertEquals(idstring, urls[0]);
+ assertEquals(URL_PREFIX + idstring + URL_SUFFIX, urls[1]);
+ assertTrue(ul.isValid());
+ assertNull(ul.getInvalidMessage());
+
+ // nested regex
+ idstring = "Label:gi|9234|pdb|102L|A";
+ urls = ul.makeUrls(idstring, true);
+
+ assertEquals(2, urls.length);
+ assertEquals("9234", urls[0]);
+ assertEquals(URL_PREFIX + "9234" + URL_SUFFIX, urls[1]);
+ assertTrue(ul.isValid());
+ assertNull(ul.getInvalidMessage());
+
+ urls = ul.makeUrls(idstring, false);
+
+ assertEquals(2, urls.length);
+ assertEquals("9234", urls[0]);
+ assertEquals(URL_PREFIX + "9234" + URL_SUFFIX, urls[1]);
+ assertTrue(ul.isValid());
+ assertNull(ul.getInvalidMessage());
+
+ // unmatched regex
+ idstring = "this does not match";
+ urls = ul.makeUrls(idstring, true);
+
+ assertEquals(2, urls.length);
+ assertEquals(idstring, urls[0]);
+ assertEquals(URL_PREFIX + idstring + URL_SUFFIX, urls[1]);
+ assertTrue(ul.isValid());
+ assertNull(ul.getInvalidMessage());
+
+ urls = ul.makeUrls(idstring, false);
+
+ assertEquals(2, urls.length);
+ assertEquals(idstring, urls[0]);
+ assertEquals(URL_PREFIX + idstring + URL_SUFFIX, urls[1]);
+ assertTrue(ul.isValid());
+ assertNull(ul.getInvalidMessage());
+
+ // empty idstring
+ idstring = "";
+ urls = ul.makeUrls(idstring, true);
+
+ assertNull(urls);
+
+ urls = ul.makeUrls(idstring, false);
+
+ assertEquals(2, urls.length);
+ assertEquals("", urls[0]);
+ assertEquals(URL_PREFIX + URL_SUFFIX, urls[1]);
+ assertTrue(ul.isValid());
+ assertNull(ul.getInvalidMessage());
+ }
+
+}
--- /dev/null
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
+package jalview.workers;
+
+import static org.testng.AssertJUnit.assertEquals;
+import static org.testng.AssertJUnit.assertFalse;
+import static org.testng.AssertJUnit.assertTrue;
+
+import jalview.api.AlignCalcManagerI;
+import jalview.api.AlignCalcWorkerI;
+import jalview.api.FeatureRenderer;
+import jalview.datamodel.Alignment;
+import jalview.datamodel.AlignmentAnnotation;
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.Annotation;
+import jalview.datamodel.Sequence;
+import jalview.datamodel.SequenceI;
+import jalview.gui.AlignFrame;
+
+import java.util.Collections;
+import java.util.List;
+
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+public class AlignCalcManagerTest
+{
+ private AlignFrame alignFrame;
+
+ /**
+ * Test the method that removes a worker associated with an annotation,
+ * provided the worker is marked as 'deletable' (some workers should continue
+ * to run even when their results are no longer displayed)
+ */
+ @Test(groups = "Functional")
+ public void testRemoveWorkerForAnnotation()
+ {
+ AlignCalcManagerI acm = alignFrame.getViewport().getCalcManager();
+ final AlignmentAnnotation ann1 = new AlignmentAnnotation("Ann1",
+ "desc", new Annotation[] {});
+ final AlignmentAnnotation ann2 = new AlignmentAnnotation("Ann2",
+ "desc", new Annotation[] {});
+
+ /*
+ * make two workers for ann1, one deletable, one not
+ * and no worker for ann2
+ */
+ AlignCalcWorkerI worker1 = makeWorker(ann1, true);
+ AlignCalcWorkerI worker2 = makeWorker(ann1, false);
+
+ /*
+ * The new workers will get run each in their own thread.
+ * We can't tell here whether they have finished, or not yet started.
+ * They have to finish to be 'seen' by getRegisteredWorkersOfClass()
+ * registerWorker adds to the 'restartable' list but
+ * getRegisteredWorkers reads from the 'canUpdate' list
+ * (which is only updated after a worker has run) - why?
+ * So just give workers time to start and finish
+ */
+ synchronized (this)
+ {
+ try
+ {
+ wait(100);
+ } catch (InterruptedException e)
+ {
+ //
+ }
+ }
+
+ List<AlignCalcWorkerI> workers = acm
+ .getRegisteredWorkersOfClass(worker1.getClass());
+ assertEquals(2, workers.size());
+ assertTrue(workers.contains(worker1));
+ assertTrue(workers.contains(worker2));
+ assertFalse(acm.isDisabled(worker1));
+ assertFalse(acm.isDisabled(worker2));
+
+ /*
+ * remove workers for ann2 (there aren't any)
+ */
+ acm.removeWorkerForAnnotation(ann2);
+ assertTrue(acm.getRegisteredWorkersOfClass(worker1.getClass())
+ .contains(worker1));
+ assertTrue(acm.getRegisteredWorkersOfClass(worker1.getClass())
+ .contains(worker2));
+ assertFalse(acm.isDisabled(worker1));
+ assertFalse(acm.isDisabled(worker2));
+
+ /*
+ * remove worker2 for ann1
+ * - should delete worker1 but not worker2
+ */
+ acm.removeWorkerForAnnotation(ann1);
+ assertEquals(1, acm.getRegisteredWorkersOfClass(worker1.getClass())
+ .size());
+ assertTrue(acm.getRegisteredWorkersOfClass(worker1.getClass())
+ .contains(worker2));
+ assertFalse(acm.isDisabled(worker1));
+ assertFalse(acm.isDisabled(worker2));
+ }
+
+ /**
+ * Make a worker linked to the given annotation
+ *
+ * @param ann
+ * @param deletable
+ * @return
+ */
+ AnnotationWorker makeWorker(final AlignmentAnnotation ann,
+ final boolean deletable)
+ {
+ AnnotationProviderI annotationProvider = new AnnotationProviderI()
+ {
+ @Override
+ public List<AlignmentAnnotation> calculateAnnotation(AlignmentI al,
+ FeatureRenderer fr)
+ {
+ return Collections.singletonList(ann);
+ }
+ };
+ return new AnnotationWorker(alignFrame.getViewport(),
+ alignFrame.alignPanel, annotationProvider)
+ {
+ @Override
+ public boolean isDeletable()
+ {
+ return deletable;
+ }
+
+ @Override
+ public boolean involves(AlignmentAnnotation ann1)
+ {
+ return ann == ann1;
+ }
+ };
+ }
+
+ @BeforeMethod(alwaysRun = true)
+ public void setUp()
+ {
+ AlignmentI al = new Alignment(new SequenceI[] { new Sequence("Seq1",
+ "ABC") });
+ al.setDataset(null);
+ alignFrame = new AlignFrame(al, 3, 1);
+ }
+}
import jalview.bin.Cache;
import jalview.datamodel.AlignmentI;
import jalview.datamodel.SequenceI;
-import jalview.structure.StructureViewSettings;
+import jalview.structure.StructureImportSettings;
+import jalview.structure.StructureImportSettings.StructureParser;
import jalview.ws.seqfetcher.DbSourceProxy;
import java.util.List;
@BeforeMethod(alwaysRun = true)
public void setUp() throws Exception
{
+ Cache.loadProperties("test/jalview/io/testProps.jvprops");
// ensure 'add annotation from structure' is selected
Cache.applicationProperties.setProperty("STRUCT_FROM_PDB",
Boolean.TRUE.toString());
@Test(groups = { "Network" }, enabled = true)
public void testRnaSeqRetrieve() throws Exception
{
- Cache.applicationProperties.setProperty("STRUCT_FROM_PDB",
- Boolean.TRUE.toString());
- Cache.applicationProperties.setProperty("DEFAULT_STRUCTURE_FORMAT",
- "PDB");
+ Cache.applicationProperties.setProperty("PDB_DOWNLOAD_FORMAT", "PDB");
List<DbSourceProxy> sps = sf.getSourceProxy("PDB");
AlignmentI response = sps.get(0).getSequenceRecords("2GIS");
assertTrue(response != null);
@Test(groups = { "Network" }, enabled = true)
public void testPdbSeqRetrieve() throws Exception
{
- Cache.applicationProperties.setProperty("STRUCT_FROM_PDB",
- Boolean.TRUE.toString());
- StructureViewSettings.setCurrentDefaultFormat("PDB");
+ StructureImportSettings.setDefaultStructureFileFormat("PDB");
+ StructureImportSettings
+ .setDefaultPDBFileParser(StructureParser.JALVIEW_PARSER);
testRetrieveProteinSeqFromPDB();
}
@Test(groups = { "Network" }, enabled = true)
public void testmmCifSeqRetrieve() throws Exception
{
- Cache.applicationProperties.setProperty("STRUCT_FROM_PDB",
- Boolean.TRUE.toString());
- StructureViewSettings.setCurrentDefaultFormat("mmCIF");
+ StructureImportSettings.setDefaultStructureFileFormat("mmCIF");
testRetrieveProteinSeqFromPDB();
}
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
package jalview.ws;
+import jalview.analysis.CrossRef;
import jalview.datamodel.Alignment;
import jalview.datamodel.AlignmentI;
import jalview.datamodel.DBRefSource;
// TODO: extracted from SequenceFetcher - convert to proper unit test with
// assertions
- AlignmentI ds = null;
- Vector<Object[]> noProds = new Vector<Object[]>();
String usage = "SequenceFetcher.main [-nodas] [<DBNAME> [<ACCNO>]]\n"
+ "With no arguments, all DbSources will be queried with their test Accession number.\n"
+ "With one argument, the argument will be resolved to one or more db sources and each will be queried with their test accession only.\n"
{
List<DbSourceProxy> sps = new SequenceFetcher(withDas)
.getSourceProxy(argv[0]);
-
+
if (sps != null)
{
for (DbSourceProxy sp : sps)
AlignmentI al = null;
try
{
- al = sp.getSequenceRecords(argv.length > 1 ? argv[1] : sp
- .getTestQuery());
+ testRetrieval(argv[0], sp,
+ argv.length > 1 ? argv[1] : sp.getTestQuery());
} catch (Exception e)
{
e.printStackTrace();
+ (argv.length > 1 ? argv[1] : sp.getTestQuery())
+ " from " + argv[0] + "\nUsage: " + usage);
}
- SequenceI[] prod = al.getSequencesArray();
- if (al != null)
- {
- for (int p = 0; p < prod.length; p++)
- {
- System.out.println("Prod " + p + ": "
- + prod[p].getDisplayId(true) + " : "
- + prod[p].getDescription());
- }
- }
}
return;
}
}
for (DbSourceProxy sp : sfetcher.getSourceProxy(db))
{
- System.out.println("Source: " + sp.getDbName() + " (" + db
- + "): retrieving test:" + sp.getTestQuery());
- AlignmentI al = null;
- try
+ testRetrieval(db, sp, sp.getTestQuery());
+ }
+ }
+
+ }
+
+ private static void testRetrieval(String db, DbSourceProxy sp,
+ String testQuery)
+ {
+ AlignmentI ds = null;
+ Vector<Object[]> noProds = new Vector<Object[]>();
+ System.out.println("Source: " + sp.getDbName() + " (" + db
+ + "): retrieving test:" + sp.getTestQuery());
+ {
+ AlignmentI al = null;
+ try
+ {
+ al = sp.getSequenceRecords(testQuery);
+ if (al != null && al.getHeight() > 0)
{
- al = sp.getSequenceRecords(sp.getTestQuery());
- if (al != null && al.getHeight() > 0)
+ boolean dna = sp.isDnaCoding();
+ al.setDataset(null);
+ AlignmentI alds = al.getDataset();
+ // try and find products
+ CrossRef crossRef = new CrossRef(al.getSequencesArray(), alds);
+ List<String> types = crossRef.findXrefSourcesForSequences(dna);
+ if (types != null)
{
- boolean dna = sp.isDnaCoding();
- // try and find products
- String types[] = jalview.analysis.CrossRef
- .findSequenceXrefTypes(dna, al.getSequencesArray());
- if (types != null)
+ System.out.println("Xref Types for: " + (dna ? "dna" : "prot"));
+ for (String source : types)
{
- System.out.println("Xref Types for: "
- + (dna ? "dna" : "prot"));
- for (int t = 0; t < types.length; t++)
+ System.out.println("Type: " + source);
+ SequenceI[] prod = crossRef.findXrefSequences(source, dna)
+ .getSequencesArray();
+ System.out.println("Found "
+ + ((prod == null) ? "no" : "" + prod.length)
+ + " products");
+ if (prod != null)
{
- System.out.println("Type: " + types[t]);
- SequenceI[] prod = jalview.analysis.CrossRef
- .findXrefSequences(al.getSequencesArray(), dna,
- types[t], null)
- .getSequencesArray();
- System.out.println("Found "
- + ((prod == null) ? "no" : "" + prod.length)
- + " products");
- if (prod != null)
+ for (int p = 0; p < prod.length; p++)
{
- for (int p = 0; p < prod.length; p++)
- {
- System.out.println("Prod " + p + ": "
- + prod[p].getDisplayId(true));
- }
+ System.out.println("Prod " + p + ": "
+ + prod[p].getDisplayId(true));
}
}
}
- else
- {
- noProds.addElement((dna ? new Object[] { al, al }
- : new Object[] { al }));
- }
-
- }
- } catch (Exception ex)
- {
- System.out.println("ERROR:Failed to retrieve test query.");
- ex.printStackTrace(System.out);
- }
-
- if (al == null)
- {
- System.out.println("ERROR:No alignment retrieved.");
- StringBuffer raw = sp.getRawRecords();
- if (raw != null)
- {
- System.out.println(raw.toString());
}
else
{
- System.out.println("ERROR:No Raw results.");
+ noProds.addElement((dna ? new Object[] { al, al }
+ : new Object[] { al }));
}
+
+ }
+ } catch (Exception ex)
+ {
+ System.out.println("ERROR:Failed to retrieve test query.");
+ ex.printStackTrace(System.out);
+ }
+
+ if (al == null)
+ {
+ System.out.println("ERROR:No alignment retrieved.");
+ StringBuffer raw = sp.getRawRecords();
+ if (raw != null)
+ {
+ System.out.println(raw.toString());
}
else
{
- System.out.println("Retrieved " + al.getHeight() + " sequences.");
- for (int s = 0; s < al.getHeight(); s++)
- {
- SequenceI sq = al.getSequenceAt(s);
- while (sq.getDatasetSequence() != null)
- {
- sq = sq.getDatasetSequence();
-
- }
- if (ds == null)
- {
- ds = new Alignment(new SequenceI[] { sq });
-
- }
- else
- {
- ds.addSequence(sq);
- }
- }
+ System.out.println("ERROR:No Raw results.");
+ }
+ }
+ else
+ {
+ System.out.println("Retrieved " + al.getHeight() + " sequences.");
+ if (ds == null)
+ {
+ ds = al.getDataset();
+ }
+ else
+ {
+ ds.append(al.getDataset());
+ al.setDataset(ds);
}
- System.out.flush();
- System.err.flush();
-
}
- if (noProds.size() > 0)
+ System.out.flush();
+ System.err.flush();
+ }
+ if (noProds.size() > 0)
+ {
+ Enumeration<Object[]> ts = noProds.elements();
+ while (ts.hasMoreElements())
+
{
- Enumeration<Object[]> ts = noProds.elements();
- while (ts.hasMoreElements())
-
+ Object[] typeSq = ts.nextElement();
+ boolean dna = (typeSq.length > 1);
+ AlignmentI al = (AlignmentI) typeSq[0];
+ System.out.println("Trying getProducts for "
+ + al.getSequenceAt(0).getDisplayId(true));
+ System.out.println("Search DS Xref for: " + (dna ? "dna" : "prot"));
+ // have a bash at finding the products amongst all the retrieved
+ // sequences.
+ SequenceI[] seqs = al.getSequencesArray();
+ Alignment prodal = new CrossRef(seqs, ds).findXrefSequences(null,
+ dna);
+ System.out.println("Found "
+ + ((prodal == null) ? "no" : "" + prodal.getHeight())
+ + " products");
+ if (prodal != null)
{
- Object[] typeSq = ts.nextElement();
- boolean dna = (typeSq.length > 1);
- AlignmentI al = (AlignmentI) typeSq[0];
- System.out.println("Trying getProducts for "
- + al.getSequenceAt(0).getDisplayId(true));
- System.out.println("Search DS Xref for: "
- + (dna ? "dna" : "prot"));
- // have a bash at finding the products amongst all the retrieved
- // sequences.
- SequenceI[] seqs = al.getSequencesArray();
- Alignment prodal = jalview.analysis.CrossRef.findXrefSequences(
- seqs, dna, null, ds);
- System.out.println("Found "
- + ((prodal == null) ? "no" : "" + prodal.getHeight())
- + " products");
- if (prodal != null)
+ SequenceI[] prod = prodal.getSequencesArray(); // note
+ // should
+ // test
+ // rather
+ // than
+ // throw
+ // away
+ // codon
+ // mapping
+ // (if
+ // present)
+ for (int p = 0; p < prod.length; p++)
{
- SequenceI[] prod = prodal.getSequencesArray(); // note
- // should
- // test
- // rather
- // than
- // throw
- // away
- // codon
- // mapping
- // (if
- // present)
- for (int p = 0; p < prod.length; p++)
- {
- System.out.println("Prod " + p + ": "
- + prod[p].getDisplayId(true));
- }
+ System.out.println("Prod " + p + ": "
+ + prod[p].getDisplayId(true));
}
}
-
}
-
}
}
-
}
package jalview.ws.dbsources;
import static org.testng.AssertJUnit.assertEquals;
+import static org.testng.AssertJUnit.assertFalse;
+import static org.testng.AssertJUnit.assertNotNull;
import static org.testng.AssertJUnit.assertNull;
import jalview.datamodel.PDBEntry;
import jalview.datamodel.SequenceFeature;
+import jalview.datamodel.SequenceI;
import jalview.datamodel.UniprotEntry;
import java.io.Reader;
+ "<protein><recommendedName><fullName>Mitogen-activated protein kinase 13</fullName><fullName>Henry</fullName></recommendedName></protein>"
+ "<dbReference type=\"PDB\" id=\"2FSQ\"><property type=\"method\" value=\"X-ray\"/><property type=\"resolution\" value=\"1.40\"/></dbReference>"
+ "<dbReference type=\"PDBsum\" id=\"2FSR\"/>"
+ + "<dbReference type=\"EMBL\" id=\"AE007869\"><property type=\"protein sequence ID\" value=\"AAK85932.1\"/><property type=\"molecule type\" value=\"Genomic_DNA\"/></dbReference>"
+ "<feature type=\"signal peptide\" evidence=\"7\"><location><begin position=\"1\"/><end position=\"18\"/></location></feature>"
+ "<feature type=\"propeptide\" description=\"Activation peptide\" id=\"PRO_0000027399\" evidence=\"9 16 17 18\"><location><begin position=\"19\"/><end position=\"20\"/></location></feature>"
+ "<feature type=\"chain\" description=\"Granzyme B\" id=\"PRO_0000027400\"><location><begin position=\"21\"/><end position=\"247\"/></location></feature>"
* Check cross-references
*/
Vector<PDBEntry> xrefs = entry.getDbReference();
- assertEquals(2, xrefs.size());
+ assertEquals(3, xrefs.size());
PDBEntry xref = xrefs.get(0);
assertEquals("2FSQ", xref.getId());
assertEquals("PDB", xref.getType());
- assertEquals(2, xref.getProperty().size());
- assertEquals("X-ray", xref.getProperty().get("method"));
- assertEquals("1.40", xref.getProperty().get("resolution"));
+ assertEquals("X-ray", xref.getProperty("method"));
+ assertEquals("1.40", xref.getProperty("resolution"));
xref = xrefs.get(1);
assertEquals("2FSR", xref.getId());
assertEquals("PDBsum", xref.getType());
- assertNull(xref.getProperty());
+ assertFalse(xref.getProperties().hasMoreElements());
+
+ xref = xrefs.get(2);
+ assertEquals("AE007869", xref.getId());
+ assertEquals("EMBL", xref.getType());
+ assertEquals("AAK85932.1",
+ xref.getProperty("protein sequence ID"));
+ assertEquals("Genomic_DNA",
+ xref.getProperty("molecule type"));
+ }
+
+ @Test(groups = { "Functional" })
+ public void testGetUniprotSequence()
+ {
+ UniprotEntry entry = new Uniprot().getUniprotEntries(
+ new StringReader(UNIPROT_XML)).get(0);
+ SequenceI seq = new Uniprot().uniprotEntryToSequenceI(entry);
+ assertNotNull(seq);
+ assertEquals(6, seq.getDBRefs().length); // 2*Uniprot, PDB, PDBsum, 2*EMBL
+
}
/**
{
UniprotEntry entry = new Uniprot().getUniprotEntries(
new StringReader(UNIPROT_XML)).get(0);
-
+
/*
* recommended names concatenated with space separator
*/
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
package jalview.ws.ebi;
import static org.testng.AssertJUnit.assertEquals;
import jalview.datamodel.AlignmentI;
import jalview.gui.Jalview2XML;
import jalview.io.AnnotationFile;
+import jalview.io.FileLoader;
import jalview.io.FormatAdapter;
import jalview.io.StockholmFileTest;
import jalview.ws.jws2.Jws2Discoverer;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
+import compbio.metadata.Argument;
import compbio.metadata.WrongParameterException;
public class RNAStructExportImport
Assert.fail("no web service");
}
- jalview.io.FileLoader fl = new jalview.io.FileLoader(false);
+ FileLoader fl = new FileLoader(false);
- af = fl.LoadFileWaitTillLoaded(testseqs, jalview.io.FormatAdapter.FILE);
+ af = fl.LoadFileWaitTillLoaded(testseqs, FormatAdapter.FILE);
assertNotNull("Couldn't load test data ('" + testseqs + "')", af);
} catch (InterruptedException x)
{
}
- ;
} while (af.getViewport().getCalcManager().isWorking());
AlignmentI orig_alig = af.getViewport().getAlignment();
} catch (InterruptedException x)
{
}
- ;
} while (af.getViewport().getCalcManager().isWorking());
AlignmentI orig_alig = af.getViewport().getAlignment();
String anfileout = new AnnotationFile()
.printAnnotationsForAlignment(al);
- assertTrue(
+ assertNotNull(
"Test "
+ testname
+ "\nAlignment annotation file was not regenerated. Null string",
- anfileout != null);
+ anfileout);
assertTrue(
"Test "
+ testname
@Test(groups = { "Functional" })
public void testRnaalifoldSettingsRecovery()
{
- List<compbio.metadata.Argument> opts = new ArrayList<compbio.metadata.Argument>();
- for (compbio.metadata.Argument rg : (List<compbio.metadata.Argument>) rnaalifoldws
- .getRunnerConfig().getArguments())
+ List<Argument> opts = new ArrayList<Argument>();
+ for (Argument rg : (List<Argument>) rnaalifoldws.getRunnerConfig()
+ .getArguments())
{
if (rg.getDescription().contains("emperature"))
{
import jalview.ws.dbsources.Uniprot;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.List;
import org.testng.annotations.AfterClass;
@Test(groups = { "Functional" })
public void testStandardProtDbs()
{
- String[] defdb = DBRefSource.PROTEINDBS;
+ List<String> defdb = new ArrayList<String>();
+ defdb.addAll(Arrays.asList(DBRefSource.PROTEINDBS));
+ defdb.add(DBRefSource.PDB);
List<DbSourceProxy> srces = new ArrayList<DbSourceProxy>();
SequenceFetcher sfetcher = new SequenceFetcher();
boolean pdbFound = false;
sfs[0].getType()));
assertEquals(embl.getDbSource(), sfs[0].getFeatureGroup());
DBRefEntry[] dr = DBRefUtils.selectRefs(seq.getDBRefs(),
- new String[] { DBRefSource.UNIPROT, DBRefSource.UNIPROTKB,
- DBRefSource.EMBLCDSProduct, DBRefSource.ENSEMBL });
+ new String[] { DBRefSource.UNIPROT });
assertNotNull(dr);
assertEquals("Expected a single Uniprot cross reference", 1, dr.length);
assertEquals("Expected cross reference map to be one amino acid", dr[0]
.getMap().getMappedWidth(), 1);
assertEquals("Expected local reference map to be 3 nucleotides", dr[0]
.getMap().getWidth(), 3);
- AlignmentI sprods = CrossRef.findXrefSequences(
- alsq.getSequencesArray(), true, dr[0].getSource(), alsq);
+ AlignmentI sprods = new CrossRef(alsq.getSequencesArray(), alsq)
+ .findXrefSequences(dr[0].getSource(), true);
assertNotNull(
"Couldn't recover cross reference sequence from dataset. Was it ever added ?",
sprods);
package jalview.ws.sifts;
import jalview.api.DBRefEntryI;
+import jalview.bin.Cache;
import jalview.datamodel.DBRefEntry;
import jalview.datamodel.DBRefSource;
import jalview.datamodel.Sequence;
@BeforeTest(alwaysRun = true)
public void populateExpectedMapping() throws SiftsException
- {
+ {
expectedMapping.put(51, new int[] { 1, 2 });
expectedMapping.put(52, new int[] { 2, 7 });
expectedMapping.put(53, new int[] { 3, 12 });
expectedMapping.put(145, new int[] { 95, 714 });
expectedMapping.put(146, new int[] { 96, 722 });
expectedMapping.put(147, new int[] { 97, 729 });
- }
-
+ }
+
@BeforeTest(alwaysRun = true)
public void setUpSiftsClient() throws SiftsException
{
+ // read test props before manipulating config
+ Cache.loadProperties("test/jalview/io/testProps.jvprops");
// SIFTs entries are updated weekly - so use saved SIFTs file to enforce
// test reproducibility
new SiftsSettings();
}
}
-
@Test(groups = { "Functional" })
public void getAllMappingAccessionTest()
{
// TODO delete when auto-fetching of DBRefEntry is implemented
DBRefEntry dbRef = new DBRefEntry("uniprot", "", "P00221");
- dbRef.setStartRes(1);
- dbRef.setEndRes(147);
testSeq.addDBRef(dbRef);
// testSeq.setSourceDBRef(dbRef);
try
{
HashMap<Integer, int[]> actualMapping = siftsClient.getGreedyMapping(
- "A", testSeq,
- null);
+ "A", testSeq, null);
Assert.assertEquals(testSeq.getStart(), 1);
Assert.assertEquals(testSeq.getEnd(), 147);
Assert.assertEquals(actualMapping, expectedMapping);
private void populateAtomPositionsNullTest1()
throws IllegalArgumentException, SiftsException
{
- siftsClient.populateAtomPositions(null, null);
+ siftsClient.populateAtomPositions(null, null);
}
@Test(
DBRefEntryI expectedDBRef = new DBRefEntry();
expectedDBRef.setSource(DBRefSource.UNIPROT);
expectedDBRef.setAccessionId("P00221");
- expectedDBRef.setStartRes(1);
- expectedDBRef.setEndRes(147);
expectedDBRef.setVersion("");
Assert.assertEquals(actualValidSrcDBRef, expectedDBRef);
} catch (Exception e)
expectedExceptions = SiftsException.class)
public void getValidSourceDBRefExceptionTest() throws SiftsException
{
- SequenceI invalidTestSeq = new Sequence("testSeq", "ABCDEFGH");
+ SequenceI invalidTestSeq = new Sequence("testSeq", "ABCDEFGH");
try
{
siftsClient.getValidSourceDBRef(invalidTestSeq);
DBRefEntryI validDBRef = new DBRefEntry();
validDBRef.setSource(DBRefSource.UNIPROT);
validDBRef.setAccessionId("P00221");
- validDBRef.setStartRes(1);
- validDBRef.setEndRes(147);
validDBRef.setVersion("");
Assert.assertTrue(siftsClient.isValidDBRefEntry(validDBRef));
}
--- /dev/null
+import java.io.BufferedReader;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.StringReader;
+
+/**
+ * A file reader that concatenates lines
+ *
+ * @author gmcarstairs
+ *
+ */
+public class BufferedLineReader
+{
+ interface LineCleaner
+ {
+ String cleanLine(String l);
+ }
+
+ /*
+ * a reader for the file being read
+ */
+ private BufferedReader br;
+
+ /*
+ * optional handler to post-process each line as it is read
+ */
+ private LineCleaner cleaner;
+
+ /*
+ * current buffer of <bufferSize> post-processed input lines
+ */
+ private String[] buffer;
+
+ private boolean atEof;
+
+ /**
+ * Constructor
+ *
+ * @param reader
+ * @param bufferSize
+ * the number of lines to concatenate at a time while reading
+ * @param tidier
+ * an optional callback handler to post-process each line after
+ * reading
+ * @throws FileNotFoundException
+ */
+ public BufferedLineReader(BufferedReader reader, int bufferSize,
+ LineCleaner tidier)
+ throws IOException
+ {
+ br = reader;
+ buffer = new String[bufferSize];
+ cleaner = tidier;
+
+ /*
+ * load up the buffer with N-1 lines, ready for the first read
+ */
+ for (int i = 1; i < bufferSize; i++)
+ {
+ readLine();
+ }
+
+ }
+
+ /**
+ * Reads the next line from file, invokes the post-processor if one was
+ * provided, and returns the 'cleaned' line, or null at end of file.
+ *
+ * @return
+ */
+ private String readLine() // throws IOException
+ {
+ if (atEof)
+ {
+ return null;
+ }
+
+ String line = null;
+ try
+ {
+ line = br.readLine();
+ } catch (IOException e)
+ {
+ e.printStackTrace();
+ }
+ if (line == null)
+ {
+ atEof = true;
+ return null;
+ }
+ if (cleaner != null)
+ {
+ line = cleaner.cleanLine(line);
+ }
+
+ /*
+ * shuffle down the lines buffer and add the new line
+ * in the last position
+ */
+ for (int i = 1; i < buffer.length; i++)
+ {
+ buffer[i - 1] = buffer[i];
+ }
+ buffer[buffer.length - 1] = line;
+ return line;
+ }
+
+ /**
+ * Returns a number of concatenated lines from the file, or null at end of
+ * file.
+ *
+ * @return
+ */
+ public String read()
+ {
+ if (readLine() == null)
+ {
+ return null;
+ }
+ StringBuilder result = new StringBuilder(100 * buffer.length);
+ for (String line : buffer)
+ {
+ if (line != null)
+ {
+ result.append(line);
+ }
+ }
+ return result.toString();
+ }
+
+ /**
+ * A main 'test' method!
+ *
+ * @throws IOException
+ */
+ public static void main(String[] args) throws IOException
+ {
+ String data = "Now is the winter\n" + "Of our discontent\n"
+ + "Made glorious summer\n" + "By this sun of York\n";
+ BufferedReader br = new BufferedReader(new StringReader(data));
+ BufferedLineReader reader = new BufferedLineReader(br, 3,
+ new LineCleaner()
+ {
+ @Override
+ public String cleanLine(String l)
+ {
+ return l.toUpperCase();
+ }
+ });
+ String line = reader.read();
+ String expect = "NOW IS THE WINTEROF OUR DISCONTENTMADE GLORIOUS SUMMER";
+ if (!line.equals(expect))
+ {
+ System.err.println("Fail: expected '" + expect + "', found '" + line
+ + ";");
+ }
+ else
+ {
+ System.out.println("Line one ok!");
+ }
+ line = reader.read();
+ expect = "OF OUR DISCONTENTMADE GLORIOUS SUMMERBY THIS SUN OF YORK";
+ if (!line.equals(expect))
+ {
+ System.err.println("Fail: expected '" + expect + "', found '" + line
+ + "'");
+ }
+ else
+ {
+ System.out.println("Line two ok!!");
+ }
+ line = reader.read();
+ if (line != null)
+ {
+ System.err.println("Fail: expected null at eof, got '" + line + "'");
+ }
+ else
+ {
+ System.out.println("EOF ok!!!");
+ }
+ }
+}
-
-
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
* @author gmcarstairs
*
*/
-public class HelpLinksChecker
+public class HelpLinksChecker implements BufferedLineReader.LineCleaner
{
private static final String HELP_HS = "help.hs";
private int anchorRefCount = 0;
+ private int invalidAnchorRefCount = 0;
+
private int externalHrefCount = 0;
private int invalidMapUrlCount = 0;
if (args.length == 0 || args.length > 2
|| (args.length == 2 && !args[1].equals("-nointernet")))
{
- System.out.println("Usage: <pathToHelpFolder> [-nointernet]");
+ log("Usage: <pathToHelpFolder> [-nointernet]");
return;
}
*/
void checkLinks(String helpDirectoryPath) throws IOException
{
- System.out.println("Checking help file links");
- File helpFolder = new File(helpDirectoryPath);
+ log("Checking help file links");
+ File helpFolder = new File(helpDirectoryPath).getCanonicalFile();
if (!helpFolder.exists())
{
- System.out.println("Can't find " + helpDirectoryPath);
+ log("Can't find " + helpDirectoryPath);
return;
}
- internetAvailable &= connectToUrl("http://www.example.com");
+ internetAvailable &= connectToUrl("http://www.example.org");
Map<String, String> tocTargets = checkHelpMappings(helpFolder);
unusedTargets.remove(image);
if (!tocTargets.containsKey(image))
{
- System.out.println(String.format(
- "Invalid image '%s' at line %d of %s", image, lineNo,
- HELP_HS));
+ log(String.format("Invalid image '%s' at line %d of %s", image,
+ lineNo, HELP_HS));
invalidImageCount++;
}
}
*/
private void reportResults(Map<String, String> unusedTargets)
{
- System.out.println("\nResults:");
- System.out.println(targetCount + " distinct help targets");
- System.out.println(mapCount + " help mappings");
- System.out.println(invalidTargetCount + " invalid targets");
- System.out.println(unusedTargets.size() + " unused targets");
+ log("\nResults:");
+ log(targetCount + " distinct help targets");
+ log(mapCount + " help mappings");
+ log(invalidTargetCount + " invalid targets");
+ log(unusedTargets.size() + " unused targets");
for (String target : unusedTargets.keySet())
{
- System.out.println(String.format(" %s: %s", target,
- unusedTargets.get(target)));
+ log(String.format(" %s: %s", target, unusedTargets.get(target)));
}
- System.out.println(invalidMapUrlCount + " invalid map urls");
- System.out.println(invalidImageCount + " invalid image attributes");
- System.out.println(String.format(
- "%d internal href links (%d with anchors - not checked)",
+ log(invalidMapUrlCount + " invalid map urls");
+ log(invalidImageCount + " invalid image attributes");
+ log(String.format("%d internal href links (%d with anchors)",
internalHrefCount, anchorRefCount));
- System.out.println(invalidInternalHrefCount
- + " invalid internal href links");
- System.out.println(externalHrefCount + " external href links");
+ log(invalidInternalHrefCount + " invalid internal href links");
+ log(invalidAnchorRefCount + " invalid internal anchor links");
+ log(externalHrefCount + " external href links");
if (internetAvailable)
{
- System.out.println(invalidExternalHrefCount
- + " invalid external href links");
+ log(invalidExternalHrefCount + " invalid external href links");
}
else
{
System.out
.println("External links not verified as internet not available");
}
+ if (invalidInternalHrefCount > 0 || invalidExternalHrefCount > 0
+ || invalidImageCount > 0 || invalidAnchorRefCount > 0)
+ {
+ log("*** Failed ***");
+ System.exit(1);
+ }
+ log("*** Success ***");
+ }
+ /**
+ * @param s
+ */
+ static void log(String s)
+ {
+ System.out.println(s);
}
/**
internalHrefCount++;
File hrefFile = href.equals("") ? htmlFile : new File(htmlFolder,
href);
- if (!hrefFile.exists())
+ if (hrefFile != htmlFile && !fileExists(hrefFile, href))
{
badLink = true;
invalidInternalHrefCount++;
{
if (!checkAnchorExists(hrefFile, anchor))
{
- System.out.println(String.format(
- "Invalid anchor: %s at line %d of %s", anchor,
- lineNo, getPath(htmlFile)));
+ log(String.format("Invalid anchor: %s at line %d of %s",
+ anchor, lineNo, getPath(htmlFile)));
+ invalidAnchorRefCount++;
}
}
}
}
if (badLink)
{
- System.out.println(String.format(
- "Invalid href %s at line %d of %s", href, lineNo,
- getPath(htmlFile)));
+ log(String.format("Invalid href %s at line %d of %s", href,
+ lineNo, getPath(htmlFile)));
}
}
data = br.readLine();
}
/**
+ * Performs a case-sensitive check that the href'd file exists
+ *
+ * @param hrefFile
+ * @return
+ * @throws IOException
+ */
+ boolean fileExists(File hrefFile, String href) throws IOException
+ {
+ if (!hrefFile.exists())
+ {
+ return false;
+ }
+
+ /*
+ * On Mac or Windows, file.exists() is not case sensitive, so do an
+ * additional check with case sensitivity
+ */
+ int slashPos = href.lastIndexOf(File.separator);
+ String expectedFileName = slashPos == -1 ? href : href
+ .substring(slashPos + 1);
+ String cp = hrefFile.getCanonicalPath();
+ slashPos = cp.lastIndexOf(File.separator);
+ String actualFileName = slashPos == -1 ? cp : cp
+ .substring(slashPos + 1);
+
+ return expectedFileName.equals(actualFileName);
+ }
+
+ /**
* Reads the file and checks for the presence of the given html anchor
*
* @param hrefFile
try
{
BufferedReader br = new BufferedReader(new FileReader(hrefFile));
- String data = br.readLine();
+ BufferedLineReader blr = new BufferedLineReader(br, 3, this);
+ String data = blr.read();
while (data != null)
{
if (data.contains(nameAnchor) || data.contains(idAnchor))
found = true;
break;
}
- data = br.readLine();
+ data = blr.read();
}
br.close();
} catch (IOException e)
mapCount++;
if (targets.containsKey(target))
{
- System.out.println(String.format(
+ log(String.format(
"Duplicate target mapping to %s at line %d of %s",
target, lineNo, HELP_JHM));
}
}
if (!new File(helpFolder, url).exists())
{
- System.out.println(String.format(
- "Invalid url path '%s' at line %d of %s", url, lineNo,
- HELP_JHM));
+ log(String.format("Invalid url path '%s' at line %d of %s", url,
+ lineNo, HELP_JHM));
invalidMapUrlCount++;
}
}
unusedTargets.remove(target);
if (!tocTargets.containsKey(target))
{
- System.out.println(String.format(
- "Invalid target '%s' at line %d of %s", target, lineNo,
- HELP_TOC_XML));
+ log(String.format("Invalid target '%s' at line %d of %s", target,
+ lineNo, HELP_TOC_XML));
invalidTargetCount++;
}
}
}
return value;
}
+
+ /**
+ * Trim whitespace from concatenated lines but preserve one space for valid
+ * parsing
+ */
+ @Override
+ public String cleanLine(String l)
+ {
+ return l.trim() + " ";
+ }
}
//========================================================================
//
-
import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.DefaultHandler;
// In this example it is the current directory but it can be configured to
// anything that the jvm has access to.
resource_handler.setDirectoriesListed(true);
- resource_handler.setWelcomeFiles(new String[]
- { "applets.html" });
+ resource_handler.setWelcomeFiles(new String[] { "applets.html" });
resource_handler.setResourceBase(".");
// Add the ResourceHandler to the server.
// GzipHandler gzip = new GzipHandler();
// server.setHandler(gzip);
HandlerList handlers = new HandlerList();
- handlers.setHandlers(new Handler[]
- { resource_handler, new DefaultHandler() });
+ handlers.setHandlers(new Handler[] { resource_handler,
+ new DefaultHandler() });
server.setHandler(handlers);
// Start things up! By using the server.join() the server thread will join
// for more details.
server.start();
server.join();
-}
+ }
}
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.util.HashSet;
import java.util.Properties;
import java.util.TreeSet;
+import java.util.regex.Pattern;
/**
* This class scans Java source files for calls to MessageManager and reports
* @author gmcarstairs
*
*/
-public class MessageBundleChecker
+public class MessageBundleChecker implements BufferedLineReader.LineCleaner
{
/*
+ * regex ^"[^"]*"$
+ * opening quote, closing quote, no quotes in between
+ */
+ static Pattern STRING_PATTERN = Pattern.compile("^\"[^\"]*\"$");
+
+ /*
* number of text lines to read at a time in order to parse
* code that is split over several lines
*/
static int bufferSize = 3;
+ /*
+ * resource bundle key is arg0 for these methods
+ */
static final String METHOD1 = "MessageManager.getString(";
- static final String METHOD2 = "MessageManager.getStringOrReturn(";
+ static final String METHOD2 = "MessageManager.formatMessage(";
- static final String METHOD3 = "MessageManager.formatMessage(";
+ static final String METHOD3 = "MessageManager.getStringOrReturn(";
- static final String[] METHODS = { METHOD1, METHOD2, METHOD3 };
+ /*
+ * resource bundle key is arg1 for this method
+ */
+ static final String JVINIT = "JvSwingUtils.jvInitComponent(";
+
+ static final String[] METHODS = { METHOD1, METHOD2, METHOD3, JVINIT };
/*
* root of the Java source folders we want to scan
+ " possibly invalid parameter calls");
System.out.println(messageKeys.size()
- + " keys not found, possibly unused");
+ + " keys not found, either unused or constructed dynamically");
for (String key : messageKeys)
{
System.out.println(" " + key);
}
javaCount++;
- String[] lines = new String[bufferSize];
- BufferedReader br = new BufferedReader(new FileReader(f));
- for (int i = 0; i < bufferSize; i++)
+ /*
+ * skip class with designed dynamic lookup call
+ */
+ if (path.endsWith("gui/JvSwingUtils.java"))
{
- String readLine = br.readLine();
- lines[i] = stripCommentsAndTrim(readLine);
+ return;
}
- int lineNo = 0;
+ BufferedReader br = new BufferedReader(new FileReader(f));
+ BufferedLineReader blr = new BufferedLineReader(br, bufferSize, this);
- while (lines[bufferSize - 1] != null)
+ int lineNo = 0;
+ String line = blr.read();
+ while (line != null)
{
lineNo++;
- inspectSourceLines(path, lineNo, lines);
-
- for (int i = 0; i < bufferSize - 1; i++)
- {
- lines[i] = lines[i + 1];
- }
- lines[bufferSize - 1] = stripCommentsAndTrim(br.readLine());
+ inspectSourceLines(path, lineNo, line);
+ line = blr.read();
}
br.close();
}
- /*
- * removes anything after (and including) '//'
- */
- private String stripCommentsAndTrim(String line)
- {
- if (line != null)
- {
- int pos = line.indexOf("//");
- if (pos != -1)
- {
- line = line.substring(0, pos);
- }
- line = line.replace("\t", " ").trim();
- }
- return line;
- }
-
/**
* Look for calls to MessageManager methods, possibly split over two or more
- * lines
+ * lines that have been concatenated while parsing the file
*
* @param path
* @param lineNo
- * @param lines
+ * @param line
*/
- private void inspectSourceLines(String path, int lineNo, String[] lines)
+ private void inspectSourceLines(String path, int lineNo, String line)
{
- String lineNos = String.format("%d-%d", lineNo, lineNo + lines.length
+ String lineNos = String
+ .format("%d-%d", lineNo, lineNo + bufferSize
- 1);
- String combined = combineLines(lines);
for (String method : METHODS)
{
- int pos = combined.indexOf(method);
+ int pos = line.indexOf(method);
if (pos == -1)
{
continue;
}
- String methodArgs = combined.substring(pos + method.length());
+
+ /*
+ * extract what follows the opening bracket of the method call
+ */
+ String methodArgs = line.substring(pos + method.length()).trim();
if ("".equals(methodArgs))
{
/*
- * continues on next line - catch in the next read loop iteration
+ * arguments are on next line - catch in the next read loop iteration
*/
continue;
}
- if (!methodArgs.startsWith("\""))
+ if (methodArgs.indexOf(",") == -1 && methodArgs.indexOf(")") == -1)
{
- System.out.println(String.format(
- "Possible dynamic key at %s line %s %s",
- path.substring(sourcePath.length()), lineNos, combined));
+ /*
+ * arguments continue on next line - catch in the next read loop iteration
+ */
continue;
}
- methodArgs = methodArgs.substring(1);
- int quotePos = methodArgs.indexOf("\"");
- if (quotePos == -1)
+
+ if (JVINIT == method && methodArgs.indexOf(",") == -1)
+ {
+ /*
+ * not interested in 1-arg calls to jvInitComponent
+ */
+ continue;
+ }
+
+ if (METHOD3 == method)
+ {
+ System.out.println(String.format("Dynamic key at %s line %s %s",
+ path.substring(sourcePath.length()), lineNos, line));
+ continue;
+ }
+
+ String messageKey = getMessageKey(method, methodArgs);
+ if (messageKey == null)
{
System.out.println(String.format("Trouble parsing %s line %s %s",
- path.substring(sourcePath.length()), lineNos, combined));
+ path.substring(sourcePath.length()), lineNos, line));
continue;
}
- String messageKey = methodArgs.substring(0, quotePos);
+
+ if (!(STRING_PATTERN.matcher(messageKey).matches()))
+ {
+ System.out.println(String.format("Dynamic key at %s line %s %s",
+ path.substring(sourcePath.length()), lineNos, line));
+ continue;
+ }
+
+ /*
+ * strip leading and trailing quote
+ */
+ messageKey = messageKey.substring(1, messageKey.length() - 1);
+
if (!this.messages.containsKey(messageKey))
{
System.out.println(String.format(
}
}
- private String combineLines(String[] lines)
+ /**
+ * Helper method to parse out the resource bundle key parameter of a method
+ * call
+ *
+ * @param method
+ * @param methodArgs
+ * the rest of the source line starting with arguments to method
+ * @return
+ */
+ private String getMessageKey(String method, String methodArgs)
{
- String combined = "";
- if (lines != null)
+ String key = methodArgs;
+
+ /*
+ * locate second argument if calling jvInitComponent()
+ */
+ if (method == JVINIT)
{
- for (String line : lines)
+ int commaLoc = methodArgs.indexOf(",");
+ if (commaLoc == -1)
{
- if (line != null)
- {
- combined += line;
- }
+ return null;
}
+ key = key.substring(commaLoc + 1).trim();
}
- return combined;
+
+ /*
+ * take up to next comma or ) or end of line
+ */
+ int commaPos = key.indexOf(",");
+ int bracePos = key.indexOf(")");
+ int endPos = commaPos == -1 ? bracePos : (bracePos == -1 ? commaPos
+ : Math.min(commaPos, bracePos));
+ if (endPos == -1 && key.length() > 1 && key.endsWith("\""))
+ {
+ endPos = key.length();
+ }
+
+ return endPos == -1 ? null : key.substring(0, endPos);
}
/**
}
+ /**
+ * Remove any trailing comments, change tabs to space, and trim
+ */
+ @Override
+ public String cleanLine(String l)
+ {
+ if (l != null)
+ {
+ int pos = l.indexOf("//");
+ if (pos != -1)
+ {
+ l = l.substring(0, pos);
+ }
+ l = l.replace("\t", " ").trim();
+ }
+ return l;
+ }
+
}
--- /dev/null
+Checkstyle for Jalview
+----------------------
+
+http://checkstyle.sourceforge.net/
+GNU LGPL
+
+To get the Eclipse Checkstyle plugin
+------------------------------------
+ - Help | Eclipse Marketplace
+ - search for checkstyle
+ - install eclipse-cs checkstyle plugin
+The current version is 6.19.1 (August 2016).
+
+Config
+------
+
+ File Jalview/.checkstyle holds configuration for the "JalviewCheckstyle" ruleset.
+ This includes confining its scope to src/*.java and resources/*.properties.
+ This can be modified interactively through the checkstyle properties editor.
+
+ Checkstyle config files in utils/checkstyle:
+ checkstyle.xml : main configuration file with selected checkstyle modules
+ checkstyle-suppress.xml : rules to exclude certain checks / files
+ import-control.xml : package import rules
+
+ Checkstyle error messages can be customised. See TypeName for an example.
+
+How to use checkstyle
+---------------------
+
+ Option 1: enable it for the Jalview project
+ - right-click on project | Checkstyle | Activate Checkstyle
+ - notice CheckstyleNature gets added to the .project file
+ - don't commit this file unless we all agree to!
+ - Checkstyle will run as you recompile changed code
+
+ Option 2: on demand on selected code
+ - right-click on a class or package and Checkstyle | Check code with checkstyle
+ - (or Clear Checkstyle violations to remove checkstyle warnings)
+
+Checkstyle rules
+----------------
+ Documented at http://checkstyle.sourceforge.net/checks.html
+ Should be self-documenting in checkstyle.xml
+ Open for discussion:
+ - which rules to use
+ - what naming and layout standards to apply
+ - settings for complexity metrics
+ - whether any rules should report an error instead of a warning
+
+Suppressing findings
+--------------------
+ If there are warnings you judge it ok to suppress (false positives),
+ your options are (from most global to most local impact):
+ - remove the rule entirely
+ - adjust its properties
+ - add an entry in checkstyle-suppress.xml to skip the file for the rule
+ - add comments around the reported source lines
+ // CHECKSTYLE.OFF: RuleName 'a comment to justify suppression'
+ source code here
+ // CHECKSTYLE.ON: RuleName
+ The suppression should be as localised as possible, to avoid false negatives.
+
+Tips
+----
+ Sometimes checkstyle needs a kick before it will refresh its findings.
+ A whitespace edit in checkstyle.xml usually does this. There may be better ways.
+
+ Invalid configuration files may result in checkstyle failing with an error reported
+ in the Eclipse log file.
+ Help | Installation Details | Configuration takes you to a screen with a
+ 'View Error Log' button.
+
+ Sometimes checkstyle can fail silently. Try 'touching' (editing) config files, failing
+ that, carefully check / back out / redo any recent changes to its config.
+
+ Putting <!-- XML comments --> inside a checkstyle <module> causes it to be ignored!
+
+ If a rule doesn't behave as you expected, read its documentation carefully, including
+ the use and default value of any properties.
+
+ To highlight a single rule's findings, you can 'Configure Contents' of the Problems view
+ and filter on Text Contains <rule name> (case-sensitive).
+ Here you should select 'Use item limits' with a value of, say, 500, or Eclipse may
+ labour to display all warnings.
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!DOCTYPE suppressions PUBLIC
+ "-//Puppy Crawl//DTD Suppressions 1.1//EN"
+ "http://www.puppycrawl.com/dtds/suppressions_1_1.dtd">
+
+<suppressions>
+ <!--
+ Do not put individual file-level suppressions here.
+ Instead use embedded comments to switch checks on and off.
+ -->
+
+ <!--
+ Suppress check of XML binding generated code packages
+ -->
+ <suppress checks="[a-zA-Z0-9]*" files="jalview[\\/]schemabinding[\\/]*"/>
+ <suppress checks="[a-zA-Z0-9]*" files="jalview[\\/]binding[\\/]*"/>
+ <suppress checks="[a-zA-Z0-9]*" files="jalview[\\/]json[\\/]binding[\\/]*"/>
+ <suppress checks="[a-zA-Z0-9]*" files="jalview[\\/]xml[\\/]binding[\\/]*"/>
+
+ <!--
+ Suppress check of externally sourced code
+ -->
+ <suppress checks="[a-zA-Z0-9]*" files="com[\\/]*"/>
+ <suppress checks="[a-zA-Z0-9]*" files="ext[\\/]*"/>
+ <suppress checks="[a-zA-Z0-9]*" files="org[\\/]*"/>
+ <suppress checks="[a-zA-Z0-9]*" files="uk[\\/]*"/>
+
+ <!--
+ ImportControl can only handle one top level package
+ -->
+ <suppress checks="ImportControl" files="MCview[\\/]*" />
+ <suppress checks="ImportControl" files="vamsas[\\/]*" />
+
+ <!--
+ Suppress checks by name
+ -->
+ <suppress checks="FinalLocalVariable" files=".*\.java"/>
+
+ <!--
+ Suppress checks by id
+ -->
+ <suppress id="InterfaceNaming" files=".*\.java"/>
+ <suppress id="NoStaticInitialization" files=".*\.java"/>
+
+</suppressions>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE module PUBLIC "-//Puppy Crawl//DTD Check Configuration 1.3//EN" "http://www.puppycrawl.com/dtds/configuration_1_3.dtd">
+<!--
+ Jalview Checkstyle configuration file
+-->
+<module name="Checker">
+ <!-- Default severity is warning -->
+ <property name="severity" value="warning"/>
+ <property name="fileExtensions" value="java,properties"/>
+
+ <!--
+ Add any metrics that you wish to suppress to the following file.
+ -->
+ <module name="SuppressionFilter">
+ <property name="file" value="${basedir}/utils/checkstyle/checkstyle-suppress.xml"/>
+ </module>
+
+ <!--
+ Allow suppression of rules by comments, e.g.:
+ // CHECKSTYLE.OFF: ParameterNumber
+ ..method declaration
+ // CHECKSTYLE.ON: ParameterNumber
+ -->
+ <module name="SuppressionCommentFilter">
+ <property name="offCommentFormat" value="CHECKSTYLE.OFF\: ([\w\|]+)"/>
+ <property name="onCommentFormat" value="CHECKSTYLE.ON\: ([\w\|]+)"/>
+ <property name="checkFormat" value="$1"/>
+ </module>
+
+ <!--
+ Check language bundles have the same keys and no duplicates
+ (ensure Checkstyle is configured to scan non-source files)
+ -->
+ <module name="Translation">
+ <property name="fileExtensions" value="properties"/>
+ <property name="baseName" value="^Messages.*$"/>
+ </module>
+ <module name="UniqueProperties">
+ <property name="fileExtensions" value="properties" />
+ <property name="severity" value="error"/>
+ </module>
+
+ <!--
+ Maximum line count for source files
+ (note this can't be inside TreeWalker)
+ -->
+ <module name="FileLength">
+ <property name="max" value="1200"/>
+ <property name="fileExtensions" value="java"/>
+ </module>
+
+ <module name="TreeWalker">
+
+ <property name="tabWidth" value="4"/>
+
+ <!--
+ Enables parsing of suppressions comments
+ see http://checkstyle.sourceforge.net/config_filters.html#SuppressionCommentFilter
+ -->
+ <module name="FileContentsHolder"/>
+
+ <!-- ****************************** -->
+ <!-- NAMING STANDARDS -->
+ <!-- ****************************** -->
+
+ <!--
+ Naming convention for member fields. Start with (optional) underscore, then
+ lower case, then camel case; no internal underscores
+ -->
+ <module name="MemberName">
+ <property name="format" value="^_?[a-z][a-zA-Z0-9]*$"/>
+ </module>
+
+ <!--
+ Naming convention for methods. Start with (optional) underscore, then
+ lower case, then camel case; no internal underscores
+ -->
+ <module name="MethodName">
+ <property name="format" value="^_?[a-z]([a-zA-Z0-9]+)*$"/>
+ </module>
+
+ <!--
+ Name pattern for local final variables.
+ -->
+ <module name="LocalFinalVariableName">
+ <property name="format" value="^[a-z][a-zA-Z0-9]*$"/>
+ </module>
+
+ <!--
+ Name pattern for local variables
+ -->
+ <module name="LocalVariableName">
+ <property name="format" value="^[a-z][a-zA-Z0-9]*$"/>
+ </module>
+
+ <!--
+ Name pattern for constants (static final fields)
+ -->
+ <module name="ConstantName">
+ <property name="format" value="^[A-Z][A-Z0-9]*(_[A-Z0-9]+)*$"/>
+ </module>
+
+ <!--
+ Name pattern for parameters (note no underscores allowed)
+ -->
+ <module name="ParameterName">
+ <property name="format" value="^[a-z][a-zA-Z0-9]*$"/>
+ </module>
+
+ <!--
+ Name pattern for static (non-final) fields
+ -->
+ <module name="StaticVariableName">
+ <property name="format" value="^[a-z][a-zA-Z0-9_]*$"/>
+ </module>
+
+ <!--
+ Name pattern for classes
+ -->
+ <module name="TypeName">
+ <property name="format" value="[A-Z][a-zA-Z0-9]*$"/>
+ <property name="tokens" value="CLASS_DEF"/>
+ </module>
+
+ <!--
+ Name pattern for interfaces. All interfaces names must end with 'I'.
+ ** currently suppressed in checkstyle-suppress.xml **
+ -->
+ <module name="TypeName">
+ <property name="id" value="InterfaceNaming"/>
+ <property name="format" value="^[A-Z][a-zA-Z0-9]*I$"/>
+ <property name="tokens" value="INTERFACE_DEF"/>
+ <message key="name.invalidPattern" value="Interface names should end in a I"/>
+ </module>
+
+ <!--
+ Java package name pattern
+ -->
+ <module name="PackageName">
+ <property name="format" value="^[a-z]+(\.[a-z][a-z0-9]*)*$"/>
+ </module>
+
+ <!-- ****************************** -->
+ <!-- LAYOUT AND STYLE -->
+ <!-- ****************************** -->
+
+ <!--
+ Only one top level type per source file
+ -->
+ <module name="OuterTypeNumber"/>
+
+ <!--
+ Ensure a class has a package declaration
+ -->
+ <module name="PackageDeclaration"/>
+
+ <!--
+ see http://www.oracle.com/technetwork/java/javase/documentation/codeconventions-141855.html#1852
+ 1. Class (static) variables: public, protected, package, private
+ 2. Instance variables: public, protected, package, private
+ 3. Constructors
+ 4. Methods
+ -->
+ <module name="DeclarationOrder"/>
+
+ <!--
+ Modifier order should conform to JLS
+ see http://checkstyle.sourceforge.net/config_modifier.html#ModifierOrder
+ public protected private abstract static final transient volatile synchronized native strictfp
+ -->
+ <module name="ModifierOrder"/>
+
+ <!--
+ Declare variables in separate statements, for readability and bug avoidance
+ -->
+ <module name="MultipleVariableDeclarations"/>
+
+ <!--
+ Don't have more than one statement on a line
+ (code formatting on save may enforce this anyway)
+ -->
+ <module name="OneStatementPerLine"/>
+
+ <!--
+ Declare variables close to their point of first use
+ (doesn't handle variables used inside loops very well)
+ -->
+ <module name="VariableDeclarationUsageDistance">
+ <property name="allowedDistance" value="5" />
+ <message key="variable.declaration.usage.distance.extend"
+ value="Distance between declaration of ''{0}'' and its first use is {1}, suggested maximum is {2}. Consider moving, or make final if it may not be modified." />
+ </module>
+
+ <!--
+ Only use blocks within control statements
+ -->
+ <module name="AvoidNestedBlocks" />
+
+ <!--
+ Require at least a comment within a block.
+ Note this will accept auto-generated // TODO comments,
+ (but they should be flagged up by the TodoComment rule)
+ -->
+ <module name="EmptyBlock">
+ <property name="option" value="text"/>
+ </module>
+
+ <!--
+ Require braces round all code blocks within if/else/for/do/while
+ -->
+ <module name="NeedBraces"/>
+
+ <!--
+ Disallow empty ';' statements
+ -->
+ <module name="EmptyStatement"/>
+
+ <!--
+ Maximum number of return statements for a method
+ -->
+ <module name="ReturnCount">
+ <property name="max" value="4"/>
+ </module>
+
+ <!--
+ Don't use modifiers in contexts where their value is not optional,
+ for example all interface methods are always public
+ see http://checkstyle.sourceforge.net/config_modifier.html#RedundantModifier
+ -->
+ <module name="RedundantModifier"/>
+
+ <!--
+ Variables whose value is not modified should be declared final, both to show the
+ program's intent, and to allow compiler optimisation
+ ** currently suppressed in checkstyle-suppress.xml **
+ -->
+ <module name="FinalLocalVariable">
+ <property name="tokens" value="VARIABLE_DEF" />
+ </module>
+
+ <!--
+ Disallows shorthand of assigning values within an expression
+ -->
+ <module name="InnerAssignment"/>
+
+ <!--
+ Use Java style array declarations to assist in readability
+ -->
+ <module name="ArrayTypeStyle"/>
+
+ <!--
+ Use L not l to define a long constant
+ -->
+ <module name="UpperEll"/>
+
+ <!-- ****************************** -->
+ <!-- SIZE LIMITS -->
+ <!-- ****************************** -->
+
+ <!--
+ Maximum line count for methods
+ -->
+ <module name="MethodLength">
+ <property name="tokens" value="METHOD_DEF"/>
+ <property name="max" value="50"/>
+ <property name="countEmpty" value="false"/>
+ </module>
+
+ <!--
+ Maximum statement count for methods, constructors,
+ instance initialisation and static initialisation blocks
+ -->
+ <module name="ExecutableStatementCount">
+ <property name="max" value="30"/>
+ <property name="tokens" value="METHOD_DEF"/>
+ </module>
+ <module name="ExecutableStatementCount">
+ <property name="max" value="30"/>
+ <property name="tokens" value="CTOR_DEF"/>
+ </module>
+ <module name="ExecutableStatementCount">
+ <property name="max" value="4"/>
+ <property name="tokens" value="INSTANCE_INIT"/>
+ </module>
+ <module name="ExecutableStatementCount">
+ <property name="id" value="NoStaticInitialization"/>
+ <property name="max" value="0"/>
+ <property name="tokens" value="STATIC_INIT"/>
+ </module>
+
+ <!--
+ Maximum parameter count for methods
+ -->
+ <module name="ParameterNumber">
+ <property name="max" value="5"/>
+ </module>
+
+ <!--
+ Maximum line length for anonymous inner classes
+ -->
+ <module name="AnonInnerLength">
+ <property name="max" value="40"/>
+ </module>
+
+ <!-- ****************************** -->
+ <!-- IMPORTS -->
+ <!-- ****************************** -->
+
+ <!--
+ Ensures that there are no redundant or unused imports.
+ Should be handled by Save actions if using Eclipse
+ -->
+ <module name="RedundantImport"/>
+ <module name="UnusedImports"/>
+
+ <!--
+ Disallow * imports; may also be enforced by IDE Save Actions
+ -->
+ <module name="AvoidStarImport"/>
+
+ <!--
+ Disallow import of sun.* packages as they are not portable
+ -->
+ <module name="IllegalImport"/>
+
+ <!--
+ rules as to what packages each package may (not) import
+ see http://checkstyle.sourceforge.net/config_imports.html#ImportControl
+ -->
+ <module name="ImportControl">
+ <property name="file" value="${basedir}/utils/checkstyle/import-control.xml"/>
+ <property name="severity" value="error"/>
+ </module>
+
+ <!-- ****************************** -->
+ <!-- CATCH and THROW -->
+ <!-- ****************************** -->
+
+ <!--
+ Disallow catch of Exception, RunTimeException or Error
+ -->
+ <module name="IllegalCatch"/>
+
+ <!--
+ Disallow throw of Exception, RunTimeException or Error
+ -->
+ <module name="IllegalThrows"/>
+
+ <!-- ****************************** -->
+ <!-- CODING CHECKS -->
+ <!-- ****************************** -->
+
+ <!--
+ Check for use of factory method rather than constructor for specified classes
+ e.g. Boolean.valueOf(true) rather than new Boolean(true)
+ -->
+ <module name="IllegalInstantiation">
+ <property name="classes" value="java.lang.Boolean"/>
+ </module>
+
+ <!--
+ Check that "string".equals(value) is used rather than value.equals("string")
+ -->
+ <module name="EqualsAvoidNull"/>
+
+ <!--
+ Check that equals() and hashCode() are always overridden together
+ -->
+ <module name="EqualsHashCode"/>
+
+ <!--
+ Require switch statements to include a default
+ -->
+ <module name="MissingSwitchDefault"/>
+
+ <!--
+ Check that switch default follows all case statements
+ -->
+ <module name="DefaultComesLast">
+ <property name="severity" value="error"/>
+ </module>
+
+ <!--
+ Disallows fall-through in switch statements
+ i.e. a case without a break, return, throw or continue
+ NB a comment with the words "fall[s] through" suppresses this message
+ -->
+ <module name="FallThrough">
+ <property name="severity" value="error" />
+ </module>
+
+ <!--
+ Warn if boolean expressions can be simplified
+ -->
+ <module name="SimplifyBooleanExpression"/>
+
+ <!--
+ Warn if boolean return expressions can be simplified
+ -->
+ <module name="SimplifyBooleanReturn"/>
+
+ <!--
+ Classes with only private constructors should be declared final
+ -->
+ <module name="FinalClass"/>
+
+ <!--
+ Classes with only static methods should not be instantiable,
+ so should declare a private default constructor.
+ -->
+ <module name="HideUtilityClassConstructor"/>
+
+ <!--
+ An Interface should declare methods (do not use to define constants only)
+ -->
+ <module name="InterfaceIsType"/>
+
+ <!--
+ Disallow public fields in classes (other than constants)
+ -->
+ <module name="VisibilityModifier">
+ <property name="packageAllowed" value="true"/>
+ <property name="allowPublicImmutableFields" value="true"/>
+ </module>
+
+ <!--
+ Checks that a local variable or a parameter does not shadow a field that is defined in the same class.
+ Note this should also be configured as a compiler warning in the IDE.
+ -->
+ <module name="HiddenField"/>
+
+ <!--
+ Check that proper logging is used.
+ This may be suppressed in the class that provides logging functions.
+ -->
+ <module name="RegexpSinglelineJava">
+ <property name="id" value="NoSysout" />
+ <property name="format" value="System\.out\.println"/>
+ <property name="ignoreComments" value="true"/>
+ <message key="regexp.exceeded" value="Should use jalview.bin.Cache.log for logging"/>
+ </module>
+ <module name="RegexpSinglelineJava">
+ <property name="id" value="NoSyserr" />
+ <property name="format" value="System\.err\.println"/>
+ <property name="ignoreComments" value="true"/>
+ <message key="regexp.exceeded" value="Should use jalview.bin.Cache.log for logging"/>
+ </module>
+
+ <!--
+ Checks that classes that define a covariant equals() method also override
+ method equals(java.lang.Object).
+ -->
+ <module name="CovariantEquals"/>
+
+ <!--
+ Checks that there are no "magic numbers" (numeric literals)
+ -->
+ <module name="MagicNumber">
+ <property name="ignoreNumbers" value="-1,0,1,2"/>
+ </module>
+
+ <!--
+ Check that loop control variables are not modified inside the for block
+ -->
+ <module name="ModifiedControlVariable">
+ </module>
+
+ <!--
+ Checks that string literals are not used with == or !=.
+ -->
+ <module name="StringLiteralEquality">
+ </module>
+
+ <!--
+ Don't override clone - it never works!
+ -->
+ <module name="NoClone"/>
+
+ <!--
+ Checks that clone() invokes super.clone()
+ (for classes that break the NoClone rule)
+ -->
+ <module name="SuperClone"/>
+
+ <!--
+ Checks that finalize() invokes super.finalize()
+ -->
+ <module name="SuperFinalize"/>
+
+ <!--
+ Disallow assignment of parameters.
+ -->
+ <module name="ParameterAssignment"/>
+
+ <!--
+ Checks for multiple occurrences of the same string literal within a single file.
+ NB - does not check for the same string in different files.
+ -->
+ <module name="MultipleStringLiterals">
+ <property name="allowedDuplicates" value="1"/>
+ </module>
+
+ <!--
+ Checks that exceptions are immutable (have only final fields)
+ -->
+ <module name="MutableException"/>
+
+ <!--
+ A general rule to check for source text tokens that shouldn't be there
+ see http://checkstyle.sourceforge.net/apidocs/com/puppycrawl/tools/checkstyle/api/TokenTypes.html
+ -->
+ <module name="IllegalToken">
+ <property name="tokens" value="LITERAL_ASSERT"/>
+ </module>
+
+ <!-- ****************************** -->
+ <!-- COMPLEXITY -->
+ <!-- ****************************** -->
+
+ <!--
+ Restrict the number of number of &&, ||, &, | and ^ in an expression.
+ Note that the operators & and | are not only integer bitwise operators, they are also the
+ non-shortcut versions of the boolean operators && and ||.
+ -->
+ <module name="BooleanExpressionComplexity">
+ <property name="max" value="3"/>
+ </module>
+
+ <!--
+ This metric measures the number of instantiations of other classes within the given class.
+ The higher the DAC, the more complex the data structure of the system.
+ -->
+ <module name="ClassDataAbstractionCoupling">
+ <property name="max" value="7"/>
+ </module>
+
+ <!--
+ The number of other classes a class relies on. A high number indicates over-complex
+ class interdependencies that might benefit from refactoring.
+ -->
+ <module name="ClassFanOutComplexity">
+ <property name="max" value="10"/>
+ </module>
+
+ <!--
+ Checks cyclomatic complexity against a specified limit. The complexity is a measure
+ of the minimum number of possible paths through the source and therefore the number of required
+ tests. Consider re-factoring if at or above 10.
+ -->
+ <module name="CyclomaticComplexity">
+ <property name="max" value="15"/>
+ </module>
+
+ <!--
+ The NPATH metric computes the number of possible execution paths through a function. It takes
+ into account the nesting of conditional statements and multi-part boolean expressions
+ (e.g., A && B, C || D, etc.).
+ -->
+ <module name="NPathComplexity">
+ <property name="max" value="200"/>
+ </module>
+
+ <!--
+ Maximum number of throws statements in a method
+ -->
+ <module name="ThrowsCount">
+ <property name="max" value="2"/>
+ </module>
+
+ <!--
+ Maximum if-else depth
+ -->
+ <module name="NestedIfDepth">
+ <property name="max" value="4"/>
+ </module>
+
+ <!--
+ Restricts nested try blocks to a specified depth.
+ -->
+ <module name="NestedTryDepth">
+ <property name="max" value="2"/>
+ </module>
+
+ <!-- ****************************** -->
+ <!-- TODO -->
+ <!-- ****************************** -->
+
+ <!--
+ Checks for uncommented main() methods (debugging leftovers)
+ -->
+ <module name="UncommentedMain"/>
+
+ <!--
+ Check for TODO and similar comments
+ -->
+ <module name="TodoComment">
+ <property name="format" value="(TODO)|(FIXME)"/>
+ <message key="todo.match" value="TODO or FIXME comment"/>
+ </module>
+
+ <module name="TodoComment">
+ <property name="format" value="DOCUMENT ME"/>
+ <message key="todo.match" value="Documentation incomplete"/>
+ </module>
+
+ </module>
+</module>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!DOCTYPE import-control PUBLIC
+ "-//Puppy Crawl//DTD Import Control 1.1//EN"
+ "http://www.puppycrawl.com/dtds/import_control_1_1.dtd">
+
+ <!--
+ see http://checkstyle.sourceforge.net/config_imports.html#ImportControl
+ allow/disallow rules propagate to sub-packages
+ unless local-only="true" is specified
+
+ note this can handle only one top-level package, so ImportControl is
+ suppressed for MCview and vamsas in checkstyle-suppress.xml
+ (all rules are suppressed for com/ext/org/uk)
+ -->
+ <import-control pkg="jalview">
+
+ <allow pkg="java"/>
+ <allow pkg="jalview"/>
+ <allow pkg="com.stevesoft.pat"/>
+
+ <subpackage name="appletgui">
+ <disallow pkg="javax.swing"/>
+ <disallow pkg="jalview.gui"/>
+ <disallow pkg="jalview.ws"/>
+ <allow pkg="org.jmol"/>
+ <allow pkg="javajs.awt" class="jalview.appletgui.AppletJmolBinding"/>
+ </subpackage>
+
+ <subpackage name="bin">
+ <allow pkg="groovy"/>
+ <allow pkg="org.apache.log4j" class="jalview.bin.Cache"/>
+ <allow pkg="javax.swing" class="jalview.bin.Jalview"/>
+ <allow pkg="netscape.javascript" class="jalview.bin.JalviewLite"/>
+ </subpackage>
+
+ <subpackage name="datamodel">
+ <disallow pkg="jalview.gui"/>
+ <allow pkg="fr.orsay.lri.varna"/>
+ <subpackage name="xdb">
+ <subpackage name="embl">
+ <allow pkg="org.exolab.castor"/>
+ </subpackage>
+ </subpackage>
+ </subpackage>
+
+ <subpackage name="fts">
+ <allow pkg="javax.swing"/>
+ <allow pkg="javax.ws"/>
+ <allow pkg="org.json"/>
+ <allow pkg="com.sun.jersey"/>
+ </subpackage>
+
+ <subpackage name="gui">
+ <allow pkg="javax.swing"/>
+ <allow pkg="javax.help"/>
+ <allow pkg="javax.imageio"/>
+ <allow pkg="ext.edu.ucsf"/>
+ <allow pkg="net.miginfocom"/>
+ <allow pkg="org.jibble"/>
+ <allow pkg="org.jmol"/>
+ <allow pkg="org.openscience"/>
+ <allow pkg="org.exolab.castor" class="jalview.gui.Jalview2XML"/>
+ <allow pkg="org.robsite" class="jalview.gui.BlogReader"/>
+ <allow pkg="org.apache.log4j" class="jalview.gui.Console"/>
+ <allow pkg="org.apache.log4j" class="jalview.gui.JalviewAppender"/>
+ <allow pkg="org.biodas" class="jalview.gui.DasSourceBrowser"/>
+ <allow pkg="compbio.metadata" class="jalview.gui.WsJobParameters"/>
+ <allow pkg="fr.orsay.lri.varna" class="jalview.gui.AppVarna"/>
+ <allow pkg="fr.orsay.lri.varna" class="jalview.gui.AppVarnaBinding"/>
+ <allow pkg="uk.ac.vamsas" class="jalview.gui.VamsasApplication"/>
+ </subpackage>
+
+ <subpackage name="jbgui">
+ <allow pkg="javax.swing"/>
+ <allow pkg="net.miginfocom"/>
+ </subpackage>
+
+ <subpackage name="httpserver">
+ <allow pkg="javax.servlet"/>
+ <allow pkg="org.eclipse.jetty"/>
+ </subpackage>
+
+ <subpackage name="io">
+ <allow pkg="javax.swing"/>
+ <allow pkg="org.jfree"/>
+ <allow pkg="org.json"/>
+ <allow pkg="org.jsoup"/>
+ <allow pkg="uk.ac.ebi"/>
+ <allow pkg="uk.ac.vamsas"/>
+ <allow pkg="fr.orsay.lri.varna"/>
+ <allow pkg="MCview"/>
+ </subpackage>
+
+ <subpackage name="javascript">
+ <allow pkg="netscape.javascript"/>
+ </subpackage>
+
+ <subpackage name="rest">
+ <allow pkg="javax.servlet"/>
+ </subpackage>
+
+ <subpackage name="structure">
+ <allow pkg="MCview"/>
+ </subpackage>
+
+ <subpackage name="util">
+ <allow pkg="javax.swing"/>
+ <allow pkg="javax.imageio"/>
+ <allow pkg="org.jfree"/>
+ <allow pkg="org.jibble"/>
+ </subpackage>
+
+ <subpackage name="ws">
+ <allow pkg="javax.swing"/>
+ <allow pkg="javax.xml"/>
+ <allow pkg="ext.vamsas"/>
+ <allow pkg="compbio"/>
+ <allow pkg="MCview"/>
+ <allow pkg="org.apache.http"/>
+ <allow pkg="org.apache.james"/>
+ <allow pkg="org.apache.axis"/>
+ <allow pkg="org.biodas.jdas"/>
+ <allow pkg="org.exolab.castor"/>
+ <allow pkg="uk.ac.ebi"/>
+ <allow pkg="vamsas.objects"/>
+ </subpackage>
+
+ </import-control>
\ No newline at end of file
public class getJavaVersion
{
-/**
- * Takes a set of Jars and/or class files as arguments. Reports the java version for the classes
- */
+ /**
+ * Takes a set of Jars and/or class files as arguments. Reports the java
+ * version for the classes
+ */
public static void main(String[] args) throws IOException
{
- Hashtable observed=new Hashtable();
+ Hashtable observed = new Hashtable();
for (int i = 0; i < args.length; i++)
- {
- checkClassVersion(args[i], observed);
- }
+ {
+ checkClassVersion(args[i], observed);
+ }
printVersions(observed, System.out);
}
- public static void printVersions(Hashtable observed, java.io.PrintStream outs)
+
+ public static void printVersions(Hashtable observed,
+ java.io.PrintStream outs)
{
- if (observed.size()>0)
+ if (observed.size() > 0)
{
- int space=0;
- String key=null;
- for (Enumeration keys = observed.keys(); keys.hasMoreElements(); ) {
+ int space = 0;
+ String key = null;
+ for (Enumeration keys = observed.keys(); keys.hasMoreElements();)
+ {
key = (String) keys.nextElement();
- if (space++>0)
+ if (space++ > 0)
{
outs.print(" ");
}
String version = checkClassVersion(filename);
if (version == null)
{
-// System.err.println("Reading "+filename+" as jar:");
+ // System.err.println("Reading "+filename+" as jar:");
try
{
JarInputStream jis = new JarInputStream(new FileInputStream(
filename));
JarEntry entry;
- Hashtable perjar=new Hashtable();
+ Hashtable perjar = new Hashtable();
while ((entry = jis.getNextJarEntry()) != null)
{
if (entry != null)
}
}
}
- System.err.println("Jar : "+filename);
- printVersions(perjar,System.err);
+ System.err.println("Jar : " + filename);
+ printVersions(perjar, System.err);
} catch (Exception e)
{
{
if (version != null)
{
-// System.err.println("Version is '"+version+"'");
+ // System.err.println("Version is '"+version+"'");
int[] vrs = (int[]) observed.get(version);
if (vrs == null)
{
- vrs = new int[]
- { 0 };
+ vrs = new int[] { 0 };
}
vrs[0]++;
observed.put(version, vrs);
versions.put("52.0", "1.8");
}
- String version = (String) versions.get(major + "."
- + minor);
+ String version = (String) versions.get(major + "." + minor);
if (version == null)
{
// get nearest known version
version = (String) versions.get(major + ".0");
}
-// System.err.println("Version "+version);
+ // System.err.println("Version "+version);
if (version == null)
{
versions.put(major + "." + minor, "Class v" + major + ".0");
}
int minor = in.readUnsignedShort();
int major = in.readUnsignedShort();
-// System.err.println("Version "+major+"."+minor);
+ // System.err.println("Version "+major+"."+minor);
return parseVersions(minor, major);
}
public class help2Website
{
- public static void main(String [] args)
- {
- String line = "";
- try{
- Hashtable targets = new Hashtable();
+ public static void main(String[] args)
+ {
+ String line = "";
+ try
+ {
+ Hashtable targets = new Hashtable();
- File toc = new File("helpTOC.xml");
- File jhm = new File("help.jhm");
+ File toc = new File("helpTOC.xml");
+ File jhm = new File("help.jhm");
- BufferedReader in = new BufferedReader(new FileReader(jhm));
+ BufferedReader in = new BufferedReader(new FileReader(jhm));
- PrintWriter out = new PrintWriter(new FileWriter("helpTOC.html"));
- out.println("<html><head><title>Jalview - Help </title></head>\n"
- +"<body bgcolor=#F1F1F1>\n"
- +"<p><center><strong>Contents</strong></center></p>\n");
+ PrintWriter out = new PrintWriter(new FileWriter("helpTOC.html"));
+ out.println("<html><head><title>Jalview - Help </title></head>\n"
+ + "<body bgcolor=#F1F1F1>\n"
+ + "<p><center><strong>Contents</strong></center></p>\n");
+ StringTokenizer st;
+ StringBuffer indent = new StringBuffer();
+ String target, url, text;
+ while ((line = in.readLine()) != null)
+ {
+ if (line.indexOf("target") == -1)
+ continue;
- StringTokenizer st;
- StringBuffer indent = new StringBuffer();
- String target, url, text;
- while( (line = in.readLine()) != null)
- {
- if(line.indexOf("target")==-1)
- continue;
+ st = new StringTokenizer(line, "\"");
+ st.nextToken(); // <mapID target="
+ target = st.nextToken();
+ st.nextToken(); // " url="
- st = new StringTokenizer(line, "\"");
- st.nextToken(); //<mapID target="
+ url = st.nextToken();
+ targets.put(target, url);
+ }
- target = st.nextToken();
- st.nextToken(); //" url="
+ in = new BufferedReader(new FileReader(toc));
+ while ((line = in.readLine()) != null)
+ {
+ if (line.indexOf("</tocitem>") != -1)
+ indent.setLength(indent.length() - 18);
- url = st.nextToken();
- targets.put(target, url);
- }
+ if (line.indexOf("<tocitem") == -1)
+ continue;
- in = new BufferedReader(new FileReader(toc));
- while( (line = in.readLine()) != null)
- {
- if(line.indexOf("</tocitem>")!=-1)
- indent.setLength(indent.length()-18);
+ st = new StringTokenizer(line, "\"");
+ st.nextToken();
- if(line.indexOf("<tocitem")==-1)
- continue;
+ text = st.nextToken();
+ st.nextToken();
- st = new StringTokenizer(line, "\"");
- st.nextToken();
+ target = st.nextToken();
- text = st.nextToken();
- st.nextToken();
+ if (targets.get(target) != null)
+ {
+ out.println("<br>" + indent + "<a href=\"" + targets.get(target)
+ + "\" target=bodyframe>" + text + "</a>");
+ }
+ else
+ out.println("<br>" + indent + text);
- target = st.nextToken();
+ if (line.indexOf("/>") == -1)
+ indent.append(" ");
- if(targets.get(target)!=null)
- {
- out.println("<br>"+indent+"<a href=\""
- + targets.get(target)
- +"\" target=bodyframe>"
- +text
- +"</a>");
- }
- else
- out.println("<br>"+indent+text);
+ }
+ // Add Googletracker.
+ out.close();
- if(line.indexOf("/>")==-1)
- indent.append(" ");
+ }
- }
- // Add Googletracker.
+ catch (Exception ex)
+ {
+ ex.printStackTrace();
- out.close();
-
- }
-
- catch(Exception ex)
- {
-
- ex.printStackTrace();
-
- System.out.println("\n"+line+"\n");
-
- System.out.println("Usage: move to Help directory. help2Website will read"
- +"\nhelpTOC.xml and help.jhm producing output helpTOC.html");
- }
- }
+ System.out.println("\n" + line + "\n");
+ System.out
+ .println("Usage: move to Help directory. help2Website will read"
+ + "\nhelpTOC.xml and help.jhm producing output helpTOC.html");
+ }
+ }
}
var logger = project.getBuildListeners( ).firstElement( );
logger.setMessageOutputLevel( 1 );
</script>
- <echo message="Missing message labels compared to Messages.properties"/>
- <foreach target="compareProperties" param="file2">
+ <foreach target="compareBundles" param="file2">
<path>
<fileset dir="${basedir}/resources/lang">
<exclude name="Messages.properties" />
</foreach>
</target>
+<target name="compareBundles" description="compare a properties file with Messages.properties and vice versa">
+ <echo message=" "/>
+ <echo message="Missing message labels in ${file2} compared to Messages.properties"/>
+ <antcall target="compareProperties">
+ <param name="file1" value="resources/lang/Messages.properties"/>
+ <param name="file2" value="${file2}" />
+ </antcall>
+ <echo message=" "/>
+ <echo message="Missing message labels in Messages.properties compare to ${file2}"/>
+ <antcall target="compareProperties">
+ <param name="file2" value="resources/lang/Messages.properties"/>
+ <param name="file1" value="${file2}" />
+ </antcall>
+</target>
+
<target name="compareProperties" description="reports missing entries in one message bundle">
- <loadproperties srcFile="resources/lang/Messages.properties" prefix="prefixfile1"/>
+ <loadproperties srcFile="${file1}" prefix="prefixfile1"/>
<loadproperties srcFile="${file2}" prefix="prefixfile2"/>
<propertyselector property="file1.list" delimiter="," match="prefixfile1\.(.+)" select="\1"/>
<propertyselector property="file2.list" delimiter="," match="prefixfile2\.(.+)" select="\1"/>
- <echo message=" "/>
- <echo message="*** ${file2}:" />
<for list="${file1.list}" param="file1.property">
<sequential>
<if>