httpclient-4.0.3.jar
httpcore-4.0.1.jar
httpmime-4.0.3.jar
-intervalstore-v1.0.jar
+intervalstore-v1.1.jar
jabaws-min-client-2.2.0.jar
java-json.jar
jaxrpc.jar
--- /dev/null
+<?xml version="1.0"?>
+<!--
+ * just a crude zip up of non-Jalview classes for development purposes -BH 2018
+ *
+ * external JAR class treatment for JavaScript: see src2/README_SWINGJS.txt
+ *
+ -->
+
+<project name="jalviewX" default="zipall" basedir="."
+ xmlns:if="ant:if"
+ xmlns:unless="ant:unless">
+
+ <!-- inputs directories -->
+ <property name="resource.dir" value="resources" />
+ <property name="swingjs.dir" value="swingjs"/>
+ <!-- output directories -->
+ <property name="site.dir" value="site"/>
+ <property name="j2s.dir" value="${site.dir}/swingjs/j2s"/>
+ <property name="libjs.dir" value="libjs"/>
+
+ <target name="zipall" depends="zipvarna,zipmig,zipintervalstore">
+
+
+ </target>
+
+ <target name="zipvarna">
+ <!-- VARNA -->
+ <property name="varna.zip" value="${libjs.dir}/VARNA-site.zip" />
+ <echo> Zipping up ${varna.zip} </echo>
+ <zip destfile="${varna.zip}" basedir="${site.dir}" includes="fr_*.html,swingjs/j2s/fr/**" />
+ </target>
+
+ <target name="zipmig">
+ <!-- net.miginfo.com MiGLayout -->
+ <property name="mig.zip" value="${libjs.dir}/MiGLayout-site.zip" />
+ <echo> Zipping up ${mig.zip} </echo>
+ <zip destfile="${mig.zip}" basedir="${site.dir}" includes="swingjs/j2s/net/miginfocom/**" />
+ </target>
+
+ <target name="zipintervalstore">
+ <!-- intervalstore.impl NCList implementation -->
+ <property name="intervalstore.zip" value="${libjs.dir}/intervalstore-site.zip" />
+ <echo> Zipping up ${intervalstore.zip} </echo>
+ <zip destfile="${intervalstore.zip}" basedir="${site.dir}" includes="swingjs/j2s/intervalstore/**" />
+ </target>
+
+ <!-- already in SwingJS
+ <target name="zipjson" already in SwingJS>
+ <property name="json.zip" value="${libjs.dir}/json-site.zip" />
+ <echo> Zipping up ${json.zip} </echo>
+ <zip destfile="${json.zip}" basedir="${site.dir}" includes="swingjs/j2s/org/json/**" />
+ </target>
+ -->
+
+ <!-- log4j minimal implementation is already in jalview/javascript
+ and is mapped from org.apache.log4j by the following .j2s line:
+
+ j2s.class.replacements=org.apache.log4j.->jalview.javascript.log4j.
+
+ <target name="ziplog4j">
+ <!- org.apache.log4j ->
+ <property name="log4j.zip" value="${libjs.dir}/log4j-site.zip" />
+ <echo> Zipping up ${log4j.zip} </echo>
+ <zip destfile="${log4j.zip}" basedir="${site.dir}" includes="swingjs/j2s/org/apache/log4j/**" />
+ </target>
+ -->
+</project>
import groovy.transform.ExternalizeMethods
import groovy.util.XmlParser
import groovy.xml.XmlUtil
+
import com.vladsch.flexmark.util.ast.Node
import com.vladsch.flexmark.html.HtmlRenderer
import com.vladsch.flexmark.parser.Parser
}
-
// in ext the values are cast to Object. Ensure string values are cast as String (and not GStringImpl) for later use
def string(Object o) {
return o == null ? "" : o.toString()
}
+
def overrideProperties(String propsFileName, boolean output = false) {
if (propsFileName == null) {
return
// datestamp
buildDate = new Date().format("yyyyMMdd")
-
// essentials
bareSourceDir = string(source_dir)
sourceDir = string("${jalviewDir}/${bareSourceDir}")
//cloverTestClassesDir = cloverClassesDir
cloverDb = string("${cloverBuildDir}/clover.db")
+
testSourceDir = useClover ? cloverTestInstrDir : testDir
testClassesDir = useClover ? cloverTestClassesDir : "${jalviewDir}/${test_output_dir}"
helpBuildDir = string("${resourceBuildDir}/help_build")
docBuildDir = string("${resourceBuildDir}/doc_build")
+
if (buildProperties == null) {
buildProperties = string("${resourcesBuildDir}/${build_properties_file}")
}
srcDirs = [ resourcesBuildDir, docBuildDir, helpBuildDir ]
}
+
compileClasspath = files(sourceSets.main.java.outputDir)
compileClasspath += fileTree(dir: "${jalviewDir}/${libDir}", include: ["*.jar"])
def htmlFilePath = mdFile.getPath().replaceAll(/\..*?$/, ".html")
htmlFiles.add(file(htmlFilePath))
}
+
outputs.files(htmlFiles)
}
outputs.file(outputFile)
}
-
task buildIndices(type: JavaExec) {
dependsOn copyHelp
classpath = sourceSets.main.compileClasspath
dependsOn createBuildProperties
}
+
task prepare {
dependsOn buildResources
dependsOn copyDocs
compileJava.dependsOn prepare
run.dependsOn compileJava
//run.dependsOn prepare
-
-
//testReportDirName = "test-reports" // note that test workingDir will be $jalviewDir
test {
dependsOn prepare
}
+
+
task compileLinkCheck(type: JavaCompile) {
options.fork = true
classpath = files("${jalviewDir}/${utils_dir}")
outputs.file(helpLinksCheckerOutFile)
}
-
// import the pubhtmlhelp target
ant.properties.basedir = "${jalviewDir}"
ant.properties.helpBuildDir = "${helpBuildDir}/${help_dir}"
archiveFileName = rootProject.name+".jar"
duplicatesStrategy "EXCLUDE"
-
exclude "cache*/**"
exclude "*.jar"
exclude "*.jar.*"
dependsOn clean
}
-
shadowJar {
group = "distribution"
description = "Create a single jar file with all dependency libraries merged. Can be run with java -jar"
attributes "Implementation-Version": JALVIEW_VERSION,
"Application-Name": install4jApplicationName
}
-
duplicatesStrategy "INCLUDE"
-
mainClassName = shadow_jar_main_class
mergeServiceFiles()
classifier = "all-"+JALVIEW_VERSION+"-j"+JAVA_VERSION
}
}
+
// write install4j file
install4jConfFile.text = XmlUtil.serialize(install4jConfigXml)
}
'WINDOWS_ICONS_FILE': install4jWindowsIconsFile,
'PNG_ICON_FILE': install4jPngIconFile,
'BACKGROUND': install4jBackground,
-
]
//println("INSTALL4J VARIABLES:")
dependsOn createBuildProperties
dependsOn convertMdFiles
-
def VERSION_UNDERSCORES = JALVIEW_VERSION.replaceAll("\\.", "_")
def outputFileName = "${project.name}_${VERSION_UNDERSCORES}.tar.gz"
archiveFileName = outputFileName
// exclude(EXCLUDE_FILES)
// exclude(PROCESS_FILES)
// }
-
from(file(buildProperties).getParent()) {
include(file(buildProperties).getName())
rename(file(buildProperties).getName(), "build_properties")
line.replaceAll("^INSTALLATION=.*\$","INSTALLATION=Source Release"+" git-commit\\\\:"+gitHash+" ["+gitBranch+"]")
})
}
-
}
property(jalviewjs_j2s_alt_file_property_config, jalviewjs_j2s_alt_file_property)
}
}
-
-
task jalviewjsSetEclipseWorkspace {
def propKey = "jalviewjs_eclipse_workspace"
def propVal = null
preserve {
include "**"
}
-
// should this be exclude really ?
duplicatesStrategy "INCLUDE"
-
outputs.files outputFiles
inputs.files inputFiles
}
--- /dev/null
+# public interface JalviewJSApi
+
+## full list of available methods (from JalviewLiteJsApi):
+
+ public boolean addPdbFile(AlignFrame alFrame, String sequenceId, String pdbEntryString, String pdbFile);
+ public String getAlignment(String format);
+ public String getAlignment(String format, String suffix);
+ public String getAlignmentFrom(AlignFrame alf, String format);
+ public String getAlignmentFrom(AlignFrame alf, String format, String suffix);
+ public String getAlignmentOrder();
+ public String getAlignmentOrderFrom(AlignFrame alf);
+ public String getAlignmentOrderFrom(AlignFrame alf, String sep);
+ public String getAnnotation();
+ public String getAnnotationFrom(AlignFrame alf);
+ public Object getAppletParameter(String name, boolean asString);
+ public URL getCodeBase();
+ public URL getDocumentBase();
+ public String getFeatureGroups();
+ public String getFeatureGroupsOfState(boolean visible);
+ public String getFeatureGroupsOfStateOn(AlignFrame alf, boolean visible);
+ public String getFeatureGroupsOn(AlignFrame alf);
+ public String getFeatures(String format);
+ public String getFeaturesFrom(AlignFrame alf, String format);
+ public Object getFrameForSource(VamsasSource source);
+ public String getParameter(String name);
+ public String getSelectedSequences();
+ public String getSelectedSequences(String sep);
+ public String getSelectedSequencesAsAlignment(String format, String suffix);
+ public String getSelectedSequencesAsAlignmentFrom(AlignFrame alf, String format, String suffix);
+ public String getSelectedSequencesFrom(AlignFrame alf);
+ public String getSelectedSequencesFrom(AlignFrame alf, String sep);
+ public String getSeparator();
+ public AlignViewportI getViewport();
+ public void highlight(String sequenceId, String position, String alignedPosition);
+ public void highlightIn(AlignFrame alf, String sequenceId, String position, String alignedPosition);
+ public AlignFrame loadAlignment(String text, String title);
+ public void loadAnnotation(String annotation);
+ public void loadAnnotationFrom(AlignFrame alf, String annotation);
+ public void loadFeatures(String features, boolean autoenabledisplay);
+ public boolean loadFeaturesFrom(AlignFrame alf, String features, boolean autoenabledisplay);
+ public boolean loadScoreFile(String sScoreFile) throws IOException;
+ public void newFeatureSettings();
+ public void newStructureView(PDBEntry pdb, SequenceI[] seqs, String[] chains, DataSourceType protocol);
+ public Object openPcaPanel(AlignFrame af, String modelName);
+ public Object openTreePanel(AlignFrame af, String treeType, String modelName);
+ public String orderAlignmentBy(AlignFrame alf, String order, String undoName, String sep);
+ public String orderBy(String order, String undoName);
+ public String orderBy(String order, String undoName, String sep);
+ public Object parseArguments(String[] args);
+ public boolean parseFeaturesFile(String param, DataSourceType protocol);
+ public void removeSelectionListener(AlignFrame af, String listener);
+ public void scrollViewToColumnIn(AlignFrame alf, String leftHandColumn);
+ public void scrollViewToIn(AlignFrame alf, String topRow, String leftHandColumn);
+ public void scrollViewToRowIn(AlignFrame alf, String topRow);
+ public void select(String sequenceIds, String columns);
+ public void select(String sequenceIds, String columns, String sep);
+ public void selectIn(AlignFrame alf, String sequenceIds, String columns);
+ public void selectIn(AlignFrame alf, String sequenceIds, String columns, String sep);
+ public void setFeatureGroupState(String groups, boolean state);
+ public void setFeatureGroupState(String[] groups, boolean state);
+ public void setFeatureGroupStateOn(AlignFrame alf, String groups, boolean state);
+ public void setSelectionListener(AlignFrame af, String listener);
+ public void setSelectionListener(String listener);
+ public void setSeparator(String separator);
+ public void showOverview();
+ public void updateForAnnotations();
+
+## addition available methods (from JalviewLite):
+
+ public static String getBuildDate()
+ public static String getInstallation()
+ public static String getVersion()
+
+
+
+## proposed alias list:
+
+- remove overloaded methods
+- indicate null options
+- use standard arrays; no need for special separators
+- possibly return more actual objects, not just strings
+- moves AlignFrame to last parameter, as it is likely to be unnecessary
+
+public boolean addPdbFile(String sequenceId, String pdbId, String pdbFile, AlignFrame alFrame);
+public String getAlignment(String format, boolean addSuffix, AlignFrame alf);
+public String[] getAlignmentOrder(AlignFrame alf);
+public String getAnnotation(AlignFrame alf);
+public URL getCodeBase();
+public URL getDocumentBase();
+public String[] getFeatureGroups(AlignFrame alf);
+public String[] getFeatureGroupsOfState(boolean visible, AlignFrame alf);
+public String getFeatures(String format, AlignFrame alf);
+public String getParameter(String name);
+public Object getParameterAsObject(String name);
+public SequenceI[] getSelectedSequences(AlignFrame alf);
+public AlignFrame newView();
+public AlignFrame newView(String name);
+public AlignFrame newViewFrom(AlignFrame alf);
+public AlignFrame newViewFrom(AlignFrame alf, String name);
+public String getSelectedSequencesAsAlignment(String format, boolean addSuffix, AlignFrame alf);
+public void highlight(String sequenceId, String position, String alignedPosition, AlignFrame alf);
+public AlignFrame loadAlignment(String data, String title, int width, int height);
+public void loadAnnotation(String annotation, AlignFrame alf);
+public boolean loadFeatures(String features, boolean autoenabledisplay, AlignFrame alf);
+public boolean loadScoreFile(String sScoreFile, AlignFrame alf);
+public Object openPcaPanel(String modelName, AlignFrame alf);
+public Object openTreePanel(String treeType, String modelName, AlignFrame alf);
+public boolean orderAlignment(String[] ids, String undoName, AlignFrame alf);
+public Object parseArguments(String[] args);
+public void removeSelectionListener(String listener, AlignFrame af);
+public void scrollViewTo(int topRow, int leftHandColumn, AlignFrame alf);
+public void select(String[] sequenceIds, String[] columns, AlignFrame alf);
+public void setFeatureGroupState(String[] groups, boolean state, AlignFrame alf);
+public void setSelectionListener(String listener, AlignFrame alf);
+public void showOverview();
+public void showStructure(String pdbID, String fileType, AlignFrame alf);
+
+
+# unknown methods/shouldn't be in interface?
+
+ public Object getFrameForSource(VamsasSource source);
+ public void setSeparator(String separator);
+
\ No newline at end of file
--- /dev/null
+## JalviewJS startup parameters
+
+TODO -- go through these
+
+# parameters -- from jalview.bin.AppletParams
+
+ private final static String[] params = {
+ "alignpdbfiles",
+ "ANNOTATIONCOLOUR_MAX", "ANNOTATIONCOLOUR_MIN",
+ "annotations",
+ "APPLICATION_URL", "automaticScrolling", "centrecolumnlabels",
+ "debug", "defaultColour", "defaultColourNuc", "defaultColourProt",
+ "embedded", "enableSplitFrame", "externalstructureviewer", "features",
+ "file", "file2", "format", "heightScale", "hidefeaturegroups",
+ "jalviewhelpurl", "jnetfile", "jpredfile", "label", "linkLabel_",
+ "linkLabel_1", "linkURL_", "nojmol", "normaliseLogo",
+ "normaliseSequenceLogo", "oninit", "PDBFILE", "PDBSEQ",
+ "relaxedidmatch", "resolvetocodebase", "RGB", "scaleProteinAsCdna",
+ "scoreFile", "separator", "sequence", "showAnnotation", "showbutton",
+ "showConsensus", "showConsensusHistogram", "showConservation",
+ "showfeaturegroups", "showFeatureSettings", "showFullId",
+ "showGroupConsensus", "showGroupConservation", "showOccupancy",
+ "showQuality", "showSequenceLogo", "showTreeBootstraps",
+ "showTreeDistances", "showUnconserved", "showUnlinkedTreeNodes",
+ "sortBy", "sortByTree", "tree", "treeFile", "upperCase",
+ "userDefinedColour", "widthScale", "windowHeight", "windowWidth",
+ "wrap", };
+
+
+
+
+# arguments -- from jalview.bin.ArgsParser
+
+ public static final String NOCALCULATION = "nocalculation";
+
+ public static final String NOMENUBAR = "nomenubar";
+
+ public static final String NOSTATUS = "nostatus";
+
+ public static final String SHOWOVERVIEW = "showoverview";
+
+ //
+ public static final String ANNOTATIONS = "annotations";
+
+ public static final String COLOUR = "colour";
+
+ public static final String FEATURES = "features";
+
+ public static final String GROOVY = "groovy";
+
+ public static final String GROUPS = "groups";
+
+ public static final String HEADLESS = "headless";
+
+ public static final String JABAWS = "jabaws";
+
+ public static final String NOANNOTATION = "no-annotation";
+
+ public static final String NOANNOTATION2 = "noannotation"; // BH 2019.05.07
+
+ public static final String NODISPLAY = "nodisplay";
+
+ public static final String NOGUI = "nogui";
+
+ public static final String NONEWS = "nonews";
+
+ public static final String NOQUESTIONNAIRE = "noquestionnaire";
+
+ public static final String NOSORTBYTREE = "nosortbytree";
+
+ public static final String NOUSAGESTATS = "nousagestats";
+
+ public static final String OPEN = "open";
+
+ public static final String OPEN2 = "open2"; // BH added -- for applet
+ // compatibility; not fully
+ // implemented
+
+ public static final String PROPS = "props";
+
+ public static final String QUESTIONNAIRE = "questionnaire";
+
+ public static final String SETPROP = "setprop";
+
+ public static final String SORTBYTREE = "sortbytree";
+
+ public static final String TREE = "tree";
+
+ public static final String VDOC = "vdoc";
+
+ public static final String VSESS = "vsess";
+
--- /dev/null
+# How to add a web service backend to Jalview's web services UI
+
+### Document Status: *Work in progress !*
+
+There are two phases to services.
+
+ *Discovery* threads are started by jalview.gui.Desktop (or other UI components or the CLI if they are headless services accessible via commandline). Your service discovery thread registers discovered instances so they can be accessed by the user.
+
+ *Access* most services are accessed by selecting a menu item, option, or specifying a nickname for the service instance as a Jalview command line parameter. Different access patterns are used for the various services: seqeunce data source, sequence feature annotation source, multiple sequence alignment, multiple alignment annotation source, etc. There should be no need for your code to create UI components (if there is then Jalview's UI needs to be refactored to avoid this).
+
+## Discovery
+
+*jalview.gui.Desktop*
+- start a discovery thread to discover services provided by your framework. The discoverer should generate a list of objects that either implement WsMenuEntryProviderI or provide another mechanism to add themselves to Jalview's menus (via jalview.gui.AlignFrame.BuildWebServiceMenu() below)
+
+*jalview.gui.AlignFrame*
+- BuildWebServiceMenu()
+ This method creates a runnable that's called when the available set of web services changes (e.g. when a discovery thread completes). Add code to the Runnable's run method to create Menu Items in the web services menu via jalview.ws.WSMenuEntryProviderI instances generated by your discoverer.
+
+
+## Types of service
+
+### Services that create new alignments or windows, optionally with a progress log
+
+The pattern for these services requires a Client that initates a thread which creates, and montors one or more jobs based on input data.
+
+jalview.ws.MsaWSClient -- currently does double duty with Jaba services for alignment analysis and instantiation of alignment services.
+
+jalview.ws.gui.MSAThread -- UI model and controller for a running MSA service. Instantiated with an instance of jalview.ws.MultipleSequenceAlignmentI provided by the service endpoint factory.
+
+
+## Other classes of interest
+
+### jalview.ws.api
+
+Interfaces and base classes to be implemented and used by a service endpoint.
+
+ jalview.ws.api.CancellableI.java - implement if the service is cancellable
+ jalview.ws.api.JalviewWebServiceI.java - base service interface
+ jalview.ws.api.JobId.java - a timestamped job id that can be saved in a Jalview project
+
+#### submission interfaces
+jalview.ws.api.MsaI.java
+jalview.ws.api.MsaWithGuideTreeI.java
+
+
+#### result interfaces
+jalview.ws.api.MsaResultI.java
+jalview.ws.api.TreeResultI.java
+jalview.ws.api.DistanceMatrixResultI.java
+
+
+#### minimal composed interfaces for a complete functional analysis
+
+jalview.ws.api.MultipleSequenceAlignmentI.java
+
+
+#### base class for a service endpoint instance - to be materialised by service discoverers
+
+jalview.ws.api.UIinfo.java - basic information
+jalview.ws.api.ServiceWithParameters.java
+
+jalview.ws.api.JalviewServiceEndpointProviderI - implemented by service endpoint factories (typically extended from UIinfo or ServiceWithParameters).
+
+
+## Analysis services
+
+These have not yet been refactored. Feel free to look at how jalview.ws.jws2.AACons and Disorder clients operate and adapt the pattern for your own services. The Groovy example in the help [[help/html/groovy/featuresCounter.html]] for creating custom annotation tracks uses the same basic 'alignment analysis worker' mechanism to provide dynamically executed alignment analysis calculations that result in annotation tracks displayed below the alginment.
-<html>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
+<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta http-equiv="Content-Style-Type" content="text/css" />
- <meta name="generator" content="flexmark" />
+ <title>Building Jalview from Source</title>
<title>Building Jalview from Source</title>
<style type="text/css">code{white-space: pre;}</style>
<style>
</head>
<body>
<ul>
-<li><a href="#tldr">tl;dr</a></li>
-<li><a href="#setting-up">Setting up</a>
<ul>
+<li><a href="#setting-up">Setting up</a>
+<li><a href="#tldr">tl;dr</a></li>
+<li><a href="#java-11-compliant-jdk">Java 11 compliant JDK</a></li>
<li><a href="#java-11-compliant-jdk">Java 11 compliant JDK</a></li>
<li><a href="#gradle-and-git">gradle and git</a></li>
-</ul>
</li>
<li><a href="#downloading-the-jalview-source-tree">Downloading the Jalview source tree</a>
-<ul>
+<li><a href="#whats-in-the-source-tree">What's in the source tree?</a></li>
<li><a href="#whats-in-the-source-tree">What's in the source tree?</a></li>
</ul>
-</li>
-<li><a href="#building-jalview">Building Jalview</a>
-<ul>
<li><a href="#minimal-jalview-build">Minimal Jalview Build</a></li>
<li><a href="#jalview-in-a-jar-file">Jalview in a Jar File</a></li>
<li><a href="#distributed-jar-files">Distributed Jar Files</a></li>
<li><a href="#building-the-getdown-launcher">Building the <code>getdown</code> launcher</a></li>
<li><a href="#running-tests">Running tests</a></li>
<li><a href="#installer-packaging-with-install4j">Installer packaging with <em>install4j</em></a></li>
-</ul>
-</li>
+<li><a href="#building-the-getdown-launcher">Building the <code>getdown</code> launcher</a></li>
<li><a href="#gradle-properties">Gradle properties</a></li>
<li><a href="#enabling-code-coverage-with-openclover">Enabling Code Coverage with OpenClover</a></li>
-<li><a href="#setting-up-in-eclipse-ide">Setting up in Eclipse IDE</a>
-<ul>
+</ul>
<li><a href="#installing-eclipse-ide">Installing Eclipse IDE</a></li>
<li><a href="#importing-jalview-as-an-eclipse-project">Importing Jalview as an Eclipse project</a></li>
+<li><a href="#enabling-code-coverage-with-openclover">Enabling Code Coverage with OpenClover</a></li>
+<li><a href="#setting-up-in-eclipse-ide">Setting up in Eclipse IDE</a>
</ul>
</li>
</ul>
<h1 id="building-jalview-from-source"><a href="#building-jalview-from-source" name="building-jalview-from-source" class="anchor"><span class="octicon octicon-link"></span>Building Jalview from Source</a></h1>
-<h2 id="tldr"><a href="#tldr" name="tldr" class="anchor"><span class="octicon octicon-link"></span>tl;dr</a></h2>
+</head>
+<pre><code># download
+git clone http://source.jalview.org/git/jalview.git
+<ul>
+cd jalview
+<li><a href="#tldr">tl;dr</a></li>
+# run
+<li><a href="#java-11-compliant-jdk">Java 11 compliant JDK</a></li>
+<li><a href="#gradle-and-git">gradle and git</a></li>
+# and/or create launcher
+gradle getdown
+<li><a href="#whats-in-the-source-tree">What's in the source tree?</a></li>
+cd getdown/files
+java -jar getdown-launcher.jar . jalview
+<li><a href="#minimal-jalview-build">Minimal Jalview Build</a></li>
+<li><a href="#jalview-in-a-jar-file">Jalview in a Jar File</a></li>
+<li><a href="#distributed-jar-files">Distributed Jar Files</a></li>
+<li><a href="#single-shadow-jar-file">Single <em>shadow</em> Jar File</a></li>
+<li><a href="#building-the-getdown-launcher">Building the <code>getdown</code> launcher</a></li>
+<li><a href="#running-tests">Running tests</a></li>
+<li><a href="#installer-packaging-with-install4j">Installer packaging with <em>install4j</em></a></li>
+<li>Java 11 compliant JDK</li>
+<li><a href="#gradle-properties">Gradle properties</a></li>
+<li><a href="#enabling-code-coverage-with-openclover">Enabling Code Coverage with OpenClover</a></li>
+</ul>
+<li><a href="#installing-eclipse-ide">Installing Eclipse IDE</a></li>
+<li><a href="#importing-jalview-as-an-eclipse-project">Importing Jalview as an Eclipse project</a></li>
+so are known to work). If you need or wish to use different implementations (particularly
+you might need a bespoke JDK if you are on an exotic architecture) then the general
+</ul>
+bytecode with any JDK Java 11+. The resulting bytecode (in particular the shadow jar)
+should be runnable in any JRE Java 1.8+. Remember that because Jalview and the getdown launcher
+are Java bytecode you can build on one system where you might have gradle, and run
<pre><code># download
git clone http://source.jalview.org/git/jalview.git
# compile
cd jalview
gradle shadowJar
# run
-java -jar build/libs/jalview-all-*-j11.jar
+# compile
# and/or create launcher
gradle getdown
# use launcher
cd getdown/files
-java -jar getdown-launcher.jar . jalview
-</code></pre>
-<h2 id="setting-up"><a href="#setting-up" name="setting-up" class="anchor"><span class="octicon octicon-link"></span>Setting up</a></h2>
+java -jar getdown-launcher.jar . jalview</code></pre>
+<h2 id="setting-up">Setting up</h2>
<blockquote>
-<p>To get set up using <em>only</em> the Eclipse IDE (<a href="https://www.eclipse.org/">https://www.eclipse.org/</a>) then please see the section <a href="#setting-up-in-eclipse-ide">Setting up in Eclipse IDE</a></p>
+<p>To get set up using <em>only</em> the Eclipse IDE (<a href="https://www.eclipse.org/" class="uri">https://www.eclipse.org/</a>) then please see the section <a href="#setting-up-in-eclipse-ide">Setting up in Eclipse IDE</a></p>
</blockquote>
-<p>The method here is described in terms of using a command line. You can easily do this on linux or in a Terminal window in macOS. You can do it in Windows.</p>
+<p>The method here is described in terms of using a command line. You can easily do this on linux or in a Terminal window in macOS. You can do it in Windows.</p>
<ul>
<li>Java 11 compliant JDK</li>
-<li>gradle 5.2 or above <em>(NB gradle 6.6 and above currently produces NullPointerExceptions during the build. This is non-fatal and does not affect the build. Use gradle 6.5.1 to avoid this)</em></li>
+<p>To get set up using <em>only</em> the Eclipse IDE (<a href="https://www.eclipse.org/">https://www.eclipse.org/</a>) then please see the section <a href="#setting-up-in-eclipse-ide">Setting up in Eclipse IDE</a></p>
<li>git</li>
</ul>
<blockquote>
-<p>The versions and installation methods here are just suggestions (which we have tested
-so are known to work). If you need or wish to use different implementations (particularly
-you might need a bespoke JDK if you are on an exotic architecture) then the general
-build instructions should work with any gradle 5+. You should be able to compile the
-bytecode with any JDK Java 11+. The resulting bytecode (in particular the shadow jar)
-should be runnable in any JRE Java 1.8+. Remember that because Jalview and the getdown launcher
-are Java bytecode you can build on one system where you might have gradle, and run
-on another where you don't (JRE 1.8+ required).</p>
+<p>The versions and installation methods here are just suggestions (which we have tested so are known to work). If you need or wish to use different implementations (particularly you might need a bespoke JDK if you are on an exotic architecture) then the general build instructions should work with any gradle 5+. You should be able to compile the bytecode with any JDK Java 11+. The resulting bytecode (in particular the shadow jar) should be runnable in any JRE Java 1.8+. Remember that because Jalview and the getdown launcher are Java bytecode you can build on one system where you might have gradle, and run on another where you don't (JRE 1.8+ required).</p>
</blockquote>
-<h3 id="java-11-compliant-jdk"><a href="#java-11-compliant-jdk" name="java-11-compliant-jdk" class="anchor"><span class="octicon octicon-link"></span>Java 11 compliant JDK</a></h3>
-<h4 id="all-platforms"><a href="#all-platforms" name="all-platforms" class="anchor"><span class="octicon octicon-link"></span>All platforms</a></h4>
-<p>We recommend obtaining an OpenJDK JDK 11 (since 11 is the long term support release) from AdoptOpenJDK: <a href="https://adoptopenjdk.net/?variant=openjdk11&jvmVariant=hotspot">https://adoptopenjdk.net/?variant=openjdk11&jvmVariant=hotspot</a>, either the <em>Installer</em> or <code>.zip</code>/<code>.tar.gz</code> variants whichever you prefer (if you're not sure, choose the <em>Installer</em>).</p>
+<h3 id="java-11-compliant-jdk">Java 11 compliant JDK</h3>
+<h4 id="all-platforms">All platforms</h4>
+<p>We recommend obtaining an OpenJDK JDK 11 (since 11 is the long term support release) from AdoptOpenJDK: <a href="https://adoptopenjdk.net/?variant=openjdk11&jvmVariant=hotspot" class="uri">https://adoptopenjdk.net/?variant=openjdk11&jvmVariant=hotspot</a>, either the <em>Installer</em> or <code>.zip</code>/<code>.tar.gz</code> variants whichever you prefer (if you're not sure, choose the <em>Installer</em>).</p>
<blockquote>
-<h5 id="alternativecli-install-of-adoptopenjdk-11"><a href="#alternativecli-install-of-adoptopenjdk-11" name="alternativecli-install-of-adoptopenjdk-11" class="anchor"><span class="octicon octicon-link"></span>Alternative/CLI install of AdoptOpenJDK 11</a></h5>
-<p>You can also install adoptopenjdk11 using either <code>brew</code> (macOS), <code>choco</code> (Windows)
-(see the section on <code>gradle</code> and <code>git</code> for more informaiton on <code>brew</code> and <code>choco</code>)
-or <code>yum</code> or <code>apt</code> (Linux):</p>
-<h6 id="alternative-for-macos-and-homebrew"><a href="#alternative-for-macos-and-homebrew" name="alternative-for-macos-and-homebrew" class="anchor"><span class="octicon octicon-link"></span>alternative for MacOS and Homebrew</a></h6>
+<h5 id="alternativecli-install-of-adoptopenjdk-11">Alternative/CLI install of AdoptOpenJDK 11</h5>
+<p>You can also install adoptopenjdk11 using either <code>brew</code> (macOS), <code>choco</code> (Windows) (see the section on <code>gradle</code> and <code>git</code> for more informaiton on <code>brew</code> and <code>choco</code>) or <code>yum</code> or <code>apt</code> (Linux):</p>
+<h6 id="alternative-for-macos-and-homebrew">alternative for MacOS and Homebrew</h6>
<pre><code>brew tap adoptopenjdk/openjdk
-brew cask install adoptopenjdk11
-</code></pre>
-<h6 id="alternative-for-windows-and-chocolatey"><a href="#alternative-for-windows-and-chocolatey" name="alternative-for-windows-and-chocolatey" class="anchor"><span class="octicon octicon-link"></span>alternative for Windows and Chocolatey</a></h6>
-<pre><code>choco install adoptopenjdk11
-</code></pre>
-<h6 id="alternative-for-linux-with-yumapt"><a href="#alternative-for-linux-with-yumapt" name="alternative-for-linux-with-yumapt" class="anchor"><span class="octicon octicon-link"></span>alternative for Linux with yum/apt</a></h6>
-<p>see <a href="https://adoptopenjdk.net/installation.html#linux-pkg">https://adoptopenjdk.net/installation.html#linux-pkg</a></p>
+brew cask install adoptopenjdk11</code></pre>
+<h6 id="alternative-for-windows-and-chocolatey">alternative for Windows and Chocolatey</h6>
+<pre><code>choco install adoptopenjdk11</code></pre>
+<h6 id="alternative-for-linux-with-yumapt">alternative for Linux with yum/apt</h6>
+<p>see <a href="https://adoptopenjdk.net/installation.html#linux-pkg" class="uri">https://adoptopenjdk.net/installation.html#linux-pkg</a></p>
</blockquote>
-<h3 id="gradle-and-git"><a href="#gradle-and-git" name="gradle-and-git" class="anchor"><span class="octicon octicon-link"></span>gradle and git</a></h3>
+<h3 id="gradle-and-git">gradle and git</h3>
<p>You should be able to install the latest (or sufficiently recent) versions of gradle and git using your OS package manager.</p>
-<h4 id="macos"><a href="#macos" name="macos" class="anchor"><span class="octicon octicon-link"></span>MacOS</a></h4>
-<p>we recommend using <code>brew</code>, which can be installed following the instructions at <a href="https://brew.sh/">https://brew.sh/</a>.
-After installing <code>brew</code>, open a Terminal window and type in (using an Administrator privileged user):</p>
-<pre><code class="language-bash">brew install gradle git
-</code></pre>
+<h4 id="macos">MacOS</h4>
+<p>we recommend using <code>brew</code>, which can be installed following the instructions at <a href="https://brew.sh/" class="uri">https://brew.sh/</a>. After installing <code>brew</code>, open a Terminal window and type in (using an Administrator privileged user):</p>
+<div class="sourceCode"><pre class="sourceCode bash"><code class="sourceCode bash"><span class="ex">brew</span> install gradle git</code></pre></div>
<p>or if you aready have them installed but need to upgrade the version:</p>
-<pre><code class="language-bash">brew upgrade gradle git
-</code></pre>
-<h4 id="windows"><a href="#windows" name="windows" class="anchor"><span class="octicon octicon-link"></span>Windows</a></h4>
-<p>we suggest using the <strong>Chocolatey</strong> package manager. See install instructions at <a href="https://chocolatey.org/">https://chocolatey.org/</a>, and you will just need</p>
-<pre><code class="language-bash">choco install gradle
-choco install git
-</code></pre>
-<p>Alternatively, you could install a real <code>bash</code> shell and install both <code>gradle</code> and <code>git</code> through <code>apt-get</code>.
-See <a href="https://devblogs.microsoft.com/commandline/bash-on-ubuntu-on-windows-download-now-3/">https://devblogs.microsoft.com/commandline/bash-on-ubuntu-on-windows-download-now-3/</a>
-for how to install the ubuntu bash shell in Windows 10.</p>
-<p>Another alternative would be to install them separately. For <code>gradle</code> follow the instructions at <a href="https://gradle.org/install/">https://gradle.org/install/</a>, and for <code>git</code> here are a couple of suggestions: Git for Windows <a href="https://gitforwindows.org/">https://gitforwindows.org/</a>.
-Getting the individual installs working together on the command line will be trickier
-so we recommend using Chocolatey or bash.</p>
-<h4 id="linux"><a href="#linux" name="linux" class="anchor"><span class="octicon octicon-link"></span>Linux</a></h4>
+<div class="sourceCode"><pre class="sourceCode bash"><code class="sourceCode bash"><span class="ex">brew</span> upgrade gradle git</code></pre></div>
+<h4 id="windows">Windows</h4>
+<p>we suggest using the <strong>Chocolatey</strong> package manager. See install instructions at <a href="https://chocolatey.org/" class="uri">https://chocolatey.org/</a>, and you will just need</p>
+<div class="sourceCode"><pre class="sourceCode bash"><code class="sourceCode bash"><span class="ex">choco</span> install gradle
+<span class="ex">choco</span> install git</code></pre></div>
+<p>Alternatively, you could install a real <code>bash</code> shell and install both <code>gradle</code> and <code>git</code> through <code>apt-get</code>. See <a href="https://devblogs.microsoft.com/commandline/bash-on-ubuntu-on-windows-download-now-3/" class="uri">https://devblogs.microsoft.com/commandline/bash-on-ubuntu-on-windows-download-now-3/</a> for how to install the ubuntu bash shell in Windows 10.</p>
+<p>Another alternative would be to install them separately. For <code>gradle</code> follow the instructions at <a href="https://gradle.org/install/" class="uri">https://gradle.org/install/</a>, and for <code>git</code> here are a couple of suggestions: Git for Windows <a href="https://gitforwindows.org/" class="uri">https://gitforwindows.org/</a>. Getting the individual installs working together on the command line will be trickier so we recommend using Chocolatey or bash.</p>
+<h4 id="linux">Linux</h4>
<p>this will depend on which distribution you're using.</p>
-<h5 id="for-debian-based-distributions-eg-mint-ubuntu-debian"><a href="#for-debian-based-distributions-eg-mint-ubuntu-debian" name="for-debian-based-distributions-eg-mint-ubuntu-debian" class="anchor"><span class="octicon octicon-link"></span>For <em>Debian</em> based distributions (e.g. Mint, Ubuntu, Debian)</a></h5>
+<h5 id="for-debian-based-distributions-e.g.-mint-ubuntu-debian">For <em>Debian</em> based distributions (e.g. Mint, Ubuntu, Debian)</h5>
<p>run</p>
-<pre><code class="language-bash"> sudo apt-get install gradle git
-</code></pre>
-<h5 id="for-rpm-based-distributions-eg-fedora-centos-redhat"><a href="#for-rpm-based-distributions-eg-fedora-centos-redhat" name="for-rpm-based-distributions-eg-fedora-centos-redhat" class="anchor"><span class="octicon octicon-link"></span>for RPM-based distributions (e.g. Fedora, CentOS, RedHat)</a></h5>
+<div class="sourceCode"><pre class="sourceCode bash"><code class="sourceCode bash"> <span class="fu">sudo</span> apt-get install gradle git</code></pre></div>
+<h5 id="for-rpm-based-distributions-e.g.-fedora-centos-redhat">for RPM-based distributions (e.g. Fedora, CentOS, RedHat)</h5>
<p>run</p>
-<pre><code class="language-bash">sudo yum install gradle git
-</code></pre>
+<div class="sourceCode"><pre class="sourceCode bash"><code class="sourceCode bash"><span class="fu">sudo</span> yum install gradle git</code></pre></div>
<p>If you have some other version of linux you'll probably be able to work it out!</p>
-<h2 id="downloading-the-jalview-source-tree"><a href="#downloading-the-jalview-source-tree" name="downloading-the-jalview-source-tree" class="anchor"><span class="octicon octicon-link"></span>Downloading the Jalview source tree</a></h2>
-<p>This can be done with <code>git</code>.
-On the command line, change directory to where you want to download Jalview's build-tree
-top level directory. Then run</p>
-<pre><code class="language-bash">git clone http://source.jalview.org/git/jalview.git
-</code></pre>
-<p>You'll get some progress output and after a minute or two you should have the full
-Jalview build-tree in the folder <code>jalview</code>.</p>
-<h3 id="whats-in-the-source-tree"><a href="#whats-in-the-source-tree" name="whats-in-the-source-tree" class="anchor"><span class="octicon octicon-link"></span>What's in the source tree?</a></h3>
-<p>Jalview is a mature product with its codebase going back many years. As such it doesn't
-have a folder structure that most new gradle projects would have, so you might not
-find everything in the place you might expect. Here's a brief description of what
-you might find in the main folders under the <code>jalview</code> tree.</p>
+<h2 id="downloading-the-jalview-source-tree">Downloading the Jalview source tree</h2>
+<p>This can be done with <code>git</code>. On the command line, change directory to where you want to download Jalview's build-tree top level directory. Then run</p>
+<div class="sourceCode"><pre class="sourceCode bash"><code class="sourceCode bash"><span class="fu">git</span> clone http://source.jalview.org/git/jalview.git</code></pre></div>
+<p>You'll get some progress output and after a minute or two you should have the full Jalview build-tree in the folder <code>jalview</code>.</p>
+<h3 id="whats-in-the-source-tree">What's in the source tree?</h3>
+<p>Jalview is a mature product with its codebase going back many years. As such it doesn't have a folder structure that most new gradle projects would have, so you might not find everything in the place you might expect. Here's a brief description of what you might find in the main folders under the <code>jalview</code> tree.</p>
<p>Within the <code>jalview</code> folder you will find (of possible interest):</p>
<table>
+<colgroup>
+<col width="16%" />
+<col width="83%" />
+</colgroup>
<thead>
-<tr><th>dir/ or file</th><th>contains</th></tr>
+<tr class="header">
+<th>dir/ or file</th>
+<th>contains</th>
+</tr>
</thead>
<tbody>
-<tr><td><code>bin/</code></td><td>used by eclipse for compiled classes -- no need to touch this</td></tr>
-<tr><td><code>build/</code></td><td>the gradle build dir</td></tr>
-<tr><td><code>classes/</code></td><td>contains the compiled Java classes for the Jalview application</td></tr>
-<tr><td><code>dist/</code></td><td>assembled <code>.jar</code> files needed to run Jalview application</td></tr>
-<tr><td><code>examples/</code></td><td>example input files usable by Jalview</td></tr>
-<tr><td><code>getdown/</code></td><td>the libraries used by the Javliew launcher (getdown)</td></tr>
-<tr><td><code>getdown/src/</code></td><td>our modified source for <code>getdown</code></td></tr>
-<tr><td><code>getdown/website/</code></td><td>the assembled "download" folder used by getdown for downloads/upgrades</td></tr>
-<tr><td><code>getdown/files/</code></td><td>the minimal fileset to launch the Jalview launcher, which can then download the rest of the Jalview application</td></tr>
-<tr><td><code>help/</code></td><td>the help documents</td></tr>
-<tr><td><code>j8lib/</code></td><td>libraries needed to run Jalview under Java 1.8</td></tr>
-<tr><td><code>j11lib/</code></td><td>libraries needed to run Jalivew under Java 11</td></tr>
-<tr><td><code>resource/</code></td><td>non-java resources used in the Jalview application</td></tr>
-<tr><td><code>src/</code></td><td>the Jalview application source <code>.java</code> files</td></tr>
-<tr><td><code>test/</code></td><td>Test class source files</td></tr>
-<tr><td><code>utils/</code></td><td>helper applications used in the build process</td></tr>
-<tr><td><code>utils/install4j/</code></td><td>files used by the packaging tool, install4j</td></tr>
-<tr><td><code>build.gradle</code></td><td>the build file used by gradle</td></tr>
-<tr><td><code>gradle.properties</code></td><td>configurable properties for the build process</td></tr>
-<tr><td><code>RELEASE</code></td><td>propertyfile configuring JALVIEW_VERSION (from jalview.version) and the release branch (from jalview.release). An alternative file can be specified via JALVIEW_RELEASE_FILE property</td></tr>
+<tr class="odd">
+<td><code>bin/</code></td>
+<td>used by eclipse for compiled classes -- no need to touch this</td>
+</tr>
+<tr class="even">
+<td><code>build/</code></td>
+<td>the gradle build dir</td>
+</tr>
+<tr class="odd">
+<td><code>classes/</code></td>
+<td>contains the compiled Java classes for the Jalview application</td>
+</tr>
+<tr class="even">
+<td><code>dist/</code></td>
+<td>assembled <code>.jar</code> files needed to run Jalview application</td>
+</tr>
+<tr class="odd">
+<td><code>examples/</code></td>
+<td>example input files usable by Jalview</td>
+</tr>
+<tr class="even">
+<td><code>getdown/</code></td>
+<td>the libraries used by the Javliew launcher (getdown)</td>
+</tr>
+<tr class="odd">
+<td><code>getdown/src/</code></td>
+<td>our modified source for <code>getdown</code></td>
+</tr>
+<tr class="even">
+<td><code>getdown/website/</code></td>
+<td>the assembled "download" folder used by getdown for downloads/upgrades</td>
+</tr>
+<tr class="odd">
+<td><code>getdown/files/</code></td>
+<td>the minimal fileset to launch the Jalview launcher, which can then download the rest of the Jalview application</td>
+</tr>
+<tr class="even">
+<td><code>help/</code></td>
+<td>the help documents</td>
+</tr>
+<tr class="odd">
+<td><code>j8lib/</code></td>
+<td>libraries needed to run Jalview under Java 1.8</td>
+</tr>
+<tr class="even">
+<td><code>j11lib/</code></td>
+<td>libraries needed to run Jalivew under Java 11</td>
+</tr>
+<tr class="odd">
+<td><code>resource/</code></td>
+<td>non-java resources used in the Jalview application</td>
+</tr>
+<tr class="even">
+<td><code>src/</code></td>
+<td>the Jalview application source <code>.java</code> files</td>
+</tr>
+<tr class="odd">
+<td><code>test/</code></td>
+<td>Test class source files</td>
+</tr>
+<tr class="even">
+<td><code>utils/</code></td>
+<td>helper applications used in the build process</td>
+</tr>
+<tr class="odd">
+<td><code>utils/install4j/</code></td>
+<td>files used by the packaging tool, install4j</td>
+</tr>
+<tr class="even">
+<td><code>build.gradle</code></td>
+<td>the build file used by gradle</td>
+</tr>
+<tr class="odd">
+<td><code>gradle.properties</code></td>
+<td>configurable properties for the build process</td>
+</tr>
</tbody>
</table>
<p>Note that you need a Java 11 JDK to compile Jalview whether your target build is Java 1.8 or Java 11.</p>
-<h2 id="building-jalview"><a href="#building-jalview" name="building-jalview" class="anchor"><span class="octicon octicon-link"></span>Building Jalview</a></h2>
-<p>You will need to have the Java 11 <code>javac</code> in your path, or alternatively you can configure
-gradle to know where this is by putting</p>
-<pre><code>org.gradle.java.home=/path_to_jdk_directory
-</code></pre>
+<h2 id="building-jalview">Building Jalview</h2>
+<p>You will need to have the Java 11 <code>javac</code> in your path, or alternatively you can configure gradle to know where this is by putting</p>
+<pre><code>org.gradle.java.home=/path_to_jdk_directory</code></pre>
<p>in the <code>gradle.properties</code> file.</p>
<blockquote>
<p><em>You may want to see some of the other properties you can change at the end of this document.</em></p>
</blockquote>
-<h3 id="minimal-jalview-build"><a href="#minimal-jalview-build" name="minimal-jalview-build" class="anchor"><span class="octicon octicon-link"></span>Minimal Jalview Build</a></h3>
+<h3 id="minimal-jalview-build">Minimal Jalview Build</h3>
<p>To compile the necessary class files, just run</p>
-<pre><code class="language-bash">gradle compileJava
-</code></pre>
-<p>to compile the classes into the <code>classes</code> folder.
-You should now be able to run the Jalview application directly with</p>
-<pre><code class="language-bash">java -cp "classes:resources:help:j11lib/*" jalview.bin.Jalview
-</code></pre>
-<p>You can also run with an automatic large memory setting (which will set the maximum
-memory heap of the Jalview JVM to 90% of your local physical memory) and docked icon setting
-(if possible in your OS) with</p>
-<pre><code class="language-bash">java -cp "classes:resources:help:j11lib/*" jalview.bin.Launcher
-</code></pre>
+<div class="sourceCode"><pre class="sourceCode bash"><code class="sourceCode bash"><span class="ex">gradle</span> compileJava</code></pre></div>
+<p>to compile the classes into the <code>classes</code> folder. You should now be able to run the Jalview application directly with</p>
+<div class="sourceCode"><pre class="sourceCode bash"><code class="sourceCode bash"><span class="ex">java</span> -cp <span class="st">"classes:resources:help:j11lib/*"</span> jalview.bin.Jalview</code></pre></div>
+<p>You can also run with an automatic large memory setting (which will set the maximum memory heap of the Jalview JVM to 90% of your local physical memory) and docked icon setting (if possible in your OS) with</p>
+<div class="sourceCode"><pre class="sourceCode bash"><code class="sourceCode bash"><span class="ex">java</span> -cp <span class="st">"classes:resources:help:j11lib/*"</span> jalview.bin.Launcher</code></pre></div>
<blockquote>
-<p><em>You must use just "<code>j11lib/*</code>" and not "<code>j11lib/*.jar</code>" as this is a special Java
-classpath argument wildcard interpreted by <code>java</code>, <strong>not</strong> a shell expansion wildcard interpreted
-by the shell.</em></p>
+<p><em>You must use just "<code>j11lib/*</code>" and not "<code>j11lib/*.jar</code>" as this is a special Java classpath argument wildcard interpreted by <code>java</code>, <strong>not</strong> a shell expansion wildcard interpreted by the shell.</em></p>
</blockquote>
-<p>Note that <code>jalview.bin.Launcher</code> is a simplified launcher class that re-launches <code>jalview.bin.Jalview</code>
-with the same JRE (<em>not</em> the same JVM instance), classpath and arguments, but with an automatically determined <code>-Xmx...</code>
-memory setting if one hasn't been provided.</p>
-<h3 id="jalview-in-a-jar-file"><a href="#jalview-in-a-jar-file" name="jalview-in-a-jar-file" class="anchor"><span class="octicon octicon-link"></span>Jalview in a Jar File</a></h3>
+<p>Note that <code>jalview.bin.Launcher</code> is a simplified launcher class that re-launches <code>jalview.bin.Jalview</code> with the same JRE (<em>not</em> the same JVM instance), classpath and arguments, but with an automatically determined <code>-Xmx...</code> memory setting if one hasn't been provided.</p>
+<h3 id="jalview-in-a-jar-file">Jalview in a Jar File</h3>
<p>To package the <code>classes</code>, <code>resources</code>, and <code>help</code> into one jar, you can run</p>
-<pre><code class="language-bash">gradle jar
-</code></pre>
+<div class="sourceCode"><pre class="sourceCode bash"><code class="sourceCode bash"><span class="ex">gradle</span> jar</code></pre></div>
<p>which assembles the Jalview classes and resources into <code>dist/jalview.jar</code></p>
<p>To run this, use</p>
-<pre><code class="language-bash">java -cp "dist/jalview.jar:j11lib/*" jalview.bin.Jalview
-</code></pre>
-<h3 id="distributed-jar-files"><a href="#distributed-jar-files" name="distributed-jar-files" class="anchor"><span class="octicon octicon-link"></span>Distributed Jar Files</a></h3>
-<p>To simplify this, all required <code>.jar</code> files can be assembled into the <code>dist</code> folder
-using</p>
-<pre><code class="language-bash">gradle makeDist
-</code></pre>
+<div class="sourceCode"><pre class="sourceCode bash"><code class="sourceCode bash"><span class="ex">java</span> -cp <span class="st">"dist/jalview.jar:j11lib/*"</span> jalview.bin.Jalview</code></pre></div>
+<h3 id="distributed-jar-files">Distributed Jar Files</h3>
+<p>To simplify this, all required <code>.jar</code> files can be assembled into the <code>dist</code> folder using</p>
+<div class="sourceCode"><pre class="sourceCode bash"><code class="sourceCode bash"><span class="ex">gradle</span> makeDist</code></pre></div>
<p>which puts all required jar files into <code>dist</code> so you can run with</p>
-<pre><code class="language-bash">java -cp "dist/*" jalview.bin.Jalview
-</code></pre>
-<h3 id="single-shadow-jar-file"><a href="#single-shadow-jar-file" name="single-shadow-jar-file" class="anchor"><span class="octicon octicon-link"></span>Single <em>shadow</em> Jar File</a></h3>
-<p>The shadow jar file is a single <code>.jar</code> that contains all required classes and resources from <code>jalview.jar</code>
-and all of the supporting libraries in <code>j11lib/*.jar</code> merged into one <code>.jar</code> archive
-file. A default launching class (<code>MAIN-CLASS: jalview.bin.Launcher</code>) is specified in the <code>.jar</code>
-manifest file (<code>META/MANIFEST.MF</code>) so a start class doesn't need to be specified.</p>
-<p>Build the shadow jar file in <code>build/libs/jalview-all-VERSION-j11.jar</code> with</p>
-<pre><code class="language-bash">gradle shadowJar
-</code></pre>
-<p><strong>NB</strong> <code>VERSION</code> will be replaced with a version number or "<code>DEVELOPMENT</code>" or "<code>TEST</code>" depending on how the branch is set up.</p>
-<p>Run it with</p>
-<pre><code class="language-bash">java -jar build/libs/jalview-all-VERSION-j11.jar
-</code></pre>
-<p>Because no arguments are required, most OSes will associate a <code>.jar</code> file with the
-<code>java</code> application (if this has been installed through the OS and not just a local
-unzip) as a <code>-jar</code> argument so you may find you can launch <code>jalview-all-VERSION-j11.jar</code>
-just by double-clicking on it)!</p>
+<div class="sourceCode"><pre class="sourceCode bash"><code class="sourceCode bash"><span class="ex">java</span> -cp <span class="st">"dist/*"</span> jalview.bin.Jalview</code></pre></div>
+<h3 id="single-shadow-jar-file">Single <em>shadow</em> Jar File</h3>
+<p>The shadow jar file is a single <code>.jar</code> that contains all required classes and resources from <code>jalview.jar</code> and all of the supporting libraries in <code>j11lib/*.jar</code> merged into one <code>.jar</code> archive file. A default launching class (<code>MAIN-CLASS: jalview.bin.Launcher</code>) is specified in the <code>.jar</code> manifest file (<code>META/MANIFEST.MF</code>) so a start class doesn't need to be specified.</p>
+<p>Build the shadow jar file in <code>build/lib/jalview-all-11.jar</code> with</p>
+<div class="sourceCode"><pre class="sourceCode bash"><code class="sourceCode bash"><span class="ex">gradle</span> shadowJar</code></pre></div>
+<p>and run it with</p>
+<div class="sourceCode"><pre class="sourceCode bash"><code class="sourceCode bash"><span class="ex">java</span> -jar build/lib/jalview-all-11.jar</code></pre></div>
+<p>Because no arguments are required, most OSes will associate a <code>.jar</code> file with the <code>java</code> application (if this has been installed through the OS and not just a local unzip) as a <code>-jar</code> argument so you may find you can launch <code>jalview-all-11.jar</code> just by double-clicking on it)!</p>
<blockquote>
-<p>The <code>shadowJar</code> task is not a requirement for any other task, so to build the shadow
-jar file you must specify the <code>shadowJar</code> task.</p>
+<p>The <code>shadowJar</code> task is not a requirement for any other task, so to build the shadow jar file you must specify the <code>shadowJar</code> task.</p>
</blockquote>
<blockquote>
-<p>The shadow jar file represents probably the simplest way to distribute the Jalview application to machines that already have a Java 11 installed,
-although without the many and compelling benefits of the <code>getdown</code> launcher.</p>
+<p>The shadow jar file represents probably the simplest way to distribute the Jalview application to machines that already have a Java 11 installed, although without the many and compelling benefits of the <code>getdown</code> launcher.</p>
</blockquote>
-<h3 id="building-the-getdown-launcher"><a href="#building-the-getdown-launcher" name="building-the-getdown-launcher" class="anchor"><span class="octicon octicon-link"></span>Building the <code>getdown</code> launcher</a></h3>
-<p>We have made significant customisations to the <code>getdown</code> launcher which you can find
-in <code>getdown/src/getdown</code>.</p>
+<h3 id="building-the-getdown-launcher">Building the <code>getdown</code> launcher</h3>
+<p>We have made significant customisations to the <code>getdown</code> launcher which you can find in <code>getdown/src/getdown</code>.</p>
<blockquote>
-<p>You don't need to build this afresh as the required <code>gradle-core.jar</code>
-and <code>gradle-launcher.jar</code> files are already distributed in <code>j11lib</code> and <code>getdown/lib</code> but if you want to, then
-you'll need a working Maven and also a Java 8 JDK. Ensure the Java 8 <code>javac</code> is forefront
-in your path and do</p>
-<pre><code class="language-bash">cd getdown/src/getdown
-mvn clean package -Dgetdown.host.whitelist="jalview.org,*.jalview.org"
-</code></pre>
-<p>and you will find the required <code>.jar</code> files in <code>core/target/gradle-core-XXX.jar</code>
-and <code>launcher/target/gradle-launcher-XXX.jar</code>. The <code>gradle-core.jar</code> should then be copied
-to all three of the <code>j8lib</code>, <code>j11lib</code> and <code>getdown/lib</code> folders, whilst the <code>gradle-launcher.jar</code> only
-needs to be copied to <code>getdown/lib</code>.</p>
-<p>The <code>mvn</code> command should ideally include the <code>-Dgetdown.host.whitelist=*.jalview.org</code> setting.
-This, and the necessary file copying commands, can be found in <code>getdown/src/getdown/mvn_cmd</code>.</p>
+<p>You don't need to build this afresh as the required <code>gradle-core.jar</code> and <code>gradle-launcher.jar</code> files are already distributed in <code>j11lib</code> and <code>getdown/lib</code> but if you want to, then you'll need a working Maven and also a Java 8 JDK. Ensure the Java 8 <code>javac</code> is forefront in your path and do</p>
+<div class="sourceCode"><pre class="sourceCode bash"><code class="sourceCode bash"><span class="bu">cd</span> getdown/src/getdown
+<span class="ex">mvn</span> clean package -Dgetdown.host.whitelist=<span class="st">"jalview.org,*.jalview.org"</span></code></pre></div>
+<p>and you will find the required <code>.jar</code> files in <code>core/target/gradle-core-XXX.jar</code> and <code>launcher/target/gradle-launcher-XXX.jar</code>. The <code>gradle-core.jar</code> should then be copied to all three of the <code>j8lib</code>, <code>j11lib</code> and <code>getdown/lib</code> folders, whilst the <code>gradle-launcher.jar</code> only needs to be copied to <code>getdown/lib</code>.</p>
+<p>The <code>mvn</code> command should ideally include the <code>-Dgetdown.host.whitelist=*.jalview.org</code> setting. This, and the necessary file copying commands, can be found in <code>getdown/src/getdown/mvn_cmd</code>.</p>
</blockquote>
<p>To assemble Jalview with <code>getdown</code> use the following gradle task:</p>
-<pre><code class="language-bash">gradle getdown
-</code></pre>
-<p>This puts all the necessary files to launch Jalview with <code>getdown</code>
-into <code>getdown/website/11/</code>. This could be treated as the reference folder
-for <code>getdown</code>, which is where a getdown launcher will check to see if the Jalview application
-files it has are up to date, and download if they aren't or it simply doesn't have
-them.</p>
-<p>A minimal getdown-launcher can be found in <code>getdown/files/11/</code> which checks its up-to-date
-status with (the absolute path to) <code>getdown/website/11/</code>.</p>
+<div class="sourceCode"><pre class="sourceCode bash"><code class="sourceCode bash"><span class="ex">gradle</span> getdown</code></pre></div>
+<p>This puts all the necessary files to launch Jalview with <code>getdown</code> into <code>getdown/website/11/</code>. This could be treated as the reference folder for <code>getdown</code>, which is where a getdown launcher will check to see if the Jalview application files it has are up to date, and download if they aren't or it simply doesn't have them.</p>
+<p>A minimal getdown-launcher can be found in <code>getdown/files/11/</code> which checks its up-to-date status with (the absolute path to) <code>getdown/website/11/</code>.</p>
<p>This can be launched with</p>
-<pre><code class="language-bash">java -jar getdown/files/11/getdown-launcher.jar getdown/files/11/ jalview
-</code></pre>
+<div class="sourceCode"><pre class="sourceCode bash"><code class="sourceCode bash"><span class="ex">java</span> -jar getdown/files/11/getdown-launcher.jar getdown/files/11/ jalview</code></pre></div>
<blockquote>
-<p>We've already met the <code>-jar file.jar</code> arguments. The next argument is the working folder for
-getdown, and the final argument, "<code>jalview</code>", is a getdown application id (only "<code>jalview</code>"
-is defined here).</p>
+<p>We've already met the <code>-jar file.jar</code> arguments. The next argument is the working folder for getdown, and the final argument, "<code>jalview</code>", is a getdown application id (only "<code>jalview</code>" is defined here).</p>
</blockquote>
-<h3 id="running-tests"><a href="#running-tests" name="running-tests" class="anchor"><span class="octicon octicon-link"></span>Running tests</a></h3>
+<h3 id="running-tests">Running tests</h3>
<p>There are substantial tests written for Jalview that use TestNG, which you can run with</p>
-<pre><code class="language-bash">gradle test
-</code></pre>
-<p>These normally take around 5 - 10 minutes to complete and outputs its full results into
-the <code>tests/</code> folder. A summary of results should appear in your console.</p>
+<div class="sourceCode"><pre class="sourceCode bash"><code class="sourceCode bash"><span class="ex">gradle</span> test</code></pre></div>
+<p>These normally take around 5 - 10 minutes to complete and outputs its full results into the <code>tests/</code> folder. A summary of results should appear in your console.</p>
<p>You can run different defined groups of tests with</p>
-<pre><code class="language-bash">gradle test -PtestngGroups=Network
-</code></pre>
+<div class="sourceCode"><pre class="sourceCode bash"><code class="sourceCode bash"><span class="ex">gradle</span> test -PtestngGroups=Network</code></pre></div>
<p>Available groups include Functional (default), Network, External.</p>
-<h4 id="excluding-some-tests"><a href="#excluding-some-tests" name="excluding-some-tests" class="anchor"><span class="octicon octicon-link"></span>Excluding some tests</a></h4>
+<h4 id="excluding-some-tests">Excluding some tests</h4>
<p>Some of Jalview's Functional tests don't pass reliably in all environments. We tag these tests with a group like 'Not-bamboo' to mark them for exclusion when we run tests as part of continuous integration.</p>
<p>To exclude one or more groups of tests, add them as a comma separated list in testngExcludedGroups.</p>
-<pre><code class="language-bash">gradle test -PtestngExcludedGroups=Not-bamboo
-</code></pre>
-<h3 id="installer-packaging-with-install4j"><a href="#installer-packaging-with-install4j" name="installer-packaging-with-install4j" class="anchor"><span class="octicon octicon-link"></span>Installer packaging with <em>install4j</em></a></h3>
-<p>Jalview is currently using <em>install4j</em> <a href="https://www.ej-technologies.com/products/install4j/overview.html">https://www.ej-technologies.com/products/install4j/overview.html</a>
-as its installer packaging tool.</p>
-<p>If you have a licensed installation of <em>install4j</em> you can build Jalview installers
-by running</p>
-<pre><code class="language-bash">gradle installers
-</code></pre>
-<p>though you may need to fiddle with the <code>install4j</code> and <code>copyInstall4jTemplate</code> tasks
-in <code>build.gradle</code> file to point to your installation of <em>install4j</em> and also to bundled
-JREs if you want to bundle those into the installers.</p>
-<p>If you want more details, get in touch on our development mailing list <a href="mailto:jalview-dev@jalview.org">jalview-dev@jalview.org</a>.
-Sign up at <a href="http://www.compbio.dundee.ac.uk/mailman/listinfo/jalview-dev">http://www.compbio.dundee.ac.uk/mailman/listinfo/jalview-dev</a>.</p>
-<h2 id="gradle-properties"><a href="#gradle-properties" name="gradle-properties" class="anchor"><span class="octicon octicon-link"></span>Gradle properties</a></h2>
-<p>There are a lot of properties configured in <code>gradle.properties</code> which we strongly recommend
-being left as they are unless you have a specific problem with the build process.</p>
-<p>There are a few gradle properties you might want to set on the command line with the
-<code>-P</code> flag when building a version of Jalview with specific requirements:</p>
-<h4 id="java-version"><a href="#java-version" name="java-version" class="anchor"><span class="octicon octicon-link"></span><code>JAVA_VERSION</code></a></h4>
-<p>This changes the <em>target</em> java bytecode version</p>
-<blockquote>
-<p>NOTE that you will need to use a Java 11 (or greater) JDK Java compiler to build
-Jalview for any byte-code target version.</p>
-</blockquote>
+<div class="sourceCode"><pre class="sourceCode bash"><code class="sourceCode bash"><span class="ex">gradle</span> test -PtestngExcludedGroups=Not-bamboo</code></pre></div>
+<h3 id="installer-packaging-with-install4j">Installer packaging with <em>install4j</em></h3>
+<p>Jalview is currently using <em>install4j</em> <a href="https://www.ej-technologies.com/products/install4j/overview.html" class="uri">https://www.ej-technologies.com/products/install4j/overview.html</a> as its installer packaging tool.</p>
+<p>If you have a licensed installation of <em>install4j</em> you can build Jalview installers by running</p>
+<div class="sourceCode"><pre class="sourceCode bash"><code class="sourceCode bash"><span class="ex">gradle</span> installers</code></pre></div>
+<p>though you may need to fiddle with the <code>install4j</code> and <code>copyInstall4jTemplate</code> tasks in <code>build.gradle</code> file to point to your installation of <em>install4j</em> and also to bundled JREs if you want to bundle those into the installers.</p>
+<p>If you want more details, get in touch on our development mailing list <a href="mailto:jalview-dev@jalview.org">jalview-dev@jalview.org</a>. Sign up at <a href="http://www.compbio.dundee.ac.uk/mailman/listinfo/jalview-dev" class="uri">http://www.compbio.dundee.ac.uk/mailman/listinfo/jalview-dev</a>.</p>
+<h2 id="gradle-properties">Gradle properties</h2>
+<p>There are a lot of properties configured in <code>gradle.properties</code> which we strongly recommend being left as they are unless you have a specific problem with the build process.</p>
+<p>There are a few gradle properties you might want to set on the command line with the <code>-P</code> flag when building a version of Jalview with specific requirements:</p>
+<h4 id="java_version"><code>JAVA_VERSION</code></h4>
+<p>This changes the <em>target</em> java bytecode version > NOTE that you will need to use a Java 11 (or greater) JDK Java compiler to build Jalview for any byte-code target version.</p>
<p>Valid values are <code>11</code> and <code>1.8</code>.</p>
<p>e.g.</p>
-<pre><code class="language-bash">gradle shadowJar -PJAVA_VERSION=1.8
-</code></pre>
+<div class="sourceCode"><pre class="sourceCode bash"><code class="sourceCode bash"><span class="ex">gradle</span> shadowJar -PJAVA_VERSION=1.8</code></pre></div>
<p>When using <code>-PJAVA_VERSION=1.8</code> the libraries from <code>j8lib</code> (instead of <code>j11lib</code>) will be used in the compile<br />
-and runtime classpath and also used in the <code>makeDist</code> build step. Where a Java version of <code>11</code> is used in folder and file names, it will
-instead use <code>1.8</code>. Also if you are building installer packages with <em>install4j</em> the
-package builder will look for JRE 1.8 bundles to package in the installers.</p>
+and runtime classpath and also used in the <code>makeDist</code> build step. Where a Java version of <code>11</code> is used in folder and file names, it will instead use <code>1.8</code>. Also if you are building installer packages with <em>install4j</em> the package builder will look for JRE 1.8 bundles to package in the installers.</p>
<blockquote>
-<p>Note that continued development of Jalview will assume a Java 11+ runtime environment,
-the 2.11.0 release will run under a Java 1.8 JRE with a few minor features disabled.</p>
+<p>Note that continued development of Jalview will assume a Java 11+ runtime environment, the 2.11.0 release will run under a Java 1.8 JRE with a few minor features disabled.</p>
</blockquote>
-<h4 id="channel"><a href="#channel" name="channel" class="anchor"><span class="octicon octicon-link"></span><code>CHANNEL</code></a></h4>
-<p>This changes the <code>appbase</code> setting in <code>getdown.txt</code> (<code>appbase</code> is where the getdown launcher
-looks to see if there's an updated file) to point to a particular Jalview channel or some other appropriate
-place to look for required files. If the selected channel type requires the getdown <code>appbase</code> to be a local
-directory on the filesystem (instead of a website URL) then a modified version of the <code>getdown-launcher.jar</code> will
-be used to allow this. The two versions of the <code>getdown-launcher.jar</code> can be found in <code>getdown/lib</code>.
-Some other variables used in the build process might also be set differently depending on the value of <code>CHANNEL</code>
-to allow smooth operation of getdown in the given context.</p>
-<p>There are several values of <code>CHANNEL</code> that can be chosen, with a default of <code>LOCAL</code>. Here's what they're for and what they do:</p>
+<h4 id="channel"><code>CHANNEL</code></h4>
+<p>This changes the <code>appbase</code> setting in <code>getdown.txt</code> (<code>appbase</code> is where the getdown launcher looks to see if there's an updated file) to point to a particular Jalview channel or some other appropriate place to look for required files. If the selected channel type requires the getdown <code>appbase</code> to be a local directory on the filesystem (instead of a website URL) then a modified version of the <code>getdown-launcher.jar</code> will be used to allow this. The two versions of the <code>getdown-launcher.jar</code> can be found in <code>getdown/lib</code>. Some other variables used in the build process might also be set differently depending on the value of <code>CHANNEL</code> to allow smooth operation of getdown in the given context.</p>
+<p>There are several values of <code>CHANNEL</code> that can be chosen, with a default of <code>LOCAL</code>. Here's what they're for and what they do:</p>
<ul>
-<li><code>LOCAL</code>: This is for running the compiled application from the development directory.
-It will set
+<li><code>LOCAL</code>: This is for running the compiled application from the development directory. It will set
<ul>
-<li><code>appbase</code> as <code>file://PATH/TO/YOUR/DEVELOPMENT/getdown/files/JAVA_VERSION</code>
-(e.g. <code>file://home/user/git/jalview/getdown/files/11</code>)</li>
+<li><code>appbase</code> as <code>file://PATH/TO/YOUR/DEVELOPMENT/getdown/files/JAVA_VERSION</code> (e.g. <code>file://home/user/git/jalview/getdown/files/11</code>)</li>
<li>application subdir as <code>alt</code></li>
<li>Getdown launcher can use a <code>file://</code> scheme appbase.</li>
-</ul>
-</li>
-<li><code>BUILD</code>: This is for creating an appbase channel on the build server by an automatic or manually started build.
-It will set
+</ul></li>
+<li><code>BUILD</code>: This is for creating an appbase channel on the build server by an automatic or manually started build. It will set
<ul>
-<li><code>appbase</code> as <code>https://builds.jalview.org/browse/${bamboo_planKey}/latest/artifact/shared/getdown-channel/JAVA_VERSION</code>
-Note that bamboo_planKey should be set by the build plan with <code>-Pbamboo_planKey=${bamboo.planKey}</code></li>
+<li><code>appbase</code> as <code>https://builds.jalview.org/browse/${bamboo_planKey}/latest/artifact/shared/getdown-channel/JAVA_VERSION</code> Note that bamboo_planKey should be set by the build plan with <code>-Pbamboo_planKey=${bamboo.planKey}</code></li>
<li>application subdir as <code>alt</code></li>
<li>Getdown launcher cannot use a <code>file://</code> scheme appbase.</li>
-</ul>
-</li>
-<li><code>DEVELOP</code>: This is for creating a <code>develop</code> appbase channel on the main web server. This won't become live until the actual getdown artefact is synced to the web server.
-It will set
+</ul></li>
+<li><code>DEVELOP</code>: This is for creating a <code>develop</code> appbase channel on the main web server. This won't become live until the actual getdown artefact is synced to the web server. It will set
<ul>
<li><code>appbase</code> as <code>http://www.jalview.org/getdown/develop/JAVA_VERSION</code></li>
<li>application subdir as <code>alt</code></li>
<li>Getdown launcher cannot use a <code>file://</code> scheme appbase.</li>
-</ul>
-</li>
-<li><code>SCRATCH-NAME</code>: This is for creating a temporary scratch appbase channel on the main web server. This won't become live until the actual getdown artefact is synced to the web server. This is meant for testing an over-the-air update without interfering with the live <code>release</code> or <code>develop</code> channels. The value of <code>NAME</code> can be any "word-character" [A-Za-z0-9_]
-It will set
+</ul></li>
+<li><code>SCRATCH-NAME</code>: This is for creating a temporary scratch appbase channel on the main web server. This won't become live until the actual getdown artefact is synced to the web server. This is meant for testing an over-the-air update without interfering with the live <code>release</code> or <code>develop</code> channels. The value of <code>NAME</code> can be any "word-character" [A-Za-z0-9_] It will set
<ul>
<li><code>appbase</code> as <code>http://www.jalview.org/getdown/SCRATCH-NAME/JAVA_VERSION</code></li>
<li>application subdir as <code>alt</code></li>
<li>Getdown launcher cannot use a <code>file://</code> scheme appbase.</li>
-</ul>
-</li>
-<li><code>TEST-LOCAL</code>: Like <code>SCRATCH</code> but with a specific <code>test-local</code> channel name and a local filesystem appbase. This is meant for testing an over-the-air update on the local filesystem. An extra property <code>LOCALDIR</code> must be given (e.g. <code>-PLOCALDIR=/home/user/tmp/test</code>)
-It will set
+</ul></li>
+<li><code>TEST-LOCAL</code>: Like <code>SCRATCH</code> but with a specific <code>test-local</code> channel name and a local filesystem appbase. This is meant for testing an over-the-air update on the local filesystem. An extra property <code>LOCALDIR</code> must be given (e.g. <code>-PLOCALDIR=/home/user/tmp/test</code>) It will set
<ul>
<li><code>appbase</code> as <code>file://${LOCALDIR}</code></li>
<li>application subdir as <code>alt</code></li>
<li>Getdown launcher can use a <code>file://</code> scheme appbase.</li>
-</ul>
-</li>
-<li><code>TEST-RELEASE</code>: Like <code>SCRATCH</code> but with a specific <code>test-release</code> channel name. This won't become live until the actual getdown artefact is synced to the web server. This is meant for testing an over-the-air update without interfering with the live <code>release</code> or <code>develop</code> channels.
-It will set
+</ul></li>
+<li><code>TEST-RELEASE</code>: Like <code>SCRATCH</code> but with a specific <code>test-release</code> channel name. This won't become live until the actual getdown artefact is synced to the web server. This is meant for testing an over-the-air update without interfering with the live <code>release</code> or <code>develop</code> channels. It will set
<ul>
<li><code>appbase</code> as <code>http://www.jalview.org/getdown/test-release/JAVA_VERSION</code></li>
<li>application subdir as <code>alt</code></li>
<li>Getdown launcher cannot use a <code>file://</code> scheme appbase.</li>
-</ul>
-</li>
-<li><code>RELEASE</code>: This is for an actual release build, and will use an appbase on the main web server with the main <code>release</code> channel name. This won't become live until the actual getdown artefact is synced to the web server.
-It will set
+</ul></li>
+<li><code>RELEASE</code>: This is for an actual release build, and will use an appbase on the main web server with the main <code>release</code> channel name. This won't become live until the actual getdown artefact is synced to the web server. It will set
<ul>
<li><code>appbase</code> as <code>http://www.jalview.org/getdown/release/JAVA_VERSION</code></li>
<li>application subdir as <code>release</code></li>
<li>Getdown launcher cannot use a <code>file://</code> scheme appbase.</li>
-</ul>
-</li>
-<li><code>ARCHIVE</code>: This is a helper to create a channel for a specific release version, and will use an appbase on the main web server with a specific <code>archive/JALVIEW_VERSION</code> channel name. This won't become live until the actual getdown artefact is synced to the web server.
-You must also specify an <code>ARCHIVEDIR</code> property that points to an earlier version of Jalview with a <code>dist</code> directory containing the required jar files. This should create a getdown structure and digest with the older jar files.
-It will set
+</ul></li>
+<li><code>ARCHIVE</code>: This is a helper to create a channel for a specific release version, and will use an appbase on the main web server with a specific <code>archive/JALVIEW_VERSION</code> channel name. This won't become live until the actual getdown artefact is synced to the web server. You must also specify an <code>ARCHIVEDIR</code> property that points to an earlier version of Jalview with a <code>dist</code> directory containing the required jar files. This should create a getdown structure and digest with the older jar files. It will set
<ul>
<li><code>appbase</code> as <code>http://www.jalview.org/getdown/archive/JALVIEW_VERSION/JAVA_VERSION</code></li>
<li>application subdir as <code>alt</code></li>
<li>Getdown launcher cannot use a <code>file://</code> scheme appbase.</li>
-</ul>
-</li>
-<li><code>ARCHIVELOCAL</code>: Like <code>ARCHIVE</code> but with a local filesystem appbase for local testing.
-You must also specify an <code>ARCHIVEDIR</code> property that points to an earlier version of Jalview with a <code>dist</code> directory containing the required jar files. This should create a getdown structure and digest with the older jar files.
-It will set
+</ul></li>
+<li><code>ARCHIVELOCAL</code>: Like <code>ARCHIVE</code> but with a local filesystem appbase for local testing. You must also specify an <code>ARCHIVEDIR</code> property that points to an earlier version of Jalview with a <code>dist</code> directory containing the required jar files. This should create a getdown structure and digest with the older jar files. It will set
<ul>
<li><code>appbase</code> as <code>file://PATH/TO/YOUR/DEVELOPMENT/getdown/website/JAVA_VERSION</code> (where the old jars will have been copied and digested)</li>
<li>application subdir as <code>alt</code></li>
<li>Getdown launcher can use a <code>file://</code> scheme appbase.</li>
-</ul>
-</li>
+</ul></li>
</ul>
<p>e.g.</p>
-<pre><code class="language-bash">gradle getdown -PCHANNEL=SCRATCH-my_test_version
-</code></pre>
-<h4 id="jalview-version-and-the-release-file"><a href="#jalview-version-and-the-release-file" name="jalview-version-and-the-release-file" class="anchor"><span class="octicon octicon-link"></span>JALVIEW_VERSION and the RELEASE file</a></h4>
-<p>Any Jalview build will include the value of JALVIEW_VERSION in various places, including the 'About' and Jalview Desktop window title, and in filenames for the stand-alone executable jar. You can specify a custom version for a build via the JALVIEW_VERSION property, but for most situations, JALVIEW_VERSION will be automatically configured according to the value of the CHANNEL property, using the <code>jalview.version</code> property specified in the RELEASE file:</p>
-<ul>
-<li><code>CHANNEL=RELEASE</code> will set version to jalview.version</li>
-<li><code>CHANNEL=TEST or DEVELOP</code> will append '-test' or '-develop' to jalview.version</li>
-</ul>
-<p>It is also possible to specify a custom location for the RELEASE file via an optional JALVIEW_RELEASE_FILE property.</p>
-<h4 id="install4jmediatypes"><a href="#install4jmediatypes" name="install4jmediatypes" class="anchor"><span class="octicon octicon-link"></span><code>install4jMediaTypes</code></a></h4>
-<p>If you are building <em>install4j</em> installers (requires <em>install4j</em> to be installed) then this property specifies a comma-separated
-list of media types (i.e. platform specific installers) <em>install4j</em> should actually build.</p>
-<p>Currently the valid values are
-<code>linuxDeb</code>,
-<code>linuxRPM</code>,
-<code>macosArchive</code>,
-<code>unixArchive</code>,
-<code>unixInstaller</code>,
-<code>windows</code></p>
+<div class="sourceCode"><pre class="sourceCode bash"><code class="sourceCode bash"><span class="ex">gradle</span> getdown -PCHANNEL=SCRATCH-my_test_version</code></pre></div>
+<h4 id="install4jmediatypes"><code>install4jMediaTypes</code></h4>
+<p>If you are building <em>install4j</em> installers (requires <em>install4j</em> to be installed) then this property specifies a comma-separated list of media types (i.e. platform specific installers) <em>install4j</em> should actually build.</p>
+<p>Currently the valid values are <code>linuxDeb</code>, <code>linuxRPM</code>, <code>macosArchive</code>, <code>unixArchive</code>, <code>unixInstaller</code>, <code>windows</code></p>
<p>The default value is all of them.</p>
<p>e.g.</p>
-<pre><code class="language-bash">gradle installers -PJAVA_VERSION=1.8 -Pinstall4jMediaTypes=macosArchive
-</code></pre>
+<div class="sourceCode"><pre class="sourceCode bash"><code class="sourceCode bash"><span class="ex">gradle</span> installers -PJAVA_VERSION=1.8 -Pinstall4jMediaTypes=macosArchive</code></pre></div>
<p>To get an up-to-date list of possible values, you can run</p>
-<pre><code class="language-bash">perl -n -e 'm/^\s*<(\w+)[^>]*\bmediaFileName=/ && print "$1\n";' utils/install4j/install4j_template.install4j | sort -u
-</code></pre>
+<div class="sourceCode"><pre class="sourceCode bash"><code class="sourceCode bash"><span class="fu">perl</span> -n -e <span class="st">'m/^\s*<(\w+)[^>]*\bmediaFileName=/ && print "$1\n";'</span> utils/install4j/install4j_template.install4j <span class="kw">|</span> <span class="fu">sort</span> -u</code></pre></div>
<p>in the <code>jalview</code> root folder.</p>
-<h2 id="enabling-code-coverage-with-openclover"><a href="#enabling-code-coverage-with-openclover" name="enabling-code-coverage-with-openclover" class="anchor"><span class="octicon octicon-link"></span>Enabling Code Coverage with OpenClover</a></h2>
+<h2 id="enabling-code-coverage-with-openclover">Enabling Code Coverage with OpenClover</h2>
<p>Bytecode instrumentation tasks are enabled by specifying 'true' (or just a non-whitespace non-numeric word) in the 'clover' property. This adds the 'openclover' plugin to the build script's classpath, making it possible to track code execution during test which can be viewed as an HTML report published at build/reports/clover/index.html.</p>
<p><code>gradle -Pclover=true test cloverReport</code></p>
-<h4 id="troubleshooting-report-generation"><a href="#troubleshooting-report-generation" name="troubleshooting-report-generation" class="anchor"><span class="octicon octicon-link"></span>Troubleshooting report generation</a></h4>
+<h4 id="troubleshooting-report-generation">Troubleshooting report generation</h4>
<p>The build forks a new JVM process to run the clover report generation tools (both XML and HTML reports are generated by default). The following properties can be used to specify additional options or adjust JVM memory settings. Default values for these options are:</p>
-<h5 id="jvm-memory-settings---increase-if-out-of-memory-errors-are-reported"><a href="#jvm-memory-settings---increase-if-out-of-memory-errors-are-reported" name="jvm-memory-settings---increase-if-out-of-memory-errors-are-reported" class="anchor"><span class="octicon octicon-link"></span>JVM Memory settings - increase if out of memory errors are reported</a></h5>
+<h5 id="jvm-memory-settings---increase-if-out-of-memory-errors-are-reported">JVM Memory settings - increase if out of memory errors are reported</h5>
<p><code>cloverReportJVMHeap = 2g</code></p>
-<h5 id="-dfileencodingutf-8-is-an-essential-parameters-for-report-generation-add-additional-ones-separated-by-a-space"><a href="#-dfileencodingutf-8-is-an-essential-parameters-for-report-generation-add-additional-ones-separated-by-a-space" name="-dfileencodingutf-8-is-an-essential-parameters-for-report-generation-add-additional-ones-separated-by-a-space" class="anchor"><span class="octicon octicon-link"></span>-Dfile.encoding=UTF-8 is an essential parameters for report generation. Add additional ones separated by a space.</a></h5>
+<h5 id="dfile.encodingutf-8-is-an-essential-parameters-for-report-generation.-add-additional-ones-separated-by-a-space.">-Dfile.encoding=UTF-8 is an essential parameters for report generation. Add additional ones separated by a space.</h5>
<p><code>cloverReportJVMArgs = -Dfile.encoding=UTF-8</code></p>
-<h5 id="add--v-to-debug-velocity-html-generation-errors-or--d-to-track-more-detailed-issues-with-the-coverage-database"><a href="#add--v-to-debug-velocity-html-generation-errors-or--d-to-track-more-detailed-issues-with-the-coverage-database" name="add--v-to-debug-velocity-html-generation-errors-or--d-to-track-more-detailed-issues-with-the-coverage-database" class="anchor"><span class="octicon octicon-link"></span>Add -v to debug velocity html generation errors, or -d to track more detailed issues with the coverage database</a></h5>
+<h5 id="add--v-to-debug-velocity-html-generation-errors-or--d-to-track-more-detailed-issues-with-the-coverage-database">Add -v to debug velocity html generation errors, or -d to track more detailed issues with the coverage database</h5>
<p><code>cloverReportHTMLOptions =</code></p>
-<h5 id="-v-for-verbose--d-for-debug-level-messages-as-above"><a href="#-v-for-verbose--d-for-debug-level-messages-as-above" name="-v-for-verbose--d-for-debug-level-messages-as-above" class="anchor"><span class="octicon octicon-link"></span>-v for verbose, -d for debug level messages (as above)</a></h5>
+<h5 id="v-for-verbose--d-for-debug-level-messages-as-above">-v for verbose, -d for debug level messages (as above)</h5>
<p><code>cloverReportXMLOptions =</code></p>
<p><em>Note</em> do not forget to include the -Dfile.encoding=UTF-8 option: this is essential for some platforms in order for Clover to correctly parse some Jalview source files that contain characters that are UTF-8 encoded.</p>
-<h2 id="setting-up-in-eclipse-ide"><a href="#setting-up-in-eclipse-ide" name="setting-up-in-eclipse-ide" class="anchor"><span class="octicon octicon-link"></span>Setting up in Eclipse IDE</a></h2>
-<h3 id="installing-eclipse-ide"><a href="#installing-eclipse-ide" name="installing-eclipse-ide" class="anchor"><span class="octicon octicon-link"></span>Installing Eclipse IDE</a></h3>
-<p>We develop in Eclipse, and support settings to develop and save Jalview source code
-in our preferred style. We also support running the Jalview application, debugging
-and running tests with TestNG from within Eclipse.</p>
-<p>To get Jalview set up as a project in Eclipse, we recommend using at least the 2020-03
-version of Eclipse IDE for Java Developers which you can download from the Eclipse
-website: <a href="https://www.eclipse.org/downloads/">https://www.eclipse.org/downloads/</a>. Since Eclipse 2020-03 you are encouraged to use the Eclipse Installer (see the Eclipse Downloads page).
-In the installer, when given a choice of packages for Eclipse you should choose the "Eclipse IDE for Enterprise Java Developers" package.</p>
-<p><img src="./images/eclipse_installer.png" alt="" title="Eclipse Installer screenshot" /></p>
+<h2 id="setting-up-in-eclipse-ide">Setting up in Eclipse IDE</h2>
+<h3 id="installing-eclipse-ide">Installing Eclipse IDE</h3>
+<p>We develop in Eclipse, and support settings to develop and save Jalview source code in our preferred style. We also support running the Jalview application, debugging and running tests with TestNG from within Eclipse.</p>
+<p>To get Jalview set up as a project in Eclipse, we recommend using at least the 2019-12 version of Eclipse IDE for Java Developers which you can download from the Eclipse website: <a href="https://www.eclipse.org/downloads/" class="uri">https://www.eclipse.org/downloads/</a>. Since Eclipse 2020-03 you are encouraged to use the Eclipse Installer (see the Eclipse Downloads page). In the installer, when given a choice of packages for Eclipse you should choose the "Eclipse IDE for Enterprise Java Developers" package.</p>
+<div class="figure">
+<img src="./images/eclipse_installer.png" title="Eclipse Installer screenshot" />
+
+</div>
<p>Once Eclipse is installed, we also recommend installing several plugins from the Eclipse Marketplace.</p>
<p>Some of these should already be installed with the Enterprise Java Developer package:</p>
-<ol>
+<ol style="list-style-type: decimal">
<li>Buildship Gradle Integration 3.0 (or greater)</li>
<li>EclEmma Java Code Coverage</li>
<li>Egit - Git Integration for Eclipse</li>
</ol>
<p>To install the others, launch Eclipse, and go to Help->Eclipse Marketplace...</p>
<p>Search for and install:</p>
-<ol>
+<ol style="list-style-type: decimal">
<li>Groovy Development Tools 3.4.0 (or greater)</li>
<li>Checkstyle Plug-in (optional)</li>
<li>TestNG for Eclipse (optional -- only needed if you want to run tests from Eclipse)</li>
</ol>
<blockquote>
-<p>At time of writing, TestNG for Eclipse does not show up in the Eclipse Marketplace
-as the latest released version does not install in Eclipse 2020-03.
-However, you can install a working release of TestNG for Eclipse by going to</p>
+<p>At time of writing, TestNG for Eclipse does not show up in the Eclipse Marketplace as the latest released version does not install in Eclipse 2019-03. However, you can install a working release of TestNG for Eclipse by going to</p>
<p>Help->Install New Software...</p>
<p>and entering</p>
<p><code>TestNG Release - https://dl.bintray.com/testng-team/testng-eclipse-release</code></p>
<p>into the <em>Work with</em> box and click on the <em>Add...</em> button.</p>
-<p>Eclipse might pause for a bit with the word <em>Pending</em> in the table below at this point, but it will eventually list TestNG with
-a selection box under the <em>Name</em> column.</p>
-<p>Select <em>TestNG</em> and carry on through the
-install process to install the TestNG plugin.</p>
+<p>Eclipse might pause for a bit with the word <em>Pending</em> in the table below at this point, but it will eventually list TestNG with a selection box under the <em>Name</em> column.</p>
+<p>Select <em>TestNG</em> and carry on through the install process to install the TestNG plugin.</p>
</blockquote>
<p>After installing the plugins, check that Java 11 is set up in Eclipse as the default JRE (see section <a href="#java-11-compliant-jdk">Java 11 compliant JDK</a>).</p>
-<p>To do this go to Preferences (Eclipse->Preferences in macOS, File->Preferences
-on Windows or Window->Preferences on Linux) and find</p>
+<p>To do this go to Preferences (Eclipse->Preferences in macOS, File->Preferences on Windows or Window->Preferences on Linux) and find</p>
<p>Java -> Installed JREs</p>
<p>If your Java 11 installation is not listed, click on</p>
<p><em>Add</em> -> Standard VM -> <em>Next</em></p>
-<p>and enter the JRE home. You can browse to where it is installed. Give it a name (like "AdoptOpenJDK 11"). Select this JDK
-as the default JRE and click on <em>Apply and Close</em>.</p>
+<p>and enter the JRE home. You can browse to where it is installed. Give it a name (like "AdoptOpenJDK 11"). Select this JDK as the default JRE and click on <em>Apply and Close</em>.</p>
<p>You can now import Jalview.</p>
-<h3 id="importing-jalview-as-an-eclipse-project"><a href="#importing-jalview-as-an-eclipse-project" name="importing-jalview-as-an-eclipse-project" class="anchor"><span class="octicon octicon-link"></span>Importing Jalview as an Eclipse project</a></h3>
-<h4 id="importing-an-already-downloaded-git-repo"><a href="#importing-an-already-downloaded-git-repo" name="importing-an-already-downloaded-git-repo" class="anchor"><span class="octicon octicon-link"></span>Importing an already downloaded git repo</a></h4>
+<h3 id="importing-jalview-as-an-eclipse-project">Importing Jalview as an Eclipse project</h3>
+<h4 id="importing-an-already-downloaded-git-repo">Importing an already downloaded git repo</h4>
<p>If you have already downloaded Jalview using <code>git clone</code> then you can import this folder into Eclipse directly.</p>
-<p><strong>Before importing the cloned git repo you must create the Eclipse project files.</strong> You can do this by either running</p>
-<p><code>gradle eclipse</code></p>
-<p>or</p>
-<p>Unzipping the file <code>utils/eclipse/eclipse_startup_files.zip</code> in the base repo directory (<code>jalview</code>)</p>
-<p>It is important to import
-Jalview as a Gradle project (not as a Java project), so go to</p>
+<p>It is important to import Jalview as a Gradle project (not as a Java project), so go to</p>
<p>File->Import...</p>
<p>find and select</p>
<p>Gradle->Existing Gradle Project</p>
<p>and then click on the <em>Next</em> button.</p>
-<p>In the following options, it is the <strong>Project Root Directory</strong> you should set to be the
-<code>jalview</code> folder that git downloaded. Then you can click on the <em>Finish</em> button.</p>
-<h4 id="using-eclipse-ide-to-download-the-git-repo"><a href="#using-eclipse-ide-to-download-the-git-repo" name="using-eclipse-ide-to-download-the-git-repo" class="anchor"><span class="octicon octicon-link"></span>Using Eclipse IDE to download the git repo</a></h4>
-<p>If you don't have git as a command line tool or would prefer to work entirely within Eclipse IDE then
-Eclipse's eGit plugin can set up a git repo of the jalview source. Go to</p>
+<p>In the following options, it is the <strong>Project Root Directory</strong> you should set to be the <code>jalview</code> folder that git downloaded. Then you can click on the <em>Finish</em> button.</p>
+<h4 id="using-eclipse-ide-to-download-the-git-repo">Using Eclipse IDE to download the git repo</h4>
+<p>If you don't have git as a command line tool or would prefer to work entirely within Eclipse IDE then Eclipse's eGit plugin can set up a git repo of the jalview source. Go to</p>
<p>File->Import...</p>
<p>Find and select</p>
<p>Git->Projects from Git</p>
<p>and then click on the <em>Next</em> button.</p>
<p>Then select Clone URI and click on <em>Next</em>.</p>
-<p>In the next window (Source Git Repository) you should put the <code>git clone</code> URL in the text box labelled <code>URI</code>. If you have a Jalview developer account (with a username and password for the Jalview git repository) then you should enter
-<code>https://source.jalview.org/git/jalview.git</code>.
-If you do not have a Jalview developer account then you should enter
-<code>http://source.jalview.org/git/jalview.git</code>.
-You will not be able to push any of your changes back to the Jalview git repository. However you can still pull all branches of the Jalview source code to your computer and develop the code there.</p>
-<blockquote>
-<p>You can sign up for a Jalview developer account at <a href="https://source.jalview.org/crucible/">https://source.jalview.org/crucible/</a></p>
-</blockquote>
-<p>If you have a Jalview developer account, enter the username and password and decide if you want to use Eclipse's secure storage. If you don't have an account you can leave the Authentication section blank.</p>
-<p><img src="./images/eclipse_egit_connection.png" alt="Eclipse eGit connection configuration" /></p>
+<p>In the next window (Source Git Repository) you should put the <code>git clone</code> URL in the text box labelled <code>URI</code>. If you have a Jalview developer account (with a username and password for the Jalview git repository) then you should enter <code>https://source.jalview.org/git/jalview.git</code>. If you do not have a Jalview developer account then you should enter <code>http://source.jalview.org/git/jalview.git</code>. You will not be able to push any of your changes back to the Jalview git repository. However you can still pull all branches of the Jalview source code to your computer and develop the code there. > You can sign up for a Jalview developer account at <a href="https://source.jalview.org/crucible/" class="uri">https://source.jalview.org/crucible/</a></p>
+<p>If you have a Jalview developer account, enter the username and password and decide if you want to use Eclipse's secure storage. If you don't have an account you can leave the Authentication section blank.</p>
+<div class="figure">
+<img src="./images/eclipse_egit_connection.png" alt="Eclipse eGit connection configuration" />
+<p class="caption">Eclipse eGit connection configuration</p>
+</div>
<p>Click on the <em>Next</em> button.</p>
-<p>The next window (Branch Selection) gives a list of the many Jalview branches, which by default will be all checked. You probably only want to download one branch (you can always download others at a later time). This is likely to be the <code>develop</code> branch so you can click on the <em>Deselect All</em> button, find the <code>develop</code> branch (the filter text helps), select that, and then click on the <em>Next</em> button.</p>
-<p>Choose a directory to your copy of the git repo in, and leave the other options as they are and click on the <em>Next</em> button. The next stage may take a minute or two as it checks out the selected branch(es) from the Jalview git repository.</p>
-<p>When it has finished it is important to select <strong>Import as general project</strong> and then click on <em>Next</em>.</p>
-<blockquote>
-<p>Ideally there would be an <em>Import as gradle project</em> here but there isn't -- we'll sort that out later.</p>
-</blockquote>
-<p><img src="./images/eclipse_egit_import.png" alt="Eclipse eGit import choice" /></p>
+<p>The next window (Branch Selection) gives a list of the many Jalview branches, which by default will be all checked. You probably only want to download one branch (you can always download others at a later time). This is likely to be the <code>develop</code> branch so you can click on the <em>Deselect All</em> button, find the <code>develop</code> branch (the filter text helps), select that, and then click on the <em>Next</em> button.</p>
+<p>Choose a directory to your copy of the git repo in, and leave the other options as they are and click on the <em>Next</em> button. The next stage may take a minute or two as it checks out the selected branch(es) from the Jalview git repository.</p>
+<p>When it has finished it is important to select <strong>Import as general project</strong> and then click on <em>Next</em>. > Ideally there would be an <em>Import as gradle project</em> here but there isn't -- we'll sort that out later.</p>
+<div class="figure">
+<img src="./images/eclipse_egit_import.png" alt="Eclipse eGit import choice" />
+<p class="caption">Eclipse eGit import choice</p>
+</div>
<p>Click on the <em>Next</em> button.</p>
-<p>You can change the project name here. By default it will show as <strong>jalview</strong> which is fine unless you have another instance of the a Jalview project also called jalview, in which case you could change this project's name now to avoid a conflict within Eclipse.</p>
+<p>You can change the project name here. By default it will show as <strong>jalview</strong> which is fine unless you have another instance of the a Jalview project also called jalview, in which case you could change this project's name now to avoid a conflict within Eclipse.</p>
<p>Click on <em>Finish</em>!</p>
<p>However, we haven't finished...</p>
-<p>You should now see, and be able to expand, the jalview project in the Project Explorer. We need to tell eclipse that this is a Gradle project, which will then allow the Eclipse Buildship plugin to automatically configure almost everything else!</p>
+<p>You should now see, and be able to expand, the jalview project in the Project Explorer. We need to tell eclipse that this is a Gradle project, which will then allow the Eclipse Buildship plugin to automatically configure almost everything else!</p>
<p>Right click on the project name (jalview) in the Project Explorer and find Configure towards the bottom of this long context menu, then choose Add Gradle Nature.</p>
-<p><img src="./images/eclipse_add_gradle_nature.png" alt="Eclipse Add Gradle Nature" /></p>
+<div class="figure">
+<img src="./images/eclipse_add_gradle_nature.png" alt="Eclipse Add Gradle Nature" />
+<p class="caption">Eclipse Add Gradle Nature</p>
+</div>
<p>The project should now reconfigure itself using the <code>build.gradle</code> file to dynamically set various aspects of the project including classpath.</p>
-<h4 id="additional-views"><a href="#additional-views" name="additional-views" class="anchor"><span class="octicon octicon-link"></span>Additional views</a></h4>
-<p>Some views that are automatically added when Importing a Gradle Project are not added when simply Adding a Gradle Nature, but we can add these manually by clicking on
-Window->Show View->Console
-and
-Window->Show View->Other...
-Filter with the word "gradle" and choose both <strong>Gradle Executions</strong> and <strong>Gradle Tasks</strong> and then click on the <em>Open</em> button.</p>
-<p>Okay, ready to code! Use of Eclipse is beyond the scope of this document, but you can find more information about developing jalview and our developer workflow in the google doc <a href="https://docs.google.com/document/d/1lZo_pZRkazDBJGNachXr6qCVlw8ByuMYG6e9SZlPUlQ/edit?usp=sharing">https://docs.google.com/document/d/1lZo_pZRkazDBJGNachXr6qCVlw8ByuMYG6e9SZlPUlQ/edit?usp=sharing</a></p>
+<h4 id="additional-views">Additional views</h4>
+<p>Some views that are automatically added when Importing a Gradle Project are not added when simply Adding a Gradle Nature, but we can add these manually by clicking on Window->Show View->Console and Window->Show View->Other... Filter with the word "gradle" and choose both <strong>Gradle Executions</strong> and <strong>Gradle Tasks</strong> and then click on the <em>Open</em> button.</p>
+<p>Okay, ready to code! Use of Eclipse is beyond the scope of this document, but you can find more information about developing jalview and our developer workflow in the google doc <a href="https://docs.google.com/document/d/1lZo_pZRkazDBJGNachXr6qCVlw8ByuMYG6e9SZlPUlQ/edit?usp=sharing" class="uri">https://docs.google.com/document/d/1lZo_pZRkazDBJGNachXr6qCVlw8ByuMYG6e9SZlPUlQ/edit?usp=sharing</a></p>
<hr />
<p><a href="mailto:help@jalview.org">Jalview Development Team</a></p>
-
- </body>
+</body>
</html>
--- /dev/null
+// def alv = new jalview.io.FileLoader().LoadFileWaitTillLoaded("examples/testdata/hmmer3/alignment_res.fa.gz","File").getViewport();
+def alv = jalview.bin.Jalview.getCurrentAlignFrame().getViewport();
+def al = alv.getAlignment();
+def jproc = new jalview.ws.ebi.HmmerJSONProcessor(al)
+jproc.parseFrom(new jalview.io.FileParse("/Users/jprocter/git/jalview/examples/testdata/hmmer3/hmmeresult.json.gz",jalview.io.DataSourceType.FILE))
+jproc.updateView(alv)
\ No newline at end of file
--- /dev/null
+HMMER3/f [3.1b2 | February 2015]
+NAME uniref50
+LENG 148
+ALPH amino
+ RF no
+MM no
+CONS yes
+CS no
+MAP yes
+DATE Mon Jun 12 14:32:05 2017
+NSEQ 15
+EFFN 0.648193
+CKSUM 2563184735
+STATS LOCAL MSV -10.0682 0.70956
+STATS LOCAL VITERBI -10.7870 0.70956
+STATS LOCAL FORWARD -4.6837 0.70956
+HMM A C D E F G H I K L M N P Q R S T V W Y
+ m->m m->i m->d i->m i->i d->m d->d
+ COMPO 2.40816 3.71583 2.80837 2.63551 3.47092 2.77036 3.85028 2.88279 2.80267 2.53589 3.68425 3.22102 3.34428 3.14560 3.11474 2.53177 2.75990 2.58070 5.00144 3.51101
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.10433 3.97705 2.52157 0.61958 0.77255 0.00000 *
+ 1 2.99317 4.53706 4.08224 3.67789 3.22093 3.85692 4.40592 2.39958 3.44433 1.81088 1.32037 3.95163 4.31759 3.82413 3.64608 3.34553 3.29902 2.40928 5.06591 3.83044 1 m - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.03044 3.90315 4.62550 0.61958 0.77255 0.55549 0.85282
+ 2 0.97044 4.20710 3.49350 3.28598 4.08269 3.03087 4.30444 3.21278 3.30302 3.09300 4.12129 3.42792 3.77296 3.64134 3.55157 2.55705 2.83652 2.86187 5.50678 4.31039 2 a - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.11955 3.90315 2.38048 0.61958 0.77255 0.55549 0.85282
+ 3 1.74035 4.09199 3.34495 3.00819 4.05288 2.91638 4.05509 3.33461 3.01251 3.11462 3.97728 3.20348 3.62940 3.32849 3.32799 1.99191 1.99086 2.89563 5.42641 4.20726 3 a - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.03323 3.81683 4.53917 0.61958 0.77255 0.62561 0.76558
+ 4 2.37663 4.18625 3.55838 3.17855 3.75132 3.18264 4.13666 2.64341 3.07328 2.62344 3.69712 3.39774 3.83139 3.44405 3.35689 2.61052 1.64486 2.15973 5.30034 4.05468 4 t - - -
+ 2.68617 4.42230 2.77525 2.73129 3.46359 2.40511 3.72500 3.29359 2.67746 2.69350 4.24695 2.90352 2.73719 3.18152 2.89806 2.37885 2.77501 2.98524 4.58482 3.61508
+ 0.33937 1.47682 2.82312 0.71438 0.67236 0.50642 0.92294
+ 5 1.78828 4.31568 3.18846 2.75366 3.97645 3.11838 3.84000 3.34055 2.67250 3.02453 3.87541 3.10729 3.71676 3.06391 2.67828 2.15246 2.50645 2.96422 5.30410 4.05011 9 a - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.03188 3.85742 4.57976 0.61958 0.77255 0.59400 0.80322
+ 6 2.60146 4.34120 4.20318 3.64233 3.23200 4.03946 4.38229 1.91078 3.53317 1.46276 2.80385 3.95250 4.35454 3.78680 3.77614 3.34686 3.12310 1.90138 5.05979 3.90282 10 l - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.03188 3.85742 4.57976 0.61958 0.77255 0.59400 0.80322
+ 7 2.51618 4.38929 3.20785 2.68482 3.53842 3.39630 3.71025 2.97988 2.63127 2.66315 3.23915 3.11866 3.35060 2.98059 3.01133 2.11689 2.77574 2.72369 4.95633 3.10650 11 s - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.03188 3.85742 4.57976 0.61958 0.77255 0.59400 0.80322
+ 8 1.83112 4.12334 3.20156 2.95461 4.23963 1.79514 4.09699 3.64646 3.07597 3.33878 4.16582 3.16397 3.61350 3.35846 3.40724 1.96001 2.64648 3.10558 5.57497 4.34818 12 g - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.07518 3.85742 2.97012 0.61958 0.77255 0.59400 0.80322
+ 9 2.02467 4.19921 3.47207 3.00878 3.03795 3.27081 3.95597 2.70270 2.96218 2.55248 3.54468 3.31239 3.83177 3.27950 3.28895 2.63385 2.09090 2.46488 5.06606 3.80489 13 a - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.03327 3.81551 4.53786 0.61958 0.77255 0.56041 0.84624
+ 10 2.25155 4.19461 3.85704 3.29295 2.92371 3.72128 4.04839 2.07964 3.20853 2.08962 2.71310 3.60847 4.09120 3.47607 3.47945 3.00735 2.74040 2.14097 4.86082 3.65928 14 i - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.03170 3.86316 4.58551 0.61958 0.77255 0.53107 0.88667
+ 11 2.97746 4.34766 4.53309 3.96552 2.78843 4.21079 4.53997 1.80103 3.85948 1.59494 2.57669 4.20401 4.48099 4.02954 4.02513 3.53069 3.20806 1.63119 5.03312 3.89134 15 l - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.03044 3.90315 4.62550 0.61958 0.77255 0.55549 0.85282
+ 12 2.01604 4.15364 3.23013 2.99255 4.26101 2.66741 4.12859 3.66796 3.09383 3.37186 4.20680 3.19709 3.64453 3.39377 3.41395 1.27425 2.68165 3.13093 5.59931 4.36607 16 s - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.03044 3.90315 4.62550 0.61958 0.77255 0.55549 0.85282
+ 13 2.41396 4.26265 3.40226 2.93569 3.72492 3.24366 3.92462 2.93397 2.83929 2.73560 3.16052 3.25846 3.81309 3.20648 3.16819 2.37913 1.73294 2.65776 5.16309 3.91530 17 t - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.03044 3.90315 4.62550 0.61958 0.77255 0.55549 0.85282
+ 14 2.06589 4.14828 3.30608 3.02868 4.20053 2.92394 4.12227 3.52677 3.06750 3.27902 4.13704 3.22373 3.65849 3.38850 3.37961 1.31011 2.40891 3.04032 5.55736 4.32788 18 s - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.03044 3.90315 4.62550 0.61958 0.77255 0.55549 0.85282
+ 15 2.74009 4.29274 3.92243 3.42912 1.74599 3.72053 3.90473 2.32427 3.32349 2.18956 3.31553 3.65797 4.14118 3.57919 3.55745 2.71376 3.01017 2.38146 4.46330 2.97696 19 f - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.03044 3.90315 4.62550 0.61958 0.77255 0.55549 0.85282
+ 16 2.76094 4.39380 4.31945 3.75589 3.18422 4.12530 4.45889 2.01307 3.63847 1.30728 2.59228 4.05575 4.41925 3.86957 3.85970 3.43754 3.19324 1.94550 5.06650 3.93230 20 l - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.03044 3.90315 4.62550 0.61958 0.77255 0.55549 0.85282
+ 17 2.70295 4.73637 3.16526 2.68917 4.18427 3.37581 3.71759 3.61851 2.27125 3.18722 4.06871 3.11427 2.39752 2.89725 1.66361 2.77186 2.98335 3.28411 5.34221 4.10051 21 r - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.07762 3.90315 2.90945 0.61958 0.77255 0.55549 0.85282
+ 18 2.49055 4.81399 3.14505 2.59164 4.19520 3.44406 3.60132 3.55142 1.92611 3.12799 3.98038 3.04037 3.86298 2.75679 1.83484 2.76119 2.76042 3.23493 5.31169 4.06564 22 r - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.06501 3.85742 3.17445 0.61958 0.77255 0.59400 0.80322
+ 19 2.43450 4.81939 2.81703 2.39298 4.15804 3.33308 3.59871 3.56807 2.06609 3.14527 3.97247 2.89702 3.36070 2.29211 2.66793 2.54254 2.87166 3.22778 5.35034 4.03520 23 k - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.03294 3.82535 4.54770 0.61958 0.77255 0.61916 0.77305
+ 20 2.61608 4.67386 2.79167 2.51004 4.07010 3.23635 3.73836 3.55025 2.48903 3.13320 4.04098 2.97430 2.02723 2.34075 2.83811 2.68076 2.93097 3.21608 5.34739 4.03735 24 p - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.03294 3.82535 4.54770 0.61958 0.77255 0.51069 0.91649
+ 21 1.83080 4.22890 3.60014 3.08598 3.61014 3.38577 4.01761 2.55536 3.00939 2.52819 3.20189 3.39791 3.91288 3.33215 3.33591 2.72706 2.41446 2.12040 5.12303 3.89826 25 a - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.03044 3.90315 4.62550 0.61958 0.77255 0.55549 0.85282
+ 22 2.43845 4.29437 3.39983 3.04145 3.80350 3.19872 4.06195 2.96220 2.98493 2.76612 3.80233 3.32666 1.71751 3.35496 3.29387 2.63325 2.83846 2.21304 5.28839 4.02321 26 p - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.03044 3.90315 4.62550 0.61958 0.77255 0.55549 0.85282
+ 23 2.55648 4.28453 3.47615 2.92649 3.45346 3.51308 3.86072 2.37030 2.85167 2.40896 2.93550 3.31525 2.97437 3.17776 3.19434 2.79032 2.33896 2.42929 4.94762 3.71651 27 t - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.03044 3.90315 4.62550 0.61958 0.77255 0.55549 0.85282
+ 24 2.23005 4.31546 3.25841 2.77512 3.78441 3.22479 3.82985 3.12652 2.73582 2.83244 3.03171 3.14960 3.26067 3.07830 3.10838 1.85715 2.73859 2.81468 5.16957 3.91289 28 s - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.03044 3.90315 4.62550 0.61958 0.77255 0.55549 0.85282
+ 25 2.72216 3.51794 4.14734 3.58168 3.26953 3.85722 4.23682 2.10046 3.47012 1.71220 2.91412 3.83361 4.22096 3.71804 3.68973 3.16541 2.79579 1.71693 4.93656 3.75086 29 l - - -
+ 2.68606 4.42227 2.77522 2.73126 3.46337 2.40515 3.72497 3.29356 2.67743 2.69357 4.24692 2.90349 2.73742 3.18149 2.89784 2.37889 2.77522 2.98521 4.58479 3.61506
+ 0.31572 1.55442 2.82310 0.27619 1.42159 0.55549 0.85282
+ 26 2.06718 4.47388 3.00085 2.59301 4.03403 3.18938 3.75234 3.40130 2.21691 3.06406 3.90876 3.01767 3.74194 2.94856 2.91976 2.09488 2.60568 3.04014 5.32541 4.04568 31 a - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.03205 3.85226 4.57460 0.61958 0.77255 0.52495 0.89548
+ 27 2.09937 4.25808 3.35967 2.86682 3.65405 3.28224 3.85971 2.93650 2.81278 2.15397 3.59474 3.22143 3.43624 3.14697 3.16235 2.43009 2.43628 2.66078 5.07593 3.83686 32 a - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.03044 3.90315 4.62550 0.61958 0.77255 0.55549 0.85282
+ 28 2.56380 4.32380 3.45039 2.92280 3.52453 3.48960 3.88793 2.33272 2.83649 2.29194 3.45598 3.31192 2.56007 3.18425 3.18050 2.78603 2.52825 2.43071 5.02605 3.78340 33 l - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.03044 3.90315 4.62550 0.61958 0.77255 0.55549 0.85282
+ 29 2.52137 4.41862 3.18708 2.64701 3.24265 3.41116 3.70401 2.99879 2.50849 2.54033 3.56040 3.09794 3.19241 2.94883 3.00442 2.32271 2.53579 2.73855 5.01724 3.74765 34 s - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.03044 3.90315 4.62550 0.61958 0.77255 0.55549 0.85282
+ 30 2.00013 4.58033 2.94855 2.53646 4.07584 3.24271 3.72285 3.46598 2.50253 3.10366 3.94143 2.28591 3.76727 2.90505 2.65085 2.58556 2.61842 3.10852 5.34830 4.05040 35 a - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.03044 3.90315 4.62550 0.61958 0.77255 0.55549 0.85282
+ 31 2.38233 4.27978 3.41241 2.86526 3.23400 3.48475 3.81694 2.67786 2.81404 2.37039 3.42629 2.84230 3.90072 3.13098 3.17039 2.75440 2.50322 2.16090 4.92926 3.68461 36 v - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.03044 3.90315 4.62550 0.61958 0.77255 0.55549 0.85282
+ 32 2.57741 4.71210 2.95136 2.48036 4.10354 2.51445 3.64563 3.50876 2.11219 3.10615 3.93363 2.96219 3.79067 2.80786 2.54902 2.50592 2.51289 3.16566 5.32824 4.02677 37 k - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.03044 3.90315 4.62550 0.61958 0.77255 0.55549 0.85282
+ 33 2.48649 4.79372 2.91636 2.20828 4.05411 3.38774 3.59403 3.46081 2.32653 3.05709 3.87988 2.78811 3.79502 2.48988 2.50461 2.63652 2.83744 2.71303 5.28703 3.96685 38 e - - -
+ 2.68619 4.42226 2.77520 2.73124 3.46338 2.40514 3.72495 3.29355 2.67742 2.69356 4.24691 2.90348 2.73732 3.18147 2.89802 2.37888 2.77520 2.98519 4.58478 3.61504
+ 0.07101 2.83445 4.62550 0.63888 0.75053 0.55549 0.85282
+ 34 1.61247 4.12982 3.30077 3.01153 4.23531 2.30721 4.11812 3.64225 3.09602 3.33089 4.15414 3.20546 3.63382 3.37908 3.42786 1.71494 2.65404 3.10635 5.57312 4.35188 41 a - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.03044 3.90315 4.62550 0.61958 0.77255 0.55549 0.85282
+ 35 2.72153 4.23229 3.98871 3.42694 2.97156 3.37228 4.12428 2.11066 3.32720 1.56866 3.14804 3.72158 4.17041 3.58506 3.57523 3.10753 2.96236 2.01957 4.85619 3.63474 42 l - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.03044 3.90315 4.62550 0.61958 0.77255 0.55549 0.85282
+ 36 2.59948 4.33296 4.13320 3.58598 1.90470 3.92561 4.14661 2.31847 3.46961 1.74381 2.73954 3.84829 4.26638 3.69996 3.68809 3.23462 3.08833 2.27549 4.71854 3.39100 43 l - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.03044 3.90315 4.62550 0.61958 0.77255 0.55549 0.85282
+ 37 2.58931 4.58161 2.85848 2.66250 4.27569 1.35942 3.92193 3.72667 2.37699 3.36968 4.25453 3.08080 3.80217 3.15095 3.05968 2.68693 2.97358 3.32002 5.50315 4.25822 44 g - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.03044 3.90315 4.62550 0.61958 0.77255 0.55549 0.85282
+ 38 2.65443 4.41996 3.43781 2.92526 3.49579 3.52457 3.83449 2.83057 2.64507 1.65492 3.47551 3.30970 3.36731 3.12885 2.65176 2.85231 2.91346 2.65496 4.98654 3.73087 45 l - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.03044 3.90315 4.62550 0.61958 0.77255 0.55549 0.85282
+ 39 2.72350 4.79628 3.09209 2.60253 4.10688 3.43694 3.64699 3.48037 1.53491 2.80300 3.97997 3.05455 3.87955 2.81812 2.48623 2.53142 2.96661 3.17965 5.30004 4.01932 46 k - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.03044 3.90315 4.62550 0.61958 0.77255 0.55549 0.85282
+ 40 1.82674 4.13179 3.37396 3.04098 4.15468 2.93287 4.10316 3.48191 3.05943 3.22685 4.07364 3.23234 3.65478 3.36800 3.38156 1.54612 2.23418 3.00585 5.51189 4.29184 47 s - - -
+ 2.68618 4.42225 2.77520 2.73124 3.46354 2.40513 3.72495 3.29354 2.67741 2.69355 4.24690 2.90347 2.73740 3.18147 2.89801 2.37887 2.77520 2.98508 4.58477 3.61503
+ 0.07101 2.83445 4.62550 0.49418 0.94179 0.55549 0.85282
+ 41 1.87334 4.14690 3.25058 2.97809 4.26468 2.12605 4.11046 3.68104 3.08263 3.36184 4.18261 3.18779 3.63442 3.36584 3.42015 1.58161 2.66271 3.13490 5.59481 4.36766 49 s - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.11955 3.90315 2.38048 0.61958 0.77255 0.55549 0.85282
+ 42 2.21070 4.25592 3.22113 2.77420 3.85340 3.11965 3.84389 3.18555 2.74438 2.69874 3.77079 3.12117 3.16635 3.08826 3.10948 2.13243 2.17697 2.83916 5.22265 3.97074 50 s - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.03323 3.81683 4.53917 0.61958 0.77255 0.62561 0.76558
+ 43 2.34367 4.62113 3.10732 2.54725 3.88271 3.41056 3.61301 3.25335 2.12788 2.89080 3.32993 3.01581 3.81452 2.79680 2.35592 2.55841 2.82420 2.96607 5.15612 3.88260 51 k - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.07842 3.81683 2.92953 0.61958 0.77255 0.50642 0.92294
+ 44 2.82371 4.84862 3.20218 2.72371 4.21308 3.44211 3.65714 3.71157 2.07944 3.25434 4.14899 2.84303 3.91564 2.83614 1.36807 2.87376 3.07618 3.38687 5.31229 4.06004 52 r - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.12129 3.86316 2.37274 0.61958 0.77255 0.58934 0.80899
+ 45 2.50307 4.57358 2.77436 2.48515 4.13002 2.10145 3.72113 3.58708 2.48196 3.19739 4.04544 2.56817 3.72971 2.91621 2.54565 2.57756 2.84032 3.19983 5.38083 4.07634 53 g - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.03462 3.77648 4.49883 0.61958 0.77255 0.55399 0.85485
+ 46 2.68547 4.96255 2.09111 2.21584 4.36925 1.97687 3.70446 3.84410 2.62382 3.41713 4.25934 2.75900 3.76266 2.58919 3.12019 2.66938 2.98839 3.45462 5.60805 4.21173 54 g - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.03205 3.85226 4.57460 0.61958 0.77255 0.52495 0.89548
+ 47 2.70472 4.70735 3.22145 2.64799 3.96742 3.15410 3.63371 3.33902 2.12091 2.43520 3.82970 3.09240 3.88741 2.81708 1.91192 2.78290 2.92703 3.06076 5.19463 3.94224 55 r - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.03044 3.90315 4.62550 0.61958 0.77255 0.55549 0.85282
+ 48 2.39251 4.23853 3.75245 3.18839 3.35715 3.69117 4.01036 2.17738 3.07061 2.00722 3.28706 3.53429 4.07078 3.39072 3.07752 2.97399 2.89120 1.85844 4.92824 3.71532 56 v - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.03044 3.90315 4.62550 0.61958 0.77255 0.55549 0.85282
+ 49 2.56050 4.39105 3.34411 2.78319 3.60155 3.46480 3.77128 2.83822 2.62742 2.58594 3.21262 3.20237 3.88486 3.03059 2.56448 2.73642 2.19035 2.37832 5.02624 3.77891 57 t - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.03044 3.90315 4.62550 0.61958 0.77255 0.55549 0.85282
+ 50 1.37812 2.80072 3.83498 3.42070 3.87397 2.99921 4.24161 2.96530 3.32256 2.89459 3.81917 3.44880 3.71764 3.60422 3.56604 2.43360 2.40411 2.61888 5.33835 4.15246 58 a - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.03044 3.90315 4.62550 0.61958 0.77255 0.55549 0.85282
+ 51 2.74532 4.50724 3.42983 2.95244 3.42568 3.60626 3.88910 2.77026 2.70375 2.22807 1.95486 3.35569 4.02547 2.58121 2.99178 2.94186 2.99694 2.66631 5.01046 3.74777 59 m - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.03044 3.90315 4.62550 0.61958 0.77255 0.44450 1.02483
+ 52 0.87297 4.24657 3.57075 3.36786 4.15839 3.06811 4.37727 3.29971 3.38685 3.17640 4.19749 3.49040 3.81731 3.71861 3.62959 2.59634 2.88098 2.93600 5.57511 4.38724 60 a - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.02824 3.97705 4.69940 0.61958 0.77255 0.48576 0.95510
+ 53 1.96298 4.17134 3.43460 3.07855 4.14627 2.98936 4.12481 3.46945 3.08161 3.21642 4.06614 3.27556 3.70074 3.39215 3.40515 1.84467 1.63498 3.01250 5.50977 4.28998 61 t - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.02824 3.97705 4.69940 0.61958 0.77255 0.48576 0.95510
+ 54 3.40066 4.84720 3.99369 3.74344 2.30278 3.95279 3.67128 3.39553 3.59798 2.82228 4.05988 3.85394 4.42456 3.87882 3.75994 3.52665 3.68805 3.27113 3.95029 0.80817 62 y - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.02824 3.97705 4.69940 0.61958 0.77255 0.48576 0.95510
+ 55 2.86663 5.06853 2.87640 2.51952 4.45748 3.43879 3.66568 3.89866 1.33937 3.41664 4.27179 2.44223 3.91577 2.81805 2.46217 2.85914 3.10555 3.54515 5.50478 4.21799 63 k - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.02824 3.97705 4.69940 0.61958 0.77255 0.48576 0.95510
+ 56 2.89101 4.40561 4.26922 3.93641 3.62800 3.83108 4.72052 2.04974 3.80577 2.29743 3.57810 4.10920 4.38636 4.15841 4.00806 3.34183 3.25039 0.90272 5.42983 4.16757 64 v - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.02824 3.97705 4.69940 0.61958 0.77255 0.48576 0.95510
+ 57 2.78989 4.87427 3.10728 2.66228 4.33471 3.44160 3.70636 3.64306 1.30828 3.25641 4.14609 3.10047 3.92071 2.86764 2.46119 2.83588 2.59339 3.32217 5.44317 4.19498 65 k - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.02824 3.97705 4.69940 0.61958 0.77255 0.48576 0.95510
+ 58 3.28295 4.64373 4.65267 4.15432 2.12281 4.39226 4.40565 2.30868 4.01063 0.99404 2.96208 4.34589 4.63887 4.13687 4.14117 3.75853 3.51440 2.42033 4.68321 3.26182 66 l - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.02824 3.97705 4.69940 0.61958 0.77255 0.48576 0.95510
+ 59 3.08248 4.42168 4.72065 4.23378 3.50231 4.37831 4.95293 1.13074 4.10572 1.99571 3.31982 4.46032 4.70821 4.37869 4.30619 3.77127 3.35421 1.44848 5.47660 4.27063 67 i - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.02824 3.97705 4.69940 0.61958 0.77255 0.48576 0.95510
+ 60 2.47137 4.31634 3.52340 3.28135 4.06362 3.15188 4.29038 3.20358 3.22639 3.06334 4.10788 3.47324 3.86421 3.61618 3.47946 2.67390 1.00625 2.88730 5.49222 4.28053 68 t - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.02824 3.97705 4.69940 0.61958 0.77255 0.48576 0.95510
+ 61 2.89484 4.63395 3.51346 3.36817 4.35306 3.31558 4.43642 3.92611 3.43456 3.54133 4.59617 3.66397 0.65427 3.82016 3.66760 3.06578 3.34480 3.55944 5.51022 4.47541 69 P - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.02824 3.97705 4.69940 0.61958 0.77255 0.48576 0.95510
+ 62 2.83547 5.32344 1.90710 1.42799 4.63051 3.24198 3.71244 4.09996 2.65068 3.63347 4.46321 2.71732 3.81726 2.86723 3.20067 2.75440 2.81778 3.69487 5.81218 4.35094 70 e - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.02824 3.97705 4.69940 0.61958 0.77255 0.48576 0.95510
+ 63 2.79923 4.56350 3.49435 3.40744 4.54632 0.58454 4.52062 4.17205 3.60289 3.81287 4.79002 3.65874 3.95796 3.91884 3.82676 2.97427 3.28861 3.68020 5.61312 4.65200 71 G - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.02824 3.97705 4.69940 0.61958 0.77255 0.48576 0.95510
+ 64 2.69344 5.03834 2.59685 1.78499 4.35492 3.31996 3.63904 3.79867 2.33359 3.34661 4.15382 2.64678 2.71516 2.78054 2.89199 2.67010 2.77928 3.42501 5.53498 4.15652 72 e - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.02824 3.97705 4.69940 0.61958 0.77255 0.48576 0.95510
+ 65 2.70271 4.40317 3.56325 3.00957 3.45446 3.68235 3.94694 2.18180 2.88182 2.21283 3.37093 3.41883 4.05792 2.33611 3.21378 2.95204 2.94041 2.01647 5.02429 3.78732 73 v - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.02824 3.97705 4.69940 0.61958 0.77255 0.48576 0.95510
+ 66 3.04481 5.17464 2.53544 0.88540 4.53437 3.34332 3.94029 4.00914 2.83416 3.60986 4.58016 2.99593 3.95313 3.15433 3.25317 3.01711 3.35013 3.68253 5.68627 4.40959 74 e - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.02824 3.97705 4.69940 0.61958 0.77255 0.48576 0.95510
+ 67 3.05681 4.44153 4.54138 3.99838 1.97987 4.22221 4.40129 2.17878 3.87522 1.45215 3.02589 4.20160 4.50632 4.03401 4.02978 3.55251 3.29207 1.80812 4.80289 3.46847 75 l - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.02824 3.97705 4.69940 0.61958 0.77255 0.48576 0.95510
+ 68 2.82984 5.35567 1.99168 1.57663 4.64578 3.25717 3.68509 4.14274 2.58330 3.63869 4.45307 2.71724 3.81329 2.22362 3.11653 2.74299 3.09347 3.72626 5.79564 4.33600 76 e - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.02824 3.97705 4.69940 0.61958 0.77255 0.48576 0.95510
+ 69 2.50977 1.62448 4.23724 3.80750 3.60189 3.40590 4.45756 2.35254 3.63764 2.45765 3.57920 3.82230 4.04603 3.92585 3.81907 2.84633 2.91668 1.82275 5.24689 4.01880 77 c - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.02824 3.97705 4.69940 0.61958 0.77255 0.48576 0.95510
+ 70 2.77571 5.11398 2.10801 2.05696 4.45701 3.25620 3.72899 3.91339 2.64389 3.48166 4.32027 2.78446 1.86353 2.89484 3.15510 2.73789 3.05806 3.53410 5.67671 4.27030 78 p - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.02824 3.97705 4.69940 0.61958 0.77255 0.48576 0.95510
+ 71 2.91274 5.42662 1.24765 1.93231 4.73792 3.20738 3.76458 4.24169 2.78531 3.76893 4.62568 2.68636 3.83308 2.93581 3.37349 2.60161 3.20907 3.82383 5.94007 4.44265 79 d - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.02824 3.97705 4.69940 0.61958 0.77255 0.48576 0.95510
+ 72 2.93000 5.34144 1.08347 2.15883 4.66482 3.19912 3.82811 4.25255 2.88821 3.80850 4.69751 2.51974 3.85217 3.02158 3.46889 2.84580 3.25390 3.83179 5.90365 4.41772 80 d - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.02824 3.97705 4.69940 0.61958 0.77255 0.48576 0.95510
+ 73 2.89101 4.40561 4.26922 3.93641 3.62800 3.83108 4.72052 2.04974 3.80577 2.29743 3.57810 4.10920 4.38636 4.15841 4.00806 3.34183 3.25039 0.90272 5.42983 4.16757 81 v - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.02824 3.97705 4.69940 0.61958 0.77255 0.48576 0.95510
+ 74 3.40066 4.84720 3.99369 3.74344 2.30278 3.95279 3.67128 3.39553 3.59798 2.82228 4.05988 3.85394 4.42456 3.87882 3.75994 3.52665 3.68805 3.27113 3.95029 0.80817 82 y - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.02824 3.97705 4.69940 0.61958 0.77255 0.48576 0.95510
+ 75 3.08173 4.41570 4.73343 4.24332 3.51344 4.38931 4.96241 1.16063 4.11994 2.00857 3.32756 4.46929 4.71466 4.39012 4.32070 3.78014 3.35186 1.39369 5.48545 4.28088 83 i - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.02824 3.97705 4.69940 0.61958 0.77255 0.48576 0.95510
+ 76 3.27378 4.70553 4.35708 3.99825 3.17780 4.11433 4.62122 2.38848 3.76496 0.75643 3.16963 4.26355 4.53226 4.10824 3.92358 3.69863 3.56359 2.45281 5.09417 3.84135 84 l - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.02824 3.97705 4.69940 0.61958 0.77255 0.48576 0.95510
+ 77 3.10426 5.24570 0.77891 2.40498 4.63731 3.29196 4.02650 4.24977 3.13093 3.83985 4.82107 2.96628 3.95224 3.26642 3.66070 3.05541 3.44536 3.87811 5.78539 4.49402 85 d - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.02824 3.97705 4.69940 0.61958 0.77255 0.48576 0.95510
+ 78 2.10165 4.63153 3.04360 2.53313 3.37849 3.42468 3.14974 3.24484 2.48640 2.87927 3.73924 3.02051 3.83549 2.34761 2.89722 2.67591 2.83487 2.96227 5.11406 3.77860 86 a - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.02824 3.97705 4.69940 0.61958 0.77255 0.48576 0.95510
+ 79 0.87297 4.24657 3.57075 3.36786 4.15839 3.06811 4.37727 3.29971 3.38685 3.17640 4.19749 3.49040 3.81731 3.71861 3.62959 2.59634 2.88098 2.93600 5.57511 4.38724 87 a - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.02824 3.97705 4.69940 0.61958 0.77255 0.48576 0.95510
+ 80 3.04481 5.17464 2.53544 0.88540 4.53437 3.34332 3.94029 4.00914 2.83416 3.60986 4.58016 2.99593 3.95313 3.15433 3.25317 3.01711 3.35013 3.68253 5.68627 4.40959 88 e - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.02824 3.97705 4.69940 0.61958 0.77255 0.48576 0.95510
+ 81 3.04481 5.17464 2.53544 0.88540 4.53437 3.34332 3.94029 4.00914 2.83416 3.60986 4.58016 2.99593 3.95313 3.15433 3.25317 3.01711 3.35013 3.68253 5.68627 4.40959 89 e - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.02824 3.97705 4.69940 0.61958 0.77255 0.48576 0.95510
+ 82 2.02804 4.79412 2.56696 2.04470 4.09359 3.33689 3.67081 3.44631 2.51465 3.10781 3.94410 2.90500 3.80252 2.83547 2.98166 2.64658 2.87169 2.76307 5.37415 4.03168 90 a - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.02824 3.97705 4.69940 0.61958 0.77255 0.48576 0.95510
+ 83 2.79923 4.56350 3.49435 3.40744 4.54632 0.58454 4.52062 4.17205 3.60289 3.81287 4.79002 3.65874 3.95796 3.91884 3.82676 2.97427 3.28861 3.68020 5.61312 4.65200 91 G - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.02824 3.97705 4.69940 0.61958 0.77255 0.48576 0.95510
+ 84 2.73428 4.33692 3.73213 3.19478 3.16177 3.72868 2.92126 1.73180 3.00305 2.10225 3.32627 3.53324 4.10443 3.37488 3.27326 3.02489 2.97120 2.37844 4.75364 3.40581 92 i - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.02824 3.97705 4.69940 0.61958 0.77255 0.48576 0.95510
+ 85 2.98626 5.46880 1.08491 1.97249 4.77077 3.21550 3.81546 4.28421 2.87189 3.82944 4.72170 2.71026 3.86087 3.00007 3.46540 2.87647 3.29141 3.87860 5.96770 4.48798 93 d - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.02824 3.97705 4.69940 0.61958 0.77255 0.48576 0.95510
+ 86 3.27378 4.70553 4.35708 3.99825 3.17780 4.11433 4.62122 2.38848 3.76496 0.75643 3.16963 4.26355 4.53226 4.10824 3.92358 3.69863 3.56359 2.45281 5.09417 3.84135 94 l - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.02824 3.97705 4.69940 0.61958 0.77255 0.48576 0.95510
+ 87 2.89484 4.63395 3.51346 3.36817 4.35306 3.31558 4.43642 3.92611 3.43456 3.54133 4.59617 3.66397 0.65427 3.82016 3.66760 3.06578 3.34480 3.55944 5.51022 4.47541 95 P - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.02824 3.97705 4.69940 0.61958 0.77255 0.48576 0.95510
+ 88 3.48726 4.82741 4.35628 4.01269 1.82549 4.23514 3.48811 3.25093 3.87322 2.62544 3.87831 3.93991 4.57991 3.96204 3.99151 3.61127 3.72377 3.16284 3.67256 0.95290 96 y - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.02824 3.97705 4.69940 0.61958 0.77255 0.48576 0.95510
+ 89 2.36871 4.29005 3.29968 3.12112 4.18153 3.01810 4.22768 3.71868 3.20194 3.43114 4.34903 3.32859 3.76571 3.54324 3.48419 0.94365 2.85682 3.23083 5.54583 4.26583 97 s - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.02824 3.97705 4.69940 0.61958 0.77255 0.48576 0.95510
+ 90 2.70964 0.75093 4.25205 4.01610 3.98428 3.30982 4.64026 3.14621 3.84384 3.05665 4.18165 3.97525 4.02496 4.18572 3.94943 2.98138 3.18527 2.88356 5.37752 4.27103 98 c - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.02824 3.97705 4.69940 0.61958 0.77255 0.48576 0.95510
+ 91 3.12574 4.95602 3.62729 3.11760 4.33719 3.59265 3.90370 3.88680 2.28467 3.38377 4.38192 3.46899 4.09078 3.11945 0.82993 3.20529 3.38498 3.60641 5.37824 4.24257 99 r - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.02824 3.97705 4.69940 0.61958 0.77255 0.48576 0.95510
+ 92 0.87297 4.24657 3.57075 3.36786 4.15839 3.06811 4.37727 3.29971 3.38685 3.17640 4.19749 3.49040 3.81731 3.71861 3.62959 2.59634 2.88098 2.93600 5.57511 4.38724 100 a - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.02824 3.97705 4.69940 0.61958 0.77255 0.48576 0.95510
+ 93 2.79923 4.56350 3.49435 3.40744 4.54632 0.58454 4.52062 4.17205 3.60289 3.81287 4.79002 3.65874 3.95796 3.91884 3.82676 2.97427 3.28861 3.68020 5.61312 4.65200 101 G - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.02824 3.97705 4.69940 0.61958 0.77255 0.48576 0.95510
+ 94 2.36871 4.29005 3.29968 3.12112 4.18153 3.01810 4.22768 3.71868 3.20194 3.43114 4.34903 3.32859 3.76571 3.54324 3.48419 0.94365 2.85682 3.23083 5.54583 4.26583 102 s - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.02824 3.97705 4.69940 0.61958 0.77255 0.48576 0.95510
+ 95 2.70964 0.75093 4.25205 4.01610 3.98428 3.30982 4.64026 3.14621 3.84384 3.05665 4.18165 3.97525 4.02496 4.18572 3.94943 2.98138 3.18527 2.88356 5.37752 4.27103 103 c - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.02824 3.97705 4.69940 0.61958 0.77255 0.48576 0.95510
+ 96 2.36871 4.29005 3.29968 3.12112 4.18153 3.01810 4.22768 3.71868 3.20194 3.43114 4.34903 3.32859 3.76571 3.54324 3.48419 0.94365 2.85682 3.23083 5.54583 4.26583 104 s - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.02824 3.97705 4.69940 0.61958 0.77255 0.48576 0.95510
+ 97 2.36871 4.29005 3.29968 3.12112 4.18153 3.01810 4.22768 3.71868 3.20194 3.43114 4.34903 3.32859 3.76571 3.54324 3.48419 0.94365 2.85682 3.23083 5.54583 4.26583 105 s - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.02824 3.97705 4.69940 0.61958 0.77255 0.48576 0.95510
+ 98 2.70964 0.75093 4.25205 4.01610 3.98428 3.30982 4.64026 3.14621 3.84384 3.05665 4.18165 3.97525 4.02496 4.18572 3.94943 2.98138 3.18527 2.88356 5.37752 4.27103 106 c - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.02824 3.97705 4.69940 0.61958 0.77255 0.48576 0.95510
+ 99 0.87297 4.24657 3.57075 3.36786 4.15839 3.06811 4.37727 3.29971 3.38685 3.17640 4.19749 3.49040 3.81731 3.71861 3.62959 2.59634 2.88098 2.93600 5.57511 4.38724 107 a - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.02824 3.97705 4.69940 0.61958 0.77255 0.48576 0.95510
+ 100 2.79923 4.56350 3.49435 3.40744 4.54632 0.58454 4.52062 4.17205 3.60289 3.81287 4.79002 3.65874 3.95796 3.91884 3.82676 2.97427 3.28861 3.68020 5.61312 4.65200 108 G - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.02824 3.97705 4.69940 0.61958 0.77255 0.48576 0.95510
+ 101 3.06946 5.03551 3.25229 2.85531 4.44585 3.54670 3.82012 3.88188 0.90373 3.42461 4.38128 3.27486 4.04036 3.00629 2.45564 3.10509 3.31538 3.58407 5.45821 4.28639 109 k - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.02824 3.97705 4.69940 0.61958 0.77255 0.48576 0.95510
+ 102 3.06247 4.41039 4.65086 4.13598 3.48324 4.35915 4.85935 1.65561 4.00771 1.89605 3.31161 4.38665 4.67296 4.28428 4.22305 3.72759 3.32396 1.08186 5.42132 4.21018 110 v - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.02824 3.97705 4.69940 0.61958 0.77255 0.48576 0.95510
+ 103 2.33323 4.28075 3.53672 3.04537 3.62455 3.45748 3.98551 2.58410 2.72399 2.59228 3.55231 3.38781 3.95328 3.30102 3.25844 2.79290 2.46624 1.66085 5.10597 3.87716 111 v - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.02824 3.97705 4.69940 0.61958 0.77255 0.48576 0.95510
+ 104 2.09904 4.31904 3.13967 2.79512 4.23584 2.43802 3.97520 3.66080 2.88605 3.30435 4.12032 2.79615 3.70254 3.18983 3.27753 1.61859 2.49732 3.17574 5.54095 4.27688 112 s - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.02824 3.97705 4.69940 0.61958 0.77255 0.48576 0.95510
+ 105 2.79923 4.56350 3.49435 3.40744 4.54632 0.58454 4.52062 4.17205 3.60289 3.81287 4.79002 3.65874 3.95796 3.91884 3.82676 2.97427 3.28861 3.68020 5.61312 4.65200 113 G - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.02824 3.97705 4.69940 0.61958 0.77255 0.48576 0.95510
+ 106 2.34210 4.57052 2.98887 2.43186 3.63497 3.31233 3.71920 3.32573 2.57569 2.97882 3.82112 2.81207 3.79423 2.91349 3.00476 1.86229 2.69145 3.00524 5.25570 3.95436 114 s - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.02824 3.97705 4.69940 0.61958 0.77255 0.48576 0.95510
+ 107 3.05964 4.41092 4.64145 4.12759 3.48238 4.35054 4.85240 1.66963 3.99735 1.89738 3.31309 4.37857 4.66775 4.27653 4.21363 3.71953 3.32208 1.07763 5.41853 4.20516 115 v - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.02824 3.97705 4.69940 0.61958 0.77255 0.48576 0.95510
+ 108 2.91005 5.38045 1.25818 2.12941 4.69830 3.20228 3.78776 4.26304 2.81947 3.79137 4.65619 2.14323 3.83796 2.96707 3.40279 2.81725 3.21882 3.83565 5.91563 4.42054 116 d - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.02824 3.97705 4.69940 0.61958 0.77255 0.48576 0.95510
+ 109 2.96665 4.95377 2.97494 2.73211 4.13599 3.43683 3.89106 3.78353 2.54586 3.27542 4.30113 3.19246 3.99230 1.05904 2.82765 3.01035 3.26391 3.50694 5.38986 4.09082 117 q - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.02824 3.97705 4.69940 0.61958 0.77255 0.48576 0.95510
+ 110 2.64618 4.90499 2.31134 2.18942 4.30332 3.26131 3.70172 3.73572 2.57300 3.32434 4.14511 2.84177 3.78986 2.86174 3.06104 1.76618 2.63178 3.35922 5.54260 4.16860 118 s - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.02824 3.97705 4.69940 0.61958 0.77255 0.48576 0.95510
+ 111 3.10426 5.24570 0.77891 2.40498 4.63731 3.29196 4.02650 4.24977 3.13093 3.83985 4.82107 2.96628 3.95224 3.26642 3.66070 3.05541 3.44536 3.87811 5.78539 4.49402 119 d - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.02824 3.97705 4.69940 0.61958 0.77255 0.48576 0.95510
+ 112 2.73269 4.96873 2.61141 2.26957 4.35491 2.17303 3.70728 3.80016 2.46897 3.36392 4.20366 2.88233 3.83451 1.94009 2.87446 2.73151 3.00866 3.43365 5.54626 4.19876 120 q - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.02824 3.97705 4.69940 0.61958 0.77255 0.48576 0.95510
+ 113 2.56630 4.67539 2.76483 2.50324 4.25470 3.20379 3.80042 3.71196 2.47872 3.32135 4.15966 2.47516 3.79205 2.98884 3.00841 1.53662 2.90903 3.30833 5.51362 4.18451 121 s - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.02824 3.97705 4.69940 0.61958 0.77255 0.48576 0.95510
+ 114 3.45422 4.77029 4.46140 4.11213 1.01250 4.26302 3.55945 3.07075 3.96969 2.40922 3.69615 4.01237 4.59409 4.02617 4.05737 3.63979 3.68916 3.02613 3.73517 1.83750 122 f - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.02824 3.97705 4.69940 0.61958 0.77255 0.48576 0.95510
+ 115 3.27378 4.70553 4.35708 3.99825 3.17780 4.11433 4.62122 2.38848 3.76496 0.75643 3.16963 4.26355 4.53226 4.10824 3.92358 3.69863 3.56359 2.45281 5.09417 3.84135 123 l - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.02824 3.97705 4.69940 0.61958 0.77255 0.48576 0.95510
+ 116 2.92493 5.35887 1.12201 2.14550 4.68054 3.19834 3.81470 4.26138 2.86788 3.80711 4.68829 2.43062 3.84716 3.00361 3.45124 2.83676 3.24430 3.83759 5.91360 4.42201 124 d - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.02824 3.97705 4.69940 0.61958 0.77255 0.48576 0.95510
+ 117 2.99103 5.43832 1.04731 2.03422 4.75036 3.21916 3.83186 4.26509 2.89245 3.82288 4.72422 2.72815 3.86743 3.02108 3.48036 2.88767 3.30065 3.86474 5.95049 4.48470 125 d - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.05161 3.97705 3.45590 0.61958 0.77255 0.48576 0.95510
+ 118 2.86997 5.43069 1.57180 1.74614 4.72729 2.80306 3.71453 4.23943 2.69618 3.73332 4.56237 2.43722 3.80910 2.87126 3.27991 2.76596 3.14983 3.81040 5.89719 4.40314 126 d - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.02889 3.95434 4.67668 0.61958 0.77255 0.50828 0.92013
+ 119 2.94701 4.93449 2.95833 2.71460 4.11381 3.42085 3.87354 3.75736 2.52981 3.25157 4.27740 3.17495 3.97565 1.09531 2.81227 2.99143 3.24405 3.48203 5.37148 4.07074 127 q - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.02889 3.95434 4.67668 0.61958 0.77255 0.50828 0.92013
+ 120 2.77849 4.28259 3.99549 3.02221 3.34513 3.89873 4.21017 1.60238 3.32583 1.96055 3.04166 3.76188 4.24121 3.61775 3.59603 3.18793 3.01465 1.89778 5.01613 3.81900 128 i - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.02889 3.95434 4.67668 0.61958 0.77255 0.50828 0.92013
+ 121 2.05663 4.99383 2.42035 1.95337 4.30142 3.11016 3.64379 3.74448 2.38547 3.30891 4.11909 2.80952 3.78509 2.79112 2.97996 2.54099 2.92358 3.37653 5.51637 4.13250 129 e - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.02889 3.95434 4.67668 0.61958 0.77255 0.50828 0.92013
+ 122 2.37074 5.20065 2.03752 1.62561 4.52764 2.94012 3.68254 3.99698 2.59389 3.53203 4.34713 2.73405 3.79399 2.83254 3.13133 2.70217 3.03318 3.59496 5.71621 4.27884 130 e - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.02889 3.95434 4.67668 0.61958 0.77255 0.50828 0.92013
+ 123 2.76891 4.53595 3.45942 3.36936 4.50963 0.61326 4.48439 4.12940 3.56175 3.77320 4.74981 3.62373 3.92970 3.87945 3.78857 2.94321 3.25651 3.64192 5.58291 4.61439 131 G - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.02889 3.95434 4.67668 0.61958 0.77255 0.50828 0.92013
+ 124 3.45280 4.72560 4.55948 4.18538 1.45983 4.27876 3.45556 3.19175 4.01502 2.56322 3.77632 3.99268 4.58568 4.02082 4.06587 3.62371 3.67122 3.09770 1.76510 1.80304 132 f - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.02889 3.95434 4.67668 0.61958 0.77255 0.50828 0.92013
+ 125 2.87283 4.39315 4.23821 3.90420 3.61058 3.80809 4.69198 2.04849 3.77322 2.28363 3.56364 4.08078 4.36427 4.12727 3.97777 3.31702 3.23254 0.92773 5.40873 4.14528 133 v - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.02889 3.95434 4.67668 0.61958 0.77255 0.50828 0.92013
+ 126 3.24760 4.68579 4.32075 3.96132 3.16793 4.08580 4.59138 2.37683 3.72825 0.78064 3.16594 4.22883 4.50730 4.07699 3.89079 3.66669 3.53825 2.43535 5.07658 3.81868 134 l - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.02889 3.95434 4.67668 0.61958 0.77255 0.50828 0.92013
+ 127 2.45786 4.30296 3.50186 3.25812 4.04222 3.13941 4.26905 3.17937 3.20271 3.03994 4.08552 3.45408 3.84975 3.59352 3.45722 2.66008 1.04037 2.86556 5.47283 4.25897 135 t - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.02889 3.95434 4.67668 0.61958 0.77255 0.50828 0.92013
+ 128 2.68154 0.78852 4.21932 3.97783 3.95068 3.28696 4.60693 3.10838 3.80528 3.02007 4.14415 3.94300 4.00035 4.14805 3.91507 2.95331 3.15521 2.84739 5.34926 4.23772 136 c - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.02889 3.95434 4.67668 0.61958 0.77255 0.50828 0.92013
+ 129 2.02617 4.29048 3.42265 2.94627 3.54036 3.40652 3.31257 2.77872 2.86355 2.59741 3.53948 3.30371 3.90044 3.21666 3.18816 2.73904 2.82169 1.86270 5.00831 3.74432 137 v - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.02889 3.95434 4.67668 0.61958 0.77255 0.50828 0.92013
+ 130 0.90195 4.23400 3.54659 3.34205 4.13472 3.05626 4.35430 3.27256 3.36043 3.15035 4.17350 3.47069 3.80326 3.69417 3.60509 2.58374 2.86679 2.91280 5.55371 4.36315 138 a - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.02889 3.95434 4.67668 0.61958 0.77255 0.50828 0.92013
+ 131 3.44381 4.80306 4.30117 3.95207 1.85364 4.19548 3.48537 3.22033 3.81418 2.60484 3.85318 3.90681 4.54641 3.92239 3.94488 3.57229 3.68268 3.12961 3.68006 0.97942 139 y - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.02889 3.95434 4.67668 0.61958 0.77255 0.50828 0.92013
+ 132 2.86235 4.60578 3.47842 3.32948 4.31715 3.28867 4.39999 3.88386 3.39382 3.50174 4.55528 3.62780 0.68858 3.78012 3.62986 3.03247 3.31042 3.51987 5.48103 4.43903 140 P - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.02889 3.95434 4.67668 0.61958 0.77255 0.50828 0.92013
+ 133 2.60256 4.60991 3.08123 2.59418 3.90705 3.39886 3.69738 3.25085 2.27951 2.91739 3.78849 3.05676 3.84470 2.63540 2.79735 2.69573 1.94572 2.76699 5.21418 3.93668 141 t - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.02889 3.95434 4.67668 0.61958 0.77255 0.50828 0.92013
+ 134 2.16968 3.47307 3.59233 3.22260 4.15866 2.47411 4.19438 3.56363 3.18625 3.27458 4.10858 3.32406 3.66022 3.48496 3.48055 1.23700 2.65371 3.05043 5.52336 4.31592 142 s - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.02889 3.95434 4.67668 0.61958 0.77255 0.50828 0.92013
+ 135 3.07859 5.21813 0.80740 2.38838 4.60638 3.27362 4.00471 4.21341 3.10456 3.80732 4.78755 2.94873 3.93224 3.24424 3.63163 3.03196 3.41903 3.84400 5.75900 4.46621 143 d - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.02889 3.95434 4.67668 0.61958 0.77255 0.50828 0.92013
+ 136 2.87283 4.39315 4.23821 3.90420 3.61058 3.80809 4.69198 2.04849 3.77322 2.28363 3.56364 4.08078 4.36427 4.12727 3.97777 3.31702 3.23254 0.92773 5.40873 4.14528 144 v - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.02889 3.95434 4.67668 0.61958 0.77255 0.50828 0.92013
+ 137 2.50102 4.23694 3.76525 3.33965 3.72246 3.37067 4.24809 2.46042 3.23911 2.55924 3.64161 3.56053 3.97799 3.58142 3.52035 2.77764 1.69802 1.75863 5.30971 4.08018 145 t - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.02889 3.95434 4.67668 0.61958 0.77255 0.50828 0.92013
+ 138 3.09498 4.49149 4.45102 4.07022 3.43002 4.15408 4.78347 0.98199 3.89992 1.99977 3.35310 4.30411 4.57779 4.24002 4.08717 3.65761 3.39284 1.85079 5.33749 4.08258 146 i - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.02889 3.95434 4.67668 0.61958 0.77255 0.50828 0.92013
+ 139 3.02382 5.15051 2.52384 0.91441 4.50717 3.32764 3.92196 3.97736 2.81286 3.58149 4.55225 2.98104 3.93620 3.13613 3.22992 2.99812 3.32879 3.65289 5.66334 4.38601 147 e - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.02889 3.95434 4.67668 0.61958 0.77255 0.50828 0.92013
+ 140 2.45786 4.30296 3.50186 3.25812 4.04222 3.13941 4.26905 3.17937 3.20271 3.03994 4.08552 3.45408 3.84975 3.59352 3.45722 2.66008 1.04037 2.86556 5.47283 4.25897 148 t - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.02889 3.95434 4.67668 0.61958 0.77255 0.50828 0.92013
+ 141 3.08695 4.88934 3.20791 2.97643 3.34377 3.51816 0.98092 3.80251 2.81733 3.28606 4.33566 3.38232 4.07539 3.34383 3.07797 3.15699 3.39324 3.53609 4.80769 3.29239 149 h - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.02889 3.95434 4.67668 0.61958 0.77255 0.50828 0.92013
+ 142 2.99214 5.06805 3.26268 2.74531 4.47846 3.57206 3.65342 3.86981 1.12103 3.36156 4.25702 3.16311 3.99796 2.80635 2.11223 3.00404 3.19554 3.55761 5.42835 4.23089 150 k - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.02889 3.95434 4.67668 0.61958 0.77255 0.50828 0.92013
+ 143 3.02382 5.15051 2.52384 0.91441 4.50717 3.32764 3.92196 3.97736 2.81286 3.58149 4.55225 2.98104 3.93620 3.13613 3.22992 2.99812 3.32879 3.65289 5.66334 4.38601 151 e - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.02889 3.95434 4.67668 0.61958 0.77255 0.50828 0.92013
+ 144 2.49167 5.21869 2.13891 1.38935 4.54510 3.23855 3.71342 3.98470 2.64038 3.55288 4.39217 2.73628 3.81159 2.87379 3.17028 2.74234 3.08340 3.59770 5.74876 4.31122 152 e - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.02889 3.95434 4.67668 0.61958 0.77255 0.50828 0.92013
+ 145 2.67924 5.36825 1.81597 1.42545 4.67130 3.22067 3.71949 4.14895 2.68617 3.67868 4.51726 2.69278 3.81366 2.87890 3.25116 2.76699 3.13943 3.73938 5.85528 4.37934 153 e - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.02889 3.95434 4.67668 0.61958 0.77255 0.50828 0.92013
+ 146 3.24708 4.60677 4.69416 4.13988 3.08947 4.47063 4.76500 1.92492 3.96672 0.95356 2.71915 4.43331 4.67883 4.15873 4.13317 3.81764 3.47493 2.15974 5.15578 4.04247 154 l - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.02889 3.95434 4.67668 0.61958 0.77255 0.50828 0.92013
+ 147 2.69781 4.29649 3.84369 3.29786 3.44437 3.73086 4.15124 2.24231 3.19336 2.10104 3.11890 3.63278 4.14347 3.51043 3.49251 3.03876 2.03846 1.78833 5.07714 3.86271 155 v - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.18495 3.95434 1.89921 0.61958 0.77255 0.50828 0.92013
+ 148 1.44115 4.10304 3.22225 2.99375 4.15355 2.08176 4.10711 3.47540 3.09081 3.24183 4.11431 3.18864 3.61518 3.39097 3.39593 2.35434 2.65737 2.99565 5.50492 4.29375 156 a - - -
+ 2.68608 4.42226 2.77520 2.73124 3.46354 2.40513 3.72495 3.29355 2.67741 2.69355 4.24690 2.90347 2.73740 3.18147 2.89801 2.37887 2.77520 2.98519 4.58477 3.61504
+ 0.08120 2.55114 * 0.46726 0.98542 0.00000 *
+//
flexmark_css = utils/doc/github.css
channel_properties_dir = utils/channels
-
install4j_home_dir = ~/buildtools/install4j8
install4j_copyright_message = ...
install4j_bundle_id = org.jalview.jalview-desktop
OSX_KEYSTORE =
OSX_KEYPASS =
JSIGN_SH = echo
+
OSX_APPLEID =
OSX_ALTOOLPASS =
# these are used for actual .j2s file to pass on to alt j2s file
jalviewjs_j2s_settings = .j2s
jalviewjs_j2s_alt_file_property_config = j2s.config.altfileproperty
-
# for developing in Eclipse as IDE, set this to automatically copy current swingjs/net.sf.j2s.core.jar to your dropins dir
jalviewjs_eclipseIDE_auto_copy_j2s_plugin = false
# Override this in a local.properties file
<mapID target="alwCalc" url="html/menus/alwcalculate.html"/>
<mapID target="wsMenu" url="html/menus/wsmenu.html"/>
+ <mapID target="alwHmmer" url="html/menus/alwhmmer.html"/>
<mapID target="popMenu" url="html/menus/popupMenu.html"/>
<mapID target="popMenuAddref" url="html/menus/popupMenu.html#addrefannot"/>
<mapID target="annotPanelMenu" url="html/menus/alwannotationpanel.html"/>
<tocitem text="Colour Menu" target="alwColour" />
<tocitem text="Calculate Menu" target="alwCalc" />
<tocitem text="Web Service Menu" target="wsMenu" />
+ <tocitem text="HMMER Menu" target="alwHmmer" />
<tocitem text="Annotation Panel Menu" target="annotPanelMenu" />
<tocitem text="Popup Menu" target="popMenu" />
</tocitem>
<li>The <a href="#editing"><strong>"Editing"</strong>
Preferences</a> tab contains settings affecting behaviour when editing alignments.
</li>
+ <li>The <a href="#hmmer"><strong>"HMMER"</strong>
+ Preferences</a> tab allows you to configure locally installed HMMER tools.
+ </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>
<em>Sort with New Tree</em> - When selected, any trees calculated or
loaded onto the alignment will automatically sort the alignment.
</p>
+ <p>
+ <a name="hmmer"><strong>"HMMER" Preferences tab</strong></a>
+ </p>
+ <p>If you have installed HMMER tools (available from <a href="http://hmmerorg">hmmer.org</a>),
+ then you should specify on this screen the location of the installation (the path to the folder
+ containing binary executable programs). Double-click in the input field to open a file browser.</p>
+ <p>When this path is configured, the <a href="../menus/alwhmmer.html">HMMER menu</a> will be
+ enabled in the Alignment window.</p>
<p> </p>
<em>Web Services Preferences</em> - documentation for this tab is
given in the
--- /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>
+</head>
+<body>
+<p>
+ <strong>HMMER Menu</strong>
+</p>
+<p>This menu is available if hmmbuild tools have been installed and configured in the
+<a href="../features/preferences.html#hmmer">HMMER Preferences</a> panel.
+ <br><br>
+
+ <strong>hmmbuild</strong>
+ <br><br>Run hmmbuild to create a Hidden Markov Model profile of your sequence alignment or sub-groups.
+ <br><br>The consensus sequence for the computed profile is inserted as the first sequence of
+ the alignment (or group) for which hmmbuild is run.
+ <br>Jalview also computes and displays an annotation below the alignment, showing
+ the information content of each column.
+ <br>This is calculated as the sum over residue symbols of
+ <pre>
+ match emission probability * log(match emission probability / background frequency) / log(2)
+ </pre>
+ where the background frequencies are taken from (tbc: where? not https://www.ebi.ac.uk/uniprot/TrEMBLstats)
+ <ul>
+ <li>Edit settings and run...
+ <br><br>Choose whether to run hmmbuild for the whole alignment, or all or selected groups, or both
+ (default is the alignment).
+ <br>Optionally enter a name to give the HMM profile consensus sequence
+ (default is "Alignment" or group name, with "_HMM" appended).
+ <br>Use Reference Annotation: select this option if your alignment has an RF reference annotation,
+ and you wish to constrain the HMM profile to it (hmmbuild option '--hand').
+ <br><br></li>
+ <li>hmmbuild with default settings
+ <br><br>Runs hmmbuild for the whole alignment.</li>
+ </ul>
+
+ <strong>hmmalign</strong> and <strong>hmmsearch</strong> require an HMM consensus sequence to be selected first.
+ <br><em>To do this, right-click on the name of an HMM sequence added by hmmbuild, and 'Select HMM'.
+ The alignment will be with respect to the HMM profile for the consensus sequence.</em>
+ <br><br>
+ <strong>hmmalign</strong>
+ <br><br>Run hmmalign to align selected sequences (or the whole alignment) to a selected HMM profile.
+ <ul>
+ <li>Edit settings and run...
+ <br><br>Choose whether to 'trim non-matching termini' - hmmalign option '--trim'.
+ <br><br></li>
+ <li>hmmalign with default settings</li>
+ </ul>
+ <strong>hmmsearch</strong>
+ <br><br>Run hmmsearch to use an HMM profile as input to search a sequence database.
+ <ul>
+ <li>Edit settings and run...
+ <ul>
+ <li>tbc: choose database</li>
+ <li>tbc: automatically align</li>
+ <li>tbc: return accessions</li>
+ <li>tbc: number of results</li>
+ <li>tbc: sequence eValue cutoff</li>
+ <li>tbc: domains eValue cutoff</li>
+ </ul>
+ </li>
+ <br><li>hmmsearch with default settings</li>
+ <br><li>Add database
+ <br>Browse to select a local sequence data file to be searched</li>
+ </ul>
+<br>
+</body>
+</html>
-
<html>
<!--
* Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
</p>
<table border="1">
<tr>
- <th nowrap><a id="Jalview.$$Version-Rel$$"><em>Release</em></th>
+ <th nowrap><em>Release</em></th>
<th><em>New Features</em></th>
<th><em>Issues Resolved</em></th>
</tr>
<tr>
<td width="60" align="center" nowrap><strong><a
- id="Jalview.2.11.2">2.11.2</a><a id="Jalview.2.11.2.0">.0</a><br />
- <em>29/09/2021</em></strong></td>
- <td align="left" valign="top">
- <ul>
- <li><!-- --></li>
- </ul>
- <em>Development</em>
- <ul>
- <li>Updated building instructions</li>
- </ul></td>
- <td>
- <ul>
- <li>
- <!-- JAL-3840 -->Occupancy calculation is incorrect for
- alignment columns with over -1+2^32 gaps (breaking filtering
- and display)
- </li>
- <li>
- <!-- JAL-3833 -->Caps on Hi-DPI scaling to prevent crazy
- scale factors being set with buggy window-managers (linux
- only)
- </li>
- <li>
- <!-- JAL-3915 -->Removed RNAview checkbox and logic from Structure Preferences
- </li>
- </ul> <em>Development</em>
- <ul>
- <li>Fixed non-fatal gradle errors during build</li>
- </ul>
- </td>
- </tr>
- <tr>
- <td width="60" align="center" nowrap><strong><a
- id="Jalview.2.11.1">2.11.1</a><a id="Jalview.2.11.1.4">.4</a><br />
- <em>09/03/2021</em></strong></td>
- <td align="left" valign="top"><em>Improved control of
- Jalview's use of network services via jalview_properties</em>
- <ul>
- <li>
- <!-- JAL-3814 -->New .jalview_properties token controlling
- launch of the news browser (like -nonews argument)
- </li>
- <li>
- <!-- JAL-3813 -->New .jalview_properties token controlling
- download of linkout URLs from
- www.jalview.org/services/identifiers
- </li>
- <li>
- <!-- JAL-3812 -->New .jalview_properties token controlling
- download of BIOJSHTML templates
- </li>
- <li>
- <!-- JAL-3811 -->New 'Discover Web Services' option to
- trigger a one off JABAWS discovery if autodiscovery was
- disabled
- </li>
- </ul></td>
- <td align="left" valign="top">
- <ul>
- <li>
- <!-- JAL-3818 -->Intermittent deadlock opening structure in
- Jmol
- </li>
- </ul> <em>New Known defects</em>
- <ul>
- <li>
- <!-- JAL-3705 -->Protein Cross-Refs for Gene Sequence not
- always restored from project (since 2.10.3)
- </li>
- <li>
- <!-- JAL-3806 -->Selections from tree built from CDS aren't
- propagated to Protein alignment (since 2.11.1.3)
- </li>
- </ul>
- </td>
- </tr>
- <tr>
- <td width="60" align="center" nowrap><strong><a
- id="Jalview.2.11.1">2.11.1</a><a id="Jalview.2.11.1.3">.3</a><br />
- <em>29/10/2020</em></strong></td>
- <td align="left" valign="top">
- <ul>
-
- </ul>
- </td>
- <td align="left" valign="top">
- <ul>
- <li>
- <!-- JAL-3765 -->Find doesn't always highlight all matching
- positions in a sequence (bug introduced in 2.11.1.2)
- </li>
- <li>
- <!-- JAL-3760 -->Alignments containing one or more protein
- sequences can be classed as nucleotide
- </li>
- <li>
- <!-- JAL-3748 -->CDS alignment doesn't match original CDS
- sequences after alignment of protein products (known defect
- first reported for 2.11.1.0)
- </li>
- <li>
- <!-- JAL-3725 -->No tooltip or popup menu for genomic
- features outwith CDS shown overlaid on protein
- </li>
- <li>
- <!-- JAL-3751 -->Overlapping CDS in ENA accessions are not
- correctly mapped by Jalview (e.g. affects viral CDS with
- ribosomal slippage, since 2.9.0)
- </li>
- <li>
- <!-- JAL-3763 -->Spliced transcript CDS sequences don't show
- CDS features
- </li>
- <li>
- <!-- JAL-3700 -->Selections in CDS sequence panel don't
- always select corresponding protein sequences
- </li>
- <li>
- <!-- JAL-3759 --> <em>Make groups from selection</em> for a
- column selection doesn't always ignore hidden columns
- </li>
- </ul> <em>Installer</em>
- <ul>
- <li>
- <!-- JAL-3611 -->Space character in Jalview install path on
- Windows prevents install4j launching getdown
- </li>
- </ul> <em>Development</em>
- <ul>
- <li>
- <!-- JAL-3248 -->Fixed typos and specified compatible gradle
- version numbers in doc/building.md
- </li>
- </ul>
- </td>
- </tr>
- <tr>
- <td width="60" align="center" nowrap><strong><a
- id="Jalview.2.11.1">2.11.1</a><a id="Jalview.2.11.1.2">.2</a><br />
- <em>25/09/2020</em></strong></td>
- <td align="left" valign="top">
- <ul>
- </ul>
- </td>
- <td align="left" valign="top">
- <ul>
- <li>
- <!-- JAL-3757 -->Fresh install of Jalview 2.11.1.1 reports
- "Encountered problems opening
- https://www.jalview.org/examples/exampleFile_2_7.jvp"
- </li>
- </ul>
- </td>
- </tr>
- <tr>
- <td width="60" align="center" nowrap><strong><a
- id="Jalview.2.11.1">2.11.1</a><a id="Jalview.2.11.1.1">.1</a><br />
- <em>17/09/2020</em></strong></td>
- <td align="left" valign="top">
- <ul>
- <li>
- <!-- JAL-3638 -->Shift+arrow keys navigate to next gap or
- residue in cursor mode
- </li>
- <li>
- <!-- JAL-3695 -->Support import of VCF 4.3 by updating
- HTSJDK from 2.12 to 2.23
- </li>
- <li>
- <!-- JAL-3621 -->IntervalStore library updated to v.1.1:
- optimisations and improvements suggested by Bob Hanson and
- improved compatibility with JalviewJS
- </li>
- <li>
- <!-- JAL-3615 -->Retrieve GZipped stockholm formatted
- alignments from Pfam and Rfam
- </li>
- <li>
- <!-- JAL-2656 -->Recognise GZipped content for URLs and File
- import (no longer based on .gz extension)
- </li>
- <li>
- <!-- JAL-3570 -->Updated Spanish Translation for 2.11.1
- </li>
- <li>
- <!-- JAL-3692 -->Migrate EMBL record retrieval to use latest
- ENA Browser (https://www.ebi.ac.uk/ena/browser/home) and
- EMBL flat file
- </li>
- <li>
- <!-- JAL-3667 -->Improved warning messages, debug logging
- and fixed Retry action when Jalview encounters errors when
- saving or making backup files.
- </li>
- <li>
- <!-- JAL-3676 -->Enhanced Jalview Java Console:
- <ul>
- <li>Jalview's logging level can be configured</li>
- <li>Copy to Clipboard Buttion</li>
- </ul>
- </li>
- <li>
- <!-- JAL-3541 -->Improved support for Hi-DPI (4K) screens
- when running on Linux (Requires Java 11+)
- </li>
- </ul> <em>Launching Jalview</em>
- <ul>
- <li>
- <!-- JAL-3608 -->Configure Jalview Desktop's look and feel
- through a system property
- </li>
- <li>
- <!-- JAL-3477 -->Improved built-in documentation and command
- line help for configuring Jalview's memory
- </li>
- </ul>
- </td>
- <td align="left" valign="top">
- <ul>
- <li>
- <!-- JAL-3691 -->Conservation and Quality tracks are shown
- but not calculated and no protein or DNA score models are
- available for tree/PCA calculation when launched with
- Turkish language locale
- </li>
- <li>
- <!-- JAL-3493 -->Escape does not clear highlights on the
- alignment (Since Jalview 2.10.3)
- </li>
- <li>
- <!-- JAL-3680 -->Alt+Left or Right arrow in cursor mode
- doesn't slide selected sequences, just sequence under cursor
- </li>
- <li>
- <!-- JAL-3732 -->Alt+Up/Down in cursor mode doesn't move
- sequence under the cursor
- </li>
- <li>
- <!-- JAL-3613 -->Peptide-to-CDS tracking broken when
- multiple EMBL gene products shown for a single contig
- </li>
- <li>
- <!-- JAL-3696 -->Errors encountered when processing variants
- from VCF files yield "Error processing VCF: Format specifier
- '%s'" on the console
- </li>
- <li>
- <!-- JAL-3697 -->Count of features not shown can be wrong
- when there are both local and complementary features mapped
- to the position under the cursor
- </li>
- <li>
- <!-- JAL-3673 -->Sequence ID for reference sequence is
- clipped when Right align Sequence IDs enabled
- </li>
- <li>
- <!-- JAL-2983 -->Slider with negative range values not
- rendered correctly in VAqua4 (Since 2.10.4)
- </li>
- <li>
- <!-- JAL-3685 -->Single quotes not displayed correctly in
- internationalised text for some messages and log output
- </li>
- <li>
- <!-- JAL-3490 -->Find doesn't report matches that span
- hidden gapped columns
- </li>
- <li>
- <!-- JAL-3597 -->Resolved memory leaks in Tree and PCA
- panels, Alignment viewport and annotation renderer.
- </li>
- <li>
- <!-- JAL-3561 -->Jalview ignores file format parameter
- specifying output format when exporting an alignment via the
- command line
- </li>
- <li>
- <!-- JAL-3667 -->Windows 10: For a minority of users, if
- backups are not enabled, Jalview sometimes fails to
- overwrite an existing file and raises a warning dialog. (in
- 2.11.0, and 2.11.1.0, the workaround is to try to save the
- file again, and if that fails, delete the original file and
- save in place.)
- </li>
- <li>
- <!-- JAL-3750 -->Cannot process alignments from HTTPS urls
- via command line
- </li>
- <li>
- <!-- JAL-3741 -->References to http://www.jalview.org in
- program and documentation
- </li>
- </ul> <em>Launching Jalview</em>
- <ul>
- <li>
- <!-- JAL-3718 -->Jalview application fails when launched the
- first time for a version that has different jars to the
- previous launched version.
- </li>
- </ul> <em>Developing Jalview</em>
- <ul>
- <li>
- <!-- JAL-3541 -->Fixed issue with cleaning up old coverage
- data, causing cloverReport gradle task to fail with an
- OutOfMemory error.
- </li>
- <li>
- <!-- JAL-3280 -->Migrated the Jalview Version Checker to
- monitor the release channel
- </li>
- </ul> <em>New Known defects</em>
- <ul>
- <li>
- <!-- JAL-3748 -->CDS shown in result of submitting proteins
- in a CDS/Protein alignment to a web service is wrong when
- proteins share a common transcript sequence (e.g.
- genome of RNA viruses)
- </li>
- <li>
- <!-- JAL-3576 -->Co-located features exported and re-imported
- are ordered differently when shown on alignment and in
- tooltips. (Also affects v2.11.1.0)
- </li>
- <li>
- <!-- JAL-3702 -->Drag and drop of alignment file onto
- alignment window when in a HiDPI scaled mode in Linux only
- works for the top left quadrant of the alignment window
- </li>
- <li>
- <!-- JAL-3701 -->Stale build data in jalview standalone jar
- builds (only affects 2.11.1.1 branch)
- </li>
- <li>
- <!-- JAL-3127 -->Sequence ID colourscheme not re-applied
- when alignment view restored from project (since Jalview 2.11.0)
- </li>
- <li>
- <!-- JAL-3749 -->Duplicate CDS sequences are generated when
- protein products for certain ENA records are repeatedly
- shown via Calculate->Show Cross Refs
- </li>
- </ul>
- </td>
- </tr>
- <tr>
- <td width="60" align="center" nowrap><strong><a
id="Jalview.2.11.1">2.11.1</a><a id="Jalview.2.11.1.0">.0</a><br />
<em>22/04/2020</em></strong></td>
<td align="left" valign="top">
--- /dev/null
+0.2
+A
+200, -4.0, -3.8, -3.6, -3.4, -3.2, -3.0, -2.8, -2.6, -2.4, -2.2, -2.0, -1.8, -1.6, -1.4, -1.2, -1.0, -0.8, -0.6, -0.4, -0.2, 0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 2.8, 3.0, 3.2
+, 0.20369859505605942, 0.4222571919176904, 0.02232980369562049, 0.026676627662949624, 0.03525533903309387, 0.04787669271298644, 0.05605478196465866, 0.0641749787418314, 0.10286871806399077, 0.12105923035393054, 0.12422338883170829, 0.10304081214854802, 0.10333588151825282, 0.10114320874739426, 0.11812749552768892, 0.15006056120099137, 0.2237625777282616, 0.30253227447901293, 0.388557592836257, 0.43721427997253054, 0.47970928320880174, 0.5289808943443863, 0.5486523348637581, 0.5583247254358412, 0.5484761487937164, 0.5995060657240099, 0.6195991719342547, 0.6227297938639322, 0.6284738072714547, 0.5548992929945823, 0.5416658828311707, 0.5848669247143425, 0.5528051163252368, 0.6785332996776757, 0.5806004778403442, 0.18593167643573633, 0.38318927736500424
+400, -3.0, -2.8, -2.6, -2.4, -2.2, -2.0, -1.8, -1.6, -1.4, -1.2, -1.0, -0.8, -0.6, -0.4, -0.2, 0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 2.8
+, 0.00538163724710359, 0.050246851326647975, 0.00325623383324987, 0.016089404836314707, 0.004768961434464644, 0.012975554662909325, 0.014612779422905292, 0.036453046922170884, 0.03669851726847946, 0.06053063401623625, 0.07734802668205788, 0.14448615467437756, 0.24953322777140308, 0.34806276783515594, 0.4229567261622065, 0.4873077681738967, 0.5401722415436365, 0.5521510226102508, 0.6000517399892216, 0.6107765515229574, 0.5870927019689605, 0.6298630970573851, 0.6879023365675971, 0.6221611553796009, 0.632263810408655, 0.689461445849211, 0.6390236708841557, 0.7242036199282817, 0.6557168681820945, 0.21069080034931634
+600, -2.4, -2.2, -2.0, -1.8, -1.6, -1.4, -1.2, -1.0, -0.8, -0.6, -0.4, -0.2, 0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6
+, 0.009258546378795182, 0.022829316518316413, 0.022698074547786367, 0.012736836086937675, 0.016469563173777596, 0.01913720324613999, 0.03173961484046805, 0.04293589176349238, 0.08585848446208531, 0.16926121837954017, 0.293436232527367, 0.3543603601267507, 0.48651755499862337, 0.5103148855367983, 0.5876985421521675, 0.5784255879120095, 0.5938007169568057, 0.5598080715719793, 0.691548146841681, 0.6943388099375437, 0.6996541955589088, 0.7434201980299975, 0.8365119642131629, 0.9095567810750043, 0.5207569176305396, 0.7405911308670332
+800, -2.4, -1.8, -1.6, -1.4, -1.2, -1.0, -0.8, -0.6, -0.4, -0.2, 0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4
+, 0.008917934185414377, 0.01017895688795886, 0.037528784049424314, 0.02798827469166613, 0.03137703539242772, 0.11784556048768703, 0.11121306048524869, 0.20430912771074103, 0.2598593792958281, 0.4306348256035734, 0.46316119541365697, 0.5405314728294079, 0.539282096838667, 0.42055185929928385, 0.5448818087581953, 0.5997338164946914, 0.62308312092143, 0.7089840268242462, 0.6436353618329662, 0.826552573493094, 0.7908826508888537, 0.6905508284818629, 0.3823632872193804
+1000, -1.4, -1.2, -1.0, -0.8, -0.6, -0.4, -0.2, 0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2
+, 0.006152180116633862, 0.015427371964555698, 0.02331992788794896, 0.10944473717642993, 0.19333261931256743, 0.2004513811627833, 0.2384363292885486, 0.5272892625055869, 0.5168199037063749, 0.5652991338441917, 0.4397653398451027, 0.46013409044401904, 0.5175981692561336, 0.6704643484850927, 0.7969708452261104, 0.4745152293484279, 0.9101407067992686, 0.9288992619408138, 0.8325611428419273
+10000000, -1.2, -1.0, -0.8, -0.6, -0.4, -0.2, 0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 2.0
+, 0.0013574547186773595, 0.07926513808931503, 0.07102964878743583, 0.0726328476783432, 0.188665578230727, 0.4670863411106134, 0.6080090637275772, 0.44379833749922704, 0.5310140600224029, 0.5931610388683948, 0.4655146952326047, 0.7948299079449878, 0.45438605875039634, 0.7676093316330358, 0.5325662206236474, 0.5570031538223215
+Q
+200, -3.4, -3.2, -3.0, -2.8, -2.6, -2.4, -2.2, -2.0, -1.8, -1.6, -1.4, -1.2, -1.0, -0.8, -0.6, -0.4, -0.2, 0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 2.8, 3.0, 3.2, 3.4, 3.8
+, 0.030660402054098843, 0.029515962408728325, 0.01386298123421587, 0.03323790765774019, 0.050077081129415675, 0.029026658778299946, 0.04803400920855964, 0.046080800910896676, 0.05350762941049219, 0.07623076885791424, 0.07766677224262616, 0.12818678386245805, 0.13808429251771162, 0.15976782729500769, 0.18553311032498795, 0.21473885233239454, 0.26862488576858196, 0.3335898147114968, 0.3933292215057105, 0.4471255648270871, 0.5140106474150711, 0.5606446177282451, 0.56645579177951, 0.6187003826533546, 0.6264565231734968, 0.6902587142708823, 0.7310434998635741, 0.7404822151595194, 0.7455970773478046, 0.8194310136729327, 0.754028761152219, 0.6904665436774613, 0.7865490878301985, 0.8251017523682402, 0.25767625767590513, 0.09683794373033726
+400, -3.0, -2.8, -2.6, -2.4, -2.2, -2.0, -1.8, -1.6, -1.4, -1.2, -1.0, -0.8, -0.6, -0.4, -0.2, 0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 2.8, 3.0, 3.2, 3.4
+, 0.015174619218570292, 0.037092256738479906, 0.02807957626685945, 0.020952215954002592, 0.012490724790011861, 0.015060526993713729, 0.02337051753316606, 0.03585907871833321, 0.04997995343607782, 0.05116995577905059, 0.08421567659761686, 0.11469062311930732, 0.1729106310315939, 0.19279889620933457, 0.2305248874399254, 0.26979519803194807, 0.35005713230775476, 0.442197230272885, 0.5123688583661171, 0.5530137422740864, 0.5569824269831563, 0.5644003448573167, 0.5847125012080069, 0.6854939519416933, 0.7023668672066997, 0.7154562402783202, 0.7676568753108612, 0.8390636087066714, 0.8073438244745248, 0.7137044911123218, 0.7005129526561815, 0.660501122004602, 0.977346670748799
+600, -2.4, -2.2, -2.0, -1.8, -1.6, -1.4, -1.2, -1.0, -0.8, -0.6, -0.4, -0.2, 0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 2.8, 3.0, 3.2
+, 0.06409443044310832, 0.17043537478138396, 0.06708416589502411, 0.04885363429869391, 0.03348033250104629, 0.05051027800044158, 0.027081552065751212, 0.05641650262162609, 0.08745592321636787, 0.13269225526345627, 0.17856051100094275, 0.2604735522213605, 0.2257012643447686, 0.33727227847072533, 0.43694229465002715, 0.47575874028429543, 0.5515806648065332, 0.5766003713260374, 0.5333600150424079, 0.6251127815619932, 0.6323814616237637, 0.7636923593854934, 0.8150120235799707, 0.8554510812808985, 0.8528317416457601, 0.8932737202285638, 0.8996973853124699, 0.7504095750846632, 0.0782035688876777
+800, -1.8, -1.6, -1.4, -1.2, -1.0, -0.8, -0.6, -0.4, -0.2, 0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.6, 2.8, 3.0, 3.2
+, 0.008569761190854706, 0.01818566336086026, 0.0035886737075778684, 0.019557202027668318, 0.04730700327264522, 0.11713253719294132, 0.11747711101000212, 0.13566131005576462, 0.22173593877845912, 0.23226589196469324, 0.3285201642634684, 0.40175918428239643, 0.514273714962315, 0.6426839325030723, 0.5592607511903168, 0.4484374500207914, 0.4271084024627013, 0.5761775665904221, 0.7207597567939774, 0.8261386365447307, 0.9533012758522402, 0.9546438827372017, 0.9144745505555422, 0.5300797598551829, 0.3222227681422887
+1000, -1.0, -0.8, -0.6, -0.4, -0.2, 0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 3.0
+, 0.03406830709780076, 0.059250254494420895, 0.06295161152712787, 0.14778317919449488, 0.2052302207229962, 0.18103793431053206, 0.27419636115330304, 0.43791113182322405, 0.5014274959179482, 0.6332032204767004, 0.4625651540928214, 0.5822609669670592, 0.46439614255985395, 0.5769223811890896, 0.7117235531057876, 0.7830268783073607, 0.7662000487154872, 0.9574188255261584, 0.9791270764706063, 0.3459984609465178
+10000000, -1.2, -1.0, -0.8, -0.6, -0.4, -0.2, 0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.4
+, 0.011375782562223234, 0.015110412493978646, 0.025236652426745946, 0.08429389717841733, 0.14087146909054712, 0.11134410528964563, 0.7012573537893643, 0.6706932505976297, 0.36458107960413166, 0.4313977123835829, 0.5936455596283988, 0.6425632118499391, 0.5015729047474079, 0.692265646351462, 0.8633350923482849, 0.4146853327478658, 0.4854770135494893
+L
+200, -4.2, -4.0, -3.8, -3.6, -3.4, -3.2, -3.0, -2.8, -2.6, -2.4, -2.2, -2.0, -1.8, -1.6, -1.4, -1.2, -1.0, -0.8, -0.6, -0.4, -0.2, 0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 2.8, 3.0, 3.2
+, 0.022694200314865198, 0.04438120468049618, 0.2034621056438575, 0.09596674258314453, 0.0936871324670998, 0.14776469827002428, 0.13802184826675024, 0.13439766666587188, 0.04220458436568829, 0.16944536376489286, 0.11668704319818315, 0.10097026506035328, 0.13321742110406912, 0.1826244747204611, 0.24029848496689793, 0.27293725510554856, 0.3702265782860514, 0.39675970663839577, 0.3865827048643012, 0.4121574468469467, 0.42297029574231776, 0.42374694961798354, 0.45387310170747625, 0.4990958786276845, 0.5249310443913181, 0.5568838889388209, 0.5814034735034034, 0.5874918865708025, 0.544773016253518, 0.5740018578298114, 0.5921713379469711, 0.631807381420908, 0.7064114207808031, 0.7452793584039196, 0.5607075738856433, 0.6177654347620544, 0.2210712700377047, 0.0341445893559449
+400, -3.8, -3.6, -3.4, -3.2, -3.0, -2.8, -2.6, -2.4, -2.2, -2.0, -1.8, -1.6, -1.4, -1.2, -1.0, -0.8, -0.6, -0.4, -0.2, 0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6
+, 0.022810154959402515, 0.022810154959402515, 0.007720793314408286, 0.020949129787512125, 0.008085477457937203, 0.025751402801163902, 0.010533333633145176, 0.019532582257393728, 0.02675455267790389, 0.04368701982880921, 0.0642728570843146, 0.09326829811586024, 0.1600825548451298, 0.2628755953431343, 0.33349628915200696, 0.3715599414484014, 0.39048003188172026, 0.3639567373219425, 0.3686159885628984, 0.3815167578493698, 0.4323222079737531, 0.47570929722908906, 0.5414607289365889, 0.5729269739868003, 0.6300711763621937, 0.6385473260853091, 0.6476475561759117, 0.6476414812252087, 0.6798341599008929, 0.7011957467766897, 0.6072402235385015, 0.6366008002469443, 0.28404340538354134
+600, -3.0, -2.8, -2.6, -2.4, -2.2, -2.0, -1.8, -1.6, -1.4, -1.2, -1.0, -0.8, -0.6, -0.4, -0.2, 0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6
+, 0.004522531317523935, 0.005379331911902031, 0.041373584208902116, 0.06341550713400419, 0.00541136917154892, 0.024970967450366772, 0.01737419159452633, 0.02698710179147721, 0.10931342415377847, 0.16986739364325762, 0.3018235387326877, 0.3955846475210277, 0.36463488371059793, 0.35591519236678093, 0.33945447736638934, 0.3474316317416148, 0.40674510340538544, 0.45543036568909234, 0.5303127712434488, 0.5480395796161592, 0.6182397608837148, 0.6337199392749969, 0.6954318960326403, 0.7741570775389336, 0.7714912509580867, 0.8938303831713577, 0.8447712444019307, 0.6180977910562903, 0.09687554836070501
+800, -2.4, -2.2, -2.0, -1.8, -1.6, -1.4, -1.2, -1.0, -0.8, -0.6, -0.4, -0.2, 0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0
+, 0.00376740149279639, 0.008994324259810987, 0.011217681458643158, 0.01782829505291646, 0.06663319133607505, 0.10356871471685111, 0.22278722861655195, 0.42553503993613984, 0.36496033595587996, 0.3610925735058211, 0.3820858282736695, 0.4198207783566425, 0.4120354668294257, 0.41931435853443944, 0.3957678881854993, 0.530671191878201, 0.5316696899190078, 0.5311791062303839, 0.5776547205659004, 0.6069486624133318, 0.6843818658889624, 0.6689819508356897, 0.851214696227136
+1000, -1.6, -1.4, -1.2, -1.0, -0.8, -0.6, -0.4, -0.2, 0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8
+, 0.032368973346990515, 0.13969512844032048, 0.2276500581125476, 0.4431061395070267, 0.44559967376517107, 0.4080484956725524, 0.345312870981004, 0.5593329427588312, 0.3453546578106801, 0.39706278392354083, 0.4575762231727116, 0.5177464816296974, 0.47914956650885854, 0.5118580467178341, 0.6401841274969214, 0.6712200329105288, 0.6463117979877456, 0.42810448131912826
+10000000, -1.8, -1.6, -1.4, -1.2, -1.0, -0.8, -0.6, -0.4, -0.2, 0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6
+, 0.01782272397306565, 0.09395030002738014, 0.28736733981389734, 0.4610503140581492, 0.4504825574929253, 0.5433177175779089, 0.39843618244538137, 0.35264792682742047, 0.2477238149909607, 0.36972491007649827, 0.4492191259986524, 0.4335075346288497, 0.5333388835840573, 0.5258079002931256, 0.4621631821269529, 0.6088093248295579, 0.7590881193363881, 0.7903597389905895
+S
+200, -4.2, -4.0, -3.8, -3.6, -3.0, -2.8, -2.6, -2.4, -2.2, -2.0, -1.8, -1.6, -1.4, -1.2, -1.0, -0.8, -0.6, -0.4, -0.2, 0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 2.8, 3.0
+, 0.12438418712700766, 0.017446874253851875, 0.18519360573679758, 0.22124855285421674, 0.059752889119277716, 0.042504821227910966, 0.0663164525876336, 0.029121816870577095, 0.05492112929293922, 0.06720779941392006, 0.08127909407093194, 0.0560348871102672, 0.09659058156200162, 0.10353812840581252, 0.1210800822205396, 0.1562651703452635, 0.20319933061104634, 0.26245317523800094, 0.3369190441521257, 0.4095080052105503, 0.48191521218608413, 0.5284157963491289, 0.5606549634969592, 0.5950347464160363, 0.6187357500970652, 0.6470608094279561, 0.6356898770675693, 0.6714774329043008, 0.6121942241790169, 0.6095743971384333, 0.6564633462830982, 0.8280795031669954, 0.726251886423071, 0.7056292388804567, 0.6339622337745136
+400, -2.8, -2.6, -2.4, -2.2, -2.0, -1.8, -1.6, -1.4, -1.2, -1.0, -0.8, -0.6, -0.4, -0.2, 0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 2.8
+, 0.03629666034518226, 0.010251346587675996, 0.00588376225845094, 0.017103038428544992, 0.014167000294475663, 0.027002831996804307, 0.022073022212184695, 0.03815019381933721, 0.056348100149132954, 0.08949481882232799, 0.11963538365342391, 0.17229156999292647, 0.23102140894642761, 0.30799404180594553, 0.39670138039825537, 0.4994930747566133, 0.5572615383451857, 0.5696161186424068, 0.6158152862031046, 0.6439833627431268, 0.6519249573567936, 0.6333835930691046, 0.6961475696922559, 0.6193005635430306, 0.6552521049455082, 0.7202828580642087, 0.7532262221700042, 0.8334731780932044, 0.2368772002791371
+600, -2.8, -2.6, -2.4, -2.2, -2.0, -1.8, -1.6, -1.4, -1.2, -1.0, -0.8, -0.6, -0.4, -0.2, 0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 2.8
+, 0.013059399423161333, 0.24102871126123523, 0.01585339152122089, 0.028060159218492607, 0.026905462227703764, 0.04927252800462799, 0.03723841497717851, 0.02803294010626132, 0.03829902396434643, 0.06344601230608479, 0.057968769867864034, 0.10541929960012424, 0.19562626406778896, 0.27703475443325176, 0.41179023162123574, 0.5335069983729668, 0.5546150860338063, 0.5747348009876617, 0.5514881911764865, 0.6364965911968703, 0.6801059018570212, 0.6534703205286367, 0.5564196913416785, 0.7302176125008304, 0.8131069350450936, 0.8027519219958231, 0.6085485091562549, 0.8202839094617357, 0.405278218549064
+800, -2.4, -1.8, -1.6, -1.4, -1.2, -1.0, -0.8, -0.6, -0.4, -0.2, 0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6
+, 0.04216693629487124, 0.0043830307084839195, 0.014462196442335668, 0.01919041673092326, 0.01977825622316669, 0.023712744831969675, 0.055443290493752295, 0.08851448392127609, 0.11455256546377275, 0.2328694553482898, 0.3367326328850246, 0.459317221407433, 0.5879316224828962, 0.6470056873737324, 0.570650862440862, 0.7095801714949331, 0.706462120036267, 0.7170494260774206, 0.6295006361454005, 0.7778910581389612, 0.7148705132619393, 0.7592112207571959, 0.7482104188792188, 0.9522502952396771
+1000, -1.0, -0.8, -0.6, -0.4, -0.2, 0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0
+, 0.026214357205221576, 0.04427631406271417, 0.1264935961447764, 0.14077609356326534, 0.2960780435431137, 0.38160536439121107, 0.474947107253397, 0.5727918213213382, 0.6855543310528419, 0.6138913582635468, 0.5778692630210621, 0.6580943515434279, 0.6050444129262045, 0.6168509337333394, 0.8288146290440119, 0.6657847422198185
+10000000, -1.6, -1.4, -1.2, -1.0, -0.8, -0.6, -0.4, -0.2, 0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.2
+, 0.027142096860031932, 0.013757755597518209, 0.0227211975407645, 0.05284974093264248, 0.048659901118917506, 0.16142942336804442, 0.12657774238502886, 0.26692784650029305, 0.3779063407756724, 0.643762567432302, 0.49130042503233945, 0.7242627649143978, 0.6783062480117502, 0.6304716291654356, 0.7038812933324693, 0.9237125448626993, 0.620579612380977, 0.6038819322983577, 0.4726479391294941
+R
+200, -4.0, -3.8, -3.6, -3.4, -3.2, -3.0, -2.8, -2.6, -2.4, -2.2, -2.0, -1.8, -1.6, -1.4, -1.2, -1.0, -0.8, -0.6, -0.4, -0.2, 0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 2.8, 3.0, 3.2, 3.4, 3.6
+, 0.03207726503553209, 0.005274482832016623, 0.02353481066931443, 0.01858536618468486, 0.029482970704681824, 0.029822145312603715, 0.03156800848371642, 0.030513654789762576, 0.04606365662704011, 0.04081943283545797, 0.05812095484759577, 0.07558217960358522, 0.08275712090661415, 0.09765221787115734, 0.13423340776679776, 0.1489303205649009, 0.2101302968591223, 0.241768086761866, 0.28003078459011693, 0.3620682642630574, 0.41228413694312804, 0.4842228134280171, 0.5208837054055414, 0.5601867659345883, 0.5971129002888642, 0.5931505256179169, 0.6398668937991495, 0.6522501064755667, 0.6681713881294856, 0.6631087700660413, 0.6581604871860909, 0.6224264678321053, 0.6767846770830652, 0.6536296591076727, 0.47393142233152774, 0.6996554390188527, 0.5687643264275022, 0.6981446635867379, 0.4736078327732734
+400, -3.4, -3.0, -2.8, -2.6, -2.4, -2.2, -2.0, -1.8, -1.6, -1.4, -1.2, -1.0, -0.8, -0.6, -0.4, -0.2, 0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 2.8, 3.0, 3.2, 3.4, 3.6
+, 0.06120237498398166, 0.041651302875030785, 0.005403336877600516, 0.005329713060580334, 0.014009522483041804, 0.030143197221196488, 0.030445491091082598, 0.029049177244755166, 0.04466300930040355, 0.02959186639672202, 0.07858217329768569, 0.10613250573098461, 0.13756433589801076, 0.1753766185741036, 0.24220992595864874, 0.3379268214752498, 0.43933847181192914, 0.4687608305155847, 0.5219843880663324, 0.5378031723967835, 0.5885073150547451, 0.5790215715229141, 0.6033105062790582, 0.6369385345570912, 0.6367438494487759, 0.6442980558476543, 0.7448119005362304, 0.6787320027676245, 0.7192587968629324, 0.6923730973665412, 0.5134331453351957, 0.5810559726136121, 0.5684926350975337, 0.6125402492396689, 0.9289869625201223
+600, -3.0, -2.8, -2.6, -2.4, -2.2, -2.0, -1.8, -1.6, -1.4, -1.2, -1.0, -0.8, -0.6, -0.4, -0.2, 0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 2.8, 3.0, 3.2, 3.4
+, 0.1378365503565375, 0.050594717687005665, 0.12781834109421955, 0.08752773884720516, 0.049670070100221224, 0.07664827304436632, 0.046105225891738925, 0.02153118141988729, 0.03233228014945535, 0.0604699995627281, 0.053891025109674896, 0.06548772677419284, 0.15524097503420448, 0.20322318539844983, 0.2685506473941544, 0.3672922083066144, 0.4728367869025848, 0.5215150279053673, 0.5827726312548501, 0.5019429810469788, 0.6236707269413359, 0.6381821952554616, 0.5617610775185542, 0.6050454853873801, 0.6781155911224431, 0.6977041177757346, 0.7921057139590649, 0.6326622936336238, 0.8560845234345356, 0.8638521228076326, 0.9234678570523027, 0.5228541729414256, 0.7057173072099404
+800, -2.0, -1.8, -1.6, -1.4, -1.2, -1.0, -0.8, -0.6, -0.4, -0.2, 0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 2.8
+, 0.012317541353916594, 0.006880746923185741, 0.0018860052516560708, 0.09200540112678679, 0.03267249789183022, 0.07654308724863221, 0.13111551917418324, 0.11110315232892057, 0.2858352233385768, 0.3183838804941956, 0.3214764152349552, 0.5381027132381613, 0.5154858992781721, 0.5938759396466544, 0.5317669156056538, 0.474571014220306, 0.6656176259936978, 0.4470667687414132, 0.5694015228099887, 0.5721682279897327, 0.8456605579912806, 0.6845196622874592, 0.701356537506164, 0.9379461680382511, 0.47849324750243555
+1000, -1.4, -1.2, -1.0, -0.8, -0.6, -0.4, -0.2, 0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 2.8, 3.0
+, 0.03673099779274436, 0.05975508700856275, 0.11729622266401589, 0.07431155893971492, 0.20129024254078534, 0.4122602456482906, 0.6700041328568925, 0.4307533654784136, 0.43106406500951033, 0.4362086337224014, 0.4358870724581107, 0.5947155769405055, 0.5170772477786677, 0.6550101981782633, 0.42172408225949354, 0.6801152737752161, 0.5717836886325366, 0.8028045185803616, 0.5636513233075834, 0.32157261133978665, 0.7451205510907003, 0.25624149496885484, 0.030797703222132593
+10000000, -1.4, -1.2, -1.0, -0.8, -0.6, -0.4, -0.2, 0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.8
+, 0.0062919463087248335, 0.024701523260601082, 0.2840737382895135, 0.0578473552912253, 0.07021063189568708, 0.436086646036658, 0.5269060018126795, 0.3787509834038887, 0.4402173913043479, 0.578105949559571, 0.6284310137501962, 0.7335907335907337, 0.45416143979928836, 0.7206038447930181, 0.9030250931270212, 0.6380443086325439, 0.7962851491959756, 0.7771192021827078, 0.4714806276492899, 0.3111369584181448, 0.5469497035762096
+E
+200, -4.4, -4.0, -3.8, -3.6, -3.4, -3.2, -3.0, -2.8, -2.6, -2.4, -2.2, -2.0, -1.8, -1.6, -1.4, -1.2, -1.0, -0.8, -0.6, -0.4, -0.2, 0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 2.8, 3.0, 3.2, 3.4, 3.8
+, 0.009621440371994583, 0.004146270499067931, 0.027007253515549435, 0.03136727179124811, 0.038744876752604566, 0.016229285222223038, 0.03822370326896233, 0.03570001601652651, 0.04401784840638429, 0.05086975856820555, 0.07644960546391222, 0.06614806173185703, 0.061318793235008814, 0.10185835962162645, 0.1450144368887007, 0.1425492047876539, 0.20799587783194384, 0.19641586610839798, 0.2043744860695266, 0.2275087023393559, 0.2756277828898441, 0.3308814934337169, 0.4129586159308165, 0.48035942769144885, 0.5342480296805483, 0.5657700139485319, 0.6110696594264812, 0.6158626562381674, 0.6120291915122046, 0.6455192674095419, 0.6780413894925083, 0.6495724311929135, 0.6361403433588055, 0.7950927440077705, 0.5949832111286862, 0.37058920504165416, 0.3524209038075929, 0.5271389454687425, 0.7803589040683762, 0.47464831353328946
+400, -3.4, -3.2, -3.0, -2.8, -2.6, -2.4, -2.2, -2.0, -1.8, -1.6, -1.4, -1.2, -1.0, -0.8, -0.6, -0.4, -0.2, 0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 2.8, 3.0, 3.2, 3.4, 3.6
+, 0.017589676152591112, 0.06683204264988173, 0.01657213629129284, 0.00332003136981703, 0.00930518388267171, 0.005974036257469811, 0.017903762602890994, 0.03761496143931975, 0.03408447798140072, 0.07714241431466798, 0.10029575266470864, 0.09561574949799023, 0.14597655312457017, 0.15454703000082912, 0.17666151890870305, 0.18425024121949826, 0.20492924164637813, 0.27328431284733345, 0.35372364617784047, 0.45535119003288305, 0.5450906270210514, 0.5819563761275088, 0.6164230496799653, 0.6272027332867812, 0.6065517245120872, 0.5779706100641258, 0.6540444997527108, 0.5860082895169939, 0.6757729762046188, 0.5782390265906364, 0.6483029111399775, 0.7238765375054353, 0.8145822355514108, 0.38720430152211993, 0.29944373638984595, 0.26181929584821206
+600, -2.6, -2.4, -2.2, -2.0, -1.8, -1.6, -1.4, -1.2, -1.0, -0.8, -0.6, -0.4, -0.2, 0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 2.8, 3.0, 3.2, 3.4, 3.6
+, 0.053283575664541366, 0.03616471216877128, 0.06326608218206026, 0.011131203387245636, 0.028527095216323052, 0.014063364780183754, 0.045519433969399455, 0.10546598100346138, 0.14949350502179756, 0.15101877591261562, 0.09738810031195794, 0.13481415571820254, 0.14257886566448752, 0.2860309312905558, 0.3680760044864281, 0.4681448135606153, 0.5807334464914079, 0.5840788193716014, 0.5684825986445871, 0.5423637974395175, 0.6322784178809525, 0.5910884453929658, 0.4403967228080618, 0.7715571363898848, 0.6055828711644718, 0.7943209953485183, 0.44098092121701576, 0.8394721618942949, 0.771295161426513, 0.28710576355040146, 0.07682020988610647, 0.011131203387245636
+800, -2.4, -2.2, -2.0, -1.8, -1.6, -1.4, -1.2, -1.0, -0.8, -0.6, -0.4, -0.2, 0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6
+, 0.03430651347512906, 0.01170316774637141, 0.02172101047389925, 0.006417685703626693, 0.008803131942231902, 0.02558597050998453, 0.07306274568825875, 0.11280115830989065, 0.09350632912488134, 0.19757784784170848, 0.13668996284243146, 0.10109885106932971, 0.21372922331058639, 0.33935195047966055, 0.4835653244772779, 0.5933154629689057, 0.5389606803781795, 0.5486205951197954, 0.6256878350116513, 0.4954150416424488, 0.6982028550061831, 0.7725732080733803, 0.7556245509596634, 0.820419992617725, 0.3871956296488177, 0.21161330536631878
+1000, -1.2, -1.0, -0.8, -0.6, -0.4, -0.2, 0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4
+, 0.007075408536552707, 0.052106342694856415, 0.054267687080583535, 0.11138738604476046, 0.18238487903712933, 0.13756590467213264, 0.20171268632711103, 0.3204675946135979, 0.4939881373188593, 0.48725191860865325, 0.4577231292051552, 0.5029274757637503, 0.5911749097279292, 0.617890908127232, 0.6754028092464903, 0.7538926271666511, 0.7790160448683208, 0.9317881518423954, 0.2815681472036956
+10000000, -1.2, -0.8, -0.6, -0.4, -0.2, 0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6
+, 0.05348182058279778, 0.033963789927669706, 0.16707500121047786, 0.16511036477645546, 0.17236127301119492, 0.10153344754105208, 0.5210622228521675, 0.5405779170203302, 0.6467331482363765, 0.5613844499745355, 0.4960746174216681, 0.6196549070937729, 0.5823067577399326, 0.6626260661097897, 0.3857996700919029, 0.2655828409440213, 0.7804169453620828, 0.6799529670918482, 0.14494194369333543
+K
+200, -4.2, -4.0, -3.8, -3.6, -3.4, -3.2, -3.0, -2.8, -2.6, -2.4, -2.2, -2.0, -1.8, -1.6, -1.4, -1.2, -1.0, -0.8, -0.6, -0.4, -0.2, 0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 2.8, 3.0, 3.2, 3.4, 3.8, 4.0
+, 0.006233425622353032, 0.030408921119546396, 0.02093592220185473, 0.03558424628095059, 0.010346048488097845, 0.005378266919520889, 0.03131994736626652, 0.028487448042530204, 0.03379094987238925, 0.024700449398553797, 0.03347424071928632, 0.07302434835089781, 0.073512659195887, 0.09610703764665972, 0.10795809398583348, 0.12494848067773846, 0.15366097022715058, 0.19623704670279507, 0.20948968747096094, 0.24338255490000843, 0.2906241049173688, 0.33876574586758207, 0.4184822248111851, 0.47928225866895335, 0.5290089476862202, 0.5603050017954271, 0.5786006171900762, 0.5901574708056799, 0.6223281637221282, 0.628128623412185, 0.5921857112354082, 0.6140101201683108, 0.5920359569841578, 0.5965921083365542, 0.6087237791828294, 0.4924534069623098, 0.38684136208760095, 0.8267798205668004, 0.052443291913803605, 0.13555614153669435, 0.4949704158969042
+400, -3.2, -3.0, -2.8, -2.6, -2.4, -2.2, -2.0, -1.8, -1.6, -1.4, -1.2, -1.0, -0.8, -0.6, -0.4, -0.2, 0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 2.8, 3.0, 3.2, 3.4, 3.6, 3.8, 4.0, 4.6
+, 0.020798610371752655, 0.005632200186423676, 0.020798610371752648, 0.017012541269074165, 0.006032073496491691, 0.01364226026152598, 0.021143675648025915, 0.01868251927506294, 0.025685901851698386, 0.05158053569829252, 0.06125362327569112, 0.10431760125648461, 0.11657963235000496, 0.16124223048718866, 0.16595610614723216, 0.20943134871276328, 0.2710357434275307, 0.3346119224884066, 0.4332968718252851, 0.5110259226245114, 0.5749134438517876, 0.6081320558919092, 0.5874087675618509, 0.6035394962722405, 0.6231341763893807, 0.5835358073444723, 0.5961581174202724, 0.5709563638636703, 0.5779902811937659, 0.6074718329071743, 0.659698021432162, 0.5065478271339936, 0.8797381245584289, 0.7417154908480318, 0.44066114867280576, 0.3040791284756775, 0.15208479719465084, 0.0783083282618651
+600, -2.6, -2.4, -2.2, -2.0, -1.8, -1.6, -1.4, -1.2, -1.0, -0.8, -0.6, -0.4, -0.2, 0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 2.8, 3.0, 3.2, 3.4, 3.6
+, 0.08005202718154787, 0.04962009188671522, 0.039406216500345155, 0.002740406190104946, 0.011403405751254717, 0.0028098082516713977, 0.0071633756207432455, 0.03306075603501498, 0.0646831514898025, 0.11569513004064116, 0.13990454263335425, 0.17679877588621143, 0.16262258352799974, 0.1706813596201359, 0.2931339965678484, 0.43799455936872084, 0.5507332991803784, 0.6083433873274956, 0.6506958124282605, 0.5950317952941324, 0.5577837159753122, 0.6396812143891745, 0.6025343792533054, 0.41729136641693454, 0.5159270205746278, 0.550689666206242, 0.6076331037708719, 0.5624524359539496, 0.6696235241307377, 0.8959934752809087, 0.07262822815281679, 0.13051495642939867
+800, -2.2, -1.8, -1.6, -1.4, -1.2, -1.0, -0.8, -0.6, -0.4, -0.2, 0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 2.8, 3.0
+, 0.018911760605919804, 0.004795965261657025, 0.045975193728396195, 0.008989657476380065, 0.017318826511208574, 0.025057718947206414, 0.12261710593295176, 0.11213161725895983, 0.19187686131466689, 0.14188715644056538, 0.14546530966094284, 0.31206534648850154, 0.47086768089542014, 0.545789218740381, 0.5885204739595565, 0.5773710383535828, 0.46045973024930353, 0.5908802815580871, 0.626959762836653, 0.6316980119840698, 0.664414162678641, 0.79310547563987, 0.33278822567457084, 0.7061514195583597, 0.15356389927792902, 0.054667562122229715
+1000, -0.8, -0.6, -0.4, -0.2, 0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6
+, 0.02052890441228883, 0.04023189215617797, 0.07663031858028652, 0.20025096556556882, 0.18400997644450603, 0.18611930275336508, 0.21527083749750153, 0.3970930399563381, 0.4481132941803083, 0.5686396636354857, 0.5301579703207275, 0.621978803891937, 0.7140332311751852, 0.6286470990555741, 0.6377560435504707, 0.7720935141696131, 0.8320930630399452, 0.3946962688868332
+10000000, -1.0, -0.8, -0.6, -0.4, -0.2, 0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.6
+, 0.01260629568849769, 0.01879100107483044, 0.09267256151895265, 0.04568967070994719, 0.09962589275592335, 0.11544315827770806, 0.28789943693289816, 0.2591618348295238, 0.3929734264526971, 0.39127635602768385, 0.5935754756602113, 0.6145883983450332, 0.3876823250131941, 0.6618930447590909, 0.6606724003127443, 0.5138853185066581, 0.5624084011945034
+T
+200, -3.8, -3.6, -3.4, -3.2, -3.0, -2.8, -2.6, -2.4, -2.2, -2.0, -1.8, -1.6, -1.4, -1.2, -1.0, -0.8, -0.6, -0.4, -0.2, 0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 2.8, 3.0
+, 0.008187665742003893, 0.028861201409083426, 0.00980913610487576, 0.1083985994398448, 0.0598706444724795, 0.05947128234147885, 0.16040484993339152, 0.09915598512252316, 0.10446723349172699, 0.1200298989675841, 0.15094705758522858, 0.1328601676913035, 0.07572629791473424, 0.12872358724292082, 0.14537735848143038, 0.18757394078969675, 0.20983017792030184, 0.2754583875906324, 0.3381900390309666, 0.40271265447333354, 0.4729359584475696, 0.5373178412824395, 0.5595641713342255, 0.6104980864110142, 0.6378975434547939, 0.6441654366086963, 0.6732334439933628, 0.666053356346672, 0.6774517895349775, 0.6637156928572294, 0.606772055426944, 0.6491227745638032, 0.6968486954506264, 0.6098259501108972, 0.6265547114255277
+400, -3.0, -2.6, -2.4, -2.2, -2.0, -1.8, -1.6, -1.4, -1.2, -1.0, -0.8, -0.6, -0.4, -0.2, 0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 2.8, 3.0
+, 0.0027025687608381557, 0.004064194112156794, 0.0016032875228119338, 0.009757997483425634, 0.007868980509490626, 0.007607238389344213, 0.02595046601655586, 0.01905911002852271, 0.031882814581105576, 0.04062653475175, 0.08168889317790175, 0.1302149726190696, 0.17840065319707346, 0.2606656745972047, 0.39450792466149653, 0.4911094546024143, 0.5585520055189517, 0.5923224948870527, 0.6302384579809271, 0.6457682162071837, 0.6946071862394861, 0.7185853742529493, 0.7454414752360349, 0.618499419222971, 0.7074628958097988, 0.7352779958711105, 0.6955516339755666, 0.726348989935302, 0.31671773573998374, 0.40958798265579704
+600, -2.8, -2.4, -2.2, -2.0, -1.8, -1.6, -1.4, -1.2, -1.0, -0.8, -0.6, -0.4, -0.2, 0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 2.8
+, 0.052328852070039164, 0.026867396031232334, 0.16837658222176605, 0.024245798575350842, 0.0262292817988048, 0.12130083036303745, 0.0613620195234056, 0.060587459883910885, 0.05055444507030803, 0.07451277195194778, 0.07160801588372659, 0.09814403889181059, 0.23180293729028179, 0.37716308908081375, 0.5000132531217487, 0.5844300853732715, 0.588706451584414, 0.6364889102697228, 0.6447154143653666, 0.6571490187910064, 0.7745048328842353, 0.6898685260527815, 0.5933031009014547, 0.8136253894039864, 0.737081747390056, 0.612229773163282, 0.8993016606028706, 0.17838061372014036
+800, -2.6, -2.2, -1.6, -1.4, -1.2, -1.0, -0.8, -0.6, -0.4, -0.2, 0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.8
+, 0.021818989702759535, 0.021818989702759535, 0.026069027674035287, 0.01465256116221214, 0.029619466548546323, 0.011029824666793777, 0.019680030570921273, 0.03947987072242306, 0.0986257950403479, 0.18456806333044862, 0.3139427691570446, 0.4815565268749844, 0.6261430195281782, 0.5140415380874448, 0.5665602405952214, 0.5992870215665328, 0.6250365102046636, 0.8048492147720124, 0.6377275954637704, 0.5701006015265965, 0.8557024286413152, 0.9530038501783763, 0.8085467849780019, 0.27882798691668526
+1000, -0.8, -0.6, -0.4, -0.2, 0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.4
+, 0.009332428725528, 0.04925965308388099, 0.07181890841950693, 0.1406860776336484, 0.259162393696497, 0.601915813203475, 0.5614990245451659, 0.5400938444987884, 0.6009355243934302, 0.5240251717766059, 0.5904347159672351, 0.7086467981563515, 0.6532544497183701, 0.7830103565979136, 0.8442480557193919, 0.6152519207547671
+10000000, -1.4, -0.8, -0.6, -0.4, -0.2, 0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.2
+, 0.017400075652502834, 0.013968671710909226, 0.016258931051023752, 0.02276972220938904, 0.07144236497729933, 0.25014108242074024, 0.6377278912714578, 0.6213497886400078, 0.8644058949419727, 0.43810672452330535, 0.5254430132270977, 0.8481163148765324, 0.3798431831480397, 0.7667171569008974, 0.8092008618156888, 0.5447444189442937
+N
+200, -4.2, -3.8, -3.6, -3.4, -3.2, -3.0, -2.8, -2.6, -2.4, -2.2, -2.0, -1.8, -1.6, -1.4, -1.2, -1.0, -0.8, -0.6, -0.4, -0.2, 0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 2.8, 3.0, 3.2, 3.4, 3.6
+, 0.0712065157005121, 0.13294638271304174, 0.024918407202641813, 0.3991956150411048, 0.0953625460996715, 0.022620790870142397, 0.07653812401707984, 0.04013908322757407, 0.06637157555040195, 0.08790716077730971, 0.06987895197872204, 0.11594595731928202, 0.09469654486442684, 0.1055032820197743, 0.11677327019941976, 0.1383930868361456, 0.17556655708200233, 0.21274981636519386, 0.24681031402251496, 0.275707492383167, 0.343676483955714, 0.41361073312621865, 0.49954020026571794, 0.5289597425675846, 0.5644353295028, 0.594018016380281, 0.6394736076806113, 0.664612890069819, 0.6676529289997108, 0.6609569315008057, 0.7241923463576184, 0.6799056719677031, 0.6618977735500067, 0.7626413640672547, 0.5363488878232969, 0.7741958263705373, 0.6860956762633909, 0.7969009695833165, 0.7827637598777691
+400, -3.2, -3.0, -2.8, -2.6, -2.4, -2.2, -2.0, -1.8, -1.6, -1.4, -1.2, -1.0, -0.8, -0.6, -0.4, -0.2, 0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 2.8, 3.0, 3.2, 3.4
+, 0.001128461356220943, 0.007744997057307509, 0.007104165781121, 0.012715233504607883, 0.01992997097665505, 0.010023506476345678, 0.008734440583315614, 0.012766891527232208, 0.037250387032780934, 0.03554618185109885, 0.0641277000435746, 0.10383126855713888, 0.15817420705543073, 0.1590150077356472, 0.19733501123405667, 0.2655449837641665, 0.33774475148059496, 0.42156779664100374, 0.49403682221432815, 0.5567834425997928, 0.5869474638861647, 0.598529564395528, 0.6427745755499635, 0.6511468650484329, 0.656275764390928, 0.7339886223828026, 0.7133697636691161, 0.7833908369222597, 0.7814001135653762, 0.6921926967996985, 0.6930677127575958, 0.8719006330411663, 0.6993407299981116, 0.7520194008570942
+600, -3.0, -2.8, -2.6, -2.4, -2.2, -2.0, -1.8, -1.6, -1.4, -1.2, -1.0, -0.8, -0.6, -0.4, -0.2, 0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 2.8, 3.0, 3.2, 3.4
+, 0.012861627109688046, 0.05731785655357574, 0.07991944732610307, 0.08479562252863253, 0.08630884538516512, 0.06730490514845179, 0.008611336673529002, 0.024364202282699095, 0.04027411837341045, 0.05638279176751919, 0.07866817897417579, 0.07014008024714515, 0.1488228079108204, 0.21117858715982965, 0.22492604700759586, 0.3527511628371557, 0.4612776292791651, 0.508376750438461, 0.5978425447842742, 0.6169494954975383, 0.5870009692193582, 0.6834443025176401, 0.7503292713151367, 0.6041252831156599, 0.7114403688322494, 0.7942233006410815, 0.8025344848026892, 0.480061963819044, 0.8510863288832535, 0.4311453569540338, 0.4549099721194074, 0.8294748061125389, 0.3232898151906798
+800, -2.4, -2.2, -2.0, -1.8, -1.6, -1.4, -1.2, -1.0, -0.8, -0.6, -0.4, -0.2, 0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 2.8, 3.0, 3.2
+, 0.019989818428644154, 0.023892261719647902, 0.0029054710661450957, 0.004062937593554483, 0.008984136668700427, 0.010308406280718847, 0.08691527710437, 0.10361026893347543, 0.04789619477114294, 0.16745026833775423, 0.21747643195160038, 0.20845806212626344, 0.32694891534008996, 0.47723349576907653, 0.5295067551508112, 0.5770392423901299, 0.5730686049665393, 0.5894890079270304, 0.6047381214895978, 0.6682541217110526, 0.7311441820863821, 0.652518439576027, 0.8361938939030221, 0.4820988922476904, 0.7577299982101305, 0.5925855581398125, 0.12158342006740268, 0.9351822615425827, 0.12598320331575102
+1000, -1.0, -0.8, -0.6, -0.4, -0.2, 0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 2.8
+, 0.08803701255783213, 0.09574103749053965, 0.08474819481634101, 0.17517515123980776, 0.26799302520655116, 0.28439407716762816, 0.41648646362717917, 0.5455595697137675, 0.5615697118402637, 0.6793471491223992, 0.6046007911293165, 0.5491817816902066, 0.49692743170413184, 0.7221889848936341, 0.5269348636773619, 0.7588655952688864, 0.47213759827611784, 0.4709761521355724, 0.643696648197198, 0.20472622478386168
+10000000, -1.4, -1.2, -1.0, -0.6, -0.4, -0.2, 0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 2.0, 2.2, 2.4
+, 0.011076077289999191, 0.021909483447944987, 0.019761832256823684, 0.1397123465907093, 0.42129914368169563, 0.0812885393899792, 0.40490640849438697, 0.445164695597671, 0.5457577680850202, 0.6138506965124918, 0.499762804469091, 0.6076612903225806, 0.6718496818294005, 0.36172655263459996, 0.30939476061427285, 0.7177078765779696, 0.6569729941950139, 0.7172609072522392
+G
+200, -4.4, -4.2, -4.0, -3.8, -3.6, -3.4, -3.2, -3.0, -2.8, -2.6, -2.4, -2.2, -2.0, -1.8, -1.6, -1.4, -1.2, -1.0, -0.8, -0.6, -0.4, -0.2, 0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 2.8, 3.0, 3.2, 3.4, 3.6, 3.8, 4.0
+, 0.04980271364834668, 0.08033718293586467, 0.02137202174972912, 0.23924182209704178, 0.04290368826652217, 0.10995998186386532, 0.09077215489621959, 0.020063069662946225, 0.05199866894271401, 0.09869248618709753, 0.05755910536963877, 0.07335095177942563, 0.07836111992160895, 0.10947432785061317, 0.1829574600664543, 0.19644932151930236, 0.2475476355976773, 0.28047029664287276, 0.3663585502825831, 0.41381370184743865, 0.45028476809894513, 0.49271429268477074, 0.5257516371642744, 0.5380569146271968, 0.5816939874640986, 0.569518767778985, 0.5743891432518737, 0.5686338321658405, 0.6140459068175762, 0.5643093026733956, 0.6011486020284298, 0.573474665378709, 0.5168116740045788, 0.5321248352677072, 0.5278162040229152, 0.4301895642957476, 0.4371969736562028, 0.28501611757799006, 0.6434525427174271, 0.28996678413494487, 0.08989837533651014, 0.2567539583435563, 0.04184963224881832
+400, -3.4, -3.2, -3.0, -2.8, -2.6, -2.4, -2.2, -2.0, -1.8, -1.6, -1.4, -1.2, -1.0, -0.8, -0.6, -0.4, -0.2, 0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 2.8, 3.0, 3.2, 3.4
+, 0.013901301934598695, 0.004289024917785121, 0.013437974346902313, 0.007368860439472664, 0.01073447463708951, 0.02777219816300249, 0.017735008916501906, 0.03167632189935238, 0.065395714271814, 0.08023970903915105, 0.11154164414214832, 0.2022512296813042, 0.25545491618906413, 0.3536476783862624, 0.42363655299206915, 0.4684936278546968, 0.4921050743779281, 0.5494874471369424, 0.558926685575915, 0.5687086639940497, 0.6215795839689724, 0.6083484928768131, 0.6314576358198148, 0.6230514702472063, 0.5920065807809958, 0.626983997044515, 0.6050340178513397, 0.5291775304616348, 0.49878218646796507, 0.47333053527490554, 0.5819171331727555, 0.5436606285875814, 0.7368953451348795, 0.21159919104802896, 0.2423277350632243
+600, -3.2, -3.0, -2.8, -2.6, -2.4, -2.2, -2.0, -1.8, -1.6, -1.4, -1.2, -1.0, -0.8, -0.6, -0.4, -0.2, 0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 2.8, 3.0
+, 0.004262592522543604, 0.009609989324161305, 0.040722908138649094, 0.017614076524928034, 0.0093627162404978, 0.015355034655796965, 0.024755600324803256, 0.020194055025720813, 0.026706288439159422, 0.08077741729614026, 0.12928457280333558, 0.2529615159130915, 0.34196845700567596, 0.45149860216958276, 0.40996695404314654, 0.42578108033137246, 0.4803786191950474, 0.5843776520341477, 0.5586147764363851, 0.617306728496986, 0.6227856958198603, 0.6671398928615958, 0.6500952347555135, 0.6889882325738811, 0.6256734694615649, 0.5995168124878059, 0.7490707491628702, 0.5011582262180214, 0.5080490865168124, 0.28843898542192936, 0.6652919608969325, 0.7408142102868135
+800, -2.2, -2.0, -1.8, -1.6, -1.4, -1.2, -1.0, -0.8, -0.6, -0.4, -0.2, 0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 2.8, 3.0
+, 0.0020230132774187795, 0.023747698329704935, 0.028075380703131567, 0.015626043218693486, 0.04235468455893636, 0.09197490603136489, 0.18883534980280212, 0.27670832943186874, 0.4442895339785569, 0.36389293680452, 0.5494049531835955, 0.4340033509928248, 0.6029975424434239, 0.5363372195839183, 0.574020584323784, 0.5723823552003017, 0.668482030254807, 0.4580004693100662, 0.7116840257389728, 0.5822536180791649, 0.4377759423870536, 0.6468675879501711, 0.7183741297796663, 0.6254979951414307, 0.5158137378302833, 0.7279496888294327, 0.2627362326894526
+1000, -1.8, -1.6, -1.4, -1.2, -1.0, -0.8, -0.6, -0.4, -0.2, 0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 2.8, 3.0
+, 0.006489542114188809, 0.006949859307726209, 0.022534370804249342, 0.04516393000377678, 0.1136821257633273, 0.5110285116517171, 0.46770290612880394, 0.3659219700856653, 0.4583001142462624, 0.41336563823768924, 0.397921392614628, 0.39534194552429375, 0.4342297564398891, 0.5579332833345442, 0.6046583720178514, 0.41123271903157327, 0.6403926457323382, 0.6698778696734571, 0.5480418899094861, 0.7586576713030415, 0.7548134802193488, 0.6548685078706759, 0.9440873569829723, 0.7717038041572167, 0.23724929693196156
+10000000, -1.2, -1.0, -0.8, -0.6, -0.4, -0.2, 0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2
+, 0.021380286118534823, 0.027108017567662453, 0.1482481505468543, 0.600664441493963, 0.6398889295975626, 0.37057797159012834, 0.7850458683916712, 0.614502459890595, 0.3122958193267364, 0.8122341869514071, 0.5943585978600379, 0.7604878736966307, 0.5587283184181798, 0.6866167554855552, 0.4973986404656242, 0.780872442534018, 0.7371014288730907, 0.30209092437916923
+M
+200, -3.4, -2.8, -2.6, -2.4, -2.2, -2.0, -1.8, -1.6, -1.4, -1.2, -1.0, -0.8, -0.6, -0.4, -0.2, 0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 2.8, 3.0, 3.2, 3.4, 3.6
+, 0.02845963128097755, 0.006327814220719094, 0.03532321766363078, 0.02785817915545463, 0.06305230492182508, 0.06525558678224297, 0.06920333364821739, 0.09663310690550701, 0.09168272875852655, 0.10444060917510496, 0.14161496195972897, 0.18760094354688894, 0.27340880409079077, 0.3140034341765975, 0.3341867951289014, 0.3632541277201427, 0.39668565401586187, 0.43522081815108804, 0.47207835629148115, 0.5026342064038121, 0.5554008469913351, 0.5833574566458571, 0.6008099311783961, 0.6450861919646963, 0.6497380418171971, 0.7249028494100742, 0.7645552091301733, 0.7775959306800271, 0.7826666371582449, 0.7687189766034876, 0.7377750773840379, 0.8546113117648433, 0.7309510025155838, 0.5922461289520015
+400, -2.6, -2.4, -2.2, -2.0, -1.8, -1.6, -1.4, -1.2, -1.0, -0.8, -0.6, -0.4, -0.2, 0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 2.8, 3.0, 3.2, 3.4, 3.6
+, 0.038170835425479464, 0.01826291926366975, 0.008627909268057714, 0.005990921954905756, 0.007691489978484118, 0.020392739300842774, 0.04472291093102174, 0.060316255940233786, 0.06302004459220394, 0.1541038418593209, 0.22685507146016778, 0.2784664330885808, 0.29825937959171117, 0.3196733796620143, 0.3640325566040108, 0.40625749304857856, 0.4479345337346429, 0.5468608319197934, 0.5597030539512597, 0.6165686331561653, 0.6632688548164488, 0.6959674881486, 0.7903394987481768, 0.7268668913376479, 0.8235451001308638, 0.8275484601484625, 0.8098358326580584, 0.8637631783068633, 0.7737756627826707, 0.8647890997855323, 0.6977375511994904, 0.5247504661744165
+600, -1.8, -1.6, -1.4, -1.2, -1.0, -0.8, -0.6, -0.4, -0.2, 0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 2.8, 3.0, 3.2
+, 0.005736237861731748, 0.009523975244624639, 0.023891194668858876, 0.025234750802993748, 0.02552717930757656, 0.056254640669280716, 0.20941928914694077, 0.19788347655830058, 0.29589811372140384, 0.29852413139321216, 0.2897028729418557, 0.39073179258287705, 0.4552629356841357, 0.5593966833420538, 0.5750394291646366, 0.585085568055378, 0.7318672657089549, 0.6941092464581831, 0.8819680496498116, 0.8406532752846406, 0.8451650670206011, 0.9416795740780045, 0.893085997768151, 0.9110602722058794, 0.7163256112121613, 0.7174375236482226
+800, -1.2, -1.0, -0.8, -0.6, -0.4, -0.2, 0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 2.8, 3.0, 3.4, 3.8
+, 0.004674108580720676, 0.0035096825949236417, 0.02573551674322442, 0.08020943690055882, 0.2141222710358276, 0.3552257946322249, 0.323221883037281, 0.334294250957123, 0.2829357833432641, 0.43434992803525485, 0.5808355469054186, 0.6241893673747914, 0.6931880921298325, 0.5795185281057724, 0.5509178962895578, 0.8197337451110486, 0.736948316454277, 0.7846023423062995, 0.6580624097643196, 0.9191076830846109, 0.9023948888700153, 0.9474981632934666, 0.016170424235835836, 0.21365134335027647
+1000, -0.4, -0.2, 0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 3.4, 3.8
+, 0.0395955810122565, 0.20251297074083224, 0.2515696605044113, 0.23118137403932495, 0.31920693493675995, 0.32386507072905335, 0.5120874998766078, 0.5880070517335512, 0.7408938081106, 0.6469459262991496, 0.40303988237456356, 0.8411104193700822, 0.9040742300533903, 0.7482458141989218, 0.7670674781862866, 0.9574210199417486, 0.23437245866088377, 0.1630415456646714
+10000000, -0.6, -0.4, -0.2, 0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.2
+, 0.005278592375366569, 0.02483900643974241, 0.21079571893904142, 0.25278114329772, 0.24822695035460993, 0.39404962972586727, 0.8361985706007341, 0.5839568257083283, 0.5340659340659342, 0.7478816708785491, 0.435701214440193, 0.7346019028542814, 0.5848733325174398, 0.5098265895953757
+W
+200, -4.0, -3.6, -3.4, -3.2, -3.0, -2.8, -2.6, -2.4, -2.2, -2.0, -1.8, -1.6, -1.4, -1.2, -1.0, -0.8, -0.6, -0.4, -0.2, 0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 2.8, 3.0, 3.2, 3.4, 3.6, 3.8, 4.0, 4.2, 4.4, 4.6, 4.8, 5.0
+, 0.010053137251715156, 0.03614107661201093, 0.07513752318069507, 0.06232763609362001, 0.04090719053394041, 0.03012721074281631, 0.01999689051399049, 0.020024382749013706, 0.035560145033910834, 0.041624797523196214, 0.06142487113870969, 0.07038694508427773, 0.0874141479196364, 0.14373224227628087, 0.1930317693688374, 0.17608850960040795, 0.2837591992712456, 0.31751427975693, 0.37402457119572285, 0.3767044103235768, 0.3875467674943792, 0.5162805569385304, 0.5513809807468663, 0.43645713565312544, 0.5295897770124752, 0.5509452638284295, 0.6355399448481385, 0.6292792289200955, 0.6154280980913217, 0.5862191648292456, 0.692729444731882, 0.6933688155617883, 0.6525897180760073, 0.6862900638687898, 0.6206267900753528, 0.7227963137333674, 0.6563610741001843, 0.6541491631508591, 0.6862278523667734, 0.5173986502301023, 0.6254962352564359, 0.2376686434766528, 0.2850520026378816, 0.32445331851643955, 0.1545443294828597
+400, -2.8, -2.6, -2.4, -2.2, -2.0, -1.8, -1.6, -1.4, -1.2, -1.0, -0.8, -0.6, -0.4, -0.2, 0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 2.8, 3.0, 3.2, 3.4, 3.6, 3.8, 4.0, 4.2, 4.4, 4.6, 4.8, 5.2
+, 0.003936305168090178, 0.002892443565021887, 0.008130955780809584, 0.012686225767031701, 0.025774402091606103, 0.04458131185056105, 0.05957848834895015, 0.09030918669627554, 0.1253577531298458, 0.1762117242340049, 0.18978784602769633, 0.2613781994982344, 0.3479702350864556, 0.38339977058667163, 0.38746151324205624, 0.4143832977912655, 0.4326335523770048, 0.48109640926677794, 0.5253077885613805, 0.5436337693892012, 0.5957468274559441, 0.6066920552022064, 0.5856318907005583, 0.7405960813443107, 0.6556337756952331, 0.7700481180232187, 0.6123487455485063, 0.716084361648064, 0.5946136429487322, 0.7631646331908402, 0.7287205565301803, 0.7089736280501816, 0.7458023147425407, 0.800312812064102, 0.7905807458117725, 0.7524453487016617, 0.6904598548976143, 0.09244951222078437, 0.8853441973001723, 0.22803862653375243
+600, -3.0, -2.8, -2.6, -2.4, -2.2, -2.0, -1.8, -1.6, -1.4, -1.2, -1.0, -0.8, -0.6, -0.4, -0.2, 0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 2.8, 3.0, 3.2, 3.4, 3.6, 3.8, 4.0, 4.2, 4.4, 4.6, 4.8
+, 0.015941116115818707, 0.016594307129943656, 0.010924353018042558, 0.014218984649465553, 0.02534885725861216, 0.06771148595573359, 0.06116471271630187, 0.058466868227181355, 0.11369094282044122, 0.10028915633745711, 0.09713241672842075, 0.23121690042026713, 0.21175385468088415, 0.28462241635242436, 0.31685345966888984, 0.34243553290584766, 0.3967943463270171, 0.5322292663560987, 0.46053074781033976, 0.46756551159626847, 0.5093913642584738, 0.46665721497662693, 0.5872387559719567, 0.5295263318218335, 0.6679207002526416, 0.633194898204035, 0.8205977787023934, 0.6778801000144382, 0.6386241437433336, 0.7474959665347901, 0.7280984639756457, 0.792440375474518, 0.8269539563283489, 0.914446352387371, 0.6292990018576369, 0.9002209011938572, 0.8814371535125446, 0.9569213613893796, 0.5613551803722755, 0.15303410010373106
+800, -2.2, -2.0, -1.8, -1.6, -1.4, -1.2, -1.0, -0.8, -0.6, -0.4, -0.2, 0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 2.8, 3.0, 3.2, 3.4, 3.6, 3.8, 4.0
+, 0.0224761653850587, 0.06897795528325656, 0.043964184488533876, 0.05426990516042012, 0.10593446276907946, 0.11088933395600369, 0.11131403251399657, 0.41212081201518397, 0.252185523895901, 0.5131779640168599, 0.4970442274474704, 0.3753445990025042, 0.4454367118169079, 0.43641127627008697, 0.5375555342059549, 0.582743847296434, 0.700875716747453, 0.3693056263810981, 0.5166424534068959, 0.5938453539126746, 0.5650094444620126, 0.7110946731164166, 0.6077794715264038, 0.797757938175236, 0.5455658878175588, 0.673111514092521, 0.7037020400243812, 0.6435682203777798, 0.604048928630185, 0.8674003285619997, 0.2236593996887986, 0.928303029180713
+1000, -1.6, -1.4, -1.2, -1.0, -0.8, -0.6, -0.4, -0.2, 0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 2.8, 3.0, 3.2, 3.4, 3.6, 3.8, 4.0, 4.6
+, 0.05041657765434737, 0.02326957207651351, 0.03004073319755601, 0.19675712971481144, 0.3266965127238455, 0.22095951443145867, 0.36550759392486015, 0.7630891680139287, 0.6041852181656279, 0.8423339540657977, 0.6174986823281381, 0.39799453053783046, 0.7304563141139018, 0.6849573328041277, 0.3470302731161567, 0.3593023674822529, 0.4835460460460461, 0.7854439789160697, 0.6272501956691886, 0.6353194544149319, 0.8131345333267939, 0.6726479627242986, 0.9429828499595941, 0.7991883202445581, 0.6992572398895678, 0.5080599505378266, 0.8768982229402262, 0.4046968016124748, 0.8114981199287552, 0.3381969775924961
+10000000, -1.0, -0.8, -0.6, -0.4, -0.2, 0.4, 0.6, 0.8, 1.0, 3.0, 4.0, 4.2
+, 0.0021122338299937207, 0.1448140900195695, 0.07805907172995782, 0.28139773895169584, 0.22224694104560624, 0.16373639516804211, 0.3721264367816092, 0.3226118969192017, 0.33218720152817577, 0.0726298477372805, 0.4892249251223611, 0.8037608756665732
+D
+200, -4.6, -4.2, -4.0, -3.8, -3.6, -3.4, -3.2, -3.0, -2.8, -2.6, -2.4, -2.2, -2.0, -1.8, -1.6, -1.4, -1.2, -1.0, -0.8, -0.6, -0.4, -0.2, 0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 2.8, 3.0, 3.2, 3.4, 3.6, 3.8
+, 0.018626895228895723, 0.11728080320078006, 0.5937426667262748, 0.03927533862645874, 0.05974671976524982, 0.0917149470704997, 0.06046434414289128, 0.04459964351175079, 0.03891584428680007, 0.05454776436988832, 0.05760795314793352, 0.06520214434682021, 0.08441878992655659, 0.10554307834242026, 0.13156414894978147, 0.14638211055267963, 0.17598859363160593, 0.17217531685054885, 0.18463737353117532, 0.20794269423656211, 0.27808363911099476, 0.3642544766197776, 0.42615125908706963, 0.5026779437159384, 0.5381913735877556, 0.5448344936741886, 0.5736658815321012, 0.5728175734848698, 0.5772159313301718, 0.5935206601384001, 0.5785927893804083, 0.5803030006598179, 0.634696992284186, 0.6632184597205736, 0.5725772600179964, 0.5806805560809384, 0.6456153291100302, 0.4008137326056845, 0.5142766154383125, 0.594144624446019, 0.9480860255395239, 0.7891323212963747
+400, -3.8, -3.6, -3.2, -3.0, -2.8, -2.6, -2.4, -2.2, -2.0, -1.8, -1.6, -1.4, -1.2, -1.0, -0.8, -0.6, -0.4, -0.2, 0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 2.8, 3.0, 3.2, 3.4, 3.6, 3.8
+, 0.017526022053705452, 0.010090662246000215, 0.005911072408159453, 0.0094242912522625, 0.00483203212764107, 0.014840210378253412, 0.035251055138788005, 0.03010333597027076, 0.05707110978001972, 0.06806654215390828, 0.10122954326734433, 0.13770152403508962, 0.1251534611085536, 0.15864699520014003, 0.12863271934388903, 0.17303911256916327, 0.23872337803608437, 0.3438374233682127, 0.4471077553553215, 0.5299235923012301, 0.5563624942893748, 0.5662502058564726, 0.5721638839165779, 0.6129871191897227, 0.5660340347563402, 0.6308606276684164, 0.632643587440431, 0.5798265428394158, 0.5711256183324998, 0.6104867833858457, 0.5477759251339209, 0.5034780015525244, 0.28633253697579686, 0.6019606099741027, 0.41753839461241327, 0.34898716933495605, 0.1753443010109411, 0.4937170887940028
+600, -3.4, -3.2, -3.0, -2.8, -2.6, -2.4, -2.2, -2.0, -1.8, -1.6, -1.4, -1.2, -1.0, -0.8, -0.6, -0.4, -0.2, 0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 2.8, 3.0, 3.2, 3.4, 3.6
+, 0.07572055697912322, 0.04685137919874146, 0.013470059859080275, 0.016120642626666723, 0.025934741332931405, 0.013470059859080279, 0.01047103161086878, 0.043184882720677706, 0.07524094553614041, 0.057131662342132405, 0.07555065450499734, 0.09094351900345422, 0.07943708440995989, 0.14120981974737906, 0.15889063869132145, 0.18288901171356836, 0.2994462254923587, 0.455922970640683, 0.470865053294829, 0.555923147176361, 0.5744394407250271, 0.5983652427055746, 0.6451298402584105, 0.6144094316369362, 0.5638708071261487, 0.5817023571301216, 0.7382954315694873, 0.6415137553013202, 0.6027798778331301, 0.5498240561188864, 0.3129098587277003, 0.5853527174502478, 0.6417674076529638, 0.34646976044148603, 0.8892401221593547, 0.06589683307979534
+800, -2.2, -2.0, -1.8, -1.6, -1.4, -1.2, -1.0, -0.8, -0.6, -0.4, -0.2, 0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 3.0, 3.2
+, 0.008510660029390252, 0.053999319540527856, 0.029166739590808066, 0.11008787306416677, 0.06867749030405805, 0.10487922755985372, 0.08441754322657907, 0.13927445001053515, 0.1262502840915484, 0.1581350088904876, 0.37032405294594306, 0.47112296199708115, 0.5059968009083806, 0.5667473589508149, 0.5662007078489808, 0.5036665508717231, 0.5685524410133438, 0.5021030771387083, 0.46777863494735494, 0.6249417586714079, 0.6570922695616377, 0.7799387736421073, 0.7624247583463559, 0.364603814519136, 0.8518129178326466, 0.33007532508626103, 0.2808647177027291
+1000, -2.0, -1.6, -1.4, -1.2, -1.0, -0.8, -0.6, -0.4, -0.2, 0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6
+, 0.03099074564389641, 0.03526188187699943, 0.0601183779288754, 0.10708870906841245, 0.14124632869365342, 0.07858307490648676, 0.16099733636085756, 0.11251951702527954, 0.31888428435752014, 0.3845687605484582, 0.47978895233223035, 0.5356864443869647, 0.5760458574570188, 0.5243609252477301, 0.44676271680565494, 0.5517489421762919, 0.40731563845050217, 0.5530463031664227, 0.7056189995435903, 0.6602700897805741, 0.7555583244746631, 0.43490969602040125, 0.9630958463140022
+10000000, -1.6, -1.4, -1.2, -1.0, -0.8, -0.6, -0.4, -0.2, 0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.4, 2.6
+, 0.0014151021012620737, 0.01120977596741344, 0.04853957951178213, 0.06924634213674427, 0.2242589254898953, 0.3488169966199903, 0.4214279585474444, 0.5540891613841836, 0.6191275770879868, 0.5765505268784041, 0.7524044757887831, 0.70228140959197, 0.36758525047113005, 0.6752083232984923, 0.8562413388764525, 0.4384222653499529, 0.2229776446185757, 0.7973201791445547, 0.13059610618454792, 0.0663917127836773
+H
+200, -4.0, -3.4, -3.2, -3.0, -2.8, -2.6, -2.4, -2.2, -2.0, -1.8, -1.6, -1.4, -1.2, -1.0, -0.8, -0.6, -0.4, -0.2, 0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 2.8, 3.0, 3.2, 3.4, 3.6, 3.8, 4.0
+, 0.03366143791073794, 0.12229579473890749, 0.0023965874294210304, 0.11142894439620184, 0.0598821754984208, 0.035073646976856346, 0.030033608637588124, 0.042770531837719, 0.07436799354604083, 0.06192889876940986, 0.07501889297412434, 0.07651922461089912, 0.10236657357048272, 0.13008490869476172, 0.17570521982550932, 0.19562570288549183, 0.2402717212537774, 0.34894741760751985, 0.3926314534309388, 0.463459973122341, 0.4872892573845177, 0.5656076053978417, 0.5702410891638474, 0.5842610000246314, 0.6401215021032886, 0.6635057656919326, 0.6858272882551264, 0.7036437455064729, 0.6900683507603625, 0.7912016521539376, 0.6256905279756557, 0.6551663451279496, 0.6442387019495477, 0.5154430296772594, 0.610714922104654, 0.47655815437182536, 0.5038680884987706, 0.331638615368125, 0.16532032785248002
+400, -3.0, -2.8, -2.6, -2.4, -2.2, -2.0, -1.8, -1.6, -1.4, -1.2, -1.0, -0.8, -0.6, -0.4, -0.2, 0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 2.8, 3.0, 3.2, 3.4, 3.6, 3.8, 4.0
+, 0.024983509456821706, 0.0023065782730348084, 0.02498350945682171, 0.03938325596225074, 0.01924885711675501, 0.017001918349411307, 0.004532697766235948, 0.01672786076537002, 0.030488464144219574, 0.04246194666294303, 0.05482530743289866, 0.09453774664211397, 0.15068238595070957, 0.22043514025408253, 0.30862698998080434, 0.40606922105192056, 0.4635111004362203, 0.5490011391057846, 0.5896936531471226, 0.6012522032441759, 0.6334213044527051, 0.6530489917577715, 0.6816836432220428, 0.7235863198736988, 0.6104989855312881, 0.744281538492875, 0.6437700766365099, 0.6596101401847652, 0.6237587050584414, 0.4909123749450153, 0.4754536332396059, 0.5319185585373064, 0.5738471453688846, 0.5770204247077545, 0.3974957524720365, 0.12628946646351794
+600, -1.8, -1.6, -1.4, -1.2, -1.0, -0.8, -0.6, -0.4, -0.2, 0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 2.8, 3.0, 3.2, 3.4, 3.6, 3.8
+, 0.003375360767234541, 0.02315851530668037, 0.007713013203962888, 0.020489809218885796, 0.02789797627428184, 0.05670945810086781, 0.08172911385087334, 0.10354699727263074, 0.20946023963686963, 0.3485166802620737, 0.4135052949447255, 0.5048283954868971, 0.5810659272872755, 0.6252028870513755, 0.49276922092287434, 0.6972373542165986, 0.598283244541968, 0.7060471943352125, 0.6335714820846869, 0.8409656287721421, 0.8713022883991768, 0.7548429339870076, 0.7731077709300429, 0.6286562667563377, 0.7416134578437232, 0.7973583875768113, 0.6246797630480752, 0.44839283867200974, 0.618207741949151
+800, -1.2, -1.0, -0.8, -0.6, -0.4, -0.2, 0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 2.8, 3.0, 3.2, 3.4, 3.6
+, 0.004332254797836343, 0.008517472428799602, 0.02801288412634691, 0.04042976376212141, 0.05638253860440923, 0.1485878639312434, 0.45494966839303996, 0.5364218471499814, 0.6019752585827106, 0.6468967344018158, 0.7291083814949837, 0.5541234821386483, 0.44092351636485544, 0.5412120458980819, 0.5492062498043022, 0.6146558441172213, 0.46263676380203994, 0.8097888157180061, 0.8253314552869299, 0.9025689021252576, 0.3065145430410163, 0.887952826612005, 0.7349291853455371, 0.6930569512214189, 0.7189787433389939
+1000, -0.8, -0.6, -0.4, -0.2, 0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 3.0, 3.2, 3.4
+, 0.016726572227312234, 0.044336969269249515, 0.06230922176482117, 0.2733652504290111, 0.3606353085893688, 0.4154854412512842, 0.4931667421477475, 0.5421469025922283, 0.5483236455497511, 0.569378907839295, 0.43122599932991407, 0.506119714597294, 0.4286583086215133, 0.6048992306603105, 0.45424657023908194, 0.6333345687706163, 0.5822196798974196, 0.8918964292632531, 0.9422988109598484, 0.8579332348997845
+10000000, -0.4, -0.2, 0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 2.0, 2.4, 3.0, 3.4
+, 0.026043125175021, 0.28627129078596353, 0.2006741486957521, 0.3602109329490757, 0.5126121076233183, 0.7521644636049453, 0.7345747319418476, 0.4402735868034601, 0.7231112172597723, 0.4617557163307154, 0.4887361728712654, 0.6417756720568545, 0.36683051156016755, 0.3773720014321518, 0.6682563906905762
+F
+200, -3.8, -3.6, -3.4, -3.2, -3.0, -2.8, -2.6, -2.4, -2.2, -2.0, -1.8, -1.6, -1.4, -1.2, -1.0, -0.8, -0.6, -0.4, -0.2, 0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 2.8, 3.0, 3.2, 3.4, 3.6, 3.8, 4.8
+, 0.0118796572796037, 0.0014672582394740575, 0.03743998420606895, 0.027945978849726678, 0.042221213889387516, 0.010801552826949386, 0.04139522496607944, 0.03999191502135917, 0.05211549995458061, 0.060297109638310954, 0.10129384648254204, 0.15616351789120644, 0.21318276089539578, 0.25042509461225854, 0.29299384438800996, 0.30431199722184266, 0.31474465593677153, 0.3215608071222106, 0.34933410952686794, 0.4013372334166951, 0.4132461627252968, 0.4735993600214136, 0.5137798275706204, 0.5240892505076316, 0.5732127691892553, 0.5728471386016757, 0.587424087598907, 0.6378341853871199, 0.6652131586082336, 0.6434091755890186, 0.6811145001725185, 0.6778946461924046, 0.6531231489646425, 0.622114029030299, 0.7027944481835392, 0.6544984744633467, 0.6768972298187619, 0.7649999212127353, 0.17747727606580532, 0.03200371938741867
+400, -2.8, -2.6, -2.4, -2.2, -2.0, -1.8, -1.6, -1.4, -1.2, -1.0, -0.8, -0.6, -0.4, -0.2, 0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 2.8, 3.0, 3.2, 3.4
+, 0.004521502078034196, 0.011294546197758165, 0.01902181455153136, 0.028453600912992427, 0.045494587204780265, 0.075636622645322, 0.1346817828927533, 0.1858370410511906, 0.21145461364683354, 0.22993300300255923, 0.24758097664369763, 0.2503946720700768, 0.2893435384653396, 0.33294847977837494, 0.3801325469321394, 0.4218741104610451, 0.4797481604447298, 0.511808478587414, 0.5974117622187544, 0.5834704269428962, 0.6578279478883984, 0.6933440994726486, 0.7200687227206225, 0.6742670559283108, 0.7199198750632219, 0.7264408323450363, 0.7378516949019436, 0.8038271425512616, 0.8296853580700081, 0.8243729580366167, 0.779678703055898, 0.7171620329790568
+600, -3.2, -3.0, -2.8, -2.6, -2.4, -2.2, -2.0, -1.8, -1.6, -1.4, -1.2, -1.0, -0.8, -0.6, -0.4, -0.2, 0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 2.8, 3.0
+, 0.04225844325367724, 0.02996073852825442, 0.0033279267524589365, 0.010538147174194904, 0.0055842967220071866, 0.023707193295361365, 0.03287914981492101, 0.055581517092584964, 0.12205147623150721, 0.18674255469804368, 0.21228362626337297, 0.19176664697425205, 0.192771021747899, 0.2738504396168108, 0.2706484536269102, 0.3113119235107976, 0.3768631860175106, 0.4286865380951811, 0.4674373782473765, 0.4470173830795746, 0.5654578562715549, 0.6089083108990303, 0.6950018580809499, 0.754745539388691, 0.6729932052759504, 0.6466101067600745, 0.7630081242628347, 0.7653017355343918, 0.7660715915354379, 0.9006582480689912, 0.8613792472553212, 0.9183691145965688
+800, -2.2, -2.0, -1.8, -1.6, -1.4, -1.2, -1.0, -0.8, -0.6, -0.4, -0.2, 0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 2.8, 3.0
+, 0.0025284892240452768, 0.0013041538615920674, 0.02322344999575436, 0.06274762646486995, 0.14440845571763275, 0.3574106974338475, 0.26027269066425, 0.2629704658055164, 0.24533138237707777, 0.26347140721903634, 0.3022788001575987, 0.29989143373704513, 0.4442104934598845, 0.5365972904585126, 0.4221062978051718, 0.5554972868238451, 0.5400155429805876, 0.6527242876757253, 0.47262603008218756, 0.6000342893579687, 0.8297108914342853, 0.5432571765506535, 0.6164512733317686, 0.659729845987438, 0.878226507885687, 0.8293156239699597, 0.39935167691260115
+1000, -1.6, -1.4, -1.2, -1.0, -0.8, -0.6, -0.4, -0.2, 0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 2.8
+, 0.06957581181214641, 0.11727576980179334, 0.19879724787180408, 0.15514564994465022, 0.15335563242078185, 0.2029411563067941, 0.33025361900905537, 0.4179908587644115, 0.4428200805838054, 0.5634100755177667, 0.5680939840623824, 0.41520905829955296, 0.5753449870929177, 0.48414588902396805, 0.5913147768147112, 0.4648190251829891, 0.6358734895010334, 0.8449506822406887, 0.5716931289884855, 0.6013880377634973, 0.7021165582108326, 0.7605031088714594, 0.8316368363163683
+10000000, -1.4, -1.2, -1.0, -0.8, -0.6, -0.4, -0.2, 0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6
+, 0.08665812891997504, 0.1893325561060915, 0.392884167636787, 0.7103372143883693, 0.1713556511117511, 0.12470072279692956, 0.2383403904279098, 0.4472355817003856, 0.3084458638141755, 0.3922429804435704, 0.5098120423323317, 0.4048967889635629, 0.4046453884579675, 0.45231916560612523, 0.578670933838637, 0.527791925571288, 0.9204796267282687, 0.9253331472075768, 0.8919738382028523, 0.8766760073779796, 0.8865785578260142
+Y
+200, -3.8, -3.6, -3.4, -3.2, -3.0, -2.8, -2.6, -2.4, -2.2, -2.0, -1.8, -1.6, -1.4, -1.2, -1.0, -0.8, -0.6, -0.4, -0.2, 0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 2.8, 3.0, 3.2, 3.4, 3.6, 3.8, 4.0
+, 0.009286499266584609, 0.04190994220311158, 0.005673267516690456, 0.011282526243736116, 0.041909942203111575, 0.05957785566189, 0.04749864096985896, 0.05803797548561103, 0.07284698771143527, 0.04867312515561958, 0.0837839451245465, 0.08136844795311347, 0.1196284938247924, 0.13488330074785607, 0.1859103414172193, 0.22494333273362108, 0.2845607850383266, 0.34148624354154694, 0.3537330507841197, 0.4303267700378927, 0.4596981968135125, 0.5043265158898462, 0.5722032966248287, 0.591132260747033, 0.5615672359144327, 0.6433527557582447, 0.6200821169061512, 0.6866199534656023, 0.6409420681507526, 0.6377669951160809, 0.6475917264147603, 0.5867402271820585, 0.6081464300418282, 0.5855598936277712, 0.703751153709795, 0.5335558858652032, 0.5718292411383575, 0.7868125143340565, 0.5943859446876695, 0.2531795538962151
+400, -3.0, -2.8, -2.4, -2.2, -2.0, -1.8, -1.6, -1.4, -1.2, -1.0, -0.8, -0.6, -0.4, -0.2, 0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 2.8, 3.0, 3.2, 3.4, 3.6, 3.8
+, 0.0024631904120060435, 0.014599337728464305, 0.0019080473895611095, 0.0034467235991527422, 0.007898872470056247, 0.02454940809416175, 0.02767901585092433, 0.060144475081240587, 0.10182673535143302, 0.1402223895256354, 0.2159272947456956, 0.2474628127234784, 0.30672796698809546, 0.3701837946270894, 0.4281630341544478, 0.4900105528169095, 0.49672558077846896, 0.5458230184672949, 0.5822237283945346, 0.6232035400297948, 0.6309651873689367, 0.6650089068472502, 0.6906883232556257, 0.719070120561808, 0.5861318306017409, 0.6939528630753063, 0.644733589945717, 0.7557826365261244, 0.7868872016335692, 0.8077101821427416, 0.785137848061695, 0.7007336361374807, 0.7907789335787568, 0.9314640234622172
+600, -3.2, -2.8, -2.6, -2.4, -2.2, -2.0, -1.8, -1.6, -1.4, -1.2, -1.0, -0.8, -0.6, -0.4, -0.2, 0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 2.8, 3.0, 3.2, 3.4, 3.6, 3.8
+, 0.0678339420637355, 0.03132907113746549, 0.19521471211245917, 0.0790468441438464, 0.04504147115901855, 0.03621970390869113, 0.03736078959794541, 0.0702121913978338, 0.07678045932576472, 0.10633802477667664, 0.11960413292539095, 0.19900688668929817, 0.19847870369671886, 0.35052340230366474, 0.4182620478260756, 0.49334638007139636, 0.4139336918612302, 0.4758803364739189, 0.48058197497143446, 0.5325837123233392, 0.6764738640938338, 0.5824113213410999, 0.6854925565305252, 0.716699831685794, 0.6913247110998257, 0.7364537742437196, 0.6973151529206393, 0.6640017089879244, 0.7535147537884177, 0.8736524217431264, 0.8883154079240142, 0.9086524895242979, 0.3364614429341759, 0.8892455486542443, 0.516276512630574
+800, -2.4, -2.2, -1.8, -1.6, -1.4, -1.2, -1.0, -0.8, -0.6, -0.4, -0.2, 0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 2.8, 3.0, 3.2, 3.4
+, 0.12499249996999987, 0.017542677750980205, 0.004183814710350362, 0.04049577780196881, 0.01945394480279348, 0.05981555656515628, 0.1662287133765109, 0.2470726136520115, 0.2279836885745909, 0.3405906596146762, 0.39304167365159454, 0.5479494843905584, 0.5776797970134353, 0.4969350548999451, 0.554976031602476, 0.6111452872519451, 0.5933613225870421, 0.6503765957046587, 0.6459187382843162, 0.47697114639093807, 0.4439174984783494, 0.5898786001485177, 0.6521583574634947, 0.699411044781371, 0.8755290078823845, 0.6892194962693724, 0.5956513541689771, 0.4191972780617089, 0.6859665367471306
+1000, -1.2, -1.0, -0.8, -0.6, -0.4, -0.2, 0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 2.8, 3.0, 3.2, 3.4
+, 0.01513420581891473, 0.04710716529773664, 0.08675346730823665, 0.2536586494224809, 0.34051794477036007, 0.4949352227554531, 0.3744979625153848, 0.3885763166955366, 0.47500620176957165, 0.6732234245582497, 0.5916145874535242, 0.6141509220860845, 0.7235237614799357, 0.8444622025111802, 0.5840380724187212, 0.37117416203862574, 0.6845523703789804, 0.7343493349470799, 0.6147306746541727, 0.836192015818726, 0.6897855770617488, 0.7497181598163127, 0.3071472030349666, 0.1919103374866947
+10000000, -0.8, -0.6, -0.4, -0.2, 0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 2.0, 2.2, 2.6, 2.8, 3.0, 3.2
+, 0.0708645474792468, 0.17151110308719983, 0.2570225856067352, 0.11678972600342932, 0.14007308160779536, 0.5103673933918981, 0.7576957600718095, 0.7229533929002657, 0.7098140887820918, 0.6723469072042269, 0.6112883643448062, 0.6166996129966311, 0.893002867868218, 0.8895255061508461, 0.8001654763978401, 0.30475369142377656, 0.6623003900213408, 0.7044407947702315, 0.6821802063854838
+C
+200, -4.4, -4.2, -4.0, -3.8, -3.6, -3.4, -3.2, -3.0, -2.8, -2.6, -2.4, -2.2, -2.0, -1.8, -1.6, -1.4, -1.2, -1.0, -0.8, -0.6, -0.4, -0.2, 0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 2.8, 3.0, 3.2, 3.4, 3.6, 3.8, 4.0, 4.2, 4.4, 4.6, 4.8
+, 0.00552600427650797, 0.03485954094930549, 0.03838810402982251, 0.025715627803848534, 0.025488221431905482, 0.04343408489770449, 0.07142970187382498, 0.061574074307699386, 0.07314774143241341, 0.0645623004653657, 0.08295448119612607, 0.11583376897861364, 0.10923780472615427, 0.15872284777216678, 0.18960300191746962, 0.21632285501348175, 0.2689843145563964, 0.317374224275957, 0.3630447998094276, 0.47533324924738357, 0.47607691305922323, 0.5079450745840531, 0.5277576798975776, 0.5628057172760719, 0.575051710042101, 0.5593880195311266, 0.6755090738783593, 0.5934386213582137, 0.6382467809460037, 0.46977743056505733, 0.49332782901573397, 0.433919671579876, 0.4787946054736947, 0.5285187386448856, 0.5192055844835611, 0.5418864058012781, 0.4974690811553878, 0.6669903566100355, 0.5635741644172909, 0.5631278587090643, 0.4509635087812499, 0.41102196954637915, 0.5675101424562242, 0.3858209367335479, 0.7158058178212813, 0.8441831930348846, 0.917028268187617
+400, -2.8, -2.4, -2.2, -2.0, -1.8, -1.6, -1.4, -1.2, -1.0, -0.8, -0.6, -0.4, -0.2, 0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 2.8, 3.0, 3.2, 3.4, 3.6, 3.8, 4.0, 4.2, 4.4, 4.6, 4.8, 5.0, 5.2
+, 0.010395396838634843, 0.021361460299502484, 0.02165535066430582, 0.015159525108778021, 0.05264200337595036, 0.09707983819746174, 0.09731511297628698, 0.14129374581890802, 0.20022262624150677, 0.1899999623811763, 0.24177069784075372, 0.2794320762962471, 0.3349563341527679, 0.39941588667848116, 0.37542427668497114, 0.4413948575311084, 0.4994511731980783, 0.5229578236619977, 0.517824249985961, 0.5986188278934524, 0.55649711734287, 0.6546467413270598, 0.7295136272915, 0.6635498671850562, 0.6708303778437357, 0.6854662728780426, 0.7366769816589981, 0.6804239212899574, 0.8020315025334613, 0.648248800129263, 0.4883801068027809, 0.5457865193156772, 0.7435757599432814, 0.3888378116158756, 0.8142396988934587, 0.35653604110313064, 0.9515094757412567, 0.8683671258886828, 0.43063122020040623, 0.20134832264371375
+600, -2.2, -2.0, -1.8, -1.6, -1.4, -1.2, -1.0, -0.8, -0.6, -0.4, -0.2, 0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 2.8, 3.0, 3.2, 3.4, 3.6, 3.8, 4.0, 4.2, 4.4
+, 0.014640944089221617, 0.047190998499466535, 0.016131092675076904, 0.05393342938205346, 0.03794117361550069, 0.14801529752994014, 0.12649865136882416, 0.12425487801283724, 0.18258838145967776, 0.17401252442552514, 0.24820371537628083, 0.2723009495881132, 0.31076828090971514, 0.4228592493350921, 0.4833419854280797, 0.48225822549606906, 0.6096979060194508, 0.6813975348841623, 0.6390568469900091, 0.6423882998985359, 0.6933120557029364, 0.7437104177397691, 0.7344965946599342, 0.5339314985180899, 0.76693091389901, 0.7860009499083788, 0.9485711375084455, 0.7614620936289629, 0.7922335003939941, 0.8140234673530409, 0.9905994173641781, 0.7496322833936753, 0.5402660706005019, 0.18423883691036483
+800, -1.8, -1.6, -1.4, -1.2, -1.0, -0.8, -0.6, -0.4, -0.2, 0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 2.8, 3.0, 3.2, 3.4, 3.6, 4.0, 4.2, 4.4
+, 0.1676606183648437, 0.1676606183648437, 0.07743155394424302, 0.07659036520366225, 0.040008410782623315, 0.06504823840581023, 0.1572369829786188, 0.20637862095592702, 0.26511828078110244, 0.26880018429549696, 0.7715955945577099, 0.5608321221346089, 0.5723698356275932, 0.5774648391346796, 0.5310722977083755, 0.5139787601877006, 0.6388370807266754, 0.5159175246850328, 0.4037730013428791, 0.6462677917648109, 0.6914477449297176, 0.7064353719025876, 0.6496598105159759, 0.8061020949745134, 0.9114250135029706, 0.805807135371541, 0.7069698372603644, 0.5579972241756949, 0.9707483336999887, 0.2521582668435688, 0.6737025368927209
+1000, -0.6, -0.4, -0.2, 0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 2.8, 3.0, 3.2, 3.6
+, 0.020481263776634836, 0.03747584236618773, 0.07963219211712719, 0.42117945879058266, 0.40087635526094045, 0.4186096119797778, 0.7519767441860465, 0.6969740019889189, 0.6769121710047986, 0.5095117468832265, 0.49996377012356535, 0.42357137893493324, 0.3704784074335224, 0.5022112276689343, 0.5377495655874323, 0.9377135348226019, 0.518641826827345, 0.6148997981190606, 0.925832429274806, 0.9306706710610997, 0.5275370793684547
+10000000, -0.6, 0.2, 0.6, 1.0, 1.2, 1.4, 2.2, 2.6, 2.8, 3.6
+, 0.2450956648098813, 0.34003811136989204, 0.5689392891716222, 0.5240494732020156, 0.4197691734921817, 0.6071833648393195, 0.47977746870653687, 0.1474288840262582, 0.2158490566037736, 0.059728506787330306
+I
+200, -4.2, -4.0, -3.8, -3.6, -3.4, -3.2, -3.0, -2.8, -2.6, -2.4, -2.2, -2.0, -1.8, -1.6, -1.4, -1.2, -1.0, -0.8, -0.6, -0.4, -0.2, 0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 2.8, 3.0, 3.2, 3.4, 3.6
+, 0.010246568324761396, 0.023586419611002423, 0.07326453667116309, 0.02266434565723754, 0.19125014334998405, 0.049215674536650926, 0.08042765604892763, 0.11504040934022898, 0.09190473758714221, 0.07884776581058621, 0.13204286686172295, 0.17339014874279796, 0.14738531701866997, 0.1925666588813994, 0.2798288367649437, 0.30356530000018567, 0.37802490411090917, 0.3891635072532392, 0.4188735667360788, 0.4130451708923584, 0.4090566074203953, 0.4005398324769401, 0.43727658014390886, 0.4525658021391098, 0.49469453336259855, 0.5364548074114078, 0.5487359041804901, 0.5589759259605349, 0.5600275134828192, 0.5857561779201617, 0.5950991838931297, 0.6171171951409766, 0.6208158282379346, 0.5341821673007862, 0.5911918922048982, 0.47767207984960436, 0.6016175443003301, 0.453017422332317, 0.009829615646825916, 0.011933949374280328
+400, -3.2, -3.0, -2.8, -2.6, -2.4, -2.2, -2.0, -1.8, -1.6, -1.4, -1.2, -1.0, -0.8, -0.6, -0.4, -0.2, 0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 2.8
+, 0.009424041651289006, 0.005248090853102813, 0.020104435812286, 0.008380660947748239, 0.011633543757944554, 0.031233862457621414, 0.03796795304800285, 0.05304879411403409, 0.09428391079887828, 0.1957080355293911, 0.26417738982917194, 0.33722314135736386, 0.3835329367560942, 0.38791379723365044, 0.3469048845284936, 0.33981871326454166, 0.3718334747259479, 0.3744119941355528, 0.4371801106903041, 0.4742278199477808, 0.5467307808120919, 0.5889710925569661, 0.6003132839102469, 0.6282891377294968, 0.6667994100593078, 0.7149791981213757, 0.7165443100481403, 0.7648169965214152, 0.7931588888124155, 0.849697960723633, 0.5985009755051228
+600, -2.6, -2.4, -2.2, -2.0, -1.8, -1.6, -1.4, -1.2, -1.0, -0.8, -0.6, -0.4, -0.2, 0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6
+, 0.01177149197646163, 0.019466387676539337, 0.009179617714196748, 0.021002809412977955, 0.012304705104874294, 0.01742489800381316, 0.09673996824968178, 0.20818513532059035, 0.24902690941466604, 0.3201033911616928, 0.3968527717263692, 0.32677150095038016, 0.2956502311222198, 0.3521918640702484, 0.34323878987875367, 0.41238085067793995, 0.4528202043089073, 0.4946606714015018, 0.60916176112803, 0.586244459052103, 0.731691655254136, 0.7615547888406847, 0.7532320282223522, 0.8256747853564931, 0.8227885041950739, 0.9414977098583945, 0.8707420724568614
+800, -1.8, -1.6, -1.4, -1.2, -1.0, -0.8, -0.6, -0.4, -0.2, 0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4
+, 0.004884508436313263, 0.008895670331354973, 0.04738253012569462, 0.15700893886749803, 0.2720568723512916, 0.29754465051552165, 0.3529009205231974, 0.33901402505796213, 0.33151291774566327, 0.3171419785124146, 0.39610993206239475, 0.42435592249318754, 0.4284240846602554, 0.48610410052424313, 0.5011209748404598, 0.5923040805122267, 0.6801122435468188, 0.6003811302269592, 0.6886824799977288, 0.6536244005652843, 0.7340922067541863, 0.9749464234875972
+1000, -2.0, -1.4, -1.2, -1.0, -0.8, -0.6, -0.4, -0.2, 0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2
+, 0.04006366374589266, 0.016420176967562962, 0.10541928765426886, 0.1842196914154018, 0.33370157870353867, 0.4140144214086954, 0.37627524716443256, 0.376828275689411, 0.350294020866546, 0.29056694294813423, 0.428977185963412, 0.4437891708347922, 0.4040640317539013, 0.5436759732095426, 0.6396942795183248, 0.699574241911313, 0.6264500766775059, 0.6958787809288652, 0.6647049856983595, 0.9007007532728866
+10000000, -1.4, -1.2, -1.0, -0.8, -0.6, -0.4, -0.2, 0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0
+, 0.05928374933750602, 0.2840734480639214, 0.355188042763727, 0.4981825035676783, 0.522066931657905, 0.687219937903835, 0.4285758086769892, 0.26404535582320265, 0.4070341937448583, 0.31549829407614327, 0.3522842812258061, 0.41463591162408975, 0.44042322850815757, 0.8108811576260953, 0.6660499661785326, 0.6714949448238751, 0.6945054584794939, 0.9471616054797473
+P
+200, -3.8, -3.6, -3.4, -3.2, -3.0, -2.8, -2.6, -2.4, -2.2, -2.0, -1.8, -1.6, -1.4, -1.2, -1.0, -0.8, -0.6, -0.4, -0.2, 0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 2.8, 3.0, 3.2, 3.4, 3.6, 3.8, 4.0, 4.2
+, 0.09462093250004656, 0.06513499980673217, 0.25836149525869284, 0.003590843571806108, 0.08011419031573228, 0.03750805525576047, 0.0574609648224664, 0.021046661598639223, 0.03965651331683649, 0.03233547498093971, 0.05244949461037999, 0.059239211279768764, 0.08658427873468452, 0.11641077018764909, 0.17102302987730567, 0.21557776345358962, 0.3488992728757439, 0.38412126513874806, 0.4717518589355339, 0.48086303211958253, 0.5349972443434652, 0.5523284345890979, 0.5139727330404497, 0.5737275580736053, 0.646507295963126, 0.6177418767988746, 0.5913879649161384, 0.6113435859450091, 0.6248086488637173, 0.6177495838258914, 0.5915088103951179, 0.5390155146848349, 0.5544234138321293, 0.4961989976316854, 0.5910782276103086, 0.575955804525867, 0.8040228012576552, 0.2552364547730815, 0.1539699424587969, 0.6105382318958665, 0.6920195597291678
+400, -3.2, -2.8, -2.6, -2.4, -2.2, -2.0, -1.8, -1.6, -1.4, -1.2, -1.0, -0.8, -0.6, -0.4, -0.2, 0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 2.8, 3.0, 3.2, 3.4, 3.6, 4.0, 4.2
+, 0.027678544003005952, 0.0017759936101448578, 0.01563976484987035, 0.02662887534696838, 0.010267917113890223, 0.014499665143659572, 0.027299347695871414, 0.045885094521211214, 0.04395609633506502, 0.07075355873801675, 0.11122160543559785, 0.19482765066850968, 0.3102447121351171, 0.4323382675846813, 0.5049196275808877, 0.5340408301827624, 0.5699327744168944, 0.5646308086676382, 0.5898440411347238, 0.5960532705788892, 0.6456568185067169, 0.6761301863788893, 0.6705221804706994, 0.6794427710153623, 0.6560926262495437, 0.6670270517403344, 0.6415870485838746, 0.4940385904199614, 0.5459239564924565, 0.47599332002445893, 0.409220079384302, 0.42847584927258375, 0.827666355527503, 0.6427397436884055, 0.3387975859228055, 0.6658481930242676
+600, -2.6, -2.4, -2.2, -2.0, -1.8, -1.6, -1.4, -1.2, -1.0, -0.8, -0.6, -0.4, -0.2, 0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 2.8, 3.0, 3.2, 3.4
+, 0.054115861337130235, 0.046296087292164195, 0.056336173545012996, 0.005138426504631574, 0.03016715284976033, 0.02195661225379361, 0.035469037639700524, 0.043213639799410224, 0.07923069137404684, 0.1892981614814477, 0.24008662810215636, 0.4542352013348483, 0.5155927001365727, 0.6227024593529396, 0.6069408758206023, 0.5689367573494439, 0.6173067228915726, 0.6507688014522729, 0.5604747283213789, 0.7005841663886421, 0.6021972001890809, 0.7322327525953377, 0.6256764860648757, 0.6644107146326537, 0.6404289926815111, 0.5798792570169877, 0.48913332794575626, 0.4739894981973522, 0.6169184160982089, 0.6311019946564094, 0.9162938262863316
+800, -2.4, -2.2, -1.8, -1.6, -1.4, -1.2, -1.0, -0.8, -0.6, -0.4, -0.2, 0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 2.8, 3.0, 3.2
+, 0.00625109691006886, 0.0036866050811829405, 0.010821473610371099, 0.034581709047270474, 0.052505947010089406, 0.04046046640914797, 0.0715445762534076, 0.19387348265185214, 0.3024834157149413, 0.4407693068754491, 0.5501948550333603, 0.4344640358714685, 0.4429962655179792, 0.4559017802592965, 0.4550889515888062, 0.562065860749629, 0.5872819382503642, 0.5031074411074145, 0.549570630011202, 0.7331689607663807, 0.637804892388616, 0.7508243979930967, 0.6847389871555631, 0.6837776185382219, 0.7089342805159007, 0.7548686754100637, 0.6858453269953747, 0.737874223470343
+1000, -1.8, -1.6, -1.4, -1.2, -1.0, -0.8, -0.6, -0.4, -0.2, 0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 2.8, 3.0
+, 0.09319850573232, 0.10979172199248835, 0.06948530038214824, 0.07586792624252905, 0.1989606990626378, 0.3974041167469781, 0.4836987107065937, 0.43529270200348963, 0.5872083609038189, 0.4748060743676909, 0.4782649923500425, 0.47660581529267176, 0.40493349371783804, 0.4729478286637323, 0.5031491548381056, 0.4918696117603916, 0.474799166651737, 0.7606885434541573, 0.6515931714096899, 0.8523660209056383, 0.6549542201339508, 0.49738075923608915, 0.37358200278550074, 0.9102043744992286, 0.30461699146099175
+10000000, -1.2, -1.0, -0.8, -0.6, -0.4, -0.2, 0.2, 0.4, 0.6, 0.8, 1.0, 1.4, 1.6, 1.8, 2.0, 2.4, 2.8, 3.0
+, 0.002034225211333397, 0.03213966868366234, 0.1254929577464789, 0.22886329058900245, 0.5338868536424239, 0.30411880078453357, 0.7558683600047184, 0.8943652386947497, 0.5068308181096108, 0.8747794169548951, 0.808677163898561, 0.6541717723070068, 0.520123659549802, 0.8308427892277724, 0.75944364805703, 0.46422176679969807, 0.11903193440828615, 0.9246754822273444
+V
+200, -4.2, -4.0, -3.8, -3.6, -3.4, -3.2, -3.0, -2.8, -2.6, -2.4, -2.2, -2.0, -1.8, -1.6, -1.4, -1.2, -1.0, -0.8, -0.6, -0.4, -0.2, 0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 2.8, 3.0
+, 0.3013177924972648, 0.0670576962538446, 0.027947536968587417, 0.025471567022443797, 0.17738326284128084, 0.10698026054520915, 0.027192326456929903, 0.04736489830728461, 0.15565145058718088, 0.08889759595104872, 0.0901815261535527, 0.12890229680120277, 0.17640442149470179, 0.20057478536198106, 0.25497736014857153, 0.2845496101729879, 0.3387008081814645, 0.36859541367677057, 0.408859593377653, 0.42852982770728926, 0.43491545736005727, 0.4437173153173867, 0.4307511980475097, 0.4688229717283917, 0.5041690529385188, 0.5206150940885195, 0.5504178549950146, 0.604449454781223, 0.5852695922917379, 0.5892740759521515, 0.5821242214118382, 0.611738803380447, 0.5748701424067844, 0.5470664583475426, 0.4366875437443472, 0.2990467205099567, 0.17194313586429896
+400, -3.4, -3.2, -3.0, -2.8, -2.6, -2.4, -2.2, -2.0, -1.8, -1.6, -1.4, -1.2, -1.0, -0.8, -0.6, -0.4, -0.2, 0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 3.0
+, 0.007630710431630884, 0.05643138079149608, 0.0019464106682222882, 0.00495914554400256, 0.008471384625919275, 0.022434103491537804, 0.040253776825090605, 0.025356097618350212, 0.048630164072312, 0.06994433785325964, 0.10054807768512329, 0.17714681726250375, 0.262931751831555, 0.34550802640469575, 0.3781959689270546, 0.43546932456834325, 0.4111227842326892, 0.39342474726021504, 0.40754351242412284, 0.460087545031051, 0.4784670790288331, 0.5272787211953236, 0.5658096821582352, 0.6095502530391147, 0.6572364343932448, 0.6458428060835956, 0.699498928622632, 0.7675563268175648, 0.7165153170099512, 0.5393942384511748, 0.5587490608280018, 0.7684784086894817
+600, -2.8, -2.6, -2.4, -2.2, -2.0, -1.8, -1.6, -1.4, -1.2, -1.0, -0.8, -0.6, -0.4, -0.2, 0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4
+, 0.061032997065434115, 0.18533639985747144, 0.0145577041202563, 0.010942786101539745, 0.07387934237880509, 0.037536176376309634, 0.02763024311231824, 0.02265328277135838, 0.09520478453610436, 0.1595129075059143, 0.22597260291075094, 0.37063686634929416, 0.4028000965396746, 0.40189585160555535, 0.32174279329124866, 0.37195239626061044, 0.4539851836669101, 0.4666124404448917, 0.5233672984387059, 0.5443786020355682, 0.670588238862655, 0.6746727393780464, 0.774273657653073, 0.8059482440811514, 0.7534118409082837, 0.933769318652744, 0.9199396810574295
+800, -2.0, -1.8, -1.6, -1.4, -1.2, -1.0, -0.8, -0.6, -0.4, -0.2, 0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4
+, 0.008536139445826405, 0.010647452272946844, 0.003065442904427912, 0.004083085051204419, 0.017935306813610788, 0.09716361787367706, 0.19725368574759128, 0.3505081624049802, 0.4204715759928817, 0.45469008403510625, 0.388999422485893, 0.32305500994632613, 0.39140601027418337, 0.48052658276599364, 0.421967881355336, 0.5799579944888391, 0.619119965966238, 0.619504925624972, 0.6769064254531707, 0.7778709874558832, 0.771651999854801, 0.7479361219585633, 0.5246872402663989
+1000, -1.0, -0.8, -0.6, -0.4, -0.2, 0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2
+, 0.03892955516942246, 0.12043398243351962, 0.2645304545541721, 0.4365200127998329, 0.437088025611357, 0.35702064605615885, 0.4010590154472944, 0.36781079834103564, 0.4587836912312046, 0.39663279275577046, 0.6365005914806564, 0.5655098255829267, 0.593426197811947, 0.6692760067022221, 0.8622693278223753, 0.7184982472426565, 0.7060497525545142
+10000000, -1.4, -1.2, -1.0, -0.8, -0.6, -0.4, -0.2, 0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 2.0
+, 0.017728944142882157, 0.007167824432547233, 0.08493880095308559, 0.2528489732042521, 0.4813898894916351, 0.36070591557949294, 0.39824076805492237, 0.3119042195275812, 0.32650985724376896, 0.49659876345439163, 0.5211131565504622, 0.4260184611915101, 0.5637321616051639, 0.5428210040346628, 0.7687209074612477, 0.7000895494459963, 0.8891690518938169
action.show_html_source = Show HTML Source
action.print = Print...
action.web_service = Web Service
+action.hmmer = HMMER
action.cancel_job = Cancel Job
action.start_job = Start Job
action.revert = Revert
action.text = Text
action.by_pairwise_id = By Pairwise Identity
action.by_id = By Id
+action.by_evalue = By E-Value
+action.by_bit_score = By Bit Score
action.by_length = By Length
action.by_group = By Group
action.unmark_as_reference = Unmark as Reference
action.border_colour = Border colour
action.edit_new_group = Edit New Group
action.hide_sequences = Hide Sequences
+action.add_background_frequencies = Add Background Frequencies
action.sequences = Sequences
action.ids = IDS
action.ids_sequences = IDS and sequences
tooltip.select_highlighted_columns = Press B to mark highlighted columns, Ctrl-(or Cmd)-B to toggle, and Alt-B to mark all but highlighted columns
action.deselect_all = Deselect all
action.invert_selection = Invert selection
+action.filter_by_evalue = Filter by E-Value
+action.filter_by_score = Filter by Score
action.using_jmol = Using Jmol
action.undo_changes_to_feature_settings = Undo all unapplied changes to feature settings
action.undo_changes_to_feature_settings_and_close_the_dialog = Undo all pending changes and close the feature settings dialog
label.colourScheme_buriedindex = Buried Index
label.colourScheme_purine/pyrimidine = Purine/Pyrimidine
label.colourScheme_nucleotide = Nucleotide
+label.colourScheme_hmmer-uniprot = HMMER profile v global background
+label.colourScheme_hmmer-alignment = HMMER profile v alignment background
+label.colourScheme_hmm_match_score = HMM Match Score
label.colourScheme_t-coffeescores = T-Coffee Scores
label.colourScheme_rnahelices = By RNA Helices
label.colourScheme_sequenceid = Sequence ID Colour
label.save_state = Save State
label.restore_state = Restore State
label.saving_jalview_project = Saving jalview project {0}
+label.loading_jalview_project = Loading jalview project {0}
label.load_feature_colours = Load Feature Colours
label.save_feature_colours = Save Feature Colour Scheme
label.select_startup_file = Select startup file
error.implementation_error_msawbjob_called = Implementation error - StartJob(MsaWSJob) called on a WSJobInstance {0}
error.implementation_error_cannot_attach_ws_menu_entry = IMPLEMENTATION ERROR: cannot attach WS Menu Entry without service handle reference!
error.parameter_migration_not_implemented_yet = Parameter migration not implemented yet
+error.implementation_error_cannot_set_jaba_option = Implementation error: cannot set Jaba Option to a value outside its allowed value range!
error.implementation_error_valuetype_doesnt_support_jabaws_type = IMPLEMENTATION ERROR: jalview.ws.params.ValueConstrainI.ValueType does not support the JABAWS type : {0}
error.cannot_create_jabaws_param_set = Cannot create a JabaWSParamSet from non-JabaWS parameters
error.cannot_set_arguments_to_jabaws_param_set = Cannot set arguments to a JabaWSParamSet that are not JabaWS arguments
exception.ranml_invalid_file = Invalid RNAML file ({0})
exception.ranml_problem_parsing_data = Problem parsing data as RNAML ({0})
exception.pfam_no_sequences_found = No sequences found (PFAM input)
+exception.hmmer_no_valid_sequences_found = No valid sequences found
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.unknown_annotation_detected = Unknown annotation detected: {0} {1}
exception.invocation_target_calling_url = InvocationTargetException while calling openURL: {0}
exception.illegal_access_calling_url = IllegalAccessException while calling openURL: {0}
exception.interrupted_launching_browser = InterruptedException while launching browser: {0}
+exception.ebiembl_retrieval_failed_on = EBI EMBL XML retrieval failed on {0}:{1}
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_pdb = Fetching PDB {0}
status.refreshing_news = Refreshing news
status.opening_params = Opening {0}
+status.waiting_sequence_database_fetchers_init = Waiting for Sequence Database Fetchers to initialise
+status.init_sequence_database_fetchers = Initialising Sequence Database Fetchers
status.fetching_sequence_queries_from = Fetching {0} sequence queries from {1}
status.finshed_querying = Finished querying
status.parsing_results = Parsing results.
status.searching_3d_beacons = Searching 3D Beacons
status.no_structures_discovered_from_3d_beacons = No models discovered from 3D Beacons
status.opening_file_for = opening file for
+status.running_hmmbuild = Building Hidden Markov Model
+status.running_hmmalign = Creating alignment with Hidden Markov Model
+status.running_search = Searching for matching sequences
status.colouring_structures = Colouring structures
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.error_loading_file_params = Error loading file {0}
+label.error_loading_jalview_file = Error loading Jalview file
warn.out_of_memory_when_action = Out of memory when {0}\!\!\nSee help files for increasing Java Virtual Machine memory.
warn.out_of_memory_loading_file = Out of memory loading file {0}\!\!\nSee help files for increasing Java Virtual Machine memory.
label.out_of_memory = Out of memory
label.invalid_id_column_width = Invalid ID Column width
warn.user_defined_width_requirements = The user defined width for the\nannotation and sequence ID columns\nin exported figures must be\nat least 12 pixels wide.
+label.couldnt_create_sequence_fetcher = Couldn't create SequenceFetcher
+warn.couldnt_create_sequence_fetcher_client = Could not create the sequence fetcher client. Check error logs for details.
warn.server_didnt_pass_validation = Service did not pass validation.\nCheck the Jalview Console for more details.
warn.url_must_contain = Sequence URL must contain $SEQUENCE_ID$, $DB_ACCESSION$, or a regex
warn.urls_not_contacted = URLs that could not be contacted
option.autosearch = Autosearch
label.retrieve_ids = Retrieve IDs
label.display_settings_for = Display settings for {0} features
+label.simple = Simple
label.simple_colour = Simple Colour
label.colour_by_text = Colour by text
label.graduated_colour = Graduated Colour
label.pca = PCA
label.create_image_of = Create {0} image of {1}
label.click_to_edit = Click to edit, right-click for menu
+label.hmmalign = hmmalign
+label.use_hmm = HMM profile to use
+label.use_sequence = Sequence to use
+label.hmmbuild = hmmbuild
+label.hmmsearch = hmmsearch
+label.jackhmmer = jackhmmer
+label.installation = Installation
+label.hmmer_location = HMMER Binaries Installation Location
+label.cygwin_location = Cygwin Binaries Installation Location (Windows)
+label.information_annotation = Information Annotation
+label.ignore_below_background_frequency = Ignore Below Background Frequency
+label.information_description = Information content, measured in bits
+warn.no_hmm = No Hidden Markov model found.\nRun hmmbuild or load an HMM file first.
+label.no_sequences_found = No matching sequences, or an error occurred.
+label.hmmer = HMMER
+label.trim_termini = Trim Non-Matching Termini
+label.trim_termini_desc = If true, non-matching regions on either end of the resulting alignment are removed.
+label.no_of_sequences = Number of sequences returned
+label.reporting_cutoff = Reporting Cut-off
+label.inclusion_threshold = Inlcusion Threshold
+label.freq_alignment = Use alignment background frequencies
+label.freq_uniprot = Use Uniprot background frequencies
+label.hmmalign_options = hmmalign options
+label.hmmsearch_options = hmmsearch options
+label.jackhmmer_options = jackhmmer options
+label.executable_not_found = The ''{0}'' executable file was not found
+warn.command_failed = {0} failed
+label.invalid_folder = Invalid Folder
+label.number_of_results = Number of Results to Return
+label.number_of_iterations = Number of jackhmmer Iterations
+label.auto_align_seqs = Automatically Align Fetched Sequences
+label.new_returned = new sequences returned
+label.use_accessions = Return Accessions
+label.check_for_new_sequences = Return Number of New Sequences
+label.evalue = E-Value
+label.reporting_seq_evalue = Reporting Sequence E-value Cut-off
+label.reporting_seq_score = Reporting Sequence Score Threshold
+label.reporting_dom_evalue = Reporting Domain E-value Cut-off
+label.reporting_dom_score = Reporting Domain Score Threshold
+label.inclusion_seq_evalue = Inclusion Sequence E-value Cut-off
+label.inclusion_seq_score = Inclusion Sequence Score Threshold
+label.inclusion_dom_evalue = Inclusion Domain E-value Cut-off
+label.inclusion_dom_score = Inclusion Domain Score Threshold
+label.number_of_results_desc = The maximum number of hmmsearch results to display
+label.number_of_iterations_desc = The number of iterations jackhmmer will complete when searching for new sequences
+label.auto_align_seqs_desc = If true, all fetched sequences will be aligned to the hidden Markov model with which the search was performed
+label.check_for_new_sequences_desc = Display number of new sequences returned from hmmsearch compared to the previous alignment
+label.use_accessions_desc = If true, the accession number of each sequence is returned, rather than that sequence's name
+label.reporting_seq_e_value_desc = The E-value cutoff for returned sequences
+label.reporting_seq_score_desc = The score threshold for returned sequences
+label.reporting_dom_e_value_desc = The E-value cutoff for returned domains
+label.reporting_dom_score_desc = The score threshold for returned domains
+label.inclusion_seq_e_value_desc = Sequences with an E-value less than this cut-off are classed as significant
+label.inclusion_seq_score_desc = Sequences with a bit score greater than this threshold are classed as significant
+label.inclusion_dom_e_value_desc = Domains with an E-value less than this cut-off are classed as significant
+label.inclusion_dom_score_desc = Domains with a bit score greater than this threshold are classed as significant
+label.add_database = Add Database
+label.this_alignment = This alignment
+warn.invalid_format = This is not a valid database file format. The current supported formats are Fasta, Stockholm and Pfam.
+label.database_for_hmmsearch = The database hmmsearch will search through
+label.use_reference = Use Reference Annotation
+label.use_reference_desc = If true, hmmbuild will keep all columns defined as a reference position by the reference annotation
+label.hmm_name = Alignment HMM Name
+label.hmm_name_desc = The name given to the HMM for the alignment
+warn.no_reference_annotation = No reference annotation found
+label.hmmbuild_for = Build HMM for
+label.hmmbuild_for_desc = Build an HMM for the selected sets of sequences
+label.alignment = Alignment
+label.groups_and_alignment = All groups and alignment
+label.groups = All groups
+label.selected_group = Selected group
+label.use_info_for_height = Use Information Content as Letter Height
+action.search = Search
label.backupfiles_confirm_delete = Confirm delete
label.backupfiles_confirm_delete_old_files = Delete the following older backup files? (see the Backups tab in Preferences for more options)
label.backupfiles_confirm_save_file = Confirm save file
label.append_to_filename = Append to filename (%n is replaced by the backup number)
label.append_to_filename_tooltip = %n in the text will be replaced by the backup number. The text will appear after the filename. See the summary box above.
label.index_digits = Number of digits to use for the backup number (%n)
+label.summary_of_backups_scheme = Summary of backup scheme
label.scheme_examples = Scheme examples
label.increment_index = Increase appended text numbers - newest file has largest number.
label.reverse_roll = "Roll" appended text numbers - newest backup file is always number 1.
label.keep_all_versions_description = Keep all previous versions of the file
label.rolled_backups_description = Keep the last nine versions of the file from _bak.1 (newest) to _bak.9 (oldest)
label.cancel_changes_description = Cancel changes made to your last saved Custom scheme
+label.previously_saved_scheme = Previously saved scheme
label.no_backup_files = NO BACKUP FILES
label.include_backup_files = Include backup files
label.cancel_changes = Cancel changes
label.warning_confirm_change_reverse = Warning!\nIf you change the increment/decrement of the backup filename number, without changing the suffix or number of digits,\nthis may cause loss of backup files created with the previous backup filename scheme.\nAre you sure you wish to do this?
label.change_increment_decrement = Change increment/decrement?
+label.was_previous = was {0}
label.newerdelete_replacement_line = Backup file\n''{0}''\t(modified {2}, size {4})\nis to be deleted and replaced by apparently older file\n''{1}''\t(modified {3}, size {5}).
label.confirm_deletion_or_rename = Confirm deletion of ''{0}'' or rename to ''{1}''?
label.newerdelete_line = Backup file\n''{0}''\t(modified {2}, size {4})\nis to be deleted but is newer than the oldest remaining backup file\n''{1}''\t(modified {3}, size {5}).
label.overview_window = Ventana resumen
label.none = Ninguno
label.above_identity_threshold = Por encima del umbral de identidad
-label.show_sequence_features = Mostrar las caracterÃsticas de secuencia
+label.show_sequence_features = Mostrar las caracterÃsticas de las secuencias
label.nucleotide = Nucleótido
label.to_new_alignment = A nuevo alineamiento
label.to_this_alignment = Añadir a este alineamiento
label.couldnt_locate = No se pudo localizar {0}
label.url_not_found = URL no encontrada
label.new_sequence_url_link = Enlace a una nueva secuencia URL
+label.cannot_edit_annotations_in_wrapped_view = No se pueden editar anotaciones en vista envolvente
+label.wrapped_view_no_edit = Vista envolvente - no editar
label.error_retrieving_data = Error en la recuperación de datos
label.user_colour_scheme_must_have_name = El esquema de colores del usuario debe tener un nombre
label.no_name_colour_scheme = No hay nombre para el esquema de colores
label.link_name = Nombre del enalce
label.pdb_file = Fichero PDB
label.colour_with_jmol = Colorear con Jmol
+label.jmol = Jmol
label.sort_alignment_by_tree = Ordenar alineamiento por árbol
label.mark_unlinked_leaves = Marcar las hojas como no enlazadas
label.associate_leaves_with = Asociar hojas con
label.save_state = Guardar estado
label.restore_state = Restaurar estado
label.saving_jalview_project = Guardando el proyecto de Jalview {0}
+label.loading_jalview_project = Cargando el proyecto de Jalview {0}
label.load_feature_colours = Cargar colores de caracterÃsticas
label.save_feature_colours = Guardar esquema cromático de caracterÃsticas
label.select_startup_file = Seleccionar fichero de arranque
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.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.implementation_error_null_fileparse = Error de implementación. FileParse nulo en el construictor de copia
error.implementation_error_structure_selection_manager_null = Error de implementación. El contexto structure selection manager's es nulo
error.implementation_error_msawbjob_called = Error de implementación - StartJob(MsaWSJob) invocado en un WSJobInstance {0}
error.implementation_error_cannot_attach_ws_menu_entry = Error de implementación: ¡no es posible adjunto una WS Menu Entry sin una referencia a un manejador del servicio!
error.parameter_migration_not_implemented_yet = La migración de parámetros no se ha implementado todavÃa
+error.implementation_error_cannot_set_jaba_option = Error de implementación: no es posible establecer el valor de Jaba Option a un valor fuera de su rango permitido
error.implementation_error_valuetype_doesnt_support_jabaws_type = Error de implementación: jalview.ws.params.ValueConstrainI.ValueType no soporta el tipo JABAWS: {0}
error.cannot_create_jabaws_param_set = No es posible crear un JabaWSParamSet con parámetros no JabaWS
error.cannot_set_arguments_to_jabaws_param_set = No es posible establecer argumentos en JabaWSParamSet que no sean argumentos JabaWS
status.fetching_db_refs = Recuperando db refs
label.font_doesnt_have_letters_defined = La fuente no tiene letras definidas\npor lo que no puede emplease\ncon datos de alineamientos
label.font_too_small = Tamaño de la letra es demasiado pequeña
+label.error_loading_file_params = Error cargando el fichero {0}
+label.error_loading_jalview_file = Error cargando el fichero Jalview
warn.out_of_memory_when_action = Sin memoria al {0}\!\!\nConsulte los ficheros de ayuda para ajustar la memoria de la m\u00E1quina virtual de Java.
warn.out_of_memory_loading_file = Sin memoria al cargar el fichero {0}\!\!\nConsulte los ficheros de ayuda para ajustar la memoria de la m\u00E1quina virtual de Java.
label.out_of_memory = Sin memoria
exception.outofmemory_loading_mmcif_file=Sin memoria al cargar el fichero mmCIF
label.hide_columns_not_containing=Ocultar las columnas que no contengan
label.pdb_sequence_fetcher=Recuperador de secuencias PDB
+status.waiting_for_user_to_select_output_file=Esperando que el usuario seleccione el fichero {0}
action.prev_page=<<
status.cancelled_image_export_operation=Operación de exportación {0} cancelada
label.couldnt_run_groovy_script=No se ha podido ejecutar el script Groovy
option.autosearch = Auto búsqueda
label.retrieve_ids = Recuperar IDs
label.display_settings_for = Visualización de caracterÃsticas {0}
+label.simple = Simple
label.simple_colour = Color simple
label.colour_by_text = Colorear por texto
label.graduated_colour = Color graduado
</xs:attribute>
</xs:complexType>
</xs:element>
+ <xs:element name="hmmerProfile" minOccurs="0" type="xs:string">
+ <xs:annotation>
+ <xs:documentation>name of the project jar entry that holds the HMM file with the profile for the sequence</xs:documentation>
+ </xs:annotation>
+ </xs:element>
</xs:sequence>
<xs:attribute name="colour" type="xs:int" use="optional" />
<xs:attribute name="start" type="xs:int" use="required" />
import jalview.datamodel.AlignmentAnnotation;
import jalview.datamodel.AlignmentI;
import jalview.datamodel.Annotation;
+import jalview.datamodel.HiddenMarkovModel;
import jalview.datamodel.Profile;
import jalview.datamodel.ProfileI;
import jalview.datamodel.Profiles;
import jalview.datamodel.ResidueCount.SymbolCounts;
import jalview.datamodel.SequenceI;
import jalview.ext.android.SparseIntArray;
+import jalview.schemes.ResidueProperties;
import jalview.util.Comparison;
import jalview.util.Format;
import jalview.util.MappingUtils;
* This class is used extensively in calculating alignment colourschemes that
* depend on the amount of conservation in each alignment column.
*
- * @author $author$
- * @version $Revision$
*/
public class AAFrequency
{
- public static final String PROFILE = "P";
-
- /*
- * Quick look-up of String value of char 'A' to 'Z'
- */
- private static final String[] CHARS = new String['Z' - 'A' + 1];
+ private static final double LOG2 = Math.log(2);
- static
- {
- for (char c = 'A'; c <= 'Z'; c++)
- {
- CHARS[c - 'A'] = String.valueOf(c);
- }
- }
+ public static final String PROFILE = "P";
public static final ProfilesI calculate(List<SequenceI> list, int start,
int end)
}
/**
+ * Returns the full set of profiles for a hidden Markov model. The underlying
+ * data is the raw probabilities of a residue being emitted at each node,
+ * however the profiles returned by this function contain the percentage
+ * chance of a residue emission.
+ *
+ * @param hmm
+ * @param width
+ * The width of the Profile array (Profiles) to be returned.
+ * @param start
+ * The alignment column on which the first profile is based.
+ * @param end
+ * The alignment column on which the last profile is based.
+ * @param removeBelowBackground
+ * if true, symbols with a match emission probability less than
+ * background frequency are ignored
+ * @return
+ */
+ public static ProfilesI calculateHMMProfiles(final HiddenMarkovModel hmm,
+ int width, int start, int end, boolean removeBelowBackground,
+ boolean infoLetterHeight)
+ {
+ ProfileI[] result = new ProfileI[width];
+ char[] symbols = hmm.getSymbols().toCharArray();
+ int symbolCount = symbols.length;
+ for (int column = start; column < end; column++)
+ {
+ ResidueCount counts = new ResidueCount();
+ for (char symbol : symbols)
+ {
+ int value = getAnalogueCount(hmm, column, symbol,
+ removeBelowBackground, infoLetterHeight);
+ counts.put(symbol, value);
+ }
+ int maxCount = counts.getModalCount();
+ String maxResidue = counts.getResiduesForCount(maxCount);
+ int gapCount = counts.getGapCount();
+ ProfileI profile = new Profile(symbolCount, gapCount, maxCount,
+ maxResidue);
+ profile.setCounts(counts);
+
+ result[column] = profile;
+ }
+ return new Profiles(result);
+ }
+
+ /**
* 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
}
/**
- * Derive the gap count annotation row.
+ * Derive the information 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 'ignore below background frequency',
+ * which may in turn result in a change in the derived values.
+ *
+ * @param information
+ * the annotation row to add annotations to
+ * @param profiles
+ * the source information data
+ * @param startCol
+ * start column (inclusive)
+ * @param endCol
+ * end column (exclusive)
+ * @param ignoreGaps
+ * if true, normalise residue percentages
+ * @param showSequenceLogo
+ * if true include all information symbols, else just show modal
+ * residue
+ */
+ public static float completeInformation(AlignmentAnnotation information,
+ ProfilesI profiles, int startCol, int endCol)
+ {
+ // long now = System.currentTimeMillis();
+ if (information == null || information.annotations == null)
+ {
+ /*
+ * called with a bad alignment annotation row
+ * wait for it to be initialised properly
+ */
+ return 0;
+ }
+
+ float max = 0f;
+ SequenceI hmmSeq = information.sequenceRef;
+
+ int seqLength = hmmSeq.getLength();
+ if (information.annotations.length < seqLength)
+ {
+ return 0;
+ }
+
+ HiddenMarkovModel hmm = hmmSeq.getHMM();
+
+ for (int column = startCol; column < endCol; column++)
+ {
+ if (column >= seqLength)
+ {
+ // hmm consensus sequence is shorter than the alignment
+ break;
+ }
+
+ float value = hmm.getInformationContent(column);
+ boolean isNaN = Float.isNaN(value);
+ if (!isNaN)
+ {
+ max = Math.max(max, value);
+ }
+
+ String description = isNaN ? null
+ : String.format("%.4f bits", value);
+ information.annotations[column] = new Annotation(
+ Character.toString(
+ Character.toUpperCase(hmmSeq.getCharAt(column))),
+ description, ' ', value);
+ }
+
+ information.graphMax = max;
+ return max;
+ }
+
+ /**
+ * Derive the occupancy count annotation
*
- * @param gaprow
+ * @param occupancy
* the annotation row to add annotations to
* @param profiles
* the source consensus data
* @param endCol
* end column (exclusive)
*/
- public static void completeGapAnnot(AlignmentAnnotation gaprow,
+ public static void completeGapAnnot(AlignmentAnnotation occupancy,
ProfilesI profiles, int startCol, int endCol, long nseq)
{
- if (gaprow == null || gaprow.annotations == null
- || gaprow.annotations.length < endCol)
+ if (occupancy == null || occupancy.annotations == null
+ || occupancy.annotations.length < endCol)
{
/*
* called with a bad alignment annotation row
return;
}
// always set ranges again
- gaprow.graphMax = nseq;
- gaprow.graphMin = 0;
+ occupancy.graphMax = nseq;
+ occupancy.graphMin = 0;
double scale = 0.8 / nseq;
for (int i = startCol; i < endCol; i++)
{
* happens if sequences calculated over were
* shorter than alignment width
*/
- gaprow.annotations[i] = null;
+ occupancy.annotations[i] = null;
return;
}
String description = "" + gapped;
- gaprow.annotations[i] = new Annotation("", description, '\0', gapped,
+ occupancy.annotations[i] = new Annotation("", description, '\0',
+ gapped,
jalview.util.ColorUtils.bleachColour(Color.DARK_GRAY,
(float) scale * gapped));
}
return result;
}
+
/**
* Extract a sorted extract of cDNA codon profile data. The returned array
* contains
}
return scale;
}
+
+ /**
+ * Returns the sorted HMM profile for the given column of the alignment. The
+ * returned array contains
+ *
+ * <pre>
+ * [profileType=0, numberOfValues, 100, charValue1, percentage1, charValue2, percentage2, ...]
+ * in descending order of percentage value
+ * </pre>
+ *
+ * @param hmm
+ * @param column
+ * @param removeBelowBackground
+ * if true, ignores residues with probability less than their
+ * background frequency
+ * @param infoHeight
+ * if true, uses the log ratio 'information' measure to scale the
+ * value
+ * @return
+ */
+ public static int[] extractHMMProfile(HiddenMarkovModel hmm, int column,
+ boolean removeBelowBackground, boolean infoHeight)
+ {
+ if (hmm == null)
+ {
+ return null;
+ }
+ String alphabet = hmm.getSymbols();
+ int size = alphabet.length();
+ char symbols[] = new char[size];
+ int values[] = new int[size];
+ int totalCount = 0;
+
+ for (int i = 0; i < size; i++)
+ {
+ char symbol = alphabet.charAt(i);
+ symbols[i] = symbol;
+ int value = getAnalogueCount(hmm, column, symbol,
+ removeBelowBackground, infoHeight);
+ values[i] = value;
+ totalCount += value;
+ }
+
+ /*
+ * sort symbols by increasing emission probability
+ */
+ QuickSort.sort(values, symbols);
+
+ int[] profile = new int[3 + size * 2];
+
+ profile[0] = AlignmentAnnotation.SEQUENCE_PROFILE;
+ profile[1] = size;
+ profile[2] = 100;
+
+ /*
+ * order symbol/count profile by decreasing emission probability
+ */
+ if (totalCount != 0)
+ {
+ int arrayPos = 3;
+ for (int k = size - 1; k >= 0; k--)
+ {
+ Float percentage;
+ int value = values[k];
+ if (removeBelowBackground)
+ {
+ percentage = ((float) value) / totalCount * 100f;
+ }
+ else
+ {
+ percentage = value / 100f;
+ }
+ int intPercent = Math.round(percentage);
+ profile[arrayPos] = symbols[k];
+ profile[arrayPos + 1] = intPercent;
+ arrayPos += 2;
+ }
+ }
+ return profile;
+ }
+
+ /**
+ * Converts the emission probability of a residue at a column in the alignment
+ * to a 'count', suitable for rendering as an annotation value
+ *
+ * @param hmm
+ * @param column
+ * @param symbol
+ * @param removeBelowBackground
+ * if true, returns 0 for any symbol with a match emission
+ * probability less than the background frequency
+ * @infoHeight if true, uses the log ratio 'information content' to scale the
+ * value
+ * @return
+ */
+ static int getAnalogueCount(HiddenMarkovModel hmm, int column,
+ char symbol, boolean removeBelowBackground, boolean infoHeight)
+ {
+ double value = hmm.getMatchEmissionProbability(column, symbol);
+ double freq = ResidueProperties.backgroundFrequencies
+ .get(hmm.getAlphabetType()).get(symbol);
+ if (value < freq && removeBelowBackground)
+ {
+ return 0;
+ }
+
+ if (infoHeight)
+ {
+ value = value * (Math.log(value / freq) / LOG2);
+ }
+
+ value = value * 10000d;
+ return Math.round((float) value);
+ }
}
* Build a lookup, by calcId (annotation source), of all annotation types in
* each graph group.
*/
- Map<String, Map<Integer, List<String>>> groupLabels = new HashMap<String, Map<Integer, List<String>>>();
+ Map<String, Map<Integer, List<String>>> groupLabels = new HashMap<>();
// trackers for which calcId!label combinations we have dealt with
- List<String> addedToShown = new ArrayList<String>();
- List<String> addedToHidden = new ArrayList<String>();
+ List<String> addedToShown = new ArrayList<>();
+ List<String> addedToHidden = new ArrayList<>();
for (AlignmentAnnotation aa : annotations)
{
/*
* Build a 'composite label' for types in line graph groups.
*/
- final List<String> labelAsList = new ArrayList<String>();
+ final List<String> labelAsList = new ArrayList<>();
final String displayLabel = aa.label;
labelAsList.add(displayLabel);
if (aa.graph == AlignmentAnnotation.LINE_GRAPH
return (anns == null ? Collections.<AlignmentAnnotation> emptyList()
: Arrays.asList(anns));
}
+
+ /**
+ * replace an existing sequence associated annotation with another, creating
+ * association as necessary.
+ *
+ * @param newAnnot
+ * - annotation row associated with a sequence to be propagated to
+ * its reference annotation
+ * @param typeName
+ * - label used to match existing row
+ * @param calcId
+ * - calcId for existing row
+ */
+ public static void replaceAnnotationOnAlignmentWith(
+ AlignmentAnnotation newAnnot, String typeName, String calcId)
+ {
+ if (newAnnot.sequenceRef != null)
+ {
+ SequenceI dsseq = newAnnot.sequenceRef;
+ while (dsseq.getDatasetSequence() != null)
+ {
+ dsseq = dsseq.getDatasetSequence();
+ }
+ // look for same annotation on dataset and lift this one over
+ List<AlignmentAnnotation> dsan = dsseq.getAlignmentAnnotations(calcId,
+ typeName);
+ if (dsan != null && dsan.size() > 0)
+ {
+ for (AlignmentAnnotation dssan : dsan)
+ {
+ dsseq.removeAlignmentAnnotation(dssan);
+ }
+ }
+ AlignmentAnnotation dssan = new AlignmentAnnotation(newAnnot);
+ dsseq.addAlignmentAnnotation(dssan);
+ dssan.adjustForAlignment();
+ }
+ }
}
import jalview.analysis.scoremodels.PIDModel;
import jalview.analysis.scoremodels.SimilarityParams;
+import jalview.bin.ApplicationSingletonProvider;
+import jalview.bin.ApplicationSingletonProvider.ApplicationSingletonI;
import jalview.datamodel.AlignmentAnnotation;
import jalview.datamodel.AlignmentI;
import jalview.datamodel.AlignmentOrder;
import jalview.util.QuickSort;
import java.util.ArrayList;
+import java.util.BitSet;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
* from the first tobesorted position in the alignment. e.g. (a,tb2,b,tb1,c,tb3
* becomes a,tb1,tb2,tb3,b,c)
*/
-public class AlignmentSorter
+public class AlignmentSorter implements ApplicationSingletonI
{
+
+ private AlignmentSorter()
+ {
+ // private singleton
+ }
+
+ public static AlignmentSorter getInstance()
+ {
+ return (AlignmentSorter) ApplicationSingletonProvider
+ .getInstance(AlignmentSorter.class);
+ }
+
+ /**
+ * types of feature ordering: Sort by score : average score - or total score -
+ * over all features in region Sort by feature label text: (or if null -
+ * feature type text) - numerical or alphabetical Sort by feature density:
+ * based on counts - ignoring individual text or scores for each feature
+ */
+ public static final String FEATURE_SCORE = "average_score";
+
+ public static final String FEATURE_LABEL = "text";
+
+ public static final String FEATURE_DENSITY = "density";
+
/*
* todo: refactor searches to follow a basic pattern: (search property, last
* search state, current sort direction)
*/
- static boolean sortIdAscending = true;
+ boolean sortIdAscending = true;
- static int lastGroupHash = 0;
+ int lastGroupHash = 0;
- static boolean sortGroupAscending = true;
+ boolean sortGroupAscending = true;
- static AlignmentOrder lastOrder = null;
+ AlignmentOrder lastOrder = null;
- static boolean sortOrderAscending = true;
+ boolean sortOrderAscending = true;
- static TreeModel lastTree = null;
+ TreeModel lastTree = null;
- static boolean sortTreeAscending = true;
+ boolean sortTreeAscending = true;
- /*
+ /**
* last Annotation Label used for sort by Annotation score
*/
- private static String lastSortByAnnotation;
+ private String lastSortByAnnotation;
- /*
- * string hash of last arguments to sortByFeature
- * (sort order toggles if this is unchanged between sorts)
+ /**
+ * string hash of last arguments to sortByFeature (sort order toggles if this
+ * is unchanged between sorts)
*/
- private static String sortByFeatureCriteria;
+ private String sortByFeatureCriteria;
- private static boolean sortByFeatureAscending = true;
+ private boolean sortByFeatureAscending = true;
- private static boolean sortLengthAscending;
+ private boolean sortLengthAscending;
+
+ private static boolean sortEValueAscending;
+
+ private static boolean sortBitScoreAscending;
/**
* Sorts sequences in the alignment by Percentage Identity with the given
}
QuickSort.sort(scores, seqs);
-
setReverseOrder(align, seqs);
}
/**
- * Reverse the order of the sort
+ * Sorts by ID. Numbers are sorted before letters.
*
* @param align
- * DOCUMENT ME!
- * @param seqs
- * DOCUMENT ME!
+ * The alignment object to sort
*/
- private static void setReverseOrder(AlignmentI align, SequenceI[] seqs)
+ public static void sortByID(AlignmentI align)
{
- int nSeq = seqs.length;
-
- int len = 0;
+ int nSeq = align.getHeight();
- if ((nSeq % 2) == 0)
- {
- len = nSeq / 2;
- }
- else
- {
- len = (nSeq + 1) / 2;
- }
+ String[] ids = new String[nSeq];
+ SequenceI[] seqs = new SequenceI[nSeq];
- // NOTE: DO NOT USE align.setSequenceAt() here - it will NOT work
- List<SequenceI> asq = align.getSequences();
- synchronized (asq)
+ for (int i = 0; i < nSeq; i++)
{
- for (int i = 0; i < len; i++)
- {
- // SequenceI tmp = seqs[i];
- asq.set(i, seqs[nSeq - i - 1]);
- asq.set(nSeq - i - 1, seqs[i]);
- }
+ ids[i] = align.getSequenceAt(i).getName();
+ seqs[i] = align.getSequenceAt(i);
}
- }
- /**
- * Sets the Alignment object with the given sequences
- *
- * @param align
- * Alignment object to be updated
- * @param tmp
- * sequences as a vector
- */
- private static void setOrder(AlignmentI align, List<SequenceI> tmp)
- {
- setOrder(align, vectorSubsetToArray(tmp, align.getSequences()));
+ QuickSort.sort(ids, seqs);
+ AlignmentSorter as = getInstance();
+ as.sortIdAscending = !as.sortIdAscending;
+ set(align, seqs, as.sortIdAscending);
}
/**
- * Sets the Alignment object with the given sequences
+ * Sorts by sequence length
*
* @param align
- * DOCUMENT ME!
- * @param seqs
- * sequences as an array
+ * The alignment object to sort
*/
- public static void setOrder(AlignmentI align, SequenceI[] seqs)
+ public static void sortByLength(AlignmentI align)
{
- // NOTE: DO NOT USE align.setSequenceAt() here - it will NOT work
- List<SequenceI> algn = align.getSequences();
- synchronized (algn)
- {
- List<SequenceI> tmp = new ArrayList<>();
+ int nSeq = align.getHeight();
- for (int i = 0; i < seqs.length; i++)
- {
- if (algn.contains(seqs[i]))
- {
- tmp.add(seqs[i]);
- }
- }
+ float[] length = new float[nSeq];
+ SequenceI[] seqs = new SequenceI[nSeq];
- algn.clear();
- // User may have hidden seqs, then clicked undo or redo
- for (int i = 0; i < tmp.size(); i++)
- {
- algn.add(tmp.get(i));
- }
+ for (int i = 0; i < nSeq; i++)
+ {
+ seqs[i] = align.getSequenceAt(i);
+ length[i] = (seqs[i].getEnd() - seqs[i].getStart());
}
+
+ QuickSort.sort(length, seqs);
+ AlignmentSorter as = getInstance();
+ as.sortLengthAscending = !as.sortLengthAscending;
+ set(align, seqs, as.sortLengthAscending);
}
/**
- * Sorts by ID. Numbers are sorted before letters.
+ * Sorts by sequence evalue. Currently moves all sequences without an evalue to
+ * the top of the alignment.
*
* @param align
- * The alignment object to sort
+ * The alignment object to sort
*/
- public static void sortByID(AlignmentI align)
+ public static void sortByEValue(AlignmentI align)
{
int nSeq = align.getHeight();
- String[] ids = new String[nSeq];
+ double[] evalue = new double[nSeq];
SequenceI[] seqs = new SequenceI[nSeq];
for (int i = 0; i < nSeq; i++)
{
- ids[i] = align.getSequenceAt(i).getName();
seqs[i] = align.getSequenceAt(i);
+ AlignmentAnnotation[] ann = seqs[i].getAnnotation("Search Scores");
+ if (ann != null)
+ {
+ evalue[i] = ann[0].getEValue();
+ }
+ else
+ {
+ evalue[i] = -1;
+ }
}
- QuickSort.sort(ids, seqs);
+ QuickSort.sort(evalue, seqs);
- if (sortIdAscending)
+ if (sortEValueAscending)
{
setReverseOrder(align, seqs);
}
setOrder(align, seqs);
}
- sortIdAscending = !sortIdAscending;
+ sortEValueAscending = !sortEValueAscending;
}
/**
- * Sorts by sequence length
+ * Sorts by sequence bit score. Currently moves all sequences without a bit
+ * score to the top of the alignment
*
* @param align
- * The alignment object to sort
+ * The alignment object to sort
*/
- public static void sortByLength(AlignmentI align)
+ public static void sortByBitScore(AlignmentI align)
{
int nSeq = align.getHeight();
- float[] length = new float[nSeq];
+ double[] score = new double[nSeq];
SequenceI[] seqs = new SequenceI[nSeq];
for (int i = 0; i < nSeq; i++)
{
seqs[i] = align.getSequenceAt(i);
- length[i] = (seqs[i].getEnd() - seqs[i].getStart());
+ AlignmentAnnotation[] ann = seqs[i].getAnnotation("Search Scores");
+ if (ann != null)
+ {
+ score[i] = ann[0].getEValue();
+ }
+ else
+ {
+ score[i] = -1;
+ }
}
- QuickSort.sort(length, seqs);
+ QuickSort.sort(score, seqs);
- if (sortLengthAscending)
+ if (sortBitScoreAscending)
{
setReverseOrder(align, seqs);
}
setOrder(align, seqs);
}
- sortLengthAscending = !sortLengthAscending;
+ sortBitScoreAscending = !sortBitScoreAscending;
}
/**
// ORDERS BY GROUP SIZE
List<SequenceGroup> groups = new ArrayList<>();
- if (groups.hashCode() != lastGroupHash)
+ AlignmentSorter as = getInstance();
+
+ if (groups.hashCode() != as.lastGroupHash)
{
- sortGroupAscending = true;
- lastGroupHash = groups.hashCode();
+ as.sortGroupAscending = true;
+ as.lastGroupHash = groups.hashCode();
}
else
{
- sortGroupAscending = !sortGroupAscending;
+ as.sortGroupAscending = !as.sortGroupAscending;
}
// SORTS GROUPS BY SIZE
// NOW ADD SEQUENCES MAINTAINING ALIGNMENT ORDER
// /////////////////////////////////////////////
- List<SequenceI> seqs = new ArrayList<>();
+ List<SequenceI> tmp = new ArrayList<>();
for (int i = 0; i < groups.size(); i++)
{
for (int j = 0; j < orderedseqs.length; j++)
{
- seqs.add(orderedseqs[j]);
- }
- }
-
- if (sortGroupAscending)
- {
- setOrder(align, seqs);
- }
- else
- {
- setReverseOrder(align,
- vectorSubsetToArray(seqs, align.getSequences()));
- }
- }
-
- /**
- * Select sequences in order from tmp that is present in mask, and any
- * remaining sequences in mask not in tmp
- *
- * @param tmp
- * thread safe collection of sequences
- * @param mask
- * thread safe collection of sequences
- *
- * @return intersect(tmp,mask)+intersect(complement(tmp),mask)
- */
- private static SequenceI[] vectorSubsetToArray(List<SequenceI> tmp,
- List<SequenceI> mask)
- {
- // or?
- // tmp2 = tmp.retainAll(mask);
- // return tmp2.addAll(mask.removeAll(tmp2))
-
- ArrayList<SequenceI> seqs = new ArrayList<>();
- int i, idx;
- boolean[] tmask = new boolean[mask.size()];
-
- for (i = 0; i < mask.size(); i++)
- {
- tmask[i] = true;
- }
-
- for (i = 0; i < tmp.size(); i++)
- {
- SequenceI sq = tmp.get(i);
- idx = mask.indexOf(sq);
- if (idx > -1 && tmask[idx])
- {
- tmask[idx] = false;
- seqs.add(sq);
- }
- }
-
- for (i = 0; i < tmask.length; i++)
- {
- if (tmask[i])
- {
- seqs.add(mask.get(i));
+ tmp.add(orderedseqs[j]);
}
}
-
- return seqs.toArray(new SequenceI[seqs.size()]);
+ set(align, tmp, as.sortGroupAscending);
}
/**
// Get an ordered vector of sequences which may also be present in align
List<SequenceI> tmp = order.getOrder();
- if (lastOrder == order)
- {
- sortOrderAscending = !sortOrderAscending;
- }
- else
- {
- sortOrderAscending = true;
- }
+ AlignmentSorter as = getInstance();
- if (sortOrderAscending)
+ if (as.lastOrder == order)
{
- setOrder(align, tmp);
+ as.sortOrderAscending = !as.sortOrderAscending;
}
else
{
- setReverseOrder(align,
- vectorSubsetToArray(tmp, align.getSequences()));
+ as.sortOrderAscending = true;
}
+ set(align, tmp, as.sortOrderAscending);
}
/**
{
List<SequenceI> tmp = getOrderByTree(align, tree);
- // tmp should properly permute align with tree.
- if (lastTree != tree)
- {
- sortTreeAscending = true;
- lastTree = tree;
- }
- else
- {
- sortTreeAscending = !sortTreeAscending;
- }
+ AlignmentSorter as = getInstance();
- if (sortTreeAscending)
+ // tmp should properly permute align with tree.
+ if (as.lastTree != tree)
{
- setOrder(align, tmp);
+ as.sortTreeAscending = true;
+ as.lastTree = tree;
}
else
{
- setReverseOrder(align,
- vectorSubsetToArray(tmp, align.getSequences()));
+ as.sortTreeAscending = !as.sortTreeAscending;
}
+ set(align, tmp, as.sortTreeAscending);
}
/**
}
jalview.util.QuickSort.sort(scores, seqs);
- if (lastSortByAnnotation != scoreLabel)
+
+ AlignmentSorter as = getInstance();
+
+ if (as.lastSortByAnnotation != scoreLabel)
{
- lastSortByAnnotation = scoreLabel;
+ as.lastSortByAnnotation = scoreLabel;
setOrder(alignment, seqs);
}
else
}
/**
- * types of feature ordering: Sort by score : average score - or total score -
- * over all features in region Sort by feature label text: (or if null -
- * feature type text) - numerical or alphabetical Sort by feature density:
- * based on counts - ignoring individual text or scores for each feature
- */
- public static String FEATURE_SCORE = "average_score";
-
- public static String FEATURE_LABEL = "text";
-
- public static String FEATURE_DENSITY = "density";
-
- /**
* Sort sequences by feature score or density, optionally restricted by
* feature types, feature groups, or alignment start/end positions.
* <p>
if (method != FEATURE_SCORE && method != FEATURE_LABEL
&& method != FEATURE_DENSITY)
{
- String msg = String
- .format("Implementation Error - sortByFeature method must be either '%s' or '%s'",
- FEATURE_SCORE, FEATURE_DENSITY);
+ String msg = String.format(
+ "Implementation Error - sortByFeature method must be either '%s' or '%s'",
+ FEATURE_SCORE, FEATURE_DENSITY);
System.err.println(msg);
return;
}
- flipFeatureSortIfUnchanged(method, featureTypes, groups, startCol, endCol);
+ flipFeatureSortIfUnchanged(method, featureTypes, groups, startCol,
+ endCol);
SequenceI[] seqs = alignment.getSequencesArray();
* get sequence residues overlapping column region
* and features for residue positions and specified types
*/
- String[] types = featureTypes == null ? null : featureTypes
- .toArray(new String[featureTypes.size()]);
+ String[] types = featureTypes == null ? null
+ : featureTypes.toArray(new String[featureTypes.size()]);
List<SequenceFeature> sfs = seqs[i].findFeatures(startCol + 1,
endCol + 1, types);
}
}
+ boolean doSort = false;
+
if (FEATURE_SCORE.equals(method))
{
if (hasScores == 0)
}
}
}
- QuickSort.sortByDouble(scores, seqs, sortByFeatureAscending);
+ doSort = true;
}
else if (FEATURE_DENSITY.equals(method))
{
// System.err.println("Sorting on Density: seq "+seqs[i].getName()+
// " Feats: "+featureCount+" Score : "+scores[i]);
}
- QuickSort.sortByDouble(scores, seqs, sortByFeatureAscending);
+ doSort = true;
+ }
+ if (doSort)
+ {
+ QuickSort.sortByDouble(scores, seqs,
+ getInstance().sortByFeatureAscending);
}
-
setOrder(alignment, seqs);
}
/*
* if resorting on the same criteria, toggle sort order
*/
- if (sortByFeatureCriteria == null
- || !scoreCriteria.equals(sortByFeatureCriteria))
+ AlignmentSorter as = getInstance();
+ if (as.sortByFeatureCriteria == null
+ || !scoreCriteria.equals(as.sortByFeatureCriteria))
+ {
+ as.sortByFeatureAscending = true;
+ }
+ else
+ {
+ as.sortByFeatureAscending = !as.sortByFeatureAscending;
+ }
+ as.sortByFeatureCriteria = scoreCriteria;
+ }
+
+ /**
+ * Set the alignment's sequences list to contain the sequences from a
+ * temporary list, first adding all the elements from the tmp list, then adding all sequences in the alignment that
+ * are not in the list. Option to do the final sort either in order or in reverse order.
+ *
+ * @param align The alignment being sorted
+ * @param tmp
+ * the temporary sequence list
+ * @param ascending
+ * false for reversed order; only sequences already in
+ * the alignment will be used (which is actually already guaranteed
+ * by vectorSubsetToArray)
+ */
+ private static void set(AlignmentI align, List<SequenceI> tmp,
+ boolean ascending)
+ {
+ set(align, vectorSubsetToArray(align.getSequences(), tmp), ascending);
+ }
+
+ /**
+ * Set the alignment's sequences list to contain these sequences, either in
+ * this order or its reverse.
+ *
+ * @param align
+ * @param seqs
+ * the new sequence array
+ * @param ascending
+ * false for reversed order; if ascending, only sequences already in
+ * the alignment will be used; if descending, then a direct 1:1
+ * replacement is made
+ */
+ private static void set(AlignmentI align, SequenceI[] seqs,
+ boolean ascending)
+ {
+ if (ascending)
{
- sortByFeatureAscending = true;
+ setOrder(align, seqs);
}
else
{
- sortByFeatureAscending = !sortByFeatureAscending;
+ setReverseOrder(align, seqs);
+ }
+
+ }
+
+ /**
+ * Replace the alignment's sequences with values in an array, clearing the
+ * alignment's sequence list and filtering for sequences that are actually in
+ * the alignment already.
+ *
+ * @param align
+ * the Alignment
+ * @param seqs
+ * the array of replacement values, of any length
+ */
+ public static void setOrder(AlignmentI align, SequenceI[] seqs)
+ {
+ // NOTE: DO NOT USE align.setSequenceAt() here - it will NOT work
+ List<SequenceI> seqList = align.getSequences();
+ synchronized (seqList)
+ {
+ List<SequenceI> tmp = new ArrayList<>();
+
+ for (int i = 0; i < seqs.length; i++)
+ {
+ if (seqList.contains(seqs[i]))
+ {
+ tmp.add(seqs[i]);
+ }
+ }
+
+ seqList.clear();
+ // User may have hidden seqs, then clicked undo or redo
+ for (int i = 0; i < tmp.size(); i++)
+ {
+ seqList.add(tmp.get(i));
+ }
+ }
+ }
+
+ /**
+ * Replace the alignment's sequences or a subset of those sequences with
+ * values in an array in reverse order. All sequences are replaced; no check
+ * is made that these sequences are in the alignment already.
+ *
+ * @param align
+ * the Alignment
+ * @param seqs
+ * the array of replacement values, length must be less than or equal
+ * to Alignment.sequences.size()
+ */
+ private static void setReverseOrder(AlignmentI align, SequenceI[] seqs)
+ {
+ int nSeq = seqs.length;
+
+ int len = (nSeq + (nSeq % 2)) / 2;
+ // int len = 0;
+ //
+ // if ((nSeq % 2) == 0)
+ // {
+ // len = nSeq / 2;
+ // }
+ // else
+ // {
+ // len = (nSeq + 1) / 2;
+ // }
+
+ // NOTE: DO NOT USE align.setSequenceAt() here - it will NOT work
+ List<SequenceI> seqList = align.getSequences();
+ synchronized (seqList)
+ {
+ for (int i = 0; i < len; i++)
+ {
+ // SequenceI tmp = seqs[i];
+ seqList.set(i, seqs[nSeq - i - 1]);
+ seqList.set(nSeq - i - 1, seqs[i]);
+ }
+ }
+ }
+
+ /**
+ * Create and array of reordered sequences in order first from tmp that are
+ * present in seqList already, then, after that, any remaining sequences in
+ * seqList not in tmp. Any sequences in tmp that are not in seqList already
+ * are discarded.
+ *
+ * @param seqList
+ * thread safe collection of sequences originally in the alignment
+ * @param tmp
+ * thread safe collection of sequences or subsequences possibly in
+ * seqList
+ *
+ * @return intersect(tmp,seqList)+intersect(complement(tmp),seqList)
+ */
+ private static SequenceI[] vectorSubsetToArray(List<SequenceI> seqList,
+ List<SequenceI> tmp)
+ {
+ ArrayList<SequenceI> seqs = new ArrayList<>();
+ int n = seqList.size();
+ BitSet bs = new BitSet(n);
+ bs.set(0, n);
+ for (int i = 0, nt = tmp.size(); i < nt; i++)
+ {
+ SequenceI sq = tmp.get(i);
+ int idx = seqList.indexOf(sq);
+ if (idx >= 0 && bs.get(idx))
+ {
+ seqs.add(sq);
+ bs.clear(idx);
+ }
+ }
+
+ for (int i = bs.nextSetBit(0); i >= 0; i = bs.nextSetBit(i + 1))
+ {
+ seqs.add(seqList.get(i));
}
- sortByFeatureCriteria = scoreCriteria;
+
+ return seqs.toArray(new SequenceI[seqs.size()]);
}
}
final List<AlignmentAnnotation> result = new ArrayList<>();
for (AlignmentAnnotation dsann : datasetAnnotations)
{
- /*
- * Find matching annotations on the alignment. If none is found, then
- * add this annotation to the list of 'addable' annotations for this
- * sequence.
- */
- final Iterable<AlignmentAnnotation> matchedAlignmentAnnotations = al
- .findAnnotations(seq, dsann.getCalcId(), dsann.label);
- if (!matchedAlignmentAnnotations.iterator().hasNext())
+ if (dsann.annotations != null) // ignore non-positional annotation
{
- result.add(dsann);
- if (labelForCalcId != null)
+ /*
+ * Find matching annotations on the alignment. If none is found, then
+ * add this annotation to the list of 'addable' annotations for this
+ * sequence.
+ */
+ final Iterable<AlignmentAnnotation> matchedAlignmentAnnotations = al
+ .findAnnotations(seq, dsann.getCalcId(), dsann.label);
+ if (!matchedAlignmentAnnotations.iterator().hasNext())
{
- labelForCalcId.put(dsann.getCalcId(), dsann.label);
+ result.add(dsann);
+ if (labelForCalcId != null)
+ {
+ labelForCalcId.put(dsann.getCalcId(), dsann.label);
+ }
}
}
- }
- /*
- * Save any addable annotations for this sequence
- */
- if (!result.isEmpty())
- {
- candidates.put(seq, result);
+ /*
+ * Save any addable annotations for this sequence
+ */
+ if (!result.isEmpty())
+ {
+ candidates.put(seq, result);
+ }
}
}
}
*/
package jalview.analysis;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
import jalview.datamodel.AlignedCodonFrame;
import jalview.datamodel.Alignment;
import jalview.datamodel.AlignmentI;
import jalview.datamodel.SequenceI;
import jalview.util.DBRefUtils;
import jalview.util.MapList;
-import jalview.ws.SequenceFetcherFactory;
-import jalview.ws.seqfetcher.ASequenceFetcher;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
+import jalview.ws.SequenceFetcher;
/**
* Functions for cross-referencing sequence databases.
private void retrieveCrossRef(List<DBRefEntry> sourceRefs, SequenceI seq,
List<DBRefEntry> xrfs, boolean fromDna, AlignedCodonFrame cf)
{
- ASequenceFetcher sftch = SequenceFetcherFactory.getSequenceFetcher();
SequenceI[] retrieved = null;
SequenceI dss = seq.getDatasetSequence() == null ? seq
: seq.getDatasetSequence();
}
try
{
- retrieved = sftch.getSequences(sourceRefs, !fromDna);
+ retrieved = SequenceFetcher.getInstance().getSequences(sourceRefs, !fromDna);
} catch (Exception e)
{
System.err.println(
*/
package jalview.analysis;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.List;
+
import jalview.api.AlignViewportI;
import jalview.datamodel.AlignedCodon;
import jalview.datamodel.AlignedCodonFrame;
import jalview.datamodel.AlignmentI;
import jalview.datamodel.Annotation;
import jalview.datamodel.DBRefEntry;
-import jalview.datamodel.DBRefSource;
import jalview.datamodel.FeatureProperties;
import jalview.datamodel.GraphLine;
import jalview.datamodel.Mapping;
import jalview.util.MapList;
import jalview.util.ShiftList;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Comparator;
-import java.util.Iterator;
-import java.util.List;
-
public class Dna
{
private static final String STOP_ASTERIX = "*";
import jalview.datamodel.SequenceGroup;
import jalview.datamodel.SequenceI;
import jalview.util.Comparison;
+import jalview.util.Platform;
import jalview.util.MapList;
import java.util.ArrayList;
String searchString = matchCase ? theSearchString
: theSearchString.toUpperCase(Locale.ROOT);
- Regex searchPattern = new Regex(searchString);
+ Regex searchPattern = Platform.newRegex(searchString);
searchPattern.setIgnoreCase(!matchCase);
SequenceGroup selection = viewport.getSelectionGroup();
import jalview.datamodel.AlignmentAnnotation;
import jalview.datamodel.AlignmentI;
import jalview.datamodel.SequenceI;
+import jalview.util.Platform;
import com.stevesoft.pat.Regex;
String[] ScoreDescriptions, String regex, boolean repeat)
{
int count = 0;
- Regex pattern = new Regex(regex);
+ Regex pattern = Platform.newRegex(regex);
if (pattern.numSubs() > ScoreNames.length)
{
// Check that we have enough labels and descriptions for any parsed
*/
package jalview.analysis;
+import jalview.datamodel.AlignmentAnnotation;
+import jalview.datamodel.HiddenMarkovModel;
import jalview.datamodel.PDBEntry;
import jalview.datamodel.Sequence;
import jalview.datamodel.SequenceFeature;
/**
* Store essential properties of a sequence in a hashtable for later recovery
- * Keys are Name, Start, End, SeqFeatures, PdbId
+ * Keys are Name, Start, End, SeqFeatures, PdbId, HMM
*
* @param seq
* SequenceI
sqinfo.put("Description", seq.getDescription());
}
- Vector<SequenceFeature> sfeat = new Vector<SequenceFeature>();
+ Vector<SequenceFeature> sfeat = new Vector<>();
List<SequenceFeature> sfs = seq.getFeatures().getAllFeatures();
sfeat.addAll(sfs);
(seq.getDatasetSequence() != null) ? seq.getDatasetSequence()
: new Sequence("THISISAPLACEHOLDER", ""));
}
+ if (seq.hasHMMProfile())
+ {
+ sqinfo.put("HMM", seq.getHMM());
+ }
+
+ if (seq.getAnnotation("Search Scores") != null)
+ {
+ sqinfo.put("Score", seq.getAnnotation("Search Scores"));
+ }
+
return sqinfo;
}
Vector<PDBEntry> pdbid = (Vector<PDBEntry>) sqinfo.get("PdbId");
String description = (String) sqinfo.get("Description");
Sequence seqds = (Sequence) sqinfo.get("datasetSequence");
+ HiddenMarkovModel hmm = (HiddenMarkovModel) sqinfo.get("HMM");
+ AlignmentAnnotation[] scores = (AlignmentAnnotation[]) sqinfo
+ .get("Score");
+
if (oldname == null)
{
namePresent = false;
sq.setDatasetSequence(seqds);
}
+ if (hmm != null)
+ {
+ sq.setHMM(new HiddenMarkovModel(hmm, sq));
+ }
+
+ if (scores != null)
+ {
+ for (AlignmentAnnotation score : scores)
+ {
+ sq.addAlignmentAnnotation(score);
+ }
+ }
return namePresent;
}
import jalview.api.AlignmentViewPanel;
import jalview.api.analysis.ScoreModelI;
+import jalview.bin.ApplicationSingletonProvider;
+import jalview.bin.ApplicationSingletonProvider.ApplicationSingletonI;
import jalview.io.DataSourceType;
import jalview.io.FileParse;
import jalview.io.ScoreMatrixFile;
/**
* A class that can register and serve instances of ScoreModelI
*/
-public class ScoreModels
+public class ScoreModels implements ApplicationSingletonI
{
- private final ScoreMatrix BLOSUM62;
-
- private final ScoreMatrix PAM250;
-
- private final ScoreMatrix DNA;
-
- private static ScoreModels instance;
-
- private Map<String, ScoreModelI> models;
-
/**
* Answers the singleton instance of this class, with lazy initialisation
* (built-in score models are loaded on the first call to this method)
*/
public static ScoreModels getInstance()
{
- if (instance == null)
- {
- instance = new ScoreModels();
- }
- return instance;
+ return (ScoreModels) ApplicationSingletonProvider.getInstance(ScoreModels.class);
}
/**
registerScoreModel(new FeatureDistanceModel());
}
+ private final ScoreMatrix BLOSUM62;
+
+ private final ScoreMatrix PAM250;
+
+ private final ScoreMatrix DNA;
+
+ private Map<String, ScoreModelI> models;
+
/**
* Tries to load a score matrix from the given resource file, and if
* successful, registers it.
*/
public void reset()
{
- instance = new ScoreModels();
+ ApplicationSingletonProvider.removeInstance(this.getClass());
}
/**
--- /dev/null
+package jalview.api;
+
+import java.util.EventListener;
+
+/**
+ * A listener class which receives state updates of {@link AlignCalcWorkerI}.
+ * It can be registered with an {@link AlignCalcManagerI2}.
+ *
+ * @author mmwarowny
+ *
+ */
+public interface AlignCalcListener extends EventListener
+{
+ /**
+ * Called when the worker is scheduler for execution with
+ * {@link AlignCalcManagerI2#startWorker(AlignCalcWorkerI)}.
+ */
+ default void workerQueued(AlignCalcWorkerI worker) {}
+
+ /**
+ * Called when the worker starts calculations.
+ */
+ default void workerStarted(AlignCalcWorkerI worker) {}
+
+ /**
+ * Called when the worker finishes successfully.
+ */
+ default void workerCompleted(AlignCalcWorkerI worker) {}
+
+ /**
+ * Called when the worker is cancelled.
+ */
+ default void workerCancelled(AlignCalcWorkerI worker) {}
+
+ /**
+ * Called when the worker finishes with an exception.
+ */
+ default void workerExceptional(AlignCalcWorkerI worker, Throwable throwable) {}
+}
*
* @param worker
*/
- void notifyStart(AlignCalcWorkerI worker);
+ void notifyStarted(AlignCalcWorkerI worker);
/**
* tell manager that a thread running worker's run() loop is ready to start
*
* @param typeToRemove
*/
- void removeRegisteredWorkersOfClass(
+ void removeWorkersOfClass(
Class<? extends AlignCalcWorkerI> typeToRemove);
/**
--- /dev/null
+package jalview.api;
+
+import java.util.List;
+
+import jalview.datamodel.AlignmentAnnotation;
+
+/**
+ * An abstract manager which controls the execution of interactive jobs.
+ * There is always one instance of AlignCancManager per AlignmenViewport
+ * which runs the jobs, notifies observers and ensures no race conditions.
+ *
+ * @author mmwarowny
+ *
+ */
+public interface AlignCalcManagerI2
+{
+ /**
+ * Registers the worker with the manager and immediately schedules it
+ * for execution.
+ */
+ void registerWorker(AlignCalcWorkerI worker);
+
+ /**
+ * Returns the list of all registered workers or an empty list if
+ * there are none
+ */
+ List<AlignCalcWorkerI> getWorkers();
+
+ /**
+ * Returns the list of all workers of a given class or an empty list
+ * if there are none. The classes are compared using
+ * {@ink Class#equals(Object)} rather than {@code instanceof}.
+ */
+ List<AlignCalcWorkerI> getWorkersOfClass(Class<? extends AlignCalcWorkerI> cls);
+
+ /**
+ * Removes the worker from the scheduler. It does not cancel workers
+ * already scheduled for execution.
+ */
+ void removeWorker(AlignCalcWorkerI worker);
+
+ /**
+ * Removes all workers which are involved with the given annotation.
+ */
+ void removeWorkerForAnnotation(AlignmentAnnotation annot);
+
+ /**
+ * Alias of removeWorkerForAnnotation
+ */
+ default void removeWorkersForAnnotation(AlignmentAnnotation annot) {
+ removeWorkerForAnnotation(annot);
+ }
+
+ /**
+ * Removes all workers of a given class. The classes are compared using
+ * {@link Class#equals(Object)}.
+ */
+ void removeWorkersOfClass(Class<? extends AlignCalcWorkerI> cls);
+
+ /**
+ * Disables a worker so it won't be run during the following restarts.
+ */
+ void disableWorker(AlignCalcWorkerI worker);
+
+ /**
+ * Restores the previously disabled worker back to operation.
+ */
+ void enableWorker(AlignCalcWorkerI worker);
+
+ /**
+ * Checks whether the worker is disabled either due to failure or
+ * disabling it manually.
+ */
+ boolean isDisabled(AlignCalcWorkerI worker);
+
+ /**
+ * Checks whether the given worker is currently running.
+ */
+ boolean isWorking(AlignCalcWorkerI worker);
+
+ /**
+ * Checks whether the currently running worker (if any) is processing
+ * the given annotation.
+ */
+ boolean isWorkingWithAnnotation(AlignmentAnnotation annot);
+
+ /**
+ * Checks whether this manager is running a worker.
+ */
+ boolean isWorking();
+
+ /**
+ * Scheduler the worker for one-time execution. The worker does not need
+ * to be registered with this manager and will be scheduler regardless
+ * of being disabled. If the worker has already been scheduled, the
+ * previous one will be cancelled.
+ */
+ void startWorker(AlignCalcWorkerI worker);
+
+ /**
+ * Schedules all registered and not-disabled workers for next execution.
+ */
+ void restartWorkers();
+
+ /**
+ * Cancels the execution of the worker. Note, if the worker is already
+ * running, this method may, but doesn't have to, interrupt it in
+ * the middle of the work.
+ */
+ void cancelWorker(AlignCalcWorkerI worker);
+
+ /**
+ * Connect the listener of the worker state changes.
+ */
+ void addAlignCalcListener(AlignCalcListener listener);
+
+ /**
+ * Remove previously registered worker listener.
+ */
+ void removeAlignCalcListener(AlignCalcListener listener);
+
+ /**
+ * Stops the manager from running new jobs and cleans-up all
+ * resources such as threads and thread pools.
+ */
+ void shutdown();
+}
*/
package jalview.api;
+import java.util.concurrent.Callable;
+
import jalview.datamodel.AlignmentAnnotation;
/**
* Interface describing a worker that calculates alignment annotation(s). The
* main (re-)calculation should be performed by the inherited run() method.
*/
-public interface AlignCalcWorkerI extends Runnable
+public interface AlignCalcWorkerI
{
/**
* Answers true if this worker updates the given annotation (regardless of its
/**
* Updates the display of calculated annotation values (does not recalculate
- * the values). This allows ßquick redraw of annotations when display settings
- * are changed.
+ * the values). This allows a quick redraw of annotations when display
+ * settings are changed.
*/
void updateAnnotation();
* Removes any annotation(s) managed by this worker from the alignment
*/
void removeAnnotation();
-
+
+ /**
+ * The main calculation happens here
+ * @throws Throwable
+ */
+ public void run() throws Throwable;
+
/**
* 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
*
* @return
*/
- public ViewportRanges getRanges();
+ ViewportRanges getRanges();
/**
* calculate the height for visible annotation, revalidating bounds where
*
* @return total height of annotation
*/
- public int calcPanelHeight();
+ int calcPanelHeight();
/**
* Answers true if the viewport has at least one column selected
boolean isNormaliseSequenceLogo();
+ boolean isShowInformationHistogram();
+
+ boolean isShowHMMSequenceLogo();
+
+ boolean isNormaliseHMMSequenceLogo();
+
ColourSchemeI getGlobalColourScheme();
/**
boolean isIgnoreGapsConsensus();
+ boolean isIgnoreBelowBackground();
+
boolean isCalculationInProgress(AlignmentAnnotation alignmentAnnotation);
AlignmentAnnotation getAlignmentQualityAnnot();
*
* @return
*/
- AlignCalcManagerI getCalcManager();
+ AlignCalcManagerI2 getCalcManager();
/**
* get the percentage gaps allowed in a conservation calculation
@Override
void setProteinFontAsCdna(boolean b);
- TreeModel getCurrentTree();
+ void setHmmProfiles(ProfilesI info);
- void setCurrentTree(TreeModel tree);
+ ProfilesI getHmmProfiles();
+
+ /**
+ * Registers and starts a worker thread to calculate Information Content
+ * annotation, if it is not already registered
+ *
+ * @param ap
+ */
+ void initInformationWorker(AlignmentViewPanel ap);
+
+ boolean isInfoLetterHeight();
+
+ public abstract TreeModel getCurrentTree();
/**
* Answers a data bean containing data for export as configured by the
*/
AlignmentExportData getAlignExportData(AlignExportSettingsI options);
+ public abstract void setCurrentTree(TreeModel tree);
+
/**
* @param update
* - set the flag for updating structures on next repaint
*/
package jalview.api;
+import jalview.datamodel.features.FeatureMatcherSetI;
+
import java.util.Comparator;
/**
FeatureColourI getFeatureColour(String type);
/**
+ * Returns any filters defined for the feature type, or null if not known
+ *
+ * @param type
+ * @return
+ */
+
+ FeatureMatcherSetI getFeatureFilters(String type);
+
+ /**
* Returns the transparency value, from 0 (fully transparent) to 1 (fully
* opaque)
*
--- /dev/null
+package jalview.api;
+
+import java.net.URL;
+
+import jalview.datamodel.SequenceI;
+import jalview.gui.AlignFrame;
+
+/**
+ * JAL-3369 JalviewJS API BH 2019.07.17
+ *
+ * @author hansonr
+ *
+ */
+public interface JalviewJSApi
+{
+
+ /**
+ * bind a pdb file to a sequence in the given AlignFrame.
+ *
+ * @param sequenceId
+ * - sequenceId within the dataset or null
+ * @param pdbId
+ * - the four-character PDB ID
+ * @param pdbFile
+ * - pdb file - either a URL or a valid PDB file or null.
+ * @param alFrame
+ * - null or specific AlignFrame. This specifies the dataset that
+ * will be searched for a seuqence called sequenceId
+ *
+ * @return true if binding was success
+ */
+ public boolean addPdbFile(String sequenceId, String pdbId, String pdbFile,
+ AlignFrame alFrame);
+
+ /**
+ * Get alignment as format with or without the jalview start-end sequence
+ * suffix appended.
+ *
+ * @param format
+ * @param addSuffix
+ * (default false)
+ * @param alf
+ * (default current)
+ *
+ * @return
+ */
+ public String getAlignment(String format, boolean addSuffix,
+ AlignFrame alf);
+
+ /**
+ * Get an array of sequence IDs reflecting the order of the alignment in the
+ * specified alignment frame
+ *
+ * @param alf
+ * (default current)
+ * @return array of sequence IDs
+ */
+ public String[] getAlignmentOrder(AlignFrame alf);
+
+ /**
+ * Get alignment view alf's annotation as an annotation file
+ *
+ * @param alf
+ * (default current)
+ * @return annotation
+ */
+ public String getAnnotation(AlignFrame alf);
+
+ /**
+ * Get the URL for the location where the code is found; typically ending in
+ * "swingjs/j2s".
+ *
+ * @return web page URL
+ */
+ public URL getCodeBase();
+
+ AlignFrame getCurrentAlignFrame();
+
+ /**
+ * Get the URL for the hosting web page.
+ *
+ * @return web page URL
+ */
+ public URL getDocumentBase();
+
+ /**
+ * Get the array of feature groups for an alignment frame.
+ *
+ * @param alf
+ * AlignFrame to get feature groups for (default current)
+ * @return
+ */
+ public String[] getFeatureGroups(AlignFrame alf);
+
+ /**
+ * Get the array of feature groups for an alignment frame with a specific
+ * on/off state.
+ *
+ * @param visible
+ * (default off)
+ * @param alf
+ * align frame (default current)
+ *
+ * @return
+ */
+ public String[] getFeatureGroupsOfState(boolean visible, AlignFrame alf);
+
+ /**
+ * Get the sequence features in the alignment frame in the given format
+ * (Jalview or GFF). Two additional options can be added to the format, each
+ * starting with a semicolon:
+ *
+ * ;includeNonpositional (default) or ;positionalOnly
+ *
+ * ;includeComplement
+ *
+ * @param format
+ * case-insensitive "Jalview" or "GFF" (default "GFF")
+ * @param alf
+ * (default current)
+ * @return formatted sequence features
+ */
+ public String getFeatures(String format, AlignFrame alf);
+
+ /**
+ * Get an applet parameter as a string.
+ *
+ * @param name
+ * @return value or null
+ */
+ public String getParameter(String name);
+
+ /**
+ * Get an applet parameter object value.
+ *
+ * @param name
+ * @return value or null
+ */
+ public Object getParameterAsObject(String name);
+
+ /**
+ * @param alf
+ * AlignFrame containing selection
+ * @return String list of selected sequence IDs, each terminated by current
+ * default separator sequence
+ *
+ */
+ public SequenceI[] getSelectedSequences(AlignFrame alf);
+
+ // BH incompatibility here -- JalviewLite created an AlignFrame; Jalview
+ // creates an AlignmentPanel
+ // /**
+ // * create a new view and return the AlignFrame instance
+ // *
+ // * @return
+ // */
+ //
+ // public AlignFrame newView();
+ //
+ // /**
+ // * create a new view named name and return the AlignFrame instance
+ // *
+ // * @param name
+ // * @return
+ // */
+ //
+ // public AlignFrame newView(String name);
+ //
+ // /**
+ // * create a new view on alf and return the AlignFrame instance
+ // *
+ // * @param alf
+ // * @return
+ // */
+ // public AlignFrame newViewFrom(AlignFrame alf);
+ //
+ // /**
+ // * create a new view named name on alf
+ // *
+ // * @param alf
+ // * @param name
+ // * @return
+ // */
+ // public AlignFrame newViewFrom(AlignFrame alf, String name);
+ //
+
+ /**
+ * get sequences selected in alf and return their alignment in format 'format'
+ * either with or without suffix
+ *
+ * @param format
+ * - format of alignment file
+ * @param alf
+ * - where selection is
+ * @param suffix
+ * - true to append /start-end string to each sequence ID
+ *
+ * @return selected sequences as flat file or empty string if there was no
+ * current selection
+ */
+ public String getSelectedSequencesAsAlignment(String format,
+ boolean addSuffix, AlignFrame alf);
+
+ /**
+ *
+ * @param sequenceId
+ * id of sequence to highlight
+ * @param position
+ * integer position [ tobe implemented or range ] on sequence
+ * @param alignedPosition
+ * false, blank or something else - indicate if position is an
+ * alignment column or unaligned sequence position
+ * @param alf
+ * alignment frame (default current)
+ */
+ public void highlight(String sequenceId, String position,
+ String alignedPosition, AlignFrame alf);
+
+ /**
+ *
+ * @param data
+ * alignment data as a string
+ * @param title
+ * window title
+ * @param width
+ * desired width or 0 for default width
+ * @param height
+ * desired height or 0 for default height
+ * @return null or new alignment frame
+ */
+
+ public AlignFrame loadAlignment(String data, String title, int width,
+ int height);
+
+ /**
+ * add the given features or annotation to the given alignment view
+ *
+ * @param annotation
+ * @param alf
+ * alignment frame (default current)
+ */
+ public void loadAnnotation(String annotation, AlignFrame alf);
+
+ /**
+ * Parse the given string as a jalview feature or GFF annotation file and
+ * optionally enable feature display on the given AlignFrame.
+ *
+ * @param features
+ * - gff or features file
+ * @param autoenabledisplay
+ * - when true, feature display will be enabled if any features can
+ * be parsed from the string.
+ * @param alf
+ * alignment frame (default current)
+ *
+ * @return true if data parsed as features
+ */
+ public boolean loadFeatures(String features, boolean autoenabledisplay,
+ AlignFrame alf);
+
+ /**
+ * Load a score file.
+ *
+ * @param sScoreFile
+ * @param alf
+ * alignment frame (default current)
+ *
+ * @return
+ */
+ public boolean loadScoreFile(String sScoreFile, AlignFrame alf);
+
+ /**
+ * public static method for JalviewJS API to open a PCAPanel without
+ * necessarily using a dialog.
+ *
+ * @param modelName
+ * @param alf
+ * may be null
+ *
+ * @return the PCAPanel, or the string "label.you_need_at_least_n_sequences"
+ * if number of sequences selected is inappropriate
+ */
+ public Object openPcaPanel(String modelName, AlignFrame alf);
+
+ /**
+ * Open a new Tree panel on the desktop statically. Params are standard (not
+ * set by Groovy). No dialog is opened.
+ *
+ * @param treeType
+ * @param modelName
+ * @param alf
+ * align frame (default current)
+ *
+ * @return null, or the string "label.you_need_at_least_n_sequences" if number
+ * of sequences selected is inappropriate
+ */
+ public Object openTreePanel(String treeType, String modelName,
+ AlignFrame alf);
+
+ /**
+ * re-order the given alignment using the given array of sequence IDs
+ *
+ * @param ids
+ * array of sequence IDs
+ * @param undoName
+ * - string to use when referring to ordering action in undo buffer
+ * @param alf
+ * alignment frame (default current)
+ *
+ * @return 'true' if alignment was actually reordered. empty string if
+ * alignment did not contain sequences.
+ */
+ public boolean orderAlignment(String[] ids, String undoName,
+ AlignFrame alf);
+
+ /**
+ * process commandline arguments after the JavaScript application has started
+ *
+ * @param args
+ * @return
+ */
+ public Object parseArguments(String[] args);
+
+ boolean parseFeaturesFile(String filename, AlignFrame alf);
+
+ // Bob's additions:
+
+ /**
+ * remove any callback using the given listener function and associated with
+ * the given AlignFrame (or null for all callbacks);
+ *
+ * @param listener
+ * (may be null);
+ * @param alf
+ * alignment frame (default current)
+ */
+ public void removeSelectionListener(String listener, AlignFrame af);
+
+ /**
+ * adjust horizontal/vertical scroll to make the given location the top left
+ * hand corner for the given view
+ *
+ * @param topRow
+ * -1 for current top row
+ * @param leftHandColumn
+ * -1 for current left-hand column
+ * @param alf
+ * alignment frame (default current)
+ */
+ public void scrollViewTo(int topRow, int leftHandColumn, AlignFrame alf);
+ /**
+ * select regions of the given alignment frame
+ *
+ * @param alf
+ * alignment frame (default current)
+ * @param toselect
+ * String separated list { column range, seq1...seqn sequence ids }
+ * @param sep
+ * separator between toselect fields
+ */
+ public void select(String[] sequenceIds, String[] columns,
+ AlignFrame alf);
+
+ /**
+ * Set the state (visible or not) of the selected feature groups.
+ *
+ * @param groups
+ * @param state
+ * @param alf
+ * (default current)
+ */
+ public void setFeatureGroupState(String[] groups, boolean state,
+ AlignFrame alf);
+
+ /**
+ * Register a JavaScript function to handle alignment selection events. Events
+ * are generated when the user completes a selection event, or when the user
+ * deselects all selected regions. The method is called back with the
+ * following arguments:
+ *
+ * the appletID (such as "Jalview1")
+ *
+ * the source alignment frame
+ *
+ * the SelectionSource object (for example, an AlignViewport)
+ *
+ * the sequence set ID
+ *
+ * an array of sequence IDs
+ *
+ * an array of columns (single number or hyphenated range)
+ *
+ * @param listener
+ * name of JavaScript function to be called
+ *
+ * @param alf
+ * alignment frame (default ALL)
+ */
+ public void setSelectionListener(String listener, AlignFrame alf);
+
+ public void showOverview();
+
+ /**
+ *
+ * @param pdbID
+ * @param fileType
+ * @param alf
+ * align frame (default current)
+ */
+ public void showStructure(String pdbID, String fileType, AlignFrame alf);
+
+}
--- /dev/null
+package jalview.api;
+
+public interface PollableAlignCalcWorkerI extends AlignCalcWorkerI
+{
+ @Override
+ public default void run() throws Throwable
+ {
+ startUp();
+ }
+
+ public void startUp() throws Throwable;
+
+ public boolean poll() throws Throwable;
+
+ public void cancel();
+
+ public void done();
+}
ap.alignFrame.addHistoryItem(editCommand);
- ap.av.firePropertyChange("alignment", null,
- ap.av.getAlignment().getSequences());
+ ap.av.notifyAlignment();
}
}
}
ap.alignFrame.addHistoryItem(caseCommand);
- ap.av.firePropertyChange("alignment", null,
- ap.av.getAlignment().getSequences());
+ ap.av.notifyAlignment();
}
}
alignPanel);
viewport.updateConservation(alignPanel);
viewport.updateConsensus(alignPanel);
+ viewport.initInformationWorker(alignPanel);
displayNonconservedMenuItem.setState(viewport.getShowUnconserved());
followMouseOverFlag.setState(viewport.isFollowHighlight());
}
else if (source == autoCalculate)
{
- viewport.autoCalculateConsensus = autoCalculate.getState();
+ viewport.setAutoCalculateConsensusAndConservation(autoCalculate.getState());
}
else if (source == sortByTree)
{
{
sortGroupMenuItem_actionPerformed();
}
+ else if (source == sortEValueMenuItem)
+ {
+ sortEValueMenuItem_actionPerformed();
+ }
+ else if (source == sortBitScoreMenuItem)
+ {
+ sortBitScoreMenuItem_actionPerformed();
+ }
else if (source == removeRedundancyMenuItem)
{
removeRedundancyMenuItem_actionPerformed();
// viewport.getColumnSelection().getHiddenColumns()
// != null;
updateEditMenuBar();
- originalSource.firePropertyChange("alignment", null,
- originalSource.getAlignment().getSequences());
+ originalSource.notifyAlignment();
}
/**
// != null;
updateEditMenuBar();
- originalSource.firePropertyChange("alignment", null,
- originalSource.getAlignment().getSequences());
+ originalSource.notifyAlignment();
}
AlignmentViewport getOriginatingSource(CommandI command)
viewport.getRanges().setEndSeq(viewport.getAlignment().getHeight() - 1); // BH
// 2019.04.18
viewport.getAlignment().getWidth();
- viewport.firePropertyChange("alignment", null,
- viewport.getAlignment().getSequences());
+ viewport.notifyAlignment();
}
viewport.setSelectionGroup(null);
viewport.getAlignment().deleteGroup(sg);
- viewport.firePropertyChange("alignment", null,
- viewport.getAlignment().getSequences());
+ viewport.notifyAlignment();
if (viewport.getAlignment().getHeight() < 1)
{
}
}
- viewport.firePropertyChange("alignment", null, al.getSequences());
+ viewport.notifyAlignment();
}
}
// if (viewport.hasHiddenColumns)
// viewport.getColumnSelection().compensateForEdits(shifts);
ranges.setStartRes(seq.findIndex(startRes) - 1);
- viewport.firePropertyChange("alignment", null, al.getSequences());
+ viewport.notifyAlignment();
}
ranges.setStartRes(seq.findIndex(startRes) - 1);
- viewport.firePropertyChange("alignment", null, al.getSequences());
+ viewport.notifyAlignment();
}
}
+ public void sortEValueMenuItem_actionPerformed()
+ {
+ SequenceI[] oldOrder = viewport.getAlignment().getSequencesArray();
+ AlignmentSorter.sortByEValue(viewport.getAlignment());
+ addHistoryItem(new OrderCommand("Group Sort", oldOrder,
+ viewport.getAlignment()));
+ alignPanel.paintAlignment(true, false);
+
+ }
+
+ public void sortBitScoreMenuItem_actionPerformed()
+ {
+ SequenceI[] oldOrder = viewport.getAlignment().getSequencesArray();
+ AlignmentSorter.sortByBitScore(viewport.getAlignment());
+ addHistoryItem(new OrderCommand("Group Sort", oldOrder,
+ viewport.getAlignment()));
+ alignPanel.paintAlignment(true, false);
+
+ }
+
public void removeRedundancyMenuItem_actionPerformed()
{
new RedundancyPanel(alignPanel);
MenuItem sortGroupMenuItem = new MenuItem();
+ MenuItem sortEValueMenuItem = new MenuItem();
+
+ MenuItem sortBitScoreMenuItem = new MenuItem();
+
MenuItem removeRedundancyMenuItem = new MenuItem();
MenuItem pairwiseAlignmentMenuItem = new MenuItem();
/*
- * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
* Copyright (C) $$Year-Rel$$ The Jalview Authors
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
*
* This file is part of Jalview.
*
private AnnotationColumnChooser annotationColumnSelectionState;
+ java.awt.Frame nullFrame;
+
+ protected FeatureSettings featureSettings = null;
+
+ private float heightScale = 1, widthScale = 1;
+
public AlignViewport(AlignmentI al, JalviewLite applet)
{
super(al);
- calculator = new jalview.workers.AlignCalcManager();
+ calculator = new jalview.workers.AlignCalcManager2();
this.applet = applet;
// we always pad gaps
colour));
if (residueShading != null)
{
- residueShading.setConsensus(hconsensus);
+ residueShading.setConsensus(consensusProfiles);
}
}
}
}
initAutoAnnotation();
-
}
- java.awt.Frame nullFrame;
-
- protected FeatureSettings featureSettings = null;
-
- private float heightScale = 1, widthScale = 1;
-
/**
* {@inheritDoc}
*/
.getStructureSelectionManager(applet);
}
- @Override
- public boolean isNormaliseSequenceLogo()
- {
- return normaliseSequenceLogo;
- }
-
- public void setNormaliseSequenceLogo(boolean state)
- {
- normaliseSequenceLogo = state;
- }
-
/**
*
* @return true if alignment characters should be displayed
if (mappedCommand != null)
{
mappedCommand.doCommand(null);
- firePropertyChange("alignment", null, getAlignment().getSequences());
+ notifyAlignment();
// ap.scalePanelHolder.repaint();
// ap.repaint();
// this is called after loading new annotation onto alignment
if (alignFrame.getSize().height == 0)
{
- System.out.println(
- "adjustAnnotationHeight frame size zero NEEDS FIXING");
+ // panel not laid out yet?
+ return;
}
fontChanged();
validateAnnotationDimensions(true);
MessageManager.getString("label.ignore_gaps_consensus"),
(aa[selectedRow].groupRef != null)
? aa[selectedRow].groupRef
- .getIgnoreGapsConsensus()
+ .getIgnoreGapsConsensus()
: ap.av.isIgnoreGapsConsensus());
final AlignmentAnnotation aaa = aa[selectedRow];
cbmi.addItemListener(new ItemListener()
import java.awt.event.MouseMotionListener;
import java.beans.PropertyChangeEvent;
+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.viewmodel.ViewportListenerI;
+import jalview.viewmodel.ViewportRanges;
+
public class AnnotationPanel extends Panel
implements AwtRenderPanelI, AdjustmentListener, ActionListener,
MouseListener, MouseMotionListener, ViewportListenerI
od = new OverviewDimensionsShowHidden(av.getRanges(),
(av.isShowAnnotation()
- && av.getSequenceConsensusHash() != null));
+ && av.getSequenceConsensusHash() != null));
oviewCanvas = new OverviewCanvas(od, av);
setLayout(new BorderLayout());
ap.alignFrame.addHistoryItem(cut);
PaintRefresher.Refresh(this, ap.av.getSequenceSetId(), true, true);
- ap.av.firePropertyChange("alignment", null,
- ap.av.getAlignment().getSequences());
+ ap.av.notifyAlignment();
}
}
{
ap.av.getHistoryList().remove(command);
ap.alignFrame.updateEditMenuBar();
- ap.av.firePropertyChange("alignment", null,
- ap.av.getAlignment().getSequences());
+ ap.av.notifyAlignment();
}
ap.paintAlignment(true, true);
if (editCommand != null && editCommand.getSize() > 0)
{
ap.alignFrame.addHistoryItem(editCommand);
- av.firePropertyChange("alignment", null,
- av.getAlignment().getSequences());
+ av.notifyAlignment();
}
startseq = -1;
*/
package jalview.appletgui;
-import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Insets;
-import java.awt.Label;
import java.awt.Panel;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
ap.updateAnnotation();
if (av.getCodingComplement() != null)
{
- ((AlignmentViewport) av.getCodingComplement()).firePropertyChange(
- "alignment", null, ap.av.getAlignment().getSequences());
+ ((AlignmentViewport) av.getCodingComplement()).notifyAlignment();
+ // Technically, the property change is not the same because av is not necessarily getCodingComplement(),
+ // but this is the appletgui, so I am not going to worry about it. BH
+ //.firePropertyChange("alignment", null, ap.av.getAlignment().getSequences());
}
}
* along with Jalview. If not, see <http://www.gnu.org/licenses/>.
* The Jalview Authors are detailed in the 'AUTHORS' file.
*/
-package jalview.javascript;
+package jalview.appletgui.js;
import jalview.bin.JalviewLite;
* along with Jalview. If not, see <http://www.gnu.org/licenses/>.
* The Jalview Authors are detailed in the 'AUTHORS' file.
*/
-package jalview.javascript;
+package jalview.appletgui.js;
import jalview.appletgui.AlignFrame;
* - separator separated list of PDB file URIs that this viewer is
* handling. These files must be in the same order they appear in
* Jmol (e.g. first one is frame 1, second is frame 2, etc).
- * @see jalview.javascript.MouseOverStructureListener
+ * @see jalview.appletgui.js.MouseOverStructureListener
*/
public abstract void setStructureListener(String listener,
String modelSet);
* along with Jalview. If not, see <http://www.gnu.org/licenses/>.
* The Jalview Authors are detailed in the 'AUTHORS' file.
*/
-package jalview.javascript;
+package jalview.appletgui.js;
public interface JsCallBack
{
* along with Jalview. If not, see <http://www.gnu.org/licenses/>.
* The Jalview Authors are detailed in the 'AUTHORS' file.
*/
-package jalview.javascript;
+package jalview.appletgui.js;
import jalview.appletgui.AlignFrame;
import jalview.bin.JalviewLite;
* along with Jalview. If not, see <http://www.gnu.org/licenses/>.
* The Jalview Authors are detailed in the 'AUTHORS' file.
*/
-package jalview.javascript;
+package jalview.appletgui.js;
import jalview.appletgui.AlignFrame;
import jalview.bin.JalviewLite;
* along with Jalview. If not, see <http://www.gnu.org/licenses/>.
* The Jalview Authors are detailed in the 'AUTHORS' file.
*/
-package jalview.javascript;
+package jalview.appletgui.js;
import jalview.api.AlignmentViewPanel;
import jalview.api.FeatureRenderer;
import jalview.api.SequenceRenderer;
import jalview.appletgui.AlignFrame;
+import jalview.appletgui.js.JsCallBack;
import jalview.bin.JalviewLite;
import jalview.datamodel.SequenceI;
import jalview.ext.jmol.JmolCommands;
--- /dev/null
+
+package jalview.bin;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import jalview.gui.Preferences;
+
+/**
+ * Collection of all known applet tags from JalviewLite.
+ * Three cases; can be one or more of these:
+ *
+ * CASE I. args[] name and value for ArgsParser
+ *
+ * CASE II. applet parameter for JalviewJSApp
+ *
+ * CASE III. mapped to a Preference
+ *
+ *
+ * @author hansonr
+ *
+ */
+@SuppressWarnings("serial")
+public class AppletParams extends HashMap<String, Object>
+{
+
+ private final static String[] params = {
+ "alignpdbfiles",
+ "ANNOTATIONCOLOUR_MAX", "ANNOTATIONCOLOUR_MIN",
+ "annotations",
+ "APPLICATION_URL", "automaticScrolling", "centrecolumnlabels",
+ "debug", "defaultColour", "defaultColourNuc", "defaultColourProt",
+ "embedded", "enableSplitFrame", "externalstructureviewer", "features",
+ "file", "file2", "format", "heightScale", "hidefeaturegroups",
+ "jalviewhelpurl", "jnetfile", "jpredfile", "label", "linkLabel_",
+ "linkLabel_1", "linkURL_", "nojmol", "normaliseLogo",
+ "normaliseSequenceLogo", "oninit", "PDBFILE", "PDBSEQ",
+ "relaxedidmatch", "resolvetocodebase", "RGB", "scaleProteinAsCdna",
+ "scoreFile", "separator", "sequence", "showAnnotation", "showbutton",
+ "showConsensus", "showConsensusHistogram", "showConservation",
+ "showfeaturegroups", "showFeatureSettings", "showFullId",
+ "showGroupConsensus", "showGroupConservation", "showOccupancy",
+ "showQuality", "showSequenceLogo", "showTreeBootstraps",
+ "showTreeDistances", "showUnconserved", "showUnlinkedTreeNodes",
+ "sortBy", "sortByTree", "tree", "treeFile", "upperCase",
+ "userDefinedColour", "widthScale", "windowHeight", "windowWidth",
+ "wrap", };
+
+ public String getParam(String param, String def)
+ {
+ Object val = get(param);
+ return (val != null ? val.toString() : def);
+ }
+
+ // <applet
+ // code="jalview.bin.JalviewLite" width="140" height="35"
+ // archive="jalviewApplet.jar,JmolApplet-14.6.4_2016.10.26.jar,java-json.jar,json_simple-1.1.jar">
+ // <param name="permissions" value="sandbox"/>
+ // <param name="file" value="uniref50.fa"/>
+ // <param name="treeFile" value="ferredoxin.nw"/>
+ // <param name="userDefinedColour" value="C=yellow; R,K,H=FF5555;
+ // D,E=5555FF"/>
+ // <param name="sortByTree" value="True"/>
+ // <param name="showSequenceLogo" value="true"/>
+ // <param name="showGroupConsensus" value="true"/>
+ // <param name="showFullId" value="false"/>
+ // <param name="linkLabel_1" value="Uniprot"/>
+ // <param name="linkUrl_1"
+ // value="http://www.uniprot.org/uniprot/$SEQUENCE_ID$"/>
+ // <param name="linkLabel_2" value="EMBL-EBI Search"/>
+ // <param name="linkUrl_2"
+ // value="http://www.ebi.ac.uk/ebisearch/search.ebi?db=allebi&query=$SEQUENCE_ID$"/>
+ // <param name="APPLICATION_URL"
+ // value="http://www.jalview.org/services/launchApp"/>
+ // </applet>
+ //
+ public AppletParams(String outerHTML)
+ {
+ String[] tokens = outerHTML.split("<param");
+ outerHTML = tokens[0];
+ String code = getAttr(outerHTML, "code");
+ if (!code.equals("jalview.bin.JalviewLite"))
+ {
+ return;
+ }
+ for (int i = tokens.length; --i > 0;)
+ {
+ String param = tokens[i];
+ String key = getAttr(param, "name");
+ if (key != null)
+ {
+ String value = getAttr(param, "value");
+ System.out.println("AppletParams " + key + " = \"" + value + "\"");
+ put(key, value);
+ }
+ }
+ put("_width", getAttr(outerHTML, "width"));
+ put("_height", getAttr(outerHTML, "height"));
+ put("_id", getAttr(outerHTML, "id"));
+ put("_name", getAttr(outerHTML, "name"));
+ put("_archive", getAttr(outerHTML, "archive"));
+ put("_code", code);
+ }
+
+ public AppletParams()
+ {
+ }
+
+ public static AppletParams getAppletParams(Map<String, Object> map,
+ List<String> vargs)
+ {
+ AppletParams appletParams = new AppletParams();
+ String resourcePath = getString(map, "resourcePath");
+ if (resourcePath == null)
+ resourcePath = "";
+ if (resourcePath.length() > 0 && !resourcePath.endsWith("/"))
+ {
+ resourcePath += "/";
+ }
+ for (int i = params.length; --i >= 0;)
+ {
+ String prefName = params[i];
+ Object value = map.get(prefName);
+ if (value != null)
+ addParam(vargs, prefName, value, appletParams, resourcePath);
+ }
+ return appletParams;
+ }
+
+ private static String getString(Map<String, Object> map, String key)
+ {
+ Object o = map.get(key);
+ return (o == null ? null : o.toString());
+ }
+
+ public static AppletParams getAppletParams(String[] args,
+ List<String> vargs)
+ {
+ AppletParams appletParams = new AppletParams();
+ String resourcePath = "";
+ for (int i = args.length; --i > 0;) // > 0 is correct, not >=0
+ {
+ if (args[i].startsWith("name=\"Info.resourcePath\""))
+ {
+ resourcePath = getAttr(args[i], "value");
+ if (resourcePath.length() > 0 && !resourcePath.endsWith("/"))
+ {
+ resourcePath += "/";
+ }
+ break;
+ }
+ }
+ for (int i = 1; i < args.length; i++)
+ {
+ String arg = args[i].trim();
+ if (arg.startsWith("name="))
+ {
+ String prefName = getAttr(arg, "name");
+ String value = getAttr(arg, "value");
+ addParam(vargs, prefName, value, appletParams, resourcePath);
+ }
+ }
+ return appletParams;
+ }
+
+ private static void addParam(List<String> vargs, String prefName,
+ Object value, AppletParams appletParams, String resourcePath)
+ {
+
+ // note that Application arguments ARE case-sensitive, but
+ // Applet.getParameter() is not.
+
+ // prefName // CASE III
+
+ String argName = null; // CASE I
+
+ String appletName = prefName.toLowerCase(); // CASE II
+
+ // by nulling one or more of these names, that route will not be used.
+
+ switch (appletName)
+ {
+
+ case "file":
+ argName = "open";
+ prefName = null;
+ value = resourcePath + value;
+ break;
+ case "file2":
+ argName = "open2";
+ prefName = null;
+ value = resourcePath + value;
+ break;
+ case "oninit":
+ case "hidefeaturegroups":
+ // applet parameter only
+ // setting argName to null indicates that we want
+ // JalviewJSApp to take care of this using getParameter or getParameterAsObject
+ prefName = argName = null;
+ break;
+ case "tree":
+ case "treefile":
+ // setting appletName to null indicates that we want
+ // Jalview.doMain to taken care of this as Jalview args
+ argName = "tree";
+ prefName = null;
+ value = resourcePath + value;
+ break;
+
+ case "features":
+ case "jnetfile":
+ case "jpredfile":
+ case "pdbfile":
+ case "scorefile":
+ case "sequence":
+ case "annotations":
+ prefName = argName = null;
+ value = resourcePath + value;
+ break;
+
+ // non-loading preferences
+
+ case "defaultcolour":
+ prefName = Preferences.DEFAULT_COLOUR;
+ break;
+ case "defaultcolournuc":
+ prefName = Preferences.DEFAULT_COLOUR_NUC;
+ break;
+ case "defaultcolourprot":
+ prefName = Preferences.DEFAULT_COLOUR_PROT;
+ break;
+ case "annotationcolour_max":
+ prefName = Preferences.ANNOTATIONCOLOUR_MAX;
+ break;
+ case "annotationcolour_min":
+ prefName = Preferences.ANNOTATIONCOLOUR_MIN;
+ break;
+ case "enablesplitframe":
+ prefName = Preferences.ENABLE_SPLIT_FRAME;
+ break;
+ case "centrecolumnlabels":
+ prefName = Preferences.CENTRE_COLUMN_LABELS;
+ break;
+ case "sortby":
+ prefName = Preferences.SORT_ALIGNMENT; // id, etc.
+ break;
+ case "normalisesequencelogo":
+ prefName = Preferences.NORMALISE_CONSENSUS_LOGO;
+ break;
+ case "relaxedidmatch":
+ prefName = Preferences.RELAXEDSEQIDMATCHING;
+ break;
+ case "scaleproteinascdna":
+ prefName = Preferences.SCALE_PROTEIN_TO_CDNA;
+ break;
+ case "userdefinedcolour":
+ argName = "colour";
+ prefName = Preferences.USER_DEFINED_COLOURS;
+ break;
+ case "wrap":
+ prefName = Preferences.WRAP_ALIGNMENT;
+ break;
+ case "sortbytree":
+ argName = prefName;
+ prefName = Preferences.SORT_BY_TREE;
+ value = checkTF(value);
+ break;
+
+ // implemented; not tested:
+
+ case "pdbseq":
+ case "alignpdbfiles":
+ prefName = null;
+ break;
+ case "format":
+ argName = prefName;
+ break;
+ case "separator":
+ argName = prefName;
+ break;
+
+ // TODO: probably not relevant?
+
+ case "rgb":
+ prefName = null; // TODO no background for application?
+ break;
+ case "externalstructureviewer":
+ break;
+ case "application_url":
+ break;
+ case "automaticscrolling":
+ break;
+ case "heightscale":
+ break;
+ case "jalviewhelpurl":
+ break;
+ case "label":
+ break;
+ case "linklabel_":
+ prefName = "linkLabel_";
+ break;
+ case "linklabel_1":
+ prefName = "linkLabel_1";
+ break;
+ case "linkurl_":
+ prefName = "linkURL_";
+ break;
+
+ // unknown:
+
+ case "nojmol":
+ case "normaliselogo":
+ case "resolvetocodebase":
+ case "uppercase":
+ case "widthscale":
+ case "windowheight":
+ case "windowwidth":
+ prefName = null;
+ break;
+
+ // TRUE/FALSE
+
+ case "debug":
+ case "embedded":
+ case "showbutton":
+ value = checkTF(value);
+ break;
+ case "showannotation":
+ prefName = Preferences.SHOW_ANNOTATIONS;
+ value = checkTF(value);
+ break;
+ case "showconsensus":
+ prefName = Preferences.SHOW_CONSENSUS_LOGO;
+ value = checkTF(value);
+ break;
+ case "showconsensushistogram":
+ prefName = Preferences.SHOW_CONSENSUS_HISTOGRAM;
+ value = checkTF(value);
+ break;
+ case "showconservation":
+ prefName = Preferences.SHOW_CONSERVATION;
+ value = checkTF(value);
+ break;
+ case "showgroupconsensus":
+ prefName = Preferences.SHOW_GROUP_CONSENSUS;
+ value = checkTF(value);
+ break;
+ case "showgroupconservation":
+ prefName = Preferences.SHOW_GROUP_CONSERVATION;
+ value = checkTF(value);
+ break;
+ case "showoccupancy":
+ prefName = Preferences.SHOW_OCCUPANCY;
+ value = checkTF(value);
+ break;
+ case "showquality":
+ prefName = Preferences.SHOW_QUALITY;
+ value = checkTF(value);
+ break;
+ case "showsequencelogo":
+ prefName = Preferences.SHOW_CONSENSUS_LOGO;
+ value = checkTF(value);
+ break;
+ case "showunconserved":
+ prefName = Preferences.SHOW_UNCONSERVED;
+ value = checkTF(value);
+ break;
+ case "showfeaturegroups":
+ case "showfeaturesettings":
+ case "showfullid":
+ case "showtreebootstraps":
+ case "showtreedistances":
+ case "showunlinkedtreenodes":
+ value = checkTF(value);
+ break;
+ default:
+ if (appletName.startsWith("pdbfile")
+ || appletName.startsWith("sequence") && Character
+ .isDigit(appletName.charAt(appletName.length() - 1)))
+ {
+ // could be pdbFile2, for example
+ prefName = argName = null;
+ value = resourcePath + value;
+ break;
+ }
+ // or one of the app preference names
+ break;
+ }
+
+ // CASE I. args[] name and value for ArgsParser
+ //
+ // If given an argument name,
+ // put name and value into application args
+ if (value != null && argName != null)
+ {
+ vargs.add(argName);
+ if (value != "true")
+ {
+ vargs.add(value.toString());
+ }
+ }
+
+ // CASE II. applet parameter for JalviewJSApp
+
+ if (value == null)
+ {
+ value = "false";
+ }
+ System.out.println("AppletParams propName=" + prefName + " argName="
+ + argName + " appletName=" + appletName + " value=" + value);
+ if (appletName != null)
+ {
+ appletParams.put(appletName, value);
+ }
+
+ // CASE III. mapped to a Preference
+
+ if (prefName != null)
+ {
+ Cache.setPropertyNoSave(prefName, value.toString());
+ }
+ }
+
+ /**
+ * Check for a single-argument option.
+ *
+ * @param value
+ * @return "true" or null
+ */
+ private static String checkTF(Object value)
+ {
+ return (("" + value).toLowerCase() == "true" ? "true" : null);
+ }
+
+ /**
+ * Crude applet innerHTML parser
+ *
+ * @param tag
+ * @param attr
+ * @return
+ */
+ private static String getAttr(String tag, String attr)
+ {
+ int pt = tag.indexOf(attr + "=\"");
+ if (pt < 0)
+ {
+ System.out
+ .println("AppletParams did not read " + attr + " in " + tag);
+ return null;
+ }
+ // <param name="sortByTree" value="True"/>
+ int pt1 = pt + attr.length() + 2;
+ int pt2 = tag.indexOf("\"", pt1);
+ return (pt < 0 ? null : tag.substring(pt1, pt2));
+ }
+
+ public static void main(String[] args)
+ {
+ new AppletParams("<applet\r\n"
+ + " code=\"jalview.bin.JalviewLite\" width=\"140\" height=\"35\"\r\n"
+ + " archive=\"jalviewApplet.jar,JmolApplet-14.6.4_2016.10.26.jar,java-json.jar,json_simple-1.1.jar\"> \r\n"
+ + " <param name=\"permissions\" value=\"sandbox\"/>\r\n"
+ + " <param name=\"file\" value=\"uniref50.fa\"/>\r\n"
+ + " <param name=\"treeFile\" value=\"ferredoxin.nw\"/>\r\n"
+ + " <param name=\"userDefinedColour\" value=\"C=yellow; R,K,H=FF5555; D,E=5555FF\"/>\r\n"
+ + " <param name=\"sortByTree\" value=\"True\"/>\r\n"
+ + " <param name=\"showSequenceLogo\" value=\"true\"/>\r\n"
+ + " <param name=\"showGroupConsensus\" value=\"true\"/>\r\n"
+ + " <param name=\"showFullId\" value=\"false\"/>\r\n"
+ + " <param name=\"linkLabel_1\" value=\"Uniprot\"/>\r\n"
+ + " <param name=\"linkUrl_1\" value=\"http://www.uniprot.org/uniprot/$SEQUENCE_ID$\"/>\r\n"
+ + " <param name=\"linkLabel_2\" value=\"EMBL-EBI Search\"/>\r\n"
+ + " <param name=\"linkUrl_2\" value=\"http://www.ebi.ac.uk/ebisearch/search.ebi?db=allebi&query=$SEQUENCE_ID$\"/>\r\n"
+ + " <param name=\"APPLICATION_URL\" value=\"http://www.jalview.org/services/launchApp\"/>\r\n"
+ + " </applet>");
+ }
+
+}
\ No newline at end of file
--- /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 jalview.util.Platform;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * A class to hold singleton objects, whose scope (context) is
+ * <ul>
+ * <li>the Java runtime (JVM) when running as Java</li>
+ * <li>one 'applet', when running as JalviewJS</li>
+ * </ul>
+ * This allows separation of multiple JS applets running on the same browser
+ * page, each with their own 'singleton' instances.
+ * <p>
+ * Instance objects are held in a separate Map (keyed by Class) for each
+ * context. For Java, this is just a single static Map. For SwingJS, the map is
+ * stored as a field {@code _swingjsSingletons} of
+ * {@code Thread.currentThread.getThreadGroup()}, as a proxy for the applet.
+ * <p>
+ * Note that when an applet is stopped, its ThreadGroup is removed, allowing any
+ * singleton references to be garbage collected.
+ *
+ * @author hansonr
+ */
+public class ApplicationSingletonProvider
+{
+ /**
+ * A tagging interface to mark classes whose singleton instances may be served
+ * by {@code ApplicationSingletonProvider}, giving a distinct instance per JS
+ * 'applet'.
+ * <p>
+ * A class whose singleton should have global scope (be shared across all
+ * applets on a page) should <em>not</em> use this mechanism, but just provide
+ * a single instance (class static member) in the normal way.
+ */
+ public interface ApplicationSingletonI
+ {
+ }
+
+ /*
+ * Map used to hold singletons in JVM context
+ */
+ private static Map<Class<? extends ApplicationSingletonI>, ApplicationSingletonI> singletons = new HashMap<>();
+
+ /**
+ * private constructor for non-instantiable class
+ */
+ private ApplicationSingletonProvider()
+ {
+ }
+
+ /**
+ * Returns the singletons map for the current context (JVM for Java,
+ * ThreadGroup for JS), creating the map on the first request for each JS
+ * ThreadGroup
+ *
+ * @return
+ */
+ private static Map<Class<? extends ApplicationSingletonI>, ApplicationSingletonI> getContextMap()
+ {
+ @SuppressWarnings("unused")
+ ThreadGroup g = (Platform.isJS()
+ ? Thread.currentThread().getThreadGroup()
+ : null);
+ Map<Class<? extends ApplicationSingletonI>, ApplicationSingletonI> map = singletons;
+ /** @j2sNative map = g._swingjsSingletons; */
+ if (map == null)
+ {
+ map = new HashMap<>();
+ /** @j2sNative g._swingjsSingletons = map; */
+ }
+
+ return map;
+ }
+
+ /**
+ * Answers the singleton instance of the given class for the current context
+ * (JVM or SwingJS 'applet'). If no instance yet exists, one is created, by
+ * calling the class's no-argument constructor. Answers null if any error
+ * occurs (or occurred previously for the same class).
+ *
+ * @param c
+ * @return
+ */
+ public static ApplicationSingletonI getInstance(Class<? extends ApplicationSingletonI> c)
+ {
+ Map<Class<? extends ApplicationSingletonI>, ApplicationSingletonI> map = getContextMap();
+ if (map.containsKey(c))
+ {
+ /*
+ * singleton already created _or_ creation failed (null value stored)
+ */
+ return map.get(c);
+ }
+
+ /*
+ * create and save the singleton
+ */
+ ApplicationSingletonI o = map.get(c);
+ try
+ {
+ Constructor<? extends ApplicationSingletonI> con = c
+ .getDeclaredConstructor();
+ con.setAccessible(true);
+ o = con.newInstance();
+ } catch (IllegalAccessException | InstantiationException
+ | IllegalArgumentException | InvocationTargetException
+ | NoSuchMethodException | SecurityException e)
+ {
+ Cache.log.error("Failed to create singleton for " + c.toString()
+ + ", error was: " + e.toString());
+ e.printStackTrace();
+ }
+
+ /*
+ * store the new singleton; note that a
+ * null value is saved if construction failed
+ */
+ getContextMap().put(c, o);
+ return o;
+ }
+
+ /**
+ * Removes the current singleton instance of the given class from the current
+ * application context. This has the effect of ensuring that a new instance is
+ * created the next time one is requested.
+ *
+ * @param c
+ */
+ public static void removeInstance(
+ Class<? extends ApplicationSingletonI> c)
+ {
+ Map<Class<? extends ApplicationSingletonI>, ApplicationSingletonI> map = getContextMap();
+ if (map != null)
+ {
+ map.remove(c);
+ }
+ }
+}
*/
package jalview.bin;
+import jalview.util.Platform;
+
import java.net.URLDecoder;
-import java.util.Vector;
+import java.util.ArrayList;
+import java.util.List;
/**
* Notes: this argParser does not distinguish between parameter switches,
*/
public class ArgsParser
{
- Vector<String> vargs = null;
+
+ // BH 2019 - new
+
+ public static final String NOCALCULATION = "nocalculation";
+
+ public static final String NOMENUBAR = "nomenubar";
+
+ public static final String NOSTATUS = "nostatus";
+
+ public static final String SHOWOVERVIEW = "showoverview";
+
+ //
+ public static final String ANNOTATIONS = "annotations";
+
+ public static final String COLOUR = "colour";
+
+ public static final String FEATURES = "features";
+
+ public static final String GROOVY = "groovy";
+
+ public static final String GROUPS = "groups";
+
+ public static final String HEADLESS = "headless";
+
+ public static final String JABAWS = "jabaws";
+
+ public static final String NOANNOTATION = "no-annotation";
+
+ public static final String NOANNOTATION2 = "noannotation"; // BH 2019.05.07
+
+ public static final String NODISPLAY = "nodisplay";
+
+ public static final String NOGUI = "nogui";
+
+ public static final String NONEWS = "nonews";
+
+ public static final String NOQUESTIONNAIRE = "noquestionnaire";
+
+ public static final String NOSORTBYTREE = "nosortbytree";
+
+ public static final String NOUSAGESTATS = "nousagestats";
+
+ public static final String OPEN = "open";
+
+ public static final String OPEN2 = "open2"; // BH added -- for applet
+ // compatibility; not fully
+ // implemented
+
+ public static final String PROPS = "props";
+
+ public static final String QUESTIONNAIRE = "questionnaire";
+
+ public static final String SETPROP = "setprop";
+
+ public static final String SORTBYTREE = "sortbytree";
+
+ public static final String TREE = "tree";
+
+ public static final String VDOC = "vdoc";
+
+ public static final String VSESS = "vsess";
+
+ private List<String> vargs = null;
+
+ private boolean isApplet;
+
+ private AppletParams appletParams;
+
+ public boolean isApplet()
+ {
+ return isApplet;
+ }
public ArgsParser(String[] args)
{
- vargs = new Vector<String>();
- for (int i = 0; i < args.length; i++)
+ vargs = new ArrayList<>();
+ isApplet = (args.length > 0 && args[0].startsWith("<applet"));
+ if (isApplet)
{
- String arg = args[i].trim();
- if (arg.charAt(0) == '-')
+ appletParams = AppletParams.getAppletParams(args, vargs);
+ }
+ else
+ {
+ if (Platform.isJS())
+
{
- arg = arg.substring(1);
+ isApplet = true;
+ appletParams = AppletParams
+ .getAppletParams(Platform.getAppletInfoAsMap(), vargs);
+ }
+ for (int i = 0; i < args.length; i++)
+ {
+ String arg = args[i].trim();
+ if (arg.charAt(0) == '-')
+ {
+ arg = arg.substring(1);
+ }
+ vargs.add(arg);
}
- vargs.addElement(arg);
}
}
String dc = null, ret = null;
if (index != -1)
{
- ret = vargs.elementAt(index + 1).toString();
- vargs.removeElementAt(index);
- vargs.removeElementAt(index);
+ ret = vargs.get(index + 1).toString();
+ vargs.remove(index);
+ vargs.remove(index);
if (utf8decode && ret != null)
{
try
{
if (vargs.contains(arg))
{
- vargs.removeElement(arg);
+ vargs.remove(arg);
return true;
}
else
return vargs.size();
}
+ public Object getAppletValue(String key, String def, boolean asString)
+ {
+ Object value;
+ return (appletParams == null ? null
+ : (value = appletParams.get(key.toLowerCase())) == null
+ ? def : asString ? "" + value
+ : value);
+ }
+
}
import org.apache.log4j.Logger;
import org.apache.log4j.SimpleLayout;
+import jalview.bin.ApplicationSingletonProvider.ApplicationSingletonI;
import jalview.datamodel.PDBEntry;
import jalview.gui.Preferences;
import jalview.gui.UserDefinedColours;
* @author $author$
* @version $Revision$
*/
-public class Cache
+public class Cache implements ApplicationSingletonI
{
+
+ private Cache()
+ {
+ // private singleton
+ }
+
+ /**
+ * In Java, this will be a static field instance, which will be
+ * application-specific; in JavaScript it will be an applet-specific instance
+ * tied to the applet's ThreadGroup.
+ *
+ * @return
+ */
+ public static Cache getInstance()
+ {
+ return (Cache) ApplicationSingletonProvider.getInstance(Cache.class);
+ }
+
/**
* property giving log4j level for CASTOR loggers
*/
/**
* Sifts settings
*/
- public static final String DEFAULT_SIFTS_DOWNLOAD_DIR = System
- .getProperty("user.home") + File.separatorChar
- + ".sifts_downloads" + File.separatorChar;
-
+ public static final String DEFAULT_SIFTS_DOWNLOAD_DIR = Platform.getUserPath(".sifts_downloads/");
+
private final static String DEFAULT_CACHE_THRESHOLD_IN_DAYS = "2";
private final static String DEFAULT_FAIL_SAFE_PID_THRESHOLD = "30";
/**
* Identifiers.org download settings
*/
- private static final String ID_ORG_FILE = System.getProperty("user.home")
- + File.separatorChar + ".identifiers.org.ids.json";
+ private static final String ID_ORG_FILE = Platform.getUserPath(".identifiers.org.ids.json");
/**
* Allowed values are PDB or mmCIF
public static char[] proxyAuthPassword = null;
/** Jalview Properties */
- public static Properties applicationProperties = new Properties()
+ private Properties applicationProperties = new Properties()
{
// override results in properties output in alphabetical order
@Override
*/
public static void loadProperties(String propsFile)
{
+
+ getInstance().loadPropertiesImpl(propsFile);
+
+ }
+
+ private void loadPropertiesImpl(String propsFile)
+ {
+
propertiesFile = propsFile;
String releasePropertiesFile = null;
boolean defaultProperties = false;
if (propsFile == null && !propsAreReadOnly)
{
+ // TODO: @bsoares - for 2.12 testing: check test,develop,release props are located correctly
String channelPrefsFilename = ChannelProperties
.getProperty("preferences.filename");
String releasePrefsFilename = ".jalview_properties";
- propertiesFile = System.getProperty("user.home") + File.separatorChar
- + channelPrefsFilename;
- releasePropertiesFile = System.getProperty("user.home")
- + File.separatorChar + releasePrefsFilename;
+ propertiesFile = Platform.getUserPath(channelPrefsFilename);
+ releasePropertiesFile = Platform.getUserPath(releasePrefsFilename);
defaultProperties = true;
}
else
return url;
}
- public static void loadBuildProperties(boolean reportVersion)
+ public void loadBuildProperties(boolean reportVersion)
{
String codeInstallation = getProperty("INSTALLATION");
boolean printVersion = codeInstallation == null;
}
}
- private static void deleteBuildProperties()
+ private void deleteBuildProperties()
{
applicationProperties.remove("LATEST_VERSION");
applicationProperties.remove("VERSION");
*/
public static String getProperty(String key)
{
- String prop = applicationProperties.getProperty(key);
- if (prop == null && Platform.isJS())
- {
- prop = applicationProperties.getProperty(Platform.getUniqueAppletID()
- + "_" + JS_PROPERTY_PREFIX + key);
- }
+ String prop = getInstance().applicationProperties.getProperty(key);
+ // if (prop == null && Platform.isJS())
+ // {
+ // prop = applicationProperties.getProperty(Platform.getUniqueAppletID()
+ // + "_" + JS_PROPERTY_PREFIX + key);
+ // }
return prop;
}
*/
public static Object setProperty(String key, String obj)
{
- Object oldValue = null;
- try
- {
- oldValue = applicationProperties.setProperty(key, obj);
- if (propertiesFile != null && !propsAreReadOnly)
- {
- FileOutputStream out = new FileOutputStream(propertiesFile);
- applicationProperties.store(out, "---JalviewX Properties File---");
- out.close();
- }
- } catch (Exception ex)
- {
- System.out.println(
- "Error setting property: " + key + " " + obj + "\n" + ex);
- }
- return oldValue;
+ return getInstance().setPropertyImpl(key, obj, true);
+ }
+
+ /**
+ * Removes the specified property from the jalview properties file
+ *
+ * @param key
+ */
+ public static void removeProperty(String key)
+ {
+ getInstance().removePropertyImpl(key, true);
}
/**
- * remove the specified property from the jalview properties file
+ * Removes the named property for the running application, without saving the
+ * properties file
*
- * @param string
+ * BH noting that ColourMenuHelper calls this. If the intent is to save, then
+ * simply chanet that call to removeProperty(key).
+ *
+ * @param key
*/
- public static void removeProperty(String string)
+ public static void removePropertyNoSave(String key)
{
- applicationProperties.remove(string);
- saveProperties();
+
+ getInstance().
+
+ removePropertyImpl(key, false);
+ }
+
+ /**
+ * Removes the named property, and optionally saves the current properties to
+ * file
+ *
+ * @param key
+ * @param andSave
+ */
+ private void removePropertyImpl(String key, boolean andSave)
+ {
+ applicationProperties.remove(key);
+ if (andSave)
+ saveProperties();
}
/**
*/
public static void saveProperties()
{
+ getInstance().savePropertiesImpl();
+ }
+
+ /**
+ * save the properties to the jalview properties path
+ */
+ private void savePropertiesImpl()
+
+ {
if (!propsAreReadOnly)
{
try
* @param property
* @param colour
*/
- public static void setColourProperty(String property, Color colour)
+ public static void setColourPropertyNoSave(String property, Color colour)
{
- setProperty(property, jalview.util.Format.getHexString(colour));
+ setPropertyNoSave(property, jalview.util.Format.getHexString(colour));
}
/**
public static Date getDateProperty(String propertyName)
{
String val = getProperty(propertyName);
+
if (val != null)
{
try
{
- return date_format.parse(val);
+ if ((val = val.trim()).indexOf(",") < 0 && val.indexOf("-") >= 0 && val.indexOf(" ") == val.lastIndexOf(" ")) {
+ val = val.replace(" ",", ").replace('-',' ');
+ }
+ Date date = date_format.parse(val);
+ return date;
} catch (Exception ex)
{
System.err.println("Invalid or corrupt date in property '"
}
if (value == null || value.trim().length() < 1)
{
- Cache.applicationProperties.remove(propName);
+ getInstance().applicationProperties.remove(propName);
}
else
{
- Cache.applicationProperties.setProperty(propName, value);
+ getInstance().applicationProperties.setProperty(propName, value);
}
}
}
else
{
- applicationProperties
+ getInstance().applicationProperties
.remove(UserDefinedColours.USER_DEFINED_COLOURS);
}
}
.append(" Installation: ");
sb.append(jalview.bin.Cache.getDefault("INSTALLATION", "unknown"));
sb.append("\n");
- sb.append("Build Date: ");
- sb.append(jalview.bin.Cache.getDefault("BUILD_DATE", "unknown"));
+ sb.append("Build Date: "
+ + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown"));
sb.append("\n");
sb.append("Java version: ");
sb.append(System.getProperty("java.version"));
return jalview.bin.Cache.getDefault("INSTALLATION", "unknown");
}
+ /**
+ *
+ * For AppletParams and Preferences ok_actionPerformed and
+ * startupFileTextfield_mouseClicked
+ *
+ * Sets a property value for the running application, without saving it to the
+ * properties file
+ *
+ * @param key
+ * @param obj
+ */
+ public static void setPropertyNoSave(String key, String obj)
+ {
+ getInstance().setPropertyImpl(key, obj, false);
+ }
+
+ /**
+ * Sets a property value, and optionally also saves the current properties to
+ * file
+ *
+ * @param key
+ * @param obj
+ * @param andSave
+ * @return
+ */
+ private Object setPropertyImpl(
+ String key, String obj, boolean andSave)
+ {
+ Object oldValue = null;
+ try
+ {
+ oldValue = applicationProperties.setProperty(key, obj);
+ if (andSave && !propsAreReadOnly && propertiesFile != null)
+ {
+ FileOutputStream out = new FileOutputStream(propertiesFile);
+ applicationProperties.store(out, "---JalviewX Properties File---");
+ out.close();
+ }
+ } catch (Exception ex)
+ {
+ System.out.println(
+ "Error setting property: " + key + " " + obj + "\n" + ex);
+ }
+ return oldValue;
+ }
+
public static String getStackTraceString(Throwable t)
{
StringWriter sw = new StringWriter();
*/
package jalview.bin;
-import java.util.Locale;
+import java.awt.GraphicsEnvironment;
import java.io.BufferedReader;
import java.io.File;
import java.security.Permissions;
import java.security.Policy;
import java.util.HashMap;
+import java.util.Locale;
import java.util.Map;
import java.util.Vector;
import java.util.logging.ConsoleHandler;
import groovy.lang.Binding;
import groovy.util.GroovyScriptEngine;
+import jalview.api.AlignCalcWorkerI;
+import jalview.bin.ApplicationSingletonProvider.ApplicationSingletonI;
import jalview.ext.so.SequenceOntology;
import jalview.gui.AlignFrame;
+import jalview.gui.AlignViewport;
import jalview.gui.Desktop;
+import jalview.gui.Preferences;
import jalview.gui.PromptUserConfig;
import jalview.io.AppletFormatAdapter;
import jalview.io.BioJsHTMLOutput;
* @author $author$
* @version $Revision$
*/
-public class Jalview
+public class Jalview implements ApplicationSingletonI
{
- static
+ // for testing those nasty messages you cannot ever find.
+ // static
+ // {
+ // System.setOut(new PrintStream(new ByteArrayOutputStream())
+ // {
+ // @Override
+ // public void println(Object o)
+ // {
+ // if (o != null)
+ // {
+ // System.err.println(o);
+ // }
+ // }
+ //
+ // });
+ // }
+ public static Jalview getInstance()
+ {
+ return (Jalview) ApplicationSingletonProvider
+ .getInstance(Jalview.class);
+ }
+
+ private Jalview()
{
Platform.getURLCommandArguments();
}
- /*
- * singleton instance of this class
- */
- private static Jalview instance;
private Desktop desktop;
- public static AlignFrame currentAlignFrame;
+ public AlignFrame currentAlignFrame;
+
+ public String appletResourcePath;
+
+ public String j2sAppletID;
+
+ private boolean noCalculation, noMenuBar, noStatus;
+
+ private boolean noAnnotation;
+
+ public boolean getStartCalculations()
+ {
+ return !noCalculation;
+ }
+
+ public boolean getAllowMenuBar()
+ {
+ return !noMenuBar;
+ }
+
+ public boolean getShowStatus()
+ {
+ return !noStatus;
+ }
+
+ public boolean getShowAnnotation()
+ {
+ return !noAnnotation;
+ }
static
{
}
- public static Jalview getInstance()
- {
- return instance;
- }
+ private final static boolean doPlatformLogging = false;
/**
* main class for Jalview application
*/
public static void main(String[] args)
{
- // setLogging(); // BH - for event debugging in JavaScript
- instance = new Jalview();
- instance.doMain(args);
- }
-
- private static void logClass(String name)
- {
- // BH - for event debugging in JavaScript
- ConsoleHandler consoleHandler = new ConsoleHandler();
- consoleHandler.setLevel(Level.ALL);
- Logger logger = Logger.getLogger(name);
- logger.setLevel(Level.ALL);
- logger.addHandler(consoleHandler);
- }
-
- @SuppressWarnings("unused")
- private static void setLogging()
- {
-
- /**
- * @j2sIgnore
- *
- */
+ if (doPlatformLogging)
{
- System.out.println("not in js");
+ Platform.startJavaLogging();
}
- // BH - for event debugging in JavaScript (Java mode only)
- if (!Platform.isJS())
- /**
- * Java only
- *
- * @j2sIgnore
- */
- {
- Logger.getLogger("").setLevel(Level.ALL);
- logClass("java.awt.EventDispatchThread");
- logClass("java.awt.EventQueue");
- logClass("java.awt.Component");
- logClass("java.awt.focus.Component");
- logClass("java.awt.focus.DefaultKeyboardFocusManager");
- }
+ getInstance().doMain(args);
}
+
+
+
/**
* @param args
void doMain(String[] args)
{
- if (!Platform.isJS())
+ boolean isJS = Platform.isJS();
+ if (!isJS)
{
System.setSecurityManager(null);
}
}
// report Jalview version
- Cache.loadBuildProperties(true);
+ Cache.getInstance().loadBuildProperties(true);
ArgsParser aparser = new ArgsParser(args);
boolean headless = false;
String usrPropsFile = aparser.getValue("props");
Cache.loadProperties(usrPropsFile); // must do this before
- if (usrPropsFile != null)
+ boolean allowServices = true;
+
+ if (isJS)
{
- System.out.println(
- "CMD [-props " + usrPropsFile + "] executed successfully!");
+ j2sAppletID = Platform.getAppID(null);
+ Preferences.setAppletDefaults();
+ Cache.loadProperties(usrPropsFile); // again, because we
+ // might be changing defaults here?
+ appletResourcePath = (String) aparser.getAppletValue("resourcepath",
+ null, true);
}
- if (!Platform.isJS())
+ else
/**
* Java only
*
* @j2sIgnore
*/
{
+ if (usrPropsFile != null)
+ {
+ System.out.println(
+ "CMD [-props " + usrPropsFile + "] executed successfully!");
+ }
if (aparser.contains("help") || aparser.contains("h"))
{
showUsage();
System.exit(0);
}
+ // BH note: Only -nodisplay is official; others are deprecated?
if (aparser.contains("nodisplay") || aparser.contains("nogui")
- || aparser.contains("headless"))
+ || aparser.contains("headless")
+ || GraphicsEnvironment.isHeadless())
{
- System.setProperty("java.awt.headless", "true");
+ if (!isJS) {
+ // BH Definitely not a good idea in JavaScript;
+ // probably should not be here for Java, either.
+ System.setProperty("java.awt.headless", "true");
+ }
headless = true;
}
// anything else!
- final String jabawsUrl = aparser.getValue("jabaws");
- if (jabawsUrl != null)
+ final String jabawsUrl = aparser.getValue(ArgsParser.JABAWS);
+ allowServices = !("none".equals(jabawsUrl));
+ if (allowServices && jabawsUrl != null)
{
try
{
- Jws2Discoverer.getDiscoverer().setPreferredUrl(jabawsUrl);
+ Jws2Discoverer.getInstance().setPreferredUrl(jabawsUrl);
System.out.println(
"CMD [-jabaws " + jabawsUrl + "] executed successfully!");
} catch (MalformedURLException e)
"Invalid jabaws parameter: " + jabawsUrl + " ignored");
}
}
- }
- String defs = aparser.getValue("setprop");
+ }
+ String defs = aparser.getValue(ArgsParser.SETPROP);
while (defs != null)
{
int p = defs.indexOf('=');
else
{
System.out.println("Executing setprop argument: " + defs);
- if (Platform.isJS())
+ if (isJS)
{
Cache.setProperty(defs.substring(0, p), defs.substring(p + 1));
}
- // DISABLED FOR SECURITY REASONS
- // TODO: add a property to allow properties to be overriden by cli args
- // Cache.setProperty(defs.substring(0,p), defs.substring(p+1));
}
defs = aparser.getValue("setprop");
}
* configure 'full' SO model if preferences say to, else use the default (full SO)
* - as JS currently doesn't have OBO parsing, it must use 'Lite' version
*/
- boolean soDefault = !Platform.isJS();
+ boolean soDefault = !isJS;
if (Cache.getDefault("USE_FULL_SO", soDefault))
{
SequenceOntologyFactory.setInstance(new SequenceOntology());
if (!headless)
{
Desktop.nosplash = aparser.contains("nosplash");
- desktop = new Desktop();
+ desktop = Desktop.getInstance();
desktop.setInBatchMode(true); // indicate we are starting up
try
Cache.log.error(t.getMessage());
// t.printStackTrace();
}
-
// set Proxy settings before all the internet calls
Cache.setProxyPropertiesFromPreferences();
desktop.setVisible(true);
- if (!Platform.isJS())
+ if (isJS)
+ {
+ Cache.setProperty("SHOW_JWS2_SERVICES", "false");
+ }
+ if (allowServices && !aparser.contains("nowebservicediscovery"))
+ {
+ desktop.startServiceDiscovery();
+ }
+
+ if (!isJS)
/**
* Java only
*
* @j2sIgnore
*/
{
- if (!aparser.contains("nowebservicediscovery"))
- {
- desktop.startServiceDiscovery();
- }
if (!aparser.contains("nousagestats"))
{
startUsageStats(desktop);
BioJsHTMLOutput.updateBioJS();
}
}
+ parseArguments(aparser, true);
+ }
+
+ /**
+ * Parse all command-line String[] arguments as well as all JavaScript-derived
+ * parameters from Info.
+ *
+ * We allow for this method to be run from JavaScript. Basically allowing
+ * simple scripting.
+ *
+ * @param aparser
+ * @param isStartup
+ */
+ public void parseArguments(ArgsParser aparser, boolean isStartup)
+ {
- // Move any new getdown-launcher-new.jar into place over old
- // getdown-launcher.jar
- String appdirString = System.getProperty("getdownappdir");
- if (appdirString != null && appdirString.length() > 0)
+ String groovyscript = null; // script to execute after all loading is
+ boolean isJS = Platform.isJS();
+ if (!isJS)
+ /** @j2sIgnore */
{
- final File appdir = new File(appdirString);
- new Thread()
+ // Move any new getdown-launcher-new.jar into place over old
+ // getdown-launcher.jar
+ String appdirString = System.getProperty("getdownappdir");
+ if (appdirString != null && appdirString.length() > 0)
{
- @Override
- public void run()
+ final File appdir = new File(appdirString);
+ new Thread()
{
- LaunchUtil.upgradeGetdown(
- new File(appdir, "getdown-launcher-old.jar"),
- new File(appdir, "getdown-launcher.jar"),
- new File(appdir, "getdown-launcher-new.jar"));
- }
- }.start();
- }
+ @Override
+ public void run()
+ {
+ LaunchUtil.upgradeGetdown(
+ new File(appdir, "getdown-launcher-old.jar"),
+ new File(appdir, "getdown-launcher.jar"),
+ new File(appdir, "getdown-launcher-new.jar"));
+ }
+ }.start();
+ }
- String file = null, data = null;
- FileFormatI format = null;
- DataSourceType protocol = null;
- FileLoader fileLoader = new FileLoader(!headless);
+ // completed one way or another
+ // extract groovy argument and execute if necessary
+ groovyscript = aparser.getValue("groovy", true);
+ }
- String groovyscript = null; // script to execute after all loading is
- // completed one way or another
- // extract groovy argument and execute if necessary
- groovyscript = aparser.getValue("groovy", true);
- file = aparser.getValue("open", true);
+ String file = aparser.getValue("open", true);
- if (file == null && desktop == null)
+ if (!isJS && file == null && desktop == null)
{
System.out.println("No files to open!");
System.exit(1);
}
+ setDisplayParameters(aparser);
+
+ // time to open a file.
long progress = -1;
+ DataSourceType protocol = null;
+ FileLoader fileLoader = new FileLoader(!headless);
+ FileFormatI format = null;
// Finally, deal with the remaining input data.
- if (file != null)
+ AlignFrame af = null;
+
+ JalviewJSApp jsApp = (isJS ? new JalviewJSApp(this, aparser) : null);
+
+ if (file == null)
+ {
+ if (isJS)
+ {
+ // JalviewJS allows sequence1 sequence2 ....
+
+ }
+ else if (!headless && Cache.getDefault("SHOW_STARTUP_FILE", true))
+ /**
+ * Java only
+ *
+ * @j2sIgnore
+ */
+ {
+
+ // We'll only open the default file if the desktop is visible.
+ // And the user
+ // ////////////////////
+
+ file = Cache.getDefault("STARTUP_FILE",
+ Cache.getDefault("www.jalview.org",
+ "http://www.jalview.org")
+ + "/examples/exampleFile_2_7.jar");
+ if (file.equals(
+ "http://www.jalview.org/examples/exampleFile_2_3.jar"))
+ {
+ // hardwire upgrade of the startup file
+ file.replace("_2_3.jar", "_2_7.jar");
+ // and remove the stale setting
+ Cache.removeProperty("STARTUP_FILE");
+ }
+
+ protocol = DataSourceType.FILE;
+
+ if (file.indexOf("http:") > -1)
+ {
+ protocol = DataSourceType.URL;
+ }
+
+ if (file.endsWith(".jar"))
+ {
+ format = FileFormat.Jalview;
+ }
+ else
+ {
+ try
+ {
+ format = new IdentifyFile().identify(file, protocol);
+ } catch (FileFormatException e)
+ {
+ // TODO what?
+ }
+ }
+ af = fileLoader.LoadFileWaitTillLoaded(file, protocol, format);
+ }
+ }
+ else
{
if (!headless)
{
}
}
+ // JS Only argument to provide a format parameter to specify what format to use
+ String fileFormat = (isJS
+ ? (String) aparser.getAppletValue("format", null, true)
+ : null);
protocol = AppletFormatAdapter.checkProtocol(file);
try
{
- format = new IdentifyFile().identify(file, protocol);
+ format = (fileFormat != null
+ ? FileFormats.getInstance().forName(fileFormat)
+ : null);
+ if (format == null)
+ {
+ format = new IdentifyFile().identify(file, protocol);
+ }
} catch (FileFormatException e1)
{
// TODO ?
}
- AlignFrame af = fileLoader.LoadFileWaitTillLoaded(file, protocol,
+ af = new FileLoader(!headless).LoadFileWaitTillLoaded(file, protocol,
format);
if (af == null)
{
- System.out.println("error");
+ System.out.println("jalview error - AlignFrame was not created");
}
else
{
- setCurrentAlignFrame(af);
- data = aparser.getValue("colour", true);
- if (data != null)
+
+ // JalviewLite interface for JavaScript allows second file open
+ String file2 = aparser.getValue(ArgsParser.OPEN2, true);
+ if (file2 != null)
{
- data.replaceAll("%20", " ");
-
- ColourSchemeI cs = ColourSchemeProperty.getColourScheme(
- af.getViewport(), af.getViewport().getAlignment(), data);
-
- if (cs != null)
+ protocol = AppletFormatAdapter.checkProtocol(file2);
+ try
{
- System.out.println(
- "CMD [-color " + data + "] executed successfully!");
+ format = new IdentifyFile().identify(file2, protocol);
+ } catch (FileFormatException e1)
+ {
+ // TODO ?
}
- af.changeColour(cs);
- }
-
- // Must maintain ability to use the groups flag
- data = aparser.getValue("groups", true);
- if (data != null)
- {
- af.parseFeaturesFile(data,
- AppletFormatAdapter.checkProtocol(data));
- // System.out.println("Added " + data);
- System.out.println(
- "CMD groups[-" + data + "] executed successfully!");
- }
- data = aparser.getValue("features", true);
- if (data != null)
- {
- af.parseFeaturesFile(data,
- AppletFormatAdapter.checkProtocol(data));
- // System.out.println("Added " + data);
- System.out.println(
- "CMD [-features " + data + "] executed successfully!");
- }
-
- data = aparser.getValue("annotations", true);
- if (data != null)
- {
- af.loadJalviewDataFile(data, null, null, null);
- // System.out.println("Added " + data);
- System.out.println(
- "CMD [-annotations " + data + "] executed successfully!");
- }
- // set or clear the sortbytree flag.
- if (aparser.contains("sortbytree"))
- {
- af.getViewport().setSortByTree(true);
- if (af.getViewport().getSortByTree())
+ AlignFrame af2 = new FileLoader(!headless)
+ .LoadFileWaitTillLoaded(file2, protocol, format);
+ if (af2 == null)
{
- System.out.println("CMD [-sortbytree] executed successfully!");
+ System.out.println("error");
}
- }
- if (aparser.contains("no-annotation"))
- {
- af.getViewport().setShowAnnotation(false);
- if (!af.getViewport().isShowAnnotation())
+ else
{
- System.out.println("CMD no-annotation executed successfully!");
+ AlignViewport.openLinkedAlignmentAs(af,
+ af.getViewport().getAlignment(),
+ af2.getViewport().getAlignment(), "",
+ AlignViewport.SPLIT_FRAME);
+ System.out.println(
+ "CMD [-open2 " + file2 + "] executed successfully!");
}
}
- if (aparser.contains("nosortbytree"))
+ // af is loaded - so set it as current frame
+ setCurrentAlignFrame(af);
+
+ setFrameDependentProperties(aparser, af);
+
+ if (isJS)
{
- af.getViewport().setSortByTree(false);
- if (!af.getViewport().getSortByTree())
- {
- System.out
- .println("CMD [-nosortbytree] executed successfully!");
- }
+ jsApp.initFromParams(af);
}
- data = aparser.getValue("tree", true);
- if (data != null)
+ else
+ /**
+ * Java only
+ *
+ * @j2sIgnore
+ */
{
- try
+ if (groovyscript != null)
{
- System.out.println(
- "CMD [-tree " + data + "] executed successfully!");
- NewickFile nf = new NewickFile(data,
- AppletFormatAdapter.checkProtocol(data));
- af.getViewport()
- .setCurrentTree(af.showNewickTree(nf, data).getTree());
- } catch (IOException ex)
- {
- System.err.println("Couldn't add tree " + data);
- ex.printStackTrace(System.err);
+ // Execute the groovy script after we've done all the rendering
+ // stuff
+ // and before any images or figures are generated.
+ System.out.println("Executing script " + groovyscript);
+ executeGroovyScript(groovyscript, af);
+ System.out.println("CMD groovy[" + groovyscript
+ + "] executed successfully!");
+ groovyscript = null;
}
}
- // TODO - load PDB structure(s) to alignment JAL-629
- // (associate with identical sequence in alignment, or a specified
- // sequence)
- if (groovyscript != null)
- {
- // Execute the groovy script after we've done all the rendering stuff
- // and before any images or figures are generated.
- System.out.println("Executing script " + groovyscript);
- executeGroovyScript(groovyscript, af);
- System.out.println("CMD groovy[" + groovyscript
- + "] executed successfully!");
- groovyscript = null;
+ if (!isJS || !isStartup) {
+ createOutputFiles(aparser, format);
}
- String imageName = "unnamed.png";
- while (aparser.getSize() > 1)
- {
- String outputFormat = aparser.nextValue();
- file = aparser.nextValue();
+ }
+ if (headless)
+ {
+ af.getViewport().getCalcManager().shutdown();
+ }
+ }
+ // extract groovy arguments before anything else.
+ // Once all other stuff is done, execute any groovy scripts (in order)
+ if (!isJS && groovyscript != null)
+ {
+ if (Cache.groovyJarsPresent())
+ {
+ // TODO: DECIDE IF THIS SECOND PASS AT GROOVY EXECUTION IS STILL REQUIRED !!
+ System.out.println("Executing script " + groovyscript);
+ executeGroovyScript(groovyscript, af);
+ System.out.println("CMD groovy[" + groovyscript
+ + "] executed successfully!");
- if (outputFormat.equalsIgnoreCase("png"))
- {
- af.createPNG(new File(file));
- imageName = (new File(file)).getName();
- System.out.println("Creating PNG image: " + file);
- continue;
- }
- else if (outputFormat.equalsIgnoreCase("svg"))
- {
- File imageFile = new File(file);
- imageName = imageFile.getName();
- af.createSVG(imageFile);
- System.out.println("Creating SVG image: " + file);
- continue;
- }
- else if (outputFormat.equalsIgnoreCase("html"))
- {
- File imageFile = new File(file);
- imageName = imageFile.getName();
- HtmlSvgOutput htmlSVG = new HtmlSvgOutput(af.alignPanel);
- htmlSVG.exportHTML(file);
+ }
+ else
+ {
+ System.err.println(
+ "Sorry. Groovy Support is not available, so ignoring the provided groovy script "
+ + groovyscript);
+ }
+ }
- System.out.println("Creating HTML image: " + file);
- continue;
- }
- else if (outputFormat.equalsIgnoreCase("biojsmsa"))
- {
- if (file == null)
- {
- System.err.println("The output html file must not be null");
- return;
- }
- try
- {
- BioJsHTMLOutput.refreshVersionInfo(
- BioJsHTMLOutput.BJS_TEMPLATES_LOCAL_DIRECTORY);
- } catch (URISyntaxException e)
- {
- e.printStackTrace();
- }
- BioJsHTMLOutput bjs = new BioJsHTMLOutput(af.alignPanel);
- bjs.exportHTML(file);
- System.out
- .println("Creating BioJS MSA Viwer HTML file: " + file);
- continue;
- }
- else if (outputFormat.equalsIgnoreCase("imgMap"))
- {
- af.createImageMap(new File(file), imageName);
- System.out.println("Creating image map: " + file);
- continue;
- }
- else if (outputFormat.equalsIgnoreCase("eps"))
- {
- File outputFile = new File(file);
- System.out.println(
- "Creating EPS file: " + outputFile.getAbsolutePath());
- af.createEPS(outputFile);
- continue;
- }
- FileFormatI outFormat = null;
- try
- {
- outFormat = FileFormats.getInstance().forName(outputFormat);
- } catch (Exception formatP)
- {
- System.out.println("Couldn't parse " + outFormat
- + " as a valid Jalview format string.");
- }
- if (outFormat != null)
- {
- if (!outFormat.isWritable())
- {
- System.out.println(
- "This version of Jalview does not support alignment export as "
- + outputFormat);
- }
- else
- {
- af.saveAlignment(file, outFormat);
- if (af.isSaveAlignmentSuccessful())
- {
- System.out.println("Written alignment in "
- + outFormat.getName() + " format to " + file);
- }
- else
- {
- System.out.println("Error writing file " + file + " in "
- + outFormat.getName() + " format!!");
- }
- }
- }
+ // and finally, turn off batch mode indicator - if the desktop still exists
+ if (desktop != null)
+ {
+ if (progress != -1)
+ {
+ desktop.setProgressBar(null, progress);
+ }
+ desktop.setInBatchMode(false);
+ }
+
+ if (jsApp != null) {
+ jsApp.callInitCallback();
+ }
+ }
+
+ /**
+ * Set general display parameters irrespective of file loading or headlessness.
+ *
+ * @param aparser
+ */
+ private void setDisplayParameters(ArgsParser aparser)
+ {
+ if (aparser.contains(ArgsParser.NOMENUBAR))
+ {
+ noMenuBar = true;
+ System.out.println("CMD [nomenu] executed successfully!");
+ }
- }
+ if (aparser.contains(ArgsParser.NOSTATUS))
+ {
+ noStatus = true;
+ System.out.println("CMD [nostatus] executed successfully!");
+ }
- while (aparser.getSize() > 0)
- {
- System.out.println("Unknown arg: " + aparser.nextValue());
- }
- }
+ if (aparser.contains(ArgsParser.NOANNOTATION)
+ || aparser.contains(ArgsParser.NOANNOTATION2))
+ {
+ noAnnotation = true;
+ System.out.println("CMD no-annotation executed successfully!");
+ }
+ if (aparser.contains(ArgsParser.NOCALCULATION))
+ {
+ noCalculation = true;
+ System.out.println("CMD [nocalculation] executed successfully!");
}
- AlignFrame startUpAlframe = null;
- // We'll only open the default file if the desktop is visible.
- // And the user
- // ////////////////////
+ }
- if (!Platform.isJS() && !headless && file == null
- && Cache.getDefault("SHOW_STARTUP_FILE", true))
- /**
- * Java only
- *
- * @j2sIgnore
- */
+
+ private void setFrameDependentProperties(ArgsParser aparser,
+ AlignFrame af)
+ {
+ String data = aparser.getValue(ArgsParser.COLOUR, true);
+ if (data != null)
{
- file = jalview.bin.Cache.getDefault("STARTUP_FILE",
- jalview.bin.Cache.getDefault("www.jalview.org",
- "https://www.jalview.org")
- + "/examples/exampleFile_2_7.jvp");
- if (file.equals(
- "http://www.jalview.org/examples/exampleFile_2_3.jar") || file.equals(
- "http://www.jalview.org/examples/exampleFile_2_7.jar"))
+ data.replaceAll("%20", " ");
+
+ ColourSchemeI cs = ColourSchemeProperty.getColourScheme(
+ af.getViewport(), af.getViewport().getAlignment(), data);
+
+ if (cs != null)
{
- file.replace("http:", "https:");
- // hardwire upgrade of the startup file
- file.replace("_2_3", "_2_7");
- file.replace("2_7.jar", "2_7.jvp");
- // and remove the stale setting
- Cache.removeProperty("STARTUP_FILE");
+ System.out.println(
+ "CMD [-color " + data + "] executed successfully!");
}
+ af.changeColour(cs);
+ }
- protocol = AppletFormatAdapter.checkProtocol(file);
+ // Must maintain ability to use the groups flag
+ data = aparser.getValue(ArgsParser.GROUPS, true);
+ if (data != null)
+ {
+ af.parseFeaturesFile(data,
+ AppletFormatAdapter.checkProtocol(data));
+ // System.out.println("Added " + data);
+ System.out.println(
+ "CMD groups[-" + data + "] executed successfully!");
+ }
+ data = aparser.getValue(ArgsParser.FEATURES, true);
+ if (data != null)
+ {
+ af.parseFeaturesFile(data,
+ AppletFormatAdapter.checkProtocol(data));
+ // System.out.println("Added " + data);
+ System.out.println(
+ "CMD [-features " + data + "] executed successfully!");
+ }
+ data = aparser.getValue(ArgsParser.ANNOTATIONS, true);
+ if (data != null)
+ {
+ af.loadJalviewDataFile(data, null, null, null);
+ // System.out.println("Added " + data);
+ System.out.println(
+ "CMD [-annotations " + data + "] executed successfully!");
+ }
- if (file.endsWith(".jar"))
+ // JavaScript feature
+
+ if (aparser.contains(ArgsParser.SHOWOVERVIEW))
+ {
+ af.overviewMenuItem_actionPerformed(null);
+ System.out.println("CMD [showoverview] executed successfully!");
+ }
+
+ // set or clear the sortbytree flag.
+ if (aparser.contains(ArgsParser.SORTBYTREE))
+ {
+ af.getViewport().setSortByTree(true);
+ if (af.getViewport().getSortByTree())
{
- format = FileFormat.Jalview;
+ System.out.println("CMD [-sortbytree] executed successfully!");
}
- else
+ }
+
+ boolean doUpdateAnnotation = false;
+ /**
+ * we do this earlier in JalviewJS because of a complication with
+ * SHOWOVERVIEW
+ *
+ * For now, just fixing this in JalviewJS.
+ *
+ *
+ * @j2sIgnore
+ *
+ */
+ {
+ if (noAnnotation)
{
- try
- {
- format = new IdentifyFile().identify(file, protocol);
- } catch (FileFormatException e)
+ af.getViewport().setShowAnnotation(false);
+ if (!af.getViewport().isShowAnnotation())
{
- // TODO what?
+ doUpdateAnnotation = true;
}
}
-
- startUpAlframe = fileLoader.LoadFileWaitTillLoaded(file, protocol,
- format);
- // extract groovy arguments before anything else.
}
- // Once all other stuff is done, execute any groovy scripts (in order)
- if (groovyscript != null)
+ if (aparser.contains(ArgsParser.NOSORTBYTREE))
{
- if (Cache.groovyJarsPresent())
+ af.getViewport().setSortByTree(false);
+ if (!af.getViewport().getSortByTree())
{
- System.out.println("Executing script " + groovyscript);
- executeGroovyScript(groovyscript, startUpAlframe);
+ doUpdateAnnotation = true;
+ System.out
+ .println("CMD [-nosortbytree] executed successfully!");
}
- else
+ }
+ if (doUpdateAnnotation)
+ { // BH 2019.07.24
+ af.setMenusForViewport();
+ af.alignPanel.updateLayout();
+ }
+
+ data = aparser.getValue(ArgsParser.TREE, true);
+ if (data != null)
+ {
+ try
{
- System.err.println(
- "Sorry. Groovy Support is not available, so ignoring the provided groovy script "
- + groovyscript);
+ NewickFile nf = new NewickFile(data,
+ AppletFormatAdapter.checkProtocol(data));
+ af.getViewport()
+ .setCurrentTree(af.showNewickTree(nf, data).getTree());
+ System.out.println(
+ "CMD [-tree " + data + "] executed successfully!");
+ } catch (IOException ex)
+ {
+ System.err.println("Couldn't add tree " + data);
+ ex.printStackTrace(System.err);
}
}
- // and finally, turn off batch mode indicator - if the desktop still exists
- if (desktop != null)
+ // TODO - load PDB structure(s) to alignment JAL-629
+ // (associate with identical sequence in alignment, or a specified
+ // sequence)
+
+ }
+
+ /**
+ * Writes an output file for each format (if any) specified in the
+ * command-line arguments. Supported formats are currently
+ * <ul>
+ * <li>png</li>
+ * <li>svg</li>
+ * <li>html</li>
+ * <li>biojsmsa</li>
+ * <li>imgMap</li>
+ * <li>eps</li>
+ * </ul>
+ * A format parameter should be followed by a parameter specifying the output
+ * file name. {@code imgMap} parameters should follow those for the
+ * corresponding alignment image output.
+ *
+ * @param aparser
+ * @param format
+ */
+ private void createOutputFiles(ArgsParser aparser, FileFormatI format)
+ {
+ // logic essentially the same as 2.11.2/2.11.3 but uses a switch instead
+ AlignFrame af = currentAlignFrame;
+ while (aparser.getSize() >= 2)
{
- if (progress != -1)
+ String outputFormat = aparser.nextValue();
+ File imageFile;
+ String fname;
+ switch (outputFormat.toLowerCase(Locale.ROOT))
{
- desktop.setProgressBar(null, progress);
+ case "png":
+ imageFile = new File(aparser.nextValue());
+ af.createPNG(imageFile);
+ System.out.println(
+ "Creating PNG image: " + imageFile.getAbsolutePath());
+ continue;
+ case "svg":
+ imageFile = new File(aparser.nextValue());
+ af.createSVG(imageFile);
+ System.out.println(
+ "Creating SVG image: " + imageFile.getAbsolutePath());
+ continue;
+ case "eps":
+ imageFile = new File(aparser.nextValue());
+ System.out.println(
+ "Creating EPS file: " + imageFile.getAbsolutePath());
+ af.createEPS(imageFile);
+ continue;
+ case "biojsmsa":
+ fname = new File(aparser.nextValue()).getAbsolutePath();
+ try
+ {
+ BioJsHTMLOutput.refreshVersionInfo(
+ BioJsHTMLOutput.BJS_TEMPLATES_LOCAL_DIRECTORY);
+ } catch (URISyntaxException e)
+ {
+ e.printStackTrace();
+ }
+ BioJsHTMLOutput bjs = new BioJsHTMLOutput(af.alignPanel);
+ bjs.exportHTML(fname);
+ System.out.println("Creating BioJS MSA Viwer HTML file: " + fname);
+ continue;
+ case "html":
+ fname = new File(aparser.nextValue()).getAbsolutePath();
+ HtmlSvgOutput htmlSVG = new HtmlSvgOutput(af.alignPanel);
+ htmlSVG.exportHTML(fname);
+ System.out.println("Creating HTML image: " + fname);
+ continue;
+ case "imgmap":
+ imageFile = new File(aparser.nextValue());
+ af.alignPanel.makePNGImageMap(imageFile, "unnamed.png");
+ System.out.println(
+ "Creating image map: " + imageFile.getAbsolutePath());
+ continue;
+ default:
+ // fall through - try to parse as an alignment data export format
+ FileFormatI outFormat = null;
+ try
+ {
+ outFormat = FileFormats.getInstance().forName(outputFormat);
+ } catch (Exception formatP)
+ {
+ }
+ if (outFormat == null)
+ {
+ System.out.println("Couldn't parse " + outputFormat
+ + " as a valid Jalview format string.");
+ continue;
+ }
+ if (!outFormat.isWritable())
+ {
+ System.out.println(
+ "This version of Jalview does not support alignment export as "
+ + outputFormat);
+ continue;
+ }
+ // record file as it was passed to Jalview so it is recognisable to the CLI
+ // caller
+ String file;
+ fname = new File(file = aparser.nextValue()).getAbsolutePath();
+ // JBPNote - yuck - really wish we did have a bean returned from this which gave
+ // success/fail like before !
+ af.saveAlignment(fname, outFormat);
+ if (!af.isSaveAlignmentSuccessful())
+ {
+ System.out.println("Written alignment in " + outputFormat
+ + " format to " + file);
+ continue;
+ }
+ else
+ {
+ System.out.println("Error writing file " + file + " in "
+ + outputFormat + " format!!");
+ }
}
- desktop.setInBatchMode(false);
+ }
+ // ??? Should report - 'ignoring' extra args here...
+ while (aparser.getSize() > 0)
+ {
+ System.out.println("Ignoring extra argument: " + aparser.nextValue());
}
}
}
return set;
}
-
private static void showUsage()
{
System.out.println(
/**
* start a User Config prompt asking if we can log usage statistics.
*/
- PromptUserConfig prompter = new PromptUserConfig(Desktop.desktop,
+ PromptUserConfig prompter = new PromptUserConfig(Desktop.getDesktopPane(),
"USAGESTATS", "Jalview Usage Statistics",
"Do you want to help make Jalview better by enabling "
+ "the collection of usage statistics with Google Analytics ?"
}
/**
- * Quit method delegates to Desktop.quit - unless running in headless mode
- * when it just ends the JVM
+ * Quit method delegates to Desktop.quit - unless running in headless mode when
+ * it just ends the JVM
*/
public void quit()
{
public static AlignFrame getCurrentAlignFrame()
{
- return Jalview.currentAlignFrame;
+ return Jalview.getInstance().currentAlignFrame;
}
public static void setCurrentAlignFrame(AlignFrame currentAlignFrame)
{
- Jalview.currentAlignFrame = currentAlignFrame;
+ Jalview.getInstance().currentAlignFrame = currentAlignFrame;
+ }
+
+ public void notifyWorker(AlignCalcWorkerI worker, String status)
+ {
+ // System.out.println("Jalview worker " + worker.getClass().getSimpleName()
+ // + " " + status);
+ }
+
+
+ private static boolean isInteractive = true;
+
+ public static boolean isInteractive()
+ {
+ return isInteractive;
+ }
+
+ public static void setInteractive(boolean tf)
+ {
+ isInteractive = tf;
}
}
static {
/**
- * @j2sNative
+ * @ could do it this way:
*
- * J2S.thisApplet.__Info.args =
- * ["open","examples/uniref50.fa","features",
- * "examples/exampleFeatures.txt"];
+ * j2sNative
+ *
+ * J2S.thisApplet.__Info.args = [ "open","examples/uniref50.fa",
+ * "features","examples/exampleFeatures.txt", "noannotation" ];
*/
}
public static void main(String[] args) throws Exception
{
+ if (args.length == 0)
+ {
+ args = new String[] {
+ // "headless",
+ "open", "examples/uniref50.fa",
+// "features",
+// "examples/exampleFeatures.txt"
+// , "noannotation"
+ //, "showoverview"
+ //, "png", "test-bh.png"
+ };
+ }
+
+ // String cmds = "nodisplay -open examples/uniref50.fa -sortbytree -props
+ // test/jalview/io/testProps.jvprops -colour zappo "
+ // + "-jabaws http://www.compbio.dundee.ac.uk/jabaws -nosortbytree "
+ // + "-features examples/testdata/plantfdx.features -annotations
+ // examples/testdata/plantfdx.annotations -tree
+ // examples/testdata/uniref50_test_tree";
+ // args = cmds.split(" ");
Jalview.main(args);
//showFocusTimer();
}
--- /dev/null
+package jalview.bin;
+
+import java.awt.EventQueue;
+//import java.applet.AppletContext;
+import java.io.IOException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.StringTokenizer;
+import java.util.Vector;
+
+import javax.swing.SwingUtilities;
+
+import jalview.api.JalviewJSApi;
+import jalview.api.StructureSelectionManagerProvider;
+import jalview.datamodel.Alignment;
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.AlignmentOrder;
+import jalview.datamodel.ColumnSelection;
+import jalview.datamodel.HiddenColumns;
+import jalview.datamodel.PDBEntry;
+import jalview.datamodel.Sequence;
+import jalview.datamodel.SequenceGroup;
+import jalview.datamodel.SequenceI;
+import jalview.gui.AlignFrame;
+import jalview.gui.AlignViewport;
+import jalview.gui.CalculationChooser;
+import jalview.gui.Desktop;
+import jalview.gui.StructureViewer;
+import jalview.io.AnnotationFile;
+import jalview.io.AppletFormatAdapter;
+import jalview.io.DataSourceType;
+import jalview.io.FeaturesFile;
+import jalview.io.FileFormat;
+import jalview.io.FileFormatI;
+import jalview.io.FileFormats;
+import jalview.io.IdentifyFile;
+import jalview.io.JPredFile;
+import jalview.io.JnetAnnotationMaker;
+import jalview.io.NewickFile;
+import jalview.structure.SelectionListener;
+import jalview.structure.SelectionSource;
+import jalview.structure.StructureSelectionManager;
+import jalview.util.HttpUtils;
+import jalview.util.Platform;
+
+/**
+ * Basically the JalviewLite application, but without JalviewLite
+ *
+ * Processing all "applet parameters" and also all "applet interface" methods.
+ *
+ * @author hansonr
+ *
+ */
+public class JalviewJSApp implements JalviewJSApi
+{
+ private ArgsParser aparser;
+
+ private String[] ret = new String[1];
+
+ // private boolean alignPDBStructures; From JalviewLite; not implemented
+
+ private String separator = "\u00AC"; // JalviewLite note: the default used to
+ // be '|', but many sequence IDS include
+ // pipes.
+
+ /**
+ * We maintain a pointer to the jalview instance here, because only with that
+ * do we have a direct connection from the JavaScript "applet" object to the
+ * proper instance of Jalview in case there are multiple applets on a page.
+ */
+ private Jalview jalview;
+
+ public class JsSelectionListener
+ implements jalview.structure.SelectionListener
+ {
+
+ AlignFrame _alf;
+
+ String _listener;
+
+ public JsSelectionListener(AlignFrame alf, String listener)
+ {
+ _alf = alf;
+ _listener = listener;
+ }
+
+ public boolean isFor(AlignFrame alf, String listener)
+ {
+ return (_alf == null || _alf == alf) && _listener.equals(listener);
+ }
+
+ @Override
+ public void selection(SequenceGroup seqsel, ColumnSelection colsel,
+ HiddenColumns hidden, SelectionSource source)
+ {
+ // System.err.println("Testing selection event relay to
+ // jsfunction:"+_listener);
+ String setid = "";
+ AlignFrame srcFrame = (_alf == null ? getCurrentAlignFrame() : _alf);
+ if (source != null)
+ {
+ if (source instanceof AlignViewport
+ && srcFrame.getViewport() != source)
+ {
+ return;
+ }
+ }
+ String[] seqs = new String[] {};
+ String[] cols = new String[] {};
+ int strt = 0, end = (srcFrame == null) ? -1
+ : srcFrame.alignPanel.av.getAlignment().getWidth();
+ if (seqsel != null && seqsel.getSize() > 0)
+ {
+ seqs = new String[seqsel.getSize()];
+ for (int i = 0; i < seqs.length; i++)
+ {
+ seqs[i] = seqsel.getSequenceAt(i).getName();
+ }
+ if (strt < seqsel.getStartRes())
+ {
+ strt = seqsel.getStartRes();
+ }
+ if (end == -1 || end > seqsel.getEndRes())
+ {
+ end = seqsel.getEndRes();
+ }
+ }
+ if (colsel != null && !colsel.isEmpty())
+ {
+ if (end == -1)
+ {
+ end = colsel.getMax() + 1;
+ }
+ cols = new String[colsel.getSelected().size()];
+ for (int i = 0; i < cols.length; i++)
+ {
+ cols[i] = "" + (1 + colsel.getSelected().get(i).intValue());
+ }
+ }
+ else
+ {
+ if (seqsel != null && seqsel.getSize() > 0)
+ {
+ // send a valid range, otherwise we send the empty selection
+ cols = new String[1];
+ cols[0] = "" + (1 + strt) + "-" + (1 + end);
+ }
+ }
+ doSendCallback(_listener,
+ new Object[]
+ { Jalview.getInstance().j2sAppletID, srcFrame, source, setid,
+ seqs, cols });
+ }
+
+ }
+
+ public JalviewJSApp(Jalview jalview, ArgsParser aparser)
+ {
+ Platform.setAppClass(this);
+ this.jalview = jalview;
+ this.aparser = aparser;
+ }
+
+ @Override
+ public boolean addPdbFile(String sequenceId, String pdbId, String pdbFile,
+ AlignFrame alf)
+ {
+ if (alf == null)
+ {
+ alf = getCurrentAlignFrame();
+ }
+ SequenceI seq = alf.getViewport().getAlignment().findName(sequenceId);
+ if (seq != null)
+ {
+ Vector<PDBEntry> pdbe = seq.getAllPDBEntries();
+ PDBEntry pdbentry = null;
+ if (pdbe != null && pdbe.size() > 0)
+ {
+ for (int pe = 0, peSize = pdbe.size(); pe < peSize; pe++)
+ {
+ pdbentry = pdbe.elementAt(pe);
+ if (!pdbentry.getId().equals(pdbId)
+ || pdbFile != null && !pdbentry.getFile().equals(pdbFile))
+ {
+ pdbentry = null;
+ }
+ }
+ }
+ if (pdbentry == null)
+ {
+ pdbentry = new PDBEntry(pdbId, null, pdbFile);
+ if (pdbFile != null)
+ {
+ DataSourceType protocol = AppletFormatAdapter
+ .resolveProtocol(pdbFile, FileFormat.PDB);
+ if (protocol == null)
+ return false;
+ pdbentry.setProperty("protocol", protocol);
+ }
+ seq.addPDBId(pdbentry);
+ alf.alignPanel.getStructureSelectionManager()
+ .registerPDBEntry(pdbentry);
+ }
+ }
+ return true;
+ }
+
+ @Override
+ public String getAlignment(String format, boolean addSuffix,
+ AlignFrame alf)
+ {
+ try
+ {
+ if (alf == null)
+ {
+ alf = getCurrentAlignFrame();
+ }
+
+ FileFormatI theFormat = FileFormats.getInstance().forName(format);
+ String reply = new AppletFormatAdapter().formatSequences(theFormat,
+ alf.getViewport().getAlignment(), addSuffix);
+ return reply;
+ } catch (IllegalArgumentException ex)
+ {
+ ex.printStackTrace();
+ return "Error retrieving alignment, possibly invalid format specifier: "
+ + format;
+ }
+ }
+
+ @Override
+ public String[] getAlignmentOrder(AlignFrame alf)
+ {
+ if (alf == null)
+ {
+ alf = getCurrentAlignFrame();
+ }
+ AlignmentI alorder = alf.getViewport().getAlignment();
+ String[] order = new String[alorder.getHeight()];
+ for (int i = 0; i < order.length; i++)
+ {
+ order[i] = alorder.getSequenceAt(i).getName();
+ }
+ return order;// arrayToSeparatorList(order, sep);
+ }
+
+ @Override
+ public String getAnnotation(AlignFrame alf)
+ {
+ if (alf == null)
+ {
+ alf = getCurrentAlignFrame();
+ }
+ String annotation = new AnnotationFile()
+ .printAnnotationsForView(alf.getViewport());
+ return annotation;
+ }
+
+ /**
+ * Get the applet-like code base even though this is an application.
+ */
+
+ @Override
+ public URL getCodeBase()
+ {
+ return Platform.getCodeBase();
+ }
+
+ @Override
+ public AlignFrame getCurrentAlignFrame()
+ {
+ // if (jalview != Jalview.getInstance() || jalview.currentAlignFrame !=
+ // Jalview.getCurrentAlignFrame()) {
+ // /** @j2sNative debugger */
+ // }
+ return jalview.currentAlignFrame;
+ }
+
+ /**
+ * Get the applet-like document base even though this is an application.
+ */
+
+ @Override
+ public URL getDocumentBase()
+ {
+ return Platform.getDocumentBase();
+ }
+
+ @Override
+ public String[] getFeatureGroups(AlignFrame alf)
+ {
+ if (alf == null)
+ {
+ alf = getCurrentAlignFrame();
+ }
+ return alf.getFeatureGroups();
+ }
+
+ @Override
+ public String[] getFeatureGroupsOfState(boolean visible, AlignFrame alf)
+ {
+ if (alf == null)
+ {
+ alf = getCurrentAlignFrame();
+ }
+ return alf.getFeatureGroupsOfState(visible);
+ }
+
+ /**
+ * JavaScript interface to print the alignment frame
+ *
+ * @param format
+ * "jalview" or "gff" with or without ";includeComplement" or
+ * ";includeNonpositional"; default with no ";" is
+ * ";includeNonpositional"
+ * @param alf
+ *
+ * @return
+ */
+ @Override
+ public String getFeatures(String format, AlignFrame alf)
+ {
+ if (alf == null)
+ {
+ alf = getCurrentAlignFrame();
+ }
+ String features;
+ FeaturesFile formatter = new FeaturesFile();
+ format = format.toLowerCase();
+ if (format.indexOf(";") < 0)
+ format += ";includenonpositional";
+ boolean nonpos = format.indexOf(";includenonpositional") >= 0;
+ boolean compl = format.indexOf(";includecomplement") >= 0;
+ if (format.startsWith("jalview"))
+ {
+ features = formatter.printJalviewFormat(
+ alf.getViewport().getAlignment().getSequencesArray(),
+ alf.alignPanel.getFeatureRenderer(), nonpos, compl);
+ }
+ else
+ {
+ features = formatter.printGffFormat(
+ alf.getViewport().getAlignment().getSequencesArray(),
+ alf.alignPanel.getFeatureRenderer(), nonpos, compl);
+ }
+
+ if (features == null)
+ {
+ features = "";
+ }
+ return features;
+
+ }
+
+ /**
+ * Get an applet parameter as a string.
+ *
+ */
+ @Override
+ public String getParameter(String name)
+ {
+ return (String) aparser.getAppletValue(name, null, true);
+ }
+
+ /**
+ * Get an applet parameter as an Object.
+ */
+
+ @Override
+ public Object getParameterAsObject(String name)
+ {
+ return aparser.getAppletValue(name, null, false);
+ }
+
+ /**
+ * read sequence1...sequenceN as a raw alignment
+ *
+ * @param jalviewApp
+ * @return
+ */
+ public String getPastedSequence(JalviewJSApp jalviewApp)
+ {
+ StringBuffer data = new StringBuffer("PASTE");
+ int i = 1;
+ String file = null;
+ while ((file = getParameter("sequence" + i)) != null)
+ {
+ data.append(file.toString() + "\n");
+ i++;
+ }
+ if (data.length() > 5)
+ {
+ file = data.toString();
+ }
+ return file;
+ }
+
+ /**
+ * @j2sAlias getSelectedSequences
+ *
+ * @see jalview.appletgui.js.JalviewLiteJsApi#getSelectedSequencesFrom(jalview.appletgui
+ * .AlignFrame)
+ */
+ @Override
+ public SequenceI[] getSelectedSequences(AlignFrame alf)
+ {
+ // return getSelectedSequencesFrom(alf, null);
+ // }
+ //
+ // @Override
+ // public SequenceI[] getSelectedSequencesFrom(AlignFrame alf, String sep)
+ // {
+ if (alf == null)
+ {
+ alf = getCurrentAlignFrame();
+ }
+ AlignViewport v = alf.getViewport();
+ if (v.getSelectionGroup() != null)
+ {
+ return v.getSelectionGroup().getSequencesInOrder(v.getAlignment());
+ }
+ return null;
+ }
+ // /**
+ // *
+ // * @see
+ // jalview.appletgui.js.JalviewLiteJsApi#getSelectedSequencesFrom(jalview.appletgui
+ // * .AlignFrame, java.lang.String)
+ // */
+ // @Override
+ // public void highlight(String sequenceId, String position,
+ // String alignedPosition)
+ // {
+ // highlightIn(null, sequenceId, position, alignedPosition);
+ // }
+
+ /**
+ * @j2sAlias getSelectedSequencesAsAlignment
+ */
+ @Override
+ public String getSelectedSequencesAsAlignment(String format,
+ boolean addSuffix, AlignFrame alf)
+ {
+
+ if (alf == null)
+ {
+ alf = getCurrentAlignFrame();
+ }
+ try
+ {
+ AlignViewport vp = alf.getViewport();
+ FileFormatI theFormat = FileFormats.getInstance().forName(format);
+ if (vp.getSelectionGroup() != null)
+ {
+ // JBPNote: getSelectionAsNewSequence behaviour has changed - this
+ // method now returns a full copy of sequence data
+ // TODO consider using getSequenceSelection instead here
+ String reply = new AppletFormatAdapter().formatSequences(theFormat,
+ new Alignment(vp.getSelectionAsNewSequence()), addSuffix);
+ return reply;
+ }
+ } catch (IllegalArgumentException ex)
+ {
+ ex.printStackTrace();
+ return "Error retrieving alignment, possibly invalid format specifier: "
+ + format;
+ }
+ return "";
+ }
+
+ @Override
+ public void highlight(String sequenceId, String position,
+ String alignedPosition, AlignFrame alf)
+ {
+ if (alf == null)
+ {
+ alf = getCurrentAlignFrame();
+ }
+ // TODO: could try to highlight in all alignments if alf==null
+ jalview.analysis.SequenceIdMatcher matcher = new jalview.analysis.SequenceIdMatcher(
+ alf.getViewport().getAlignment().getSequencesArray());
+ final SequenceI sq = matcher.findIdMatch(sequenceId);
+ if (sq != null)
+ {
+ int apos = -1;
+ try
+ {
+ apos = Integer.valueOf(position).intValue();
+ apos--;
+ } catch (NumberFormatException ex)
+ {
+ return;
+ }
+ final int pos = apos;
+ // use vamsas listener to broadcast to all listeners in scope
+ if (alignedPosition != null && (alignedPosition.trim().length() == 0
+ || alignedPosition.toLowerCase().indexOf("false") > -1))
+ {
+ java.awt.EventQueue.invokeLater(new Runnable()
+ {
+ @Override
+ public void run()
+ {
+ StructureSelectionManager
+ .getStructureSelectionManager(Desktop.getInstance())
+ .mouseOverVamsasSequence(sq, sq.findIndex(pos), null);
+ }
+ });
+ }
+ else
+ {
+ java.awt.EventQueue.invokeLater(new Runnable()
+ {
+ @Override
+ public void run()
+ {
+ StructureSelectionManager
+ .getStructureSelectionManager(Desktop.getInstance())
+ .mouseOverVamsasSequence(sq, pos, null);
+ }
+ });
+ }
+ }
+ }
+
+ @Override
+ public AlignFrame loadAlignment(String text, String title, int width,
+ int height)
+ {
+ AlignmentI al = null;
+
+ try
+ {
+ FileFormatI format = new IdentifyFile().identify(text,
+ DataSourceType.PASTE);
+ al = new AppletFormatAdapter().readFile(text, DataSourceType.PASTE,
+ format);
+ if (al.getHeight() > 0)
+ {
+ return new AlignFrame(al,
+ width > 0 ? width : AlignFrame.DEFAULT_WIDTH,
+ height > 0 ? height : AlignFrame.DEFAULT_HEIGHT, title);
+ }
+ } catch (IOException ex)
+ {
+ ex.printStackTrace();
+ }
+ return null;
+ }
+
+ @Override
+ public void loadAnnotation(String annotation, AlignFrame alf)
+ {
+ if (alf == null)
+ {
+ alf = getCurrentAlignFrame();
+ }
+ if (new AnnotationFile().annotateAlignmentView(alf.getViewport(),
+ annotation, DataSourceType.PASTE))
+ {
+ alf.alignPanel.fontChanged();
+ alf.alignPanel.setScrollValues(0, 0);
+ }
+ else
+ {
+ alf.parseFeaturesFile(annotation, DataSourceType.PASTE);
+ }
+ }
+
+ @Override
+ public boolean loadFeatures(String features, boolean autoenabledisplay,
+ AlignFrame alf)
+ {
+ if (alf == null)
+ {
+ alf = getCurrentAlignFrame();
+ }
+ boolean ret = alf.parseFeaturesFile(features, DataSourceType.PASTE);
+ if (!ret)
+ {
+ return false;
+ }
+ if (autoenabledisplay)
+ {
+ alf.getViewport().setShowSequenceFeatures(true);
+ // this next was for a checkbox in JalviewLite
+ // ((AlignFrame) alf).getViewport().sequenceFeatures.setState(true);
+ }
+ return true;
+ }
+
+ @Override
+ public boolean loadScoreFile(String fileName, AlignFrame alf)
+ {
+ try
+ {
+ (alf == null ? getCurrentAlignFrame() : alf)
+ .loadJalviewDataFile(fileName, null, null, null);
+ return true;
+ } catch (Throwable t)
+ {
+ return false;
+ }
+ }
+
+ /**
+ * @j2sAlias openPcaPanel
+ *
+ * public static method for JalviewJS API to open a PCAPanel without
+ * necessarily using a dialog.
+ * @param modelName
+ * @param alf
+ *
+ * @return the PCAPanel, or the string "label.you_need_at_least_n_sequences"
+ * if number of sequences selected is inappropriate
+ */
+ @Override
+ public Object openPcaPanel(String modelName, AlignFrame alf)
+ {
+ if (alf == null)
+ {
+ alf = getCurrentAlignFrame();
+ }
+ return CalculationChooser.openPcaPanel(alf, modelName, null);
+ }
+
+ /**
+ * @j2sAlias openTreePanel
+ *
+ * Open a new Tree panel on the desktop statically. Params are
+ * standard (not set by Groovy). No dialog is opened.
+ * @param treeType
+ * @param modelName
+ * @param alf
+ *
+ * @return null, or the string "label.you_need_at_least_n_sequences" if number
+ * of sequences selected is inappropriate
+ */
+ @Override
+ public Object openTreePanel(String treeType, String modelName,
+ AlignFrame alf)
+ {
+ if (alf == null)
+ {
+ alf = getCurrentAlignFrame();
+ }
+ return CalculationChooser.openTreePanel(alf, treeType, modelName, null);
+ }
+
+ @Override
+ public boolean orderAlignment(String[] ids, String undoName,
+ AlignFrame alf)
+ {
+ if (alf == null)
+ alf = getCurrentAlignFrame();
+ SequenceI[] sqs = null;
+ if (ids != null && ids.length > 0)
+ {
+ jalview.analysis.SequenceIdMatcher matcher = new jalview.analysis.SequenceIdMatcher(
+ alf.getViewport().getAlignment().getSequencesArray());
+ int s = 0;
+ sqs = new SequenceI[ids.length];
+ for (int i = 0; i < ids.length; i++)
+ {
+ if (ids[i].trim().length() == 0)
+ {
+ continue;
+ }
+ SequenceI sq = matcher.findIdMatch(ids[i]);
+ if (sq != null)
+ {
+ sqs[s++] = sq;
+ }
+ }
+ if (s > 0)
+ {
+ SequenceI[] sqq = new SequenceI[s];
+ System.arraycopy(sqs, 0, sqq, 0, s);
+ sqs = sqq;
+ }
+ else
+ {
+ sqs = null;
+ }
+ }
+ if (sqs == null)
+ {
+ return false;
+ }
+ ;
+ final AlignmentOrder aorder = new AlignmentOrder(sqs);
+
+ if (undoName != null && undoName.trim().length() == 0)
+ {
+ undoName = null;
+ }
+ final String _undoName = undoName;
+ // TODO: deal with synchronization here: cannot raise any events until
+ // alfter
+ // this has returned.
+ return alf.sortBy(aorder, _undoName);
+ }
+
+ /**
+ * Allow an outside entity to initiate the second half of argument parsing
+ * (only).
+ *
+ * @param args
+ * @return null is good
+ */
+ @Override
+ public Object parseArguments(String[] args)
+ {
+
+ try
+ {
+ jalview.parseArguments(new ArgsParser(args), false);
+ return null;
+ } catch (Throwable t)
+ {
+ return t;
+ }
+ }
+
+ /**
+ * @j2sAlias parseFeatureFile
+ *
+ * @param filename
+ * @param alf
+ * @return
+ */
+ @Override
+ public boolean parseFeaturesFile(String filename, AlignFrame alf)
+ {
+ ret[0] = filename;
+ DataSourceType protocol = resolveFileProtocol(ret);
+ if (protocol == null)
+ return false;
+ return (alf == null ? getCurrentAlignFrame() : alf)
+ .parseFeaturesFile(ret[0], protocol);
+ }
+
+ @Override
+ public void removeSelectionListener(String listener, AlignFrame alf)
+ {
+
+ List<SelectionListener> listeners = Desktop
+ .getStructureSelectionManager().getListeners();
+ for (int i = listeners.size(); --i >= 0;)
+ {
+ SelectionListener l = listeners.get(i);
+ if (l instanceof JsSelectionListener
+ && ((JsSelectionListener) l).isFor(alf, listener))
+ {
+ listeners.remove(i);
+ break;
+ }
+ }
+ }
+
+ private DataSourceType resolveFileProtocol(String[] retPath)
+ {
+ String path = retPath[0];
+ /*
+ * is it paste data?
+ */
+ if (path.startsWith("PASTE"))
+ {
+ retPath[0] = path.substring(5);
+ return DataSourceType.PASTE;
+ }
+
+ /*
+ * is it a URL?
+ */
+ if (path.indexOf("://") >= 0)
+ {
+ return DataSourceType.URL;
+ }
+
+ /*
+ * try relative to document root
+ */
+ URL documentBase = getDocumentBase();
+ String withDocBase = resolveUrlForLocalOrAbsolute(path, documentBase);
+ if (HttpUtils.isValidUrl(withDocBase))
+ {
+ // if (debug)
+ // {
+ // System.err.println("Prepended document base '" + documentBase
+ // + "' to make: '" + withDocBase + "'");
+ // }
+ retPath[0] = withDocBase;
+ return DataSourceType.URL;
+ }
+
+ /*
+ * try relative to codebase (if different to document base)
+ */
+ URL codeBase = getCodeBase();
+ String withCodeBase = resolveUrlForLocalOrAbsolute(path, codeBase);
+ if (!withCodeBase.equals(withDocBase)
+ && HttpUtils.isValidUrl(withCodeBase))
+ {
+ // if (debug)
+ // {
+ // System.err.println("Prepended codebase '" + codeBase
+ // + "' to make: '" + withCodeBase + "'");
+ // }
+ retPath[0] = withCodeBase;
+ return DataSourceType.URL;
+ }
+
+ /*
+ * try locating by classloader; try this last so files in the directory
+ * are resolved using document base
+ */
+ if (inArchive(getClass(), path))
+ {
+ return DataSourceType.CLASSLOADER;
+ }
+ return null;
+ }
+
+ @Override
+ public void scrollViewTo(int topRow, int leftHandColumn, AlignFrame alf)
+ {
+ // TODO test
+ java.awt.EventQueue.invokeLater(new Runnable()
+ {
+ @Override
+ public void run()
+ {
+ try
+ {
+ (alf == null ? getCurrentAlignFrame() : alf).scrollTo(topRow,
+ leftHandColumn);
+ } catch (Exception ex)
+ {
+ System.err.println("Couldn't parse integer arguments (topRow='"
+ + topRow + "' and leftHandColumn='" + leftHandColumn
+ + "')");
+ ex.printStackTrace();
+ }
+ }
+ });
+ }
+
+ @Override
+ public void select(String ids[], String cols[], AlignFrame alf)
+ {
+ if (alf == null)
+ alf = getCurrentAlignFrame();
+ final SequenceGroup sel = new SequenceGroup();
+ final ColumnSelection csel = new ColumnSelection();
+ AlignmentI al = alf.getViewport().getAlignment();
+ jalview.analysis.SequenceIdMatcher matcher = new jalview.analysis.SequenceIdMatcher(
+ alf.getViewport().getAlignment().getSequencesArray());
+ int start = 0, end = al.getWidth(), alw = al.getWidth();
+ boolean seqsfound = true;
+ if (ids != null && ids.length > 0)
+ {
+ seqsfound = false;
+ for (int i = 0; i < ids.length; i++)
+ {
+ if (ids[i].trim().length() == 0)
+ {
+ continue;
+ }
+ SequenceI sq = matcher.findIdMatch(ids[i]);
+ if (sq != null)
+ {
+ seqsfound = true;
+ sel.addSequence(sq, false);
+ }
+ }
+ }
+ boolean inseqpos = false;
+ if (cols != null && cols.length > 0)
+ {
+ boolean seset = false;
+ for (int i = 0; i < cols.length; i++)
+ {
+ String cl = cols[i].trim();
+ if (cl.length() == 0)
+ {
+ continue;
+ }
+ int p;
+ if ((p = cl.indexOf("-")) > -1)
+ {
+ int from = -1, to = -1;
+ try
+ {
+ from = Integer.valueOf(cl.substring(0, p)).intValue();
+ from--;
+ } catch (NumberFormatException ex)
+ {
+ System.err.println(
+ "ERROR: Couldn't parse first integer in range element column selection string '"
+ + cl + "' - format is 'from-to'");
+ return;
+ }
+ try
+ {
+ to = Integer.valueOf(cl.substring(p + 1)).intValue();
+ to--;
+ } catch (NumberFormatException ex)
+ {
+ System.err.println(
+ "ERROR: Couldn't parse second integer in range element column selection string '"
+ + cl + "' - format is 'from-to'");
+ return;
+ }
+ if (from >= 0 && to >= 0)
+ {
+ // valid range
+ if (from < to)
+ {
+ int t = to;
+ to = from;
+ to = t;
+ }
+ if (!seset)
+ {
+ start = from;
+ end = to;
+ seset = true;
+ }
+ else
+ {
+ // comment to prevent range extension
+ if (start > from)
+ {
+ start = from;
+ }
+ if (end < to)
+ {
+ end = to;
+ }
+ }
+ for (int r = from; r <= to; r++)
+ {
+ if (r >= 0 && r < alw)
+ {
+ csel.addElement(r);
+ }
+ }
+ }
+ else
+ {
+ System.err.println("ERROR: Invalid Range '" + cl
+ + "' deparsed as [" + from + "," + to + "]");
+ }
+ }
+ else
+ {
+ int r = -1;
+ try
+ {
+ r = Integer.valueOf(cl).intValue();
+ r--;
+ } catch (NumberFormatException ex)
+ {
+ if (cl.toLowerCase().equals("sequence"))
+ {
+ // we are in the dataset sequence's coordinate frame.
+ inseqpos = true;
+ }
+ else
+ {
+ System.err.println(
+ "ERROR: Couldn't parse integer from point selection element of column selection string '"
+ + cl + "'");
+ return;
+ }
+ }
+ if (r >= 0 && r <= alw)
+ {
+ if (!seset)
+ {
+ start = r;
+ end = r;
+ seset = true;
+ }
+ else
+ {
+ // comment to prevent range extension
+ if (start > r)
+ {
+ start = r;
+ }
+ if (end < r)
+ {
+ end = r;
+ }
+ }
+ csel.addElement(r);
+ }
+ else
+ {
+ System.err.println("ERROR: Invalid Point selection '" + cl
+ + "' deparsed as [" + r + "]");
+ }
+ }
+ }
+ }
+ if (seqsfound)
+ {
+ // we only propagate the selection when it was the null selection, or the
+ // given sequences were found in the alignment.
+ if (inseqpos && sel.getSize() > 0)
+ {
+ // assume first sequence provides reference frame ?
+ SequenceI rs = sel.getSequenceAt(0);
+ start = rs.findIndex(start);
+ end = rs.findIndex(end);
+ List<Integer> cs = new ArrayList<>(csel.getSelected());
+ csel.clear();
+ for (Integer selectedCol : cs)
+ {
+ csel.addElement(rs.findIndex(selectedCol));
+ }
+ }
+ sel.setStartRes(start);
+ sel.setEndRes(end);
+ AlignFrame af = alf;
+ EventQueue.invokeLater(new Runnable()
+ {
+ @Override
+ public void run()
+ {
+ af.select(sel, csel,
+ af.getCurrentView().getAlignment().getHiddenColumns());
+ }
+ });
+ }
+ }
+
+ //
+ // @Override
+ // public void setFeatureGroupState(String[] groups, boolean state)
+ // {
+ // setFeatureGroupState(null, groups, state);
+ // }
+ //
+ // @Override
+ // public void setFeatureGroupState(String[] groups, boolean state)
+ // { // JalviewLite API
+ // setFeatureGroupStateOn(null, groups, state);
+ // }
+ //
+ @Override
+ public void setFeatureGroupState(final String[] groups,
+ boolean state, AlignFrame alf)
+ {
+ // setFeatureGroupState(alf, groups, state);
+ // java.awt.EventQueue.invokeLater(new Runnable()
+ // {
+ // @Override
+ // public void run()
+ // {
+ // (alf == null ? getCurrentAlignFrame() : alf)
+ // .setFeatureGroupState(
+ // separatorListToArray(groups, separator), state);
+ // }
+ // });
+ // }
+ //
+ // public void setFeatureGroupState(AlignFrame alf, String[] groups, boolean
+ // state) {
+ (alf == null ? getCurrentAlignFrame() : alf)
+ .setFeatureGroupState(groups, state);
+ }
+
+ @Override
+ public void setSelectionListener(String listener, AlignFrame alf)
+ {
+ Desktop.getStructureSelectionManager()
+ .addSelectionListener(new JsSelectionListener(alf, listener));
+ }
+
+ @Override
+ public void showOverview()
+ {
+ getCurrentAlignFrame().overviewMenuItem_actionPerformed(null);
+ }
+
+ /**
+ * @j2sAlias showStructure
+ */
+ @Override
+ public void showStructure(String pdbID, String fileType, AlignFrame alf)
+ {
+ if (alf == null)
+ alf = getCurrentAlignFrame();
+ PDBEntry pe = null;
+ SequenceI[] seqs = null;
+ if (pdbID == null)
+ {
+ seqs = alf.getViewport().getSequenceSelection();
+ if (seqs.length == 0)
+ seqs = alf.getViewport().getAlignment().getSequencesArray();
+ for (int i = 0; i < seqs.length; i++)
+ {
+ Vector<PDBEntry> list = seqs[i].getAllPDBEntries();
+ if (list.size() > 0)
+ {
+ pe = list.get(0);
+ break;
+ }
+ }
+ }
+ if (pe == null)
+ {
+ if (pdbID == null)
+ return;
+ pe = new PDBEntry(pdbID, null, fileType);
+ List<SequenceI> list = alf.getViewport().getAlignment()
+ .getSequences();
+ List<SequenceI> tmp = new ArrayList<SequenceI>();
+ for (int i = 0; i < list.size(); i++)
+ {
+ SequenceI seq = list.get(i);
+ if (seq.getPDBEntry(pdbID) != null)
+ {
+ tmp.add(seq);
+ }
+ }
+ seqs = tmp.toArray(new SequenceI[tmp.size()]);
+ alf.alignPanel.selectSequences(tmp);
+ }
+ StructureViewer.launchStructureViewer(alf.alignPanel, pe, seqs);
+ }
+
+ // private or package-private methods
+
+ /**
+ * form a complete URL given a path to a resource and a reference location on
+ * the same server
+ *
+ * @param targetPath
+ * - an absolute path on the same server as localref or a document
+ * located relative to localref
+ * @param localref
+ * - a URL on the same server as url
+ * @return a complete URL for the resource located by url
+ */
+ private static String resolveUrlForLocalOrAbsolute(String targetPath,
+ URL localref)
+ {
+ String resolvedPath = "";
+ if (targetPath.startsWith("/"))
+ {
+ String codebase = localref.toString();
+ String localfile = localref.getFile();
+ resolvedPath = codebase.substring(0,
+ codebase.length() - localfile.length()) + targetPath;
+ return resolvedPath;
+ }
+
+ /*
+ * get URL path and strip off any trailing file e.g.
+ * www.jalview.org/examples/index.html#applets?a=b is trimmed to
+ * www.jalview.org/examples/
+ */
+ String urlPath = localref.toString();
+ String directoryPath = urlPath;
+ int lastSeparator = directoryPath.lastIndexOf("/");
+ if (lastSeparator > 0)
+ {
+ directoryPath = directoryPath.substring(0, lastSeparator + 1);
+ }
+
+ if (targetPath.startsWith("/"))
+ {
+ /*
+ * construct absolute URL to a file on the server - this is not allowed?
+ */
+ // String localfile = localref.getFile();
+ // resolvedPath = urlPath.substring(0,
+ // urlPath.length() - localfile.length())
+ // + targetPath;
+ resolvedPath = directoryPath + targetPath.substring(1);
+ }
+ else
+ {
+ resolvedPath = directoryPath + targetPath;
+ }
+ // if (debug)
+ // {
+ // System.err.println(
+ // "resolveUrlForLocalOrAbsolute returning " + resolvedPath);
+ // }
+ return resolvedPath;
+ }
+
+ /**
+ * parse the string into a list
+ *
+ * @param list
+ * @param separator
+ * @return elements separated by separator
+ */
+ private static String[] separatorListToArray(String list,
+ String separator)
+ {
+ // TODO use StringUtils version (slightly different...)
+ int seplen = separator.length();
+ if (list == null || list.equals("") || list.equals(separator))
+ {
+ return null;
+ }
+ Vector<String> jv = new Vector<>();
+ int cp = 0, pos;
+ while ((pos = list.indexOf(separator, cp)) > cp)
+ {
+ jv.addElement(list.substring(cp, pos));
+ cp = pos + seplen;
+ }
+ if (cp < list.length())
+ {
+ String c = list.substring(cp);
+ if (!c.equals(separator))
+ {
+ jv.addElement(c);
+ }
+ }
+ if (jv.size() > 0)
+ {
+ String[] v = new String[jv.size()];
+ for (int i = 0; i < v.length; i++)
+ {
+ v[i] = jv.elementAt(i);
+ }
+ jv.removeAllElements();
+ return v;
+ }
+ return null;
+ }
+
+ /**
+ * Discovers whether the given file is in the Applet Archive
+ *
+ * @param f
+ * String
+ * @return boolean
+ */
+ private static boolean inArchive(Class<?> c, String f)
+ {
+ // This might throw a security exception in certain browsers
+ // Netscape Communicator for instance.
+ try
+ {
+ boolean rtn = (c.getResourceAsStream("/" + f) != null);
+ return rtn;
+ } catch (Exception ex)
+ {
+ System.out.println("Exception checking resources: " + f + " " + ex);
+ return false;
+ }
+ }
+
+ /**
+ * Allowing for a JavaScript function here.
+ */
+ void callInitCallback()
+ {
+ Object initjscallback = getParameterAsObject("oninit");
+ if (initjscallback != null)
+ {
+ SwingUtilities.invokeLater(new Runnable() {
+
+ @Override
+ public void run()
+ {
+ try
+ {
+ doSendCallback(initjscallback, new Object[] {this});
+ } catch (Exception e)
+ {
+ System.err.println("Exception when executing _oninit callback '"
+ + initjscallback + "'.");
+ e.printStackTrace();
+ }
+ }
+
+ });
+ }
+ }
+
+ /**
+ * Pass the provided array prepended with Jalview.this
+ *
+ * Appropriated from org.jmol.appletjs.Jmol
+ *
+ * @param callback
+ * a window function or "alert"
+ * @param data
+ * @return String return from the callback method.
+ */
+ String doSendCallback(Object callback, Object[] data)
+ {
+ Jalview me = jalview;
+
+ if (me != null && callback != null)
+ {
+ /**
+ * @j2sNative
+ *
+ * try{
+ *
+ * if (callback == "alert") { alert(data[0]); return ""; } var
+ * o; if (typeof callback == "function") { o = callback; } else
+ * { if (!callback)return; var tokens = callback.split("."); o
+ * = window[tokens[0]]; for (var i = 1; i < tokens.length; i++)
+ * o = o[tokens[i]]; } var a = [me]; for (var i = 0; i <
+ * data.length; i++) a.push(data[i] ? data[i].booleanValue &&
+ * (data[i] = data[i].booleanValue()) : data[i]); return
+ * o.apply(null,a) } catch (e) { System.out.println(callback +
+ * " failed " + e); }
+ */
+ }
+ return "";
+ }
+
+ /**
+ * Initialize from Info.key/value pairs that match the old JalviewLite applet
+ * parameters.
+ *
+ * See http://www.jalview.org/old/v2_8/examples/appletParameters.html
+ *
+ * Note that some of these parameters are handled as command-line arguments,
+ * as determined in ArgsParser.
+ *
+ * @param alf
+ */
+ void initFromParams(AlignFrame alf)
+ {
+ String sep = getParameter("separator");
+ if (sep != null && sep.length() > 0)
+ {
+ separator = sep;
+ }
+ initTree(alf);
+ initScoreFile(alf);
+ initFeatures(alf);
+ initAnnotations(alf);
+ initJnetFile(alf);
+ initPdbFiles(alf);
+ }
+
+ /**
+ * Load annotations if specified by parameter. Returns true if loaded, else
+ * false.
+ *
+ *
+ * @param alignFrame
+ * @return
+ */
+ private boolean initAnnotations(AlignFrame alf)
+ {
+
+ String param = getParameter("annotations");
+ if (param == null)
+ return false;
+ ret[0] = param;
+ DataSourceType protocol = resolveFileProtocol(ret);
+ param = ret[0];
+ if (!new AnnotationFile().annotateAlignmentView(alf.getViewport(),
+ param, protocol))
+ {
+ System.err.println("Annotations were not added from annotation file '"
+ + param + "'");
+ return false;
+ }
+ updateForAnnotations();
+ return true;
+ }
+
+ /**
+ * Load features file and view settings as specified by parameters. Returns
+ * true if features were loaded, else false.
+ *
+ * @param
+ *
+ * @param alignFrame
+ * @return
+ */
+ private boolean initFeatures(AlignFrame alf)
+ {
+
+ // ///////////////////////////
+ // modify display of features
+ // we do this before any features have been loaded, ensuring any hidden
+ // groups are hidden when features first displayed
+ //
+ // hide specific groups
+ //
+ String param = getParameter("hidefeaturegroups");
+ if (param != null)
+ {
+ setFeatureGroupState(separatorListToArray(param, separator),
+ false, alf);
+ // setFeatureGroupStateOn(newAlignFrame, param, false);
+ }
+ // show specific groups
+ param = getParameter("showfeaturegroups");
+ if (param != null)
+ {
+ setFeatureGroupState(separatorListToArray(param, separator),
+ true, alf);
+ // setFeatureGroupStateOn(newAlignFrame, param, true);
+ }
+ // and now load features
+ param = getParameter("features");
+ if (param == null)
+ {
+ return false;
+ }
+ if (!parseFeaturesFile(param, alf))
+ return false;
+ param = getParameter("showFeatureSettings");
+ if (param != null && param.equalsIgnoreCase("true"))
+ {
+ alf.showFeatureSettingsUI();
+ }
+ return true;
+ }
+
+ /**
+ * Load in a Jnetfile if specified by parameter. Returns true if loaded, else
+ * false.
+ *
+ * @param alignFrame
+ * @return
+ */
+ private boolean initJnetFile(AlignFrame alf)
+ {
+
+ String param = getParameter("jnetfile");
+ if (param == null)
+ {
+ // jnet became jpred around 2016
+ param = getParameter("jpredfile");
+ }
+ if (param != null)
+ {
+ try
+ {
+ ret[0] = param;
+ DataSourceType protocol = resolveFileProtocol(ret);
+ JPredFile predictions = new JPredFile(ret[0], protocol);
+ JnetAnnotationMaker.add_annotation(predictions,
+ alf.getViewport().getAlignment(), 0, false);
+ // false == do not add sequence profile from concise output
+ alf.getViewport().getAlignment().setupJPredAlignment();
+ updateForAnnotations();
+ } catch (Exception ex)
+ {
+ ex.printStackTrace();
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Load PDBFiles if any specified by parameter(s). Returns true if loaded,
+ * else false.
+ *
+ * @param loaderFrame
+ * @return
+ */
+ private boolean initPdbFiles(AlignFrame alf)
+ {
+
+ /*
+ * <param name="alignpdbfiles" value="false/true"/> Undocumented for 2.6 -
+ * related to JAL-434
+ */
+
+ // not supported (as for JalviewLite)
+ // boolean doAlign = false;//"true".equalsIgnoreCase("" +
+ // getAppletParameter("alignpdbfiles", false));
+ // setAlignPdbStructures(doAlign);
+ /*
+ * <param name="PDBfile" value="1gaq.txt PDB|1GAQ|1GAQ|A PDB|1GAQ|1GAQ|B
+ * PDB|1GAQ|1GAQ|C">
+ *
+ * <param name="PDBfile2" value="1gaq.txt A=SEQA B=SEQB C=SEQB">
+ *
+ * <param name="PDBfile3" value="1q0o Q45135_9MICO">
+ */
+
+ // Accumulate pdbs here if they are heading for the same view (if
+ // alignPdbStructures is true)
+ // ArrayList<Object[]> pdbs = new ArrayList<>();
+ // init a lazy matcher if we're asked to
+ boolean relaxed = "true"
+ .equalsIgnoreCase(getParameter("relaxedidmatch"));
+ jalview.analysis.SequenceIdMatcher matcher = relaxed
+ ? new jalview.analysis.SequenceIdMatcher(
+ alf.getViewport().getAlignment().getSequencesArray())
+ : null;
+
+ String param = getParameter("PDBFILE");
+ int plast = (param == null ? 9 : 1);
+ if (param == null && (param = getParameter("PDBFILE1")) == null)
+ {
+ return false;
+ }
+ for (int p = 1; p <= plast; p++)
+ {
+ if (p > 1)
+ {
+ param = getParameter("PDBFILE" + p);
+ if (param == null)
+ break;
+ }
+ PDBEntry pdb = new PDBEntry();
+
+ String seqstring;
+ SequenceI[] seqs = null;
+ String[] chains = null;
+
+ StringTokenizer st = new StringTokenizer(param, " ");
+
+ if (st.countTokens() < 2)
+ {
+ String sequence = getParameter("PDBSEQ");
+ if (sequence != null)
+ {
+ seqs = new SequenceI[] { matcher == null
+ ? (Sequence) alf.getViewport().getAlignment()
+ .findName(sequence)
+ : matcher.findIdMatch(sequence) };
+ }
+
+ }
+ else
+ {
+ param = st.nextToken();
+ List<SequenceI> tmp = new ArrayList<>();
+ List<String> tmp2 = new ArrayList<>();
+
+ while (st.hasMoreTokens())
+ {
+ seqstring = st.nextToken();
+ StringTokenizer st2 = new StringTokenizer(seqstring, "=");
+ if (st2.countTokens() > 1)
+ {
+ // This is the chain
+ tmp2.add(st2.nextToken());
+ seqstring = st2.nextToken();
+ }
+ tmp.add(matcher == null
+ ? (Sequence) alf.getViewport().getAlignment()
+ .findName(seqstring)
+ : matcher.findIdMatch(seqstring));
+ }
+
+ seqs = tmp.toArray(new SequenceI[tmp.size()]);
+ if (tmp2.size() == tmp.size())
+ {
+ chains = tmp2.toArray(new String[tmp2.size()]);
+ }
+ }
+ pdb.setId(param);
+ ret[0] = param;
+ DataSourceType protocol = resolveFileProtocol(ret);
+ // TODO check JAL-357 for files in a jar (CLASSLOADER)
+ pdb.setFile(ret[0]);
+
+ if (seqs != null)
+ {
+ for (int i = 0; i < seqs.length; i++)
+ {
+ if (seqs[i] != null)
+ {
+ ((Sequence) seqs[i]).addPDBId(pdb);
+ StructureSelectionManager
+ .getStructureSelectionManager(
+ (StructureSelectionManagerProvider) this)
+ .registerPDBEntry(pdb);
+ }
+ }
+
+ // if (doAlign)
+ // {
+ // pdbs.add(new Object[] { pdb, seqs, chains, protocol });
+ // }
+ // else
+ {
+ StructureViewer.launchStructureViewer(
+ (alf == null ? getCurrentAlignFrame() : alf).alignPanel,
+ pdb, seqs);
+ }
+ }
+ }
+ //
+ // if (doAlign && pdbs.size() > 0)
+ // {
+ // SequenceI[][] seqs = new SequenceI[pdbs.size()][];
+ // PDBEntry[] pdb = new PDBEntry[pdbs.size()];
+ // String[][] chains = new String[pdbs.size()][];
+ // String[] protocols = new String[pdbs.size()];
+ // for (int pdbsi = 0, pdbsiSize = pdbs
+ // .size(); pdbsi < pdbsiSize; pdbsi++)
+ // {
+ // Object[] o = pdbs.get(pdbsi);
+ // pdb[pdbsi] = (PDBEntry) o[0];
+ // seqs[pdbsi] = (SequenceI[]) o[1];
+ // chains[pdbsi] = (String[]) o[2];
+ // protocols[pdbsi] = (String) o[3];
+ // }
+ //// alignedStructureView(pdb, seqs, chains, protocols);
+ // result = true;
+ // }
+ return true;
+ }
+
+ /**
+ * Load a score file if specified by parameter. Returns true if file was
+ * loaded, else false.
+ *
+ * @param loaderFrame
+ */
+ private boolean initScoreFile(AlignFrame alf)
+ {
+
+ String sScoreFile = getParameter("scoreFile");
+ if (sScoreFile != null && !"".equals(sScoreFile))
+ {
+ try
+ {
+ if (loadScoreFile(sScoreFile, alf))
+ {
+ return true;
+ }
+ System.err.println(
+ "Failed to parse T-COFFEE parameter as a valid score file ('"
+ + sScoreFile + "')");
+ } catch (Exception e)
+ {
+ System.err.printf("Cannot read score file: '%s'. Cause: %s \n",
+ sScoreFile, e.getMessage());
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Load a tree for the alignment if specified by parameter. Returns true if a
+ * tree was loaded, else false.
+ *
+ * @return
+ */
+ private boolean initTree(AlignFrame alf)
+ {
+ String treeFile;
+ if ((treeFile = getParameter("tree")) == null
+ && (treeFile = getParameter("treefile")) == null)
+ return false;
+ if (alf == null)
+ alf = getCurrentAlignFrame();
+ try
+ {
+ ret[0] = treeFile;
+ NewickFile nf = new NewickFile(treeFile, resolveFileProtocol(ret));
+ nf.parse();
+ if (nf.getTree() != null)
+ {
+ treeFile = ret[0];
+ alf.getViewport()
+ .setCurrentTree(alf.showNewickTree(nf, treeFile).getTree());
+ return true;
+ }
+ } catch (Exception ex)
+ {
+ ex.printStackTrace();
+ }
+ return false;
+ }
+
+ private void updateForAnnotations()
+ {
+ getCurrentAlignFrame().updateForAnnotations();
+ }
+}
import jalview.io.JPredFile;
import jalview.io.JnetAnnotationMaker;
import jalview.io.NewickFile;
-import jalview.javascript.JSFunctionExec;
-import jalview.javascript.JalviewLiteJsApi;
-import jalview.javascript.JsCallBack;
-import jalview.javascript.MouseOverStructureListener;
+import jalview.appletgui.js.JSFunctionExec;
+import jalview.appletgui.js.JalviewLiteJsApi;
+import jalview.appletgui.js.JsCallBack;
+import jalview.appletgui.js.JsSelectionSender;
+import jalview.appletgui.js.MouseOverListener;
+import jalview.appletgui.js.MouseOverStructureListener;
import jalview.structure.SelectionListener;
import jalview.structure.StructureSelectionManager;
import jalview.util.ColorUtils;
setMouseoverListener(currentAlignFrame, listener);
}
- private Vector<jalview.javascript.JSFunctionExec> javascriptListeners = new Vector<>();
+ private Vector<JSFunctionExec> javascriptListeners = new Vector<>();
/*
* (non-Javadoc)
return;
}
}
- jalview.javascript.MouseOverListener mol = new jalview.javascript.MouseOverListener(
+ MouseOverListener mol = new MouseOverListener(
this, af, listener);
javascriptListeners.addElement(mol);
StructureSelectionManager.getStructureSelectionManager(this)
return;
}
}
- jalview.javascript.JsSelectionSender mol = new jalview.javascript.JsSelectionSender(
+ JsSelectionSender mol = new JsSelectionSender(
this, af, listener);
javascriptListeners.addElement(mol);
StructureSelectionManager.getStructureSelectionManager(this)
{
while (javascriptListeners.size() > 0)
{
- jalview.javascript.JSFunctionExec mol = javascriptListeners
+ JSFunctionExec mol = javascriptListeners
.elementAt(0);
javascriptListeners.removeElement(mol);
if (mol instanceof SelectionListener)
StructureSelectionManager.release(this);
}
- private jalview.javascript.JSFunctionExec jsFunctionExec;
+ private JSFunctionExec jsFunctionExec;
/*
* (non-Javadoc)
* (non-Javadoc)
*
* @see
- * jalview.javascript.JalviewLiteJsApi#scrollViewToRowIn(jalview.appletgui
+ * JalviewLiteJsApi#scrollViewToRowIn(jalview.appletgui
* .AlignFrame, java.lang.String)
*/
@Override
* (non-Javadoc)
*
* @see
- * jalview.javascript.JalviewLiteJsApi#scrollViewToColumnIn(jalview.appletgui
+ * JalviewLiteJsApi#scrollViewToColumnIn(jalview.appletgui
* .AlignFrame, java.lang.String)
*/
@Override
}
/**
+ * Inserts a sequence at a point in the alignment.
+ *
+ * @param i
+ * the index of the position the sequence is to be inserted in.
+ */
+ @Override
+ public void insertSequenceAt(int i, SequenceI snew)
+ {
+ synchronized (sequences)
+ {
+ if (sequences.size() > i)
+ {
+ sequences.add(i, snew);
+ return;
+
+ }
+ else
+ {
+ sequences.add(snew);
+ hiddenSequences.adjustHeightSequenceAdded();
+ }
+ return;
+ }
+ }
+
+ /**
* DOCUMENT ME!
*
* @return DOCUMENT ME!
@Override
public SequenceI findName(SequenceI startAfter, String token, boolean b)
{
-
+ if (token == null)
+ return null;
int i = 0;
SequenceI sq = null;
String sqname = null;
String calcId, boolean autoCalc, SequenceI seqRef,
SequenceGroup groupRef)
{
- if (annotations != null)
+ AlignmentAnnotation annot = annotations == null ? null
+ : AlignmentAnnotation.findFirstAnnotation(
+ Arrays.asList(getAlignmentAnnotation()), name, calcId,
+ autoCalc, seqRef, groupRef);
+
+ if (annot == null)
{
- for (AlignmentAnnotation annot : getAlignmentAnnotation())
+
+ annot = new AlignmentAnnotation(name, name, new Annotation[1], 0f, 0f,
+ AlignmentAnnotation.BAR_GRAPH);
+ annot.hasText = false;
+ if (calcId != null)
{
- if (annot.autoCalculated == autoCalc && (name.equals(annot.label))
- && (calcId == null || annot.getCalcId().equals(calcId))
- && annot.sequenceRef == seqRef
- && annot.groupRef == groupRef)
- {
- return annot;
- }
+ annot.setCalcId(calcId);
+ }
+ annot.autoCalculated = autoCalc;
+ if (seqRef != null)
+ {
+ annot.setSequenceRef(seqRef);
}
+ annot.groupRef = groupRef;
+ addAnnotation(annot);
}
- AlignmentAnnotation annot = new AlignmentAnnotation(name, name,
- new Annotation[1], 0f, 0f, AlignmentAnnotation.BAR_GRAPH);
- annot.hasText = false;
- if (calcId != null)
+ return annot;
+ }
+
+
+ @Override
+ public AlignmentAnnotation updateFromOrCopyAnnotation(
+ AlignmentAnnotation ala)
+ {
+ AlignmentAnnotation annot = AlignmentAnnotation.findFirstAnnotation(
+ Arrays.asList(getAlignmentAnnotation()), ala.label, ala.calcId,
+ ala.autoCalculated, ala.sequenceRef, ala.groupRef);
+ if (annot == null)
{
- annot.setCalcId(new String(calcId));
+ annot = new AlignmentAnnotation(ala);
+ addAnnotation(annot);
}
- annot.autoCalculated = autoCalc;
- if (seqRef != null)
+ else
{
- annot.setSequenceRef(seqRef);
+ annot.updateAlignmentAnnotationFrom(ala);
}
- annot.groupRef = groupRef;
- addAnnotation(annot);
-
+ validateAnnotation(annot);
return annot;
}
}
}
+ @Override
+ public List<SequenceI> getHmmSequences()
+ {
+ List<SequenceI> result = new ArrayList<>();
+ for (int i = 0; i < sequences.size(); i++)
+ {
+ SequenceI seq = sequences.get(i);
+ if (seq.hasHMMProfile())
+ {
+ result.add(seq);
+ }
+ }
+ return result;
+ }
}
*/
private long invalidrnastruc = -2;
+ private double bitScore;
+
+ private double eValue;
+
/**
* Updates the _rnasecstr field Determines the positions that base pair and
* the positions of helices based on secondary structure from a Stockholm file
}
return null;
}
-
+
/**
* Creates a new AlignmentAnnotation object.
*
}
}
}
-
+
/**
* Copy constructor creates a new independent annotation row with the same
* associated sequenceRef
public AlignmentAnnotation(AlignmentAnnotation annotation)
{
setAnnotationId();
+ updateAlignmentAnnotationFrom(annotation);
+ }
+
+ /**
+ * copy attributes and annotation from an existing annotation (used by copy
+ * constructor). This method does not update the unique annotationId
+ *
+ * @param annotation
+ */
+ public void updateAlignmentAnnotationFrom(AlignmentAnnotation annotation)
+ {
this.label = new String(annotation.label);
if (annotation.description != null)
{
this.scaleColLabel = annotation.scaleColLabel;
this.showAllColLabels = annotation.showAllColLabels;
this.calcId = annotation.calcId;
+ this.bitScore = annotation.bitScore;
+ this.eValue = annotation.eValue;
+
if (annotation.properties != null)
{
properties = new HashMap<>();
* @param seqRef
* @param startRes
* @param alreadyMapped
+ * - annotation are at aligned columns
*/
public void createSequenceMapping(SequenceI seqRef, int startRes,
boolean alreadyMapped)
{
return hasScore || !Double.isNaN(score);
}
-
+
/**
* Score only annotation
*
makeVisibleAnnotation(hidden);
}
+
public void setPadGaps(boolean padgaps, char gapchar)
{
this.padGaps = padgaps;
Iterable<AlignmentAnnotation> list, SequenceI seq, String calcId,
String label)
{
-
ArrayList<AlignmentAnnotation> aa = new ArrayList<>();
for (AlignmentAnnotation ann : list)
{
public static Iterable<AlignmentAnnotation> findAnnotation(
List<AlignmentAnnotation> list, String calcId)
{
-
List<AlignmentAnnotation> aa = new ArrayList<>();
if (calcId == null)
{
return aa;
}
+ public double getBitScore()
+ {
+ return bitScore;
+ }
+
+ public void setBitScore(double bitScore)
+ {
+ this.bitScore = bitScore;
+ }
+
+ public double getEValue()
+ {
+ return eValue;
+ }
+
+ public void setEValue(double eValue)
+ {
+ this.eValue = eValue;
+ }
+
+ public static AlignmentAnnotation findFirstAnnotation(
+ Iterable<AlignmentAnnotation> alignmentAnnotation, String name,
+ String calcId, boolean autoCalc, SequenceI seqRef,
+ SequenceGroup groupRef)
+ {
+
+ for (AlignmentAnnotation annot : alignmentAnnotation)
+ {
+ if (annot.autoCalculated == autoCalc && (name.equals(annot.label))
+ && (calcId == null || annot.getCalcId().equals(calcId))
+ && annot.sequenceRef == seqRef && annot.groupRef == groupRef)
+ {
+ return annot;
+ }
+ }
+ return null;
+ }
+
}
* - null or specific sequence reference
* @param groupRef
* - null or specific group reference
- * @param method
- * - CalcId for the annotation (must match)
*
* @return existing annotation matching the given attributes
*/
boolean autoCalc, SequenceI seqRef, SequenceGroup groupRef);
/**
+ * like findOrCreateAnnotation - looks for an existing alignment annotation
+ * row with matching name, calcId, sequenceRef, groupRef and autoCalculated
+ * flag and updates it from the annotation. If none is found the annotation is
+ * added directly.
+ *
+ * @param ala
+ * @return ala or the annotation row that was updated.
+ */
+ AlignmentAnnotation updateFromOrCopyAnnotation(AlignmentAnnotation ala);
+
+ /**
* move the given group up or down in the alignment by the given number of
* rows. Implementor assumes given group is already present on alignment - no
* recalculations are triggered.
public boolean setHiddenColumns(HiddenColumns cols);
/**
+ * Insert a sequence at a position in an alignment
+ *
+ * @param i
+ * The index of the position.
+ * @param snew
+ * The new sequence.
+ */
+ void insertSequenceAt(int i, SequenceI snew);
+
+ /**
* Set the first sequence as representative and hide its insertions. Typically
* used when loading JPred files.
*/
*/
public HiddenColumns propagateInsertions(SequenceI profileseq,
AlignmentView input);
-
}
*/
public AlignmentOrder(AlignmentI orderFrom)
{
- Order = new ArrayList<SequenceI>();
+ Order = new ArrayList<>();
for (SequenceI seq : orderFrom.getSequences())
{
*/
public AlignmentOrder(SequenceI[] orderFrom)
{
- Order = new ArrayList<SequenceI>(Arrays.asList(orderFrom));
+ Order = new ArrayList<>(Arrays.asList(orderFrom));
}
/**
import java.io.PrintStream;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.List;
/**
{
return seqs.size();
}
+
+ public SequenceGroup getNewSequenceGroup(char c)
+ {
+ SequenceGroup newsg = new SequenceGroup(sg);
+ for (SeqCigar seq : seqs)
+ {
+ newsg.addSequence(seq.getSeq(c), false);
+ }
+ return newsg;
+ }
}
/**
}
}
+
+ /**
+ * return pruned visible sequences in each group in alignment view
+ *
+ * @param c
+ * @return
+ */
+ public Collection<? extends AnnotatedCollectionI> getVisibleGroups(char c)
+ {
+ ArrayList<SequenceGroup> groups = new ArrayList<>();
+ for (ScGroup sc : scGroups)
+ {
+ SequenceGroup sg = sc.getNewSequenceGroup(c);
+ groups.add(sg);
+ }
+ return groups;
+ }
}
* alignment, parent group).
*/
AnnotatedCollectionI getContext();
+
+
}
--- /dev/null
+package jalview.datamodel;
+
+/**
+ * stores data for each node in the hmm model
+ * @author TZVanaalten
+ *
+ */
+public class HMMNode
+{
+ //contains the match emissions for each symbol
+ double[] matchEmissions;
+
+ //contains the insert emissions for each symbol
+ double[] insertEmissions;
+
+ // contains the state transitions for each possible transition. These are mm,
+ // mi, md, im, ii, dm and dd in order
+ double[] stateTransitions;
+
+ //annotations
+ int residueNumber;
+ char consensusResidue;
+ char referenceAnnotation;
+ char maskValue;
+ char consensusStructure;
+
+ /**
+ * Constructor
+ */
+ public HMMNode()
+ {
+ }
+
+ public double[] getMatchEmissions()
+ {
+ return matchEmissions;
+ }
+
+ double getMatchEmission(int symbolIndex)
+ {
+ return matchEmissions[symbolIndex];
+ }
+
+ public void setMatchEmissions(double[] matches)
+ {
+ this.matchEmissions = matches;
+ }
+
+ public double[] getInsertEmissions()
+ {
+ return insertEmissions;
+ }
+
+ double getInsertEmission(int symbolIndex)
+ {
+ return insertEmissions[symbolIndex];
+ }
+
+ public void setInsertEmissions(double[] insertEmissionsL)
+ {
+ this.insertEmissions = insertEmissionsL;
+ }
+
+ public double[] getStateTransitions()
+ {
+ return stateTransitions;
+ }
+
+ double getStateTransition(int transition)
+ {
+ return stateTransitions[transition];
+ }
+
+ public void setStateTransitions(double[] stateTransitionsM)
+ {
+ this.stateTransitions = stateTransitionsM;
+ }
+
+ int getResidueNumber()
+ {
+ return residueNumber;
+ }
+ public void setResidueNumber(int resNo)
+ {
+ this.residueNumber = resNo;
+ }
+
+ char getConsensusResidue()
+ {
+ return consensusResidue;
+ }
+ public void setConsensusResidue(char consensusResidue)
+ {
+ this.consensusResidue = consensusResidue;
+ }
+
+ char getReferenceAnnotation()
+ {
+ return referenceAnnotation;
+ }
+ public void setReferenceAnnotation(char referenceAnnotation)
+ {
+ this.referenceAnnotation = referenceAnnotation;
+ }
+
+ char getMaskValue()
+ {
+ return maskValue;
+ }
+ public void setMaskValue(char maskValue)
+ {
+ this.maskValue = maskValue;
+ }
+
+ char getConsensusStructure()
+ {
+ return consensusStructure;
+ }
+ public void setConsensusStructure(char consensusStructure)
+ {
+ this.consensusStructure = consensusStructure;
+ }
+
+ /**
+ * Answers the symbol index of the symbol with the highest match emission
+ * probability (first symbol in case of a tie). Note this object stores
+ * probabilities, not the negative logarithms as in the HMM file.
+ *
+ * @return
+ */
+ int getMaxMatchEmissionIndex()
+ {
+ int maxIndex = 0;
+ double max = 0D;
+
+ for (int i = 0; i < matchEmissions.length; i++)
+ {
+ if (matchEmissions[i] > max)
+ {
+ max = matchEmissions[i];
+ maxIndex = i;
+ }
+ }
+ return maxIndex;
+ }
+}
+
+
--- /dev/null
+package jalview.datamodel;
+
+import jalview.io.HMMFile;
+import jalview.schemes.ResidueProperties;
+import jalview.util.Comparison;
+import jalview.util.MapList;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Data structure which stores a hidden Markov model
+ *
+ * @author TZVanaalten
+ *
+ */
+public class HiddenMarkovModel
+{
+ private static final char GAP_DASH = '-';
+
+ public final static String YES = "yes";
+
+ public final static String NO = "no";
+
+ public static final int MATCHTOMATCH = 0;
+
+ public static final int MATCHTOINSERT = 1;
+
+ public static final int MATCHTODELETE = 2;
+
+ public static final int INSERTTOMATCH = 3;
+
+ public static final int INSERTTOINSERT = 4;
+
+ public static final int DELETETOMATCH = 5;
+
+ public static final int DELETETODELETE = 6;
+
+ private static final double LOG2 = Math.log(2);
+
+ /*
+ * properties read from HMM file header lines
+ */
+ private Map<String, String> fileProperties = new HashMap<>();
+
+ private String fileHeader;
+
+ /*
+ * the symbols used in this model e.g. "ACGT"
+ */
+ private String alphabet;
+
+ /*
+ * symbol lookup index into the alphabet for 'A' to 'Z'
+ */
+ private int[] symbolIndexLookup = new int['Z' - 'A' + 1];
+
+ /*
+ * Nodes in the model. The begin node is at index 0, and contains
+ * average emission probabilities for each symbol.
+ */
+ private List<HMMNode> nodes = new ArrayList<>();
+
+ /*
+ * the aligned HMM consensus sequence extracted from the HMM profile
+ */
+ private SequenceI hmmSeq;
+
+ /*
+ * mapping from HMM nodes to residues of the hmm consensus sequence
+ */
+ private Mapping mapToHmmConsensus;
+
+ // stores background frequencies of alignment from which this model came
+ private Map<Character, Float> backgroundFrequencies;
+
+ /**
+ * Constructor
+ */
+ public HiddenMarkovModel()
+ {
+ }
+
+ /**
+ * Copy constructor given a new aligned sequence with which to associate the
+ * HMM profile
+ *
+ * @param hmm
+ * @param sq
+ */
+ public HiddenMarkovModel(HiddenMarkovModel hmm, SequenceI sq)
+ {
+ super();
+ this.fileProperties = new HashMap<>(hmm.fileProperties);
+ this.alphabet = hmm.alphabet;
+ this.nodes = new ArrayList<>(hmm.nodes);
+ this.symbolIndexLookup = hmm.symbolIndexLookup;
+ this.fileHeader = new String(hmm.fileHeader);
+ this.hmmSeq = sq;
+ this.backgroundFrequencies = hmm.getBackgroundFrequencies();
+ if (sq.getDatasetSequence() == hmm.mapToHmmConsensus.getTo())
+ {
+ // same dataset sequence e.g. after realigning search results
+ this.mapToHmmConsensus = hmm.mapToHmmConsensus;
+ }
+ else
+ {
+ // different dataset sequence e.g. after loading HMM from project
+ this.mapToHmmConsensus = new Mapping(sq.getDatasetSequence(),
+ hmm.mapToHmmConsensus.getMap());
+ }
+ }
+
+ /**
+ * Returns the information content at a specified column, calculated as the
+ * sum (over possible symbols) of the log ratio
+ *
+ * <pre>
+ * log(emission probability / background probability) / log(2)
+ * </pre>
+ *
+ * @param column
+ * column position (base 0)
+ * @return
+ */
+ public float getInformationContent(int column)
+ {
+ float informationContent = 0f;
+
+ for (char symbol : getSymbols().toCharArray())
+ {
+ float freq = ResidueProperties.backgroundFrequencies
+ .get(getAlphabetType()).get(symbol);
+ float prob = (float) getMatchEmissionProbability(column, symbol);
+ informationContent += prob * Math.log(prob / freq);
+ }
+
+ informationContent = informationContent / (float) LOG2;
+
+ return informationContent;
+ }
+
+ /**
+ * Gets the file header of the .hmm file this model came from
+ *
+ * @return
+ */
+ public String getFileHeader()
+ {
+ return fileHeader;
+ }
+
+ /**
+ * Sets the file header of this model.
+ *
+ * @param header
+ */
+ public void setFileHeader(String header)
+ {
+ fileHeader = header;
+ }
+
+ /**
+ * Returns the symbols used in this hidden Markov model
+ *
+ * @return
+ */
+ public String getSymbols()
+ {
+ return alphabet;
+ }
+
+ /**
+ * Gets the node in the hidden Markov model at the specified position.
+ *
+ * @param nodeIndex
+ * The index of the node requested. Node 0 optionally contains the
+ * average match emission probabilities across the entire model, and
+ * always contains the insert emission probabilities and state
+ * transition probabilities for the begin node. Node 1 contains the
+ * first node in the HMM that can correspond to a column in the
+ * alignment.
+ * @return
+ */
+ public HMMNode getNode(int nodeIndex)
+ {
+ return nodes.get(nodeIndex);
+ }
+
+ /**
+ * Returns the name of the sequence alignment on which the HMM is based.
+ *
+ * @return
+ */
+ public String getName()
+ {
+ return fileProperties.get(HMMFile.NAME);
+ }
+
+ /**
+ * Answers the string value of the property (parsed from an HMM file) for the
+ * given key, or null if the property is not present
+ *
+ * @param key
+ * @return
+ */
+ public String getProperty(String key)
+ {
+ return fileProperties.get(key);
+ }
+
+ /**
+ * Answers true if the property with the given key is present with a value of
+ * "yes" (not case-sensitive), else false
+ *
+ * @param key
+ * @return
+ */
+ public boolean getBooleanProperty(String key)
+ {
+ return YES.equalsIgnoreCase(fileProperties.get(key));
+ }
+
+ /**
+ * Returns the length of the hidden Markov model. The value returned is the
+ * LENG property if specified, else the number of nodes, excluding the begin
+ * node (which should be the same thing).
+ *
+ * @return
+ */
+ public int getLength()
+ {
+ if (fileProperties.get(HMMFile.LENGTH) == null)
+ {
+ return nodes.size() - 1; // not counting BEGIN node
+ }
+ return Integer.parseInt(fileProperties.get(HMMFile.LENGTH));
+ }
+
+ /**
+ * Returns the value of mandatory property "ALPH" - "amino", "DNA", "RNA" are
+ * the options. Other alphabets may be added.
+ *
+ * @return
+ */
+ public String getAlphabetType()
+ {
+ return fileProperties.get(HMMFile.ALPHABET);
+ }
+
+ /**
+ * Sets the model alphabet to the symbols in the given string (ignoring any
+ * whitespace), and returns the number of symbols
+ *
+ * @param symbols
+ */
+ public int setAlphabet(String symbols)
+ {
+ String trimmed = symbols.toUpperCase().replaceAll("\\s", "");
+ int count = trimmed.length();
+ alphabet = trimmed;
+ symbolIndexLookup = new int['Z' - 'A' + 1];
+ Arrays.fill(symbolIndexLookup, -1);
+ int ignored = 0;
+
+ /*
+ * save the symbols in order, and a quick lookup of symbol position
+ */
+ for (short i = 0; i < count; i++)
+ {
+ char symbol = trimmed.charAt(i);
+ if (symbol >= 'A' && symbol <= 'Z'
+ && symbolIndexLookup[symbol - 'A'] == -1)
+ {
+ symbolIndexLookup[symbol - 'A'] = i;
+ }
+ else
+ {
+ System.err
+ .println(
+ "Unexpected or duplicated character in HMM ALPHabet: "
+ + symbol);
+ ignored++;
+ }
+ }
+ return count - ignored;
+ }
+
+ /**
+ * Answers the node of the model corresponding to an aligned column position
+ * (0...), or null if there is no such node
+ *
+ * @param column
+ * @return
+ */
+ HMMNode getNodeForColumn(int column)
+ {
+ /*
+ * if the hmm consensus is gapped at the column,
+ * there is no corresponding node
+ */
+ if (Comparison.isGap(hmmSeq.getCharAt(column)))
+ {
+ return null;
+ }
+
+ /*
+ * find the node (if any) that is mapped to the
+ * consensus sequence residue position at the column
+ */
+ int seqPos = hmmSeq.findPosition(column);
+ int[] nodeNo = mapToHmmConsensus.getMap().locateInFrom(seqPos, seqPos);
+ if (nodeNo != null)
+ {
+ return getNode(nodeNo[0]);
+ }
+ return null;
+ }
+
+ /**
+ * Gets the match emission probability for a given symbol at a column in the
+ * alignment.
+ *
+ * @param alignColumn
+ * The index of the alignment column, starting at index 0. Index 0
+ * usually corresponds to index 1 in the HMM.
+ * @param symbol
+ * The symbol for which the desired probability is being requested.
+ * @return
+ *
+ */
+ public double getMatchEmissionProbability(int alignColumn, char symbol)
+ {
+ HMMNode node = getNodeForColumn(alignColumn);
+ int symbolIndex = getSymbolIndex(symbol);
+ if (node != null && symbolIndex != -1)
+ {
+ return node.getMatchEmission(symbolIndex);
+ }
+ return 0D;
+ }
+
+ /**
+ * Gets the insert emission probability for a given symbol at a column in the
+ * alignment.
+ *
+ * @param alignColumn
+ * The index of the alignment column, starting at index 0. Index 0
+ * usually corresponds to index 1 in the HMM.
+ * @param symbol
+ * The symbol for which the desired probability is being requested.
+ * @return
+ *
+ */
+ public double getInsertEmissionProbability(int alignColumn, char symbol)
+ {
+ HMMNode node = getNodeForColumn(alignColumn);
+ int symbolIndex = getSymbolIndex(symbol);
+ if (node != null && symbolIndex != -1)
+ {
+ return node.getInsertEmission(symbolIndex);
+ }
+ return 0D;
+ }
+
+ /**
+ * Gets the state transition probability for a given symbol at a column in the
+ * alignment.
+ *
+ * @param alignColumn
+ * The index of the alignment column, starting at index 0. Index 0
+ * usually corresponds to index 1 in the HMM.
+ * @param symbol
+ * The symbol for which the desired probability is being requested.
+ * @return
+ *
+ */
+ public double getStateTransitionProbability(int alignColumn,
+ int transition)
+ {
+ HMMNode node = getNodeForColumn(alignColumn);
+ if (node != null)
+ {
+ return node.getStateTransition(transition);
+ }
+ return 0D;
+ }
+
+ /**
+ * Returns the sequence position linked to the node at the given index. This
+ * corresponds to an aligned column position (counting from 1).
+ *
+ * @param nodeIndex
+ * The index of the node, starting from index 1. Index 0 is the begin
+ * node, which does not correspond to a column in the alignment.
+ * @return
+ */
+ public int getNodeMapPosition(int nodeIndex)
+ {
+ return nodes.get(nodeIndex).getResidueNumber();
+ }
+
+ /**
+ * Returns the consensus residue at the specified node.
+ *
+ * @param nodeIndex
+ * The index of the specified node.
+ * @return
+ */
+ public char getConsensusResidue(int nodeIndex)
+ {
+ char value = nodes.get(nodeIndex).getConsensusResidue();
+ return value;
+ }
+
+ /**
+ * Returns the reference annotation at the specified node.
+ *
+ * @param nodeIndex
+ * The index of the specified node.
+ * @return
+ */
+ public char getReferenceAnnotation(int nodeIndex)
+ {
+ char value = nodes.get(nodeIndex).getReferenceAnnotation();
+ return value;
+ }
+
+ /**
+ * Returns the mask value at the specified node.
+ *
+ * @param nodeIndex
+ * The index of the specified node.
+ * @return
+ */
+ public char getMaskedValue(int nodeIndex)
+ {
+ char value = nodes.get(nodeIndex).getMaskValue();
+ return value;
+ }
+
+ /**
+ * Returns the consensus structure at the specified node.
+ *
+ * @param nodeIndex
+ * The index of the specified node.
+ * @return
+ */
+ public char getConsensusStructure(int nodeIndex)
+ {
+ char value = nodes.get(nodeIndex).getConsensusStructure();
+ return value;
+ }
+
+ /**
+ * Sets a property read from an HMM file
+ *
+ * @param key
+ * @param value
+ */
+ public void setProperty(String key, String value)
+ {
+ fileProperties.put(key, value);
+ }
+
+ /**
+ * Temporary implementation, should not be used.
+ *
+ * @return
+ */
+ public String getViterbi()
+ {
+ String value;
+ value = fileProperties.get(HMMFile.VITERBI);
+ return value;
+ }
+
+ /**
+ * Temporary implementation, should not be used.
+ *
+ * @return
+ */
+ public String getMSV()
+ {
+ String value;
+ value = fileProperties.get(HMMFile.MSV);
+ return value;
+ }
+
+ /**
+ * Temporary implementation, should not be used.
+ *
+ * @return
+ */
+ public String getForward()
+ {
+ String value;
+ value = fileProperties.get(HMMFile.FORWARD);
+ return value;
+ }
+
+ /**
+ * Constructs the consensus sequence based on the most probable symbol at each
+ * position. Gap characters are inserted for discontinuities in the node map
+ * numbering (if provided), else an ungapped sequence is generated.
+ * <p>
+ * A mapping between the HMM nodes and residue positions of the sequence is
+ * also built and saved.
+ *
+ * @return
+ */
+ void buildConsensusSequence()
+ {
+ List<int[]> toResidues = new ArrayList<>();
+
+ /*
+ * if the HMM provided a map to sequence, use those start/end values,
+ * else just treat it as for a contiguous sequence numbered from 1
+ */
+ boolean hasMap = getBooleanProperty(HMMFile.MAP);
+ int start = hasMap ? getNode(1).getResidueNumber() : 1;
+ int endResNo = hasMap ? getNode(nodes.size() - 1).getResidueNumber()
+ : (start + getLength() - 1);
+ char[] sequence = new char[endResNo];
+
+ int lastResNo = start - 1;
+ int seqOffset = -1;
+ int gapCount = 0;
+
+
+ for (int seqN = 0; seqN < start; seqN++)
+ {
+ sequence[seqN] = GAP_DASH;
+ seqOffset++;
+ }
+
+ for (int nodeNo = 1; nodeNo < nodes.size(); nodeNo++)
+ {
+ HMMNode node = nodes.get(nodeNo);
+ final int resNo = hasMap ? node.getResidueNumber() : lastResNo + 1;
+
+ /*
+ * insert gaps if map numbering is not continuous
+ */
+ while (resNo > lastResNo + 1)
+ {
+ sequence[seqOffset++] = GAP_DASH;
+ lastResNo++;
+ gapCount++;
+ }
+ char consensusResidue = node.getConsensusResidue();
+ if (GAP_DASH == consensusResidue)
+ {
+ /*
+ * no residue annotation in HMM - scan for the symbol
+ * with the highest match emission probability
+ */
+ int symbolIndex = node.getMaxMatchEmissionIndex();
+ consensusResidue = alphabet.charAt(symbolIndex);
+ if (node.getMatchEmission(symbolIndex) < 0.5D)
+ {
+ // follow convention of lower case if match emission prob < 0.5
+ consensusResidue = Character.toLowerCase(consensusResidue);
+ }
+ }
+ sequence[seqOffset++] = consensusResidue;
+ lastResNo = resNo;
+ }
+
+ Sequence seq = new Sequence(getName(), sequence, start,
+ lastResNo - gapCount);
+ seq.createDatasetSequence();
+ seq.setHMM(this);
+ this.hmmSeq = seq;
+
+ /*
+ * construct and store Mapping of nodes to residues
+ * note as constructed this is just an identity mapping,
+ * but it allows for greater flexibility in future
+ */
+ List<int[]> fromNodes = new ArrayList<>();
+ fromNodes.add(new int[] { 1, getLength() });
+ toResidues.add(new int[] { seq.getStart(), seq.getEnd() });
+ MapList mapList = new MapList(fromNodes, toResidues, 1, 1);
+ mapToHmmConsensus = new Mapping(seq.getDatasetSequence(), mapList);
+ }
+
+
+ /**
+ * Answers the aligned consensus sequence for the profile. Note this will
+ * return null if called before <code>setNodes</code> has been called.
+ *
+ * @return
+ */
+ public SequenceI getConsensusSequence()
+ {
+ return hmmSeq;
+ }
+
+ /**
+ * Answers the index position (0...) of the given symbol, or -1 if not a valid
+ * symbol for this HMM
+ *
+ * @param symbol
+ * @return
+ */
+ private int getSymbolIndex(char symbol)
+ {
+ /*
+ * symbolIndexLookup holds the index for 'A' to 'Z'
+ */
+ char c = Character.toUpperCase(symbol);
+ if ('A' <= c && c <= 'Z')
+ {
+ return symbolIndexLookup[c - 'A'];
+ }
+ return -1;
+ }
+
+ /**
+ * Sets the nodes of this HMM, and also extracts the HMM consensus sequence
+ * and a mapping between node numbers and sequence positions
+ *
+ * @param nodeList
+ */
+ public void setNodes(List<HMMNode> nodeList)
+ {
+ nodes = nodeList;
+ if (nodes.size() > 1)
+ {
+ buildConsensusSequence();
+ }
+ }
+
+ /**
+ * Sets the aligned consensus sequence this HMM is the model for
+ *
+ * @param hmmSeq
+ */
+ public void setHmmSeq(SequenceI hmmSeq)
+ {
+ this.hmmSeq = hmmSeq;
+ }
+
+ public void setBackgroundFrequencies(Map<Character, Float> bkgdFreqs)
+ {
+ backgroundFrequencies = bkgdFreqs;
+ }
+
+ public void setBackgroundFrequencies(ResidueCount bkgdFreqs)
+ {
+ backgroundFrequencies = new HashMap<>();
+
+ int total = bkgdFreqs.getTotalResidueCount();
+
+ for (char c : bkgdFreqs.getSymbolCounts().symbols)
+ {
+ backgroundFrequencies.put(c, bkgdFreqs.getCount(c) * 1f / total);
+ }
+
+ }
+
+ public Map<Character, Float> getBackgroundFrequencies()
+ {
+ return backgroundFrequencies;
+ }
+
+}
+
*/
package jalview.datamodel;
-import jalview.util.CaseInsensitiveString;
-
import java.util.Collections;
import java.util.Enumeration;
import java.util.Hashtable;
+import jalview.util.CaseInsensitiveString;
+
public class PDBEntry
{
{
}
+ /**
+ * Entry point when file is not known and fileType may be string
+ * @param pdbId
+ * @param chain may be null
+ * @param fileType "pdb", "mmcif", or "bcif"; null defaults to mmcif
+ */
+ public PDBEntry(String pdbId, String chain, String fileType) {
+ this.id = pdbId.toLowerCase();
+ setChainCode(chain); // I note that PDB Chains ARE case-sensitive now
+ if (fileType == null)
+ fileType = "mmcif";
+ switch (fileType.toLowerCase()) {
+ case "pdb":
+ this.type = Type.PDB.toString();
+ break;
+ case "mmcif":
+ this.type = Type.MMCIF.toString();
+ break;
+ default:
+ case "bcif":
+ System.out.println("format " + fileType + " has not been implemented; using mmCIF");
+ this.type = Type.MMCIF.toString();
+ break;
+ }
+ }
+
public PDBEntry(String pdbId, String chain, PDBEntry.Type type,
String filePath)
{
return id;
}
+ /**
+ * TODO
+ *
+ * @param key "protocol"
+ * @param value
+ */
public void setProperty(String key, Object value)
{
if (this.properties == null)
import jalview.util.QuickSort;
import jalview.util.SparseCount;
+import java.util.List;
+
/**
* A class to count occurrences of residues in a profile, optimised for speed
* and memory footprint.
}
/**
+ * A constructor that counts frequency of all symbols (including gaps) in the
+ * sequences (not case-sensitive)
+ *
+ * @param sequences
+ */
+ public ResidueCount(List<SequenceI> sequences)
+ {
+ this();
+ for (SequenceI seq : sequences)
+ {
+ for (int i = 0; i < seq.getLength(); i++)
+ {
+ add(seq.getCharAt(i));
+ }
+ }
+ }
+
+ /**
* 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.
sb.append("]");
return sb.toString();
}
+
+ /**
+ * Answers the total count for all symbols (excluding gaps)
+ *
+ * @return
+ */
+ public int getTotalResidueCount()
+ {
+ int total = 0;
+ for (char symbol : this.getSymbolCounts().symbols)
+ {
+ total += getCount(symbol);
+ }
+ return total;
+ }
}
import jalview.util.DBRefUtils;
import jalview.util.MapList;
import jalview.util.StringUtils;
+import jalview.workers.InformationThread;
import java.util.ArrayList;
import java.util.Arrays;
private String vamsasId;
+ HiddenMarkovModel hmm;
+
+ boolean isHMMConsensusSequence = false;
private DBModList<DBRefEntry> dbrefs; // controlled access
/**
this.addPDBId(new PDBEntry(pdb));
}
}
+ if (seq.getHMM() != null)
+ {
+ this.hmm = new HiddenMarkovModel(seq.getHMM(), this);
+ }
}
@Override
@Override
public ContiguousI findPositions(int fromColumn, int toColumn)
{
- if (toColumn < fromColumn || fromColumn < 1)
+ fromColumn = Math.max(fromColumn, 1);
+ if (toColumn < fromColumn)
{
return null;
}
{
for (AlignmentAnnotation ann : annotation)
{
- if ((ann.calcId != null && ann.calcId.equals(calcId))
+ String id = ann.getCalcId();
+ if ((id != null && id.equals(calcId))
&& (ann.label != null && ann.label.equals(label))
&& ((ignoreDescription && description == null)
|| (ann.description != null
&& ann.description.equals(description))))
-
{
result.add(ann);
}
}
}
+ @Override
+ public HiddenMarkovModel getHMM()
+ {
+ return hmm;
+ }
+
+ @Override
+ public void setHMM(HiddenMarkovModel hmm)
+ {
+ this.hmm = hmm;
+ }
+
+ @Override
+ public boolean hasHMMAnnotation()
+ {
+ if (this.annotation == null) {
+ return false;
+ }
+ for (AlignmentAnnotation ann : annotation)
+ {
+ if (InformationThread.HMM_CALC_ID.equals(ann.getCalcId()))
+ {
+ return true;
+ }
+ }
+ return false;
+ }
/**
* {@inheritDoc}
*/
// otherwise, sequence was completely hidden
return 0;
}
+
+ @Override
+ public boolean hasHMMProfile()
+ {
+ return hmm != null;
+ }
}
* @return
*/
boolean isNucleotide();
+
+ /**
+ * Returns the (possibly empty) list of HMM consensus sequences in the
+ * collection
+ *
+ * @return
+ */
+ List<SequenceI> getHmmSequences();
}
import jalview.renderer.ResidueShader;
import jalview.renderer.ResidueShaderI;
import jalview.schemes.ColourSchemeI;
+import jalview.util.MessageManager;
+import jalview.workers.InformationThread;
import java.awt.Color;
import java.beans.PropertyChangeListener;
public class SequenceGroup implements AnnotatedCollectionI
{
// TODO ideally this event notification functionality should be separated into
- // a
- // subclass of ViewportProperties similarly to ViewportRanges. Done here as
- // quick fix for JAL-2665
+ // a subclass of ViewportProperties similarly to ViewportRanges.
+ // Done here as a quick fix for JAL-2665
public static final String SEQ_GROUP_CHANGED = "Sequence group changed";
-
+
protected PropertyChangeSupport changeSupport = new PropertyChangeSupport(
this);
String groupName;
String description;
-
+
Conservation conserve;
+ Conservation conservationData;
+
+ ProfilesI consensusProfiles;
+
+ ProfilesI hmmProfiles;
+
boolean displayBoxes = true;
boolean displayText = true;
boolean colourText = false;
- /**
- * True if the group is defined as a group on the alignment, false if it is
- * just a selection.
+ /*
+ * true if the group is defined as a group on the alignment, false if it is
+ * just a selection
*/
boolean isDefined = false;
- /**
+ /*
* after Olivier's non-conserved only character display
*/
boolean showNonconserved = false;
- /**
- * group members
+ /*
+ * sequences in the group
*/
private List<SequenceI> sequences;
- /**
+ /*
* representative sequence for this group (if any)
*/
private SequenceI seqrep = null;
int width = -1;
- /**
- * Colourscheme applied to group if any
+ /*
+ * colour scheme applied to group if any
*/
public ResidueShaderI cs;
public Color textColour2 = Color.white;
- /**
- * consensus calculation property
+ /*
+ * properties for consensus annotation
*/
private boolean ignoreGapsInConsensus = true;
- /**
- * consensus calculation property
- */
private boolean showSequenceLogo = false;
- /**
- * flag indicating if logo should be rendered normalised
- */
private boolean normaliseSequenceLogo;
/*
+ * properties for HMM information annotation
+ */
+ private boolean hmmIgnoreBelowBackground = true;
+
+ private boolean hmmUseInfoLetterHeight;
+
+ private boolean hmmShowSequenceLogo;
+
+ private boolean hmmNormaliseSequenceLogo;
+
+ private boolean hmmShowHistogram;
+
+ /*
* visibility of rows or represented rows covered by group
*/
private boolean hidereps = false;
/*
* visibility of columns intersecting this group
*/
- private boolean hidecols = false;
+ private boolean hidecols;
AlignmentAnnotation consensus = null;
AlignmentAnnotation conservation = null;
+ private AlignmentAnnotation hmmInformation;
+
private boolean showConsensusHistogram;
-
+
private AnnotatedCollectionI context;
+
/**
- * Creates a new SequenceGroup object.
+ * Constructor, assigning a generated default name of "JGroup:" with object
+ * hashcode appended
*/
public SequenceGroup()
{
* copy constructor
*
* @param seqsel
+ * @param keepsequences
+ * if false do not add sequences from seqsel to new instance
*/
public SequenceGroup(SequenceGroup seqsel)
{
this();
+
if (seqsel != null)
{
sequences = new ArrayList<>();
showSequenceLogo = seqsel.showSequenceLogo;
normaliseSequenceLogo = seqsel.normaliseSequenceLogo;
showConsensusHistogram = seqsel.showConsensusHistogram;
+ hmmShowSequenceLogo = seqsel.hmmShowSequenceLogo;
+ hmmNormaliseSequenceLogo = seqsel.hmmNormaliseSequenceLogo;
+ hmmShowHistogram = seqsel.hmmShowHistogram;
idColour = seqsel.idColour;
outlineColour = seqsel.outlineColour;
seqrep = seqsel.seqrep;
thresholdTextColour = seqsel.thresholdTextColour;
width = seqsel.width;
ignoreGapsInConsensus = seqsel.ignoreGapsInConsensus;
+ hmmIgnoreBelowBackground = seqsel.hmmIgnoreBelowBackground;
+ hmmUseInfoLetterHeight = seqsel.hmmUseInfoLetterHeight;
if (seqsel.conserve != null)
{
+ // todo avoid doing this if we don't actually want derived calculations
+ // !
recalcConservation(); // safer than
// aaFrequency = (Vector) seqsel.aaFrequency.clone(); // ??
}
}
/**
- * calculate residue conservation for group - but only if necessary. returns
- * true if the calculation resulted in a visible change to group
+ * Recalculates column consensus, conservation, and HMM annotation for the
+ * group (as applicable). Returns true if the calculation resulted in a
+ * visible change to group.
*
* @param defer
* when set, colourschemes for this group are not refreshed after
*/
public boolean recalcConservation(boolean defer)
{
- if (cs == null && consensus == null && conservation == null)
+ if (cs == null && consensus == null && conservation == null
+ && hmmInformation == null)
{
return false;
}
{
ProfilesI cnsns = AAFrequency.calculate(sequences, startRes,
endRes + 1, showSequenceLogo);
+ if (hmmInformation != null)
+ {
+ HiddenMarkovModel hmm = hmmInformation.sequenceRef.getHMM();
+
+ ProfilesI info = AAFrequency.calculateHMMProfiles(hmm,
+ (endRes + 1) - startRes, startRes, endRes + 1,
+ hmmIgnoreBelowBackground, hmmUseInfoLetterHeight);
+ _updateInformationRow(info);
+ upd = true;
+ }
if (consensus != null)
{
_updateConsensusRow(cnsns, sequences.size());
}
/**
+ * Recalculates the information content on the HMM annotation
+ *
+ * @param cnsns
+ */
+ private void _updateInformationRow(ProfilesI cnsns)
+ {
+ if (hmmInformation == null)
+ {
+ createInformationAnnotation();
+ }
+ hmmInformation.description = MessageManager
+ .getString("label.information_description");
+ setHmmProfiles(cnsns);
+ // preserve width if already set
+ int aWidth = (hmmInformation.annotations != null)
+ ? (endRes < hmmInformation.annotations.length
+ ? hmmInformation.annotations.length : endRes + 1)
+ : endRes + 1;
+ hmmInformation.annotations = null;
+ hmmInformation.annotations = new Annotation[aWidth]; // should be alignment
+ // width
+ hmmInformation.setCalcId(InformationThread.HMM_CALC_ID);
+ AAFrequency.completeInformation(hmmInformation, cnsns, startRes,
+ endRes + 1);
+ }
+
+ /**
* @param s
* sequence to either add or remove from group
* @param recalc
}
/**
+ * Creates the Hidden Markov Model annotation for this group
+ */
+ void createInformationAnnotation()
+ {
+ hmmInformation = new AlignmentAnnotation("", "", new Annotation[1], 0f,
+ 6.25f, AlignmentAnnotation.BAR_GRAPH);
+ hmmInformation.hasText = true;
+ hmmInformation.autoCalculated = false;
+ hmmInformation.groupRef = this;
+ hmmInformation.label = getName();
+ hmmInformation.description = MessageManager
+ .getString("label.information_description");
+ hmmInformation.setCalcId(InformationThread.HMM_CALC_ID);
+ }
+
+ /**
* set this alignmentAnnotation object as the one used to render consensus
* annotation
*
return ignoreGapsInConsensus;
}
+ public void setIgnoreBelowBackground(boolean state)
+ {
+ hmmIgnoreBelowBackground = state;
+ }
+
+ public boolean isIgnoreBelowBackground()
+ {
+ return hmmIgnoreBelowBackground;
+ }
+
+ public void setInfoLetterHeight(boolean state)
+ {
+ hmmUseInfoLetterHeight = state;
+ }
+
+ public boolean isUseInfoLetterHeight()
+ {
+ return hmmUseInfoLetterHeight;
+ }
+
/**
* @param showSequenceLogo
* indicates if a sequence logo is shown for consensus annotation
{
return (startRes <= apos && endRes >= apos) && sequences.contains(seq);
}
+
+ public boolean isShowInformationHistogram()
+ {
+ return hmmShowHistogram;
+ }
+
+ public void setShowInformationHistogram(boolean state)
+ {
+ if (hmmShowHistogram != state && hmmInformation != null)
+ {
+ this.hmmShowHistogram = state;
+ // recalcConservation(); TODO don't know what to do here next
+ }
+ this.hmmShowHistogram = state;
+ }
+
+ public boolean isShowHMMSequenceLogo()
+ {
+ return hmmShowSequenceLogo;
+ }
+
+ public void setShowHMMSequenceLogo(boolean state)
+ {
+ hmmShowSequenceLogo = state;
+ }
+
+ public boolean isNormaliseHMMSequenceLogo()
+ {
+ return hmmNormaliseSequenceLogo;
+ }
+
+ public void setNormaliseHMMSequenceLogo(boolean state)
+ {
+ hmmNormaliseSequenceLogo = state;
+ }
+
+ public ProfilesI getConsensusData()
+ {
+ return consensusProfiles;
+ }
+
+ public ProfilesI getHmmProfiles()
+ {
+ return hmmProfiles;
+ }
+
+ public void setHmmProfiles(ProfilesI hmmProfiles)
+ {
+ this.hmmProfiles = hmmProfiles;
+ }
+
+ @Override
+ public List<SequenceI> getHmmSequences()
+ {
+ List<SequenceI> result = new ArrayList<>();
+ for (int i = 0; i < sequences.size(); i++)
+ {
+ SequenceI seq = sequences.get(i);
+ if (seq.hasHMMProfile())
+ {
+ result.add(seq);
+ }
+ }
+ return result;
+ }
+
}
*/
public void setName(String name);
+ public HiddenMarkovModel getHMM();
+
+ public void setHMM(HiddenMarkovModel hmm);
+
/**
* Get the display name
*/
* from 1), or null if no residues are included in the range
*
* @param fromColum
- * - first column base 1
+ * - first column base 1. (0 and negative positions are rounded up)
* @param toColumn
* - last column, base 1
- * @return
+ * @return null if fromColum>toColumn
*/
public ContiguousI findPositions(int fromColum, int toColumn);
public List<DBRefEntry> getPrimaryDBRefs();
/**
+ * Answers true if the sequence has annotation for Hidden Markov Model
+ * information content, else false
+ */
+ boolean hasHMMAnnotation();
+
+ /**
* Returns a (possibly empty) list of sequence features that overlap the given
* alignment column range, optionally restricted to one or more specified
* feature types. If the range is all gaps, then features which enclose it are
* @param c1
* @param c2
*/
- public int replace(char c1, char c2);
+ int replace(char c1, char c2);
/**
* Answers the GeneLociI, or null if not known
* the iterator to use
* @return a String corresponding to the sequence
*/
- public String getSequenceStringFromIterator(Iterator<int[]> it);
+ String getSequenceStringFromIterator(Iterator<int[]> it);
/**
* Locate the first position in this sequence which is not contained in an
* iterator over regions
* @return first residue not contained in regions
*/
+
public int firstResidueOutsideIterator(Iterator<int[]> it);
+ /**
+ * Answers true if this sequence has an associated Hidden Markov Model
+ *
+ * @return
+ */
+ boolean hasHMMProfile();
}
import java.util.Map.Entry;
import java.util.TreeMap;
+import jalview.bin.ApplicationSingletonProvider;
+import jalview.bin.ApplicationSingletonProvider.ApplicationSingletonI;
+
/**
* A singleton class to hold the set of attributes known for each feature type
*/
-public class FeatureAttributes
+public class FeatureAttributes implements ApplicationSingletonI
{
public enum Datatype
{
Character, Number, Mixed
}
- private static FeatureAttributes instance = new FeatureAttributes();
+ public static FeatureAttributes getInstance()
+ {
+ return (FeatureAttributes) ApplicationSingletonProvider
+ .getInstance(FeatureAttributes.class);
+ }
+
+ private FeatureAttributes()
+ {
+ attributes = new HashMap<>();
+ }
/*
* map, by feature type, of a map, by attribute name, of
if (value != null)
{
value = value.trim();
+ if (value.isEmpty())
+ {
+ return;
+ }
/*
* Parse numeric value unless we have previously
* seen text data for this attribute type
*/
- if (type == null || type == Datatype.Number)
+ if ((type == null && couldBeNumber(value))
+ || type == Datatype.Number)
{
try
{
hasValue = false;
}
}
+ else
+ {
+ /*
+ * if not a number, and not seen before...
+ */
+ type = Datatype.Character;
+ min = 0f;
+ max = 0f;
+ hasValue = false;
+ }
}
}
/**
- * Answers the description of the attribute, if recorded and unique, or null if either no, or more than description is recorded
+ * Answers the description of the attribute, if recorded and unique, or null
+ * if either no, or more than description is recorded
+ *
* @return
*/
public String getDescription()
}
/**
- * Answers the singleton instance of this class
- *
- * @return
- */
- public static FeatureAttributes getInstance()
- {
- return instance;
- }
-
- private FeatureAttributes()
- {
- attributes = new HashMap<>();
- }
-
- /**
* Answers the attribute names known for the given feature type, in
* alphabetical order (not case sensitive), or an empty set if no attributes
* are known. An attribute name is typically 'simple' e.g. "AC", but may be
}
/**
+ * A partial check that the string is numeric - only checks the first
+ * character. Returns true if the first character is a digit, or if it is '.',
+ * '+' or '-' and not the only character. Otherwise returns false (including
+ * for an empty string). Note this is not a complete check as it returns true
+ * for (e.g.) "1A".
+ *
+ * @param f
+ * @return
+ */
+ public static boolean couldBeNumber(String f)
+ {
+ int len = f.length();
+ if (len == 0)
+ {
+ return false;
+ }
+ char ch = f.charAt(0);
+ switch (ch)
+ {
+ case '.':
+ case '+':
+ case '-':
+ return len > 1;
+ }
+ return (ch <= '9' && ch >= '0');
+ }
+
+ /**
* Answers true if at least one attribute is known for the given feature type,
* else false
*
{
return;
}
-
+
Map<String[], AttributeData> atts = attributes.get(featureType);
if (atts == null)
{
import java.util.HashMap;
import java.util.Map;
+import jalview.bin.ApplicationSingletonProvider;
+import jalview.bin.ApplicationSingletonProvider.ApplicationSingletonI;
+
/**
* A singleton to hold metadata about feature attributes, keyed by a unique
* feature source identifier
* @author gmcarstairs
*
*/
-public class FeatureSources
+public class FeatureSources implements ApplicationSingletonI
{
- private static FeatureSources instance = new FeatureSources();
-
- private Map<String, FeatureSourceI> sources;
- /**
- * Answers the singleton instance of this class
- *
- * @return
- */
public static FeatureSources getInstance()
{
- return instance;
+ return (FeatureSources) ApplicationSingletonProvider
+ .getInstance(FeatureSources.class);
}
+ private Map<String, FeatureSourceI> sources;
+
private FeatureSources()
{
sources = new HashMap<>();
{
return true;
}
- SequenceOntologyI so = SequenceOntologyFactory.getInstance();
+ SequenceOntologyI so = SequenceOntologyFactory.getSequenceOntology();
for (String term : soTerm)
{
if (type.equals(term) || so.isA(type, term))
import jalview.datamodel.SequenceFeature;
import jalview.datamodel.SequenceI;
import jalview.io.gff.SequenceOntologyI;
+import jalview.util.Platform;
import java.util.ArrayList;
import java.util.List;
* or ENSMUST or similar for other species
* or CCDSnnnnn.nn with at least 3 digits
*/
- private static final Regex ACCESSION_REGEX = new Regex(
+ private static final Regex ACCESSION_REGEX = Platform.newRegex(
"(ENS([A-Z]{3}|)[TG][0-9]{11}$)" + "|" + "(CCDS[0-9.]{3,}$)");
/*
@Override
protected boolean retainFeature(SequenceFeature sf, String accessionId)
{
- if (SequenceOntologyFactory.getInstance().isA(sf.getType(),
+ if (SequenceOntologyFactory.getSequenceOntology().isA(sf.getType(),
SequenceOntologyI.CDS))
{
return false;
*/
package jalview.ext.ensembl;
-import jalview.datamodel.Alignment;
-import jalview.datamodel.AlignmentI;
-import jalview.datamodel.Sequence;
-import jalview.datamodel.SequenceFeature;
-import jalview.datamodel.SequenceI;
-import jalview.io.gff.SequenceOntologyI;
-import jalview.util.JSONUtils;
-import jalview.util.Platform;
-
-import java.io.BufferedReader;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import org.json.simple.parser.ParseException;
+import jalview.datamodel.Alignment;
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.Sequence;
+import jalview.datamodel.SequenceFeature;
+import jalview.datamodel.SequenceI;
+import jalview.io.gff.SequenceOntologyI;
+import jalview.util.JSONUtils;
+
/**
* A client for fetching and processing Ensembl feature data in GFF format by
* calling the overlap REST service
* accepts anything as we will attempt lookup of gene or
* transcript id or gene name
*/
- private static final Regex ACCESSION_REGEX = new Regex(".*");
+ private static final Regex ACCESSION_REGEX = Platform.newRegex(".*");
private static final EnsemblFeatureType[] FEATURES_TO_FETCH = {
EnsemblFeatureType.gene, EnsemblFeatureType.transcript,
@Override
protected boolean retainFeature(SequenceFeature sf, String accessionId)
{
- SequenceOntologyI so = SequenceOntologyFactory.getInstance();
+ SequenceOntologyI so = SequenceOntologyFactory.getSequenceOntology();
String type = sf.getType();
if (so.isA(type, SequenceOntologyI.GENE))
{
{
return new FeatureSettingsAdapter()
{
- SequenceOntologyI so = SequenceOntologyFactory.getInstance();
+ SequenceOntologyI so = SequenceOntologyFactory.getSequenceOntology();
@Override
public boolean isFeatureHidden(String type)
import jalview.datamodel.AlignmentI;
import jalview.datamodel.SequenceFeature;
import jalview.datamodel.SequenceI;
+import jalview.util.Platform;
import java.util.ArrayList;
import java.util.List;
* or ENSMUSP or similar for other species
* or CCDSnnnnn.nn with at least 3 digits
*/
- private static final Regex ACCESSION_REGEX = new Regex(
+ private static final Regex ACCESSION_REGEX = Platform.newRegex(
"(ENS([A-Z]{3}|)P[0-9]{11}$)" + "|" + "(CCDS[0-9.]{3,}$)");
/**
* for sequence_variant on reverse strand, have to convert the allele
* values to their complements
*/
- if (!forwardStrand && SequenceOntologyFactory.getInstance()
+ if (!forwardStrand && SequenceOntologyFactory.getSequenceOntology()
.isA(sf.getType(), SequenceOntologyI.SEQUENCE_VARIANT))
{
reverseComplementAlleles(copy);
public static boolean isTranscript(String featureType)
{
return SequenceOntologyI.NMD_TRANSCRIPT_VARIANT.equals(featureType)
- || SequenceOntologyFactory.getInstance().isA(featureType,
+ || SequenceOntologyFactory.getSequenceOntology().isA(featureType,
SequenceOntologyI.TRANSCRIPT);
}
}
import jalview.analysis.AlignmentUtils;
import jalview.bin.Cache;
import jalview.datamodel.DBRefSource;
+import jalview.util.Platform;
import jalview.ws.seqfetcher.DbSourceProxyImpl;
import com.stevesoft.pat.Regex;
* or ENSMUSP or similar for other species
* or CCDSnnnnn.nn with at least 3 digits
*/
- private static final Regex ACCESSION_REGEX = new Regex(
+ private static final Regex ACCESSION_REGEX = Platform.newRegex(
"(ENS([A-Z]{3}|)[GTEP]{1}[0-9]{11}$)" + "|"
+ "(CCDS[0-9.]{3,}$)");
*/
package jalview.ext.ensembl;
-import jalview.datamodel.AlignmentI;
-import jalview.datamodel.DBRefEntry;
-import jalview.util.DBRefUtils;
-import jalview.util.JSONUtils;
-
-import java.io.BufferedReader;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import org.json.simple.parser.ParseException;
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.DBRefEntry;
+import jalview.util.DBRefUtils;
+
/**
* A class to fetch cross-references from Ensembl by calling the /xrefs REST
* service
import java.util.Vector;
import javax.swing.SwingUtilities;
-
import org.jmol.adapter.smarter.SmarterJmolAdapter;
import org.jmol.api.JmolAppConsoleInterface;
import org.jmol.api.JmolSelectionListener;
import jalview.structures.models.AAStructureBindingModel;
import jalview.ws.dbsources.Pdb;
import javajs.util.BS;
-
public abstract class JalviewJmolBinding extends AAStructureBindingModel
implements JmolStatusListener, JmolSelectionListener,
ComponentListener
{
private String lastMessage;
+
/*
* when true, try to search the associated datamodel for sequences that are
* associated with any unknown structures in the Jmol view.
{
return null;
}
+
String cmd = command.getCommand();
jmolHistory(false);
if (lastCommand == null || !lastCommand.equals(cmd))
return null;
}
+
/**
* map between index of model filename returned from getPdbFile and the first
* index of models from this file in the viewer. Note - this is not trimmed -
jmolScript(cmd.toString());
jmolHistory(true);
+
}
private boolean debug = true;
setLoadingFromArchive(false);
}
+
protected IProgressIndicator getIProgressIndicator()
{
return null;
}
+
public void showHelp()
{
showUrl("http://wiki.jmol.org"
import com.sun.jersey.api.client.WebResource;
import com.sun.jersey.api.client.config.DefaultClientConfig;
+import jalview.bin.ApplicationSingletonProvider;
+import jalview.bin.ApplicationSingletonProvider.ApplicationSingletonI;
import jalview.datamodel.SequenceI;
import jalview.fts.api.FTSData;
import jalview.fts.api.FTSDataColumnI;
* @author tcnofoegbu
*/
public class PDBFTSRestClient extends FTSRestClient
- implements StructureFTSRestClientI
+ implements StructureFTSRestClientI,ApplicationSingletonI
{
private static FTSRestClientI instance = null;
public static final String PDB_SEARCH_ENDPOINT = "https://www.ebi.ac.uk/pdbe/search/pdb/select?";
+ public static FTSRestClientI getInstance()
+ {
+ return (FTSRestClientI) ApplicationSingletonProvider
+ .getInstance(PDBFTSRestClient.class);
+ }
protected PDBFTSRestClient()
{
}
System.out.println(uri);
ClientResponse clientResponse = null;
int responseStatus = -1;
+
// Get the JSON string from the response object or directly from the
// client (JavaScript)
Map<String, Object> jsonObj = null;
switch (responseStatus)
{
case 200:
-
if (isMocked())
{
responseString = mockQueries.get(uri.toString());
result = new ArrayList<FTSData>();
if (numFound > 0)
{
-
for (Iterator<Object> docIter = docs.iterator(); docIter.hasNext();)
{
Map<String, Object> doc = (Map<String, Object>) docIter.next();
searchResult.setNumberOfItemsFound(numFound);
searchResult.setResponseTime(queryTime);
searchResult.setSearchSummary(result);
-
} catch (ParseException e)
{
e.printStackTrace();
return "/fts/pdb_data_columns.txt";
}
- public static FTSRestClientI getInstance()
- {
- if (instance == null)
- {
- instance = new PDBFTSRestClient();
- }
- return instance;
- }
private Collection<FTSDataColumnI> allDefaultDisplayedStructureDataColumns;
}
return allDefaultDisplayedStructureDataColumns;
}
-
@Override
public String[] getPreferencesColumnsFor(PreferenceSource source)
{
package jalview.fts.service.uniprot;
+import jalview.bin.ApplicationSingletonProvider;
+import jalview.bin.ApplicationSingletonProvider.ApplicationSingletonI;
import jalview.bin.Cache;
import jalview.fts.api.FTSData;
import jalview.fts.api.FTSDataColumnI;
import com.sun.jersey.api.client.config.DefaultClientConfig;
public class UniProtFTSRestClient extends FTSRestClient
+implements ApplicationSingletonI
{
+
+public static FTSRestClientI getInstance()
+{
+return (FTSRestClientI) ApplicationSingletonProvider
+ .getInstance(UniProtFTSRestClient.class);
+}
+
private static final String DEFAULT_UNIPROT_DOMAIN = "https://www.uniprot.org";
static
Platform.addJ2SDirectDatabaseCall(DEFAULT_UNIPROT_DOMAIN);
}
- private static FTSRestClientI instance = null;
-
public final String uniprotSearchEndpoint;
- public UniProtFTSRestClient()
+ private UniProtFTSRestClient()
{
super();
uniprotSearchEndpoint = Cache.getDefault("UNIPROT_DOMAIN",
};
}
- public static FTSRestClientI getInstance()
- {
- if (instance == null)
- {
- instance = new UniProtFTSRestClient();
- }
- return instance;
- }
-
@Override
public String getColumnDataConfigFileName()
{
this.settings = defaults;
this.isComplexAlignFile = format.isComplexAlignFile();
init(viewport.hasHiddenRows(), viewport.hasHiddenColumns());
- dialog = JvOptionPane.newOptionDialog(Desktop.desktop);
+ dialog = JvOptionPane.newOptionDialog(Desktop.getDesktopPane());
}
/**
import java.util.Locale;
+import java.io.IOException;
+import java.util.HashSet;
+import java.util.Set;
+
+import javax.swing.JFileChooser;
+import javax.swing.JOptionPane;
+
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
+import java.awt.Dimension;
import java.awt.Rectangle;
import java.awt.Toolkit;
import java.awt.datatransfer.Clipboard;
import java.awt.print.PageFormat;
import java.awt.print.PrinterJob;
import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
import java.io.File;
import java.io.FileWriter;
-import java.io.IOException;
import java.io.PrintWriter;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collection;
import java.util.Deque;
import java.util.Enumeration;
import java.util.Hashtable;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.SwingUtilities;
+import javax.swing.event.InternalFrameAdapter;
+import javax.swing.event.InternalFrameEvent;
import ext.vamsas.ServiceHandle;
import jalview.analysis.AlignmentSorter;
import jalview.datamodel.SequenceI;
import jalview.gui.ColourMenuHelper.ColourChangeListener;
import jalview.gui.ViewSelectionMenu.ViewSetProvider;
+import jalview.hmmer.HMMAlign;
+import jalview.hmmer.HMMBuild;
+import jalview.hmmer.HMMERParamStore;
+import jalview.hmmer.HMMERPreset;
+import jalview.hmmer.HMMSearch;
+import jalview.hmmer.HmmerCommand;
+import jalview.hmmer.JackHMMER;
import jalview.io.AlignmentProperties;
import jalview.io.AnnotationFile;
import jalview.io.BackupFiles;
import jalview.viewmodel.ViewportRanges;
import jalview.ws.DBRefFetcher;
import jalview.ws.DBRefFetcher.FetchFinishedListenerI;
+import jalview.ws.ServiceChangeListener;
+import jalview.ws.WSDiscovererI;
+import jalview.ws.api.ServiceWithParameters;
import jalview.ws.jws1.Discoverer;
import jalview.ws.jws2.Jws2Discoverer;
-import jalview.ws.jws2.jabaws2.Jws2Instance;
+import jalview.ws.jws2.PreferredServiceRegistry;
+import jalview.ws.params.ArgumentI;
+import jalview.ws.params.ParamDatastoreI;
+import jalview.ws.params.WsParamSetI;
import jalview.ws.seqfetcher.DbSourceProxy;
+import jalview.ws.slivkaws.SlivkaWSDiscoverer;
+import java.io.IOException;
+import java.util.HashSet;
+import java.util.Set;
+
+import javax.swing.JFileChooser;
+import javax.swing.JOptionPane;
+
+import java.awt.BorderLayout;
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.Dimension;
+import java.awt.Rectangle;
+import java.awt.Toolkit;
+import java.awt.datatransfer.Clipboard;
+import java.awt.datatransfer.DataFlavor;
+import java.awt.datatransfer.StringSelection;
+import java.awt.datatransfer.Transferable;
+import java.awt.dnd.DnDConstants;
+import java.awt.dnd.DropTargetDragEvent;
+import java.awt.dnd.DropTargetDropEvent;
+import java.awt.dnd.DropTargetEvent;
+import java.awt.dnd.DropTargetListener;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.FocusAdapter;
+import java.awt.event.FocusEvent;
+import java.awt.event.ItemEvent;
+import java.awt.event.ItemListener;
+import java.awt.event.KeyAdapter;
+import java.awt.event.KeyEvent;
+import java.awt.event.MouseEvent;
+import java.awt.print.PageFormat;
+import java.awt.print.PrinterJob;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.PrintWriter;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Deque;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.List;
+import java.util.Vector;
+
+import javax.swing.ButtonGroup;
+import javax.swing.JCheckBoxMenuItem;
+import javax.swing.JComponent;
+import javax.swing.JEditorPane;
+import javax.swing.JInternalFrame;
+import javax.swing.JLabel;
+import javax.swing.JLayeredPane;
+import javax.swing.JMenu;
+import javax.swing.JMenuItem;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.SwingUtilities;
+import javax.swing.event.InternalFrameAdapter;
+import javax.swing.event.InternalFrameEvent;
+
+import ext.vamsas.ServiceHandle;
/**
* DOCUMENT ME!
* @version $Revision$
*/
@SuppressWarnings("serial")
-public class AlignFrame extends GAlignFrame implements DropTargetListener,
- IProgressIndicator, AlignViewControllerGuiI, ColourChangeListener
+public class AlignFrame extends GAlignFrame
+ implements DropTargetListener, IProgressIndicator,
+ AlignViewControllerGuiI, ColourChangeListener, ServiceChangeListener
{
+ public static int frameCount;
public static final int DEFAULT_WIDTH = 700;
public static final int DEFAULT_HEIGHT = 500;
*/
String fileName = null;
+ /**
+ * TODO: remove reference to 'FileObject' in AlignFrame - not correct mapping
+ */
File fileObject;
+ private int id;
+
+ private DataSourceType protocol ;
/**
* Creates a new AlignFrame object with specific width and height.
*
public AlignFrame(AlignmentI al, HiddenColumns hiddenColumns, int width,
int height, String sequenceSetId, String viewId)
{
+ id = (++frameCount);
setSize(width, height);
if (al.getDataset() == null)
viewport = new AlignViewport(al, hiddenColumns, sequenceSetId, viewId);
- alignPanel = new AlignmentPanel(this, viewport);
-
- addAlignmentPanel(alignPanel, true);
+ // JalviewJS needs to distinguish a new panel from an old one in init()
+ // alignPanel = new AlignmentPanel(this, viewport);
+ // addAlignmentPanel(alignPanel, true);
init();
}
{
viewport.hideSequence(hiddenSeqs);
}
- alignPanel = new AlignmentPanel(this, viewport);
- addAlignmentPanel(alignPanel, true);
+ // alignPanel = new AlignmentPanel(this, viewport);
+ // addAlignmentPanel(alignPanel, true);
init();
}
{
viewport = ap.av;
alignPanel = ap;
- addAlignmentPanel(ap, false);
+ // addAlignmentPanel(ap, false);
init();
}
*/
void init()
{
- // setBackground(Color.white); // BH 2019
+ boolean newPanel = (alignPanel == null);
+ viewport.setShowAutocalculatedAbove(isShowAutoCalculatedAbove());
+ if (newPanel)
+ {
+ if (Platform.isJS())
+ {
+ // need to set this up front if NOANNOTATION is
+ // used in conjunction with SHOWOVERVIEW.
+
+ // I have not determined if this is appropriate for
+ // Jalview/Java, as it means we are setting this flag
+ // for all subsequent AlignFrames. For now, at least,
+ // I am setting it to be JalviewJS-only.
+
+ boolean showAnnotation = Jalview.getInstance().getShowAnnotation();
+ viewport.setShowAnnotation(showAnnotation);
+ }
+ alignPanel = new AlignmentPanel(this, viewport);
+ }
+ addAlignmentPanel(alignPanel, newPanel);
+ // setBackground(Color.white); // BH 2019
if (!Jalview.isHeadlessMode())
{
progressBar = new ProgressBar(this.statusPanel, this.statusBar);
+ // JalviewJS options
+ statusPanel.setVisible(Jalview.getInstance().getShowStatus());
+ alignFrameMenuBar.setVisible(Jalview.getInstance().getAllowMenuBar());
}
avc = new jalview.controller.AlignViewController(this, viewport,
// modifyPID.setEnabled(false);
}
- String sortby = jalview.bin.Cache.getDefault("SORT_ALIGNMENT",
+ String sortby = jalview.bin.Cache.getDefault(Preferences.SORT_ALIGNMENT,
"No sort");
if (sortby.equals("Id"))
sortPairwiseMenuItem_actionPerformed(null);
}
- this.alignPanel.av
- .setShowAutocalculatedAbove(isShowAutoCalculatedAbove());
+ // BH see above
+ //
+ // this.alignPanel.av
+ // .setShowAutocalculatedAbove(isShowAutoCalculatedAbove());
setMenusFromViewport(viewport);
buildSortByAnnotationScoresMenu();
});
buildColourMenu();
- if (Desktop.desktop != null)
+ if (Desktop.getDesktopPane() != null)
{
this.setDropTarget(new java.awt.dnd.DropTarget(this, this));
+ addServiceListeners();
if (!Platform.isJS())
{
- addServiceListeners();
}
setGUINucleotide();
}
wrapMenuItem_actionPerformed(null);
}
- if (jalview.bin.Cache.getDefault("SHOW_OVERVIEW", false))
+ if (jalview.bin.Cache.getDefault(Preferences.SHOW_OVERVIEW, false))
{
this.overviewMenuItem_actionPerformed(null);
}
* @param format
* format of file
*/
+ @Deprecated
public void setFileName(String file, FileFormatI format)
{
fileName = file;
}
/**
+ *
+ * @param fileName
+ * @param file from SwingJS; may contain bytes -- for reload
+ * @param protocol from SwingJS; may be RELATIVE_URL
+ * @param format
+ */
+ public void setFile(String fileName, File file, DataSourceType protocol, FileFormatI format)
+ {
+ this.fileName = fileName;
+ this.fileObject = file;
+ this.protocol = protocol;
+ setFileFormat(format);
+ reload.setEnabled(true);
+ }
+
+ /**
* JavaScript will have this, maybe others. More dependable than a file name
* and maintains a reference to the actual bytes loaded.
*
switch (evt.getKeyCode())
{
- case 27: // escape key
- deselectAllSequenceMenuItem_actionPerformed(null);
+ case KeyEvent.VK_ESCAPE: // escape key
+ // alignPanel.deselectAllSequences();
+ alignPanel.deselectAllSequences();
break;
case KeyEvent.VK_LEFT:
if (evt.isAltDown() || !viewport.cursorMode)
{
- viewport.firePropertyChange("alignment", null,
- viewport.getAlignment().getSequences());
+ viewport.notifyAlignment();
}
break;
case KeyEvent.VK_RIGHT:
if (evt.isAltDown() || !viewport.cursorMode)
{
- viewport.firePropertyChange("alignment", null,
- viewport.getAlignment().getSequences());
+ viewport.notifyAlignment();
}
break;
}
{
ap.av.getAlignment().padGaps();
}
- ap.av.updateConservation(ap);
- ap.av.updateConsensus(ap);
- ap.av.updateStrucConsensus(ap);
+ if (Jalview.getInstance().getStartCalculations())
+ {
+ ap.av.updateConservation(ap);
+ ap.av.updateConsensus(ap);
+ ap.av.updateStrucConsensus(ap);
+ ap.av.initInformationWorker(ap);
+ }
}
}
return viewport;
}
+ @Override
+ public void servicesChanged(WSDiscovererI discoverer,
+ Collection<? extends ServiceWithParameters> services)
+ {
+ buildWebServicesMenu();
+ }
/* Set up intrinsic listeners for dynamically generated GUI bits. */
private void addServiceListeners()
{
- final java.beans.PropertyChangeListener thisListener;
- Desktop.instance.addJalviewPropertyChangeListener("services",
- thisListener = new java.beans.PropertyChangeListener()
- {
- @Override
- public void propertyChange(PropertyChangeEvent evt)
- {
- // // System.out.println("Discoverer property change.");
- // if (evt.getPropertyName().equals("services"))
- {
- SwingUtilities.invokeLater(new Runnable()
- {
-
- @Override
- public void run()
- {
- System.err.println(
- "Rebuild WS Menu for service change");
- BuildWebServiceMenu();
- }
-
- });
- }
- }
- });
- addInternalFrameListener(new javax.swing.event.InternalFrameAdapter()
+ if (Cache.getDefault("SHOW_SLIVKA_SERVICES", true))
+ {
+ WSDiscovererI discoverer = SlivkaWSDiscoverer.getInstance();
+ discoverer.addServiceChangeListener(this);
+ }
+ if (Cache.getDefault("SHOW_JWS2_SERVICES", true))
{
+ WSDiscovererI discoverer = Jws2Discoverer.getInstance();
+ discoverer.addServiceChangeListener(this);
+ }
+ // legacy event listener for compatibility with jws1
+ PropertyChangeListener legacyListener = (changeEvent) -> {
+ buildWebServicesMenu();
+ };
+ Desktop.getInstance().addJalviewPropertyChangeListener("services",legacyListener);
+
+ addInternalFrameListener(new InternalFrameAdapter() {
@Override
- public void internalFrameClosed(
- javax.swing.event.InternalFrameEvent evt)
- {
- // System.out.println("deregistering discoverer listener");
- Desktop.instance.removeJalviewPropertyChangeListener("services",
- thisListener);
+ public void internalFrameClosed(InternalFrameEvent e) {
+ System.out.println("deregistering discoverer listener");
+ SlivkaWSDiscoverer.getInstance().removeServiceChangeListener(AlignFrame.this);
+ Jws2Discoverer.getInstance().removeServiceChangeListener(AlignFrame.this);
+ Desktop.getInstance().removeJalviewPropertyChangeListener("services", legacyListener);
closeMenuItem_actionPerformed(true);
}
});
- // Finally, build the menu once to get current service state
- new Thread(new Runnable()
- {
- @Override
- public void run()
- {
- BuildWebServiceMenu();
- }
- }).start();
+ buildWebServicesMenu();
}
/**
scaleLeft.setVisible(av.getWrapAlignment());
scaleRight.setVisible(av.getWrapAlignment());
annotationPanelMenuItem.setState(av.isShowAnnotation());
- /*
- * Show/hide annotations only enabled if annotation panel is shown
- */
- showAllSeqAnnotations.setEnabled(annotationPanelMenuItem.getState());
- hideAllSeqAnnotations.setEnabled(annotationPanelMenuItem.getState());
- showAllAlAnnotations.setEnabled(annotationPanelMenuItem.getState());
- hideAllAlAnnotations.setEnabled(annotationPanelMenuItem.getState());
+ // Show/hide annotations only enabled if annotation panel is shown
+ syncAnnotationMenuItems(av.isShowAnnotation());
viewBoxesMenuItem.setSelected(av.getShowBoxes());
viewTextMenuItem.setSelected(av.getShowText());
showNonconservedMenuItem.setSelected(av.getShowUnconserved());
showConsensusHistogram.setSelected(av.isShowConsensusHistogram());
showSequenceLogo.setSelected(av.isShowSequenceLogo());
normaliseSequenceLogo.setSelected(av.isNormaliseSequenceLogo());
+ showInformationHistogram.setSelected(av.isShowInformationHistogram());
+ showHMMSequenceLogo.setSelected(av.isShowHMMSequenceLogo());
+ normaliseHMMSequenceLogo.setSelected(av.isNormaliseHMMSequenceLogo());
ColourMenuHelper.setColourSelected(colourMenu,
av.getGlobalColourScheme());
applyToAllGroups.setState(av.getColourAppliesToAllGroups());
showNpFeatsMenuitem.setSelected(av.isShowNPFeats());
showDbRefsMenuitem.setSelected(av.isShowDBRefs());
- autoCalculate.setSelected(av.autoCalculateConsensus);
+ autoCalculate
+ .setSelected(av.getAutoCalculateConsensusAndConservation());
sortByTree.setSelected(av.sortByTree);
listenToViewSelections.setSelected(av.followSelection);
{
progressBar.setProgressBar(message, id);
}
+
+ @Override
+ public void removeProgressBar(long id)
+ {
+ progressBar.removeProgressBar(id);
+ }
@Override
public void registerHandler(final long id,
@Override
public void addFromFile_actionPerformed(ActionEvent e)
{
- Desktop.instance.inputLocalFileMenuItem_actionPerformed(viewport);
+ Desktop.getInstance().inputLocalFileMenuItem_actionPerformed(viewport);
}
@Override
- public void reload_actionPerformed(ActionEvent e)
+ public void hmmBuild_actionPerformed(boolean withDefaults)
{
- if (fileName != null)
+ if (!alignmentIsSufficient(1))
{
- // TODO: JAL-1108 - ensure all associated frames are closed regardless of
- // originating file's format
- // TODO: work out how to recover feature settings for correct view(s) when
- // file is reloaded.
- if (FileFormat.Jalview.equals(currentFileFormat))
- {
- JInternalFrame[] frames = Desktop.desktop.getAllFrames();
- for (int i = 0; i < frames.length; i++)
+ return;
+ }
+
+ /*
+ * get default parameters, and optionally show a dialog
+ * to allow them to be modified
+ */
+ ParamDatastoreI store = HMMERParamStore.forBuild(viewport);
+ List<ArgumentI> args = store.getServiceParameters();
+
+ if (!withDefaults)
+ {
+ WsParamSetI set = new HMMERPreset();
+ WsJobParameters params = new WsJobParameters(store, set, args);
+ params.showRunDialog().thenAccept((startJob) -> {
+ if (startJob)
{
- if (frames[i] instanceof AlignFrame && frames[i] != this
- && ((AlignFrame) frames[i]).fileName != null
- && ((AlignFrame) frames[i]).fileName.equals(fileName))
- {
- try
- {
- frames[i].setSelected(true);
- Desktop.instance.closeAssociatedWindows();
- } catch (java.beans.PropertyVetoException ex)
- {
- }
- }
+ var args2 = params.getJobParams();
+ new Thread(new HMMBuild(this, args2)).start();
+ }
+ });
+ }
+ else
+ {
+ new Thread(new HMMBuild(this, args)).start();
+ }
+ }
+
+ @Override
+ public void hmmAlign_actionPerformed(boolean withDefaults)
+ {
+ if (!(checkForHMM() && alignmentIsSufficient(2)))
+ {
+ return;
+ }
+
+ /*
+ * get default parameters, and optionally show a dialog
+ * to allow them to be modified
+ */
+ ParamDatastoreI store = HMMERParamStore.forAlign(viewport);
+ List<ArgumentI> args = store.getServiceParameters();
+ if (!withDefaults)
+ {
+ WsParamSetI set = new HMMERPreset();
+ WsJobParameters params = new WsJobParameters(store, set, args);
+ params.showRunDialog().thenAccept((startJob) -> {
+ if (startJob)
+ {
+ var args2 = params.getJobParams();
+ new Thread(new HMMAlign(this, args2)).start();
}
- Desktop.instance.closeAssociatedWindows();
+ });
+ }
+ else
+ {
+ new Thread(new HMMAlign(this, args)).start();
+ }
+ }
+
+ @Override
+ public void hmmSearch_actionPerformed(boolean withDefaults)
+ {
+ if (!checkForHMM())
+ {
+ return;
+ }
+
+ /*
+ * get default parameters, and (if requested) show
+ * dialog to allow modification
+ */
+ ParamDatastoreI store = HMMERParamStore.forSearch(viewport);
+ List<ArgumentI> args = store.getServiceParameters();
+
+ if (!withDefaults)
+ {
+ WsParamSetI set = new HMMERPreset();
+ WsJobParameters params = new WsJobParameters(store, set, args);
+ params.showRunDialog().thenAccept((startJob) -> {
+ if (startJob)
+ {
+ var args2 = params.getJobParams();
+ new Thread(new HMMSearch(this, args2)).start();
+ alignPanel.repaint();
+ }
+ });
+ }
+ else
+ {
+ new Thread(new HMMSearch(this, args)).start();
+ alignPanel.repaint();
+ }
+ }
+
+ @Override
+ public void jackhmmer_actionPerformed(boolean withDefaults)
+ {
+
+ /*
+ * get default parameters, and (if requested) show
+ * dialog to allow modification
+ */
+
+ ParamDatastoreI store = HMMERParamStore.forJackhmmer(viewport);
+ List<ArgumentI> args = store.getServiceParameters();
+
+ if (!withDefaults)
+ {
+ WsParamSetI set = new HMMERPreset();
+ WsJobParameters params = new WsJobParameters(store, set, args);
+ params.showRunDialog().thenAccept((startJob) -> {
+ if (startJob)
+ {
+ var args2 = params.getJobParams();
+ new Thread(new JackHMMER(this, args2)).start();
+ alignPanel.repaint();
+ }
+ });
+ }
+ else
+ {
+ new Thread(new JackHMMER(this, args)).start();
+ alignPanel.repaint();
+ }
+ }
+
+ /**
+ * Checks if the alignment has at least one hidden Markov model, if not shows
+ * a dialog advising to run hmmbuild or load an HMM profile
+ *
+ * @return
+ */
+ private boolean checkForHMM()
+ {
+ if (viewport.getAlignment().getHmmSequences().isEmpty())
+ {
+ JOptionPane.showMessageDialog(this,
+ MessageManager.getString("warn.no_hmm"));
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ protected void filterByEValue_actionPerformed()
+ {
+ viewport.filterByEvalue(inputDouble("Enter E-Value Cutoff"));
+ }
- FileLoader loader = new FileLoader();
- DataSourceType protocol = HttpUtils.startsWithHttpOrHttps(fileName)
- ? DataSourceType.URL
- : DataSourceType.FILE;
- loader.LoadFile(viewport, fileName, protocol, currentFileFormat);
+ @Override
+ protected void filterByScore_actionPerformed()
+ {
+ viewport.filterByScore(inputDouble("Enter Bit Score Threshold"));
+ }
+
+ private double inputDouble(String message)
+ {
+ String str = null;
+ Double d = null;
+ while (d == null || d <= 0)
+ {
+ str = JOptionPane.showInputDialog(this.alignPanel, message);
+ try
+ {
+ d = Double.valueOf(str);
+ } catch (NumberFormatException e)
+ {
+ }
+ }
+ return d;
+ }
+
+ /**
+ * Checks if the alignment contains the required number of sequences.
+ *
+ * @param required
+ * @return
+ */
+ public boolean alignmentIsSufficient(int required)
+ {
+ if (getViewport().getSequenceSelection().length < required)
+ {
+ JOptionPane.showMessageDialog(this,
+ MessageManager.getString("label.not_enough_sequences"));
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Opens a file browser and adds the selected file, if in Fasta, Stockholm or
+ * Pfam format, to the list held under preference key "HMMSEARCH_DBS" (as a
+ * comma-separated list)
+ */
+ @Override
+ public void addDatabase_actionPerformed() throws IOException
+ {
+ if (Cache.getProperty(Preferences.HMMSEARCH_DBS) == null)
+ {
+ Cache.setProperty(Preferences.HMMSEARCH_DBS, "");
+ }
+
+ String path = openFileChooser(false);
+ if (path != null && new File(path).exists())
+ {
+ IdentifyFile identifier = new IdentifyFile();
+ FileFormatI format = identifier.identify(path, DataSourceType.FILE);
+ if (format == FileFormat.Fasta || format == FileFormat.Stockholm
+ || format == FileFormat.Pfam)
+ {
+ String currentDbPaths = Cache
+ .getProperty(Preferences.HMMSEARCH_DBS);
+ currentDbPaths += Preferences.COMMA + path;
+ Cache.setProperty(Preferences.HMMSEARCH_DBS, currentDbPaths);
}
else
{
- Rectangle bounds = this.getBounds();
+ JOptionPane.showMessageDialog(this,
+ MessageManager.getString("warn.invalid_format"));
+ }
+ }
+ }
- FileLoader loader = new FileLoader();
+ /**
+ * Opens a file chooser, optionally restricted to selecting folders
+ * (directories) only. Answers the path to the selected file or folder, or
+ * null if none is chosen.
+ *
+ * @param
+ * @return
+ */
+ protected String openFileChooser(boolean forFolder)
+ {
+ // TODO duplicates GPreferences method - relocate to JalviewFileChooser?
+ String choice = null;
+ JFileChooser chooser = new JFileChooser();
+ if (forFolder)
+ {
+ chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
+ }
+ chooser.setDialogTitle(
+ MessageManager.getString("label.open_local_file"));
+ chooser.setToolTipText(MessageManager.getString("action.open"));
- AlignFrame newframe = null;
+ int value = chooser.showOpenDialog(this);
- if (fileObject == null)
- {
+ if (value == JFileChooser.APPROVE_OPTION)
+ {
+ choice = chooser.getSelectedFile().getPath();
+ }
+ return choice;
+ }
- DataSourceType protocol = HttpUtils.startsWithHttpOrHttps(
- fileName) ? DataSourceType.URL : DataSourceType.FILE;
- newframe = loader.LoadFileWaitTillLoaded(fileName, protocol,
- currentFileFormat);
- }
- else
+ @Override
+ public void reload_actionPerformed(ActionEvent e)
+ {
+ if (fileName == null && fileObject == null)
+ {
+ return;
+ }
+ // TODO: JAL-1108 - ensure all associated frames are closed regardless of
+ // originating file's format
+ // TODO: work out how to recover feature settings for correct view(s) when
+ // file is reloaded.
+ if (FileFormat.Jalview.equals(currentFileFormat))
+ {
+ JInternalFrame[] frames = Desktop.getDesktopPane().getAllFrames();
+ for (int i = 0; i < frames.length; i++)
+ {
+ if (frames[i] instanceof AlignFrame && frames[i] != this
+ && ((AlignFrame) frames[i]).fileName != null
+ && ((AlignFrame) frames[i]).fileName.equals(fileName))
{
- newframe = loader.LoadFileWaitTillLoaded(fileObject,
- DataSourceType.FILE, currentFileFormat);
+ try
+ {
+ frames[i].setSelected(true);
+ Desktop.getInstance().closeAssociatedWindows();
+ } catch (java.beans.PropertyVetoException ex)
+ {
+ }
}
- newframe.setBounds(bounds);
- if (featureSettings != null && featureSettings.isShowing())
+ }
+ Desktop.getInstance().closeAssociatedWindows();
+
+ FileLoader loader = new FileLoader();
+ loader.LoadFile(viewport, (fileObject == null ? fileName : fileObject), protocol, currentFileFormat);
+ }
+ else
+ {
+ Rectangle bounds = this.getBounds();
+
+ FileLoader loader = new FileLoader();
+
+ AlignFrame newframe = null;
+
+ if (fileObject == null)
+ {
+ newframe = loader.LoadFileWaitTillLoaded(fileName, protocol,
+ currentFileFormat);
+ }
+ else
+ {
+ newframe = loader.LoadFileWaitTillLoaded(fileObject,
+ DataSourceType.FILE, currentFileFormat);
+ }
+
+ newframe.setBounds(bounds);
+ if (featureSettings != null && featureSettings.isShowing())
+ {
+ final Rectangle fspos = featureSettings.frame.getBounds();
+ // TODO: need a 'show feature settings' function that takes bounds -
+ // need to refactor Desktop.addFrame
+ newframe.featureSettings_actionPerformed(null);
+ final FeatureSettings nfs = newframe.featureSettings;
+ SwingUtilities.invokeLater(new Runnable()
{
- final Rectangle fspos = featureSettings.frame.getBounds();
- // TODO: need a 'show feature settings' function that takes bounds -
- // need to refactor Desktop.addFrame
- newframe.featureSettings_actionPerformed(null);
- final FeatureSettings nfs = newframe.featureSettings;
- SwingUtilities.invokeLater(new Runnable()
+ @Override
+ public void run()
{
- @Override
- public void run()
- {
- nfs.frame.setBounds(fspos);
- }
- });
- this.featureSettings.close();
- this.featureSettings = null;
- }
- this.closeMenuItem_actionPerformed(true);
+ nfs.frame.setBounds(fspos);
+ }
+ });
+ this.featureSettings.close();
+ this.featureSettings = null;
}
+ this.closeMenuItem_actionPerformed(true);
}
}
@Override
public void addFromText_actionPerformed(ActionEvent e)
{
- Desktop.instance
+ Desktop.getInstance()
.inputTextboxMenuItem_actionPerformed(viewport.getAlignPanel());
}
@Override
public void addFromURL_actionPerformed(ActionEvent e)
{
- Desktop.instance.inputURLMenuItem_actionPerformed(viewport);
+ Desktop.getInstance().inputURLMenuItem_actionPerformed(viewport);
}
@Override
// todo is this (2005) test now obsolete - value is never null?
while (currentFileFormat == null)
{
- JvOptionPane.showInternalMessageDialog(Desktop.desktop,
+ JvOptionPane.showInternalMessageDialog(Desktop.getDesktopPane(),
MessageManager
.getString("label.select_file_format_before_saving"),
MessageManager.getString("label.file_format_not_specified"),
}
lastSaveSuccessful = new Jalview2XML().saveAlignment(this, file,
shortName);
-
statusBar.setText(MessageManager.formatMessage(
"label.successfully_saved_to_file_in_format", new Object[]
- { file, format }));
-
+ { fileName, format }));
return;
}
bjs.exportHTML(null);
}
+ // ??
public void createImageMap(File file, String image)
{
alignPanel.makePNGImageMap(file, image);
@Override
public void associatedData_actionPerformed(ActionEvent e)
+ throws IOException, InterruptedException
{
final JalviewFileChooser chooser = new JalviewFileChooser(
jalview.bin.Cache.getProperty("LAST_DIRECTORY"));
// && viewport.getColumnSelection().getHiddenColumns() != null &&
// viewport.getColumnSelection()
// .getHiddenColumns().size() > 0);
- originalSource.firePropertyChange("alignment", null,
- originalSource.getAlignment().getSequences());
+ originalSource.notifyAlignment();
}
}
// && viewport.getColumnSelection().getHiddenColumns() != null &&
// viewport.getColumnSelection()
// .getHiddenColumns().size() > 0);
- originalSource.firePropertyChange("alignment", null,
- originalSource.getAlignment().getSequences());
+ originalSource.notifyAlignment();
}
}
{
return;
}
-
// TODO: JAL-3733 - add an event to the undo buffer for this !
-
viewport.getAlignment().moveSelectedSequencesByOne(sg,
viewport.getHiddenRepSequences(), up);
alignPanel.paintAlignment(true, false);
StringSelection ss = new StringSelection(output);
+ Desktop d = Desktop.getInstance();
try
{
- jalview.gui.Desktop.internalCopy = true;
+ d.internalCopy = true;
// Its really worth setting the clipboard contents
// to empty before setting the large StringSelection!!
Toolkit.getDefaultToolkit().getSystemClipboard()
.setContents(new StringSelection(""), null);
Toolkit.getDefaultToolkit().getSystemClipboard().setContents(ss,
- Desktop.instance);
+ d);
} catch (OutOfMemoryError er)
{
new OOMWarning("copying region", er);
hiddenCutoff, hiddenOffset);
}
- Desktop.jalviewClipboard = new Object[] { seqs,
+ d.jalviewClipboard = new Object[] { seqs,
viewport.getAlignment().getDataset(), hiddenColumns };
setStatus(MessageManager.formatMessage(
"label.copied_sequences_to_clipboard", new Object[]
*
* @param e
* DOCUMENT ME!
+ * @throws InterruptedException
+ * @throws IOException
*/
@Override
protected void pasteNew_actionPerformed(ActionEvent e)
+ throws IOException, InterruptedException
{
paste(true);
}
*
* @param e
* DOCUMENT ME!
+ * @throws InterruptedException
+ * @throws IOException
*/
@Override
protected void pasteThis_actionPerformed(ActionEvent e)
+ throws IOException, InterruptedException
{
paste(false);
}
*
* @param newAlignment
* true to paste to a new alignment, otherwise add to this.
+ * @throws InterruptedException
+ * @throws IOException
*/
- void paste(boolean newAlignment)
+ void paste(boolean newAlignment) throws IOException, InterruptedException
{
boolean externalPaste = true;
try
boolean annotationAdded = false;
AlignmentI alignment = null;
- if (Desktop.jalviewClipboard != null)
+ Desktop d = Desktop.getInstance();
+
+ if (d.jalviewClipboard != null)
{
// The clipboard was filled from within Jalview, we must use the
// sequences
// And dataset from the copied alignment
- SequenceI[] newseq = (SequenceI[]) Desktop.jalviewClipboard[0];
+ SequenceI[] newseq = (SequenceI[]) d.jalviewClipboard[0];
// be doubly sure that we create *new* sequence objects.
sequences = new SequenceI[newseq.length];
for (int i = 0; i < newseq.length; i++)
if (newAlignment)
{
- if (Desktop.jalviewClipboard != null)
+ if (d.jalviewClipboard != null)
{
// dataset is inherited
- alignment.setDataset((Alignment) Desktop.jalviewClipboard[1]);
+ alignment.setDataset((Alignment) d.jalviewClipboard[1]);
}
else
{
alignment = viewport.getAlignment();
alwidth = alignment.getWidth() + 1;
// decide if we need to import sequences from an existing dataset
- boolean importDs = Desktop.jalviewClipboard != null
- && Desktop.jalviewClipboard[1] != alignment.getDataset();
+ boolean importDs = d.jalviewClipboard != null
+ && d.jalviewClipboard[1] != alignment.getDataset();
// importDs==true instructs us to copy over new dataset sequences from
// an existing alignment
Vector<SequenceI> newDs = (importDs) ? new Vector<>() : null; // used to
}
buildSortByAnnotationScoresMenu();
}
- viewport.firePropertyChange("alignment", null,
- alignment.getSequences());
+ viewport.notifyAlignment();
if (alignPanels != null)
{
for (AlignmentPanel ap : alignPanels)
DEFAULT_HEIGHT);
String newtitle = new String("Copied sequences");
- if (Desktop.jalviewClipboard != null
- && Desktop.jalviewClipboard[2] != null)
+ if (d.jalviewClipboard != null && d.jalviewClipboard[2] != null)
{
- HiddenColumns hc = (HiddenColumns) Desktop.jalviewClipboard[2];
+ HiddenColumns hc = (HiddenColumns) d.jalviewClipboard[2];
af.viewport.setHiddenColumns(hc);
}
DEFAULT_HEIGHT);
String newtitle = new String("Flanking alignment");
- if (Desktop.jalviewClipboard != null
- && Desktop.jalviewClipboard[2] != null)
+ Desktop d = Desktop.getInstance();
+ if (d.jalviewClipboard != null && d.jalviewClipboard[2] != null)
{
- HiddenColumns hc = (HiddenColumns) Desktop.jalviewClipboard[2];
+ HiddenColumns hc = (HiddenColumns) d.jalviewClipboard[2];
af.viewport.setHiddenColumns(hc);
}
Runnable okAction = new Runnable()
{
+
@Override
public void run()
{
viewport.sendSelection();
viewport.getAlignment().deleteGroup(sg);
- viewport.firePropertyChange("alignment", null,
- viewport.getAlignment().getSequences());
+ viewport.notifyAlignment();
+
if (viewport.getAlignment().getHeight() < 1)
{
try
} catch (Exception ex)
{
}
+ } else {
+ updateAll(null);
}
}
};
+ 1) == viewport.getAlignment().getWidth()) ? true : false;
if (wholeHeight && wholeWidth)
{
- JvOptionPane dialog = JvOptionPane.newOptionDialog(Desktop.desktop);
+ JvOptionPane dialog = JvOptionPane
+ .newOptionDialog(Desktop.getDesktopPane());
dialog.setResponseHandler(0, okAction); // 0 = OK_OPTION
Object[] options = new Object[] {
MessageManager.getString("action.ok"),
{
if (avc.deleteGroups())
{
- PaintRefresher.Refresh(this, viewport.getSequenceSetId());
- alignPanel.updateAnnotation();
+ updateAll(viewport.getSequenceSetId());
+ }
+ }
+
+ private void updateAll(String id)
+ {
+ if (id == null)
+ {
+ // this will force a non-fast repaint of both the IdPanel and SeqPanel
+ alignPanel.getIdPanel().getIdCanvas().setNoFastPaint();
+ alignPanel.getSeqPanel().seqCanvas.setNoFastPaint();
+ alignPanel.repaint();
+ }
+ else
+ {
+ // original version
+ PaintRefresher.Refresh(this, id);
alignPanel.paintAlignment(true, true);
}
+ alignPanel.updateAnnotation();
}
/**
@Override
public void selectAllSequenceMenuItem_actionPerformed(ActionEvent e)
{
- SequenceGroup sg = new SequenceGroup(
- viewport.getAlignment().getSequences());
-
- sg.setEndRes(viewport.getAlignment().getWidth() - 1);
- viewport.setSelectionGroup(sg);
- viewport.isSelectionGroupChanged(true);
- viewport.sendSelection();
- // JAL-2034 - should delegate to
- // alignPanel to decide if overview needs
- // updating.
- alignPanel.paintAlignment(false, false);
- PaintRefresher.Refresh(alignPanel, viewport.getSequenceSetId());
+ alignPanel.selectAllSequences();
}
/**
@Override
public void deselectAllSequenceMenuItem_actionPerformed(ActionEvent e)
{
- if (viewport.cursorMode)
- {
- alignPanel.getSeqPanel().keyboardNo1 = null;
- alignPanel.getSeqPanel().keyboardNo2 = null;
- }
- viewport.setSelectionGroup(null);
- viewport.getColumnSelection().clear();
- viewport.setSearchResults(null);
- alignPanel.getIdPanel().getIdCanvas().searchResults = null;
- // JAL-2034 - should delegate to
- // alignPanel to decide if overview needs
- // updating.
- alignPanel.paintAlignment(false, false);
- PaintRefresher.Refresh(alignPanel, viewport.getSequenceSetId());
- viewport.sendSelection();
+ alignPanel.deselectAllSequences();
}
/**
if (sg == null)
{
- selectAllSequenceMenuItem_actionPerformed(null);
+ alignPanel.selectAllSequences();
return;
}
}
}
- viewport.firePropertyChange("alignment", null,
- viewport.getAlignment().getSequences());
+ viewport.notifyAlignment();
}
}
// if (viewport.hasHiddenColumns)
// viewport.getColumnSelection().compensateForEdits(shifts);
ranges.setStartRes(seq.findIndex(startRes) - 1);
- viewport.firePropertyChange("alignment", null,
- viewport.getAlignment().getSequences());
+ viewport.notifyAlignment();
}
viewport.getRanges().setStartRes(seq.findIndex(startRes) - 1);
- viewport.firePropertyChange("alignment", null,
- viewport.getAlignment().getSequences());
+ viewport.notifyAlignment();
}
public void padGapsMenuitem_actionPerformed(ActionEvent e)
{
viewport.setPadGaps(padGapsMenuitem.isSelected());
- viewport.firePropertyChange("alignment", null,
- viewport.getAlignment().getSequences());
+ viewport.notifyAlignment();
}
/**
@Override
public void gatherViews_actionPerformed(ActionEvent e)
{
- Desktop.instance.gatherViews(this);
+ Desktop.getInstance().gatherViews(this);
}
/**
{
final boolean setVisible = annotationPanelMenuItem.isSelected();
viewport.setShowAnnotation(setVisible);
- this.showAllSeqAnnotations.setEnabled(setVisible);
- this.hideAllSeqAnnotations.setEnabled(setVisible);
- this.showAllAlAnnotations.setEnabled(setVisible);
- this.hideAllAlAnnotations.setEnabled(setVisible);
+ syncAnnotationMenuItems(setVisible);
alignPanel.updateLayout();
+ repaint();
+ SwingUtilities.invokeLater(new Runnable() {
+
+ @Override
+ public void run()
+ {
+ alignPanel.updateScrollBarsFromRanges();
+ }
+
+ });
+ }
+
+ private void syncAnnotationMenuItems(boolean setVisible)
+ {
+ showAllSeqAnnotations.setEnabled(setVisible);
+ hideAllSeqAnnotations.setEnabled(setVisible);
+ showAllAlAnnotations.setEnabled(setVisible);
+ hideAllAlAnnotations.setEnabled(setVisible);
}
@Override
JLabel textLabel = new JLabel();
textLabel.setText(content);
textLabel.setBackground(Color.WHITE);
-
pane = new JPanel(new BorderLayout());
((JPanel) pane).setOpaque(true);
pane.setBackground(Color.WHITE);
}
JInternalFrame frame = new JInternalFrame();
- final OverviewPanel overview = new OverviewPanel(alignPanel);
+ // BH 2019.07.26 we allow for an embedded
+ // undecorated overview with defined size
+ frame.setName(Platform.getAppID("overview"));
+ //
+ Dimension dim = Platform.getDimIfEmbedded(frame, -1, -1);
+ if (dim != null && dim.width == 0)
+ {
+ dim = null; // hidden, not embedded
+ }
+ OverviewPanel overview = new OverviewPanel(alignPanel, dim);
frame.setContentPane(overview);
+ if (dim == null)
+ {
+ dim = new Dimension();
+ // was frame.getSize(), but that is 0,0 at this point;
+ }
+ else
+ {
+ // we are imbedding, and so we have an undecorated frame
+ // and we can set the the frame dimensions accordingly.
+ }
+ // allowing for unresizable option using, style="resize:none"
+ boolean resizable = (Platform.getEmbeddedAttribute(frame,
+ "resize") != "none");
Desktop.addInternalFrame(frame, MessageManager
.formatMessage("label.overview_params", new Object[]
- { this.getTitle() }), true, frame.getWidth(), frame.getHeight(),
- true, true);
+ { this.getTitle() }), Desktop.FRAME_MAKE_VISIBLE, dim.width,
+ dim.height, resizable, Desktop.FRAME_ALLOW_ANY_SIZE);
frame.pack();
frame.setLayer(JLayeredPane.PALETTE_LAYER);
frame.addInternalFrameListener(
alignPanel.paintAlignment(true, false);
}
+ @Override
+ public void sortEValueMenuItem_actionPerformed(ActionEvent e)
+ {
+ SequenceI[] oldOrder = viewport.getAlignment().getSequencesArray();
+ AlignmentSorter.sortByEValue(viewport.getAlignment());
+ addHistoryItem(new OrderCommand("Group Sort", oldOrder,
+ viewport.getAlignment()));
+ alignPanel.paintAlignment(true, false);
+
+ }
+
+ @Override
+ public void sortBitScoreMenuItem_actionPerformed(ActionEvent e)
+ {
+ SequenceI[] oldOrder = viewport.getAlignment().getSequencesArray();
+ AlignmentSorter.sortByBitScore(viewport.getAlignment());
+ addHistoryItem(new OrderCommand("Group Sort", oldOrder,
+ viewport.getAlignment()));
+ alignPanel.paintAlignment(true, false);
+
+ }
/**
* DOCUMENT ME!
*
@Override
public void autoCalculate_actionPerformed(ActionEvent e)
{
- viewport.autoCalculateConsensus = autoCalculate.isSelected();
- if (viewport.autoCalculateConsensus)
+ viewport.setAutoCalculateConsensusAndConservation(
+ autoCalculate.isSelected());
+ if (viewport.getAutoCalculateConsensusAndConservation())
{
- viewport.firePropertyChange("alignment", null,
- viewport.getAlignment().getSequences());
+ viewport.notifyAlignment();
}
}
{
if (_s.getLength() < sg.getEndRes())
{
- JvOptionPane.showMessageDialog(Desktop.desktop,
+ JvOptionPane.showMessageDialog(Desktop.getDesktopPane(),
MessageManager.getString(
"label.selected_region_to_tree_may_only_contain_residues_or_gaps"),
MessageManager.getString(
frameTitle += this.title;
- Desktop.addInternalFrame(tp, frameTitle, 600, 500);
+ Dimension dim = Platform.getDimIfEmbedded(tp, 600, 500);
+ Desktop.addInternalFrame(tp, frameTitle, dim.width, dim.height);
}
/**
}
if (viewport.getAlignment().getAlignmentAnnotation()
- .hashCode() != _annotationScoreVectorHash)
+ .hashCode() == _annotationScoreVectorHash)
{
- sortByAnnotScore.removeAll();
- // almost certainly a quicker way to do this - but we keep it simple
- Hashtable<String, String> scoreSorts = new Hashtable<>();
- AlignmentAnnotation aann[];
- for (SequenceI sqa : viewport.getAlignment().getSequences())
+ return;
+ }
+
+ sortByAnnotScore.removeAll();
+ Set<String> scoreSorts = new HashSet<>();
+ for (SequenceI sqa : viewport.getAlignment().getSequences())
+ {
+ AlignmentAnnotation[] anns = sqa.getAnnotation();
+ for (int i = 0; anns != null && i < anns.length; i++)
{
- aann = sqa.getAnnotation();
- for (int i = 0; aann != null && i < aann.length; i++)
+ AlignmentAnnotation aa = anns[i];
+ if (aa != null && aa.hasScore() && aa.sequenceRef != null)
{
- if (aann[i].hasScore() && aann[i].sequenceRef != null)
- {
- scoreSorts.put(aann[i].label, aann[i].label);
- }
+ scoreSorts.add(aa.label);
}
}
- Enumeration<String> labels = scoreSorts.keys();
- while (labels.hasMoreElements())
- {
- addSortByAnnotScoreMenuItem(sortByAnnotScore, labels.nextElement());
- }
- sortByAnnotScore.setVisible(scoreSorts.size() > 0);
- scoreSorts.clear();
-
- _annotationScoreVectorHash = viewport.getAlignment()
- .getAlignmentAnnotation().hashCode();
}
+ for (String label : scoreSorts)
+ {
+ addSortByAnnotScoreMenuItem(sortByAnnotScore, label);
+ }
+ sortByAnnotScore.setVisible(!scoreSorts.isEmpty());
+
+ _annotationScoreVectorHash = viewport.getAlignment()
+ .getAlignmentAnnotation().hashCode();
}
/**
+ * Enable (or, if desired, make visible) the By Tree
+ * submenu only if it has at least one element (or will have).
+ *
+ */
+ @Override
+ protected void enableSortMenuOptions()
+ {
+ List<TreePanel> treePanels = getTreePanels();
+ sortByTreeMenu.setEnabled(!treePanels.isEmpty());
+ }
+
+ /**
* Maintain the Order by->Displayed Tree menu. Creates a new menu item for a
* TreePanel with an appropriate <code>jalview.analysis.AlignmentSorter</code>
* call. Listeners are added to remove the menu item when the treePanel is
{
sortByTreeMenu.removeAll();
- List<Component> comps = PaintRefresher.components
- .get(viewport.getSequenceSetId());
- List<TreePanel> treePanels = new ArrayList<>();
- for (Component comp : comps)
- {
- if (comp instanceof TreePanel)
- {
- treePanels.add((TreePanel) comp);
- }
- }
-
- if (treePanels.size() < 1)
- {
- sortByTreeMenu.setVisible(false);
- return;
- }
-
- sortByTreeMenu.setVisible(true);
+ List<TreePanel> treePanels = getTreePanels();
for (final TreePanel tp : treePanels)
{
sortByTreeMenu.add(item);
}
}
-
+
+ private List<TreePanel> getTreePanels()
+ {
+ List<Component> comps = PaintRefresher.components
+ .get(viewport.getSequenceSetId());
+ List<TreePanel> treePanels = new ArrayList<>();
+ for (Component comp : comps)
+ {
+ if (comp instanceof TreePanel)
+ {
+ treePanels.add((TreePanel) comp);
+ }
+ }
+ return treePanels;
+ }
public boolean sortBy(AlignmentOrder alorder, String undoname)
{
SequenceI[] oldOrder = viewport.getAlignment().getSequencesArray();
viewport.setCurrentTree(showNewickTree(fin, filePath).getTree());
} catch (Exception ex)
{
- JvOptionPane.showMessageDialog(Desktop.desktop, ex.getMessage(),
+ JvOptionPane.showMessageDialog(Desktop.getDesktopPane(),
+ ex.getMessage(),
MessageManager
.getString("label.problem_reading_tree_file"),
JvOptionPane.WARNING_MESSAGE);
}
if (fin != null && fin.hasWarningMessage())
{
- JvOptionPane.showMessageDialog(Desktop.desktop,
+ JvOptionPane.showMessageDialog(Desktop.getDesktopPane(),
fin.getWarningMessage(),
MessageManager.getString(
"label.possible_problem_with_tree_file"),
{
tp = new TreePanel(alignPanel, nf, treeTitle, input);
- tp.setSize(w, h);
+ Dimension dim = Platform.getDimIfEmbedded(tp, -1, -1);
+ if (dim == null)
+ {
+ dim = new Dimension(w, h);
+ }
+ else
+ {
+ // no offset, either
+ x = 0;
+ }
+ tp.setSize(dim.width, dim.height);
if (x > 0 && y > 0)
{
tp.setLocation(x, y);
}
- Desktop.addInternalFrame(tp, treeTitle, w, h);
+ Desktop.addInternalFrame(tp, treeTitle, dim.width, dim.height);
}
} catch (Exception ex)
{
return tp;
}
- private boolean buildingMenu = false;
/**
- * Generates menu items and listener event actions for web service clients
- *
+ * Schedule the web services menu rebuild to the event dispatch thread.
*/
- public void BuildWebServiceMenu()
+ public void buildWebServicesMenu()
{
- while (buildingMenu)
- {
- try
+ SwingUtilities.invokeLater(() -> {
+ Cache.log.info("Rebuiling WS menu");
+ webService.removeAll();
+ if (Cache.getDefault("SHOW_SLIVKA_SERVICES", true))
{
- System.err.println("Waiting for building menu to finish.");
- Thread.sleep(10);
- } catch (Exception e)
+ Cache.log.info("Building web service menu for slivka");
+ SlivkaWSDiscoverer discoverer = SlivkaWSDiscoverer.getInstance();
+ JMenu submenu = new JMenu("Slivka");
+ buildWebServicesMenu(discoverer, submenu);
+ webService.add(submenu);
+ }
+ if (Cache.getDefault("SHOW_JWS2_SERVICES", true))
{
+ WSDiscovererI jws2servs = Jws2Discoverer.getInstance();
+ JMenu submenu = new JMenu("JABAWS");
+ buildLegacyWebServicesMenu(submenu);
+ buildWebServicesMenu(jws2servs, submenu);
+ webService.add(submenu);
}
- }
- final AlignFrame me = this;
- buildingMenu = true;
- new Thread(new Runnable()
+ });
+ }
+
+ private void buildLegacyWebServicesMenu(JMenu menu)
+ {
+ JMenu secstrmenu = new JMenu("Secondary Structure Prediction");
+ if (Discoverer.getServices() != null && Discoverer.getServices().size() > 0)
{
- @Override
- public void run()
+ var secstrpred = Discoverer.getServices().get("SecStrPred");
+ if (secstrpred != null)
{
- final List<JMenuItem> legacyItems = new ArrayList<>();
- try
- {
- // System.err.println("Building ws menu again "
- // + Thread.currentThread());
- // TODO: add support for context dependent disabling of services based
- // on
- // alignment and current selection
- // TODO: add additional serviceHandle parameter to specify abstract
- // handler
- // class independently of AbstractName
- // TODO: add in rediscovery GUI function to restart discoverer
- // TODO: group services by location as well as function and/or
- // introduce
- // object broker mechanism.
- final Vector<JMenu> wsmenu = new Vector<>();
- 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");
- // JAL-940 - only show secondary structure prediction services from
- // the legacy server
- if (// Cache.getDefault("SHOW_JWS1_SERVICES", true)
- // &&
- Discoverer.services != null && (Discoverer.services.size() > 0))
- {
- // TODO: refactor to allow list of AbstractName/Handler bindings to
- // be
- // stored or retrieved from elsewhere
- // No MSAWS used any more:
- // Vector msaws = null; // (Vector)
- // Discoverer.services.get("MsaWS");
- Vector<ServiceHandle> secstrpr = Discoverer.services
- .get("SecStrPred");
- if (secstrpr != null)
- {
- // Add any secondary structure prediction services
- for (int i = 0, j = secstrpr.size(); i < j; i++)
- {
- final ext.vamsas.ServiceHandle sh = secstrpr.get(i);
- jalview.ws.WSMenuEntryProviderI impl = jalview.ws.jws1.Discoverer
- .getServiceClient(sh);
- int p = secstrmenu.getItemCount();
- impl.attachWSMenuEntry(secstrmenu, me);
- int q = secstrmenu.getItemCount();
- for (int litm = p; litm < q; litm++)
- {
- legacyItems.add(secstrmenu.getItem(litm));
- }
- }
- }
- }
-
- // Add all submenus in the order they should appear on the web
- // services menu
- wsmenu.add(msawsmenu);
- wsmenu.add(secstrmenu);
- wsmenu.add(dismenu);
- wsmenu.add(analymenu);
- // No search services yet
- // wsmenu.add(seqsrchmenu);
-
- javax.swing.SwingUtilities.invokeLater(new Runnable()
- {
- @Override
- public void run()
- {
- try
- {
- webService.removeAll();
- // first, add discovered services onto the webservices menu
- if (wsmenu.size() > 0)
- {
- for (int i = 0, j = wsmenu.size(); i < j; i++)
- {
- webService.add(wsmenu.get(i));
- }
- }
- else
- {
- webService.add(me.webServiceNoServices);
- }
- // TODO: move into separate menu builder class.
- boolean new_sspred = false;
- if (Cache.getDefault("SHOW_JWS2_SERVICES", true))
- {
- Jws2Discoverer jws2servs = Jws2Discoverer.getDiscoverer();
- if (jws2servs != null)
- {
- if (jws2servs.hasServices())
- {
- jws2servs.attachWSMenuEntry(webService, me);
- for (Jws2Instance sv : jws2servs.getServices())
- {
- if (sv.description.toLowerCase(Locale.ROOT).contains("jpred"))
- {
- for (JMenuItem jmi : legacyItems)
- {
- jmi.setVisible(false);
- }
- }
- }
-
- }
- if (jws2servs.isRunning())
- {
- JMenuItem tm = new JMenuItem(
- "Still discovering JABA Services");
- tm.setEnabled(false);
- webService.add(tm);
- }
- }
- }
- build_urlServiceMenu(me.webService);
- build_fetchdbmenu(webService);
- for (JMenu item : wsmenu)
- {
- if (item.getItemCount() == 0)
- {
- item.setEnabled(false);
- }
- else
- {
- item.setEnabled(true);
- }
- }
- } catch (Exception e)
- {
- Cache.log.debug(
- "Exception during web service menu building process.",
- e);
- }
- }
- });
- } catch (Exception e)
+ for (ext.vamsas.ServiceHandle sh : secstrpred)
{
+ var menuProvider = Discoverer.getServiceClient(sh);
+ menuProvider.attachWSMenuEntry(secstrmenu, this);
}
- buildingMenu = false;
}
- }).start();
+ }
+ menu.add(secstrmenu);
+ }
+ /**
+ * Constructs the web services menu for the given discoverer under the
+ * specified menu. This method must be called on the EDT
+ *
+ * @param discoverer
+ * the discoverer used to build the menu
+ * @param menu
+ * parent component which the elements will be attached to
+ */
+ private void buildWebServicesMenu(WSDiscovererI discoverer, JMenu menu)
+ {
+ if (discoverer.hasServices())
+ {
+ PreferredServiceRegistry.getRegistry().populateWSMenuEntry(
+ discoverer.getServices(), sv -> buildWebServicesMenu(), menu,
+ this, null);
+ }
+ if (discoverer.isRunning())
+ {
+ JMenuItem item = new JMenuItem("Service discovery in progress.");
+ item.setEnabled(false);
+ menu.add(item);
+ }
+ else if (!discoverer.hasServices())
+ {
+ JMenuItem item = new JMenuItem("No services available.");
+ item.setEnabled(false);
+ menu.add(item);
+ }
}
/**
* JMenuItem testAlView = new JMenuItem("Test AlignmentView"); final
* AlignFrame af = this; testAlView.addActionListener(new ActionListener() {
*
- * @Override public void actionPerformed(ActionEvent e) {
+ * public void actionPerformed(ActionEvent e) {
* jalview.datamodel.AlignmentView
* .testSelectionViews(af.viewport.getAlignment(),
* af.viewport.getColumnSelection(), af.viewport.selectionGroup); }
final String errorTitle = MessageManager
.getString("label.implementation_error")
+ MessageManager.getString("label.translation_failed");
- JvOptionPane.showMessageDialog(Desktop.desktop, msg, errorTitle,
- JvOptionPane.ERROR_MESSAGE);
+ JvOptionPane.showMessageDialog(Desktop.getDesktopPane(), msg,
+ errorTitle, JvOptionPane.ERROR_MESSAGE);
return;
}
if (al == null || al.getHeight() == 0)
"label.select_at_least_three_bases_in_at_least_one_sequence_to_cDNA_translation");
final String errorTitle = MessageManager
.getString("label.translation_failed");
- JvOptionPane.showMessageDialog(Desktop.desktop, msg, errorTitle,
- JvOptionPane.WARNING_MESSAGE);
+ JvOptionPane.showMessageDialog(Desktop.getDesktopPane(), msg,
+ errorTitle, JvOptionPane.WARNING_MESSAGE);
}
else
{
if (Cache.getDefault(Preferences.ENABLE_SPLIT_FRAME, true))
{
final SequenceI[] seqs = viewport.getSelectionAsNewSequence();
- viewport.openSplitFrame(af, new Alignment(seqs));
+ AlignViewport.openSplitFrame(this, af, new Alignment(seqs));
}
else
{
{
// BH 2018
return avc.parseFeaturesFile(file, sourceType,
- Cache.getDefault("RELAXEDSEQIDMATCHING", false));
+ Cache.getDefault(Preferences.RELAXEDSEQIDMATCHING, false));
}
evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
Transferable t = evt.getTransferable();
- final AlignFrame thisaf = this;
final List<Object> files = new ArrayList<>();
List<DataSourceType> protocols = new ArrayList<>();
try
{
Desktop.transferFromDropTarget(files, protocols, evt, t);
+ if (files.size() > 0)
+ {
+ new Thread(new Runnable()
+ {
+
+ @Override
+ public void run()
+ {
+ loadDroppedFiles(files, protocols, evt, t);
+ }
+ }).start();
+ }
} catch (Exception e)
{
e.printStackTrace();
}
- if (files != null)
+ }
+
+ protected void loadDroppedFiles(List<Object> files,
+ List<DataSourceType> protocols, DropTargetDropEvent evt,
+ Transferable t)
+ {
+ try
{
- new Thread(new Runnable()
+ // check to see if any of these files have names matching sequences
+ // in
+ // the alignment
+ SequenceIdMatcher idm = new SequenceIdMatcher(
+ viewport.getAlignment().getSequencesArray());
+ /**
+ * Object[] { String,SequenceI}
+ */
+ ArrayList<Object[]> filesmatched = new ArrayList<>();
+ ArrayList<Object> filesnotmatched = new ArrayList<>();
+ for (int i = 0; i < files.size(); i++)
{
- @Override
- public void run()
+ // BH 2018
+ Object fileObj = files.get(i);
+ String fileName = fileObj.toString();
+ String pdbfn = "";
+ DataSourceType protocol = (fileObj instanceof File
+ ? DataSourceType.FILE
+ : FormatAdapter.checkProtocol(fileName));
+ if (protocol == DataSourceType.FILE)
{
- try
+ File file;
+ if (fileObj instanceof File)
+ {
+ file = (File) fileObj;
+ Platform.cacheFileData(file);
+ }
+ else
+ {
+ file = new File(fileName);
+ }
+ pdbfn = file.getName();
+ }
+ else if (protocol == DataSourceType.URL)
+ {
+ URL url = new URL(fileName);
+ pdbfn = url.getFile();
+ }
+ if (pdbfn.length() > 0)
+ {
+ // attempt to find a match in the alignment
+ SequenceI[] mtch = idm.findAllIdMatches(pdbfn);
+ int l = 0, c = pdbfn.indexOf(".");
+ while (mtch == null && c != -1)
{
- // check to see if any of these files have names matching sequences
- // in
- // the alignment
- SequenceIdMatcher idm = new SequenceIdMatcher(
- viewport.getAlignment().getSequencesArray());
- /**
- * Object[] { String,SequenceI}
- */
- ArrayList<Object[]> filesmatched = new ArrayList<>();
- ArrayList<Object> filesnotmatched = new ArrayList<>();
- for (int i = 0; i < files.size(); i++)
+ do
{
- // BH 2018
- Object file = files.get(i);
- String fileName = file.toString();
- String pdbfn = "";
- DataSourceType protocol = (file instanceof File
- ? DataSourceType.FILE
- : FormatAdapter.checkProtocol(fileName));
- if (protocol == DataSourceType.FILE)
- {
- File fl;
- if (file instanceof File)
- {
- fl = (File) file;
- Platform.cacheFileData(fl);
- }
- else
- {
- fl = new File(fileName);
- }
- pdbfn = fl.getName();
- }
- else if (protocol == DataSourceType.URL)
- {
- URL url = new URL(fileName);
- pdbfn = url.getFile();
- }
- if (pdbfn.length() > 0)
- {
- // attempt to find a match in the alignment
- SequenceI[] mtch = idm.findAllIdMatches(pdbfn);
- int l = 0, c = pdbfn.indexOf(".");
- while (mtch == null && c != -1)
- {
- do
- {
- l = c;
- } while ((c = pdbfn.indexOf(".", l)) > l);
- if (l > -1)
- {
- pdbfn = pdbfn.substring(0, l);
- }
- mtch = idm.findAllIdMatches(pdbfn);
- }
- if (mtch != null)
- {
- FileFormatI type;
- try
- {
- type = new IdentifyFile().identify(file, protocol);
- } catch (Exception ex)
- {
- type = null;
- }
- if (type != null && type.isStructureFile())
- {
- filesmatched.add(new Object[] { file, protocol, mtch });
- continue;
- }
- }
- // File wasn't named like one of the sequences or wasn't a PDB
- // file.
- filesnotmatched.add(file);
- }
+ l = c;
+ } while ((c = pdbfn.indexOf(".", l)) > l);
+ if (l > -1)
+ {
+ pdbfn = pdbfn.substring(0, l);
}
- int assocfiles = 0;
- if (filesmatched.size() > 0)
+ mtch = idm.findAllIdMatches(pdbfn);
+ }
+ if (mtch != null)
+ {
+ FileFormatI type;
+ try
{
- boolean autoAssociate = Cache
- .getDefault("AUTOASSOCIATE_PDBANDSEQS", false);
- if (!autoAssociate)
- {
- String msg = MessageManager.formatMessage(
- "label.automatically_associate_structure_files_with_sequences_same_name",
- new Object[]
- { Integer.valueOf(filesmatched.size())
- .toString() });
- String ttl = MessageManager.getString(
- "label.automatically_associate_structure_files_by_name");
- int choice = JvOptionPane.showConfirmDialog(thisaf, msg,
- ttl, JvOptionPane.YES_NO_OPTION);
- autoAssociate = choice == JvOptionPane.YES_OPTION;
- }
- if (autoAssociate)
- {
- for (Object[] fm : filesmatched)
- {
- // try and associate
- // TODO: may want to set a standard ID naming formalism for
- // associating PDB files which have no IDs.
- for (SequenceI toassoc : (SequenceI[]) fm[2])
- {
- PDBEntry pe = new AssociatePdbFileWithSeq()
- .associatePdbWithSeq(fm[0].toString(),
- (DataSourceType) fm[1], toassoc, false,
- Desktop.instance);
- if (pe != null)
- {
- System.err.println("Associated file : "
- + (fm[0].toString()) + " with "
- + toassoc.getDisplayId(true));
- assocfiles++;
- }
- }
- // TODO: do we need to update overview ? only if features are
- // shown I guess
- alignPanel.paintAlignment(true, false);
- }
- }
- else
- {
- /*
- * add declined structures as sequences
- */
- for (Object[] o : filesmatched)
- {
- filesnotmatched.add(o[0]);
- }
- }
+ type = new IdentifyFile().identify(fileObj, protocol);
+ } catch (Exception ex)
+ {
+ type = null;
}
- if (filesnotmatched.size() > 0)
+ if (type != null && type.isStructureFile())
{
- if (assocfiles > 0 && (Cache.getDefault(
- "AUTOASSOCIATE_PDBANDSEQS_IGNOREOTHERS", false)
- || JvOptionPane.showConfirmDialog(thisaf,
- "<html>" + MessageManager.formatMessage(
- "label.ignore_unmatched_dropped_files_info",
- new Object[]
- { Integer.valueOf(
- filesnotmatched.size())
- .toString() })
- + "</html>",
- MessageManager.getString(
- "label.ignore_unmatched_dropped_files"),
- JvOptionPane.YES_NO_OPTION) == JvOptionPane.YES_OPTION))
- {
- return;
- }
- for (Object fn : filesnotmatched)
+ filesmatched.add(new Object[] { fileObj, protocol, mtch });
+ continue;
+ }
+ }
+ // File wasn't named like one of the sequences or wasn't a PDB
+ // file.
+ filesnotmatched.add(fileObj);
+ }
+ }
+ int assocfiles = 0;
+ if (filesmatched.size() > 0)
+ {
+ boolean autoAssociate = Cache
+ .getDefault(Preferences.AUTOASSOCIATE_PDBANDSEQS, false);
+ if (!autoAssociate)
+ {
+ String msg = MessageManager.formatMessage(
+ "label.automatically_associate_structure_files_with_sequences_same_name",
+ new Object[]
+ { Integer.valueOf(filesmatched.size()).toString() });
+ String ttl = MessageManager.getString(
+ "label.automatically_associate_structure_files_by_name");
+ int choice = JvOptionPane.showConfirmDialog(this, msg, ttl,
+ JvOptionPane.YES_NO_OPTION);
+ autoAssociate = choice == JvOptionPane.YES_OPTION;
+ }
+ if (autoAssociate)
+ {
+ for (Object[] fm : filesmatched)
+ {
+ // try and associate
+ // TODO: may want to set a standard ID naming formalism for
+ // associating PDB files which have no IDs.
+ for (SequenceI toassoc : (SequenceI[]) fm[2])
+ {
+ PDBEntry pe = AssociatePdbFileWithSeq.associatePdbWithSeq(
+ fm[0].toString(), (DataSourceType) fm[1], toassoc,
+ false);
+ if (pe != null)
{
- loadJalviewDataFile(fn, null, null, null);
+ System.err.println("Associated file : " + (fm[0].toString())
+ + " with " + toassoc.getDisplayId(true));
+ assocfiles++;
}
}
- } catch (Exception ex)
+ // TODO: do we need to update overview ? only if features are
+ // shown I guess
+ alignPanel.paintAlignment(true, false);
+ }
+ }
+ else
+ {
+ /*
+ * add declined structures as sequences
+ */
+ for (Object[] o : filesmatched)
{
- ex.printStackTrace();
+ filesnotmatched.add(o[0]);
}
}
- }).start();
+ }
+ if (filesnotmatched.size() > 0)
+ {
+ if (assocfiles > 0 && (Cache
+ .getDefault("AUTOASSOCIATE_PDBANDSEQS_IGNOREOTHERS", false)
+ || JvOptionPane.showConfirmDialog(this,
+ "<html>" + MessageManager.formatMessage(
+ "label.ignore_unmatched_dropped_files_info",
+ new Object[]
+ { Integer.valueOf(filesnotmatched.size())
+ .toString() })
+ + "</html>",
+ MessageManager.getString(
+ "label.ignore_unmatched_dropped_files"),
+ JvOptionPane.YES_NO_OPTION) == JvOptionPane.YES_OPTION))
+ {
+ return;
+ }
+ for (Object fn : filesnotmatched)
+ {
+ loadJalviewDataFile(fn, null, null, null);
+ }
+
+ }
+ } catch (Exception ex)
+ {
+ ex.printStackTrace();
}
}
*
* @param file
* either a filename or a URL string.
+ * @throws InterruptedException
+ * @throws IOException
*/
public void loadJalviewDataFile(Object file, DataSourceType sourceType,
FileFormatI format, SequenceI assocSeq)
{
// some problem - if no warning its probable that the ID matching
// process didn't work
- JvOptionPane.showMessageDialog(Desktop.desktop,
+ JvOptionPane.showMessageDialog(Desktop.getDesktopPane(),
tcf.getWarningMessage() == null
? MessageManager.getString(
"label.check_file_matches_sequence_ids_alignment")
if (isAnnotation)
{
- alignPanel.adjustAnnotationHeight();
- viewport.updateSequenceIdColours();
- buildSortByAnnotationScoresMenu();
- alignPanel.paintAlignment(true, true);
+ updateForAnnotations();
}
} catch (Exception ex)
{
+ (format != null
? "(parsing as '" + format + "' file)"
: ""),
- oom, Desktop.desktop);
+ oom, Desktop.getDesktopPane());
+ }
+ }
+
+ /**
+ * Do all updates necessary after an annotation file such as jnet. Also called
+ * from Jalview.loadAppletParams for "annotations", "jnetFile"
+ */
+
+ public void updateForAnnotations()
+ {
+ alignPanel.adjustAnnotationHeight();
+ viewport.updateSequenceIdColours();
+ buildSortByAnnotationScoresMenu();
+ alignPanel.paintAlignment(true, true);
+ }
+
+ /**
+ * Change the display state for the given feature groups -- Added by BH from
+ * JalviewLite
+ *
+ * @param groups
+ * list of group strings
+ * @param state
+ * visible or invisible
+ */
+
+ public void setFeatureGroupState(String[] groups, boolean state)
+ {
+ jalview.api.FeatureRenderer fr = null;
+ viewport.setShowSequenceFeatures(true);
+ if (alignPanel != null
+ && (fr = alignPanel.getFeatureRenderer()) != null)
+ {
+
+ fr.setGroupVisibility(Arrays.asList(groups), state);
+ alignPanel.getSeqPanel().seqCanvas.repaint();
+ if (alignPanel.overviewPanel != null)
+ {
+ alignPanel.overviewPanel.updateOverviewImage();
+ }
}
}
@Override
public void run()
{
- final jalview.ws.SequenceFetcher sf = jalview.gui.SequenceFetcher
- .getSequenceFetcherSingleton();
+ // ??
+ // final jalview.ws.SequenceFetcher sf = jalview.gui.SequenceFetcher
+ // .getSequenceFetcherSingleton();
javax.swing.SwingUtilities.invokeLater(new Runnable()
{
@Override
public void run()
{
+ jalview.ws.SequenceFetcher sf = jalview.ws.SequenceFetcher
+ .getInstance();
String[] dbclasses = sf.getNonAlignmentSources();
List<DbSourceProxy> otherdb;
JMenu dfetch = new JMenu();
}
if (otherdb.size() == 1)
{
- final DbSourceProxy[] dassource = otherdb
- .toArray(new DbSourceProxy[0]);
DbSourceProxy src = otherdb.get(0);
+ DbSourceProxy[] dassource = new DbSourceProxy[] { src };
fetchr = new JMenuItem(src.getDbSource());
fetchr.addActionListener(new ActionListener()
{
@Override
protected void justifyLeftMenuItem_actionPerformed(ActionEvent e)
{
- AlignmentI al = viewport.getAlignment();
- al.justify(false);
- viewport.firePropertyChange("alignment", null, al);
+ viewport.getAlignment().justify(false);
+ viewport.notifyAlignment();
}
/**
@Override
protected void justifyRightMenuItem_actionPerformed(ActionEvent e)
{
- AlignmentI al = viewport.getAlignment();
- al.justify(true);
- viewport.firePropertyChange("alignment", null, al);
+ viewport.getAlignment().justify(true);
+ viewport.notifyAlignment();
}
@Override
} catch (Exception ex)
{
System.err.println((ex.toString()));
- JvOptionPane.showInternalMessageDialog(Desktop.desktop,
+ JvOptionPane.showInternalMessageDialog(Desktop.getDesktopPane(),
MessageManager.getString("label.couldnt_run_groovy_script"),
MessageManager.getString("label.groovy_support_failed"),
JvOptionPane.ERROR_MESSAGE);
}
}
+ /**
+ * Sets the status of the HMMER menu
+ */
+ public void updateHMMERStatus()
+ {
+ hmmerMenu.setEnabled(HmmerCommand.isHmmerAvailable());
+ }
@Override
protected void loadVcf_actionPerformed()
{
}
private Rectangle lastFeatureSettingsBounds = null;
-
@Override
public void setFeatureSettingsGeometry(Rectangle bounds)
{
{
return lastFeatureSettingsBounds;
}
-}
-class PrintThread extends Thread
-{
- AlignmentPanel ap;
+ public void scrollTo(int row, int column)
+ {
+ alignPanel.getSeqPanel().scrollTo(row, column);
+ }
- public PrintThread(AlignmentPanel ap)
+ public void scrollToRow(int row)
{
- this.ap = ap;
+ alignPanel.getSeqPanel().scrollToRow(row);
}
- static PageFormat pf;
+ public void scrollToColumn(int column)
+ {
+ alignPanel.getSeqPanel().scrollToColumn(column);
+ }
- @Override
- public void run()
+ /**
+ * BH 2019 from JalviewLite
+ *
+ * get sequence feature groups that are hidden or shown
+ *
+ * @param visible
+ * true is visible
+ * @return list
+ */
+
+ public String[] getFeatureGroupsOfState(boolean visible)
{
- PrinterJob printJob = PrinterJob.getPrinterJob();
+ jalview.api.FeatureRenderer fr = null;
+ if (alignPanel != null
+ && (fr = alignPanel.getFeatureRenderer()) != null)
+ {
+ List<String> gps = fr.getGroups(visible);
+ String[] _gps = gps.toArray(new String[gps.size()]);
+ return _gps;
+ }
+ return null;
+ }
+
+ /**
+ *
+ * @return list of feature groups on the view
+ */
- if (pf != null)
+ public String[] getFeatureGroups()
+ {
+ jalview.api.FeatureRenderer fr = null;
+ if (alignPanel != null
+ && (fr = alignPanel.getFeatureRenderer()) != null)
{
- printJob.setPrintable(ap, pf);
+ List<String> gps = fr.getFeatureGroups();
+ String[] _gps = gps.toArray(new String[gps.size()]);
+ return _gps;
}
- else
+ return null;
+ }
+
+ public void select(SequenceGroup sel, ColumnSelection csel,
+ HiddenColumns hidden)
+ {
+ alignPanel.getSeqPanel().selection(sel, csel, hidden, null);
+ }
+
+ public int getID()
+ {
+ return id;
+ }
+
+ static class PrintThread extends Thread
+ {
+ AlignmentPanel ap;
+
+ public PrintThread(AlignmentPanel ap)
{
- printJob.setPrintable(ap);
+ this.ap = ap;
}
- if (printJob.printDialog())
+ static PageFormat pf;
+
+ @Override
+ public void run()
{
- try
+ PrinterJob printJob = PrinterJob.getPrinterJob();
+
+ if (pf != null)
+ {
+ printJob.setPrintable(ap, pf);
+ }
+ else
{
- printJob.print();
- } catch (Exception PrintException)
+ printJob.setPrintable(ap);
+ }
+
+ if (printJob.printDialog())
{
- PrintException.printStackTrace();
+ try
+ {
+ printJob.print();
+ } catch (Exception PrintException)
+ {
+ PrintException.printStackTrace();
+ }
}
}
}
import jalview.datamodel.SearchResultsI;
import jalview.datamodel.SequenceGroup;
import jalview.datamodel.SequenceI;
+import jalview.datamodel.features.FeatureMatcherSetI;
import jalview.renderer.ResidueShader;
import jalview.schemes.ColourSchemeI;
import jalview.schemes.ColourSchemeProperty;
import java.awt.Rectangle;
import java.util.ArrayList;
import java.util.Hashtable;
+import java.util.Iterator;
import java.util.List;
import javax.swing.JInternalFrame;
public class AlignViewport extends AlignmentViewport
implements SelectionSource
{
+ public final static int NO_SPLIT = 0;
+
+ public final static int SPLIT_FRAME = 1;
+
+ public final static int NEW_WINDOW = 2;
Font font;
boolean cursorMode = false;
setRightAlignIds(Cache.getDefault("RIGHT_ALIGN_IDS", false));
setCentreColumnLabels(Cache.getDefault("CENTRE_COLUMN_LABELS", false));
- autoCalculateConsensus = Cache.getDefault("AUTO_CALC_CONSENSUS", true);
+ autoCalculateConsensusAndConservation = Cache.getDefault("AUTO_CALC_CONSENSUS", true);
setPadGaps(Cache.getDefault("PAD_GAPS", true));
setShowNPFeats(Cache.getDefault("SHOW_NPFEATS_TOOLTIP", true));
setFont(new Font(fontName, style, Integer.parseInt(fontSize)), true);
- alignment
- .setGapCharacter(Cache.getDefault("GAP_SYMBOL", "-").charAt(0));
+ alignment.setGapCharacter(Cache.getDefault("GAP_SYMBOL", "-").charAt(0));
// We must set conservation and consensus before setting colour,
// as Blosum and Clustal require this to be done
- if (hconsensus == null && !isDataset)
+ if (hconsensus == null && !isDataset)
{
- if (!alignment.isNucleotide())
+ if (!alignment.isNucleotide())
{
showConservation = Cache.getDefault("SHOW_CONSERVATION", true);
showQuality = Cache.getDefault("SHOW_QUALITY", true);
showSequenceLogo = Cache.getDefault("SHOW_CONSENSUS_LOGO", false);
normaliseSequenceLogo = Cache.getDefault("NORMALISE_CONSENSUS_LOGO",
false);
+ // for now, use consensus options for Information till it gets its own
+ setShowHMMSequenceLogo(showSequenceLogo);
+ setNormaliseHMMSequenceLogo(normaliseSequenceLogo);
+ setShowInformationHistogram(showConsensusHistogram);
showGroupConsensus = Cache.getDefault("SHOW_GROUP_CONSENSUS", false);
showConsensus = Cache.getDefault("SHOW_IDENTITY", true);
showOccupancy = Cache.getDefault(Preferences.SHOW_OCCUPANCY, true);
}
initAutoAnnotation();
- String colourProperty = alignment.isNucleotide()
+ // initInformation();
+
+ String colourProperty = alignment.isNucleotide()
? Preferences.DEFAULT_COLOUR_NUC
: Preferences.DEFAULT_COLOUR_PROT;
String schemeName = Cache.getProperty(colourProperty);
if (residueShading != null)
{
- residueShading.setConsensus(hconsensus);
+ residueShading.setConsensus(hconsensus);
}
setColourAppliesToAllGroups(true);
}
+
boolean validCharWidth;
/**
if (align != null)
{
StructureSelectionManager ssm = StructureSelectionManager
- .getStructureSelectionManager(Desktop.instance);
+ .getStructureSelectionManager(Desktop.getInstance());
ssm.registerMappings(align.getCodonFrames());
}
/*
* replace mappings on our alignment
*/
- if (alignment != null && align != null)
+ if (alignment != null && align != null)
{
alignment.setCodonFrames(align.getCodonFrames());
}
if (mappings != null)
{
StructureSelectionManager ssm = StructureSelectionManager
- .getStructureSelectionManager(Desktop.instance);
+ .getStructureSelectionManager(Desktop.getInstance());
for (AlignedCodonFrame acf : mappings)
{
if (noReferencesTo(acf))
public void sendSelection()
{
jalview.structure.StructureSelectionManager
- .getStructureSelectionManager(Desktop.instance)
+ .getStructureSelectionManager(Desktop.getInstance())
.sendSelection(new SequenceGroup(getSelectionGroup()),
new ColumnSelection(getColumnSelection()),
new HiddenColumns(getAlignment().getHiddenColumns()),
public StructureSelectionManager getStructureSelectionManager()
{
return StructureSelectionManager
- .getStructureSelectionManager(Desktop.instance);
+ .getStructureSelectionManager(Desktop.getInstance());
}
+
@Override
public boolean isNormaliseSequenceLogo()
{
return normaliseSequenceLogo;
}
- public void setNormaliseSequenceLogo(boolean state)
+ @Override
+public void setNormaliseSequenceLogo(boolean state)
{
normaliseSequenceLogo = state;
}
{
return validCharWidth;
}
-
+
private Hashtable<String, AutoCalcSetting> calcIdParams = new Hashtable<>();
public AutoCalcSetting getCalcIdSettingsFor(String calcId)
}
ranges.setEndSeq(getAlignment().getHeight() - 1); // BH 2019.04.18
- firePropertyChange("alignment", null, getAlignment().getSequences());
+ notifyAlignment();
}
/**
* dialog responses 0, 1, 2 (even though JOptionPane shows them
* in reverse order)
*/
- JvOptionPane dialog = JvOptionPane.newOptionDialog(Desktop.desktop)
- .setResponseHandler(0, new Runnable()
+ JvOptionPane dialog = JvOptionPane.newOptionDialog(Desktop.getDesktopPane())
+ .setResponseHandler(NO_SPLIT, new Runnable()
{
@Override
public void run()
{
addDataToAlignment(al);
}
- }).setResponseHandler(1, new Runnable()
+ }).setResponseHandler(SPLIT_FRAME, new Runnable()
{
@Override
public void run()
{
- us.openLinkedAlignmentAs(al, title, true);
+ // Make a copy of this one to open it in a splitframe
+ openLinkedAlignmentAs(getAlignPanel().alignFrame,
+ new Alignment(getAlignment()), al, title,
+ SPLIT_FRAME);
}
- }).setResponseHandler(2, new Runnable()
+ }).setResponseHandler(NEW_WINDOW, new Runnable()
{
@Override
public void run()
{
- us.openLinkedAlignmentAs(al, title, false);
+ openLinkedAlignmentAs(null, getAlignment(), al, title,
+ NEW_WINDOW);
}
});
- dialog.showDialog(question,
+ dialog.showDialog(question,
MessageManager.getString("label.open_split_window"),
JvOptionPane.DEFAULT_OPTION, JvOptionPane.PLAIN_MESSAGE, null,
options, options[0]);
}
- protected void openLinkedAlignmentAs(AlignmentI al, String title,
- boolean newWindowOrSplitPane)
- {
+ /**
+ * Open a split frame or a new window
+ *
+ * @param al
+ * @param title
+ * @param mode
+ * SPLIT_FRAME or NEW_WINDOW
+ */
+ public static void openLinkedAlignmentAs(AlignFrame thisFrame,
+ AlignmentI thisAlignment, AlignmentI al, String title, int mode)
+ {
/*
- * Identify protein and dna alignments. Make a copy of this one if opening
- * in a new split pane.
+ * Identify protein and dna alignments.
*/
- AlignmentI thisAlignment = newWindowOrSplitPane
- ? new Alignment(getAlignment())
- : getAlignment();
AlignmentI protein = al.isNucleotide() ? thisAlignment : al;
- final AlignmentI cdna = al.isNucleotide() ? al : thisAlignment;
+ AlignmentI cdna = al.isNucleotide() ? al : thisAlignment;
/*
* Map sequences. At least one should get mapped as we have already passed
// alignFrame.setFileName(file, format);
// }
- if (!newWindowOrSplitPane)
+ if (mode == NEW_WINDOW)
{
Desktop.addInternalFrame(newAlignFrame, title,
AlignFrame.DEFAULT_WIDTH, AlignFrame.DEFAULT_HEIGHT);
{
}
- if (newWindowOrSplitPane)
+ if (mode == SPLIT_FRAME)
{
al.alignAs(thisAlignment);
- protein = openSplitFrame(newAlignFrame, thisAlignment);
+ openSplitFrame(thisFrame, newAlignFrame, thisAlignment);
}
}
* cdna/protein complement alignment to show in the other split half
* @return the protein alignment in the split frame
*/
- protected AlignmentI openSplitFrame(AlignFrame newAlignFrame,
- AlignmentI complement)
+ static protected AlignmentI openSplitFrame(AlignFrame thisFrame,
+ AlignFrame newAlignFrame, AlignmentI complement)
{
/*
* Make a new frame with a copy of the alignment we are adding to. If this
*/
AlignFrame copyMe = new AlignFrame(complement, AlignFrame.DEFAULT_WIDTH,
AlignFrame.DEFAULT_HEIGHT);
- copyMe.setTitle(getAlignPanel().alignFrame.getTitle());
+ copyMe.setTitle(thisFrame.getTitle());
AlignmentI al = newAlignFrame.viewport.getAlignment();
final AlignFrame proteinFrame = al.isNucleotide() ? copyMe
FeatureRenderer fr = getAlignPanel().getSeqPanel().seqCanvas
.getFeatureRenderer();
- List<String> origRenderOrder = new ArrayList<>();
- List<String> origGroups = new ArrayList<>();
+ List<String> origRenderOrder = new ArrayList(),
+ origGroups = new ArrayList();
// preserve original render order - allows differentiation between user configured colours and autogenerated ones
origRenderOrder.addAll(fr.getRenderOrder());
origGroups.addAll(fr.getFeatureGroups());
if (!mergeOnly)
{
// only clear displayed features if we are mergeing
- // displayed.clear();
+ displayed.clear();
}
// TODO this clears displayed.featuresRegistered - do we care?
//
{
FeatureColourI preferredColour = featureSettings
.getFeatureColour(type);
+ FeatureMatcherSetI preferredFilters = featureSettings
+ .getFeatureFilters(type);
FeatureColourI origColour = fr.getFeatureStyle(type);
if (!mergeOnly || (!origRenderOrder.contains(type)
|| origColour == null
{
fr.setColour(type, preferredColour);
}
+ if (preferredFilters != null
+ && (!mergeOnly || fr.getFeatureFilter(type) != null))
+ {
+ fr.setFeatureFilter(type, preferredFilters);
+ }
if (featureSettings.isFeatureDisplayed(type))
{
displayed.setVisible(type);
fr.orderFeatures(featureSettings);
}
fr.setTransparency(featureSettings.getTransparency());
-
fr.notifyFeaturesChanged();
}
*/
package jalview.gui;
-import jalview.analysis.AnnotationSorter;
-import jalview.api.AlignViewportI;
-import jalview.api.AlignmentViewPanel;
-import jalview.bin.Cache;
-import jalview.bin.Jalview;
-import jalview.datamodel.AlignmentI;
-import jalview.datamodel.HiddenColumns;
-import jalview.datamodel.SearchResultsI;
-import jalview.datamodel.SequenceFeature;
-import jalview.datamodel.SequenceGroup;
-import jalview.datamodel.SequenceI;
-import jalview.gui.ImageExporter.ImageWriterI;
-import jalview.io.HTMLOutput;
-import jalview.jbgui.GAlignmentPanel;
-import jalview.math.AlignmentDimension;
-import jalview.schemes.ResidueProperties;
-import jalview.structure.StructureSelectionManager;
-import jalview.util.Comparison;
-import jalview.util.ImageMaker;
-import jalview.util.MessageManager;
-import jalview.viewmodel.ViewportListenerI;
-import jalview.viewmodel.ViewportRanges;
-
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import javax.swing.SwingUtilities;
+import jalview.analysis.AnnotationSorter;
+import jalview.api.AlignViewportI;
+import jalview.api.AlignmentViewPanel;
+import jalview.bin.Cache;
+import jalview.bin.Jalview;
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.HiddenColumns;
+import jalview.datamodel.SearchResultsI;
+import jalview.datamodel.SequenceFeature;
+import jalview.datamodel.SequenceGroup;
+import jalview.datamodel.SequenceI;
+import jalview.gui.ImageExporter.ImageWriterI;
+import jalview.io.HTMLOutput;
+import jalview.jbgui.GAlignmentPanel;
+import jalview.math.AlignmentDimension;
+import jalview.schemes.ResidueProperties;
+import jalview.structure.StructureSelectionManager;
+import jalview.util.Comparison;
+import jalview.util.ImageMaker;
+import jalview.util.MessageManager;
+import jalview.viewmodel.AlignmentViewport;
+import jalview.viewmodel.ViewportListenerI;
+import jalview.viewmodel.ViewportRanges;
+
/**
* DOCUMENT ME!
*
*/
public AlignmentPanel(AlignFrame af, final AlignViewport av)
{
-// setBackground(Color.white); // BH 2019
+ setName("AligmentPanel");
+ // setBackground(Color.white); // BH 2019
alignFrame = af;
this.av = av;
setSeqPanel(new SeqPanel(av, this));
ranges.setViewportWidth(widthInRes);
ranges.setViewportHeight(heightInSeq);
}
+ repaint();
}
});
@Override
public void propertyChange(PropertyChangeEvent evt)
{
- if (evt.getPropertyName().equals("alignment"))
- {
+ switch (evt.getPropertyName()) {
+ case AlignmentViewport.PROPERTY_SEQUENCE:
+ updateScrollBarsFromRanges();
+ if (annotationPanel != null)
+ annotationPanel.paintImmediately(0, 0, getWidth(), getHeight());
+ break;
+ case AlignmentViewport.PROPERTY_ALIGNMENT:
+ updateScrollBarsFromRanges();
PaintRefresher.Refresh(ap, av.getSequenceSetId(), true, true);
alignmentChanged();
+ break;
}
}
};
int oldWidth = av.getIdWidth();
// calculate sensible default width when no preference is available
- Dimension r = null;
+ Dimension d = null;
if (av.getIdWidth() < 0)
{
- int afwidth = (alignFrame != null ? alignFrame.getWidth() : 300);
- int idWidth = Math.min(afwidth - 200, 2 * afwidth / 3);
- int maxwidth = Math.max(IdwidthAdjuster.MIN_ID_WIDTH, idWidth);
- r = calculateIdWidth(maxwidth);
- av.setIdWidth(r.width);
+ int maxWidth = getMaxWidth();
+ d = calculateIdWidth(maxWidth);
+ av.setIdWidth(d.width);
}
else
{
- r = new Dimension();
- r.width = av.getIdWidth();
- r.height = 0;
+ d = new Dimension();
+ d.width = av.getIdWidth();
+ d.height = 0;
}
/*
* fudge: if desired width has changed, update layout
* (see also paintComponent - updates layout on a repaint)
*/
- if (r.width != oldWidth)
+ if (d.width != oldWidth)
{
- idPanelHolder.setPreferredSize(r);
+ idPanelHolder.setPreferredSize(d);
validate();
}
- return r;
+ return d;
+ }
+
+ public int getMaxWidth()
+ {
+ int afwidth = (alignFrame != null ? alignFrame.getWidth() : 300);
+ int idWidth = Math.min(afwidth - 200, 2 * afwidth / 3);
+ return Math.max(IdwidthAdjuster.MIN_ID_WIDTH, idWidth);
}
/**
* @return Dimension giving the maximum width of the alignment label panel
* that should be used.
*/
- protected Dimension calculateIdWidth(int maxwidth)
+ public Dimension calculateIdWidth(int maxwidth)
{
- Container c = new Container();
-
+ Container c = this;// new Container();
FontMetrics fm = c.getFontMetrics(
new Font(av.font.getName(), Font.ITALIC, av.font.getSize()));
int i = 0;
int idWidth = 0;
+ boolean withSuffix = av.getShowJVSuffix();
+
while ((i < al.getHeight()) && (al.getSequenceAt(i) != null))
{
SequenceI s = al.getSequenceAt(i);
- String id = s.getDisplayId(av.getShowJVSuffix());
+ String id = s.getDisplayId(withSuffix);
int stringWidth = fm.stringWidth(id);
idWidth = Math.max(idWidth, stringWidth);
i++;
/*
* Scroll down to make end of search results visible
*/
- setScrollValues(ranges.getStartRes(), starts + seqIndex - ends
- + 1);
+ setScrollValues(ranges.getStartRes(), starts + seqIndex - ends + 1);
}
/*
* Else results are already visible - no need to scroll
{
// BH 2018.04.18 comment: addNotify() is not appropriate here. We
// are not changing ancestors, and keyboard action listeners do
- // not need to be reset. addNotify() is a very expensive operation,
+ // not need to be reset, and most importantly, we can't be sure we are actually
+ // connected to resources.
+
+ // addNotify() is a very expensive operation,
// requiring a full re-layout of all parents and children.
+
// Note in JComponent:
+
// This method is called by the toolkit internally and should
// not be called directly by programs.
+
// I note that addNotify() is called in several areas of Jalview.
int annotationHeight = getAnnotationPanel().adjustPanelHeight();
annotationHeight = getAnnotationPanel()
.adjustForAlignFrame(adjustPanelHeight, annotationHeight);
+ // BH no!!
hscroll.addNotify();
annotationScroller.setPreferredSize(
new Dimension(annotationScroller.getWidth(), annotationHeight));
Dimension e = idPanel.getSize();
alabels.setSize(new Dimension(e.width, annotationHeight));
-
annotationSpaceFillerHolder.setPreferredSize(new Dimension(
annotationSpaceFillerHolder.getWidth(), annotationHeight));
annotationScroller.validate();
/**
* update alignment layout for viewport settings
- *
- * @param wrap
- * DOCUMENT ME!
*/
public void updateLayout()
{
+ ViewportRanges ranges = av.getRanges();
fontChanged();
setAnnotationVisible(av.isShowAnnotation());
boolean wrap = av.getWrapAlignment();
- ViewportRanges ranges = av.getRanges();
ranges.setStartSeq(0);
scalePanelHolder.setVisible(!wrap);
hscroll.setVisible(!wrap);
{
annotationScroller.setVisible(true);
annotationSpaceFillerHolder.setVisible(true);
- validateAnnotationDimensions(false);
}
+ idSpaceFillerPanel1.setVisible(!wrap);
+
+ /*
+ * defer dimension calculations if panel not yet added to a Window
+ * BH 2020.06.09
+ */
+ if (getTopLevelAncestor() == null)
+ {
+ repaint();
+ return;
+ }
+
+ if (!wrap && av.isShowAnnotation())
+ {
+ validateAnnotationDimensions(false);
+ }
int canvasWidth = getSeqPanel().seqCanvas.getWidth();
if (canvasWidth > 0)
{ // may not yet be laid out
}
}
- idSpaceFillerPanel1.setVisible(!wrap);
+ // System.out.println("ap dim = " + getSize());
+ // these values will go negative if getSize() returns (0,0):
+ // System.out.println("seqpan dim = " + getSeqPanel().getSize());
+ // System.out.println("seqcan dim = " + getSeqPanel().seqCanvas.getSize());
repaint();
}
* visible row to scroll to
*
*/
- public void setScrollValues(int xpos, int ypos)
+ public void setScrollValues(int x, int y)
{
- int x = xpos;
- int y = ypos;
if (av == null || av.getAlignment() == null)
{
{
int width = av.getAlignment().getVisibleWidth();
int height = av.getAlignment().getHeight();
-
- hextent = getSeqPanel().seqCanvas.getWidth() / av.getCharWidth();
- vextent = getSeqPanel().seqCanvas.getHeight() / av.getCharHeight();
-
- if (hextent > width)
- {
- hextent = width;
- }
-
- if (vextent > height)
- {
- vextent = height;
- }
-
- if ((hextent + x) > width)
- {
- x = width - hextent;
- }
-
- if ((vextent + y) > height)
- {
- y = height - vextent;
- }
-
- if (y < 0)
- {
- y = 0;
- }
-
- if (x < 0)
- {
- x = 0;
- }
-
- // update the scroll values
- hscroll.setValues(x, hextent, 0, width);
- vscroll.setValues(y, vextent, 0, height);
+
+ hextent = Math.min(getSeqPanel().seqCanvas.getWidth() / av.getCharWidth(), width);
+ vextent = Math.min(getSeqPanel().seqCanvas.getHeight() / av.getCharHeight(), height);
+
+ x = Math.max(0, Math.min(x, width - hextent));
+ y = Math.max(0, Math.min(y, height - vextent));
+
+ updateRanges(x, y);
+ updateScrollBars(x, y, width, height);
}
}
+ private void updateScrollBars(int x, int y, int width, int height)
+ {
+ hscroll.setValues(x, hextent, 0, width);
+ vscroll.setValues(y, vextent, 0, height);
+ }
+
/**
* Respond to adjustment event when horizontal or vertical scrollbar is
* changed
return;
}
- ViewportRanges ranges = av.getRanges();
-
if (evt.getSource() == hscroll)
{
+ if (!updateRanges(hscroll.getValue(), Integer.MIN_VALUE))
+ return;
+ }
+ else if (evt.getSource() == vscroll)
+ {
+ if (!updateRanges(Integer.MIN_VALUE, vscroll.getValue()))
+ return;
+ }
+ repaint();
+ }
+
+ private boolean updateRanges(int x, int y)
+ {
+ ViewportRanges ranges = av.getRanges();
+ boolean isChanged = false;
+ if (x != Integer.MIN_VALUE)
+ {
int oldX = ranges.getStartRes();
int oldwidth = ranges.getViewportWidth();
- int x = hscroll.getValue();
int width = getSeqPanel().seqCanvas.getWidth() / av.getCharWidth();
// if we're scrolling to the position we're already at, stop
// this prevents infinite recursion of events when the scroll/viewport
// ranges values are the same
- if ((x == oldX) && (width == oldwidth))
+ if (width > 0 && (x != oldX || width != oldwidth))
{
- return;
+ ranges.setViewportStartAndWidth(x, width);
+ isChanged = true;
}
- ranges.setViewportStartAndWidth(x, width);
}
- else if (evt.getSource() == vscroll)
+ if (y != Integer.MIN_VALUE)
{
int oldY = ranges.getStartSeq();
int oldheight = ranges.getViewportHeight();
- int y = vscroll.getValue();
int height = getSeqPanel().seqCanvas.getHeight() / av.getCharHeight();
// if we're scrolling to the position we're already at, stop
// this prevents infinite recursion of events when the scroll/viewport
// ranges values are the same
- if ((y == oldY) && (height == oldheight))
+ if (height > 0 && (y != oldY || height != oldheight))
{
- return;
+ ranges.setViewportStartAndHeight(y, height);
+ isChanged = true;
}
- ranges.setViewportStartAndHeight(y, height);
}
- repaint();
+ return isChanged;
}
/**
av.isShowAutocalculatedAbove());
sorter.sort(getAlignment().getAlignmentAnnotation(),
av.getSortAnnotationsBy());
- repaint();
if (updateStructures)
{
}
if (updateOverview)
{
-
+ alignFrame.repaint();
if (overviewPanel != null)
{
overviewPanel.updateOverviewImage();
}
+ } else {
+ invalidate(); // needed so that the id width adjuster works correctly
+ repaint();
}
}
@Override
public void paintComponent(Graphics g)
{
+ // BH OUCH!
invalidate(); // needed so that the id width adjuster works correctly
Dimension d = getIdPanel().getIdCanvas().getPreferredSize();
* though I still think this call should be elsewhere.
*/
ViewportRanges ranges = av.getRanges();
- setScrollValues(ranges.getStartRes(), ranges.getStartSeq());
+ // setScrollValues(ranges.getStartRes(), ranges.getStartSeq());
super.paintComponent(g);
}
* single graphics context), then reset to (0, scale height)
*/
alignmentGraphics.translate(alignmentGraphicsOffset, scaleHeight);
- getSeqPanel().seqCanvas.drawPanelForPrinting(alignmentGraphics, startRes,
- endRes, startSeq, endSeq - 1);
+ getSeqPanel().seqCanvas.drawPanelForPrinting(alignmentGraphics,
+ startRes, endRes, startSeq, endSeq - 1);
alignmentGraphics.translate(-alignmentGraphicsOffset, 0);
if (av.isShowAnnotation() && (endSeq == alignmentHeight))
*
* @throws PrinterException
*/
- public int printWrappedAlignment(int pageWidth, int pageHeight, int pageNumber,
- Graphics g) throws PrinterException
+ public int printWrappedAlignment(int pageWidth, int pageHeight,
+ int pageNumber, Graphics g) throws PrinterException
{
- getSeqPanel().seqCanvas.calculateWrappedGeometry(getWidth(),
- getHeight());
+ getSeqPanel().seqCanvas.calculateWrappedGeometry();
int annotationHeight = 0;
if (av.isShowAnnotation())
{
g.translate(idWidth, 0);
- getSeqPanel().seqCanvas.drawWrappedPanelForPrinting(g, pageWidth - idWidth,
- totalHeight, 0);
+ getSeqPanel().seqCanvas.drawWrappedPanelForPrinting(g,
+ pageWidth - idWidth, totalHeight, 0);
if ((pageNumber * pageHeight) < totalHeight)
{
String triplet = null;
if (av.getAlignment().isNucleotide())
{
- triplet = ResidueProperties.nucleotideName.get(seq
- .getCharAt(column) + "");
+ triplet = ResidueProperties.nucleotideName
+ .get(seq.getCharAt(column) + "");
}
else
{
- triplet = ResidueProperties.aa2Triplet.get(seq.getCharAt(column)
- + "");
+ triplet = ResidueProperties.aa2Triplet
+ .get(seq.getCharAt(column) + "");
}
if (triplet == null)
text.append("<area shape=\"rect\" coords=\"")
.append((idWidth + column * av.getCharWidth()))
.append(",").append(sy).append(",")
- .append((idWidth + (column + 1) * av.getCharWidth()))
+ .append((idWidth
+ + (column + 1) * av.getCharWidth()))
.append(",").append((av.getCharHeight() + sy))
.append("\"").append(" onMouseOver=\"toolTip('")
.append(seqPos).append(" ").append(triplet);
}
if (!Comparison.isGap(seq.getCharAt(column)))
{
- List<SequenceFeature> features = seq.findFeatures(column, column);
+ List<SequenceFeature> features = seq.findFeatures(column,
+ column);
for (SequenceFeature sf : features)
{
if (sf.isContactFeature())
public void propertyChange(PropertyChangeEvent evt)
{
// update this panel's scroll values based on the new viewport ranges values
- ViewportRanges ranges = av.getRanges();
- int x = ranges.getStartRes();
- int y = ranges.getStartSeq();
- setScrollValues(x, y);
+ updateScrollBarsFromRanges();
// now update any complementary alignment (its viewport ranges object
// is different so does not get automatically updated)
}
}
+ void updateScrollBarsFromRanges()
+ {
+ ViewportRanges ranges = av.getRanges();
+ setScrollValues(ranges.getStartRes(), ranges.getStartSeq());
+ }
+
/**
* Set the reference to the PCA/Tree chooser dialog for this panel. This
* reference should be nulled when the dialog is closed.
return calculationDialog;
}
+ /**
+ * From appletgui, for JalviewJS JavaScript interface
+ *
+ * preliminary - untested
+ *
+ * @param ostart
+ * @param end
+ * @param seqIndex
+ * @param scrollToNearest
+ * @param redrawOverview
+ * @return
+ */
+ public boolean scrollTo(int ostart, int end, int seqIndex,
+ boolean scrollToNearest, boolean redrawOverview)
+ {
+ int startv, endv, starts, ends;// , width;
+
+ int start = -1;
+ if (av.hasHiddenColumns())
+ {
+ AlignmentI al = av.getAlignment();
+ start = al.getHiddenColumns().absoluteToVisibleColumn(ostart);
+ end = al.getHiddenColumns().absoluteToVisibleColumn(end);
+ if (start == end)
+ {
+ if (!scrollToNearest && !al.getHiddenColumns().isVisible(ostart))
+ {
+ // don't scroll - position isn't visible
+ return false;
+ }
+ }
+ }
+ else
+ {
+ start = ostart;
+ }
+
+ ViewportRanges ranges = av.getRanges();
+ if (!av.getWrapAlignment())
+ {
+ /*
+ * int spos=av.getStartRes(),sqpos=av.getStartSeq(); if ((startv =
+ * av.getStartRes()) >= start) { spos=start-1; // seqIn //
+ * setScrollValues(start - 1, seqIndex); } else if ((endv =
+ * av.getEndRes()) <= end) { // setScrollValues(spos=startv + 1 + end -
+ * endv, seqIndex); spos=startv + 1 + end - endv; } else if ((starts =
+ * av.getStartSeq()) > seqIndex) { setScrollValues(av.getStartRes(),
+ * seqIndex); } else if ((ends = av.getEndSeq()) <= seqIndex) {
+ * setScrollValues(av.getStartRes(), starts + seqIndex - ends + 1); }
+ */
+
+ // below is scrolling logic up to Jalview 2.8.2
+ // if ((av.getStartRes() > end)
+ // || (av.getEndRes() < start)
+ // || ((av.getStartSeq() > seqIndex) || (av.getEndSeq() < seqIndex)))
+ // {
+ // if (start > av.getAlignment().getWidth() - hextent)
+ // {
+ // start = av.getAlignment().getWidth() - hextent;
+ // if (start < 0)
+ // {
+ // start = 0;
+ // }
+ //
+ // }
+ // if (seqIndex > av.getAlignment().getHeight() - vextent)
+ // {
+ // seqIndex = av.getAlignment().getHeight() - vextent;
+ // if (seqIndex < 0)
+ // {
+ // seqIndex = 0;
+ // }
+ // }
+ // setScrollValues(start, seqIndex);
+ // }
+ // logic copied from jalview.gui.AlignmentPanel:
+ if ((startv = ranges.getStartRes()) >= start)
+ {
+ /*
+ * Scroll left to make start of search results visible
+ */
+ setScrollValues(start - 1, seqIndex);
+ }
+ else if ((endv = ranges.getEndRes()) <= end)
+ {
+ /*
+ * Scroll right to make end of search results visible
+ */
+ setScrollValues(startv + 1 + end - endv, seqIndex);
+ }
+ else if ((starts = ranges.getStartSeq()) > seqIndex)
+ {
+ /*
+ * Scroll up to make start of search results visible
+ */
+ setScrollValues(ranges.getStartRes(), seqIndex);
+ }
+ else if ((ends = ranges.getEndSeq()) <= seqIndex)
+ {
+ /*
+ * Scroll down to make end of search results visible
+ */
+ setScrollValues(ranges.getStartRes(), starts + seqIndex - ends + 1);
+ }
+ /*
+ * Else results are already visible - no need to scroll
+ */
+ }
+ else
+ {
+ ranges.scrollToWrappedVisible(start);
+ }
+
+ paintAlignment(redrawOverview, false);
+ return true;
+ }
+
+ private boolean holdRepaint = false;
+
+ /**
+ * Called by IdCanvas and SeqPanel to defer painting until after JVP loading.
+ *
+ * @return true if holding
+ */
+ public boolean getHoldRepaint()
+ {
+ return holdRepaint;
+ }
+
+ /**
+ * Called by Jalview2xml while loading
+ *
+ * @param tf
+ */
+ public void setHoldRepaint(boolean tf)
+ {
+ if (holdRepaint == tf)
+ {
+ return;
+ }
+ holdRepaint = tf;
+ if (!tf)
+ {
+ repaint();
+ }
+ }
+
+ @Override
+ public void repaint()
+ {
+ if (holdRepaint)
+ {
+ // System.out.println("AP repaint holding");
+ // Platform.stackTrace();
+ return;
+ }
+ super.repaint();
+ }
+
+ public void selectAllSequences()
+ {
+ selectSequences(av.getAlignment().getSequences());
+ }
+
+ public void deselectAllSequences()
+ {
+ if (av.cursorMode)
+ {
+ getSeqPanel().keyboardNo1 = null;
+ getSeqPanel().keyboardNo2 = null;
+ }
+ av.setSelectionGroup(null);
+ av.getColumnSelection().clear();
+ av.setSearchResults(null);
+ getIdPanel().getIdCanvas().searchResults = null;
+ av.sendSelection();
+ // JAL-2034 - should delegate to
+ // alignPanel to decide if overview needs
+ // updating.
+ paintAlignment(false, false);
+ PaintRefresher.Refresh(this, av.getSequenceSetId());
+ }
+
+ public void selectSequences(List<SequenceI> seqs)
+ {
+ SequenceGroup sg = new SequenceGroup(seqs);
+ sg.setEndRes(av.getAlignment().getWidth() - 1);
+ av.setSelectionGroup(sg);
+ av.isSelectionGroupChanged(true);
+ av.sendSelection();
+ // JAL-2034 - should delegate to
+ // alignPanel to decide if overview needs
+ // updating.
+ paintAlignment(false, false);
+ PaintRefresher.Refresh(this, av.getSequenceSetId());
+ }
+
}
frame.setContentPane(this);
frame.setLayer(JLayeredPane.PALETTE_LAYER);
Desktop.addInternalFrame(frame,
- MessageManager.getString("label.choose_annotations"),
- MY_FRAME_WIDTH, MY_FRAME_HEIGHT, true);
+ MessageManager.getString("label.choose_annotations"), Desktop.FRAME_MAKE_VISIBLE,
+ MY_FRAME_WIDTH, MY_FRAME_HEIGHT, Desktop.FRAME_ALLOW_RESIZE, Desktop.FRAME_SET_MIN_SIZE_300);
}
protected void setShowSelected(boolean showSelected)
updateView();
}
};
- JalviewColourChooser.showColourChooser(Desktop.getDesktop(), ttl,
+ JalviewColourChooser.showColourChooser(Desktop.getDesktopPane(), ttl,
colourPanel.getBackground(), listener);
}
frame.setContentPane(this);
frame.setLayer(JLayeredPane.PALETTE_LAYER);
Dimension preferredSize = frame.getPreferredSize();
- Desktop.addInternalFrame(frame, "", true, preferredSize.width,
- preferredSize.height, true, true);
+ Desktop.addInternalFrame(frame, "", Desktop.FRAME_MAKE_VISIBLE, preferredSize.width,
+ preferredSize.height, Desktop.FRAME_ALLOW_RESIZE, Desktop.FRAME_ALLOW_ANY_SIZE);
}
/**
import jalview.util.Comparison;
import jalview.util.MessageManager;
import jalview.util.Platform;
+import jalview.workers.InformationThread;
import java.awt.Color;
import java.awt.Cursor;
pop.show(this, evt.getX(), evt.getY());
return;
}
+ final AlignmentAnnotation ann = aa[selectedRow];
+ final boolean isSequenceAnnotation = ann.sequenceRef != null;
item = new JMenuItem(EDITNAME);
item.addActionListener(this);
pop.add(item);
if (selectedRow < aa.length)
{
final String label = aa[selectedRow].label;
- if (!aa[selectedRow].autoCalculated)
+ if (!(aa[selectedRow].autoCalculated)
+ && !(InformationThread.HMM_CALC_ID.equals(ann.getCalcId())))
{
if (aa[selectedRow].graph == AlignmentAnnotation.NO_GRAPH)
{
pop.addSeparator();
// av and sequencegroup need to implement same interface for
item = new JCheckBoxMenuItem(TOGGLE_LABELSCALE,
- aa[selectedRow].scaleColLabel);
+ aa[selectedRow].scaleColLabel);
item.addActionListener(this);
pop.add(item);
}
consclipbrd.addActionListener(this);
pop.add(consclipbrd);
}
+ else if (InformationThread.HMM_CALC_ID.equals(ann.getCalcId()))
+ {
+ addHmmerMenu(pop, ann);
+ }
}
pop.show(this, evt.getX(), evt.getY());
}
/**
+ * Adds context menu options for (alignment or group) Hmmer annotation
+ *
+ * @param pop
+ * @param ann
+ */
+ protected void addHmmerMenu(JPopupMenu pop, final AlignmentAnnotation ann)
+ {
+ final boolean isGroupAnnotation = ann.groupRef != null;
+ pop.addSeparator();
+ final JCheckBoxMenuItem cbmi = new JCheckBoxMenuItem(
+ MessageManager.getString(
+ "label.ignore_below_background_frequency"),
+ isGroupAnnotation
+ ? ann.groupRef
+ .isIgnoreBelowBackground()
+ : ap.av.isIgnoreBelowBackground());
+ cbmi.addActionListener(new ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ if (isGroupAnnotation)
+ {
+ if (!ann.groupRef.isUseInfoLetterHeight())
+ {
+ ann.groupRef.setIgnoreBelowBackground(cbmi.getState());
+ // todo and recompute group annotation
+ }
+ }
+ else if (!ap.av.isInfoLetterHeight())
+ {
+ ap.av.setIgnoreBelowBackground(cbmi.getState(), ap);
+ // todo and recompute annotation
+ }
+ ap.alignmentChanged(); // todo not like this
+ }
+ });
+ pop.add(cbmi);
+ final JCheckBoxMenuItem letterHeight = new JCheckBoxMenuItem(
+ MessageManager.getString("label.use_info_for_height"),
+ isGroupAnnotation ? ann.groupRef.isUseInfoLetterHeight()
+ : ap.av.isInfoLetterHeight());
+ letterHeight.addActionListener(new ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ if (isGroupAnnotation)
+ {
+ ann.groupRef.setInfoLetterHeight((letterHeight.getState()));
+ ann.groupRef.setIgnoreBelowBackground(true);
+ // todo and recompute group annotation
+ }
+ else
+ {
+ ap.av.setInfoLetterHeight(letterHeight.getState(), ap);
+ ap.av.setIgnoreBelowBackground(true, ap);
+ // todo and recompute annotation
+ }
+ ap.alignmentChanged();
+ }
+ });
+ pop.add(letterHeight);
+ if (isGroupAnnotation)
+ {
+ final JCheckBoxMenuItem chist = new JCheckBoxMenuItem(
+ MessageManager.getString("label.show_group_histogram"),
+ ann.groupRef.isShowInformationHistogram());
+ chist.addActionListener(new ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ ann.groupRef.setShowInformationHistogram(chist.getState());
+ ap.repaint();
+ }
+ });
+ pop.add(chist);
+ final JCheckBoxMenuItem cprofl = new JCheckBoxMenuItem(
+ MessageManager.getString("label.show_group_logo"),
+ ann.groupRef.isShowHMMSequenceLogo());
+ cprofl.addActionListener(new ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ ann.groupRef.setShowHMMSequenceLogo(cprofl.getState());
+ ap.repaint();
+ }
+ });
+ pop.add(cprofl);
+ final JCheckBoxMenuItem cproflnorm = new JCheckBoxMenuItem(
+ MessageManager.getString("label.normalise_group_logo"),
+ ann.groupRef.isNormaliseHMMSequenceLogo());
+ cproflnorm.addActionListener(new ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ ann.groupRef
+ .setNormaliseHMMSequenceLogo(cproflnorm.getState());
+ // automatically enable logo display if we're clicked
+ ann.groupRef.setShowHMMSequenceLogo(true);
+ ap.repaint();
+ }
+ });
+ pop.add(cproflnorm);
+ }
+ else
+ {
+ final JCheckBoxMenuItem chist = new JCheckBoxMenuItem(
+ MessageManager.getString("label.show_histogram"),
+ av.isShowInformationHistogram());
+ chist.addActionListener(new ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ av.setShowInformationHistogram(chist.getState());
+ ap.repaint();
+ }
+ });
+ pop.add(chist);
+ final JCheckBoxMenuItem cprof = new JCheckBoxMenuItem(
+ MessageManager.getString("label.show_logo"),
+ av.isShowHMMSequenceLogo());
+ cprof.addActionListener(new ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ av.setShowHMMSequenceLogo(cprof.getState());
+ ap.repaint();
+ }
+ });
+ pop.add(cprof);
+ final JCheckBoxMenuItem cprofnorm = new JCheckBoxMenuItem(
+ MessageManager.getString("label.normalise_logo"),
+ av.isNormaliseHMMSequenceLogo());
+ cprofnorm.addActionListener(new ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ av.setShowHMMSequenceLogo(true);
+ av.setNormaliseHMMSequenceLogo(cprofnorm.getState());
+ ap.repaint();
+ }
+ });
+ pop.add(cprofnorm);
+ }
+ }
+
+ /**
* A helper method that adds menu options for calculation and visualisation of
* group and/or alignment consensus annotation to a popup menu. This is
* designed to be reusable for either unwrapped mode (popup menu is shown on
seqs, omitHidden, alignmentStartEnd);
Toolkit.getDefaultToolkit().getSystemClipboard()
- .setContents(new StringSelection(output), Desktop.instance);
+ .setContents(new StringSelection(output), Desktop.getInstance());
HiddenColumns hiddenColumns = null;
av.getAlignment().getHiddenColumns());
}
- Desktop.jalviewClipboard = new Object[] { seqs, ds, // what is the dataset
- // of a consensus
- // sequence ? need to
- // flag
- // sequence as special.
+ // what is the dataset of a consensus sequence?
+ // need to flag sequence as special.
+ Desktop.getInstance().jalviewClipboard = new Object[] { seqs, ds,
hiddenColumns };
}
- /**
- * DOCUMENT ME!
- *
- * @param g1
- * DOCUMENT ME!
- */
@Override
public void paintComponent(Graphics g)
{
*/
public AnnotationPanel(AlignmentPanel ap)
{
+ setName("AnnotationPanel");
ToolTipManager.sharedInstance().registerComponent(this);
ToolTipManager.sharedInstance().setInitialDelay(0);
ToolTipManager.sharedInstance().setDismissDelay(10000);
@Override
public void colourSelected(Color c)
{
- HiddenColumns hiddenColumns = av.getAlignment().getHiddenColumns();
+ HiddenColumns hiddenColumns = av.getAlignment()
+ .getHiddenColumns();
for (int index : av.getColumnSelection().getSelected())
{
if (hiddenColumns.isVisible(index))
}
fAnot[index].colour = c;
}
- }};
+ }
+ };
};
- JalviewColourChooser.showColourChooser(this,
- title, Color.black, listener);
+ JalviewColourChooser.showColourChooser(this, title, Color.black,
+ listener);
}
else
// HELIX, SHEET or STEM
}
if (dragMode == DragMode.Undefined)
- {
+ {
/*
* drag is diagonal - defer deciding whether to
* treat as up/down or left/right
*/
- return;
- }
-
+ return;
+ }
try
{
if (dragMode == DragMode.Resize)
int newHeight = Math.max(0, graphAnnotation.graphHeight + deltaY);
graphAnnotation.graphHeight = newHeight;
adjustPanelHeight();
+ setNoFastPaint();
ap.paintAlignment(false, false);
}
}
&& ann.annotations[column] != null)
{
tooltip = ann.annotations[column].description;
+ if ("".equals(tooltip))
+ {
+ tooltip = null;
+ }
}
return tooltip;
}
private volatile boolean imageFresh = false;
- private Rectangle visibleRect = new Rectangle(), clipBounds = new Rectangle();
+
+ private Rectangle visibleRect = new Rectangle(),
+ clipBounds = new Rectangle();
/**
* DOCUMENT ME!
@Override
public void paintComponent(Graphics g)
{
-
- // BH: note that this method is generally recommended to
- // call super.paintComponent(g). Otherwise, the children of this
- // component will not be rendered. That is not needed here
- // because AnnotationPanel does not have any children. It is
- // just a JPanel contained in a JViewPort.
+
+ // BH: note that this method is generally recommended to
+ // call super.paintComponent(g). Otherwise, the children of this
+ // component will not be rendered. That is not needed here
+ // because AnnotationPanel does not have any children. It is
+ // just a JPanel contained in a JViewPort.
computeVisibleRect(visibleRect);
-
+
g.setColor(Color.white);
g.fillRect(0, 0, visibleRect.width, visibleRect.height);
- if (image != null)
+ ViewportRanges ranges = av.getRanges();
+
+ if (allowFastPaint && image != null)
{
- // BH 2018 optimizing generation of new Rectangle().
- if (fastPaint || (visibleRect.width != (clipBounds = g.getClipBounds(clipBounds)).width)
- || (visibleRect.height != clipBounds.height))
+ // BH 2018 optimizing generation of new Rectangle().
+ if (fastPaint
+ || (visibleRect.width != (clipBounds = g
+ .getClipBounds(clipBounds)).width)
+ || (visibleRect.height != clipBounds.height))
{
-
-
- g.drawImage(image, 0, 0, this);
+ g.drawImage(image, 0, 0, this);
fastPaint = false;
return;
}
}
- imgWidth = (av.getRanges().getEndRes() - av.getRanges().getStartRes()
- + 1) * av.getCharWidth();
+
+ imgWidth = (ranges.getEndRes() - ranges.getStartRes() + 1)
+ * av.getCharWidth();
+
if (imgWidth < 1)
{
+ fastPaint = false;
return;
}
Graphics2D gg;
gg.setColor(Color.white);
gg.fillRect(0, 0, imgWidth, image.getHeight());
imageFresh = true;
- } else {
- gg = (Graphics2D) image.getGraphics();
+ }
+ else
+ {
+ gg = (Graphics2D) image.getGraphics();
}
-
- drawComponent(gg, av.getRanges().getStartRes(),
- av.getRanges().getEndRes() + 1);
+
+ drawComponent(gg, ranges.getStartRes(), av.getRanges().getEndRes() + 1);
gg.dispose();
imageFresh = false;
g.drawImage(image, 0, 0, this);
}
/**
- * set true to enable redraw timing debug output on stderr
- */
- private final boolean debugRedraw = false;
-
- /**
* non-Thread safe repaint
*
* @param horizontal
int er = av.getRanges().getEndRes() + 1;
int transX = 0;
+ if (er == sr + 1)
+ {
+ fastPaint = false;
+ return;
+ }
+
Graphics2D gg = (Graphics2D) image.getGraphics();
gg.copyArea(0, 0, imgWidth, getHeight(),
gg.translate(-transX, 0);
gg.dispose();
-
+
fastPaint = true;
// Call repaint on alignment panel so that repaints from other alignment
private int[] bounds = new int[2];
+ private boolean allowFastPaint;
+
@Override
public int[] getVisibleVRange()
{
ap = null;
image = null;
fadedImage = null;
-// gg = null;
+ // gg = null;
_mwl = null;
/*
}
return annotationHeight;
}
+
+ /**
+ * Clears the flag that allows a 'fast paint' on the next repaint, so
+ * requiring a full repaint
+ */
+ public void setNoFastPaint()
+ {
+ allowFastPaint = false;
+ }
+
}
import jalview.util.ImageMaker;
import jalview.util.MessageManager;
import jalview.util.Platform;
-
public class AppJmol extends StructureViewerBase
{
// ms to wait for Jmol to load files
.toArray(new SequenceI[sequencesForPdb.size()]);
i++;
}
-
// TODO: check if protocol is needed to be set, and if chains are
// autodiscovered.
jmb = new AppJmolBinding(this, ap.getStructureSelectionManager(),
seqColour.setSelected(true);
viewerColour.setSelected(false);
}
-
this.setBounds(viewerModel.getX(), viewerModel.getY(),
viewerModel.getWidth(), viewerModel.getHeight());
setViewId(viewid);
{
super.initMenus();
+
viewerColour
.setText(MessageManager.getString("label.colour_with_jmol"));
viewerColour.setToolTipText(MessageManager
@Override
public void showConsole(boolean showConsole)
{
+
if (showConsole)
{
if (splitPane == null)
*/
package jalview.gui;
-import jalview.api.StructureSelectionManagerProvider;
import jalview.datamodel.PDBEntry;
import jalview.datamodel.SequenceI;
import jalview.io.DataSourceType;
import jalview.io.StructureFile;
-import jalview.structure.StructureSelectionManager;
import jalview.util.MessageManager;
-import javax.swing.JOptionPane;
-
/**
- * GUI related routines for associating PDB files with sequences
+ * GUI related routines for associating PDB files with sequences. A single
+ * static method.
*
* @author JimP
*
public class AssociatePdbFileWithSeq
{
+ private AssociatePdbFileWithSeq()
+ {
+ // inaccessible
+ }
+
/**
- * assocate the given PDB file with
+ * Associate the given PDB file name or URL with a sequence. Do not map
+ * mouse-over events.
*
- * @param choice
+ * @param fileName
+ * or URL
+ * @param type
+ * will be DataType.FILE or DataType.URL
* @param sequence
+ * to associate
+ * @param prompt
+ * true if the user should be asked what to do if the specified file
+ * does not seem to contain PDB information (StructureChooser only)
+ * @return null if file is not found
*/
- public PDBEntry associatePdbWithSeq(String choice, DataSourceType file,
- SequenceI sequence, boolean prompt,
- StructureSelectionManagerProvider ssmp)
+ public static PDBEntry associatePdbWithSeq(String fileName,
+ DataSourceType type, SequenceI sequence, boolean prompt)
{
PDBEntry entry = new PDBEntry();
StructureFile pdbfile = null;
- pdbfile = StructureSelectionManager.getStructureSelectionManager(ssmp)
+ pdbfile = Desktop.getStructureSelectionManager()
.setMapping(false, new SequenceI[]
- { sequence }, null, choice, file);
+ { sequence }, null, fileName, type);
if (pdbfile == null)
{
// stacktrace already thrown so just return
return null;
}
- if (pdbfile.getId() == null)
- {
- String reply = null;
-
- if (prompt)
- {
- reply = JvOptionPane.showInternalInputDialog(Desktop.desktop,
- MessageManager
- .getString("label.couldnt_find_pdb_id_in_file"),
- MessageManager.getString("label.no_pdb_id_in_file"),
- JvOptionPane.QUESTION_MESSAGE);
- }
- if (reply == null)
- {
- return null;
- }
-
- entry.setId(reply);
- }
- else
+ String id = pdbfile.getId();
+ if (id == null && (id = (prompt
+ ? JvOptionPane.showInternalInputDialog(Desktop.getDesktopPane(),
+ MessageManager
+ .getString("label.couldnt_find_pdb_id_in_file"),
+ MessageManager.getString("label.no_pdb_id_in_file"),
+ JvOptionPane.QUESTION_MESSAGE)
+ : null)) == null)
{
- entry.setId(pdbfile.getId());
+ return null;
}
+ entry.setId(id);
entry.setType(PDBEntry.Type.FILE);
-
- if (pdbfile != null)
- {
- entry.setFile(choice);
- sequence.getDatasetSequence().addPDBId(entry);
- StructureSelectionManager.getStructureSelectionManager(ssmp)
- .registerPDBEntry(entry);
- }
+ entry.setFile(fileName);
+ sequence.getDatasetSequence().addPDBId(entry);
+ Desktop.getStructureSelectionManager()
+ .registerPDBEntry(entry);
return entry;
}
}
import jalview.analysis.TreeBuilder;
import jalview.analysis.scoremodels.ScoreModels;
import jalview.analysis.scoremodels.SimilarityParams;
+import jalview.api.AlignViewportI;
import jalview.api.analysis.ScoreModelI;
import jalview.api.analysis.SimilarityParamsI;
import jalview.bin.Cache;
import jalview.datamodel.SequenceGroup;
import jalview.util.MessageManager;
-
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import javax.swing.event.InternalFrameEvent;
/**
- * A dialog where a user can choose and action Tree or PCA calculation options
+ * A dialog where a user can choose and action Tree or PCA calculation options.
+ *
+ * Allows also for dialog-free static methods openPCAPanel(...) and
+ * openTreePanel(...) for scripted use.
+ *
*/
+@SuppressWarnings("serial")
public class CalculationChooser extends JPanel
{
/*
*/
private static boolean treeMatchGaps = true;
- private static final Font VERDANA_11PT = new Font("Verdana", 0, 11);
+ private static Font VERDANA_11PT;
private static final int MIN_TREE_SELECTION = 3;
private JCheckBox shorterSequence;
- final ComboBoxTooltipRenderer renderer = new ComboBoxTooltipRenderer();
+ private static ComboBoxTooltipRenderer renderer; // BH was not static
List<String> tips = new ArrayList<>();
private PCAPanel pcaPanel;
/**
+ * Open a new Tree panel on the desktop statically. Params are standard (not
+ * set by Groovy). No dialog is opened.
+ *
+ * @param af
+ * @param treeType
+ * @param modelName
+ * @return null if successful; the string
+ * "label.you_need_at_least_n_sequences" if number of sequences
+ * selected is inappropriate
+ */
+ public static Object openTreePanel(AlignFrame af, String treeType,
+ String modelName)
+ {
+ return openTreePanel(af, treeType, modelName, null);
+ }
+
+ /**
+ * public static method for JalviewJS API to open a PCAPanel without
+ * necessarily using a dialog.
+ *
+ * @param af
+ * @param modelName
+ * @return the PCAPanel, or the string "label.you_need_at_least_n_sequences"
+ * if number of sequences selected is inappropriate
+ */
+ public static Object openPcaPanel(AlignFrame af, String modelName)
+ {
+ return openPcaPanel(af, modelName, null);
+ }
+
+ /**
* Constructor
*
* @param af
paramsPanel.add(includeGappedColumns);
paramsPanel.add(shorterSequence);
+ if (VERDANA_11PT == null)
+ {
+ VERDANA_11PT = new Font("Verdana", 0, 11);
+ }
/*
* OK / Cancel buttons
*/
title = title + " (" + af.getViewport().getViewName() + ")";
}
- Desktop.addInternalFrame(frame, title, width, height, false);
+ Desktop.addInternalFrame(frame, title, Desktop.FRAME_MAKE_VISIBLE, width, height, Desktop.FRAME_NOT_RESIZABLE, Desktop.FRAME_SET_MIN_SIZE_300);
calcChoicePanel.doLayout();
revalidate();
/*
*/
protected JComboBox<String> buildModelOptionsList()
{
- final JComboBox<String> scoreModelsCombo = new JComboBox<>();
+ JComboBox<String> scoreModelsCombo = new JComboBox<>();
+ if (renderer == null)
+ {
+ renderer = new ComboBoxTooltipRenderer();
+ }
scoreModelsCombo.setRenderer(renderer);
/*
* for backwards compatibility with Jalview < 2.8 (JAL-2962)
*/
if (nucleotide && forPca
- && Cache.getDefault("BLOSUM62_PCA_FOR_NUCLEOTIDE", false))
+ && Cache.getDefault(Preferences.BLOSUM62_PCA_FOR_NUCLEOTIDE,
+ false))
{
filtered.add(scoreModels.getBlosum62());
}
*/
protected void openTreePanel(String modelName, SimilarityParamsI params)
{
+ Object ret = openTreePanel(af,
+ neighbourJoining.isSelected() ? TreeBuilder.NEIGHBOUR_JOINING
+ : TreeBuilder.AVERAGE_DISTANCE,
+ modelName, params);
+ if (ret instanceof String)
+ {
+ JvOptionPane.showMessageDialog(this, // was opening on Desktop?
+ MessageManager.formatMessage(
+ (String) ret,
+ MIN_TREE_SELECTION),
+ MessageManager.getString("label.not_enough_sequences"),
+ JvOptionPane.WARNING_MESSAGE);
+
+ }
+ }
+
+ /**
+ * Open a new PCA panel on the desktop
+ *
+ * @param modelName
+ * @param params
+ */
+ protected void openPcaPanel(String modelName, SimilarityParamsI params)
+ {
+ Object ret = openPcaPanel(af, modelName, params);
+ if (ret instanceof String)
+ {
+ JvOptionPane.showInternalMessageDialog(this,
+ MessageManager.formatMessage(
+ (String) ret,
+ MIN_PCA_SELECTION),
+ MessageManager
+ .getString("label.sequence_selection_insufficient"),
+ JvOptionPane.WARNING_MESSAGE);
+ }
+ else
+ {
+ // only used for test suite
+ pcaPanel = (PCAPanel) ret;
+ }
+
+ }
+
+ /**
+ * Open a new Tree panel on the desktop statically
+ *
+ * @param af
+ * @param treeType
+ * @param modelName
+ * @param params
+ * @return null, or the string "label.you_need_at_least_n_sequences" if number
+ * of sequences selected is inappropriate
+ */
+ public static Object openTreePanel(AlignFrame af, String treeType,
+ String modelName, SimilarityParamsI params)
+ {
+
/*
* gui validation shouldn't allow insufficient sequences here, but leave
* this check in in case this method gets exposed programmatically in future
*/
- AlignViewport viewport = af.getViewport();
+ AlignViewportI viewport = af.getViewport();
SequenceGroup sg = viewport.getSelectionGroup();
if (sg != null && sg.getSize() < MIN_TREE_SELECTION)
{
- JvOptionPane.showMessageDialog(Desktop.desktop,
- MessageManager.formatMessage(
- "label.you_need_at_least_n_sequences",
- MIN_TREE_SELECTION),
- MessageManager.getString("label.not_enough_sequences"),
- JvOptionPane.WARNING_MESSAGE);
- return;
+ return "label.you_need_at_least_n_sequences";
+ }
+
+ if (params == null)
+ {
+ params = getSimilarityParameters(false);
}
- String treeType = neighbourJoining.isSelected()
- ? TreeBuilder.NEIGHBOUR_JOINING
- : TreeBuilder.AVERAGE_DISTANCE;
af.newTreePanel(treeType, modelName, params);
+ return null;
}
/**
- * Open a new PCA panel on the desktop
+ * public static method for JalviewJS API
*
+ * @param af
* @param modelName
* @param params
+ * @return the PCAPanel, or null if number of sequences selected is
+ * inappropriate
*/
- protected void openPcaPanel(String modelName, SimilarityParamsI params)
+ public static Object openPcaPanel(AlignFrame af, String modelName,
+ SimilarityParamsI params)
{
- AlignViewport viewport = af.getViewport();
+ AlignViewportI viewport = af.getViewport();
/*
* gui validation shouldn't allow insufficient sequences here, but leave
* this check in in case this method gets exposed programmatically in future
+ *
+ *
*/
if (((viewport.getSelectionGroup() != null)
&& (viewport.getSelectionGroup().getSize() < MIN_PCA_SELECTION)
&& (viewport.getSelectionGroup().getSize() > 0))
|| (viewport.getAlignment().getHeight() < MIN_PCA_SELECTION))
{
- JvOptionPane.showInternalMessageDialog(this,
- MessageManager.formatMessage(
- "label.you_need_at_least_n_sequences",
- MIN_PCA_SELECTION),
- MessageManager
- .getString("label.sequence_selection_insufficient"),
- JvOptionPane.WARNING_MESSAGE);
- return;
+ return "label.you_need_at_least_n_sequences";
+ }
+
+ if (params == null)
+ {
+ params = getSimilarityParameters(true);
}
/*
* construct the panel and kick off its calculation thread
*/
- pcaPanel = new PCAPanel(af.alignPanel, modelName, params);
- new Thread(pcaPanel).start();
-
+ PCAPanel pcap = new PCAPanel(af.alignPanel, modelName, params);
+ new Thread(pcap).start();
+ return pcap;
}
/**
}
}
+
/**
* Returns a data bean holding parameters for similarity (or distance) model
* calculation
* @param doPCA
* @return
*/
- protected SimilarityParamsI getSimilarityParameters(boolean doPCA)
+ public static SimilarityParamsI getSimilarityParameters(
+ boolean doPCA)
{
// commented out: parameter choices read from gui widgets
// SimilarityParamsI params = new SimilarityParams(
return new SimilarityParams(includeGapGap, matchGap, includeGapResidue,
matchOnShortestLength);
+
}
/**
*/
package jalview.gui;
+
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import jalview.util.ImageMaker.TYPE;
import jalview.util.MessageManager;
import jalview.util.Platform;
-
/**
* GUI elements for handling an external chimera display
*
{
private JalviewChimeraBinding jmb;
+
/*
* Path to Chimera session file. This is set when an open Jalview/Chimera
* session is saved, or on restore from a Jalview project (if it holds the
*/
private String chimeraSessionFile = null;
+
private int myWidth = 500;
private int myHeight = 150;
});
viewerActionMenu.add(fetchAttributes);
}
+
@Override
protected void buildActionMenu()
{
return new JalviewChimeraBindingModel(this,
ap.getStructureSelectionManager(), pdbentrys, seqs, null);
}
-
/**
* Create a new viewer from saved session state data including Chimera session
* file
if (!jmb.launchChimera())
{
- JvOptionPane.showMessageDialog(Desktop.desktop,
+ JvOptionPane.showMessageDialog(Desktop.getDesktopPane(),
MessageManager.formatMessage("label.open_viewer_failed",
getViewerName()),
MessageManager.getString("label.error_loading_file"),
if (errormsgs.length() > 0)
{
- JvOptionPane.showInternalMessageDialog(Desktop.desktop,
+ JvOptionPane.showInternalMessageDialog(Desktop.getDesktopPane(),
MessageManager.formatMessage(
"label.pdb_entries_couldnt_be_retrieved", new Object[]
{ errormsgs.toString() }),
worker = null;
}
+
@Override
public void makePDBImage(TYPE imageType)
{
return jmb;
}
+
@Override
public ViewerType getViewerType()
{
ActionListener al = radioItem.getActionListeners()[0];
radioItem.removeActionListener(al);
int option = JvOptionPane.showInternalConfirmDialog(
- Desktop.desktop,
+ Desktop.getDesktopPane(),
MessageManager
.getString("label.remove_from_default_list"),
MessageManager
}
else
{
- Cache.applicationProperties.remove("USER_DEFINED_COLOURS");
+ Cache.removePropertyNoSave("USER_DEFINED_COLOURS");
}
}
}
.setGapCharacter(alignFrame.viewport.getGapCharacter());
StructureSelectionManager ssm = StructureSelectionManager
- .getStructureSelectionManager(Desktop.instance);
+ .getStructureSelectionManager(Desktop.getInstance());
/*
* register any new mappings for sequence mouseover etc
.println(MessageManager.getString("label.couldnt_read_data"));
if (!Jalview.isHeadlessMode())
{
- JvOptionPane.showInternalMessageDialog(Desktop.desktop,
+ JvOptionPane.showInternalMessageDialog(Desktop.getDesktopPane(),
AppletFormatAdapter.getSupportedFormats(),
MessageManager.getString("label.couldnt_read_data"),
JvOptionPane.WARNING_MESSAGE);
} catch (IOException ex)
{
- JvOptionPane.showInternalMessageDialog(Desktop.desktop, MessageManager
+ JvOptionPane.showInternalMessageDialog(Desktop.getDesktopPane(), MessageManager
.formatMessage("label.couldnt_read_pasted_text", new String[]
{ ex.toString() }),
MessageManager.getString("label.error_parsing_text"),
.println(MessageManager.getString("label.couldnt_read_data"));
if (!Jalview.isHeadlessMode())
{
- JvOptionPane.showInternalMessageDialog(Desktop.desktop,
+ JvOptionPane.showInternalMessageDialog(Desktop.getDesktopPane(),
AppletFormatAdapter.getSupportedFormats(),
MessageManager.getString("label.couldnt_read_data"),
JvOptionPane.WARNING_MESSAGE);
package jalview.gui;
import java.util.Locale;
-
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.util.List;
import java.util.ListIterator;
import java.util.Vector;
+import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import java.util.concurrent.FutureTask;
import java.util.concurrent.Semaphore;
import javax.swing.AbstractAction;
import jalview.api.AlignViewportI;
import jalview.api.AlignmentViewPanel;
+import jalview.api.StructureSelectionManagerProvider;
+import jalview.bin.ApplicationSingletonProvider;
+import jalview.bin.ApplicationSingletonProvider.ApplicationSingletonI;
import jalview.bin.Cache;
import jalview.bin.Jalview;
import jalview.gui.ImageExporter.ImageWriterI;
import jalview.io.IdentifyFile;
import jalview.io.JalviewFileChooser;
import jalview.io.JalviewFileView;
+import jalview.jbgui.GDesktop;
import jalview.jbgui.GSplitFrame;
import jalview.jbgui.GStructureViewer;
import jalview.project.Jalview2XML;
import jalview.util.ShortcutKeyMaskExWrapper;
import jalview.util.UrlConstants;
import jalview.viewmodel.AlignmentViewport;
+import jalview.ws.WSDiscovererI;
import jalview.ws.params.ParamManager;
import jalview.ws.utils.UrlDownloadClient;
* @author $author$
* @version $Revision: 1.155 $
*/
-public class Desktop extends jalview.jbgui.GDesktop
- implements DropTargetListener, ClipboardOwner, IProgressIndicator, jalview.api.StructureSelectionManagerProvider {
+@SuppressWarnings("serial")
+public class Desktop extends GDesktop
+ implements DropTargetListener, ClipboardOwner, IProgressIndicator,
+ StructureSelectionManagerProvider, ApplicationSingletonI
+
+{
private static final String CITATION;
static {
URL bg_logo_url = ChannelProperties.getImageURL("bg_logo." + String.valueOf(SplashScreen.logoSize));
public static HashMap<String, FileWriter> savingFiles = new HashMap<String, FileWriter>();
+ @SuppressWarnings("deprecation")
private JalviewChangeSupport changeSupport = new JalviewChangeSupport();
public static boolean nosplash = false;
-
/**
* news reader - null if it was never started.
*/
* @param listener
* @see jalview.gui.JalviewChangeSupport#addJalviewPropertyChangeListener(java.beans.PropertyChangeListener)
*/
- public void addJalviewPropertyChangeListener(PropertyChangeListener listener) {
+ @Deprecated
+ public void addJalviewPropertyChangeListener(
+ PropertyChangeListener listener)
+ {
changeSupport.addJalviewPropertyChangeListener(listener);
}
* @see jalview.gui.JalviewChangeSupport#addJalviewPropertyChangeListener(java.lang.String,
* java.beans.PropertyChangeListener)
*/
- public void addJalviewPropertyChangeListener(String propertyName, PropertyChangeListener listener) {
+ @Deprecated
+ public void addJalviewPropertyChangeListener(String propertyName,
+ PropertyChangeListener listener)
+ {
changeSupport.addJalviewPropertyChangeListener(propertyName, listener);
}
* @see jalview.gui.JalviewChangeSupport#removeJalviewPropertyChangeListener(java.lang.String,
* java.beans.PropertyChangeListener)
*/
- public void removeJalviewPropertyChangeListener(String propertyName, PropertyChangeListener listener) {
- changeSupport.removeJalviewPropertyChangeListener(propertyName, listener);
+ @Deprecated
+ public void removeJalviewPropertyChangeListener(String propertyName,
+ PropertyChangeListener listener)
+ {
+ changeSupport.removeJalviewPropertyChangeListener(propertyName,
+ listener);
}
- /** Singleton Desktop instance */
- public static Desktop instance;
+ private MyDesktopPane desktopPane;
- public static MyDesktopPane desktop;
+ public static MyDesktopPane getDesktopPane()
+ {
+ Desktop desktop = getInstance();
+ return desktop == null ? null : desktop.desktopPane;
+ }
- public static MyDesktopPane getDesktop() {
- // BH 2018 could use currentThread() here as a reference to a
- // Hashtable<Thread, MyDesktopPane> in JavaScript
- return desktop;
+ /**
+ * Answers an 'application scope' singleton instance of this class. Separate
+ * SwingJS 'applets' running in the same browser page will each have a
+ * distinct instance of Desktop.
+ *
+ * @return
+ */
+ public static Desktop getInstance()
+ {
+ return Jalview.isHeadlessMode() ? null
+ : (Desktop) ApplicationSingletonProvider
+ .getInstance(Desktop.class);
}
- static int openFrameCount = 0;
+ public static StructureSelectionManager getStructureSelectionManager()
+ {
+ return StructureSelectionManager
+ .getStructureSelectionManager(getInstance());
+ }
+
+ int openFrameCount = 0;
- static final int xOffset = 30;
+ final int xOffset = 30;
- static final int yOffset = 30;
+ final int yOffset = 30;
- public static jalview.ws.jws1.Discoverer discoverer;
+ public jalview.ws.jws1.Discoverer discoverer;
- public static Object[] jalviewClipboard;
+ public Object[] jalviewClipboard;
- public static boolean internalCopy = false;
+ public boolean internalCopy = false;
- static int fileLoadingCount = 0;
+ int fileLoadingCount = 0;
- class MyDesktopManager implements DesktopManager {
+ class MyDesktopManager implements DesktopManager
+ {
private DesktopManager delegate;
- public MyDesktopManager(DesktopManager delegate) {
+ public MyDesktopManager(DesktopManager delegate)
+ {
this.delegate = delegate;
}
@Override
- public void activateFrame(JInternalFrame f) {
- try {
+ public void activateFrame(JInternalFrame f)
+ {
+ try
+ {
delegate.activateFrame(f);
- } catch (NullPointerException npe) {
+ } catch (NullPointerException npe)
+ {
Point p = getMousePosition();
- instance.showPasteMenu(p.x, p.y);
+ showPasteMenu(p.x, p.y);
}
}
@Override
- public void beginDraggingFrame(JComponent f) {
+ public void beginDraggingFrame(JComponent f)
+ {
delegate.beginDraggingFrame(f);
}
@Override
- public void beginResizingFrame(JComponent f, int direction) {
+ public void beginResizingFrame(JComponent f, int direction)
+ {
delegate.beginResizingFrame(f, direction);
}
@Override
- public void closeFrame(JInternalFrame f) {
+ public void closeFrame(JInternalFrame f)
+ {
delegate.closeFrame(f);
}
@Override
- public void deactivateFrame(JInternalFrame f) {
+ public void deactivateFrame(JInternalFrame f)
+ {
delegate.deactivateFrame(f);
}
@Override
- public void deiconifyFrame(JInternalFrame f) {
+ public void deiconifyFrame(JInternalFrame f)
+ {
delegate.deiconifyFrame(f);
}
@Override
- public void dragFrame(JComponent f, int newX, int newY) {
- if (newY < 0) {
+ public void dragFrame(JComponent f, int newX, int newY)
+ {
+ if (newY < 0)
+ {
newY = 0;
}
delegate.dragFrame(f, newX, newY);
}
@Override
- public void endDraggingFrame(JComponent f) {
+ public void endDraggingFrame(JComponent f)
+ {
delegate.endDraggingFrame(f);
- desktop.repaint();
+ desktopPane.repaint();
}
@Override
- public void endResizingFrame(JComponent f) {
+ public void endResizingFrame(JComponent f)
+ {
delegate.endResizingFrame(f);
- desktop.repaint();
+ desktopPane.repaint();
}
@Override
- public void iconifyFrame(JInternalFrame f) {
+ public void iconifyFrame(JInternalFrame f)
+ {
delegate.iconifyFrame(f);
}
@Override
- public void maximizeFrame(JInternalFrame f) {
+ public void maximizeFrame(JInternalFrame f)
+ {
delegate.maximizeFrame(f);
}
@Override
- public void minimizeFrame(JInternalFrame f) {
+ public void minimizeFrame(JInternalFrame f)
+ {
delegate.minimizeFrame(f);
}
@Override
- public void openFrame(JInternalFrame f) {
+ public void openFrame(JInternalFrame f)
+ {
delegate.openFrame(f);
}
@Override
- public void resizeFrame(JComponent f, int newX, int newY, int newWidth, int newHeight) {
- if (newY < 0) {
+ public void resizeFrame(JComponent f, int newX, int newY, int newWidth,
+ int newHeight)
+ {
+ if (newY < 0)
+ {
newY = 0;
}
delegate.resizeFrame(f, newX, newY, newWidth, newHeight);
}
@Override
- public void setBoundsForFrame(JComponent f, int newX, int newY, int newWidth, int newHeight) {
+ public void setBoundsForFrame(JComponent f, int newX, int newY,
+ int newWidth, int newHeight)
+ {
delegate.setBoundsForFrame(f, newX, newY, newWidth, newHeight);
}
}
/**
- * Creates a new Desktop object.
+ * Private constructor enforces singleton pattern. It is called by reflection
+ * from ApplicationSingletonProvider.getInstance().
*/
- public Desktop() {
+ private Desktop()
+ {
super();
- /**
- * A note to implementors. It is ESSENTIAL that any activities that might block
- * are spawned off as threads rather than waited for during this constructor.
- */
- instance = this;
+ Cache.initLogger();
+ try
+ {
+ /**
+ * A note to implementors. It is ESSENTIAL that any activities that might
+ * block are spawned off as threads rather than waited for during this
+ * constructor.
+ */
- doConfigureStructurePrefs();
+ doConfigureStructurePrefs();
setTitle(ChannelProperties.getProperty("app_name") + " " + Cache.getProperty("VERSION"));
/**
}
});
- boolean selmemusage = Cache.getDefault("SHOW_MEMUSAGE", false);
+ boolean selmemusage = Cache.getDefault("SHOW_MEMUSAGE", false);
- boolean showjconsole = Cache.getDefault("SHOW_JAVA_CONSOLE", false);
- desktop = new MyDesktopPane(selmemusage);
+ boolean showjconsole = Cache.getDefault("SHOW_JAVA_CONSOLE", false);
+ desktopPane = new MyDesktopPane(selmemusage);
- showMemusage.setSelected(selmemusage);
- desktop.setBackground(Color.white);
+ showMemusage.setSelected(selmemusage);
+ desktopPane.setBackground(Color.white);
- getContentPane().setLayout(new BorderLayout());
- // alternate config - have scrollbars - see notes in JAL-153
- // JScrollPane sp = new JScrollPane();
- // sp.getViewport().setView(desktop);
- // getContentPane().add(sp, BorderLayout.CENTER);
+ getContentPane().setLayout(new BorderLayout());
+ // alternate config - have scrollbars - see notes in JAL-153
+ // JScrollPane sp = new JScrollPane();
+ // sp.getViewport().setView(desktop);
+ // getContentPane().add(sp, BorderLayout.CENTER);
- // BH 2018 - just an experiment to try unclipped JInternalFrames.
- if (Platform.isJS()) {
- getRootPane().putClientProperty("swingjs.overflow.hidden", "false");
- }
+ // BH 2018 - just an experiment to try unclipped JInternalFrames.
+ if (Platform.isJS())
+ {
+ getRootPane().putClientProperty("swingjs.overflow.hidden", "false");
+ }
- getContentPane().add(desktop, BorderLayout.CENTER);
- desktop.setDragMode(JDesktopPane.OUTLINE_DRAG_MODE);
+ getContentPane().add(desktopPane, BorderLayout.CENTER);
+ desktopPane.setDragMode(JDesktopPane.OUTLINE_DRAG_MODE);
- // This line prevents Windows Look&Feel resizing all new windows to maximum
- // if previous window was maximised
- desktop.setDesktopManager(new MyDesktopManager((Platform.isWindowsAndNotJS() ? new DefaultDesktopManager()
- : Platform.isAMacAndNotJS() ? new AquaInternalFrameManager(desktop.getDesktopManager())
- : desktop.getDesktopManager())));
- Rectangle dims = getLastKnownDimensions("");
- if (dims != null) {
- setBounds(dims);
- } else {
- Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
- int xPos = Math.max(5, (screenSize.width - 900) / 2);
- int yPos = Math.max(5, (screenSize.height - 650) / 2);
- setBounds(xPos, yPos, 900, 650);
- }
+ // This line prevents Windows Look&Feel resizing all new windows to
+ // maximum
+ // if previous window was maximised
+ desktopPane.setDesktopManager(new MyDesktopManager(
+ (Platform.isWindowsAndNotJS() ? new DefaultDesktopManager()
+ : Platform.isAMacAndNotJS()
+ ? new AquaInternalFrameManager(
+ desktopPane.getDesktopManager())
+ : desktopPane.getDesktopManager())));
- if (!Platform.isJS())
- /**
- * Java only
- *
- * @j2sIgnore
- */
- {
- jconsole = new Console(this, showjconsole);
- jconsole.setHeader(Cache.getVersionDetailsForConsole());
- showConsole(showjconsole);
+ Rectangle dims = getLastKnownDimensions("");
+ if (dims != null)
+ {
+ setBounds(dims);
+ }
+ else
+ {
+ Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
+ int xPos = Math.max(5, (screenSize.width - 900) / 2);
+ int yPos = Math.max(5, (screenSize.height - 650) / 2);
+ setBounds(xPos, yPos, 900, 650);
+ }
- showNews.setVisible(false);
+ if (!Platform.isJS())
+ /**
+ * Java only
+ *
+ * @j2sIgnore
+ */
+ {
+ jconsole = new Console(this, showjconsole);
+ jconsole.setHeader(Cache.getVersionDetailsForConsole());
+ showConsole(showjconsole);
- experimentalFeatures.setSelected(showExperimental());
+ showNews.setVisible(false); // not sure if we should only do this for interactive session?
- getIdentifiersOrgData();
+ experimentalFeatures.setSelected(showExperimental());
- checkURLLinks();
+ getIdentifiersOrgData();
- // Spawn a thread that shows the splashscreen
- if (!nosplash) {
- SwingUtilities.invokeLater(new Runnable() {
- @Override
- public void run() {
- new SplashScreen(true);
+ if (Jalview.isInteractive())
+ {
+ // disabled for SeqCanvasTest
+ checkURLLinks();
+
+ // Spawn a thread that shows the splashscreen
+ if (!nosplash) {
+ SwingUtilities.invokeLater(new Runnable()
+ {
+ @Override
+ public void run()
+ {
+ new SplashScreen(true);
+ }
+ });
}
- });
- }
- // Thread off a new instance of the file chooser - this reduces the time
- // it
- // takes to open it later on.
- new Thread(new Runnable() {
- @Override
- public void run() {
- Cache.log.debug("Filechooser init thread started.");
- String fileFormat = Cache.getProperty("DEFAULT_FILE_FORMAT");
- JalviewFileChooser.forRead(Cache.getProperty("LAST_DIRECTORY"), fileFormat);
- Cache.log.debug("Filechooser init thread finished.");
+ // Thread off a new instance of the file chooser - this reduces the
+ // time
+ // it
+ // takes to open it later on.
+ new Thread(new Runnable()
+ {
+ @Override
+ public void run()
+ {
+ Cache.log.debug("Filechooser init thread started.");
+ String fileFormat = Cache.getProperty("DEFAULT_FILE_FORMAT");
+ JalviewFileChooser.forRead(
+ Cache.getProperty("LAST_DIRECTORY"), fileFormat);
+ Cache.log.debug("Filechooser init thread finished.");
+ }
+ }).start();
+ // Add the service change listener
+ changeSupport.addJalviewPropertyChangeListener("services",
+ new PropertyChangeListener()
+ {
+
+ @Override
+ public void propertyChange(PropertyChangeEvent evt)
+ {
+ Cache.log.debug("Firing service changed event for "
+ + evt.getNewValue());
+ JalviewServicesChanged(evt);
+ }
+ });
}
- }).start();
- // Add the service change listener
- changeSupport.addJalviewPropertyChangeListener("services", new PropertyChangeListener() {
+ }
+ this.setDropTarget(new java.awt.dnd.DropTarget(desktopPane, this));
+
+ this.addWindowListener(new WindowAdapter()
+ {
@Override
- public void propertyChange(PropertyChangeEvent evt) {
- Cache.log.debug("Firing service changed event for " + evt.getNewValue());
- JalviewServicesChanged(evt);
+ public void windowClosing(WindowEvent evt)
+ {
+ quit();
}
});
- }
-
- this.setDropTarget(new java.awt.dnd.DropTarget(desktop, this));
- this.addWindowListener(new WindowAdapter() {
- @Override
- public void windowClosing(WindowEvent evt) {
- quit();
- }
- });
-
- MouseAdapter ma;
- this.addMouseListener(ma = new MouseAdapter() {
- @Override
- public void mousePressed(MouseEvent evt) {
- if (evt.isPopupTrigger()) // Mac
+ MouseAdapter ma;
+ this.addMouseListener(ma = new MouseAdapter()
+ {
+ @Override
+ public void mousePressed(MouseEvent evt)
{
- showPasteMenu(evt.getX(), evt.getY());
+ if (evt.isPopupTrigger()) // Mac
+ {
+ showPasteMenu(evt.getX(), evt.getY());
+ }
}
- }
-
- @Override
- public void mouseReleased(MouseEvent evt) {
- if (evt.isPopupTrigger()) // Windows
+ @Override
+ public void mouseReleased(MouseEvent evt)
{
- showPasteMenu(evt.getX(), evt.getY());
+ if (evt.isPopupTrigger()) // Windows
+ {
+ showPasteMenu(evt.getX(), evt.getY());
+ }
}
- }
- });
- desktop.addMouseListener(ma);
+ });
+ desktopPane.addMouseListener(ma);
+ } catch (Throwable t)
+ {
+ t.printStackTrace();
+ }
+
}
/**
*
* @return
*/
- public boolean showExperimental() {
- String experimental = Cache.getDefault(EXPERIMENTAL_FEATURES, Boolean.FALSE.toString());
+ public boolean showExperimental()
+ {
+ String experimental = Cache.getDefault(EXPERIMENTAL_FEATURES,
+ Boolean.FALSE.toString());
return Boolean.valueOf(experimental).booleanValue();
}
- public void doConfigureStructurePrefs() {
+ public void doConfigureStructurePrefs()
+ {
// configure services
StructureSelectionManager ssm = StructureSelectionManager.getStructureSelectionManager(this);
if (Cache.getDefault(Preferences.ADD_SS_ANN, true)) {
showNews(showNews.isSelected());
}
- void showNews(boolean visible) {
+ void showNews(boolean visible)
+ {
Cache.log.debug((visible ? "Showing" : "Hiding") + " news.");
showNews.setSelected(visible);
- if (visible && !jvnews.isVisible()) {
- new Thread(new Runnable() {
+ if (visible && !jvnews.isVisible())
+ {
+ new Thread(new Runnable()
+ {
@Override
- public void run() {
+ public void run()
+ {
long now = System.currentTimeMillis();
- Desktop.instance.setProgressBar(MessageManager.getString("status.refreshing_news"), now);
+ setProgressBar(MessageManager.getString("status.refreshing_news"),
+ now);
jvnews.refreshNews();
- Desktop.instance.setProgressBar(null, now);
+ setProgressBar(null, now);
jvnews.showNews();
}
}).start();
/**
* recover the last known dimensions for a jalview window
*
- * @param windowName - empty string is desktop, all other windows have unique
- * prefix
+ * @param windowName
+ * - empty string is desktop, all other windows have unique prefix
* @return null or last known dimensions scaled to current geometry (if last
* window geom was known)
*/
- Rectangle getLastKnownDimensions(String windowName) {
+ Rectangle getLastKnownDimensions(String windowName)
+ {
// TODO: lock aspect ratio for scaling desktop Bug #0058199
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
String x = Cache.getProperty(windowName + "SCREEN_X");
return null;
}
- void showPasteMenu(int x, int y) {
+ void showPasteMenu(int x, int y)
+ {
JPopupMenu popup = new JPopupMenu();
- JMenuItem item = new JMenuItem(MessageManager.getString("label.paste_new_window"));
- item.addActionListener(new ActionListener() {
+ JMenuItem item = new JMenuItem(
+ MessageManager.getString("label.paste_new_window"));
+ item.addActionListener(new ActionListener()
+ {
@Override
- public void actionPerformed(ActionEvent evt) {
+ public void actionPerformed(ActionEvent evt)
+ {
paste();
}
});
popup.show(this, x, y);
}
- public void paste() {
- try {
+ public void paste()
+ {
+ try
+ {
Clipboard c = Toolkit.getDefaultToolkit().getSystemClipboard();
Transferable contents = c.getContents(this);
- if (contents != null) {
- String file = (String) contents.getTransferData(DataFlavor.stringFlavor);
+ if (contents != null)
+ {
+ String file = (String) contents
+ .getTransferData(DataFlavor.stringFlavor);
- FileFormatI format = new IdentifyFile().identify(file, DataSourceType.PASTE);
+ FileFormatI format = new IdentifyFile().identify(file,
+ DataSourceType.PASTE);
new FileLoader().LoadFile(file, DataSourceType.PASTE, format);
}
- } catch (Exception ex) {
- System.out.println("Unable to paste alignment from system clipboard:\n" + ex);
+ } catch (Exception ex)
+ {
+ System.out.println(
+ "Unable to paste alignment from system clipboard:\n" + ex);
}
}
- /**
- * Adds and opens the given frame to the desktop
- *
- * @param frame Frame to show
- * @param title Visible Title
- * @param w width
- * @param h height
- */
- public static synchronized void addInternalFrame(final JInternalFrame frame, String title, int w, int h) {
- addInternalFrame(frame, title, true, w, h, true, false);
- }
- /**
- * Add an internal frame to the Jalview desktop
- *
- * @param frame Frame to show
- * @param title Visible Title
- * @param makeVisible When true, display frame immediately, otherwise, caller
- * must call setVisible themselves.
- * @param w width
- * @param h height
- */
- public static synchronized void addInternalFrame(final JInternalFrame frame, String title, boolean makeVisible, int w,
- int h) {
- addInternalFrame(frame, title, makeVisible, w, h, true, false);
- }
/**
- * Add an internal frame to the Jalview desktop and make it visible
+ * Adds and opens the given frame to the desktop that is visible, allowed to
+ * resize, and has a 300px minimum width.
*
- * @param frame Frame to show
- * @param title Visible Title
- * @param w width
- * @param h height
- * @param resizable Allow resize
- */
- public static synchronized void addInternalFrame(final JInternalFrame frame, String title, int w, int h,
- boolean resizable) {
- addInternalFrame(frame, title, true, w, h, resizable, false);
+ * @param frame
+ * Frame to show
+ * @param title
+ * Visible Title
+ * @param w
+ * width
+ * @param h
+ * height
+ */
+ public static synchronized void addInternalFrame(
+ final JInternalFrame frame, String title, int w, int h)
+ {
+ // 58 classes
+
+ addInternalFrame(frame, title, Desktop.FRAME_MAKE_VISIBLE, w, h,
+ FRAME_ALLOW_RESIZE, FRAME_SET_MIN_SIZE_300);
}
/**
- * Add an internal frame to the Jalview desktop
+ * Add an internal frame to the Jalview desktop that may optionally be
+ * visible, resizable, and allowed to be any size
*
- * @param frame Frame to show
- * @param title Visible Title
- * @param makeVisible When true, display frame immediately, otherwise, caller
- * must call setVisible themselves.
- * @param w width
- * @param h height
- * @param resizable Allow resize
- * @param ignoreMinSize Do not set the default minimum size for frame
- */
- public static synchronized void addInternalFrame(final JInternalFrame frame, String title, boolean makeVisible, int w,
- int h, boolean resizable, boolean ignoreMinSize) {
+ * @param frame
+ * Frame to show
+ * @param title
+ * Visible Title
+ * @param makeVisible
+ * When true, display frame immediately, otherwise, caller must call
+ * setVisible themselves.
+ * @param w
+ * width
+ * @param h
+ * height
+ * @param resizable
+ * Allow resize
+ * @param ignoreMinSize
+ * Do not set the default minimum size for frame
+ */
+ public static synchronized void addInternalFrame(
+ final JInternalFrame frame, String title, boolean makeVisible,
+ int w, int h, boolean resizable, boolean ignoreMinSize)
+ {
+ // 15 classes call this method directly.
+
// TODO: allow callers to determine X and Y position of frame (eg. via
// bounds object).
// the current window title
frame.setTitle(title);
- if (frame.getWidth() < 1 || frame.getHeight() < 1) {
+ if (frame.getWidth() < 1 || frame.getHeight() < 1)
+ {
frame.setSize(w, h);
}
- // THIS IS A PUBLIC STATIC METHOD, SO IT MAY BE CALLED EVEN IN
- // A HEADLESS STATE WHEN NO DESKTOP EXISTS. MUST RETURN
- // IF JALVIEW IS RUNNING HEADLESS
- // ///////////////////////////////////////////////
- if (instance == null || (System.getProperty("java.awt.headless") != null
- && System.getProperty("java.awt.headless").equals("true"))) {
- return;
- }
+ if (getInstance() != null)
+ getInstance().addFrame(frame, makeVisible, resizable,
+ ignoreMinSize);
+ }
+
+ // These can now by put into a single int flag, if desired:
+
+ public final static boolean FRAME_MAKE_VISIBLE = true;
+
+ public final static boolean FRAME_NOT_VISIBLE = false;
+
+ public final static boolean FRAME_ALLOW_RESIZE = true;
+
+ public final static boolean FRAME_NOT_RESIZABLE = false;
+
+ public final static boolean FRAME_ALLOW_ANY_SIZE = true;
+
+ public final static boolean FRAME_SET_MIN_SIZE_300 = false;
+
+ private void addFrame(JInternalFrame frame,
+ boolean makeVisible, boolean resizable,
+ boolean ignoreMinSize)
+ {
openFrameCount++;
- if (!ignoreMinSize) {
- frame.setMinimumSize(new Dimension(DEFAULT_MIN_WIDTH, DEFAULT_MIN_HEIGHT));
+
+ boolean isEmbedded = (Platform.getEmbeddedAttribute(frame, "id") != null);
+ boolean hasEmbeddedSize = (Platform.getDimIfEmbedded(frame, -1, -1) != null);
+ // Web page embedding allows us to ignore minimum size
+ ignoreMinSize |= hasEmbeddedSize;
+
+ if (!ignoreMinSize)
+ {
// Set default dimension for Alignment Frame window.
// The Alignment Frame window could be added from a number of places,
// hence,
// I did this here in order not to miss out on any Alignment frame.
- if (frame instanceof AlignFrame) {
- frame.setMinimumSize(new Dimension(ALIGN_FRAME_DEFAULT_MIN_WIDTH, ALIGN_FRAME_DEFAULT_MIN_HEIGHT));
+ if (frame instanceof AlignFrame)
+ {
+ frame.setMinimumSize(new Dimension(ALIGN_FRAME_DEFAULT_MIN_WIDTH,
+ ALIGN_FRAME_DEFAULT_MIN_HEIGHT));
+ } else {
+ frame.setMinimumSize(
+ new Dimension(DEFAULT_MIN_WIDTH, DEFAULT_MIN_HEIGHT));
+
}
}
frame.setIconifiable(resizable);
frame.setOpaque(Platform.isJS());
- if (frame.getX() < 1 && frame.getY() < 1) {
- frame.setLocation(xOffset * openFrameCount, yOffset * ((openFrameCount - 1) % 10) + yOffset);
+ if (!isEmbedded && frame.getX() < 1 && frame.getY() < 1)
+ {
+ frame.setLocation(xOffset * openFrameCount,
+ yOffset * ((openFrameCount - 1) % 10) + yOffset);
}
/*
- * add an entry for the new frame in the Window menu (and remove it when the
- * frame is closed)
+ * 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 InternalFrameAdapter() {
+ final JMenuItem menuItem = new JMenuItem(frame.getTitle());
+ frame.addInternalFrameListener(new InternalFrameAdapter()
+ {
@Override
- public void internalFrameActivated(InternalFrameEvent evt) {
- JInternalFrame itf = desktop.getSelectedFrame();
- if (itf != null) {
- if (itf instanceof AlignFrame) {
+ public void internalFrameActivated(InternalFrameEvent evt)
+ {
+ JInternalFrame itf = getDesktopPane().getSelectedFrame();
+ if (itf != null)
+ {
+ if (itf instanceof AlignFrame)
+ {
Jalview.setCurrentAlignFrame((AlignFrame) itf);
}
itf.requestFocus();
}
@Override
- public void internalFrameClosed(InternalFrameEvent evt) {
+ public void internalFrameClosed(InternalFrameEvent evt)
+ {
PaintRefresher.RemoveComponent(frame);
/*
- * defensive check to prevent frames being added half off the window
+ * defensive check to prevent frames being
+ * added half off the window
*/
- if (openFrameCount > 0) {
+ if (openFrameCount > 0)
+ {
openFrameCount--;
}
/*
* ensure no reference to alignFrame retained by menu item listener
*/
- if (menuItem.getActionListeners().length > 0) {
+ if (menuItem.getActionListeners().length > 0)
+ {
menuItem.removeActionListener(menuItem.getActionListeners()[0]);
}
- windowMenu.remove(menuItem);
+ getInstance().windowMenu.remove(menuItem);
}
});
- menuItem.addActionListener(new ActionListener() {
+ menuItem.addActionListener(new ActionListener()
+ {
@Override
- public void actionPerformed(ActionEvent e) {
- try {
+ public void actionPerformed(ActionEvent e)
+ {
+ try
+ {
frame.setSelected(true);
frame.setIcon(false);
- } catch (java.beans.PropertyVetoException ex) {
-
+ } catch (java.beans.PropertyVetoException ex)
+ {
+ // System.err.println(ex.toString());
}
}
});
setKeyBindings(frame);
- desktop.add(frame);
+ getDesktopPane().add(frame);
- windowMenu.add(menuItem);
+ getInstance().windowMenu.add(menuItem);
frame.toFront();
- try {
+ try
+ {
frame.setSelected(true);
frame.requestFocus();
- } catch (java.beans.PropertyVetoException ve) {
- } catch (java.lang.ClassCastException cex) {
+ } catch (java.beans.PropertyVetoException ve)
+ {
+ } catch (java.lang.ClassCastException cex)
+ {
Cache.log.warn(
- "Squashed a possible GUI implementation error. If you can recreate this, please look at https://issues.jalview.org/browse/JAL-869",
- cex);
+ "Squashed a possible GUI implementation error. If you can recreate this, please look at http://issues.jalview.org/browse/JAL-869",
+ cex);
}
}
/**
- * Add key bindings to a JInternalFrame so that Ctrl-W and Cmd-W will close the
- * window
+ * Add key bindings to a JInternalFrame so that Ctrl-W and Cmd-W will close
+ * the window
*
* @param frame
*/
- private static void setKeyBindings(JInternalFrame frame) {
- @SuppressWarnings("serial")
- final Action closeAction = new AbstractAction() {
+ private static void setKeyBindings(JInternalFrame frame)
+ {
+ final Action closeAction = new AbstractAction()
+ {
@Override
- public void actionPerformed(ActionEvent e) {
+ public void actionPerformed(ActionEvent e)
+ {
frame.dispose();
}
};
KeyStroke ctrlWKey = KeyStroke.getKeyStroke(KeyEvent.VK_W, InputEvent.CTRL_DOWN_MASK);
KeyStroke cmdWKey = KeyStroke.getKeyStroke(KeyEvent.VK_W, ShortcutKeyMaskExWrapper.getMenuShortcutKeyMaskEx());
- InputMap inputMap = frame.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
+ InputMap inputMap = frame
+ .getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
String ctrlW = ctrlWKey.toString();
inputMap.put(ctrlWKey, ctrlW);
inputMap.put(cmdWKey, ctrlW);
}
@Override
- public void lostOwnership(Clipboard clipboard, Transferable contents) {
- if (!internalCopy) {
- Desktop.jalviewClipboard = null;
+ public void lostOwnership(Clipboard clipboard, Transferable contents)
+ {
+ if (!internalCopy)
+ {
+ jalviewClipboard = null;
}
internalCopy = false;
}
@Override
- public void dragEnter(DropTargetDragEvent evt) {
+ public void dragEnter(DropTargetDragEvent evt)
+ {
}
@Override
- public void dragExit(DropTargetEvent evt) {
+ public void dragExit(DropTargetEvent evt)
+ {
}
@Override
- public void dragOver(DropTargetDragEvent evt) {
+ public void dragOver(DropTargetDragEvent evt)
+ {
}
@Override
- public void dropActionChanged(DropTargetDragEvent evt) {
+ public void dropActionChanged(DropTargetDragEvent evt)
+ {
}
/**
* DOCUMENT ME!
*
- * @param evt DOCUMENT ME!
+ * @param evt
+ * DOCUMENT ME!
*/
@Override
- public void drop(DropTargetDropEvent evt) {
+ public void drop(DropTargetDropEvent evt)
+ {
boolean success = true;
// JAL-1552 - acceptDrop required before getTransferable call for
// Java's Transferable for native dnd
List<Object> files = new ArrayList<>();
List<DataSourceType> protocols = new ArrayList<>();
- try {
- Desktop.transferFromDropTarget(files, protocols, evt, t);
- } catch (Exception e) {
+ try
+ {
+ transferFromDropTarget(files, protocols, evt, t);
+ } catch (Exception e)
+ {
e.printStackTrace();
success = false;
}
- if (files != null) {
- try {
- for (int i = 0; i < files.size(); i++) {
+ if (files != null)
+ {
+ try
+ {
+ for (int i = 0; i < files.size(); i++)
+ {
// BH 2018 File or String
Object file = files.get(i);
String fileName = file.toString();
- DataSourceType protocol = (protocols == null) ? DataSourceType.FILE : protocols.get(i);
+ DataSourceType protocol = (protocols == null)
+ ? DataSourceType.FILE
+ : protocols.get(i);
FileFormatI format = null;
- if (fileName.endsWith(".jar")) {
+ if (fileName.endsWith(".jar"))
+ {
format = FileFormat.Jalview;
- } else {
+ }
+ else
+ {
format = new IdentifyFile().identify(file, protocol);
}
- if (file instanceof File) {
+ if (file instanceof File)
+ {
Platform.cacheFileData((File) file);
}
new FileLoader().LoadFile(null, file, protocol, format);
}
- } catch (Exception ex) {
+ } catch (Exception ex)
+ {
success = false;
}
}
/**
* DOCUMENT ME!
*
- * @param e DOCUMENT ME!
+ * @param e
+ * DOCUMENT ME!
*/
@Override
- public void inputLocalFileMenuItem_actionPerformed(AlignViewport viewport) {
+ public void inputLocalFileMenuItem_actionPerformed(AlignViewport viewport)
+ {
String fileFormat = Cache.getProperty("DEFAULT_FILE_FORMAT");
- JalviewFileChooser chooser = JalviewFileChooser.forRead(Cache.getProperty("LAST_DIRECTORY"), fileFormat,
- BackupFiles.getEnabled());
+ JalviewFileChooser chooser = JalviewFileChooser.forRead(
+ Cache.getProperty("LAST_DIRECTORY"), fileFormat,
+ BackupFiles.getEnabled());
chooser.setFileView(new JalviewFileView());
- chooser.setDialogTitle(MessageManager.getString("label.open_local_file"));
+ chooser.setDialogTitle(
+ MessageManager.getString("label.open_local_file"));
chooser.setToolTipText(MessageManager.getString("action.open"));
- chooser.setResponseHandler(0, new Runnable() {
+ chooser.setResponseHandler(0, new Runnable()
+ {
@Override
- public void run() {
+ public void run()
+ {
File selectedFile = chooser.getSelectedFile();
Cache.setProperty("LAST_DIRECTORY", selectedFile.getParent());
/*
* Call IdentifyFile to verify the file contains what its extension implies.
- * Skip this step for dynamically added file formats, because IdentifyFile does
- * not know how to recognise them.
+ * Skip this step for dynamically added file formats, because
+ * IdentifyFile does not know how to recognise them.
*/
- if (FileFormats.getInstance().isIdentifiable(format)) {
- try {
- format = new IdentifyFile().identify(selectedFile, DataSourceType.FILE);
- } catch (FileFormatException e) {
+ if (FileFormats.getInstance().isIdentifiable(format))
+ {
+ try
+ {
+ format = new IdentifyFile().identify(selectedFile,
+ DataSourceType.FILE);
+ } catch (FileFormatException e)
+ {
// format = null; //??
}
}
- new FileLoader().LoadFile(viewport, selectedFile, DataSourceType.FILE, format);
+ new FileLoader().LoadFile(viewport, selectedFile,
+ DataSourceType.FILE, format);
}
});
chooser.showOpenDialog(this);
* @param viewport
*/
@Override
- public void inputURLMenuItem_actionPerformed(AlignViewport viewport) {
+ public void inputURLMenuItem_actionPerformed(AlignViewport viewport)
+ {
// This construct allows us to have a wider textfield
// for viewing
- JLabel label = new JLabel(MessageManager.getString("label.input_file_url"));
+ JLabel label = new JLabel(
+ MessageManager.getString("label.input_file_url"));
JPanel panel = new JPanel(new GridLayout(2, 1));
panel.add(label);
/*
- * the URL to fetch is input in Java: an editable combobox with history JS:
- * (pending JAL-3038) a plain text field
+ * the URL to fetch is
+ * Java: an editable combobox with history
+ * JS: (pending JAL-3038) a plain text field
*/
JComponent history;
- String urlBase = "https://www.";
- if (Platform.isJS()) {
+ String urlBase = "http://www.";
+ if (Platform.isJS())
+ {
history = new JTextField(urlBase, 35);
- } else
+ }
+ else
/**
* Java only
*
asCombo.setEditable(true);
asCombo.addItem(urlBase);
String historyItems = Cache.getProperty("RECENT_URL");
- if (historyItems != null) {
- for (String token : historyItems.split("\\t")) {
+ if (historyItems != null)
+ {
+ for (String token : historyItems.split("\\t"))
+ {
asCombo.addItem(token);
}
}
Object[] options = new Object[] { MessageManager.getString("action.ok"),
MessageManager.getString("action.cancel") };
- Runnable action = new Runnable() {
+ Runnable action = new Runnable()
+ {
@Override
- public void run() {
+ public void run()
+ {
@SuppressWarnings("unchecked")
String url = (history instanceof JTextField ? ((JTextField) history).getText()
: ((JComboBox<String>) history).getEditor().getItem().toString().trim());
}
} else {
FileFormatI format = null;
- try {
+ try
+ {
format = new IdentifyFile().identify(url, DataSourceType.URL);
- } catch (FileFormatException e) {
+ } catch (FileFormatException e)
+ {
// TODO revise error handling, distinguish between
// URL not found and response not valid
}
- if (format == null) {
- String msg = MessageManager.formatMessage("label.couldnt_locate", url);
- JvOptionPane.showInternalMessageDialog(Desktop.desktop, msg,
- MessageManager.getString("label.url_not_found"), JvOptionPane.WARNING_MESSAGE);
+ if (format == null)
+ {
+ String msg = MessageManager
+ .formatMessage("label.couldnt_locate", url);
+ JvOptionPane.showInternalMessageDialog(getDesktopPane(), msg,
+ MessageManager.getString("label.url_not_found"),
+ JvOptionPane.WARNING_MESSAGE);
return;
}
- if (viewport != null) {
- new FileLoader().LoadFile(viewport, url, DataSourceType.URL, format);
- } else {
+ if (viewport != null)
+ {
+ new FileLoader().LoadFile(viewport, url, DataSourceType.URL,
+ format);
+ }
+ else
+ {
new FileLoader().LoadFile(url, DataSourceType.URL, format);
}
}
}
};
- String dialogOption = MessageManager.getString("label.input_alignment_from_url");
- JvOptionPane.newOptionDialog(desktop).setResponseHandler(0, action).showInternalDialog(panel, dialogOption,
- JvOptionPane.YES_NO_CANCEL_OPTION, JvOptionPane.PLAIN_MESSAGE, null, options,
- MessageManager.getString("action.ok"));
+ String dialogOption = MessageManager
+ .getString("label.input_alignment_from_url");
+ JvOptionPane.newOptionDialog(desktopPane).setResponseHandler(0, action)
+ .showInternalDialog(panel, dialogOption,
+ JvOptionPane.YES_NO_CANCEL_OPTION,
+ JvOptionPane.PLAIN_MESSAGE, null, options,
+ MessageManager.getString("action.ok"));
}
/**
* Opens the CutAndPaste window for the user to paste an alignment in to
*
- * @param viewPanel - if not null, the pasted alignment is added to the current
- * alignment; if null, to a new alignment window
+ * @param viewPanel
+ * - if not null, the pasted alignment is added to the current
+ * alignment; if null, to a new alignment window
*/
@Override
- public void inputTextboxMenuItem_actionPerformed(AlignmentViewPanel viewPanel) {
+ public void inputTextboxMenuItem_actionPerformed(
+ AlignmentViewPanel viewPanel)
+ {
CutAndPasteTransfer cap = new CutAndPasteTransfer();
cap.setForInput(viewPanel);
- Desktop.addInternalFrame(cap, MessageManager.getString("label.cut_paste_alignmen_file"), true, 600, 500);
+ addInternalFrame(cap,
+ MessageManager.getString("label.cut_paste_alignmen_file"),
+ FRAME_MAKE_VISIBLE, 600, 500, FRAME_ALLOW_RESIZE,
+ FRAME_SET_MIN_SIZE_300);
}
/*
* Exit the program
*/
@Override
- public void quit() {
+ public void quit()
+ {
Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
Cache.setProperty("SCREENGEOMETRY_WIDTH", screen.width + "");
Cache.setProperty("SCREENGEOMETRY_HEIGHT", screen.height + "");
- storeLastKnownDimensions("", new Rectangle(getBounds().x, getBounds().y, getWidth(), getHeight()));
+ storeLastKnownDimensions("", new Rectangle(getBounds().x, getBounds().y,
+ getWidth(), getHeight()));
- if (jconsole != null) {
+ if (jconsole != null)
+ {
storeLastKnownDimensions("JAVA_CONSOLE_", jconsole.getBounds());
jconsole.stopConsole();
}
- if (jvnews != null) {
+ if (jvnews != null)
+ {
storeLastKnownDimensions("JALVIEW_RSS_WINDOW_", jvnews.getBounds());
}
- if (dialogExecutor != null) {
+ if (dialogExecutor != null)
+ {
dialogExecutor.shutdownNow();
}
closeAll_actionPerformed(null);
- if (groovyConsole != null) {
+ if (groovyConsole != null)
+ {
// suppress a possible repeat prompt to save script
groovyConsole.setDirty(false);
groovyConsole.exit();
System.exit(0);
}
- private void storeLastKnownDimensions(String string, Rectangle jc) {
- Cache.log.debug("Storing last known dimensions for " + string + ": x:" + jc.x + " y:" + jc.y + " width:" + jc.width
- + " height:" + jc.height);
+ private void storeLastKnownDimensions(String string, Rectangle jc)
+ {
+ Cache.log.debug("Storing last known dimensions for " + string + ": x:"
+ + jc.x + " y:" + jc.y + " width:" + jc.width + " height:"
+ + jc.height);
Cache.setProperty(string + "SCREEN_X", jc.x + "");
Cache.setProperty(string + "SCREEN_Y", jc.y + "");
/**
* DOCUMENT ME!
*
- * @param e DOCUMENT ME!
+ * @param e
+ * DOCUMENT ME!
*/
@Override
- public void aboutMenuItem_actionPerformed(ActionEvent e) {
- new Thread(new Runnable() {
+ public void aboutMenuItem_actionPerformed(ActionEvent e)
+ {
+ new Thread(new Runnable()
+ {
@Override
- public void run() {
+ public void run()
+ {
new SplashScreen(false);
}
}).start();
/**
* Returns the html text for the About screen, including any available version
- * number, build details, author details and citation reference, but without the
- * enclosing {@code html} tags
+ * number, build details, author details and citation reference, but without
+ * the enclosing {@code html} tags
*
* @return
*/
- public String getAboutMessage() {
+ public String getAboutMessage()
+ {
StringBuilder message = new StringBuilder(1024);
message.append("<div style=\"font-family: sans-serif;\">").append("<h1><strong>Version: ")
.append(Cache.getProperty("VERSION")).append("</strong></h1>").append("<strong>Built: <em>")
message.append(CITATION);
message.append("</div>");
-
return message.toString();
}
}
@Override
- public void closeAll_actionPerformed(ActionEvent e) {
+ 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++) {
- try {
+ JInternalFrame[] frames = desktopPane.getAllFrames();
+ for (int i = 0; i < frames.length; i++)
+ {
+ try
+ {
frames[i].setClosed(true);
- } catch (java.beans.PropertyVetoException ex) {
+ } catch (java.beans.PropertyVetoException ex)
+ {
}
}
Jalview.setCurrentAlignFrame(null);
* reset state of singleton objects as appropriate (clear down session state
* when all windows are closed)
*/
- StructureSelectionManager ssm = StructureSelectionManager.getStructureSelectionManager(this);
- if (ssm != null) {
+ StructureSelectionManager ssm = StructureSelectionManager
+ .getStructureSelectionManager(this);
+ if (ssm != null)
+ {
ssm.resetAll();
}
}
@Override
- public void raiseRelated_actionPerformed(ActionEvent e) {
+ public void raiseRelated_actionPerformed(ActionEvent e)
+ {
reorderAssociatedWindows(false, false);
}
@Override
- public void minimizeAssociated_actionPerformed(ActionEvent e) {
+ public void minimizeAssociated_actionPerformed(ActionEvent e)
+ {
reorderAssociatedWindows(true, false);
}
- void closeAssociatedWindows() {
+ void closeAssociatedWindows()
+ {
reorderAssociatedWindows(false, true);
}
* ActionEvent)
*/
@Override
- protected void garbageCollect_actionPerformed(ActionEvent e) {
+ protected void garbageCollect_actionPerformed(ActionEvent e)
+ {
// We simply collect the garbage
Cache.log.debug("Collecting garbage...");
System.gc();
/*
* (non-Javadoc)
*
- * @see jalview.jbgui.GDesktop#showMemusage_actionPerformed(java.awt.event.
- * ActionEvent )
+ * @see
+ * jalview.jbgui.GDesktop#showMemusage_actionPerformed(java.awt.event.ActionEvent
+ * )
*/
@Override
- protected void showMemusage_actionPerformed(ActionEvent e) {
- desktop.showMemoryUsage(showMemusage.isSelected());
+ protected void showMemusage_actionPerformed(ActionEvent e)
+ {
+ desktopPane.showMemoryUsage(showMemusage.isSelected());
}
/*
* )
*/
@Override
- protected void showConsole_actionPerformed(ActionEvent e) {
+ protected void showConsole_actionPerformed(ActionEvent e)
+ {
showConsole(showConsole.isSelected());
}
*
* @param selected
*/
- void showConsole(boolean selected) {
+ void showConsole(boolean selected)
+ {
// TODO: decide if we should update properties file
if (jconsole != null) // BH 2018
{
showConsole.setSelected(selected);
- Cache.setProperty("SHOW_JAVA_CONSOLE", Boolean.valueOf(selected).toString());
+ Cache.setProperty("SHOW_JAVA_CONSOLE",
+ Boolean.valueOf(selected).toString());
jconsole.setVisible(selected);
}
}
- void reorderAssociatedWindows(boolean minimize, boolean close) {
- JInternalFrame[] frames = desktop.getAllFrames();
- if (frames == null || frames.length < 1) {
+ void reorderAssociatedWindows(boolean minimize, boolean close)
+ {
+ JInternalFrame[] frames = desktopPane.getAllFrames();
+ if (frames == null || frames.length < 1)
+ {
return;
}
- AlignmentViewport source = null, target = null;
- if (frames[0] instanceof AlignFrame) {
+ AlignViewportI source = null;
+ AlignViewportI target = null;
+ if (frames[0] instanceof AlignFrame)
+ {
source = ((AlignFrame) frames[0]).getCurrentView();
- } else if (frames[0] instanceof TreePanel) {
+ }
+ else if (frames[0] instanceof TreePanel)
+ {
source = ((TreePanel) frames[0]).getViewPort();
- } else if (frames[0] instanceof PCAPanel) {
+ }
+ else if (frames[0] instanceof PCAPanel)
+ {
source = ((PCAPanel) frames[0]).av;
- } else if (frames[0].getContentPane() instanceof PairwiseAlignPanel) {
+ }
+ else if (frames[0].getContentPane() instanceof PairwiseAlignPanel)
+ {
source = ((PairwiseAlignPanel) frames[0].getContentPane()).av;
}
- if (source != null) {
- for (int i = 0; i < frames.length; i++) {
+ if (source != null)
+ {
+ for (int i = 0; i < frames.length; i++)
+ {
target = null;
- if (frames[i] == null) {
+ if (frames[i] == null)
+ {
continue;
}
- if (frames[i] instanceof AlignFrame) {
+ if (frames[i] instanceof AlignFrame)
+ {
target = ((AlignFrame) frames[i]).getCurrentView();
- } else if (frames[i] instanceof TreePanel) {
+ }
+ else if (frames[i] instanceof TreePanel)
+ {
target = ((TreePanel) frames[i]).getViewPort();
- } else if (frames[i] instanceof PCAPanel) {
+ }
+ else if (frames[i] instanceof PCAPanel)
+ {
target = ((PCAPanel) frames[i]).av;
- } else if (frames[i].getContentPane() instanceof PairwiseAlignPanel) {
+ }
+ else if (frames[i].getContentPane() instanceof PairwiseAlignPanel)
+ {
target = ((PairwiseAlignPanel) frames[i].getContentPane()).av;
}
- if (source == target) {
- try {
- if (close) {
+ if (source == target)
+ {
+ try
+ {
+ if (close)
+ {
frames[i].setClosed(true);
- } else {
+ }
+ else
+ {
frames[i].setIcon(minimize);
- if (!minimize) {
+ if (!minimize)
+ {
frames[i].toFront();
}
}
- } catch (java.beans.PropertyVetoException ex) {
+ } catch (java.beans.PropertyVetoException ex)
+ {
}
}
}
/**
* DOCUMENT ME!
*
- * @param e DOCUMENT ME!
+ * @param e
+ * DOCUMENT ME!
*/
@Override
protected void preferences_actionPerformed(ActionEvent e) {
* Jalview project file
*/
@Override
- public void saveState_actionPerformed() {
+ public void saveState_actionPerformed()
+ {
saveState_actionPerformed(false);
}
- public void saveState_actionPerformed(boolean saveAs) {
+ public void saveState_actionPerformed(boolean saveAs)
+ {
java.io.File projectFile = getProjectFile();
// autoSave indicates we already have a file and don't need to ask
- boolean autoSave = projectFile != null && !saveAs && BackupFiles.getEnabled();
+ boolean autoSave = projectFile != null && !saveAs
+ && BackupFiles.getEnabled();
// System.out.println("autoSave="+autoSave+", projectFile='"+projectFile+"',
// saveAs="+saveAs+", Backups
// "+(BackupFiles.getEnabled()?"enabled":"disabled"));
boolean approveSave = false;
- if (!autoSave) {
- JalviewFileChooser chooser = new JalviewFileChooser("jvp", "Jalview Project");
+ if (!autoSave)
+ {
+ JalviewFileChooser chooser = new JalviewFileChooser("jvp",
+ "Jalview Project");
chooser.setFileView(new JalviewFileView());
chooser.setDialogTitle(MessageManager.getString("label.save_state"));
int value = chooser.showSaveDialog(this);
- if (value == JalviewFileChooser.APPROVE_OPTION) {
+ if (value == JalviewFileChooser.APPROVE_OPTION)
+ {
projectFile = chooser.getSelectedFile();
setProjectFile(projectFile);
approveSave = true;
}
}
-
if (approveSave || autoSave) {
final Desktop me = this;
final java.io.File chosenFile = projectFile;
- new Thread(new Runnable() {
+ new Thread(new Runnable()
+ {
@Override
- public void run() {
+ public void run()
+ {
// TODO: refactor to Jalview desktop session controller action.
- setProgressBar(
- MessageManager.formatMessage("label.saving_jalview_project", new Object[] { chosenFile.getName() }),
- chosenFile.hashCode());
+ setProgressBar(MessageManager.formatMessage(
+ "label.saving_jalview_project", new Object[]
+ { chosenFile.getName() }), chosenFile.hashCode());
Cache.setProperty("LAST_DIRECTORY", chosenFile.getParent());
// TODO catch and handle errors for savestate
// TODO prevent user from messing with the Desktop whilst we're saving
- try {
+ try
+ {
boolean doBackup = BackupFiles.getEnabled();
- BackupFiles backupfiles = doBackup ? new BackupFiles(chosenFile) : null;
+ BackupFiles backupfiles = doBackup ? new BackupFiles(chosenFile)
+ : null;
- new Jalview2XML().saveState(doBackup ? backupfiles.getTempFile() : chosenFile);
+ new Jalview2XML().saveState(
+ doBackup ? backupfiles.getTempFile() : chosenFile);
- if (doBackup) {
+ if (doBackup)
+ {
backupfiles.setWriteSuccess(true);
backupfiles.rollBackupsAndRenameTempFile();
}
- } catch (OutOfMemoryError oom) {
- new OOMWarning("Whilst saving current state to " + chosenFile.getName(), oom);
- } catch (Exception ex) {
- Cache.log.error("Problems whilst trying to save to " + chosenFile.getName(), ex);
+ } catch (OutOfMemoryError oom)
+ {
+ new OOMWarning("Whilst saving current state to "
+ + chosenFile.getName(), oom);
+ } catch (Exception ex)
+ {
+ Cache.log.error("Problems whilst trying to save to "
+ + chosenFile.getName(), ex);
JvOptionPane.showMessageDialog(me,
- MessageManager.formatMessage("label.error_whilst_saving_current_state_to",
- new Object[] { chosenFile.getName() }),
- MessageManager.getString("label.couldnt_save_project"), JvOptionPane.WARNING_MESSAGE);
+ MessageManager.formatMessage(
+ "label.error_whilst_saving_current_state_to",
+ new Object[]
+ { chosenFile.getName() }),
+ MessageManager.getString("label.couldnt_save_project"),
+ JvOptionPane.WARNING_MESSAGE);
}
setProgressBar(null, chosenFile.hashCode());
}
}
@Override
- public void saveAsState_actionPerformed(ActionEvent e) {
+ public void saveAsState_actionPerformed(ActionEvent e)
+ {
saveState_actionPerformed(true);
}
- private void setProjectFile(File choice) {
+ private void setProjectFile(File choice)
+ {
this.projectFile = choice;
}
- public File getProjectFile() {
+ public File getProjectFile()
+ {
return this.projectFile;
}
* Jalview project
*/
@Override
- public void loadState_actionPerformed() {
+ public void loadState_actionPerformed()
+ {
final String[] suffix = new String[] { "jvp", "jar" };
- final String[] desc = new String[] { "Jalview Project", "Jalview Project (old)" };
- JalviewFileChooser chooser = new JalviewFileChooser(Cache.getProperty("LAST_DIRECTORY"), suffix, desc,
- "Jalview Project", true, BackupFiles.getEnabled()); // last two
- // booleans:
- // allFiles,
+ final String[] desc = new String[] { "Jalview Project",
+ "Jalview Project (old)" };
+ JalviewFileChooser chooser = new JalviewFileChooser(
+ Cache.getProperty("LAST_DIRECTORY"), suffix, desc,
+ "Jalview Project", true, BackupFiles.getEnabled()); // last two
+ // booleans:
+ // allFiles,
// allowBackupFiles
chooser.setFileView(new JalviewFileView());
chooser.setDialogTitle(MessageManager.getString("label.restore_state"));
- chooser.setResponseHandler(0, new Runnable() {
+ chooser.setResponseHandler(0, new Runnable()
+ {
@Override
- public void run() {
+ public void run()
+ {
File selectedFile = chooser.getSelectedFile();
setProjectFile(selectedFile);
String choice = selectedFile.getAbsolutePath();
Cache.setProperty("LAST_DIRECTORY", selectedFile.getParent());
- new Thread(new Runnable() {
+ new Thread(new Runnable()
+ {
@Override
- public void run() {
- try {
+ public void run()
+ {
+ try
+ {
new Jalview2XML().loadJalviewAlign(selectedFile);
- } catch (OutOfMemoryError oom) {
+ } catch (OutOfMemoryError oom)
+ {
new OOMWarning("Whilst loading project from " + choice, oom);
- } catch (Exception ex) {
- Cache.log.error("Problems whilst loading project from " + choice, ex);
- JvOptionPane.showMessageDialog(Desktop.desktop,
- MessageManager.formatMessage("label.error_whilst_loading_project_from", new Object[] { choice }),
- MessageManager.getString("label.couldnt_load_project"), JvOptionPane.WARNING_MESSAGE);
+ } catch (Exception ex)
+ {
+ Cache.log.error(
+ "Problems whilst loading project from " + choice, ex);
+ JvOptionPane.showMessageDialog(getDesktopPane(),
+ MessageManager.formatMessage(
+ "label.error_whilst_loading_project_from",
+ new Object[]
+ { choice }),
+ MessageManager
+ .getString("label.couldnt_load_project"),
+ JvOptionPane.WARNING_MESSAGE);
}
}
}, "Project Loader").start();
}
});
-
chooser.showOpenDialog(this);
}
@Override
- public void inputSequence_actionPerformed(ActionEvent e) {
+ public void inputSequence_actionPerformed(ActionEvent e)
+ {
new SequenceFetcher(this);
}
ArrayList<JPanel> fileLoadingPanels = new ArrayList<>();
- public void startLoading(final Object fileName) {
- if (fileLoadingCount == 0) {
- fileLoadingPanels
- .add(addProgressPanel(MessageManager.formatMessage("label.loading_file", new Object[] { fileName })));
+ public void startLoading(final Object fileName)
+ {
+ if (fileLoadingCount == 0)
+ {
+ fileLoadingPanels.add(addProgressPanel(MessageManager
+ .formatMessage("label.loading_file", new Object[]
+ { fileName })));
}
fileLoadingCount++;
}
- private JPanel addProgressPanel(String string) {
- if (progressPanel == null) {
+ private JPanel addProgressPanel(String string)
+ {
+ if (progressPanel == null)
+ {
progressPanel = new JPanel(new GridLayout(1, 1));
totalProgressCount = 0;
- instance.getContentPane().add(progressPanel, BorderLayout.SOUTH);
+ getContentPane().add(progressPanel, BorderLayout.SOUTH);
}
JPanel thisprogress = new JPanel(new BorderLayout(10, 5));
JProgressBar progressBar = new JProgressBar();
thisprogress.add(progressBar, BorderLayout.CENTER);
progressPanel.add(thisprogress);
- ((GridLayout) progressPanel.getLayout()).setRows(((GridLayout) progressPanel.getLayout()).getRows() + 1);
+ ((GridLayout) progressPanel.getLayout()).setRows(
+ ((GridLayout) progressPanel.getLayout()).getRows() + 1);
++totalProgressCount;
- instance.validate();
+ validate();
return thisprogress;
}
int totalProgressCount = 0;
- private void removeProgressPanel(JPanel progbar) {
- if (progressPanel != null) {
- synchronized (progressPanel) {
+ private void removeProgressPanel(JPanel progbar)
+ {
+ if (progressPanel != null)
+ {
+ synchronized (progressPanel)
+ {
progressPanel.remove(progbar);
GridLayout gl = (GridLayout) progressPanel.getLayout();
gl.setRows(gl.getRows() - 1);
- if (--totalProgressCount < 1) {
+ if (--totalProgressCount < 1)
+ {
this.getContentPane().remove(progressPanel);
progressPanel = null;
}
validate();
}
- public void stopLoading() {
+ public void stopLoading()
+ {
fileLoadingCount--;
- if (fileLoadingCount < 1) {
- while (fileLoadingPanels.size() > 0) {
+ if (fileLoadingCount < 1)
+ {
+ while (fileLoadingPanels.size() > 0)
+ {
removeProgressPanel(fileLoadingPanels.remove(0));
}
fileLoadingPanels.clear();
validate();
}
- public static int getViewCount(String alignmentId) {
+ public static int getViewCount(String alignmentId)
+ {
AlignmentViewport[] aps = getViewports(alignmentId);
return (aps == null) ? 0 : aps.length;
}
/**
*
- * @param alignmentId - if null, all sets are returned
+ * @param alignmentId
+ * - if null, all sets are returned
* @return all AlignmentPanels concerning the alignmentId sequence set
*/
- public static AlignmentPanel[] getAlignmentPanels(String alignmentId) {
- if (Desktop.desktop == null) {
+ public static AlignmentPanel[] getAlignmentPanels(String alignmentId)
+ {
+ if (getDesktopPane() == null)
+ {
// no frames created and in headless mode
// TODO: verify that frames are recoverable when in headless mode
return null;
}
List<AlignmentPanel> aps = new ArrayList<>();
AlignFrame[] frames = getAlignFrames();
- if (frames == null) {
+ if (frames == null)
+ {
return null;
}
- for (AlignFrame af : frames) {
- for (AlignmentPanel ap : af.alignPanels) {
- if (alignmentId == null || alignmentId.equals(ap.av.getSequenceSetId())) {
+ for (AlignFrame af : frames)
+ {
+ for (AlignmentPanel ap : af.alignPanels)
+ {
+ if (alignmentId == null
+ || alignmentId.equals(ap.av.getSequenceSetId()))
+ {
aps.add(ap);
}
}
}
- if (aps.size() == 0) {
+ if (aps.size() == 0)
+ {
return null;
}
AlignmentPanel[] vap = aps.toArray(new AlignmentPanel[aps.size()]);
/**
* get all the viewports on an alignment.
*
- * @param sequenceSetId unique alignment id (may be null - all viewports
- * returned in that case)
+ * @param sequenceSetId
+ * unique alignment id (may be null - all viewports returned in that
+ * case)
* @return all viewports on the alignment bound to sequenceSetId
*/
- public static AlignmentViewport[] getViewports(String sequenceSetId) {
+ public static AlignmentViewport[] getViewports(String sequenceSetId)
+ {
List<AlignmentViewport> viewp = new ArrayList<>();
- if (desktop != null) {
- AlignFrame[] frames = Desktop.getAlignFrames();
-
- for (AlignFrame afr : frames) {
- if (sequenceSetId == null || afr.getViewport().getSequenceSetId().equals(sequenceSetId)) {
- if (afr.alignPanels != null) {
- for (AlignmentPanel ap : afr.alignPanels) {
- if (sequenceSetId == null || sequenceSetId.equals(ap.av.getSequenceSetId())) {
+ if (getDesktopPane() != null)
+ {
+ AlignFrame[] frames = getAlignFrames();
+
+ for (AlignFrame afr : frames)
+ {
+ if (sequenceSetId == null || afr.getViewport().getSequenceSetId()
+ .equals(sequenceSetId))
+ {
+ if (afr.alignPanels != null)
+ {
+ for (AlignmentPanel ap : afr.alignPanels)
+ {
+ if (sequenceSetId == null
+ || sequenceSetId.equals(ap.av.getSequenceSetId()))
+ {
viewp.add(ap.av);
}
}
- } else {
+ }
+ else
+ {
viewp.add(afr.getViewport());
}
}
}
- if (viewp.size() > 0) {
+ if (viewp.size() > 0)
+ {
return viewp.toArray(new AlignmentViewport[viewp.size()]);
}
}
*
* @param af
*/
- public static void explodeViews(AlignFrame af) {
+ public static void explodeViews(AlignFrame af)
+ {
int size = af.alignPanels.size();
- if (size < 2) {
+ if (size < 2)
+ {
return;
}
// FIXME: ideally should use UI interface API
- FeatureSettings viewFeatureSettings = (af.featureSettings != null && af.featureSettings.isOpen())
- ? af.featureSettings
- : null;
+ FeatureSettings viewFeatureSettings = (af.featureSettings != null
+ && af.featureSettings.isOpen()) ? af.featureSettings : null;
Rectangle fsBounds = af.getFeatureSettingsGeometry();
- for (int i = 0; i < size; i++) {
+ for (int i = 0; i < size; i++)
+ {
AlignmentPanel ap = af.alignPanels.get(i);
AlignFrame newaf = new AlignFrame(ap);
// transfer reference for existing feature settings to new alignFrame
- if (ap == af.alignPanel) {
- if (viewFeatureSettings != null && viewFeatureSettings.fr.ap == ap) {
+ if (ap == af.alignPanel)
+ {
+ if (viewFeatureSettings != null && viewFeatureSettings.fr.ap == ap)
+ {
newaf.featureSettings = viewFeatureSettings;
}
newaf.setFeatureSettingsGeometry(fsBounds);
}
/*
- * Restore the view's last exploded frame geometry if known. Multiple views from
- * one exploded frame share and restore the same (frame) position and size.
+ * Restore the view's last exploded frame geometry if known. Multiple
+ * views from one exploded frame share and restore the same (frame)
+ * position and size.
*/
Rectangle geometry = ap.av.getExplodedGeometry();
- if (geometry != null) {
+ if (geometry != null)
+ {
newaf.setBounds(geometry);
}
ap.av.setGatherViewsHere(false);
- addInternalFrame(newaf, af.getTitle(), AlignFrame.DEFAULT_WIDTH, AlignFrame.DEFAULT_HEIGHT);
+ addInternalFrame(newaf, af.getTitle(), AlignFrame.DEFAULT_WIDTH,
+ AlignFrame.DEFAULT_HEIGHT);
// and materialise a new feature settings dialog instance for the new
// alignframe
// (closes the old as if 'OK' was pressed)
- if (ap == af.alignPanel && newaf.featureSettings != null && newaf.featureSettings.isOpen()
- && af.alignPanel.getAlignViewport().isShowSequenceFeatures()) {
+ if (ap == af.alignPanel && newaf.featureSettings != null
+ && newaf.featureSettings.isOpen()
+ && af.alignPanel.getAlignViewport().isShowSequenceFeatures())
+ {
newaf.showFeatureSettingsUI();
}
}
/**
* Gather expanded views (separate AlignFrame's) with the same sequence set
- * identifier back in to this frame as additional views, and close the expanded
- * views. Note the expanded frames may themselves have multiple views. We take
- * the lot.
+ * identifier back in to this frame as additional views, and close the
+ * expanded views. Note the expanded frames may themselves have multiple
+ * views. We take the lot.
*
* @param source
*/
- public void gatherViews(AlignFrame source) {
+ public void gatherViews(AlignFrame source)
+ {
source.viewport.setGatherViewsHere(true);
source.viewport.setExplodedGeometry(source.getBounds());
- JInternalFrame[] frames = desktop.getAllFrames();
+ JInternalFrame[] frames = desktopPane.getAllFrames();
String viewId = source.viewport.getSequenceSetId();
- for (int t = 0; t < frames.length; t++) {
- if (frames[t] instanceof AlignFrame && frames[t] != source) {
+ for (int t = 0; t < frames.length; t++)
+ {
+ if (frames[t] instanceof AlignFrame && frames[t] != source)
+ {
AlignFrame af = (AlignFrame) frames[t];
boolean gatherThis = false;
- for (int a = 0; a < af.alignPanels.size(); a++) {
+ for (int a = 0; a < af.alignPanels.size(); a++)
+ {
AlignmentPanel ap = af.alignPanels.get(a);
- if (viewId.equals(ap.av.getSequenceSetId())) {
+ if (viewId.equals(ap.av.getSequenceSetId()))
+ {
gatherThis = true;
ap.av.setGatherViewsHere(false);
ap.av.setExplodedGeometry(af.getBounds());
}
}
- if (gatherThis) {
- if (af.featureSettings != null && af.featureSettings.isOpen()) {
- if (source.featureSettings == null) {
+ if (gatherThis)
+ {
+ if (af.featureSettings != null && af.featureSettings.isOpen())
+ {
+ if (source.featureSettings == null)
+ {
// preserve the feature settings geometry for this frame
source.featureSettings = af.featureSettings;
- source.setFeatureSettingsGeometry(af.getFeatureSettingsGeometry());
- } else {
+ source.setFeatureSettingsGeometry(
+ af.getFeatureSettingsGeometry());
+ }
+ else
+ {
// close it and forget
af.featureSettings.close();
}
}
// refresh the feature setting UI for the source frame if it exists
- if (source.featureSettings != null && source.featureSettings.isOpen()) {
+ if (source.featureSettings != null && source.featureSettings.isOpen())
+ {
source.showFeatureSettingsUI();
}
-
}
- public JInternalFrame[] getAllFrames() {
- return desktop.getAllFrames();
+ public JInternalFrame[] getAllFrames()
+ {
+ return desktopPane.getAllFrames();
}
/**
*
* @param url
*/
- public void checkForQuestionnaire(String url) {
+ public void checkForQuestionnaire(String url)
+ {
UserQuestionnaireCheck jvq = new UserQuestionnaireCheck(url);
// javax.swing.SwingUtilities.invokeLater(jvq);
new Thread(jvq).start();
}
- public void checkURLLinks() {
+ public void checkURLLinks()
+ {
// Thread off the URL link checker
- addDialogThread(new Runnable() {
+ addDialogThread(new Runnable()
+ {
@Override
- public void run() {
- if (Cache.getDefault("CHECKURLLINKS", true)) {
+ public void run()
+ {
+ if (Cache.getDefault("CHECKURLLINKS", true))
+ {
// check what the actual links are - if it's just the default don't
// bother with the warning
- List<String> links = Preferences.sequenceUrlLinks.getLinksForMenu();
+ List<String> links = Preferences.sequenceUrlLinks
+ .getLinksForMenu();
// only need to check links if there is one with a
// SEQUENCE_ID which is not the default EMBL_EBI link
ListIterator<String> li = links.listIterator();
boolean check = false;
List<JLabel> urls = new ArrayList<>();
- while (li.hasNext()) {
+ while (li.hasNext())
+ {
String link = li.next();
- if (link.contains(jalview.util.UrlConstants.SEQUENCE_ID) && !UrlConstants.isDefaultString(link)) {
+ if (link.contains(jalview.util.UrlConstants.SEQUENCE_ID)
+ && !UrlConstants.isDefaultString(link))
+ {
check = true;
int barPos = link.indexOf("|");
- String urlMsg = barPos == -1 ? link : link.substring(0, barPos) + ": " + link.substring(barPos + 1);
+ String urlMsg = barPos == -1 ? link
+ : link.substring(0, barPos) + ": "
+ + link.substring(barPos + 1);
urls.add(new JLabel(urlMsg));
}
}
- if (!check) {
+ if (!check)
+ {
return;
}
JPanel msgPanel = new JPanel();
msgPanel.setLayout(new BoxLayout(msgPanel, BoxLayout.PAGE_AXIS));
msgPanel.add(Box.createVerticalGlue());
- JLabel msg = new JLabel(MessageManager.getString("label.SEQUENCE_ID_for_DB_ACCESSION1"));
- JLabel msg2 = new JLabel(MessageManager.getString("label.SEQUENCE_ID_for_DB_ACCESSION2"));
+ JLabel msg = new JLabel(MessageManager
+ .getString("label.SEQUENCE_ID_for_DB_ACCESSION1"));
+ JLabel msg2 = new JLabel(MessageManager
+ .getString("label.SEQUENCE_ID_for_DB_ACCESSION2"));
msgPanel.add(msg);
- for (JLabel url : urls) {
+ for (JLabel url : urls)
+ {
msgPanel.add(url);
}
msgPanel.add(msg2);
- final JCheckBox jcb = new JCheckBox(MessageManager.getString("label.do_not_display_again"));
- jcb.addActionListener(new ActionListener() {
+ final JCheckBox jcb = new JCheckBox(
+ MessageManager.getString("label.do_not_display_again"));
+ jcb.addActionListener(new ActionListener()
+ {
@Override
- public void actionPerformed(ActionEvent e) {
+ public void actionPerformed(ActionEvent e)
+ {
// update Cache settings for "don't show this again"
boolean showWarningAgain = !jcb.isSelected();
- Cache.setProperty("CHECKURLLINKS", Boolean.valueOf(showWarningAgain).toString());
+ Cache.setProperty("CHECKURLLINKS",
+ Boolean.valueOf(showWarningAgain).toString());
}
});
msgPanel.add(jcb);
- JvOptionPane.showMessageDialog(Desktop.desktop, msgPanel,
- MessageManager.getString("label.SEQUENCE_ID_no_longer_used"), JvOptionPane.WARNING_MESSAGE);
+ JvOptionPane.showMessageDialog(desktopPane, msgPanel,
+ MessageManager
+ .getString("label.SEQUENCE_ID_no_longer_used"),
+ JvOptionPane.WARNING_MESSAGE);
}
}
});
/**
* Proxy class for JDesktopPane which optionally displays the current memory
- * usage and highlights the desktop area with a red bar if free memory runs low.
+ * usage and highlights the desktop area with a red bar if free memory runs
+ * low.
*
* @author AMW
*/
- public class MyDesktopPane extends JDesktopPane implements Runnable {
+ public class MyDesktopPane extends JDesktopPane implements Runnable
+ {
private static final float ONE_MB = 1048576f;
boolean showMemoryUsage = false;
java.text.NumberFormat df;
- float maxMemory, allocatedMemory, freeMemory, totalFreeMemory, percentUsage;
+ float maxMemory, allocatedMemory, freeMemory, totalFreeMemory,
+ percentUsage;
- public MyDesktopPane(boolean showMemoryUsage) {
+ public MyDesktopPane(boolean showMemoryUsage)
+ {
showMemoryUsage(showMemoryUsage);
}
- public void showMemoryUsage(boolean showMemory) {
+ public void showMemoryUsage(boolean showMemory)
+ {
this.showMemoryUsage = showMemory;
- if (showMemory) {
+ if (showMemory)
+ {
Thread worker = new Thread(this);
worker.start();
}
repaint();
}
- public boolean isShowMemoryUsage() {
+ public boolean isShowMemoryUsage()
+ {
return showMemoryUsage;
}
@Override
- public void run() {
+ public void run()
+ {
df = java.text.NumberFormat.getNumberInstance();
df.setMaximumFractionDigits(2);
runtime = Runtime.getRuntime();
- while (showMemoryUsage) {
- try {
+ while (showMemoryUsage)
+ {
+ try
+ {
maxMemory = runtime.maxMemory() / ONE_MB;
allocatedMemory = runtime.totalMemory() / ONE_MB;
freeMemory = runtime.freeMemory() / ONE_MB;
repaint();
// sleep after showing usage
Thread.sleep(3000);
- } catch (Exception ex) {
+ } catch (Exception ex)
+ {
ex.printStackTrace();
}
}
}
@Override
- public void paintComponent(Graphics g) {
- if (showMemoryUsage && g != null && df != null) {
- if (percentUsage < 20) {
+ public void paintComponent(Graphics g)
+ {
+ if (showMemoryUsage && g != null && df != null)
+ {
+ if (percentUsage < 20)
+ {
g.setColor(Color.red);
}
FontMetrics fm = g.getFontMetrics();
- if (fm != null) {
- g.drawString(
- MessageManager.formatMessage("label.memory_stats",
- new Object[] { df.format(totalFreeMemory), df.format(maxMemory), df.format(percentUsage) }),
- 10, getHeight() - fm.getHeight());
+ if (fm != null)
+ {
+ g.drawString(MessageManager.formatMessage("label.memory_stats",
+ new Object[]
+ { df.format(totalFreeMemory), df.format(maxMemory),
+ df.format(percentUsage) }),
+ 10, getHeight() - fm.getHeight());
}
}
-
// output debug scale message. Important for jalview.bin.HiDPISettingTest2
Desktop.debugScaleMessage(Desktop.getDesktop().getGraphics());
}
*
* @return an array of AlignFrame, or null if none found
*/
- public static AlignFrame[] getAlignFrames() {
- if (Jalview.isHeadlessMode()) {
- // Desktop.desktop is null in headless mode
- return new AlignFrame[] { Jalview.currentAlignFrame };
+ public static AlignFrame[] getAlignFrames()
+ {
+ if (Jalview.isHeadlessMode())
+ {
+ return new AlignFrame[] { Jalview.getInstance().currentAlignFrame };
}
- JInternalFrame[] frames = Desktop.desktop.getAllFrames();
+ JInternalFrame[] frames = getDesktopPane().getAllFrames();
- if (frames == null) {
+ if (frames == null)
+ {
return null;
}
List<AlignFrame> avp = new ArrayList<>();
// REVERSE ORDER
- for (int i = frames.length - 1; i > -1; i--) {
- if (frames[i] instanceof AlignFrame) {
+ for (int i = frames.length - 1; i > -1; i--)
+ {
+ if (frames[i] instanceof AlignFrame)
+ {
avp.add((AlignFrame) frames[i]);
- } else if (frames[i] instanceof SplitFrame) {
+ }
+ else if (frames[i] instanceof SplitFrame)
+ {
/*
* Also check for a split frame containing an AlignFrame
*/
GSplitFrame sf = (GSplitFrame) frames[i];
- if (sf.getTopFrame() instanceof AlignFrame) {
+ if (sf.getTopFrame() instanceof AlignFrame)
+ {
avp.add((AlignFrame) sf.getTopFrame());
}
- if (sf.getBottomFrame() instanceof AlignFrame) {
+ if (sf.getBottomFrame() instanceof AlignFrame)
+ {
avp.add((AlignFrame) sf.getBottomFrame());
}
}
}
- if (avp.size() == 0) {
+ if (avp.size() == 0)
+ {
return null;
}
AlignFrame afs[] = avp.toArray(new AlignFrame[avp.size()]);
*
* @return
*/
- public GStructureViewer[] getJmols() {
- JInternalFrame[] frames = Desktop.desktop.getAllFrames();
+ public GStructureViewer[] getJmols()
+ {
+ JInternalFrame[] frames = desktopPane.getAllFrames();
- if (frames == null) {
+ if (frames == null)
+ {
return null;
}
List<GStructureViewer> avp = new ArrayList<>();
// REVERSE ORDER
- for (int i = frames.length - 1; i > -1; i--) {
- if (frames[i] instanceof AppJmol) {
+ for (int i = frames.length - 1; i > -1; i--)
+ {
+ if (frames[i] instanceof AppJmol)
+ {
GStructureViewer af = (GStructureViewer) frames[i];
avp.add(af);
}
}
- if (avp.size() == 0) {
+ if (avp.size() == 0)
+ {
return null;
}
GStructureViewer afs[] = avp.toArray(new GStructureViewer[avp.size()]);
* Add Groovy Support to Jalview
*/
@Override
- public void groovyShell_actionPerformed() {
- try {
+ public void groovyShell_actionPerformed()
+ {
+ try
+ {
openGroovyConsole();
- } catch (Exception ex) {
+ } catch (Exception ex)
+ {
Cache.log.error("Groovy Shell Creation failed.", ex);
- JvOptionPane.showInternalMessageDialog(Desktop.desktop,
+ JvOptionPane.showInternalMessageDialog(desktopPane,
- MessageManager.getString("label.couldnt_create_groovy_shell"),
- MessageManager.getString("label.groovy_support_failed"), JvOptionPane.ERROR_MESSAGE);
+ MessageManager.getString("label.couldnt_create_groovy_shell"),
+ MessageManager.getString("label.groovy_support_failed"),
+ JvOptionPane.ERROR_MESSAGE);
}
}
/**
* Open the Groovy console
*/
- void openGroovyConsole() {
- if (groovyConsole == null) {
+ void openGroovyConsole()
+ {
+ if (groovyConsole == null)
+ {
groovyConsole = new groovy.ui.Console();
groovyConsole.setVariable("Jalview", this);
groovyConsole.run();
/*
* We allow only one console at a time, so that AlignFrame menu option
- * 'Calculate | Run Groovy script' is unambiguous. Disable 'Groovy Console', and
- * enable 'Run script', when the console is opened, and the reverse when it is
- * closed
+ * 'Calculate | Run Groovy script' is unambiguous.
+ * Disable 'Groovy Console', and enable 'Run script', when the console is
+ * opened, and the reverse when it is closed
*/
Window window = (Window) groovyConsole.getFrame();
- window.addWindowListener(new WindowAdapter() {
+ window.addWindowListener(new WindowAdapter()
+ {
@Override
- public void windowClosed(WindowEvent e) {
+ public void windowClosed(WindowEvent e)
+ {
/*
* rebind CMD-Q from Groovy Console to Jalview Quit
*/
((Window) groovyConsole.getFrame()).setVisible(true);
/*
- * if we got this far, enable 'Run Groovy' in AlignFrame menus and disable
- * opening a second console
+ * if we got this far, enable 'Run Groovy' in AlignFrame menus
+ * and disable opening a second console
*/
enableExecuteGroovy(true);
}
/**
- * Bind Ctrl/Cmd-Q to Quit - for reset as Groovy Console takes over this binding
- * when opened
+ * Bind Ctrl/Cmd-Q to Quit - for reset as Groovy Console takes over this
+ * binding when opened
*/
- protected void addQuitHandler() {
- getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
- KeyStroke.getKeyStroke(KeyEvent.VK_Q, jalview.util.ShortcutKeyMaskExWrapper.getMenuShortcutKeyMaskEx()),
- "Quit");
- getRootPane().getActionMap().put("Quit", new AbstractAction() {
+ protected void addQuitHandler()
+ {
+
+ getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW)
+ .put(KeyStroke.getKeyStroke(KeyEvent.VK_Q,
+ Platform.SHORTCUT_KEY_MASK),
+ "Quit");
+ getRootPane().getActionMap().put("Quit", new AbstractAction()
+ {
@Override
- public void actionPerformed(ActionEvent e) {
+ public void actionPerformed(ActionEvent e)
+ {
quit();
}
});
/**
* Enable or disable 'Run Groovy script' in AlignFrame calculate menus
*
- * @param enabled true if Groovy console is open
+ * @param enabled
+ * true if Groovy console is open
*/
- public void enableExecuteGroovy(boolean enabled) {
+ public void enableExecuteGroovy(boolean enabled)
+ {
/*
- * disable opening a second Groovy console (or re-enable when the console is
- * closed)
+ * disable opening a second Groovy console
+ * (or re-enable when the console is closed)
*/
groovyShell.setEnabled(!enabled);
AlignFrame[] alignFrames = getAlignFrames();
- if (alignFrames != null) {
- for (AlignFrame af : alignFrames) {
+ if (alignFrames != null)
+ {
+ for (AlignFrame af : alignFrames)
+ {
af.setGroovyEnabled(enabled);
}
}
* @see jalview.gui.IProgressIndicator#setProgressBar(java.lang.String, long)
*/
@Override
- public void setProgressBar(String message, long id) {
- if (progressBars == null) {
+ public void setProgressBar(String message, long id)
+ {
+ // Platform.timeCheck("Desktop " + message, Platform.TIME_MARK);
+
+ if (progressBars == null)
+ {
progressBars = new Hashtable<>();
progressBarHandlers = new Hashtable<>();
}
- if (progressBars.get(Long.valueOf(id)) != null) {
+ if (progressBars.get(Long.valueOf(id)) != null)
+ {
JPanel panel = progressBars.remove(Long.valueOf(id));
- if (progressBarHandlers.contains(Long.valueOf(id))) {
+ if (progressBarHandlers.contains(Long.valueOf(id)))
+ {
progressBarHandlers.remove(Long.valueOf(id));
}
removeProgressPanel(panel);
- } else {
+ }
+ else
+ {
progressBars.put(Long.valueOf(id), addProgressPanel(message));
}
}
+
+ @Override
+ public void removeProgressBar(long id)
+ {
+ //TODO
+ throw new UnsupportedOperationException("not implemented");
+ }
/*
* (non-Javadoc)
* jalview.gui.IProgressIndicatorHandler)
*/
@Override
- public void registerHandler(final long id, final IProgressIndicatorHandler handler) {
- if (progressBarHandlers == null || !progressBars.containsKey(Long.valueOf(id))) {
- throw new Error(MessageManager.getString("error.call_setprogressbar_before_registering_handler"));
+ public void registerHandler(final long id,
+ final IProgressIndicatorHandler handler)
+ {
+ if (progressBarHandlers == null
+ || !progressBars.containsKey(Long.valueOf(id)))
+ {
+ throw new Error(MessageManager.getString(
+ "error.call_setprogressbar_before_registering_handler"));
}
progressBarHandlers.put(Long.valueOf(id), handler);
final JPanel progressPanel = progressBars.get(Long.valueOf(id));
- if (handler.canCancel()) {
- JButton cancel = new JButton(MessageManager.getString("action.cancel"));
+ if (handler.canCancel())
+ {
+ JButton cancel = new JButton(
+ MessageManager.getString("action.cancel"));
final IProgressIndicator us = this;
- cancel.addActionListener(new ActionListener() {
+ cancel.addActionListener(new ActionListener()
+ {
@Override
- public void actionPerformed(ActionEvent e) {
+ public void actionPerformed(ActionEvent e)
+ {
handler.cancelActivity(id);
- us.setProgressBar(MessageManager.formatMessage("label.cancelled_params",
- new Object[] { ((JLabel) progressPanel.getComponent(0)).getText() }), id);
+ us.setProgressBar(MessageManager
+ .formatMessage("label.cancelled_params", new Object[]
+ { ((JLabel) progressPanel.getComponent(0)).getText() }),
+ id);
}
});
progressPanel.add(cancel, BorderLayout.EAST);
* @return true if any progress bars are still active
*/
@Override
- public boolean operationInProgress() {
- if (progressBars != null && progressBars.size() > 0) {
+ public boolean operationInProgress()
+ {
+ if (progressBars != null && progressBars.size() > 0)
+ {
return true;
}
return false;
}
/**
- * This will return the first AlignFrame holding the given viewport instance. It
- * will break if there are more than one AlignFrames viewing a particular av.
+ * This will return the first AlignFrame holding the given viewport instance.
+ * It will break if there are more than one AlignFrames viewing a particular
+ * av.
*
* @param viewport
* @return alignFrame for viewport
*/
- public static AlignFrame getAlignFrameFor(AlignViewportI viewport) {
- if (desktop != null) {
- AlignmentPanel[] aps = getAlignmentPanels(viewport.getSequenceSetId());
- for (int panel = 0; aps != null && panel < aps.length; panel++) {
- if (aps[panel] != null && aps[panel].av == viewport) {
+ public static AlignFrame getAlignFrameFor(AlignViewportI viewport)
+ {
+ if (getDesktopPane() != null)
+ {
+ AlignmentPanel[] aps = getAlignmentPanels(
+ viewport.getSequenceSetId());
+ for (int panel = 0; aps != null && panel < aps.length; panel++)
+ {
+ if (aps[panel] != null && aps[panel].av == viewport)
+ {
return aps[panel].alignFrame;
}
}
return null;
}
- public VamsasApplication getVamsasApplication() {
+ public VamsasApplication getVamsasApplication()
+ {
// TODO: JAL-3311 remove remaining code from Jalview relating to VAMSAS
return null;
*
* @return inBatchMode
*/
- public boolean isInBatchMode() {
+ public boolean isInBatchMode()
+ {
return inBatchMode;
}
*
* @param inBatchMode
*/
- public void setInBatchMode(boolean inBatchMode) {
+ public void setInBatchMode(boolean inBatchMode)
+ {
this.inBatchMode = inBatchMode;
}
- /**
- * start service discovery and wait till it is done
- */
- public void startServiceDiscovery() {
+ public void startServiceDiscovery()
+ {
startServiceDiscovery(false);
}
- /**
- * start service discovery threads - blocking or non-blocking
- *
- * @param blocking
- */
- public void startServiceDiscovery(boolean blocking) {
- startServiceDiscovery(blocking, false);
- }
-
- /**
- * start service discovery threads
- *
- * @param blocking - false means call returns
- * immediately
- * @param ignore_SHOW_JWS2_SERVICES_preference - when true JABA services are
- * discovered regardless of user's
- * JWS2 discovery preference setting
- */
- public void startServiceDiscovery(boolean blocking, boolean ignore_SHOW_JWS2_SERVICES_preference) {
- boolean alive = true;
- Thread t0 = null, t1 = null, t2 = null;
+ public void startServiceDiscovery(boolean blocking)
+ {
+ System.out.println("Starting service discovery");
+ var tasks = new ArrayList<Future<?>>();
// JAL-940 - JALVIEW 1 services are now being EOLed as of JABA 2.1 release
- if (true) {
+
+ System.out.println("loading services");
+
+ /** @j2sIgnore */
+ {
// todo: changesupport handlers need to be transferred
- if (discoverer == null) {
- discoverer = new jalview.ws.jws1.Discoverer();
+ if (discoverer == null)
+ {
+ discoverer = jalview.ws.jws1.Discoverer.getInstance();
// register PCS handler for desktop.
discoverer.addPropertyChangeListener(changeSupport);
}
// JAL-940 - disabled JWS1 service configuration - always start discoverer
// until we phase out completely
- (t0 = new Thread(discoverer)).start();
+ var f = new FutureTask<Void>(discoverer, null);
+ new Thread(f).start();
+ tasks.add(f);
}
- if (ignore_SHOW_JWS2_SERVICES_preference || Cache.getDefault("SHOW_JWS2_SERVICES", true)) {
- t2 = jalview.ws.jws2.Jws2Discoverer.getDiscoverer().startDiscoverer(changeSupport);
+ if (Cache.getDefault("SHOW_JWS2_SERVICES", true))
+ {
+ tasks.add(jalview.ws.jws2.Jws2Discoverer.getInstance().startDiscoverer());
}
- Thread t3 = null;
+ if (Cache.getDefault("SHOW_SLIVKA_SERVICES", true))
{
- // TODO: do rest service discovery
+ tasks.add(jalview.ws.slivkaws.SlivkaWSDiscoverer.getInstance().startDiscoverer());
}
- if (blocking) {
- while (alive) {
- try {
- Thread.sleep(15);
- } catch (Exception e) {
+ if (blocking)
+ {
+ for (Future<?> task : tasks) {
+ try
+ {
+ // block until all discovery tasks are done
+ task.get();
+ } catch (Exception e)
+ {
+ e.printStackTrace();
}
- alive = (t1 != null && t1.isAlive()) || (t2 != null && t2.isAlive()) || (t3 != null && t3.isAlive())
- || (t0 != null && t0.isAlive());
}
}
}
*
* @param evt
*/
- protected void JalviewServicesChanged(PropertyChangeEvent evt) {
- if (evt.getNewValue() == null || evt.getNewValue() instanceof Vector) {
- final String ermsg = jalview.ws.jws2.Jws2Discoverer.getDiscoverer().getErrorMessages();
- if (ermsg != null) {
- if (Cache.getDefault("SHOW_WSDISCOVERY_ERRORS", true)) {
- if (serviceChangedDialog == null) {
+ protected void JalviewServicesChanged(PropertyChangeEvent evt)
+ {
+ if (evt.getNewValue() == null || evt.getNewValue() instanceof Vector)
+ {
+ final WSDiscovererI discoverer = jalview.ws.jws2.Jws2Discoverer
+ .getInstance();
+ final String ermsg = discoverer.getErrorMessages();
+ // CONFLICT:ALT:? final String ermsg = jalview.ws.jws2.Jws2Discoverer.getInstance()
+ if (ermsg != null)
+ {
+ if (Cache.getDefault("SHOW_WSDISCOVERY_ERRORS", true))
+ {
+ if (serviceChangedDialog == null)
+ {
// only run if we aren't already displaying one of these.
- addDialogThread(serviceChangedDialog = new Runnable() {
+ addDialogThread(serviceChangedDialog = new Runnable()
+ {
@Override
- public void run() {
+ public void run()
+ {
/*
* JalviewDialog jd =new JalviewDialog() {
*
- * @Override protected void cancelPressed() { // TODO Auto-generated method stub
+ * @Override protected void cancelPressed() { // TODO
+ * Auto-generated method stub
*
- * }@Override protected void okPressed() { // TODO Auto-generated method stub
+ * }@Override protected void okPressed() { // TODO
+ * Auto-generated method stub
*
- * }@Override protected void raiseClosed() { // TODO Auto-generated method stub
+ * }@Override protected void raiseClosed() { // TODO
+ * Auto-generated method stub
*
- * } }; jd.initDialogFrame(new JLabel("<html><table width=\"450\"><tr><td>" +
- * ermsg +
+ * } }; jd.initDialogFrame(new
+ * JLabel("<html><table width=\"450\"><tr><td>" + ermsg +
* "<br/>It may be that you have invalid JABA URLs in your web service preferences,"
* + " or mis-configured HTTP proxy settings.<br/>" +
- * "Check the <em>Connections</em> and <em>Web services</em> tab of the" +
- * " Tools->Preferences dialog box to change them.</td></tr></table></html>" ),
- * true, true, "Web Service Configuration Problem", 450, 400);
+ * "Check the <em>Connections</em> and <em>Web services</em> tab of the"
+ * +
+ * " Tools->Preferences dialog box to change them.</td></tr></table></html>"
+ * ), true, true, "Web Service Configuration Problem", 450,
+ * 400);
*
* jd.waitForInput();
*/
- JvOptionPane.showConfirmDialog(Desktop.desktop,
- new JLabel("<html><table width=\"450\"><tr><td>" + ermsg + "</td></tr></table>"
- + "<p>It may be that you have invalid JABA URLs<br/>in your web service preferences,"
- + "<br>or as a command-line argument, or mis-configured HTTP proxy settings.</p>"
- + "<p>Check the <em>Connections</em> and <em>Web services</em> tab<br/>of the"
- + " Tools->Preferences dialog box to change them.</p></html>"),
- "Web Service Configuration Problem", JvOptionPane.DEFAULT_OPTION, JvOptionPane.ERROR_MESSAGE);
+ JvOptionPane.showConfirmDialog(desktopPane,
+ new JLabel("<html><table width=\"450\"><tr><td>"
+ + ermsg + "</td></tr></table>"
+ + "<p>It may be that you have invalid JABA URLs<br/>in your web service preferences,"
+ + "<br>or as a command-line argument, or mis-configured HTTP proxy settings.</p>"
+ + "<p>Check the <em>Connections</em> and <em>Web services</em> tab<br/>of the"
+ + " Tools->Preferences dialog box to change them.</p></html>"),
+ "Web Service Configuration Problem",
+ JvOptionPane.DEFAULT_OPTION,
+ JvOptionPane.ERROR_MESSAGE);
serviceChangedDialog = null;
}
});
}
- } else {
- Cache.log.error("Errors reported by JABA discovery service. Check web services preferences.\n" + ermsg);
+ }
+ else
+ {
+ Cache.log.error(
+ "Errors reported by JABA discovery service. Check web services preferences.\n"
+ + ermsg);
}
}
}
*
* @param url
*/
- public static void showUrl(final String url) {
- showUrl(url, Desktop.instance);
+ public static void showUrl(final String url)
+ {
+ showUrl(url, getInstance());
}
/**
* Like showUrl but allows progress handler to be specified
*
* @param url
- * @param progress (null) or object implementing IProgressIndicator
+ * @param progress
+ * (null) or object implementing IProgressIndicator
*/
- public static void showUrl(final String url, final IProgressIndicator progress) {
- new Thread(new Runnable() {
+ public static void showUrl(final String url,
+ final IProgressIndicator progress)
+ {
+ new Thread(new Runnable()
+ {
@Override
- public void run() {
- try {
- if (progress != null) {
- progress.setProgressBar(MessageManager.formatMessage("status.opening_params", new Object[] { url }),
- this.hashCode());
+ public void run()
+ {
+ try
+ {
+ if (progress != null)
+ {
+ progress.setProgressBar(MessageManager
+ .formatMessage("status.opening_params", new Object[]
+ { url }), this.hashCode());
}
jalview.util.BrowserLauncher.openURL(url);
- } catch (Exception ex) {
- JvOptionPane.showInternalMessageDialog(Desktop.desktop,
- MessageManager.getString("label.web_browser_not_found_unix"),
- MessageManager.getString("label.web_browser_not_found"), JvOptionPane.WARNING_MESSAGE);
+ } catch (Exception ex)
+ {
+ JvOptionPane.showInternalMessageDialog(getDesktopPane(),
+ MessageManager
+ .getString("label.web_browser_not_found_unix"),
+ MessageManager.getString("label.web_browser_not_found"),
+ JvOptionPane.WARNING_MESSAGE);
ex.printStackTrace();
}
- if (progress != null) {
+ if (progress != null)
+ {
progress.setProgressBar(null, this.hashCode());
}
}
public static WsParamSetManager wsparamManager = null;
- public static ParamManager getUserParameterStore() {
- if (wsparamManager == null) {
+ public static ParamManager getUserParameterStore()
+ {
+ if (wsparamManager == null)
+ {
wsparamManager = new WsParamSetManager();
}
return wsparamManager;
*
* @param e
*/
- public static void hyperlinkUpdate(HyperlinkEvent e) {
- if (e.getEventType() == EventType.ACTIVATED) {
+ public static void hyperlinkUpdate(HyperlinkEvent e)
+ {
+ if (e.getEventType() == EventType.ACTIVATED)
+ {
String url = null;
- try {
+ try
+ {
url = e.getURL().toString();
- Desktop.showUrl(url);
- } catch (Exception x) {
- if (url != null) {
- if (Cache.log != null) {
+ showUrl(url);
+ } catch (Exception x)
+ {
+ if (url != null)
+ {
+ if (Cache.log != null)
+ {
Cache.log.error("Couldn't handle string " + url + " as a URL.");
- } else {
- System.err.println("Couldn't handle string " + url + " as a URL.");
+ }
+ else
+ {
+ System.err.println(
+ "Couldn't handle string " + url + " as a URL.");
}
}
// ignore any exceptions due to dud links.
*
* @param prompter
*/
- public void addDialogThread(final Runnable prompter) {
- dialogExecutor.submit(new Runnable() {
+ public void addDialogThread(final Runnable prompter)
+ {
+ dialogExecutor.submit(new Runnable()
+ {
@Override
- public void run() {
- if (dialogPause) {
- try {
+ public void run()
+ {
+ if (dialogPause)
+ {
+ try
+ {
block.acquire();
- } catch (InterruptedException x) {
+ } catch (InterruptedException x)
+ {
}
}
- if (instance == null) {
+ if (Jalview.isHeadlessMode())
+ {
return;
}
- try {
+ try
+ {
SwingUtilities.invokeAndWait(prompter);
- } catch (Exception q) {
+ } catch (Exception q)
+ {
Cache.log.warn("Unexpected Exception in dialog thread.", q);
}
}
});
}
- public void startDialogQueue() {
+ public void startDialogQueue()
+ {
// set the flag so we don't pause waiting for another permit and semaphore
// the current task to begin
dialogPause = false;
* </pre>
*/
@Override
- protected void snapShotWindow_actionPerformed(ActionEvent e) {
+ protected void snapShotWindow_actionPerformed(ActionEvent e)
+ {
// currently the menu option to do this is not shown
invalidate();
int width = getWidth();
int height = getHeight();
- File of = new File("Jalview_snapshot_" + System.currentTimeMillis() + ".eps");
- ImageWriterI writer = new ImageWriterI() {
+ File of = new File(
+ "Jalview_snapshot_" + System.currentTimeMillis() + ".eps");
+ ImageWriterI writer = new ImageWriterI()
+ {
@Override
- public void exportImage(Graphics g) throws Exception {
+ public void exportImage(Graphics g) throws Exception
+ {
paintAll(g);
- Cache.log.info("Successfully written snapshot to file " + of.getAbsolutePath());
+ Cache.log.info("Successfully written snapshot to file "
+ + of.getAbsolutePath());
}
};
String title = "View of desktop";
- ImageExporter exporter = new ImageExporter(writer, null, TYPE.EPS, title);
+ ImageExporter exporter = new ImageExporter(writer, null, TYPE.EPS,
+ title);
exporter.doExport(of, this, width, height, title);
}
/**
* Explode the views in the given SplitFrame into separate SplitFrame windows.
- * This respects (remembers) any previous 'exploded geometry' i.e. the size and
- * location last time the view was expanded (if any). However it does not
+ * This respects (remembers) any previous 'exploded geometry' i.e. the size
+ * and location last time the view was expanded (if any). However it does not
* remember the split pane divider location - this is set to match the
* 'exploding' frame.
*
* @param sf
*/
- public void explodeViews(SplitFrame sf) {
+ public void explodeViews(SplitFrame sf)
+ {
AlignFrame oldTopFrame = (AlignFrame) sf.getTopFrame();
AlignFrame oldBottomFrame = (AlignFrame) sf.getBottomFrame();
- List<? extends AlignmentViewPanel> topPanels = oldTopFrame.getAlignPanels();
- List<? extends AlignmentViewPanel> bottomPanels = oldBottomFrame.getAlignPanels();
+ List<? extends AlignmentViewPanel> topPanels = oldTopFrame
+ .getAlignPanels();
+ List<? extends AlignmentViewPanel> bottomPanels = oldBottomFrame
+ .getAlignPanels();
int viewCount = topPanels.size();
- if (viewCount < 2) {
+ if (viewCount < 2)
+ {
return;
}
/*
- * Processing in reverse order works, forwards order leaves the first panels not
- * visible. I don't know why!
+ * Processing in reverse order works, forwards order leaves the first panels
+ * not visible. I don't know why!
*/
- for (int i = viewCount - 1; i >= 0; i--) {
+ for (int i = viewCount - 1; i >= 0; i--)
+ {
/*
- * Make new top and bottom frames. These take over the respective AlignmentPanel
- * objects, including their AlignmentViewports, so the cdna/protein
- * relationships between the viewports is carried over to the new split frames.
+ * Make new top and bottom frames. These take over the respective
+ * AlignmentPanel objects, including their AlignmentViewports, so the
+ * cdna/protein relationships between the viewports is carried over to the
+ * new split frames.
*
* explodedGeometry holds the (x, y) position of the previously exploded
* SplitFrame, and the (width, height) of the AlignFrame component
AlignFrame newTopFrame = new AlignFrame(topPanel);
newTopFrame.setSize(oldTopFrame.getSize());
newTopFrame.setVisible(true);
- Rectangle geometry = ((AlignViewport) topPanel.getAlignViewport()).getExplodedGeometry();
- if (geometry != null) {
+ Rectangle geometry = ((AlignViewport) topPanel.getAlignViewport())
+ .getExplodedGeometry();
+ if (geometry != null)
+ {
newTopFrame.setSize(geometry.getSize());
}
AlignFrame newBottomFrame = new AlignFrame(bottomPanel);
newBottomFrame.setSize(oldBottomFrame.getSize());
newBottomFrame.setVisible(true);
- geometry = ((AlignViewport) bottomPanel.getAlignViewport()).getExplodedGeometry();
- if (geometry != null) {
+ geometry = ((AlignViewport) bottomPanel.getAlignViewport())
+ .getExplodedGeometry();
+ if (geometry != null)
+ {
newBottomFrame.setSize(geometry.getSize());
}
topPanel.av.setGatherViewsHere(false);
bottomPanel.av.setGatherViewsHere(false);
- JInternalFrame splitFrame = new SplitFrame(newTopFrame, newBottomFrame);
- if (geometry != null) {
+ JInternalFrame splitFrame = new SplitFrame(newTopFrame,
+ newBottomFrame);
+ if (geometry != null)
+ {
splitFrame.setLocation(geometry.getLocation());
}
- Desktop.addInternalFrame(splitFrame, sf.getTitle(), -1, -1);
+ addInternalFrame(splitFrame, sf.getTitle(), -1, -1);
}
/*
- * Clear references to the panels (now relocated in the new SplitFrames) before
- * closing the old SplitFrame.
+ * Clear references to the panels (now relocated in the new SplitFrames)
+ * before closing the old SplitFrame.
*/
topPanels.clear();
bottomPanels.clear();
*
* @param source
*/
- public void gatherViews(GSplitFrame source) {
+ public void gatherViews(GSplitFrame source)
+ {
/*
* special handling of explodedGeometry for a view within a SplitFrame: - it
* holds the (x, y) position of the enclosing SplitFrame, and the (width,
*/
AlignFrame myTopFrame = (AlignFrame) source.getTopFrame();
AlignFrame myBottomFrame = (AlignFrame) source.getBottomFrame();
- myTopFrame.viewport.setExplodedGeometry(
- new Rectangle(source.getX(), source.getY(), myTopFrame.getWidth(), myTopFrame.getHeight()));
- myBottomFrame.viewport.setExplodedGeometry(
- new Rectangle(source.getX(), source.getY(), myBottomFrame.getWidth(), myBottomFrame.getHeight()));
+ myTopFrame.viewport.setExplodedGeometry(new Rectangle(source.getX(),
+ source.getY(), myTopFrame.getWidth(), myTopFrame.getHeight()));
+ myBottomFrame.viewport
+ .setExplodedGeometry(new Rectangle(source.getX(), source.getY(),
+ myBottomFrame.getWidth(), myBottomFrame.getHeight()));
myTopFrame.viewport.setGatherViewsHere(true);
myBottomFrame.viewport.setGatherViewsHere(true);
String topViewId = myTopFrame.viewport.getSequenceSetId();
String bottomViewId = myBottomFrame.viewport.getSequenceSetId();
- JInternalFrame[] frames = desktop.getAllFrames();
- for (JInternalFrame frame : frames) {
- if (frame instanceof SplitFrame && frame != source) {
+ JInternalFrame[] frames = desktopPane.getAllFrames();
+ for (JInternalFrame frame : frames)
+ {
+ if (frame instanceof SplitFrame && frame != source)
+ {
SplitFrame sf = (SplitFrame) frame;
AlignFrame topFrame = (AlignFrame) sf.getTopFrame();
AlignFrame bottomFrame = (AlignFrame) sf.getBottomFrame();
boolean gatherThis = false;
- for (int a = 0; a < topFrame.alignPanels.size(); a++) {
+ for (int a = 0; a < topFrame.alignPanels.size(); a++)
+ {
AlignmentPanel topPanel = topFrame.alignPanels.get(a);
AlignmentPanel bottomPanel = bottomFrame.alignPanels.get(a);
if (topViewId.equals(topPanel.av.getSequenceSetId())
- && bottomViewId.equals(bottomPanel.av.getSequenceSetId())) {
+ && bottomViewId.equals(bottomPanel.av.getSequenceSetId()))
+ {
gatherThis = true;
topPanel.av.setGatherViewsHere(false);
bottomPanel.av.setGatherViewsHere(false);
- topPanel.av.setExplodedGeometry(new Rectangle(sf.getLocation(), topFrame.getSize()));
- bottomPanel.av.setExplodedGeometry(new Rectangle(sf.getLocation(), bottomFrame.getSize()));
+ topPanel.av.setExplodedGeometry(
+ new Rectangle(sf.getLocation(), topFrame.getSize()));
+ bottomPanel.av.setExplodedGeometry(
+ new Rectangle(sf.getLocation(), bottomFrame.getSize()));
myTopFrame.addAlignmentPanel(topPanel, false);
myBottomFrame.addAlignmentPanel(bottomPanel, false);
}
}
- if (gatherThis) {
+ if (gatherThis)
+ {
topFrame.getAlignPanels().clear();
bottomFrame.getAlignPanels().clear();
sf.close();
myTopFrame.setDisplayedView(myTopFrame.alignPanel);
}
- public static groovy.ui.Console getGroovyConsole() {
+ public static groovy.ui.Console getGroovyConsole()
+ {
return groovyConsole;
}
*
* TODO refactor to desktop utilities class
*
- * @param files - Data source strings extracted from the drop event
- * @param protocols - protocol for each data source extracted from the drop
- * event
- * @param evt - the drop event
- * @param t - the payload from the drop event
+ * @param files
+ * - Data source strings extracted from the drop event
+ * @param protocols
+ * - protocol for each data source extracted from the drop event
+ * @param evt
+ * - the drop event
+ * @param t
+ * - the payload from the drop event
* @throws Exception
*/
- public static void transferFromDropTarget(List<Object> files, List<DataSourceType> protocols, DropTargetDropEvent evt,
- Transferable t) throws Exception {
-
- DataFlavor uriListFlavor = new DataFlavor("text/uri-list;class=java.lang.String"), urlFlavour = null;
- try {
- urlFlavour = new DataFlavor("application/x-java-url; class=java.net.URL");
- } catch (ClassNotFoundException cfe) {
+ @SuppressWarnings("unchecked")
+ public static void transferFromDropTarget(List<Object> files,
+ List<DataSourceType> protocols, DropTargetDropEvent evt,
+ Transferable t) throws Exception
+ {
+
+ // BH 2018 changed List<String> to List<Object> to allow for File from
+ // SwingJS
+
+ // DataFlavor[] flavors = t.getTransferDataFlavors();
+ // for (int i = 0; i < flavors.length; i++) {
+ // if (flavors[i].isFlavorJavaFileListType()) {
+ // evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
+ // List<File> list = (List<File>) t.getTransferData(flavors[i]);
+ // for (int j = 0; j < list.size(); j++) {
+ // File file = (File) list.get(j);
+ // byte[] data = getDroppedFileBytes(file);
+ // fileName.setText(file.getName() + " - " + data.length + " " +
+ // evt.getLocation());
+ // JTextArea target = (JTextArea) ((DropTarget)
+ // evt.getSource()).getComponent();
+ // target.setText(new String(data));
+ // }
+ // dtde.dropComplete(true);
+ // return;
+ // }
+ //
+
+ DataFlavor uriListFlavor = new DataFlavor(
+ "text/uri-list;class=java.lang.String"), urlFlavour = null;
+ try
+ {
+ urlFlavour = new DataFlavor(
+ "application/x-java-url; class=java.net.URL");
+ } catch (ClassNotFoundException cfe)
+ {
Cache.log.debug("Couldn't instantiate the URL dataflavor.", cfe);
}
- if (urlFlavour != null && t.isDataFlavorSupported(urlFlavour)) {
+ if (urlFlavour != null && t.isDataFlavorSupported(urlFlavour))
+ {
- try {
+ try
+ {
java.net.URL url = (URL) t.getTransferData(urlFlavour);
// nb: java 8 osx bug https://bugs.openjdk.java.net/browse/JDK-8156099
// means url may be null.
- if (url != null) {
+ if (url != null)
+ {
protocols.add(DataSourceType.URL);
files.add(url.toString());
- Cache.log.debug("Drop handled as URL dataflavor " + files.get(files.size() - 1));
+ Cache.log.debug("Drop handled as URL dataflavor "
+ + files.get(files.size() - 1));
return;
- } else {
- if (Platform.isAMacAndNotJS()) {
- System.err.println("Please ignore plist error - occurs due to problem with java 8 on OSX");
+ }
+ else
+ {
+ if (Platform.isAMacAndNotJS())
+ {
+ System.err.println(
+ "Please ignore plist error - occurs due to problem with java 8 on OSX");
}
}
- } catch (Throwable ex) {
+ } catch (Throwable ex)
+ {
Cache.log.debug("URL drop handler failed.", ex);
}
}
- if (t.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) {
+ if (t.isDataFlavorSupported(DataFlavor.javaFileListFlavor))
+ {
// Works on Windows and MacOSX
Cache.log.debug("Drop handled as javaFileListFlavor");
- for (Object file : (List) t.getTransferData(DataFlavor.javaFileListFlavor)) {
+ for (File file : (List<File>) t
+ .getTransferData(DataFlavor.javaFileListFlavor))
+ {
files.add(file);
protocols.add(DataSourceType.FILE);
}
- } else {
+ }
+ else
+ {
// Unix like behaviour
boolean added = false;
String data = null;
- if (t.isDataFlavorSupported(uriListFlavor)) {
+ if (t.isDataFlavorSupported(uriListFlavor))
+ {
Cache.log.debug("Drop handled as uriListFlavor");
// This is used by Unix drag system
data = (String) t.getTransferData(uriListFlavor);
}
- if (data == null) {
+ if (data == null)
+ {
// fallback to text: workaround - on OSX where there's a JVM bug
Cache.log.debug("standard URIListFlavor failed. Trying text");
// try text fallback
- DataFlavor textDf = new DataFlavor("text/plain;class=java.lang.String");
- if (t.isDataFlavorSupported(textDf)) {
+ DataFlavor textDf = new DataFlavor(
+ "text/plain;class=java.lang.String");
+ if (t.isDataFlavorSupported(textDf))
+ {
data = (String) t.getTransferData(textDf);
}
- Cache.log.debug("Plain text drop content returned " + (data == null ? "Null - failed" : data));
+ Cache.log.debug("Plain text drop content returned "
+ + (data == null ? "Null - failed" : data));
}
- if (data != null) {
- while (protocols.size() < files.size()) {
- Cache.log.debug("Adding missing FILE protocol for " + files.get(protocols.size()));
+ if (data != null)
+ {
+ while (protocols.size() < files.size())
+ {
+ Cache.log.debug("Adding missing FILE protocol for "
+ + files.get(protocols.size()));
protocols.add(DataSourceType.FILE);
}
- for (java.util.StringTokenizer st = new java.util.StringTokenizer(data, "\r\n"); st.hasMoreTokens();) {
+ for (java.util.StringTokenizer st = new java.util.StringTokenizer(
+ data, "\r\n"); st.hasMoreTokens();)
+ {
added = true;
String s = st.nextToken();
- if (s.startsWith("#")) {
+ if (s.startsWith("#"))
+ {
// the line is a comment (as per the RFC 2483)
continue;
}
java.net.URI uri = new java.net.URI(s);
- if (uri.getScheme().toLowerCase(Locale.ROOT).startsWith("http")) {
+ if (uri.getScheme().toLowerCase().startsWith("http"))
+ {
protocols.add(DataSourceType.URL);
files.add(uri.toString());
- } else {
+ }
+ else
+ {
// otherwise preserve old behaviour: catch all for file objects
java.io.File file = new java.io.File(uri);
protocols.add(DataSourceType.FILE);
}
}
- if (Cache.log.isDebugEnabled()) {
- if (data == null || !added) {
+ if (Cache.log.isDebugEnabled())
+ {
+ if (data == null || !added)
+ {
- if (t.getTransferDataFlavors() != null && t.getTransferDataFlavors().length > 0) {
- Cache.log.debug("Couldn't resolve drop data. Here are the supported flavors:");
- for (DataFlavor fl : t.getTransferDataFlavors()) {
- Cache.log.debug("Supported transfer dataflavor: " + fl.toString());
+ if (t.getTransferDataFlavors() != null
+ && t.getTransferDataFlavors().length > 0)
+ {
+ Cache.log.debug(
+ "Couldn't resolve drop data. Here are the supported flavors:");
+ for (DataFlavor fl : t.getTransferDataFlavors())
+ {
+ Cache.log.debug(
+ "Supported transfer dataflavor: " + fl.toString());
Object df = t.getTransferData(fl);
- if (df != null) {
+ if (df != null)
+ {
Cache.log.debug("Retrieves: " + df);
- } else {
+ }
+ else
+ {
Cache.log.debug("Retrieved nothing");
}
}
- } else {
- Cache.log.debug("Couldn't resolve dataflavor for drop: " + t.toString());
+ }
+ else
+ {
+ Cache.log.debug("Couldn't resolve dataflavor for drop: "
+ + t.toString());
}
}
}
}
- if (Platform.isWindowsAndNotJS()) {
+ if (Platform.isWindowsAndNotJS())
+ {
Cache.log.debug("Scanning dropped content for Windows Link Files");
// resolve any .lnk files in the file drop
- for (int f = 0; f < files.size(); f++) {
- String source = files.get(f).toString().toLowerCase(Locale.ROOT);
+ for (int f = 0; f < files.size(); f++)
+ {
+ String source = files.get(f).toString().toLowerCase();
if (protocols.get(f).equals(DataSourceType.FILE)
- && (source.endsWith(".lnk") || source.endsWith(".url") || source.endsWith(".site"))) {
- try {
+ && (source.endsWith(".lnk") || source.endsWith(".url")
+ || source.endsWith(".site")))
+ {
+ try
+ {
Object obj = files.get(f);
- File lf = (obj instanceof File ? (File) obj : new File((String) obj));
+ File lf = (obj instanceof File ? (File) obj
+ : new File((String) obj));
// process link file to get a URL
Cache.log.debug("Found potential link file: " + lf);
WindowsShortcut wscfile = new WindowsShortcut(lf);
String fullname = wscfile.getRealFilename();
protocols.set(f, FormatAdapter.checkProtocol(fullname));
files.set(f, fullname);
- Cache.log.debug("Parsed real filename " + fullname + " to extract protocol: " + protocols.get(f));
- } catch (Exception ex) {
- Cache.log.error("Couldn't parse " + files.get(f) + " as a link file.", ex);
+ Cache.log.debug("Parsed real filename " + fullname
+ + " to extract protocol: " + protocols.get(f));
+ } catch (Exception ex)
+ {
+ Cache.log.error(
+ "Couldn't parse " + files.get(f) + " as a link file.",
+ ex);
}
}
}
* depending on the state of the controlling menu item
*/
@Override
- protected void showExperimental_actionPerformed(boolean selected) {
+ protected void showExperimental_actionPerformed(boolean selected)
+ {
Cache.setProperty(EXPERIMENTAL_FEATURES, Boolean.toString(selected));
}
/**
- * Answers a (possibly empty) list of any structure viewer frames (currently for
- * either Jmol or Chimera) which are currently open. This may optionally be
- * restricted to viewers of a specified class, or viewers linked to a specified
- * alignment panel.
+ * Answers a (possibly empty) list of any structure viewer frames (currently
+ * for either Jmol or Chimera) which are currently open. This may optionally
+ * be restricted to viewers of a specified class, or viewers linked to a
+ * specified alignment panel.
*
- * @param apanel if not null, only return viewers linked to this
- * panel
- * @param structureViewerClass if not null, only return viewers of this class
+ * @param apanel
+ * if not null, only return viewers linked to this panel
+ * @param structureViewerClass
+ * if not null, only return viewers of this class
* @return
*/
- public List<StructureViewerBase> getStructureViewers(AlignmentPanel apanel,
- Class<? extends StructureViewerBase> structureViewerClass) {
+ public List<StructureViewerBase> getStructureViewers(
+ AlignmentPanel apanel,
+ Class<? extends StructureViewerBase> structureViewerClass)
+ {
List<StructureViewerBase> result = new ArrayList<>();
- JInternalFrame[] frames = Desktop.instance.getAllFrames();
+ JInternalFrame[] frames = getAllFrames();
- for (JInternalFrame frame : frames) {
- if (frame instanceof StructureViewerBase) {
- if (structureViewerClass == null || structureViewerClass.isInstance(frame)) {
- if (apanel == null || ((StructureViewerBase) frame).isLinkedWith(apanel)) {
+ for (JInternalFrame frame : frames)
+ {
+ if (frame instanceof StructureViewerBase)
+ {
+ if (structureViewerClass == null
+ || structureViewerClass.isInstance(frame))
+ {
+ if (apanel == null
+ || ((StructureViewerBase) frame).isLinkedWith(apanel))
+ {
result.add((StructureViewerBase) frame);
}
}
updateColourButton(mainPanel, colour, featureColour);
};
};
- JalviewColourChooser.showColourChooser(Desktop.getDesktop(),
+ JalviewColourChooser.showColourChooser(Desktop.getDesktopPane(),
title, featureColour.getColour(), listener);
}
else
* set dialog action handlers for OK (create/Amend) and Cancel options
* also for Delete if applicable (when amending features)
*/
- JvOptionPane dialog = JvOptionPane.newOptionDialog(Desktop.desktop)
+ JvOptionPane dialog = JvOptionPane.newOptionDialog(Desktop.getDesktopPane())
.setResponseHandler(0, okAction).setResponseHandler(2, cancelAction);
if (!forCreate)
{
}
else
{
- Desktop.addInternalFrame(frame, title, false, bounds.width,
- bounds.height);
+ Desktop.addInternalFrame(frame, title, Desktop.FRAME_NOT_VISIBLE, bounds.width,
+ bounds.height, Desktop.FRAME_ALLOW_RESIZE, Desktop.FRAME_SET_MIN_SIZE_300);
frame.setBounds(bounds);
frame.setVisible(true);
}
{
title += " " + scope;
}
- Desktop.addInternalFrame(frame, title, MY_WIDTH, MY_HEIGHT);
+ Desktop.addInternalFrame(frame, title, Desktop.FRAME_MAKE_VISIBLE, MY_WIDTH, MY_HEIGHT, Desktop.FRAME_ALLOW_RESIZE, Desktop.FRAME_ALLOW_ANY_SIZE);
frame.setMinimumSize(new Dimension(MIN_WIDTH, MIN_HEIGHT));
searchBox.getComponent().requestFocus();
}
*/
boolean getFocusedViewport()
{
- if (focusFixed || Desktop.desktop == null)
+ if (focusfixed || Desktop.getDesktopPane() == null)
{
if (ap != null && av != null)
{
}
// now checks further down the window stack to fix bug
// https://mantis.lifesci.dundee.ac.uk/view.php?id=36008
- JInternalFrame[] frames = Desktop.desktop.getAllFrames();
+ JInternalFrame[] frames = Desktop.getDesktopPane().getAllFrames();
for (int f = 0; f < frames.length; f++)
{
JInternalFrame alignFrame = frames[f];
if (isTreeFont())
{
Desktop.addInternalFrame(frame,
- MessageManager.getString("action.change_font_tree_panel"),
- 400, 200, false);
+ MessageManager.getString("action.change_font_tree_panel"), Desktop.FRAME_MAKE_VISIBLE,
+ 400, 200, Desktop.FRAME_NOT_RESIZABLE, Desktop.FRAME_SET_MIN_SIZE_300);
}
else
{
Desktop.addInternalFrame(frame,
- MessageManager.getString("action.change_font"), 380, 220,
- false);
+ MessageManager.getString("action.change_font"), Desktop.FRAME_MAKE_VISIBLE, 380, 220,
+ Desktop.FRAME_NOT_RESIZABLE, Desktop.FRAME_SET_MIN_SIZE_300);
}
frame.setLayer(JLayeredPane.PALETTE_LAYER);
*/
boolean operationInProgress();
+ /**
+ * Remove progress bar with a given id from the panel.
+ *
+ * @param id
+ */
+ void removeProgressBar(long id);
+
}
*/
package jalview.gui;
+import jalview.datamodel.SequenceI;
+import jalview.viewmodel.ViewportListenerI;
+import jalview.viewmodel.ViewportRanges;
+
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Font;
import javax.swing.JPanel;
-import jalview.datamodel.SequenceI;
-import jalview.viewmodel.ViewportListenerI;
-import jalview.viewmodel.ViewportRanges;
-
/**
* DOCUMENT ME!
*
int imgHeight = 0;
- boolean fastPaint = false;
+ private boolean fastPaint = false;
List<SequenceI> searchResults;
private Font idfont;
+ private boolean allowFastPaint;
+
/**
* Creates a new IdCanvas object.
*
g.drawString(s.getDisplayId(av.getShowJVSuffix()), xPos,
(((i - starty + 1) * charHeight) + ypos) - (charHeight / 5));
+ // JAL-3253-applet was just hiddenRows here. ccfc48e (gmungoc) added getShowHiddenMarkers test
if (hiddenRows && av.getShowHiddenMarkers())
{
drawMarker(g, av, i, starty, ypos);
@Override
public void paintComponent(Graphics g)
{
+ if (av.getAlignPanel().getHoldRepaint())
+ {
+ return;
+ }
+
g.setColor(Color.white);
g.fillRect(0, 0, getWidth(), getHeight());
- if (fastPaint)
+ if (allowFastPaint && fastPaint)
{
fastPaint = false;
g.drawImage(image, 0, 0, this);
if (oldHeight != imgHeight || image.getWidth(this) != getWidth())
{
- image = new BufferedImage(getWidth(), imgHeight,
+ image = new BufferedImage(getWidth(), imgHeight,
BufferedImage.TYPE_INT_RGB);
}
int alignmentWidth = alignViewport.getAlignment().getWidth();
final int alheight = alignViewport.getAlignment().getHeight();
- /*
+
+// int annotationHeight = 0;
+
+ /* (former)
* assumption: SeqCanvas.calculateWrappedGeometry has been called
+ *
+ * was based on the fact that SeqCanvas was added as a child prior to IdCanvas,
+ * and children are processed in order of addition.
+ *
+ * It's probably fine. But...
+ *
*/
SeqCanvas seqCanvas = alignViewport.getAlignPanel()
.getSeqPanel().seqCanvas;
+ // ...better: let's call it now
+ seqCanvas.calculateWrappedGeometry();
final int charHeight = alignViewport.getCharHeight();
AnnotationLabels labels = null;
if (alignViewport.isShowAnnotation())
{
+ // BH when was ap == null?
+ if (ap == null)
+ {
+ ap = new AnnotationPanel(alignViewport);
+ }
+// annotationHeight = ap.adjustPanelHeight();
labels = new AnnotationLabels(alignViewport);
}
+// int hgap = charHeight;
+// if (alignViewport.getScaleAboveWrapped())
+// {
+// hgap += charHeight;
+// }
+//
+// /*
+// * height of alignment + gap + annotations (if shown)
+// */
+// int cHeight = alheight * charHeight + hgap
+// + annotationHeight;
+//
ViewportRanges ranges = alignViewport.getRanges();
int rowSize = ranges.getViewportWidth();
public void propertyChange(PropertyChangeEvent evt)
{
String propertyName = evt.getPropertyName();
- if (propertyName.equals(ViewportRanges.STARTSEQ)
- || (av.getWrapAlignment()
- && propertyName.equals(ViewportRanges.STARTRES)))
+ switch (propertyName)
{
+ case ViewportRanges.STARTSEQ:
fastPaint((int) evt.getNewValue() - (int) evt.getOldValue());
- }
- else if (propertyName.equals(ViewportRanges.STARTRESANDSEQ))
- {
+ break;
+ case ViewportRanges.STARTRES:
+ if (av.getWrapAlignment())
+ {
+ fastPaint((int) evt.getNewValue() - (int) evt.getOldValue());
+ }
+ break;
+ case ViewportRanges.STARTRESANDSEQ:
fastPaint(((int[]) evt.getNewValue())[1]
- ((int[]) evt.getOldValue())[1]);
- }
- else if (propertyName.equals(ViewportRanges.MOVE_VIEWPORT))
- {
+ break;
+ case ViewportRanges.MOVE_VIEWPORT:
repaint();
+ break;
+ default:
}
}
+
+ /**
+ * Clears the flag that allows a 'fast paint' on the next repaint, so
+ * requiring a full repaint
+ */
+ public void setNoFastPaint()
+ {
+ allowFastPaint = false;
+ }
}
jalview.util.BrowserLauncher.openURL(url);
} catch (Exception ex)
{
- JvOptionPane.showInternalMessageDialog(Desktop.desktop,
+ JvOptionPane.showInternalMessageDialog(Desktop.getDesktopPane(),
MessageManager.getString("label.web_browser_not_found_unix"),
MessageManager.getString("label.web_browser_not_found"),
JvOptionPane.WARNING_MESSAGE);
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
+@Deprecated
public class JalviewChangeSupport implements PropertyChangeListener
{
public void propertyChange(PropertyChangeEvent evt)
boolean block, String title, int width, int height)
{
- frame = new JDialog(Desktop.instance, modal);
+ frame = new JDialog(Desktop.getInstance(), modal);
frame.setTitle(title);
- if (Desktop.instance != null)
+ if (Desktop.getInstance() != null)
{
- Rectangle deskr = Desktop.instance.getBounds();
+ Rectangle deskr = Desktop.getInstance().getBounds();
frame.setBounds(new Rectangle((int) (deskr.getCenterX() - width / 2),
(int) (deskr.getCenterY() - height / 2), width, height));
}
*/
package jalview.gui;
-import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
+import java.awt.Container;
import java.awt.Font;
-import java.awt.GridLayout;
-import java.awt.Rectangle;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JComponent;
-import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
-import javax.swing.JPanel;
import javax.swing.JScrollBar;
import javax.swing.SwingConstants;
import javax.swing.border.Border;
import javax.swing.border.TitledBorder;
import jalview.util.MessageManager;
+import jalview.util.Platform;
/**
* useful functions for building Swing GUIs
*/
public final class JvSwingUtils
{
+ static final String HTML_PREFIX = (Platform.isJS() ?
+ "<html><div style=\"max-width:350px;overflow-wrap:break-word;display:inline-block\">"
+ : "<html><div style=\"width:350; text-align: justify; word-wrap: break-word;\">"
+ );
+
/**
* wrap a bare html safe string to around 60 characters per line using a CSS
* style class specifying word-wrap and break-word
*
* @param enclose
- * if true, add <html> wrapper tags
+ * if true, add <html> wrapper tags (currently false for only
+ * two references -- both in Jws2Discoverer --
* @param ttext
*
* @return
{
Objects.requireNonNull(ttext,
"Tootip text to format must not be null!");
- ttext = ttext.trim();
- boolean maxLengthExceeded = false;
+ ttext = ttext.trim().replaceAll("<br/>", "<br>");
- if (ttext.contains("<br>"))
+ boolean maxLengthExceeded = false;
+ boolean isHTML = ttext.startsWith("<html>");
+ if (isHTML)
{
- String[] htmllines = ttext.split("<br>");
- for (String line : htmllines)
- {
- maxLengthExceeded = line.length() > 60;
- if (maxLengthExceeded)
- {
+ ttext = ttext.substring(6);
+ }
+ if (ttext.endsWith("</html>"))
+ {
+ isHTML = true;
+ ttext = ttext.substring(0, ttext.length() - 7);
+ }
+ boolean hasBR = ttext.contains("<br>");
+ enclose |= isHTML || hasBR;
+ if (hasBR)
+ {
+ int pt = -1, ptlast = -4;
+ while ((pt = ttext.indexOf("<br>", pt + 1)) >= 0) {
+ if (pt - ptlast - 4 > 60) {
+ maxLengthExceeded = true;
break;
}
}
}
- else
+ else
{
maxLengthExceeded = ttext.length() > 60;
}
- if (!maxLengthExceeded)
- {
- return enclose ? "<html>" + ttext + "</html>" : ttext;
- }
-
- return (enclose ? "<html>" : "")
- // BH 2018
- + "<style> div.ttip {width:350px;white-space:pre-wrap;padding:2px;overflow-wrap:break-word;}</style><div class=\"ttip\">"
-// + "<style> p.ttip {width:350px;margin:-14px 0px -14px 0px;padding:2px;overflow-wrap:break-word;}"
-// + "</style><p class=\"ttip\">"
- + ttext
- + " </div>"
-// + "</p>"
- + ((enclose ? "</html>" : ""));
+ String ret = (!enclose ? ttext : maxLengthExceeded ? HTML_PREFIX + ttext + "</div></html>" :
+ "<html>" + ttext + "</html>");
+ //System.out.println("JvSwUtil " + enclose + " " + maxLengthExceeded + " " + ret);
+ return ret;
}
public static JButton makeButton(String label, String tooltip,
}
/**
+ * A convenience method that that adds a component with label to a container,
+ * sets a tooltip on both component and label, and optionally specifies layout
+ * constraints for the added component (but not the label)
*
- * @param panel
+ * @param container
* @param tooltip
* @param label
- * @param valBox
- * @return the GUI element created that was added to the layout so it's
- * attributes can be changed.
+ * @param comp
+ * @param constraints
*/
- public static JPanel addtoLayout(JPanel panel, String tooltip,
- JComponent label, JComponent valBox)
- {
- JPanel laypanel = new JPanel(new GridLayout(1, 2));
- JPanel labPanel = new JPanel(new BorderLayout());
- JPanel valPanel = new JPanel();
- labPanel.setBounds(new Rectangle(7, 7, 158, 23));
- valPanel.setBounds(new Rectangle(172, 7, 270, 23));
- labPanel.add(label, BorderLayout.WEST);
- valPanel.add(valBox);
- laypanel.add(labPanel);
- laypanel.add(valPanel);
- valPanel.setToolTipText(tooltip);
- labPanel.setToolTipText(tooltip);
- valBox.setToolTipText(tooltip);
- panel.add(laypanel);
- panel.validate();
- return laypanel;
- }
-
- public static void mgAddtoLayout(JPanel cpanel, String tooltip,
- JLabel jLabel, JComponent name)
+ public static void addtoLayout(Container container, String tooltip,
+ JComponent label, JComponent comp, String constraints)
{
- mgAddtoLayout(cpanel, tooltip, jLabel, name, null);
- }
-
- public static void mgAddtoLayout(JPanel cpanel, String tooltip,
- JLabel jLabel, JComponent name, String params)
- {
- cpanel.add(jLabel);
- if (params == null)
- {
- cpanel.add(name);
- }
- else
- {
- cpanel.add(name, params);
- }
- name.setToolTipText(tooltip);
- jLabel.setToolTipText(tooltip);
+ container.add(label);
+ container.add(comp, constraints);
+ comp.setToolTipText(tooltip); // this doesn't seem to show?
+ label.setToolTipText(tooltip);
}
/**
/**
* Adds a titled border to the component in the default font and position (top
- * left), optionally witht italic text
+ * left), optionally with italic text
*
* @param comp
* @param title
ex.printStackTrace();
}
- dialog = JvOptionPane.newOptionDialog(Desktop.desktop);
+ dialog = JvOptionPane.newOptionDialog(Desktop.getDesktopPane());
}
/**
}
else
{
- Cache.applicationProperties.remove(preferencesKey);
+ Cache.removePropertyNoSave(preferencesKey);
}
}
public OOMWarning(String string, OutOfMemoryError oomerror)
{
- this(string, oomerror, Desktop.desktop);
+ this(string, oomerror, Desktop.getDesktopPane());
}
@Override
*/
package jalview.gui;
+import jalview.bin.Cache;
+import jalview.io.DataSourceType;
+import jalview.io.FileLoader;
+import jalview.io.JalviewFileChooser;
+import jalview.io.JalviewFileView;
+import jalview.util.MessageManager;
+import jalview.ws.jws2.dm.JabaOption;
+import jalview.ws.params.ArgumentI;
+import jalview.ws.params.OptionI;
+import jalview.ws.params.ParameterI;
+import jalview.ws.params.ValueConstrainI;
+import jalview.ws.params.ValueConstrainI.ValueType;
+import jalview.ws.params.simple.FileParameter;
+import jalview.ws.params.simple.LogarithmicParameter;
+import jalview.ws.params.simple.RadioChoiceParameter;
+import jalview.ws.params.simple.StringParameter;
+
import java.awt.BorderLayout;
+import java.awt.Color;
import java.awt.Component;
+import java.awt.Container;
import java.awt.Dimension;
+import java.awt.FlowLayout;
import java.awt.Font;
-import java.awt.GridLayout;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
-import java.awt.event.FocusAdapter;
-import java.awt.event.FocusEvent;
+import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
-import java.awt.event.KeyListener;
+import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
+import java.io.File;
import java.net.URL;
import java.util.ArrayList;
+import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
+import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
+import javax.swing.JRadioButton;
import javax.swing.JScrollPane;
+import javax.swing.JSlider;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.border.TitledBorder;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
-import jalview.util.MessageManager;
-import jalview.ws.params.ArgumentI;
-import jalview.ws.params.OptionI;
-import jalview.ws.params.ParameterI;
-import jalview.ws.params.ValueConstrainI;
-import jalview.ws.params.ValueConstrainI.ValueType;
import net.miginfocom.swing.MigLayout;
/**
*/
public class OptsAndParamsPage
{
- /**
+ public static final int PARAM_WIDTH = 340;
+
+ public static final int PARAM_HEIGHT = 150;
+
+ public static final int PARAM_CLOSEDHEIGHT = 80;
+
+ URL linkImageURL = getClass().getResource("/images/link.gif");
+
+ Map<String, OptionBox> optSet = new LinkedHashMap<>();
+
+ Map<String, ParamBox> paramSet = new LinkedHashMap<>();
+
+ /*
* compact or verbose style parameters
*/
boolean compact = false;
+ OptsParametersContainerI poparent;
+
+ /**
+ * A class that models a panel rendering a single option (checkbox or choice
+ * list)
+ */
public class OptionBox extends JPanel
implements MouseListener, ActionListener
{
- JCheckBox enabled = new JCheckBox();
+ JCheckBox enabled;
final URL finfo;
OptionI option;
- JLabel optlabel = new JLabel();
+ JComboBox<Object> val;
- JComboBox<String> val = new JComboBox<>();
+ /**
+ * Constructs and adds labels and controls to the panel for one Option
+ *
+ * @param opt
+ */
public OptionBox(OptionI opt)
{
option = opt;
- setLayout(new BorderLayout());
- enabled.setSelected(opt.isRequired()); // TODO: lock required options
+ setLayout(new FlowLayout(FlowLayout.LEFT));
+ enabled = new JCheckBox(opt.getLabel());
+ enabled.setSelected(opt.isRequired());
+
+ /*
+ * If option is required, show a label, if optional a checkbox
+ * (but not for Jabaws pending JWS-126 resolution)
+ */
+ if (opt.isRequired() && !(opt instanceof JabaOption))
+ {
+ finfo = null;
+ add(new JLabel(opt.getLabel()));
+ }
+ else
+ {
+ finfo = option.getFurtherDetails();
+ configureCheckbox(opt);
+ add(enabled);
+ }
+
+ /*
+ * construct the choice box with possible values,
+ * or their display names if provided
+ */
+ val = buildComboBox(opt);
+ val.setSelectedItem(opt.getValue());
+
+ /*
+ * only show the choicebox if there is more than one option,
+ * or the option is mandatory
+ */
+ if (opt.getPossibleValues().size() > 1 || opt.isRequired())
+ {
+ val.addActionListener(this);
+ add(val);
+ }
+
+ setInitialValue();
+ }
+
+ /**
+ * Configures the checkbox that controls whether or not the option is
+ * selected
+ *
+ * @param opt
+ */
+ protected void configureCheckbox(OptionI opt)
+ {
enabled.setFont(new Font("Verdana", Font.PLAIN, 11));
- enabled.setText("");
- enabled.setText(opt.getName());
enabled.addActionListener(this);
- finfo = option.getFurtherDetails();
- String desc = opt.getDescription();
+ final String desc = opt.getDescription();
if (finfo != null)
{
hasLink = true;
- enabled.setToolTipText(JvSwingUtils.wrapTooltip(true,
- ((desc == null || desc.trim().length() == 0)
- ? MessageManager.getString(
- "label.opt_and_params_further_details")
- : desc) + "<br><img src=\"" + linkImageURL
- + "\"/>"));
- enabled.addMouseListener(this);
+ String description = desc;
+ if (desc == null || desc.trim().isEmpty())
+ {
+ description = MessageManager
+ .getString("label.opt_and_params_further_details");
+ }
+ description = description + "<br><img src=\"" + linkImageURL
+ + "\"/>";
+ String text = JvSwingUtils.wrapTooltip(true, description);
+ enabled.setToolTipText(text);
+ enabled.addMouseListener(this); // for popup menu to show link
}
else
{
if (desc != null && desc.trim().length() > 0)
{
- enabled.setToolTipText(
- JvSwingUtils.wrapTooltip(true, opt.getDescription()));
+ enabled.setToolTipText(JvSwingUtils.wrapTooltip(true, desc));
}
}
- add(enabled, BorderLayout.NORTH);
- for (String str : opt.getPossibleValues())
- {
- val.addItem(str);
- }
- val.setSelectedItem(opt.getValue());
- if (opt.getPossibleValues().size() > 1)
- {
- setLayout(new GridLayout(1, 2));
- val.addActionListener(this);
- add(val, BorderLayout.SOUTH);
- }
- // TODO: add actionListeners for popup (to open further info),
- // and to update list of parameters if an option is enabled
- // that takes a value. JBPNote: is this TODO still valid ?
- setInitialValue();
}
@Override
poparent.argSetModified(this, !notmod);
}
- public OptionI getOptionIfEnabled()
+ /**
+ * Answers null if the option is not selected, else a new Option holding the
+ * selected value
+ *
+ * @return
+ */
+ public ArgumentI getSelectedOption()
{
if (!enabled.isSelected())
{
return null;
}
+ String value = getSelectedValue(option, val.getSelectedIndex());
OptionI opt = option.copy();
- if (opt.getPossibleValues() != null
- && opt.getPossibleValues().size() == 1)
- {
- // Hack to make sure the default value for an enabled option with only
- // one value is actually returned
- opt.setValue(opt.getPossibleValues().get(0));
- }
- if (val.getSelectedItem() != null)
- {
- opt.setValue((String) val.getSelectedItem());
- }
- else
- {
- if (option.getValue() != null)
- {
- opt.setValue(option.getValue());
- }
- }
+ opt.setValue(value);
return opt;
}
@Override
public void mouseEntered(MouseEvent e)
{
- // TODO Auto-generated method stub
}
@Override
public void mouseExited(MouseEvent e)
{
- // TODO Auto-generated method stub
}
}
}
+ /**
+ * toString representation for identification in the debugger only
+ */
+ @Override
+ public String toString()
+ {
+ return option == null ? super.toString() : option.toString();
+ }
}
+ /**
+ * A class that models a panel rendering a single parameter
+ */
public class ParamBox extends JPanel
implements ChangeListener, ActionListener, MouseListener
{
- boolean adjusting = false;
+ /*
+ * parameter values (or their logs) are multiplied by this
+ * scaling factor to ensure an integer range for the slider
+ */
+ private int sliderScaleFactor = 1;
+
+ boolean isLogarithmicParameter;
+
+ boolean isChoiceParameter;
- boolean choice = false;
+ boolean isIntegerParameter;
- JComboBox<String> choicebox;
+ boolean isStringParameter;
- JPanel controlPanel = new JPanel();
+ boolean adjusting;
- boolean descisvisible = false;
+ /*
+ * drop-down list of choice options (if applicable)
+ */
+ JComboBox<Object> choicebox;
+
+ /*
+ * radio buttons as an alternative to combo box
+ */
+ ButtonGroup buttonGroup;
+
+ JPanel controlsPanel = new JPanel();
+
+ boolean descriptionIsVisible = false;
JScrollPane descPanel = new JScrollPane();
final URL finfo;
- boolean integ = false;
-
- String lastVal;
+ Object lastVal;
ParameterI parameter;
JPanel settingPanel = new JPanel();
- JButton showDesc = new JButton();
+ JSlider slider;
- Slider slider = null;
+ JTextArea descriptionText = new JTextArea();
- JTextArea string = new JTextArea();
+ ValueConstrainI validator;
- ValueConstrainI validator = null;
+ JTextField valueField;
- JTextField valueField = null;
+ private String descTooltip;
- public ParamBox(final OptsParametersContainerI pmlayout,
+ public ParamBox(final OptsParametersContainerI paramContainer,
ParameterI parm)
{
- pmdialogbox = pmlayout;
+ pmdialogbox = paramContainer;
finfo = parm.getFurtherDetails();
validator = parm.getValidValue();
parameter = parm;
+ isLogarithmicParameter = parm instanceof LogarithmicParameter;
if (validator != null)
{
- integ = validator.getType() == ValueType.Integer;
- }
- else
- {
- if (parameter.getPossibleValues() != null)
+ ValueType type = validator.getType();
+ isIntegerParameter = type == ValueType.Integer;
+ isStringParameter = type == ValueType.String
+ || type == ValueType.File;
+
+ /*
+ * ensure slider has an integer range corresponding to
+ * the min-max range of the parameter
+ */
+ if (validator.getMin() != null && validator.getMax() != null
+ // && !isIntegerParameter
+ && !isStringParameter)
{
- choice = true;
+ double min = validator.getMin().doubleValue();
+ double max = validator.getMax().doubleValue();
+ if (isLogarithmicParameter)
+ {
+ min = Math.log(min);
+ max = Math.log(max);
+ }
+ sliderScaleFactor = (int) (1000000 / (max - min));
+ // todo scaleMin, scaleMax could also be final fields
}
}
- if (!compact)
+ List<String> possibleValues = parameter.getPossibleValues();
+ isChoiceParameter = possibleValues != null
+ && !possibleValues.isEmpty();
+
+ if (compact)
{
- makeExpanderParam(parm);
+ addCompactParameter(parm);
}
else
{
- makeCompactParam(parm);
+ addExpandableParam(parm);
}
}
- private void makeCompactParam(ParameterI parm)
+ /**
+ * Adds a 'compact' format parameter, with any help text shown as a tooltip
+ *
+ * @param parm
+ */
+ private void addCompactParameter(ParameterI parm)
{
setLayout(new MigLayout("", "[][grow]"));
String ttipText = null;
- controlPanel.setLayout(new BorderLayout());
+ controlsPanel.setLayout(new BorderLayout());
if (parm.getDescription() != null
&& parm.getDescription().trim().length() > 0)
{
- // Only create description boxes if there actually is a description.
ttipText = (JvSwingUtils.wrapTooltip(true,
parm.getDescription() + (finfo != null ? "<br><img src=\""
+ linkImageURL + "\"/>"
: "")));
}
- JvSwingUtils.mgAddtoLayout(this, ttipText, new JLabel(parm.getName()),
- controlPanel, "");
+ JvSwingUtils.addtoLayout(this, ttipText, new JLabel(parm.getName()),
+ controlsPanel, "");
updateControls(parm);
validate();
}
- private void makeExpanderParam(final ParameterI parm)
+ /**
+ * Adds an 'expanded' format parameter, with any help shown in a panel that
+ * may be shown or hidden
+ *
+ * @param parm
+ */
+ private void addExpandableParam(ParameterI parm)
{
setPreferredSize(new Dimension(PARAM_WIDTH, PARAM_CLOSEDHEIGHT));
setBorder(new TitledBorder(parm.getName()));
setLayout(null);
- showDesc.setFont(new Font("Verdana", Font.PLAIN, 6));
- showDesc.setText("+");
- string.setFont(new Font("Verdana", Font.PLAIN, 11));
- string.setBackground(getBackground());
+ descriptionText.setFont(new Font("Verdana", Font.PLAIN, 11));
+ descriptionText.setBackground(getBackground());
- string.setEditable(false);
- descPanel.getViewport().setView(string);
+ descriptionText.setEditable(false);
+ descPanel.getViewport().setView(descriptionText);
descPanel.setVisible(false);
JPanel firstrow = new JPanel();
firstrow.setLayout(null);
- controlPanel.setLayout(new BorderLayout());
- controlPanel.setBounds(new Rectangle(39, 10, PARAM_WIDTH - 70,
+ controlsPanel.setLayout(new BorderLayout());
+ controlsPanel.setBounds(new Rectangle(39, 10, PARAM_WIDTH - 70,
PARAM_CLOSEDHEIGHT - 50));
- firstrow.add(controlPanel);
+ firstrow.add(controlsPanel);
firstrow.setBounds(new Rectangle(10, 20, PARAM_WIDTH - 30,
PARAM_CLOSEDHEIGHT - 30));
- final ParamBox me = this;
if (parm.getDescription() != null
&& parm.getDescription().trim().length() > 0)
{
- // Only create description boxes if there actually is a description.
- if (finfo != null)
- {
- showDesc.setToolTipText(JvSwingUtils.wrapTooltip(true,
- MessageManager.formatMessage(
- "label.opt_and_params_show_brief_desc_image_link",
- new String[]
- { linkImageURL.toExternalForm() })));
- showDesc.addMouseListener(this);
- }
- else
- {
- showDesc.setToolTipText(
- JvSwingUtils.wrapTooltip(true, MessageManager.getString(
- "label.opt_and_params_show_brief_desc")));
- }
- showDesc.addActionListener(new ActionListener()
- {
-
- @Override
- public void actionPerformed(ActionEvent e)
- {
- descisvisible = !descisvisible;
- descPanel.setVisible(descisvisible);
- descPanel.getVerticalScrollBar().setValue(0);
- me.setPreferredSize(new Dimension(PARAM_WIDTH,
- (descisvisible) ? PARAM_HEIGHT : PARAM_CLOSEDHEIGHT));
- me.validate();
- pmdialogbox.refreshParamLayout();
- }
- });
- string.setWrapStyleWord(true);
- string.setLineWrap(true);
- string.setColumns(32);
- string.setText(parm.getDescription());
- showDesc.setBounds(new Rectangle(10, 10, 16, 16));
- firstrow.add(showDesc);
+ addExpandableHelp(firstrow, parm);
}
add(firstrow);
validator = parm.getValidValue();
parameter = parm;
if (validator != null)
{
- integ = validator.getType() == ValueType.Integer;
+ isIntegerParameter = validator.getType() == ValueType.Integer;
}
else
{
if (parameter.getPossibleValues() != null)
{
- choice = true;
+ isChoiceParameter = true;
}
}
updateControls(parm);
}
/**
- * Action on input in text field
+ * Adds a button which can be clicked to show or hide help text
+ *
+ * @param container
+ * @param param
*/
+ protected void addExpandableHelp(JPanel container, ParameterI param)
+ {
+ JButton showDescBtn = new JButton("+");
+ showDescBtn.setFont(new Font("Verdana", Font.PLAIN, 8));
+ if (finfo != null)
+ {
+ descTooltip = JvSwingUtils.wrapTooltip(true,
+ MessageManager.formatMessage(
+ "label.opt_and_params_show_brief_desc_image_link",
+ new String[]
+ { linkImageURL.toExternalForm() }));
+ showDescBtn.addMouseListener(this);
+ }
+ else
+ {
+ descTooltip = JvSwingUtils.wrapTooltip(true, MessageManager
+ .getString("label.opt_and_params_show_brief_desc"));
+ }
+ showDescBtn.setToolTipText(descTooltip);
+ showDescBtn.addActionListener(new ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ descriptionIsVisible = !descriptionIsVisible;
+ showDescBtn.setText(descriptionIsVisible ? "-" : "+");
+ showDescBtn.setToolTipText(
+ descriptionIsVisible ? null : descTooltip);
+ descPanel.setVisible(descriptionIsVisible);
+ descPanel.getVerticalScrollBar().setValue(0);
+ ParamBox.this.setPreferredSize(new Dimension(PARAM_WIDTH,
+ (descriptionIsVisible) ? PARAM_HEIGHT
+ : PARAM_CLOSEDHEIGHT));
+ ParamBox.this.validate();
+ pmdialogbox.refreshParamLayout();
+ }
+ });
+ descriptionText.setWrapStyleWord(true);
+ descriptionText.setLineWrap(true);
+ descriptionText.setColumns(32);
+ descriptionText.setText(param.getDescription());
+ showDescBtn.setBounds(new Rectangle(10, 10, 16, 16));
+ container.add(showDescBtn);
+ }
@Override
public void actionPerformed(ActionEvent e)
{
{
return;
}
- if (!choice)
- {
- updateSliderFromValueField();
- }
checkIfModified();
}
- private void checkIfModified()
- {
- Object cstate = getCurrentValue();
- boolean modified = !cstate.equals(lastVal);
- pmdialogbox.argSetModified(this, modified);
- }
-
/**
- * Answers the current value of the parameter, as text
- *
- * @return
+ * Checks whether the value of this parameter has been changed and notifies
+ * the parent page accordingly
*/
- private String getCurrentValue()
+ private void checkIfModified()
{
- return choice ? (String) choicebox.getSelectedItem()
- : valueField.getText();
+ Object newValue = updateSliderFromValueField();
+ boolean modified = true;
+ if (newValue.getClass() == lastVal.getClass())
+ {
+ modified = !newValue.equals(lastVal);
+ }
+ pmdialogbox.argSetModified(this, modified);
}
@Override
return Component.BaselineResizeBehavior.CONSTANT_ASCENT;
}
- public int getBoxHeight()
- {
- return (descisvisible ? PARAM_HEIGHT : PARAM_CLOSEDHEIGHT);
- }
-
- public ParameterI getParameter()
+ /**
+ * Answers an argument holding the value entered or selected in the dialog
+ *
+ * @return
+ */
+ public ArgumentI getParameter()
{
ParameterI prm = parameter.copy();
- if (choice)
+ String value = null;
+ if (parameter instanceof RadioChoiceParameter)
{
- prm.setValue((String) choicebox.getSelectedItem());
+ value = buttonGroup.getSelection().getActionCommand();
+ }
+ else if (isChoiceParameter)
+ {
+ value = getSelectedValue(this.parameter,
+ choicebox.getSelectedIndex());
}
else
{
- prm.setValue(valueField.getText());
+ value = valueField.getText();
}
+ prm.setValue(value);
return prm;
}
@Override
public void mouseEntered(MouseEvent e)
{
- // TODO Auto-generated method stub
}
@Override
public void mouseExited(MouseEvent e)
{
- // TODO Auto-generated method stub
}
@Override
public void mouseReleased(MouseEvent e)
{
- // TODO Auto-generated method stub
}
- /**
- * Action on change of slider value
- */
@Override
public void stateChanged(ChangeEvent e)
{
- if (!adjusting)
+ if (adjusting)
{
- float value = slider.getSliderValue();
- valueField.setText(
- integ ? Integer.toString((int) value)
- : Float.toString(value));
+ return;
+ }
+ try
+ {
+ adjusting = true;
+ if (!isLogarithmicParameter)
+ {
+ /*
+ * set (int or float formatted) text field value
+ */
+ valueField.setText(isIntegerParameter
+ ? String.valueOf(slider.getValue())
+ : formatDouble(
+ slider.getValue() / (float) sliderScaleFactor));
+ }
+ else
+ {
+ double value = Math.pow(Math.E,
+ slider.getValue() / (double) sliderScaleFactor);
+ valueField.setText(formatDouble(value));
+ }
checkIfModified();
+ } finally
+ {
+ adjusting = false;
}
}
- public void updateControls(ParameterI parm)
+ /**
+ * Answers the value formatted as a string to 3 decimal places - in
+ * scientific notation if the value is less than 0.001
+ *
+ * @param value
+ * @return
+ */
+ String formatDouble(double value)
+ {
+ String format = value < 0.001 ? "%3.1E" : "%3.3f";
+ return String.format(format, value);
+ }
+
+ /**
+ * Formats a number as integer or float (3dp) or scientific notation (1dp)
+ *
+ * @param n
+ * @return
+ */
+ String formatNumber(Number n)
+ {
+ return n instanceof Integer ? String.valueOf(n.intValue())
+ : formatDouble(n.doubleValue());
+ }
+
+ void updateControls(ParameterI parm)
{
adjusting = true;
- boolean init = (choicebox == null && valueField == null);
+ boolean init = (choicebox == null && valueField == null
+ && buttonGroup == null);
if (init)
{
- if (choice)
+ if (parm instanceof RadioChoiceParameter)
+ {
+ buttonGroup = addRadioButtons(parameter, controlsPanel);
+ }
+ else if (isChoiceParameter)
{
- choicebox = new JComboBox<>();
+ choicebox = buildComboBox(parm);
choicebox.addActionListener(this);
- controlPanel.add(choicebox, BorderLayout.CENTER);
+ controlsPanel.add(choicebox, BorderLayout.CENTER);
}
else
{
- valueField = new JTextField();
+ slider = new JSlider();
+ slider.addChangeListener(this);
+ int cols = parm instanceof StringParameter ? 20 : 0;
+ valueField = new JTextField(cols);
valueField.addActionListener(this);
- valueField.addKeyListener(new KeyListener()
+ valueField.addKeyListener(new KeyAdapter()
{
- @Override
- public void keyTyped(KeyEvent e)
- {
- }
@Override
public void keyReleased(KeyEvent e)
{
- if (e.isActionKey())
+ int keyCode = e.getKeyCode();
+ if (e.isActionKey() && keyCode != KeyEvent.VK_LEFT
+ && keyCode != KeyEvent.VK_RIGHT)
{
if (valueField.getText().trim().length() > 0)
{
}
}
- @Override
- public void keyPressed(KeyEvent e)
- {
- }
});
valueField.addFocusListener(new FocusAdapter() {
}
});
- valueField.setPreferredSize(new Dimension(60, 25));
- valueField.setText(parm.getValue());
- slider = makeSlider(parm.getValidValue());
- updateSliderFromValueField();
- slider.addChangeListener(this);
-
- controlPanel.add(slider, BorderLayout.WEST);
- controlPanel.add(valueField, BorderLayout.EAST);
+ valueField.setPreferredSize(new Dimension(65, 25));
+ if (parm instanceof FileParameter)
+ {
+ valueField.setToolTipText(MessageManager
+ .getString("label.double_click_to_browse"));
+ valueField.addMouseListener(new MouseAdapter()
+ {
+ @Override
+ public void mouseClicked(MouseEvent e)
+ {
+ if (e.getClickCount() == 2)
+ {
+ String dir = Cache.getProperty("LAST_DIRECTORY");
+ JalviewFileChooser chooser = new JalviewFileChooser(dir);
+ chooser.setFileView(new JalviewFileView());
+ chooser.setDialogTitle(
+ MessageManager.getString("action.select_ddbb"));
+
+ int val = chooser.showOpenDialog(ParamBox.this);
+ if (val == JalviewFileChooser.APPROVE_OPTION)
+ {
+ File choice = chooser.getSelectedFile();
+ String path = choice.getPath();
+ valueField.setText(path);
+ Cache.setProperty("LAST_DIRECTORY", choice.getParent());
+ FileLoader.updateRecentlyOpened(path,
+ DataSourceType.FILE);
+ }
+ }
+ }
+ });
+ }
+
+ controlsPanel.add(slider, BorderLayout.WEST);
+ controlsPanel.add(valueField, BorderLayout.EAST);
}
}
- if (parm != null)
+ String value = parm.getValue();
+ if (value != null)
{
- if (choice)
+ if (isChoiceParameter)
{
- if (init)
+ if (!(parm instanceof RadioChoiceParameter))
{
- List<String> vals = parm.getPossibleValues();
- for (String val : vals)
- {
- choicebox.addItem(val);
- }
- }
-
- if (parm.getValue() != null)
- {
- choicebox.setSelectedItem(parm.getValue());
+ choicebox.setSelectedItem(value);
}
}
else
{
- valueField.setText(parm.getValue());
+ valueField.setText(value);
}
}
- lastVal = getCurrentValue();
+ lastVal = updateSliderFromValueField();
adjusting = false;
}
- private Slider makeSlider(ValueConstrainI validValue)
+ /**
+ * Adds a panel to comp, containing a label and radio buttons for the choice
+ * of values of the given option. Returns a ButtonGroup whose members are
+ * the added radio buttons.
+ *
+ * @param option
+ * @param comp
+ *
+ * @return
+ */
+ protected ButtonGroup addRadioButtons(OptionI option, Container comp)
{
- if (validValue != null)
+ ButtonGroup bg = new ButtonGroup();
+ JPanel radioPanel = new JPanel();
+ radioPanel.add(new JLabel(option.getDescription()));
+
+ String value = option.getValue();
+
+ for (String opt : option.getPossibleValues())
{
- final Number minValue = validValue.getMin();
- final Number maxValue = validValue.getMax();
- if (minValue != null && maxValue != null)
- {
- return new Slider(minValue.floatValue(), maxValue.floatValue(),
- minValue.floatValue());
- }
+ JRadioButton btn = new JRadioButton(opt);
+ btn.setActionCommand(opt);
+ boolean selected = opt.equals(value);
+ btn.setSelected(selected);
+ btn.addActionListener(this);
+ bg.add(btn);
+ radioPanel.add(btn);
}
+ comp.add(radioPanel);
- /*
- * otherwise, a nominal slider which will not be visible
- */
- return new Slider(0, 100, 50);
+ return bg;
}
- public void updateSliderFromValueField()
+ /**
+ * Action depends on the type of the input parameter:
+ * <ul>
+ * <li>if a text input, returns the trimmed value</li>
+ * <li>if a choice list or radio button, returns the selected value</li>
+ * <li>if a value slider and input field, sets the value of the slider from
+ * the value in the text field, limiting it to any defined min-max
+ * range.</li>
+ * </ul>
+ * Answers the (possibly modified) input value, as a String, Integer, Float
+ * or Double.
+ *
+ * @return
+ */
+ Object updateSliderFromValueField()
{
- if (validator != null)
+ if (validator == null || isStringParameter)
{
- final Number minValue = validator.getMin();
- final Number maxValue = validator.getMax();
- if (integ)
+ if (isChoiceParameter)
{
- int iVal = 0;
- try
+ if (parameter instanceof RadioChoiceParameter)
{
- valueField.setText(valueField.getText().trim());
- iVal = Integer.valueOf(valueField.getText());
- if (minValue != null
- && minValue.intValue() > iVal)
- {
- iVal = minValue.intValue();
- // TODO: provide visual indication that hard limit was reached for
- // this parameter
- }
- if (maxValue != null && maxValue.intValue() < iVal)
- {
- iVal = maxValue.intValue();
- }
- } catch (NumberFormatException e)
- {
- System.err.println(e.toString());
- }
- if (minValue != null || maxValue != null)
- {
- valueField.setText(String.valueOf(iVal));
- slider.setSliderValue(iVal);
+ return buttonGroup.getSelection().getActionCommand();
}
else
{
- slider.setVisible(false);
+ return getSelectedValue(this.parameter,
+ choicebox.getSelectedIndex());
}
}
+ slider.setVisible(false);
+ return valueField.getText().trim();
+ }
+
+ if (validator.getMin() == null || validator.getMax() == null)
+ {
+ slider.setVisible(false);
+ }
+
+ valueField.setText(valueField.getText().trim());
+
+ /*
+ * ensure not outside min-max range
+ * TODO: provide some visual indicator if limit reached
+ */
+ try
+ {
+ valueField.setBackground(Color.WHITE);
+ double d = Double.parseDouble(valueField.getText());
+ if (validator.getMin() != null
+ && validator.getMin().doubleValue() > d)
+ {
+ valueField.setText(formatNumber(validator.getMin()));
+ }
+ if (validator.getMax() != null
+ && validator.getMax().doubleValue() < d)
+ {
+ valueField.setText(formatNumber(validator.getMax()));
+ }
+ } catch (NumberFormatException e)
+ {
+ valueField.setBackground(Color.yellow);
+ return Float.NaN;
+ }
+ if (isIntegerParameter)
+ {
+ int iVal = 0;
+ try
+ {
+ iVal = Integer.valueOf(valueField.getText());
+ } catch (Exception e)
+ {
+ valueField.setBackground(Color.yellow);
+ return Integer.valueOf(0);
+ }
+
+ if (validator.getMin() != null && validator.getMax() != null)
+ {
+ slider.getModel().setRangeProperties(iVal, 1,
+ validator.getMin().intValue(),
+ validator.getMax().intValue() + 1, true);
+ }
else
{
- float fVal = 0f;
- try
- {
- valueField.setText(valueField.getText().trim());
- fVal = Float.valueOf(valueField.getText());
- if (minValue != null
- && minValue.floatValue() > fVal)
- {
- fVal = minValue.floatValue();
- // TODO: provide visual indication that hard limit was reached for
- // this parameter
- // update value field to reflect any bound checking we performed.
- valueField.setText("" + fVal);
- }
- if (maxValue != null
- && maxValue.floatValue() < fVal)
- {
- fVal = maxValue.floatValue();
- // TODO: provide visual indication that hard limit was reached for
- // this parameter
- // update value field to reflect any bound checking we performed.
- valueField.setText("" + fVal);
- }
- } catch (NumberFormatException e)
- {
- System.err.println(e.toString());
- }
- if (minValue != null && maxValue != null)
- {
- slider.setSliderModel(minValue.floatValue(),
- maxValue.floatValue(), fVal);
- }
- else
- {
- slider.setVisible(false);
- }
+ slider.setVisible(false);
}
+ return Integer.valueOf(iVal);
}
- else
+
+ if (isLogarithmicParameter)
{
- if (!choice)
+ double dVal = 0d;
+ try
+ {
+ double eValue = Double.valueOf(valueField.getText());
+ dVal = Math.log(eValue);
+ } catch (Exception e)
+ {
+ // shouldn't be possible here
+ valueField.setBackground(Color.yellow);
+ return Double.NaN;
+ }
+ if (validator.getMin() != null && validator.getMax() != null)
+ {
+ double scaleMin = Math.log(validator.getMin().doubleValue())
+ * sliderScaleFactor;
+ double scaleMax = Math.log(validator.getMax().doubleValue())
+ * sliderScaleFactor;
+ slider.getModel().setRangeProperties(
+ (int) (sliderScaleFactor * dVal), 1,
+ (int) scaleMin, 1 + (int) scaleMax, true);
+ }
+ else
{
slider.setVisible(false);
}
+ return Double.valueOf(dVal);
}
+
+ float fVal = 0f;
+ try
+ {
+ fVal = Float.valueOf(valueField.getText());
+ } catch (Exception e)
+ {
+ return Float.valueOf(0f); // shouldn't happen
+ }
+ if (validator.getMin() != null && validator.getMax() != null)
+ {
+ float scaleMin = validator.getMin().floatValue()
+ * sliderScaleFactor;
+ float scaleMax = validator.getMax().floatValue()
+ * sliderScaleFactor;
+ slider.getModel().setRangeProperties(
+ (int) (fVal * sliderScaleFactor), 1, (int) scaleMin,
+ 1 + (int) scaleMax, true);
+ }
+ else
+ {
+ slider.setVisible(false);
+ }
+ return Float.valueOf(fVal);
}
}
- public static final int PARAM_WIDTH = 340;
-
- public static final int PARAM_HEIGHT = 150;
-
- public static final int PARAM_CLOSEDHEIGHT = 80;
-
- public OptsAndParamsPage(OptsParametersContainerI paramContainer)
- {
- this(paramContainer, false);
- }
+ /**
+ * Constructor with the option to show 'compact' format (parameter description
+ * as tooltip) or 'expanded' format (parameter description in a textbox which
+ * may be opened or closed). Use compact for simple description text, expanded
+ * for more wordy or formatted text.
+ *
+ * @param paramContainer
+ */
public OptsAndParamsPage(OptsParametersContainerI paramContainer,
boolean compact)
mnu.show(invoker, x, y);
}
- URL linkImageURL = getClass().getResource("/images/link.gif");
-
- Map<String, OptionBox> optSet = new java.util.LinkedHashMap<>();
-
- Map<String, ParamBox> paramSet = new java.util.LinkedHashMap<>();
public Map<String, OptionBox> getOptSet()
{
this.paramSet = paramSet;
}
- OptsParametersContainerI poparent;
OptionBox addOption(OptionI opt)
{
}
/**
- * recover options and parameters from GUI
+ * Answers a list of arguments representing all the options and arguments
+ * selected on the dialog, holding their chosen or input values. Optional
+ * parameters which were not selected are not included.
*
* @return
*/
List<ArgumentI> argSet = new ArrayList<>();
for (OptionBox opts : getOptSet().values())
{
- OptionI opt = opts.getOptionIfEnabled();
+ ArgumentI opt = opts.getSelectedOption();
if (opt != null)
{
argSet.add(opt);
}
for (ParamBox parambox : getParamSet().values())
{
- ParameterI parm = parambox.getParameter();
+ ArgumentI parm = parambox.getParameter();
if (parm != null)
{
argSet.add(parm);
return argSet;
}
+ /**
+ * A helper method that constructs and returns a CombBox for choice of the
+ * possible option values. If display names are provided, then these are added
+ * as options, otherwise the actual values are added.
+ *
+ * @param opt
+ * @return
+ */
+ protected static JComboBox<Object> buildComboBox(OptionI opt)
+ {
+ JComboBox<Object> cb = null;
+ List<String> displayNames = opt.getDisplayNames();
+ if (displayNames != null)
+ {
+ List<Object> displayNamesObjects = new ArrayList<>();
+ displayNamesObjects.addAll(displayNames);
+ cb = JvSwingUtils.buildComboWithTooltips(displayNamesObjects,
+ opt.getPossibleValues());
+ }
+ else
+ {
+ cb = new JComboBox<>();
+ for (String v : opt.getPossibleValues())
+ {
+ cb.addItem(v);
+ }
+ }
+ return cb;
+ }
+
+ /**
+ * Answers the value corresponding to the selected item in the choice combo
+ * box. Note that this returns the underlying value even if a different
+ * display name is used in the combo box.
+ *
+ * @return
+ */
+ protected static String getSelectedValue(OptionI opt, int sel)
+ {
+ List<String> possibleValues = opt.getPossibleValues();
+ String value = null;
+ if (possibleValues != null && possibleValues.size() == 1)
+ {
+ // Hack to make sure the default value for an enabled option with only
+ // one value is actually returned even if this.val is not displayed
+ value = possibleValues.get(0);
+ }
+ else if (sel >= 0 && sel < possibleValues.size())
+ {
+ value = possibleValues.get(sel);
+ }
+ return value;
+ }
}
*/
package jalview.gui;
+import jalview.api.AlignViewportI;
import jalview.bin.Cache;
import jalview.renderer.OverviewRenderer;
import jalview.util.MessageManager;
private OverviewCanvas oviewCanvas;
- protected AlignViewport av;
+ private AlignViewportI av;
private AlignmentPanel ap;
protected boolean draggingBox = false;
+ private Dimension dim;
+
+ private boolean showProgress = !Platform.isJS();
+
protected ProgressPanel progressPanel;
+
/**
- * Creates a new OverviewPanel object.
- *
- * @param alPanel
- * The alignment panel which is shown in the overview panel
+ * Creates the appropriate type of OverviewDimensions, with the desired size
*/
- public OverviewPanel(AlignmentPanel alPanel)
+ private void createOverviewDimensions()
{
- this.av = alPanel.av;
- this.ap = alPanel;
-
- showHidden = Cache.getDefault(Preferences.SHOW_OV_HIDDEN_AT_START,
- false);
+ boolean showAnnotation = (av.isShowAnnotation()
+ && av.getAlignmentConservationAnnotation() != null);
if (showHidden)
{
- od = new OverviewDimensionsShowHidden(av.getRanges(),
- (av.isShowAnnotation()
- && av.getAlignmentConservationAnnotation() != null));
+ od = new OverviewDimensionsShowHidden(av.getRanges(), showAnnotation,
+ dim);
}
else
{
- od = new OverviewDimensionsHideHidden(av.getRanges(),
- (av.isShowAnnotation()
- && av.getAlignmentConservationAnnotation() != null));
+ od = new OverviewDimensionsHideHidden(av.getRanges(), showAnnotation,
+ dim);
}
+ }
+ public OverviewPanel(AlignmentPanel alPanel, Dimension dim)
+ {
+ this.av = alPanel.av;
+ this.ap = alPanel;
+ this.dim = dim;
+
+ showHidden = Cache.getDefault(Preferences.SHOW_OV_HIDDEN_AT_START,
+ false);
+ createOverviewDimensions();
setLayout(new BorderLayout());
progressPanel = new ProgressPanel(OverviewRenderer.UPDATE,
MessageManager.getString("label.oview_calc"), getWidth());
*/
protected void toggleHiddenColumns()
{
- if (showHidden)
- {
- showHidden = false;
- od = new OverviewDimensionsHideHidden(av.getRanges(),
- (av.isShowAnnotation()
- && av.getAlignmentConservationAnnotation() != null));
- }
- else
- {
- showHidden = true;
- od = new OverviewDimensionsShowHidden(av.getRanges(),
- (av.isShowAnnotation()
- && av.getAlignmentConservationAnnotation() != null));
- }
+ showHidden = !showHidden;
+ createOverviewDimensions();
oviewCanvas.resetOviewDims(od);
updateOverviewImage();
setBoxPosition();
import jalview.math.RotatableMatrix.Axis;
import jalview.util.ImageMaker;
import jalview.util.MessageManager;
+import jalview.util.Platform;
import jalview.viewmodel.AlignmentViewport;
import jalview.viewmodel.PCAModel;
repaint();
if (getParent() == null)
{
- Desktop.addInternalFrame(this,
- MessageManager.formatMessage("label.calc_title", "PCA",
- getPcaModel().getScoreModelName()),
- 475, 450);
+ addToDesktop(this, getPcaModel().getScoreModelName());
this.setMinimumSize(new Dimension(MIN_WIDTH, MIN_HEIGHT));
}
working = false;
// // setMenusForViewport();
// validate();
}
+
+ @Override
+ public void removeProgressBar(long id)
+ {
+ progressBar.removeProgressBar(id);
+ }
@Override
public void registerHandler(final long id,
getRotatableCanvas().ap = panel;
PaintRefresher.Register(PCAPanel.this, panel.av.getSequenceSetId());
}
+
+ public static void addToDesktop(PCAPanel panel, String modelName)
+ {
+ Dimension dim = Platform.getDimIfEmbedded(panel, 475, 450);
+ Desktop.addInternalFrame(panel, MessageManager.formatMessage(
+ "label.calc_title", "PCA", modelName), dim.width,
+ dim.height);
+ }
}
*/
public class PaintRefresher
{
+ private static final int ALIGNMENT_CHANGED = 1 << 0;
+ private static final int VALIDATE_SEQUENCES = 1 << 1;
+
static Map<String, List<Component>> components = new HashMap<>();
/**
{
List<Component> comps = components.get(id);
+ int mode = (alignmentChanged ? ALIGNMENT_CHANGED : 0) | (validateSequences ? VALIDATE_SEQUENCES : 0);
if (comps == null)
{
return;
}
+ repaintComponents(source, mode, comps.toArray(new Component[comps.size()]));
+ }
- for (Component comp : comps)
+ public static void repaintComponents(Component source, int mode,
+ Component... comps)
+ {
+ for (int i = 0; i < comps.length; i++)
{
- if (comp == source)
+ Component comp = comps[i];
+ if (comp == null)
{
continue;
}
if (comp instanceof AlignmentPanel)
{
- if (validateSequences && source instanceof AlignmentPanel)
+ if ((mode & VALIDATE_SEQUENCES) != 0 && source instanceof AlignmentPanel)
{
validateSequences(((AlignmentPanel) source).av.getAlignment(),
((AlignmentPanel) comp).av.getAlignment());
}
- if (alignmentChanged)
+ if ((mode & ALIGNMENT_CHANGED) != 0)
{
((AlignmentPanel) comp).alignmentChanged();
}
{
// BH 2019.04.22 fixes JS problem of repaint() consolidation
// that occurs in JavaScript but not Java [JAL-3226]
- ((IdCanvas) comp).fastPaint = false;
+ ((IdCanvas) comp).setNoFastPaint();
}
else if (comp instanceof SeqCanvas)
{
// BH 2019.04.22 fixes JS problem of repaint() consolidation
// that occurs in JavaScript but not Java [JAL-3226]
- ((SeqCanvas) comp).fastPaint = false;
+ ((SeqCanvas) comp).setNoFastPaint();
}
comp.repaint();
}
return tmp.toArray(new AlignmentPanel[tmp.size()]);
}
+
}
package jalview.gui;
import jalview.analysis.AlignSeq;
+import jalview.api.AlignViewportI;
import jalview.datamodel.Alignment;
import jalview.datamodel.AlignmentView;
import jalview.datamodel.SequenceGroup;
import jalview.datamodel.SequenceI;
import jalview.jbgui.GPairwiseAlignPanel;
import jalview.util.MessageManager;
-import jalview.viewmodel.AlignmentViewport;
import java.awt.event.ActionEvent;
import java.util.Vector;
private static final String DASHES = "---------------------\n";
- AlignmentViewport av;
+ AlignViewportI av;
Vector<SequenceI> sequences;
* Creates a new PairwiseAlignPanel object.
*
* @param viewport
- * DOCUMENT ME!
*/
- public PairwiseAlignPanel(AlignmentViewport viewport)
+ public PairwiseAlignPanel(AlignViewportI viewport)
{
super();
this.av = viewport;
- sequences = new Vector<SequenceI>();
+ sequences = new Vector<>();
SequenceGroup selectionGroup = viewport.getSelectionGroup();
boolean isSelection = selectionGroup != null
import jalview.datamodel.HiddenColumns;
import jalview.datamodel.MappedFeatures;
import jalview.datamodel.PDBEntry;
+import jalview.datamodel.ResidueCount;
import jalview.datamodel.SequenceFeature;
import jalview.datamodel.SequenceGroup;
import jalview.datamodel.SequenceI;
import jalview.gui.ColourMenuHelper.ColourChangeListener;
import jalview.gui.JalviewColourChooser.ColourChooserListener;
+import jalview.io.CountReader;
import jalview.io.FileFormatI;
import jalview.io.FileFormats;
import jalview.io.FormatAdapter;
import jalview.util.UrlLink;
import jalview.viewmodel.seqfeatures.FeatureRendererModel;
+import java.io.IOException;
+import java.net.MalformedURLException;
+
/**
* The popup menu that is displayed on right-click on a sequence id, or in the
* sequence alignment.
jalview.util.BrowserLauncher.openURL(url);
} catch (Exception ex)
{
- JvOptionPane.showInternalMessageDialog(Desktop.desktop,
+ JvOptionPane.showInternalMessageDialog(Desktop.getDesktopPane(),
MessageManager.getString("label.web_browser_not_found_unix"),
MessageManager.getString("label.web_browser_not_found"),
JvOptionPane.WARNING_MESSAGE);
}
}
+ if (seq.hasHMMProfile())
+ {
+ menuItem = new JMenuItem(MessageManager
+ .getString("action.add_background_frequencies"));
+ menuItem.addActionListener(new ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ try
+ {
+ ResidueCount counts = CountReader.getBackgroundFrequencies(ap,
+ seq);
+ if (counts != null)
+ {
+ seq.getHMM().setBackgroundFrequencies(counts);
+ ap.alignFrame.buildColourMenu();
+ }
+ } catch (MalformedURLException e1)
+ {
+ e1.printStackTrace();
+ } catch (IOException e1)
+ {
+ e1.printStackTrace();
+ }
+ }
+ });
+ add(menuItem);
+ }
+
menuItem = new JMenuItem(
MessageManager.getString("action.hide_sequences"));
menuItem.addActionListener(new ActionListener()
buildGroupURLMenu(sg, groupLinks);
}
// Add a 'show all structures' for the current selection
- Hashtable<String, PDBEntry> pdbe = new Hashtable<>(), reppdb = new Hashtable<>();
+ Hashtable<String, PDBEntry> pdbe = new Hashtable<>();
+ Hashtable<String, PDBEntry> reppdb = new Hashtable<>();
SequenceI sqass = null;
for (SequenceI sq : alignPanel.av.getSequenceSelection())
menuItem.setEnabled(true);
for (String calcId : tipEntries.keySet())
{
- tooltip.append("<br/>" + calcId + "/" + tipEntries.get(calcId));
+ tooltip.append("<br>" + calcId + "/" + tipEntries.get(calcId));
}
String tooltipText = JvSwingUtils.wrapTooltip(true,
tooltip.toString());
ap.paintAlignment(false, false);
}
sequence.setDescription(dialog.getDescription());
- ap.av.firePropertyChange("alignment", null,
- ap.av.getAlignment().getSequences());
+ ap.av.notifyAlignment();
}
});
}
refresh();
}
};
- JalviewColourChooser.showColourChooser(Desktop.getDesktop(),
+ JalviewColourChooser.showColourChooser(Desktop.getDesktopPane(),
title, Color.BLUE, listener);
}
startEnd, caseChange);
ap.alignFrame.addHistoryItem(caseCommand);
+ ap.av.notifyAlignment();
- ap.av.firePropertyChange("alignment", null,
- ap.av.getAlignment().getSequences());
}
}
sg.getStartRes(), sg.getEndRes() + 1,
ap.av.getAlignment());
ap.alignFrame.addHistoryItem(editCommand);
- ap.av.firePropertyChange("alignment", null,
- ap.av.getAlignment().getSequences());
+ ap.av.notifyAlignment();
}
});
}
*/
package jalview.gui;
+
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
+import java.awt.event.FocusAdapter;
+import java.awt.event.FocusEvent;
import java.awt.event.MouseEvent;
import java.io.File;
import java.util.ArrayList;
import javax.swing.JFileChooser;
import javax.swing.JInternalFrame;
import javax.swing.JPanel;
+import javax.swing.JTextField;
import javax.swing.ListSelectionModel;
import javax.swing.RowFilter;
import javax.swing.RowSorter;
import javax.swing.table.TableModel;
import javax.swing.table.TableRowSorter;
+import jalview.hmmer.HmmerCommand;
+import jalview.util.FileUtils;
import ext.edu.ucsf.rbvi.strucviz2.StructureManager;
import jalview.analysis.AnnotationSorter.SequenceAnnotationOrder;
import jalview.bin.Cache;
* @author $author$
* @version $Revision$
*/
-/*
- * for merge with Jalview-JS
- public class Preferences extends GPreferences implements ApplicationSingletonI
- */
-public class Preferences extends GPreferences
-{
- public static final String ENABLE_SPLIT_FRAME = "ENABLE_SPLIT_FRAME";
- public static final String SCALE_PROTEIN_TO_CDNA = "SCALE_PROTEIN_TO_CDNA";
+public class Preferences extends GPreferences implements ApplicationSingletonI
+{
+ // suggested list delimiter character
+ public static final String COMMA = ",";
- public static final String DEFAULT_COLOUR = "DEFAULT_COLOUR";
+ public static final String HMMSEARCH_SEQCOUNT = "HMMSEARCH_SEQCOUNT";
- public static final String DEFAULT_COLOUR_PROT = "DEFAULT_COLOUR_PROT";
+ public static final String HMMINFO_GLOBAL_BACKGROUND = "HMMINFO_GLOBAL_BACKGROUND";
- public static final String DEFAULT_COLOUR_NUC = "DEFAULT_COLOUR_NUC";
+ public static final String HMMALIGN_TRIM_TERMINI = "HMMALIGN_TRIM_TERMINI";
+
+ public static final String ADD_SS_ANN = "ADD_SS_ANN";
public static final String ADD_TEMPFACT_ANN = "ADD_TEMPFACT_ANN";
- public static final String ADD_SS_ANN = "ADD_SS_ANN";
+ public static final String ALLOW_UNPUBLISHED_PDB_QUERYING = "ALLOW_UNPUBLISHED_PDB_QUERYING";
- public static final String USE_RNAVIEW = "USE_RNAVIEW";
+ public static final String ANNOTATIONCOLOUR_MAX = "ANNOTATIONCOLOUR_MAX";
- public static final String STRUCT_FROM_PDB = "STRUCT_FROM_PDB";
+ public static final String ANNOTATIONCOLOUR_MIN = "ANNOTATIONCOLOUR_MIN";
- public static final String STRUCTURE_DISPLAY = "STRUCTURE_DISPLAY";
+ public static final String ANTI_ALIAS = "ANTI_ALIAS";
+
+ public static final String AUTO_CALC_CONSENSUS = "AUTO_CALC_CONSENSUS";
+
+ public static final String AUTOASSOCIATE_PDBANDSEQS = "AUTOASSOCIATE_PDBANDSEQS";
+
+ public static final String BLOSUM62_PCA_FOR_NUCLEOTIDE = "BLOSUM62_PCA_FOR_NUCLEOTIDE";
+
+ public static final String CENTRE_COLUMN_LABELS = "CENTRE_COLUMN_LABELS";
public static final String CHIMERA_PATH = "CHIMERA_PATH";
public static final String CHIMERAX_PATH = "CHIMERAX_PATH";
+ public static final String DBREFFETCH_USEPICR = "DBREFFETCH_USEPICR";
+
+ public static final String DEFAULT_COLOUR = "DEFAULT_COLOUR";
+
+ public static final String DEFAULT_COLOUR_NUC = "DEFAULT_COLOUR_NUC";
+ public static final String DEFAULT_COLOUR_PROT = "DEFAULT_COLOUR_PROT";
+
+ public static final String ENABLE_SPLIT_FRAME = "ENABLE_SPLIT_FRAME";
+
+ public static final String FIGURE_AUTOIDWIDTH = "FIGURE_AUTOIDWIDTH";
+
+ public static final String FIGURE_FIXEDIDWIDTH = "FIGURE_FIXEDIDWIDTH";
+
+ public static final String FOLLOW_SELECTIONS = "FOLLOW_SELECTIONS";
+
+ public static final String FONT_NAME = "FONT_NAME";
+
+ public static final String FONT_SIZE = "FONT_SIZE";
+
+ public static final String FONT_STYLE = "FONT_STYLE";
+
+ public static final String HMMER_PATH = "HMMER_PATH";
+
+ public static final String CYGWIN_PATH = "CYGWIN_PATH";
+
+ public static final String HMMSEARCH_DBS = "HMMSEARCH_DBS";
+
+ public static final String GAP_COLOUR = "GAP_COLOUR";
+
+ public static final String GAP_SYMBOL = "GAP_SYMBOL";
+
+ public static final String HIDDEN_COLOUR = "HIDDEN_COLOUR";
+
+ public static final String HIDE_INTRONS = "HIDE_INTRONS";
+
+ public static final String ID_ITALICS = "ID_ITALICS";
+
+ public static final String ID_ORG_HOSTURL = "ID_ORG_HOSTURL";
+
+ public static final String MAP_WITH_SIFTS = "MAP_WITH_SIFTS";
+
+ public static final String NOQUESTIONNAIRES = "NOQUESTIONNAIRES";
+
+ public static final String NORMALISE_CONSENSUS_LOGO = "NORMALISE_CONSENSUS_LOGO";
+
+ public static final String NORMALISE_LOGO = "NORMALISE_LOGO";
+
+ public static final String PAD_GAPS = "PAD_GAPS";
+
+ public static final String PDB_DOWNLOAD_FORMAT = "PDB_DOWNLOAD_FORMAT";
+
public static final String PYMOL_PATH = "PYMOL_PATH";
- public static final String SORT_ANNOTATIONS = "SORT_ANNOTATIONS";
+ public static final String QUESTIONNAIRE = "QUESTIONNAIRE";
+
+ public static final String RELAXEDSEQIDMATCHING = "RELAXEDSEQIDMATCHING";
+
+ public static final String RIGHT_ALIGN_IDS = "RIGHT_ALIGN_IDS";
+
+ public static final String SCALE_PROTEIN_TO_CDNA = "SCALE_PROTEIN_TO_CDNA";
+
+ public static final String SHOW_ANNOTATIONS = "SHOW_ANNOTATIONS";
public static final String SHOW_AUTOCALC_ABOVE = "SHOW_AUTOCALC_ABOVE";
+ public static final String SHOW_CONSENSUS = "SHOW_CONSENSUS";
+
+ public static final String SHOW_CONSENSUS_HISTOGRAM = "SHOW_CONSENSUS_HISTOGRAM";
+
+ public static final String SHOW_CONSENSUS_LOGO = "SHOW_CONSENSUS_LOGO";
+
+ public static final String SHOW_CONSERVATION = "SHOW_CONSERVATION";
+
+ public static final String SHOW_DBREFS_TOOLTIP = "SHOW_DBREFS_TOOLTIP";
+
+ public static final String SHOW_GROUP_CONSENSUS = "SHOW_GROUP_CONSENSUS";
+
+ public static final String SHOW_GROUP_CONSERVATION = "SHOW_GROUP_CONSERVATION";
+
+ public static final String SHOW_JVSUFFIX = "SHOW_JVSUFFIX";
+
+ public static final String SHOW_NPFEATS_TOOLTIP = "SHOW_NPFEATS_TOOLTIP";
public static final String SHOW_OCCUPANCY = "SHOW_OCCUPANCY";
public static final String SHOW_OV_HIDDEN_AT_START = "SHOW_OV_HIDDEN_AT_START";
+ public static final String SHOW_OVERVIEW = "SHOW_OVERVIEW";
+
+ public static final String SHOW_QUALITY = "SHOW_QUALITY";
+
+ public static final String SHOW_UNCONSERVED = "SHOW_UNCONSERVED";
+
+ public static final String SORT_ALIGNMENT = "SORT_ALIGNMENT";
+
+ public static final String SORT_ANNOTATIONS = "SORT_ANNOTATIONS";
+
+ public static final String SORT_BY_TREE = "SORT_BY_TREE";
+
+ public static final String STRUCT_FROM_PDB = "STRUCT_FROM_PDB";
+
+ public static final String STRUCTURE_DISPLAY = "STRUCTURE_DISPLAY";
+
+ public static final String STRUCTURE_DIMENSIONS = "STRUCTURE_DIMENSIONS";
+
+ public static final String UNIPROT_DOMAIN = "UNIPROT_DOMAIN";
+
+ public static final String USE_FULL_SO = "USE_FULL_SO";
public static final String USE_LEGACY_GAP = "USE_LEGACY_GAP";
- public static final String GAP_COLOUR = "GAP_COLOUR";
+ public static final String USE_RNAVIEW = "USE_RNAVIEW";
- public static final String HIDDEN_COLOUR = "HIDDEN_COLOUR";
+ public static final String USER_DEFINED_COLOURS = "USER_DEFINED_COLOURS";
+
+ public static final String WRAP_ALIGNMENT = "WRAP_ALIGNMENT";
private static final int MIN_FONT_SIZE = 1;
private String previousProxyType;
private static Preferences INSTANCE = null; // add "final"
-
/**
* Holds name and link separated with | character. Sequence ID must be
* $SEQUENCE_ID$ or $SEQUENCE_ID=/.possible | chars ./=$
private WsPreferences wsPrefs;
+ private SlivkaPreferences slivkaPrefs;
private OptionsParam promptEachTimeOpt = new OptionsParam(
MessageManager.getString("label.prompt_each_time"),
"Prompt each time");
this.setMessage(message);
this.frame.show();
}
-
/**
* Creates a new Preferences object.
*/
{
wsPrefs = new WsPreferences();
wsTab.add(wsPrefs, BorderLayout.CENTER);
+ slivkaPrefs = new SlivkaPreferences();
+ slivkaTab.add(slivkaPrefs, BorderLayout.CENTER);
}
int width = 500, height = 450;
if (Platform.isAMacAndNotJS())
frame.setMinimumSize(new Dimension(width, height));
/*
+ * Set HMMER tab defaults
+ */
+ hmmrTrimTermini.setSelected(Cache.getDefault(HMMALIGN_TRIM_TERMINI, false));
+ if (Cache.getDefault(HMMINFO_GLOBAL_BACKGROUND, false))
+ {
+ hmmerBackgroundUniprot.setSelected(true);
+ }
+ else
+ {
+ hmmerBackgroundAlignment.setSelected(true);
+ }
+ hmmerSequenceCount
+ .setText(Cache.getProperty(HMMSEARCH_SEQCOUNT));
+ hmmerPath.setText(Cache.getProperty(HMMER_PATH));
+ hmmerPath.addActionListener(new ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ validateHmmerPath();
+ }
+ });
+ hmmerPath.addFocusListener(new FocusAdapter()
+ {
+ @Override
+ public void focusLost(FocusEvent e)
+ {
+ validateHmmerPath();
+ }
+ });
+ if (cygwinPath != null)
+ {
+ String path = Cache.getProperty(CYGWIN_PATH);
+ if (path == null)
+ {
+ path = FileUtils.getPathTo("bash");
+ }
+ cygwinPath.setText(path);
+ cygwinPath.addActionListener(new ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ validateCygwinPath();
+ }
+ });
+ cygwinPath.addFocusListener(new FocusAdapter()
+ {
+ @Override
+ public void focusLost(FocusEvent e)
+ {
+ validateCygwinPath();
+ }
+ });
+ }
+
+ /*
* Set Visual tab defaults
*/
seqLimit.setSelected(Cache.getDefault("SHOW_JVSUFFIX", true));
Cache.getDefault("SHOW_CONSENSUS_HISTOGRAM", true));
showConsensLogo
.setSelected(Cache.getDefault("SHOW_CONSENSUS_LOGO", false));
+ showInformationHistogram.setSelected(
+ Cache.getDefault("SHOW_INFORMATION_HISTOGRAM", true));
+ showHMMLogo.setSelected(Cache.getDefault("SHOW_HMM_LOGO", false));
showNpTooltip
.setSelected(Cache.getDefault("SHOW_NPFEATS_TOOLTIP", true));
showDbRefTooltip
addSecondaryStructure.setEnabled(structSelected);
addTempFactor.setSelected(Cache.getDefault(ADD_TEMPFACT_ANN, true));
addTempFactor.setEnabled(structSelected);
-
/*
* set choice of structure viewer, and path if saved as a preference;
* default to Jmol (first choice) if an unexpected value is found
*/
- String viewerType = Cache.getDefault(STRUCTURE_DISPLAY,
+ String viewerType = ViewerType.JMOL.name();
+ if (!Platform.isJS())
+ {
+ Cache.getDefault(STRUCTURE_DISPLAY,
ViewerType.JMOL.name());
+ }
+ // TODO - disable external viewers for JS
structViewer.setSelectedItem(viewerType);
String viewerPath = "";
ViewerType type = null;
annotations_actionPerformed(null); // update the display of the annotation
// settings
-
+
+
/*
* Set Backups tab defaults
*/
comboBox.addItem(promptEachTimeOpt);
comboBox.addItem(lineArtOpt);
comboBox.addItem(textOpt);
-
+
/*
* JalviewJS doesn't support Lineart so force it to Text
*/
* Set proxy settings first (to be before web services refresh)
*/
saveProxySettings();
-
/*
* Save Visual settings
*/
- Cache.applicationProperties.setProperty("SHOW_JVSUFFIX",
+ Cache.setPropertyNoSave("SHOW_JVSUFFIX",
Boolean.toString(seqLimit.isSelected()));
- Cache.applicationProperties.setProperty("RIGHT_ALIGN_IDS",
+ Cache.setPropertyNoSave("RIGHT_ALIGN_IDS",
Boolean.toString(rightAlign.isSelected()));
- Cache.applicationProperties.setProperty("SHOW_FULLSCREEN",
+ Cache.setPropertyNoSave("SHOW_FULLSCREEN",
Boolean.toString(fullScreen.isSelected()));
- Cache.applicationProperties.setProperty("SHOW_OVERVIEW",
+ Cache.setPropertyNoSave("SHOW_OVERVIEW",
Boolean.toString(openoverv.isSelected()));
- Cache.applicationProperties.setProperty("SHOW_ANNOTATIONS",
+ Cache.setPropertyNoSave("SHOW_ANNOTATIONS",
Boolean.toString(annotations.isSelected()));
- Cache.applicationProperties.setProperty("SHOW_CONSERVATION",
+ Cache.setPropertyNoSave("SHOW_CONSERVATION",
Boolean.toString(conservation.isSelected()));
- Cache.applicationProperties.setProperty("SHOW_QUALITY",
+ Cache.setPropertyNoSave("SHOW_QUALITY",
Boolean.toString(quality.isSelected()));
- Cache.applicationProperties.setProperty("SHOW_IDENTITY",
+ Cache.setPropertyNoSave("SHOW_IDENTITY",
Boolean.toString(identity.isSelected()));
- Cache.applicationProperties.setProperty("GAP_SYMBOL",
+ Cache.setPropertyNoSave("GAP_SYMBOL",
gapSymbolCB.getSelectedItem().toString());
- Cache.applicationProperties.setProperty("FONT_NAME",
+ Cache.setPropertyNoSave("FONT_NAME",
fontNameCB.getSelectedItem().toString());
- Cache.applicationProperties.setProperty("FONT_STYLE",
+ Cache.setPropertyNoSave("FONT_STYLE",
fontStyleCB.getSelectedItem().toString());
- Cache.applicationProperties.setProperty("FONT_SIZE",
+ Cache.setPropertyNoSave("FONT_SIZE",
fontSizeCB.getSelectedItem().toString());
- Cache.applicationProperties.setProperty("ID_ITALICS",
+ Cache.setPropertyNoSave("ID_ITALICS",
Boolean.toString(idItalics.isSelected()));
- Cache.applicationProperties.setProperty("SHOW_UNCONSERVED",
+ Cache.setPropertyNoSave("SHOW_UNCONSERVED",
Boolean.toString(showUnconserved.isSelected()));
- Cache.applicationProperties.setProperty(SHOW_OCCUPANCY,
+ Cache.setPropertyNoSave(SHOW_OCCUPANCY,
Boolean.toString(showOccupancy.isSelected()));
- Cache.applicationProperties.setProperty("SHOW_GROUP_CONSENSUS",
+ Cache.setPropertyNoSave("SHOW_GROUP_CONSENSUS",
Boolean.toString(showGroupConsensus.isSelected()));
- Cache.applicationProperties.setProperty("SHOW_GROUP_CONSERVATION",
+ Cache.setPropertyNoSave("SHOW_GROUP_CONSERVATION",
Boolean.toString(showGroupConservation.isSelected()));
- Cache.applicationProperties.setProperty("SHOW_CONSENSUS_HISTOGRAM",
+ Cache.setPropertyNoSave("SHOW_CONSENSUS_HISTOGRAM",
Boolean.toString(showConsensHistogram.isSelected()));
- Cache.applicationProperties.setProperty("SHOW_CONSENSUS_LOGO",
+ Cache.setPropertyNoSave("SHOW_CONSENSUS_LOGO",
Boolean.toString(showConsensLogo.isSelected()));
- Cache.applicationProperties.setProperty("ANTI_ALIAS",
+ Cache.setPropertyNoSave("SHOW_INFORMATION_HISTOGRAM",
+ Boolean.toString(showConsensHistogram.isSelected()));
+ Cache.setPropertyNoSave("SHOW_HMM_LOGO",
+ Boolean.toString(showHMMLogo.isSelected()));
+ Cache.setPropertyNoSave("ANTI_ALIAS",
Boolean.toString(smoothFont.isSelected()));
- Cache.applicationProperties.setProperty(SCALE_PROTEIN_TO_CDNA,
+ Cache.setPropertyNoSave(SCALE_PROTEIN_TO_CDNA,
Boolean.toString(scaleProteinToCdna.isSelected()));
- Cache.applicationProperties.setProperty("SHOW_NPFEATS_TOOLTIP",
+ Cache.setPropertyNoSave("SHOW_NPFEATS_TOOLTIP",
Boolean.toString(showNpTooltip.isSelected()));
- Cache.applicationProperties.setProperty("SHOW_DBREFS_TOOLTIP",
+ Cache.setPropertyNoSave("SHOW_DBREFS_TOOLTIP",
Boolean.toString(showDbRefTooltip.isSelected()));
- Cache.applicationProperties.setProperty("WRAP_ALIGNMENT",
+ Cache.setPropertyNoSave("WRAP_ALIGNMENT",
Boolean.toString(wrap.isSelected()));
- Cache.applicationProperties.setProperty("STARTUP_FILE",
+ Cache.setPropertyNoSave("STARTUP_FILE",
startupFileTextfield.getText());
- Cache.applicationProperties.setProperty("SHOW_STARTUP_FILE",
+ Cache.setPropertyNoSave("SHOW_STARTUP_FILE",
Boolean.toString(startupCheckbox.isSelected()));
- Cache.applicationProperties.setProperty("SORT_ALIGNMENT",
+ Cache.setPropertyNoSave("SORT_ALIGNMENT",
sortby.getSelectedItem().toString());
// convert description of sort order to enum name for save
.forDescription(sortAnnBy.getSelectedItem().toString());
if (annSortOrder != null)
{
- Cache.applicationProperties.setProperty(SORT_ANNOTATIONS,
+ Cache.setPropertyNoSave(SORT_ANNOTATIONS,
annSortOrder.name());
}
final boolean showAutocalcFirst = sortAutocalc.getSelectedIndex() == 0;
- Cache.applicationProperties.setProperty(SHOW_AUTOCALC_ABOVE,
+ Cache.setPropertyNoSave(SHOW_AUTOCALC_ABOVE,
Boolean.valueOf(showAutocalcFirst).toString());
/*
* Save Colours settings
*/
- Cache.applicationProperties.setProperty(DEFAULT_COLOUR_PROT,
+ Cache.setPropertyNoSave(DEFAULT_COLOUR_PROT,
protColour.getSelectedItem().toString());
- Cache.applicationProperties.setProperty(DEFAULT_COLOUR_NUC,
+ Cache.setPropertyNoSave(DEFAULT_COLOUR_NUC,
nucColour.getSelectedItem().toString());
- Cache.setColourProperty("ANNOTATIONCOLOUR_MIN",
+ Cache.setColourPropertyNoSave("ANNOTATIONCOLOUR_MIN",
minColour.getBackground());
- Cache.setColourProperty("ANNOTATIONCOLOUR_MAX",
+ Cache.setColourPropertyNoSave("ANNOTATIONCOLOUR_MAX",
maxColour.getBackground());
/*
+ * Save HMMER settings
+ */
+ Cache.setPropertyNoSave(HMMALIGN_TRIM_TERMINI,
+ Boolean.toString(hmmrTrimTermini.isSelected()));
+ Cache.setPropertyNoSave(HMMINFO_GLOBAL_BACKGROUND,
+ Boolean.toString(hmmerBackgroundUniprot.isSelected()));
+ Cache.setPropertyNoSave(HMMSEARCH_SEQCOUNT,
+ hmmerSequenceCount.getText());
+ Cache.setOrRemove(HMMER_PATH, hmmerPath.getText());
+ if (cygwinPath != null)
+ {
+ Cache.setOrRemove(CYGWIN_PATH, cygwinPath.getText());
+ }
+ AlignFrame[] frames = Desktop.getAlignFrames();
+ if (frames != null && frames.length > 0)
+ {
+ for (AlignFrame f : frames)
+ {
+ f.updateHMMERStatus();
+ }
+ }
+
+ hmmrTrimTermini.setSelected(Cache.getDefault(HMMALIGN_TRIM_TERMINI, false));
+ if (Cache.getDefault(HMMINFO_GLOBAL_BACKGROUND, false))
+ {
+ hmmerBackgroundUniprot.setSelected(true);
+ }
+ else
+ {
+ hmmerBackgroundAlignment.setSelected(true);
+ }
+ hmmerSequenceCount
+ .setText(Cache.getProperty(HMMSEARCH_SEQCOUNT));
+ hmmerPath.setText(Cache.getProperty(HMMER_PATH));
+
+ /*
* Save Overview settings
*/
- Cache.setColourProperty(GAP_COLOUR, gapColour.getBackground());
- Cache.setColourProperty(HIDDEN_COLOUR, hiddenColour.getBackground());
- Cache.applicationProperties.setProperty(USE_LEGACY_GAP,
+ Cache.setColourPropertyNoSave(GAP_COLOUR, gapColour.getBackground());
+ Cache.setColourPropertyNoSave(HIDDEN_COLOUR, hiddenColour.getBackground());
+ Cache.setPropertyNoSave(USE_LEGACY_GAP,
Boolean.toString(useLegacyGap.isSelected()));
- Cache.applicationProperties.setProperty(SHOW_OV_HIDDEN_AT_START,
+ Cache.setPropertyNoSave(SHOW_OV_HIDDEN_AT_START,
Boolean.toString(showHiddenAtStart.isSelected()));
/*
* Save Structure settings
*/
- Cache.applicationProperties.setProperty(ADD_TEMPFACT_ANN,
+ Cache.setPropertyNoSave(ADD_TEMPFACT_ANN,
Boolean.toString(addTempFactor.isSelected()));
- Cache.applicationProperties.setProperty(ADD_SS_ANN,
+ Cache.setPropertyNoSave(ADD_SS_ANN,
Boolean.toString(addSecondaryStructure.isSelected()));
- Cache.applicationProperties.setProperty(STRUCT_FROM_PDB,
+ Cache.setPropertyNoSave(STRUCT_FROM_PDB,
Boolean.toString(structFromPdb.isSelected()));
+ if (!Platform.isJS()) {
String viewer = structViewer.getSelectedItem().toString();
String viewerPath = structureViewerPath.getText();
- Cache.applicationProperties.setProperty(STRUCTURE_DISPLAY, viewer);
+ Cache.setPropertyNoSave(STRUCTURE_DISPLAY, viewer);
if (viewer.equals(ViewerType.CHIMERA.name()))
{
Cache.setOrRemove(CHIMERA_PATH, viewerPath);
{
Cache.setOrRemove(PYMOL_PATH, viewerPath);
}
- Cache.applicationProperties.setProperty("MAP_WITH_SIFTS",
+ } // nojs
+ Cache.setPropertyNoSave("MAP_WITH_SIFTS",
Boolean.toString(siftsMapping.isSelected()));
SiftsSettings.setMapWithSifts(siftsMapping.isSelected());
/*
* Save Output settings
*/
- Cache.applicationProperties.setProperty("EPS_RENDERING",
+ Cache.setPropertyNoSave("EPS_RENDERING",
((OptionsParam) epsRendering.getSelectedItem()).getCode());
- Cache.applicationProperties.setProperty("HTML_RENDERING",
+ Cache.setPropertyNoSave("HTML_RENDERING",
((OptionsParam) htmlRendering.getSelectedItem()).getCode());
- Cache.applicationProperties.setProperty("SVG_RENDERING",
+ Cache.setPropertyNoSave("SVG_RENDERING",
((OptionsParam) svgRendering.getSelectedItem()).getCode());
/*
* Save Connections settings
*/
- // Proxy settings set first (to catch web services)
-
+ // Proxy settings were already set first (to catch web services)
Cache.setOrRemove("DEFAULT_BROWSER", defaultBrowser.getText());
jalview.util.BrowserLauncher.resetBrowser();
String menuLinks = sequenceUrlLinks.writeUrlsAsString(true);
if (menuLinks.isEmpty())
{
- Cache.applicationProperties.remove("SEQUENCE_LINKS");
+ Cache.removePropertyNoSave("SEQUENCE_LINKS");
}
else
{
- Cache.applicationProperties.setProperty("SEQUENCE_LINKS",
+ Cache.setPropertyNoSave("SEQUENCE_LINKS",
menuLinks.toString());
}
String nonMenuLinks = sequenceUrlLinks.writeUrlsAsString(false);
if (nonMenuLinks.isEmpty())
{
- Cache.applicationProperties.remove("STORED_LINKS");
+ Cache.removePropertyNoSave("STORED_LINKS");
}
else
{
- Cache.applicationProperties.setProperty("STORED_LINKS",
+ Cache.setPropertyNoSave("STORED_LINKS",
nonMenuLinks.toString());
}
- Cache.applicationProperties.setProperty("DEFAULT_URL",
+ Cache.setPropertyNoSave("DEFAULT_URL",
sequenceUrlLinks.getPrimaryUrlId());
Cache.setProperty("VERSION_CHECK",
/*
* Save Output settings
*/
- Cache.applicationProperties.setProperty("BLC_JVSUFFIX",
+ Cache.setPropertyNoSave("BLC_JVSUFFIX",
Boolean.toString(blcjv.isSelected()));
- Cache.applicationProperties.setProperty("CLUSTAL_JVSUFFIX",
+ Cache.setPropertyNoSave("CLUSTAL_JVSUFFIX",
Boolean.toString(clustaljv.isSelected()));
- Cache.applicationProperties.setProperty("FASTA_JVSUFFIX",
+ Cache.setPropertyNoSave("FASTA_JVSUFFIX",
Boolean.toString(fastajv.isSelected()));
- Cache.applicationProperties.setProperty("MSF_JVSUFFIX",
+ Cache.setPropertyNoSave("MSF_JVSUFFIX",
Boolean.toString(msfjv.isSelected()));
- Cache.applicationProperties.setProperty("PFAM_JVSUFFIX",
+ Cache.setPropertyNoSave("PFAM_JVSUFFIX",
Boolean.toString(pfamjv.isSelected()));
- Cache.applicationProperties.setProperty("PILEUP_JVSUFFIX",
+ Cache.setPropertyNoSave("PILEUP_JVSUFFIX",
Boolean.toString(pileupjv.isSelected()));
- Cache.applicationProperties.setProperty("PIR_JVSUFFIX",
+ Cache.setPropertyNoSave("PIR_JVSUFFIX",
Boolean.toString(pirjv.isSelected()));
- Cache.applicationProperties.setProperty("PIR_MODELLER",
+ Cache.setPropertyNoSave("PIR_MODELLER",
Boolean.toString(modellerOutput.isSelected()));
- Cache.applicationProperties.setProperty("EXPORT_EMBBED_BIOJSON",
+ Cache.setPropertyNoSave("EXPORT_EMBBED_BIOJSON",
Boolean.toString(embbedBioJSON.isSelected()));
jalview.io.PIRFile.useModellerOutput = modellerOutput.isSelected();
- Cache.applicationProperties.setProperty("FIGURE_AUTOIDWIDTH",
+ Cache.setPropertyNoSave("FIGURE_AUTOIDWIDTH",
Boolean.toString(autoIdWidth.isSelected()));
userIdWidth_actionPerformed();
- Cache.applicationProperties.setProperty("FIGURE_FIXEDIDWIDTH",
+ Cache.setPropertyNoSave("FIGURE_FIXEDIDWIDTH",
userIdWidth.getText());
/*
* Save Editing settings
*/
- Cache.applicationProperties.setProperty("AUTO_CALC_CONSENSUS",
+ Cache.setPropertyNoSave("AUTO_CALC_CONSENSUS",
Boolean.toString(autoCalculateConsCheck.isSelected()));
- Cache.applicationProperties.setProperty("SORT_BY_TREE",
+ Cache.setPropertyNoSave("SORT_BY_TREE",
Boolean.toString(sortByTree.isSelected()));
- Cache.applicationProperties.setProperty("PAD_GAPS",
+ Cache.setPropertyNoSave("PAD_GAPS",
Boolean.toString(padGaps.isSelected()));
if (!Platform.isJS())
/*
* Save Backups settings
*/
- Cache.applicationProperties.setProperty(BackupFiles.ENABLED,
+ Cache.setPropertyNoSave(BackupFiles.ENABLED,
Boolean.toString(enableBackupFiles.isSelected()));
int preset = getComboIntStringKey(backupfilesPresetsCombo);
- Cache.applicationProperties.setProperty(BackupFiles.NS + "_PRESET",
- Integer.toString(preset));
+ Cache.applicationProperties.setProperty(BackupFiles.NS + "_PRESET", Integer.toString(preset));
if (preset == BackupFilesPresetEntry.BACKUPFILESSCHEMECUSTOM)
{
BackupFilesPresetEntry customBFPE = getBackupfilesCurrentEntry();
BackupFilesPresetEntry.backupfilesPresetEntriesValues.put(
BackupFilesPresetEntry.BACKUPFILESSCHEMECUSTOM, customBFPE);
- Cache.applicationProperties.setProperty(
- BackupFilesPresetEntry.CUSTOMCONFIG, customBFPE.toString());
+ Cache.applicationProperties
+ .setProperty(BackupFilesPresetEntry.CUSTOMCONFIG,
+ customBFPE.toString());
}
BackupFilesPresetEntry savedBFPE = BackupFilesPresetEntry.backupfilesPresetEntriesValues
.get(preset);
- Cache.applicationProperties.setProperty(
+ Cache.setPropertyNoSave(
BackupFilesPresetEntry.SAVEDCONFIG, savedBFPE.toString());
Cache.saveProperties();
- Desktop.instance.doConfigureStructurePrefs();
+ Desktop.getInstance().doConfigureStructurePrefs();
try
{
frame.setClosed(true);
{
}
}
-
public void saveProxySettings()
{
String newProxyType = customProxy.isSelected() ? Cache.PROXYTYPE_CUSTOM
: noProxy.isSelected() ? Cache.PROXYTYPE_NONE
: Cache.PROXYTYPE_SYSTEM;
- Cache.applicationProperties.setProperty("USE_PROXY", newProxyType);
+ Cache.setPropertyNoSave("USE_PROXY", newProxyType);
Cache.setOrRemove("PROXY_SERVER", proxyServerHttpTB.getText());
Cache.setOrRemove("PROXY_PORT", proxyPortHttpTB.getText());
Cache.setOrRemove("PROXY_SERVER_HTTPS", proxyServerHttpsTB.getText());
previousProxyType = newProxyType;
}
- /**
- * Do any necessary validation before saving settings. Return focus to the first
- * tab which fails validation.
+ public static void setAppletDefaults()
+ {
+
+ // http://www.jalview.org/old/v2_8/examples/appletParameters.html
+
+ // showConservation true or false Default is true.
+ // showQuality true or false Default is true.
+ // showConsensus true or false Default is true.
+ // showFeatureSettings true or false Shows the feature settings window when
+ // startin
+ // showTreeBootstraps true or false (default is true) show or hide branch
+ // bootstraps
+ // showTreeDistances true or false (default is true) show or hide branch
+ // lengths
+ // showUnlinkedTreeNodes true or false (default is false) indicate if
+ // unassociated nodes should be highlighted in the tree view
+ // showUnconserved true of false (default is false) When true, only gaps and
+ // symbols different to the consensus sequence ions of the alignment
+ // showGroupConsensus true of false (default is false) When true, shows
+ // consensus annotation row for any groups on the alignment. (since 2.7)
+ // showGroupConservation true of false (default is false) When true, shows
+ // amino-acid property conservation annotation row for any groups on the
+ // showConsensusHistogram true of false (default is true) When true, shows
+ // the percentage occurence of the consensus symbol for each column as a
+ // showSequenceLogo true of false (default is false) When true, shows a
+ // sequence logo above the consensus sequence (overlaid above the Consensus
+
+ Cache.setPropertyNoSave(SHOW_CONSERVATION, "true");
+ Cache.setPropertyNoSave(SHOW_QUALITY, "false");
+ Cache.setPropertyNoSave(SHOW_CONSENSUS, "true");
+ Cache.setPropertyNoSave(SHOW_UNCONSERVED, "false");
+ Cache.setPropertyNoSave(SHOW_GROUP_CONSERVATION, "false");
+ Cache.setPropertyNoSave(SHOW_GROUP_CONSENSUS, "false");
+
+ // TODO -- just a start here
+ }
+ /**
+ * Do any necessary validation before saving settings. Return focus to the
+ * first tab which fails validation.
*
* @return
*/
FileFormatI format = chooser.getSelectedFormat();
if (format != null)
{
- Cache.applicationProperties.setProperty("DEFAULT_FILE_FORMAT",
+ Cache.setPropertyNoSave("DEFAULT_FILE_FORMAT",
format.getName());
}
startupFileTextfield
* DOCUMENT ME!
*
* @param e
- * DOCUMENT ME!
+ * DOCUMENT ME!
*/
@Override
public void cancel_actionPerformed(ActionEvent e)
* DOCUMENT ME!
*
* @param e
- * DOCUMENT ME!
+ * DOCUMENT ME!
*/
@Override
public void annotations_actionPerformed(ActionEvent e)
&& (identity.isSelected() || showGroupConsensus.isSelected()));
showConsensLogo.setEnabled(annotations.isSelected()
&& (identity.isSelected() || showGroupConsensus.isSelected()));
+ showInformationHistogram.setEnabled(annotations.isSelected());
+ showHMMLogo.setEnabled(annotations.isSelected());
}
@Override
boolean valid = false;
while (!valid)
{
- if (JvOptionPane.showInternalConfirmDialog(Desktop.desktop, link,
+ if (JvOptionPane.showInternalConfirmDialog(Desktop.getDesktopPane(), link,
MessageManager.getString("label.new_sequence_url_link"),
JvOptionPane.OK_CANCEL_OPTION, -1,
null) == JvOptionPane.OK_OPTION)
boolean valid = false;
while (!valid)
{
- if (JvOptionPane.showInternalConfirmDialog(Desktop.desktop, link,
+ if (JvOptionPane.showInternalConfirmDialog(Desktop.getDesktopPane(), link,
MessageManager.getString("label.edit_sequence_url_link"),
JvOptionPane.OK_CANCEL_OPTION, -1,
null) == JvOptionPane.OK_OPTION)
if (!useLegacyGap.isSelected())
{
JalviewColourChooser.showColourChooser(this,
- MessageManager.getString("label.select_gap_colour"), gap);
+ MessageManager.getString("label.select_gap_colour"),
+ gap);
}
}
public void hiddenColour_actionPerformed(JPanel hidden)
{
JalviewColourChooser.showColourChooser(this,
- MessageManager.getString("label.select_hidden_colour"), hidden);
+ MessageManager.getString("label.select_hidden_colour"),
+ hidden);
}
@Override
} catch (NumberFormatException x)
{
userIdWidth.setText("");
- JvOptionPane.showInternalMessageDialog(Desktop.desktop,
+ JvOptionPane.showInternalMessageDialog(Desktop.getDesktopPane(),
MessageManager
.getString("warn.user_defined_width_requirements"),
MessageManager.getString("label.invalid_id_column_width"),
File f = new File(structureViewerPath.getText());
if (!f.canExecute())
{
- JvOptionPane.showInternalMessageDialog(Desktop.desktop,
+ JvOptionPane.showInternalMessageDialog(Desktop.getDesktopPane(),
MessageManager.getString("label.invalid_viewer_path"),
MessageManager.getString("label.invalid_viewer_path"),
JvOptionPane.ERROR_MESSAGE);
}
return true;
}
+
+ /**
+ * Returns true if the given text field contains a path to a folder that
+ * contains an executable with the given name, else false (after showing a
+ * warning dialog). The executable name will be tried with .exe appended if not
+ * found.
+ *
+ * @param textField
+ * @param executable
+ */
+ protected boolean validateExecutablePath(JTextField textField, String executable)
+ {
+ String folder = textField.getText().trim();
+
+ if (FileUtils.getExecutable(executable, folder) != null)
+ {
+ return true;
+ }
+ if (folder.length() > 0)
+ {
+ JvOptionPane.showInternalMessageDialog(Desktop.getInstance(),
+ MessageManager.formatMessage("label.executable_not_found",
+ executable),
+ MessageManager.getString("label.invalid_folder"),
+ JvOptionPane.ERROR_MESSAGE);
+ }
+ return false;
+ }
+
+ /**
+ * Checks if a file can be executed
+ *
+ * @param path
+ * the path to the file
+ * @return
+ */
+ public boolean canExecute(String path)
+ {
+ File file = new File(path);
+ if (!file.canExecute())
+ {
+ file = new File(path + ".exe");
+ {
+ if (!file.canExecute())
+ {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
/**
* If Chimera or ChimeraX or Pymol is selected, check it can be found on default
break;
}
}
-
if (!found)
{
String[] options = { "OK", "Help" };
- int showHelp = JvOptionPane.showInternalOptionDialog(Desktop.desktop,
+ int showHelp = JvOptionPane.showInternalOptionDialog(Desktop.getDesktopPane(),
JvSwingUtils.wrapTooltip(true,
MessageManager.getString("label.viewer_missing")),
"", JvOptionPane.YES_NO_OPTION, JvOptionPane.WARNING_MESSAGE,
null, options, options[0]);
-
if (showHelp == JvOptionPane.NO_OPTION)
{
this.selectTab(Preferences.TabRef.STRUCTURE_TAB, null);
}
});
}
- }
+ }
+ }
+
+ @Override
+ protected void validateHmmerPath()
+ {
+ validateExecutablePath(hmmerPath, HmmerCommand.HMMBUILD);
+ }
+
+ @Override
+ protected void validateCygwinPath()
+ {
+ validateExecutablePath(cygwinPath, "run");
}
public class OptionsParam
});
}
+
+ @Override
+ public void removeProgressBar(final long id)
+ {
+ SwingUtilities.invokeLater(() -> {
+ JPanel progressPanel = progressBars.get(id);
+ if (progressPanel != null)
+ {
+ progressBars.remove(id);
+ if (progressBarHandlers.containsKey(id))
+ {
+ progressBarHandlers.remove(id);
+ }
+ removeRow(progressPanel);
+ }
+ });
+ }
/**
* Lays out progress bar container hierarchy
}
try
{
- int reply = JvOptionPane.showConfirmDialog(Desktop.desktop, // component,
+ int reply = JvOptionPane.showConfirmDialog(Desktop.getDesktopPane(), // component,
dialogText, dialogTitle,
(allowCancel) ? JvOptionPane.YES_NO_CANCEL_OPTION
: JvOptionPane.YES_NO_OPTION,
frame.setContentPane(this);
Desktop.addInternalFrame(frame,
MessageManager
- .getString("label.redundancy_threshold_selection"),
- true, FRAME_WIDTH, FRAME_HEIGHT, false, true);
+ .getString("label.redundancy_threshold_selection"), Desktop.FRAME_MAKE_VISIBLE,
+ FRAME_WIDTH, FRAME_HEIGHT, Desktop.FRAME_NOT_RESIZABLE, Desktop.FRAME_ALLOW_ANY_SIZE);
frame.addInternalFrameListener(new InternalFrameAdapter()
{
@Override
ap.alignFrame.addHistoryItem(cut);
PaintRefresher.Refresh(this, ap.av.getSequenceSetId(), true, true);
- ap.av.firePropertyChange("alignment", null,
- ap.av.getAlignment().getSequences());
+ ap.av.notifyAlignment();
}
}
{
command.undoCommand(af.getViewAlignments());
ap.av.getHistoryList().remove(command);
- ap.av.firePropertyChange("alignment", null,
- ap.av.getAlignment().getSequences());
+ ap.av.notifyAlignment();
af.updateEditMenuBar();
}
*/
package jalview.gui;
-import jalview.jbgui.GRestInputParamEditDialog;
-import jalview.ws.params.InvalidArgumentException;
-import jalview.ws.params.OptionI;
-import jalview.ws.params.ParameterI;
-import jalview.ws.rest.InputType;
-import jalview.ws.rest.RestServiceDescription;
-
import java.util.ArrayList;
import java.util.Hashtable;
-import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.event.ListSelectionEvent;
+import jalview.jbgui.GRestInputParamEditDialog;
+import jalview.ws.params.InvalidArgumentException;
+import jalview.ws.params.OptionI;
+import jalview.ws.params.ParameterI;
+import jalview.ws.rest.InputType;
+import jalview.ws.rest.RestServiceDescription;
import net.miginfocom.swing.MigLayout;
public class RestInputParamEditDialog extends GRestInputParamEditDialog
final Thread runner = Thread.currentThread();
JFrame df = new JFrame();
df.getContentPane().setLayout(new BorderLayout());
- df.getContentPane().add((nulserv = !nulserv)
- ? new RestServiceEditorPane(jalview.ws.rest.RestClient
- .makeShmmrRestClient().getRestDescription())
- : new RestServiceEditorPane(), BorderLayout.CENTER);
+ df.getContentPane().add(
+ (nulserv = !nulserv) ? new RestServiceEditorPane(
+ jalview.ws.rest.clientdefs.ShmrRestClient
+ .makeShmmrRestClient()
+ .getRestDescription())
+ : new RestServiceEditorPane(),
+ BorderLayout.CENTER);
df.setBounds(100, 100, 600, 400);
df.addComponentListener(new ComponentListener()
{
{
av.showColumn(hiddenRange[0]);
reveal = null;
- ap.updateLayout();
- ap.paintAlignment(true, true);
- av.sendSelection();
+ updatePanel();
}
});
pop.add(item);
{
av.showAllHiddenColumns();
reveal = null;
- ap.updateLayout();
- ap.paintAlignment(true, true);
- av.sendSelection();
+ updatePanel();
}
});
pop.add(item);
{
av.setSelectionGroup(null);
}
-
- ap.updateLayout();
- ap.paintAlignment(true, true);
- av.sendSelection();
+ updatePanel();
}
});
pop.add(item);
return pop;
}
+ protected void updatePanel()
+ {
+ ap.updateLayout();
+ ap.paintAlignment(true, true);
+ ap.updateScrollBarsFromRanges();
+ av.sendSelection();
+ }
+
/**
* Handles left mouse button press
*
public class SeqCanvas extends JPanel implements ViewportListenerI
{
/**
- * vertical gap in pixels between sequences and annotations when in wrapped mode
+ * vertical gap in pixels between sequences and annotations when in wrapped
+ * mode
*/
static final int SEQS_ANNOTATION_GAP = 3;
private final SequenceRenderer seqRdr;
- boolean fastPaint = false;
+ private boolean fastPaint = false;
private boolean fastpainting = false;
private int wrappedVisibleWidths; // number of wrapped widths displayed
+ private int availWidth;
+
+ private int availHeight;
+
+ private boolean allowFastPaint;
// Don't do this! Graphics handles are supposed to be transient
- //private Graphics2D gg;
+ // private Graphics2D gg;
/**
* Creates a new SeqCanvas object.
public SequenceRenderer getSequenceRenderer()
{
- return seqRdr;
+ return seqRdr;
}
public FeatureRenderer getFeatureRenderer()
int yPos = ypos + charHeight;
int startX = startx;
int endX = endx;
-
if (av.hasHiddenColumns())
{
HiddenColumns hiddenColumns = av.getAlignment().getHiddenColumns();
}
}
-
/*
* white fill the space for the scale
*/
img.getWidth(), img.getHeight(), -horizontal * charWidth,
-vertical * charHeight);
- /** @j2sNative xxi = this.img */
gg.translate(transX, transY);
drawPanel(gg, startRes, endRes, startSeq, endSeq, 0);
// Call repaint on alignment panel so that repaints from other alignment
// panel components can be aggregated. Otherwise performance of the
// overview window and others may be adversely affected.
- // System.out.println("SeqCanvas fastPaint() repaint() request...");
av.getAlignPanel().repaint();
} finally
{
@Override
public void paintComponent(Graphics g)
{
+ if (av.getAlignPanel().getHoldRepaint())
+ {
+ return;
+ }
- int charHeight = av.getCharHeight();
- int charWidth = av.getCharWidth();
-
- int width = getWidth();
- int height = getHeight();
-
- width -= (width % charWidth);
- height -= (height % charHeight);
-
- // BH 2019 can't possibly fastPaint if either width or height is 0
+ getAvailSizes();
- if (width == 0 || height == 0)
+ if (availWidth == 0 || availHeight == 0)
{
return;
}
// }
Rectangle vis, clip;
- if (img != null
- && (fastPaint
- || (vis = getVisibleRect()).width != (clip = g
- .getClipBounds()).width
- || vis.height != clip.height))
+ if (allowFastPaint && img != null
+ && (fastPaint || (vis = getVisibleRect()).width != (clip = g.getClipBounds()).width
+ || vis.height != clip.height))
{
g.drawImage(img, 0, 0, this);
drawSelectionGroup((Graphics2D) g, startRes, endRes, startSeq,
}
else
{
+ allowFastPaint = true;
// img is a cached version of the last view we drew.
// If we have no img or the size has changed, make a new one.
//
- if (img == null || width != img.getWidth()
- || height != img.getHeight())
+ if (img == null || availWidth != img.getWidth()
+ || availHeight != img.getHeight())
{
- img = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
+ img = new BufferedImage(availWidth, availHeight,
+ BufferedImage.TYPE_INT_RGB);
}
Graphics2D gg = (Graphics2D) img.getGraphics();
}
gg.setColor(Color.white);
- gg.fillRect(0, 0, img.getWidth(), img.getHeight());
+ gg.fillRect(0, 0, availWidth, availHeight);
if (av.getWrapAlignment())
{
- drawWrappedPanel(gg, getWidth(), getHeight(), ranges.getStartRes());
+ drawWrappedPanel(gg, width, height, ranges.getStartRes());
}
else
{
drawCursor(g, startRes, endRes, startSeq, endSeq);
}
}
-
/**
* Draw an alignment panel for printing
*
{
drawPanel(g1, startRes, endRes, startSeq, endSeq, 0);
- drawSelectionGroup((Graphics2D) g1, startRes, endRes,
- startSeq, endSeq);
+ drawSelectionGroup((Graphics2D) g1, startRes, endRes, startSeq, endSeq);
}
/**
if (group != null)
{
drawWrappedSelection((Graphics2D) g, group, canvasWidth, canvasHeight,
- startRes);
+ startRes);
}
}
maxWidth = Math.max(maxWidth, alignment.getSequenceAt(i).getEnd());
}
+ // quick int log10
int length = 0;
for (int i = maxWidth; i > 0; i /= 10)
{
* window
*
* @param g
- * @param canvasWidth
+ * @param availWidth
* available width in pixels
- * @param canvasHeight
+ * @param availHeight
* available height in pixels
* @param startColumn
* the first column (0...) of the alignment to draw
*/
- public void drawWrappedPanel(Graphics g, int canvasWidth,
- int canvasHeight, final int startColumn)
+ public void drawWrappedPanel(Graphics g, int availWidth, int availHeight,
+ final int startColumn)
{
- int wrappedWidthInResidues = calculateWrappedGeometry(canvasWidth,
- canvasHeight);
+ int wrappedWidthInResidues = calculateWrappedGeometry();
av.setWrappedWidth(wrappedWidthInResidues);
// we need to call this again to make sure the startColumn +
// wrappedWidthInResidues values are used to calculate wrappedVisibleWidths
// correctly.
- calculateWrappedGeometry(canvasWidth, canvasHeight);
+ calculateWrappedGeometry();
/*
* draw one width at a time (excluding any scales shown),
int currentWidth = 0;
while ((currentWidth < wrappedVisibleWidths) && (start < maxWidth))
{
- int endColumn = Math
- .min(maxWidth, start + wrappedWidthInResidues - 1);
- drawWrappedWidth(g, ypos, start, endColumn, canvasHeight);
+ int endColumn = Math.min(maxWidth,
+ start + wrappedWidthInResidues - 1);
+ drawWrappedWidth(g, ypos, start, endColumn, availHeight);
ypos += wrappedRepeatHeightPx;
start += wrappedWidthInResidues;
currentWidth++;
drawWrappedDecorators(g, startColumn);
}
+ private void getAvailSizes()
+ {
+ int charHeight = av.getCharHeight();
+ int charWidth = av.getCharWidth();
+ availWidth = getWidth();
+ availHeight = getHeight();
+ availWidth -= (availWidth % charWidth);
+ availHeight -= (availHeight % charHeight);
+ }
/**
* Calculates and saves values needed when rendering a wrapped alignment.
* These depend on many factors, including
* <li>whether scales are shown left, right or above the alignment</li>
* </ul>
*
+ * @param availWidth
+ * @param availHeight
+ * @return the number of residue columns in each width
+ */
+ protected int calculateWrappedGeometry()
+ {
+ getAvailSizes();
+ return calculateWrappedGeometry(availWidth, availHeight);
+
+ }
+
+ /**
+ * for test only
* @param canvasWidth
* @param canvasHeight
- * @return the number of residue columns in each width
+ * @return
*/
- protected int calculateWrappedGeometry(int canvasWidth, int canvasHeight)
+ public int calculateWrappedGeometry(int canvasWidth, int canvasHeight)
{
int charHeight = av.getCharHeight();
* compute height in pixels of the wrapped widths
* - start with space above plus sequences
*/
- wrappedRepeatHeightPx = wrappedSpaceAboveAlignment;
- wrappedRepeatHeightPx += av.getAlignment().getHeight()
- * charHeight;
+ wrappedRepeatHeightPx = wrappedSpaceAboveAlignment
+ + av.getAlignment().getHeight() * charHeight;
/*
* add annotations panel height if shown
int charWidth = av.getCharWidth();
int xOffset = labelWidthWest
+ ((startColumn - ranges.getStartRes()) % viewportWidth)
- * charWidth;
+ * charWidth;
g.translate(xOffset, 0);
if (av.getScaleRightWrapped())
{
int x = labelWidthWest + viewportWidth * charWidth;
-
g.translate(x, 0);
drawVerticalScale(g, startCol, endColumn, ypos, false);
g.translate(-x, 0);
*/
g.translate(labelWidthWest, 0);
g.setColor(Color.white);
- g.fillRect(0, ypos - wrappedSpaceAboveAlignment, viewportWidth
- * charWidth + labelWidthWest, wrappedSpaceAboveAlignment);
+ g.fillRect(0, ypos - wrappedSpaceAboveAlignment,
+ viewportWidth * charWidth + labelWidthWest,
+ wrappedSpaceAboveAlignment);
g.setColor(Color.black);
g.translate(-labelWidthWest, 0);
}
}
+ private final static BasicStroke dottedStroke = new BasicStroke(1,
+ BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND, 3f, new float[]
+ { 5f, 3f }, 0f);
+
+ private final static BasicStroke basicStroke = new BasicStroke();
/*
* Draw a selection group over a wrapped alignment
*/
private void drawWrappedSelection(Graphics2D g, SequenceGroup group,
- int canvasWidth,
- int canvasHeight, int startRes)
+ int canvasWidth, int canvasHeight, int startRes)
{
// chop the wrapped alignment extent up into panel-sized blocks and treat
// each block as if it were a block from an unwrapped alignment
- g.setStroke(new BasicStroke(1, BasicStroke.CAP_BUTT,
- BasicStroke.JOIN_ROUND, 3f, new float[]
- { 5f, 3f }, 0f));
+ g.setStroke(dottedStroke);
g.setColor(Color.RED);
int charWidth = av.getCharWidth();
/ charWidth;
int startx = startRes;
int maxwidth = av.getAlignment().getVisibleWidth();
+ // JAL-3253-applet had this:
+ // // height gap above each panel
+ // int charHeight = av.getCharHeight();
+ // int hgap = charHeight;
+ // if (av.getScaleAboveWrapped())
+ // {
+ // hgap += charHeight;
+ // }
+ // int dy = getAnnotationHeight() + hgap
+ // + av.getAlignment().getHeight() * charHeight;
+ // int ypos = hgap; // vertical offset
+
+ // this is from 0b573ed (gmungoc)
+ int dy = wrappedRepeatHeightPx;
int ypos = wrappedSpaceAboveAlignment;
while ((ypos <= canvasHeight) && (startx < maxwidth))
g.translate(labelWidthWest, 0);
drawUnwrappedSelection(g, group, startx, endx, 0,
- av.getAlignment().getHeight() - 1,
- ypos);
+ av.getAlignment().getHeight() - 1, ypos);
g.translate(-labelWidthWest, 0);
- ypos += wrappedRepeatHeightPx;
+ // update vertical offset
+ ypos += dy;
+ // update horizontal offset
startx += cWidth;
}
- g.setStroke(new BasicStroke());
+ g.setStroke(basicStroke);
}
/**
- * Answers zero if annotations are not shown, otherwise recalculates and answers
- * the total height of all annotation rows in pixels
+ * Answers zero if annotations are not shown, otherwise recalculates and
+ * answers the total height of all annotation rows in pixels
*
* @return
*/
* the cursor drawn on it, if any
*/
private void drawCursor(Graphics g, int startRes, int endRes,
- int startSeq,
- int endSeq)
+ int startSeq, int endSeq)
{
// convert the cursorY into a position on the visible alignment
int cursor_ypos = cursorY;
int startRes, int endRes, int startSeq, int endSeq, int offset)
{
int charWidth = av.getCharWidth();
-
if (!av.hasHiddenColumns())
{
drawPartialGroupOutline(g, group, startRes, endRes, startSeq, endSeq,
blockStart = region[0];
g.translate(screenY * charWidth, 0);
- drawPartialGroupOutline(g, group,
- blockStart, blockEnd, startSeq, endSeq, offset);
+ drawPartialGroupOutline(g, group, blockStart, blockEnd, startSeq,
+ endSeq, offset);
g.translate(-screenY * charWidth, 0);
screenY += blockEnd - blockStart + 1;
g.drawLine(sx + xwidth, oldY, sx + xwidth, sy);
}
}
-
/**
* Highlights search results in the visible region by rendering as white text
* on a black background. Any previous highlighting is removed. Answers true
return highlightSearchResults(results, false);
}
-
/**
* Highlights search results in the visible region by rendering as white text
* on a black background. Any previous highlighting is removed. Answers true
{
firstCol = alignment.getHiddenColumns()
.absoluteToVisibleColumn(firstCol);
- lastCol = alignment.getHiddenColumns().absoluteToVisibleColumn(lastCol);
+ lastCol = alignment.getHiddenColumns()
+ .absoluteToVisibleColumn(lastCol);
}
int transX = (firstCol - ranges.getStartRes()) * av.getCharWidth();
int transY = (firstSeq - ranges.getStartSeq()) * av.getCharHeight();
public void propertyChange(PropertyChangeEvent evt)
{
String eventName = evt.getPropertyName();
- // System.err.println(">>SeqCanvas propertyChange " + eventName);
- if (eventName.equals(SequenceGroup.SEQ_GROUP_CHANGED))
+ // BH 2019.07.27 removes dead code introduced in aad3650 and simplifies
+ // logic, emphasizing no check for ENDRES or ENDSEQ
+
+ // Both scrolling and resizing change viewport ranges: scrolling changes
+ // both start and end points, but resize only changes end values.
+ // Here we only want to fastpaint on a scroll, with resize using a normal
+ // paint, so scroll events are identified as changes to the horizontal or
+ // vertical start value.
+
+ // Make sure we're not trying to draw a panel
+ // larger than the visible window
+ int scrollX = 0;
+ int scrollY = 0;
+ switch (eventName)
{
+ case SequenceGroup.SEQ_GROUP_CHANGED:
fastPaint = true;
repaint();
return;
- }
- else if (eventName.equals(ViewportRanges.MOVE_VIEWPORT))
- {
+ case ViewportRanges.MOVE_VIEWPORT:
fastPaint = false;
- // System.err.println("!!!! fastPaint false from MOVE_VIEWPORT");
repaint();
return;
- }
-
- int scrollX = 0;
- if (eventName.equals(ViewportRanges.STARTRES)
- || eventName.equals(ViewportRanges.STARTRESANDSEQ))
- {
- // Make sure we're not trying to draw a panel
- // larger than the visible window
- if (eventName.equals(ViewportRanges.STARTRES))
- {
- scrollX = (int) evt.getNewValue() - (int) evt.getOldValue();
- }
- else
+ case ViewportRanges.STARTSEQ:
+ // meaning STARTOREND
+ // typically scroll, but possibly just the end changed
+ fastPaint(0, (int) evt.getNewValue() - (int) evt.getOldValue());
+ return;
+ case ViewportRanges.STARTRES:
+ // meaning STARTOREND
+ scrollX = (int) evt.getNewValue() - (int) evt.getOldValue();
+ break;
+ case ViewportRanges.STARTRESANDSEQ:
+ scrollX = ((int[]) evt.getNewValue())[0]
+ - ((int[]) evt.getOldValue())[0];
+ scrollY = ((int[]) evt.getNewValue())[1]
+ - ((int[]) evt.getOldValue())[1];
+ if (scrollX != 0 && scrollY != 0)
{
- scrollX = ((int[]) evt.getNewValue())[0]
- - ((int[]) evt.getOldValue())[0];
- }
- ViewportRanges vpRanges = av.getRanges();
+ // all sorts of problems in JavaScript if this is commented out.
+ repaint();
+ return;
- int range = vpRanges.getEndRes() - vpRanges.getStartRes() + 1;
- if (scrollX > range)
- {
- scrollX = range;
- }
- else if (scrollX < -range)
- {
- scrollX = -range;
}
+ break;
+ default:
+ return;
}
+
+ ViewportRanges vpRanges = av.getRanges();
+ int range = vpRanges.getEndRes() - vpRanges.getStartRes() + 1;
+ scrollX = Math.max(Math.min(scrollX, range), -range);
+ // only STARTRES or STARTRESANDSEQ:
+ if (av.getWrapAlignment())
+ {
+ fastPaintWrapped(scrollX);
+ }
+ else
+ {
+ fastPaint(scrollX, scrollY);
+ }
+
+ // BH 2019.07.27 was:
+ // if (eventName.equals(SequenceGroup.SEQ_GROUP_CHANGED))
+ // {
+ // fastPaint = true;
+ // repaint();
+ // return;
+ // }
+ // else if (eventName.equals(ViewportRanges.MOVE_VIEWPORT))
+ // {
+ // fastPaint = false;
+ // // System.err.println("!!!! fastPaint false from MOVE_VIEWPORT");
+ // repaint();
+ // return;
+ // }
+ //
+ // if (eventName.equals(ViewportRanges.STARTRES)
+ // || eventName.equals(ViewportRanges.STARTRESANDSEQ))
+ // {
+ // // Make sure we're not trying to draw a panel
+ // // larger than the visible window
+ // if (eventName.equals(ViewportRanges.STARTRES))
+ // {
+ // scrollX = (int) evt.getNewValue() - (int) evt.getOldValue();
+ // }
+ // else
+ // {
+ // scrollX = ((int[]) evt.getNewValue())[0]
+ // - ((int[]) evt.getOldValue())[0];
+ // }
+ // ViewportRanges vpRanges = av.getRanges();
+ //
+ // int range = vpRanges.getEndRes() - vpRanges.getStartRes() + 1;
+ // if (scrollX > range)
+ // {
+ // scrollX = range;
+ // }
+ // else if (scrollX < -range)
+ // {
+ // scrollX = -range;
+ // }
+ // }
// Both scrolling and resizing change viewport ranges: scrolling changes
// both start and end points, but resize only changes end values.
// Here we only want to fastpaint on a scroll, with resize using a normal
// paint, so scroll events are identified as changes to the horizontal or
// vertical start value.
- if (eventName.equals(ViewportRanges.STARTRES))
- {
- if (av.getWrapAlignment())
- {
- fastPaintWrapped(scrollX);
- }
- else
- {
- fastPaint(scrollX, 0);
- }
- }
- else if (eventName.equals(ViewportRanges.STARTSEQ))
- {
- // scroll
- fastPaint(0, (int) evt.getNewValue() - (int) evt.getOldValue());
- }
- else if (eventName.equals(ViewportRanges.STARTRESANDSEQ))
- {
- if (av.getWrapAlignment())
- {
- fastPaintWrapped(scrollX);
- }
- else
- {
- fastPaint(scrollX, 0);
- }
- }
- else if (eventName.equals(ViewportRanges.STARTSEQ))
- {
- // scroll
- fastPaint(0, (int) evt.getNewValue() - (int) evt.getOldValue());
- }
- else if (eventName.equals(ViewportRanges.STARTRESANDSEQ))
- {
- if (av.getWrapAlignment())
- {
- fastPaintWrapped(scrollX);
- }
- }
+ // BH 2019.07.27 was:
+ // if (eventName.equals(ViewportRanges.STARTRES))
+ // {
+ // if (av.getWrapAlignment())
+ // {
+ // fastPaintWrapped(scrollX);
+ // }
+ // else
+ // {
+ // fastPaint(scrollX, 0);
+ // }
+ // }
+ // else if (eventName.equals(ViewportRanges.STARTSEQ))
+ // {
+ // // scroll
+ // fastPaint(0, (int) evt.getNewValue() - (int) evt.getOldValue());
+ // }
+ // else if (eventName.equals(ViewportRanges.STARTRESANDSEQ))
+ // {
+ // if (av.getWrapAlignment())
+ // {
+ // fastPaintWrapped(scrollX);
+ // }
+ // else
+ // {
+ // fastPaint(scrollX, 0);
+ // }
+ // }
+ //
+ // BH oops!
+ //
+ // else if (eventName.equals(ViewportRanges.STARTSEQ))
+ // {
+ // // scroll
+ // fastPaint(0, (int) evt.getNewValue() - (int) evt.getOldValue());
+ // }
+ // else if (eventName.equals(ViewportRanges.STARTRESANDSEQ))
+ // {
+ // if (av.getWrapAlignment())
+ // {
+ // fastPaintWrapped(scrollX);
+ // }
+ // }
}
/**
try
{
-
Graphics gg = img.getGraphics();
-
- calculateWrappedGeometry(getWidth(), getHeight());
+ calculateWrappedGeometry();
/*
* relocate the regions of the alignment that are still visible
if (scrollX < 0)
{
int startRes = ranges.getStartRes();
- drawWrappedWidth(gg, wrappedSpaceAboveAlignment, startRes, startRes
- - scrollX - 1, getHeight());
+ drawWrappedWidth(gg, wrappedSpaceAboveAlignment, startRes,
+ startRes - scrollX - 1, getHeight());
}
else
{
drawWrappedDecorators(gg, ranges.getStartRes());
gg.dispose();
-
repaint();
} finally
{
}
Graphics gg = img.getGraphics();
-
ViewportRanges ranges = av.getRanges();
int viewportWidth = ranges.getViewportWidth();
int charWidth = av.getCharWidth();
*/
int visibleWidths = wrappedVisibleWidths;
int canvasHeight = getHeight();
- boolean lastWidthPartHeight = (wrappedVisibleWidths * wrappedRepeatHeightPx) > canvasHeight;
+ boolean lastWidthPartHeight = (wrappedVisibleWidths
+ * wrappedRepeatHeightPx) > canvasHeight;
if (lastWidthPartHeight)
{
/*
* white fill first to erase annotations
*/
-
-
gg.translate(xOffset, 0);
gg.setColor(Color.white);
- gg.fillRect(labelWidthWest, ypos,
- (endRes - startRes + 1) * charWidth, wrappedRepeatHeightPx);
+ gg.fillRect(labelWidthWest, ypos, (endRes - startRes + 1) * charWidth,
+ wrappedRepeatHeightPx);
gg.translate(-xOffset, 0);
drawWrappedWidth(gg, ypos, startRes, endRes, canvasHeight);
-
}
/*
gg.fillRect(0, canvasHeight - heightBelow, getWidth(), heightBelow);
}
gg.dispose();
- }
+ }
/**
* Shifts the visible alignment by the specified number of columns - left if
if (y + wrappedRepeatHeightPx < canvasHeight - wrappedRepeatHeightPx
&& (xpos + viewportWidth <= xMax))
{
- gg.copyArea(labelWidthWest, y + wrappedRepeatHeightPx, -positions
- * charWidth, heightToCopy, widthToCopy,
+ gg.copyArea(labelWidthWest, y + wrappedRepeatHeightPx,
+ -positions * charWidth, heightToCopy, widthToCopy,
-wrappedRepeatHeightPx);
}
y += wrappedRepeatHeightPx;
gg.dispose();
}
-
/**
* Redraws any positions in the search results in the visible region of a
* wrapped alignment. Any highlights are drawn depending on the search results
boolean matchFound = false;
- calculateWrappedGeometry(getWidth(), getHeight());
+ calculateWrappedGeometry();
int wrappedWidth = av.getWrappedWidth();
int wrappedHeight = wrappedRepeatHeightPx;
}
int firstVisibleColumn = ranges.getStartRes();
- int lastVisibleColumn = ranges.getStartRes() + repeats
- * ranges.getViewportWidth() - 1;
+ int lastVisibleColumn = ranges.getStartRes()
+ + repeats * ranges.getViewportWidth() - 1;
AlignmentI alignment = av.getAlignment();
if (av.hasHiddenColumns())
int gapHeight = charHeight * (av.getScaleAboveWrapped() ? 2 : 1);
-
Graphics gg = img.getGraphics();
for (int seqNo = ranges.getStartSeq(); seqNo <= ranges
* transX: offset from left edge of canvas to residue position
*/
int transX = labelWidthWest
- + ((displayColumn - ranges.getStartRes()) % wrappedWidth)
- * av.getCharWidth();
+ + ((displayColumn - ranges.getStartRes())
+ % wrappedWidth) * av.getCharWidth();
/*
* transY: offset from top edge of canvas to residue position
}
}
}
-
gg.dispose();
return matchFound;
return labelWidthWest;
}
+ /**
+ * Clears the flag that allows a 'fast paint' on the next repaint, so
+ * requiring a full repaint
+ */
+ public void setNoFastPaint()
+ {
+ allowFastPaint = false;
+ }
+
}
SequenceListener, SelectionListener
{
/*
+ *
* a class that holds computed mouse position
* - column of the alignment (0...)
* - sequence offset (0...)
*/
public SeqPanel(AlignViewport viewport, AlignmentPanel alignPanel)
{
+ setName("SeqPanel");
seqARep = new SequenceAnnotationReport(true);
ToolTipManager.sharedInstance().registerComponent(this);
ToolTipManager.sharedInstance().setInitialDelay(0);
int alignmentHeight = av.getAlignment().getHeight();
if (av.getWrapAlignment())
{
- seqCanvas.calculateWrappedGeometry(seqCanvas.getWidth(),
- seqCanvas.getHeight());
+ seqCanvas.calculateWrappedGeometry();
/*
* yPos modulo height of repeating width
if (editCommand != null && editCommand.getSize() > 0)
{
ap.alignFrame.addHistoryItem(editCommand);
- av.firePropertyChange("alignment", null,
- av.getAlignment().getSequences());
+ ap.av.notifyAlignment();
}
} finally
{
String tooltip = AnnotationPanel.buildToolTip(anns[rowIndex], column,
anns);
- if (!tooltip.equals(lastTooltip))
+ boolean tooltipChanged = tooltip == null ? lastTooltip != null : !tooltip.equals(lastTooltip);
+ if (tooltipChanged)
{
lastTooltip = tooltip;
lastFormattedTooltip = tooltip == null ? null
{
return lastSearchResults;
}
+
+ /**
+ * scroll to the given row/column - or nearest visible location
+ *
+ * @param row
+ * @param column
+ */
+ public void scrollTo(int row, int column)
+ {
+
+ row = row < 0 ? ap.av.getRanges().getStartSeq() : row;
+ column = column < 0 ? ap.av.getRanges().getStartRes() : column;
+ ap.scrollTo(column, column, row, true, true);
+ }
+
+ /**
+ * scroll to the given row - or nearest visible location
+ *
+ * @param row
+ */
+ public void scrollToRow(int row)
+ {
+
+ row = row < 0 ? ap.av.getRanges().getStartSeq() : row;
+ ap.scrollTo(ap.av.getRanges().getStartRes(),
+ ap.av.getRanges().getStartRes(), row, true, true);
+ }
+
+ /**
+ * scroll to the given column - or nearest visible location
+ *
+ * @param column
+ */
+ public void scrollToColumn(int column)
+ {
+
+ column = column < 0 ? ap.av.getRanges().getStartRes() : column;
+ ap.scrollTo(column, column, ap.av.getRanges().getStartSeq(), true,
+ true);
+ }
+
}
*/
package jalview.gui;
+import jalview.api.FeatureSettingsModelI;
+import jalview.bin.Cache;
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.DBRefEntry;
+import jalview.datamodel.SequenceI;
+import jalview.fts.core.GFTSPanel;
+import jalview.fts.service.pdb.PDBFTSPanel;
+import jalview.fts.service.uniprot.UniprotFTSPanel;
+import jalview.io.FileFormatI;
+import jalview.io.gff.SequenceOntologyI;
+import jalview.util.DBRefUtils;
+import jalview.util.MessageManager;
+import jalview.util.Platform;
+import jalview.ws.seqfetcher.DbSourceProxy;
+
import java.awt.BorderLayout;
import java.awt.Font;
import java.awt.event.ActionEvent;
import javax.swing.JTextArea;
import javax.swing.SwingConstants;
-import jalview.api.FeatureSettingsModelI;
-import jalview.bin.Cache;
-import jalview.datamodel.AlignmentI;
-import jalview.datamodel.DBRefEntry;
-import jalview.datamodel.SequenceI;
-import jalview.fts.core.GFTSPanel;
-import jalview.fts.service.pdb.PDBFTSPanel;
-import jalview.fts.service.threedbeacons.TDBeaconsFTSPanel;
-import jalview.fts.service.uniprot.UniprotFTSPanel;
-import jalview.io.FileFormatI;
-import jalview.io.gff.SequenceOntologyI;
-import jalview.util.DBRefUtils;
-import jalview.util.MessageManager;
-import jalview.util.Platform;
-import jalview.ws.seqfetcher.DbSourceProxy;
-
/**
* A panel where the use may choose a database source, and enter one or more
* accessions, to retrieve entries from the database.
return other.key == this.key;
}
}
-
private static jalview.ws.SequenceFetcher sfetch = null;
JLabel exampleAccession;
frame = new JInternalFrame();
frame.setContentPane(this);
- Desktop.addInternalFrame(frame, getFrameTitle(), true, 400,
- Platform.isAMacAndNotJS() ? 240 : 180);
+ Desktop.addInternalFrame(frame, getFrameTitle(), Desktop.FRAME_MAKE_VISIBLE, 400,
+ Platform.isAMacAndNotJS() ? 240 : 180, Desktop.FRAME_ALLOW_RESIZE, Desktop.FRAME_SET_MIN_SIZE_300);
}
private String getFrameTitle()
}
}
}
-
/**
* Answers a semi-colon-delimited string with the example query or queries for
* the selected database
text = text.replace(",", ";");
}
text = text.replaceAll("(\\s|[; ])+", ";");
- if (!t0.equals(text))
+ if (!t0.equals(text))
{
- textArea.setText(text);
+ textArea.setText(text);
}
if (text.isEmpty())
{
for (String q : queries)
{
- // BH 2019.01.25 dbr is never used.
- // DBRefEntry dbr = new DBRefEntry();
- // dbr.setSource(proxy.getDbSource());
- // dbr.setVersion(null);
+ // BH 2019.01.25 dbr is never used.
+// DBRefEntry dbr = new DBRefEntry();
+// dbr.setSource(proxy.getDbSource());
+// dbr.setVersion(null);
String accId = proxy.getAccessionIdFromQuery(q);
- // dbr.setAccessionId(accId);
+// dbr.setAccessionId(accId);
boolean rfound = false;
for (int r = 0, nr = rs.length; r < nr; r++)
{
}
}
- af.getViewport().applyFeaturesStyle(preferredFeatureColours);
+ if (preferredFeatureColours != null)
+ {
+ af.getViewport().applyFeaturesStyle(preferredFeatureColours);
+ }
if (Cache.getDefault("HIDE_INTRONS", true))
{
af.hideFeatureColumns(SequenceOntologyI.EXON, false);
@Override
public void run()
{
- JvOptionPane.showInternalMessageDialog(Desktop.desktop, error,
+ JvOptionPane.showInternalMessageDialog(Desktop.getDesktopPane(), error,
MessageManager.getString("label.error_retrieving_data"),
JvOptionPane.WARNING_MESSAGE);
}
*/
package jalview.gui;
-import jalview.analysis.Conservation;
-import jalview.datamodel.SequenceGroup;
-import jalview.jbgui.GSliderPanel;
-import jalview.renderer.ResidueShaderI;
-import jalview.util.MessageManager;
-
-import java.awt.event.ActionEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.beans.PropertyVetoException;
import javax.swing.event.InternalFrameAdapter;
import javax.swing.event.InternalFrameEvent;
+import jalview.analysis.Conservation;
+import jalview.datamodel.SequenceGroup;
+import jalview.jbgui.GSliderPanel;
+import jalview.renderer.ResidueShaderI;
+import jalview.util.MessageManager;
+
/**
* DOCUMENT ME!
*
if (!conservationSlider.isVisible())
{
Desktop.addInternalFrame(conservationSlider,
- conservationSlider.getTitle(), true, FRAME_WIDTH,
- FRAME_HEIGHT, false, true);
+ conservationSlider.getTitle(), Desktop.FRAME_MAKE_VISIBLE, FRAME_WIDTH,
+ FRAME_HEIGHT, Desktop.FRAME_NOT_RESIZABLE, Desktop.FRAME_ALLOW_ANY_SIZE);
conservationSlider.addInternalFrameListener(new InternalFrameAdapter()
{
@Override
if (!PIDSlider.isVisible())
{
- Desktop.addInternalFrame(PIDSlider, PIDSlider.getTitle(), true,
- FRAME_WIDTH, FRAME_HEIGHT, false, true);
+ Desktop.addInternalFrame(PIDSlider, PIDSlider.getTitle(), Desktop.FRAME_MAKE_VISIBLE,
+ FRAME_WIDTH, FRAME_HEIGHT, Desktop.FRAME_NOT_RESIZABLE, Desktop.FRAME_ALLOW_ANY_SIZE);
PIDSlider.setLayer(JLayeredPane.PALETTE_LAYER);
PIDSlider.addInternalFrameListener(new InternalFrameAdapter()
{
--- /dev/null
+package jalview.gui;
+
+import jalview.bin.Cache;
+import jalview.util.MessageManager;
+import jalview.ws.WSDiscovererI;
+import jalview.ws.slivkaws.SlivkaWSDiscoverer;
+
+import java.awt.BorderLayout;
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.Dimension;
+import java.awt.Font;
+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 java.net.MalformedURLException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.NoSuchElementException;
+
+import javax.swing.BorderFactory;
+import javax.swing.Box;
+import javax.swing.BoxLayout;
+import javax.swing.JButton;
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+import javax.swing.JProgressBar;
+import javax.swing.JScrollPane;
+import javax.swing.JTable;
+import javax.swing.SwingUtilities;
+import javax.swing.UIManager;
+import javax.swing.table.AbstractTableModel;
+import javax.swing.table.DefaultTableCellRenderer;
+
+@SuppressWarnings("serial")
+public class SlivkaPreferences extends JPanel
+{
+ {
+ setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
+ setPreferredSize(new Dimension(500, 450));
+ }
+
+ WSDiscovererI discoverer;
+
+ private final ArrayList<String> urls = new ArrayList<>();
+
+ private final ArrayList<Integer> statuses = new ArrayList<>();
+
+ private final AbstractTableModel urlTableModel = new AbstractTableModel()
+ {
+ final String[] columnNames = { "Service URL", "Status" };
+
+ @Override
+ public String getColumnName(int col)
+ {
+ return columnNames[col];
+ }
+
+ @Override
+ public Object getValueAt(int rowIndex, int columnIndex)
+ {
+ switch (columnIndex)
+ {
+ case 0:
+ return urls.get(rowIndex);
+ case 1:
+ return statuses.get(rowIndex);
+ default:
+ throw new NoSuchElementException();
+ }
+ }
+
+ @Override
+ public int getRowCount()
+ {
+ return urls.size();
+ }
+
+ @Override
+ public int getColumnCount()
+ {
+ return 2;
+ }
+ };
+
+ private class WSStatusCellRenderer extends DefaultTableCellRenderer
+ {
+ @Override
+ public Component getTableCellRendererComponent(JTable table,
+ Object value, boolean isSelected, boolean hasFocus, int row,
+ int column)
+ {
+ setHorizontalAlignment(CENTER);
+ super.getTableCellRendererComponent(table, "\u25CF", isSelected,
+ hasFocus, row, column);
+ switch ((Integer) value)
+ {
+ case WSDiscovererI.STATUS_NO_SERVICES:
+ setForeground(Color.ORANGE);
+ break;
+ case WSDiscovererI.STATUS_OK:
+ setForeground(Color.GREEN);
+ break;
+ case WSDiscovererI.STATUS_INVALID:
+ setForeground(Color.RED);
+ break;
+ case WSDiscovererI.STATUS_UNKNOWN:
+ default:
+ setForeground(Color.LIGHT_GRAY);
+ }
+ return this;
+ }
+ }
+
+ private JTable urlListTable = new JTable(urlTableModel);
+ {
+ urlListTable.getColumnModel().getColumn(1).setMaxWidth(60);
+ urlListTable.getColumnModel().getColumn(1)
+ .setCellRenderer(new WSStatusCellRenderer());
+ }
+
+ // URL control panel buttons
+ JButton newWsUrl = new JButton(
+ MessageManager.getString("label.new_service_url"));
+
+ JButton editWsUrl = new JButton(
+ MessageManager.getString("label.edit_service_url"));
+
+ JButton deleteWsUrl = new JButton(
+ MessageManager.getString("label.delete_service_url"));
+
+ JButton moveUrlUp = new JButton(
+ MessageManager.getString("action.move_up"));
+
+ JButton moveUrlDown = new JButton(
+ MessageManager.getString("action.move_down"));
+
+ private String showEditUrlDialog(String oldUrl)
+ {
+ String input = (String) JvOptionPane
+ .showInternalInputDialog(
+ this,
+ MessageManager.getString("label.url:"),
+ UIManager.getString("OptionPane.inputDialogTitle", MessageManager.getLocale()),
+ JOptionPane.QUESTION_MESSAGE,
+ null,
+ null,
+ oldUrl);
+ if (input == null)
+ {
+ return null;
+ }
+ try
+ {
+ new URL(input);
+ } catch (MalformedURLException ex)
+ {
+ JvOptionPane.showInternalMessageDialog(this,
+ MessageManager.getString("label.invalid_url"),
+ UIManager.getString("OptionPane.messageDialogTitle",
+ MessageManager.getLocale()),
+ JOptionPane.WARNING_MESSAGE);
+ return null;
+ }
+ return input;
+ }
+
+ // Button Action Listeners
+ private ActionListener newUrlAction = (ActionEvent e) -> {
+ final String input = showEditUrlDialog("");
+ if (input != null)
+ {
+ urls.add(input);
+ statuses.add(discoverer.getServerStatusFor(input));
+ urlTableModel.fireTableRowsInserted(urls.size(), urls.size());
+ discoverer.setServiceUrls(urls);
+ }
+ };
+
+ private ActionListener editUrlAction = (ActionEvent e) -> {
+ final int i = urlListTable.getSelectedRow();
+ if (i >= 0)
+ {
+ final String input = showEditUrlDialog(urls.get(i));
+ if (input != null)
+ {
+ urls.set(i, input);
+ statuses.set(i, discoverer.getServerStatusFor(input));
+ urlTableModel.fireTableRowsUpdated(i, i);
+ discoverer.setServiceUrls(urls);
+ }
+ }
+ };
+
+ private ActionListener deleteUrlAction = (ActionEvent e) -> {
+ final int i = urlListTable.getSelectedRow();
+ if (i >= 0)
+ {
+ urls.remove(i);
+ statuses.remove(i);
+ urlTableModel.fireTableRowsDeleted(i, i);
+ discoverer.setServiceUrls(urls);
+ }
+ };
+
+ private ActionListener moveUrlUpAction = (ActionEvent e) -> {
+ final int i = urlListTable.getSelectedRow();
+ if (i > 0)
+ {
+ moveTableRow(i, i - 1);
+ discoverer.setServiceUrls(urls);
+ }
+ };
+
+ private ActionListener moveUrlDownAction = (ActionEvent e) -> {
+ final int i = urlListTable.getSelectedRow();
+ if (i >= 0 && i < urls.size() - 1)
+ {
+ moveTableRow(i, i + 1);
+ discoverer.setServiceUrls(urls);
+ }
+ };
+
+ private MouseListener tableClickListener = new MouseAdapter()
+ {
+ final ActionEvent actionEvent = new ActionEvent(urlListTable,
+ ActionEvent.ACTION_PERFORMED, "edit");
+
+ @Override
+ public void mouseClicked(MouseEvent e)
+ {
+ if (e.getClickCount() > 1)
+ {
+ editUrlAction.actionPerformed(actionEvent);
+ }
+ }
+ };
+
+ // Setting up URL list Pane
+ {
+ Font font = new Font("Verdana", Font.PLAIN, 10);
+ JPanel urlPaneContainer = new JPanel(new BorderLayout(5, 5));
+ urlPaneContainer.setBorder(BorderFactory.createCompoundBorder(
+ BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(),
+ "Slivka Web Services"),
+ BorderFactory.createEmptyBorder(10, 5, 5, 5)));
+
+ newWsUrl.setFont(font);
+ editWsUrl.setFont(font);
+ deleteWsUrl.setFont(font);
+ moveUrlUp.setFont(font);
+ moveUrlDown.setFont(font);
+ JPanel editContainer = new JPanel();
+ editContainer.add(newWsUrl);
+ editContainer.add(editWsUrl);
+ editContainer.add(deleteWsUrl);
+ urlPaneContainer.add(editContainer, BorderLayout.PAGE_END);
+
+ JPanel moveContainer = new JPanel();
+ moveContainer
+ .setLayout(new BoxLayout(moveContainer, BoxLayout.PAGE_AXIS));
+ moveContainer.add(moveUrlUp);
+ moveContainer.add(Box.createRigidArea(new Dimension(0, 5)));
+ moveContainer.add(moveUrlDown);
+ urlPaneContainer.add(moveContainer, BorderLayout.LINE_START);
+
+ urlPaneContainer.add(new JScrollPane(urlListTable),
+ BorderLayout.CENTER);
+ this.add(urlPaneContainer);
+
+ // Connecting action listeners
+ urlListTable.addMouseListener(tableClickListener);
+ newWsUrl.addActionListener(newUrlAction);
+ editWsUrl.addActionListener(editUrlAction);
+ deleteWsUrl.addActionListener(deleteUrlAction);
+ moveUrlUp.addActionListener(moveUrlUpAction);
+ moveUrlDown.addActionListener(moveUrlDownAction);
+ }
+
+ private void moveTableRow(int fromIndex, int toIndex)
+ {
+ String url = urls.get(fromIndex);
+ int status = statuses.get(fromIndex);
+ urls.set(fromIndex, urls.get(toIndex));
+ statuses.set(fromIndex, statuses.get(toIndex));
+ urls.set(toIndex, url);
+ statuses.set(toIndex, status);
+ if (urlListTable.getSelectedRow() == fromIndex)
+ {
+ urlListTable.setRowSelectionInterval(toIndex, toIndex);
+ }
+ int firstRow = Math.min(toIndex, fromIndex);
+ int lastRow = Math.max(fromIndex, toIndex);
+ urlTableModel.fireTableRowsUpdated(firstRow, lastRow);
+ }
+
+ // Discoverer reloading buttons
+ JButton refreshServices = new JButton(
+ MessageManager.getString("action.refresh_services"));
+
+ JButton resetServices = new JButton(
+ MessageManager.getString("action.reset_services"));
+
+ JProgressBar progressBar = new JProgressBar();
+
+ // Discoverer buttons action listeners
+ private ActionListener refreshServicesAction = (ActionEvent e) -> {
+ progressBar.setVisible(true);
+ Cache.log.info("Requesting service reload");
+ discoverer.startDiscoverer().handle((_discoverer, exception) -> {
+ if (exception == null)
+ {
+ Cache.log.info("Reloading done");
+ }
+ else
+ {
+ Cache.log.error("Reloading failed", exception);
+ }
+ SwingUtilities.invokeLater(() -> progressBar.setVisible(false));
+ return null;
+ });
+ };
+
+ private ActionListener resetServicesAction = (ActionEvent e) -> {
+ discoverer.setServiceUrls(null);
+ urls.clear();
+ statuses.clear();
+ urls.addAll(discoverer.getServiceUrls());
+ for (String url : urls)
+ {
+ statuses.add(discoverer.getServerStatusFor(url));
+ }
+ urlTableModel.fireTableDataChanged();
+ };
+
+ {
+ Font font = new Font("Verdana", Font.PLAIN, 11);
+ refreshServices.setFont(font);
+ resetServices.setFont(font);
+ JPanel container = new JPanel();
+ container.add(refreshServices);
+ container.add(resetServices);
+ this.add(container);
+
+ // Connecting action listeners
+ refreshServices.addActionListener(refreshServicesAction);
+ resetServices.addActionListener(resetServicesAction);
+ }
+
+ {
+ progressBar.setVisible(false);
+ progressBar.setIndeterminate(true);
+ add(progressBar);
+ }
+
+ SlivkaPreferences()
+ {
+ // Initial URLs loading
+ discoverer = SlivkaWSDiscoverer.getInstance();
+ urls.addAll(discoverer.getServiceUrls());
+ for (String url : urls)
+ {
+ statuses.add(discoverer.getServerStatusFor(url));
+ }
+ }
+}
*/
package jalview.gui;
+
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import jalview.util.ChannelProperties;
import jalview.util.Platform;
-
/**
* DOCUMENT ME!
*
* @author $author$
* @version $Revision$
*/
+@SuppressWarnings("serial")
public class SplashScreen extends JPanel
- implements Runnable, HyperlinkListener
+ implements HyperlinkListener, StateMachine
{
+
+ private static final int STATE_INIT = 0;
+
+ private static final int STATE_LOOP = 1;
+
+ private static final int STATE_DONE = 2;
+
private static final int SHOW_FOR_SECS = 5;
- private static final int FONT_SIZE = 11;
+ private static final int FONT_SIZE = (Platform.isJS() ? 14 : 11);
private boolean visible = true;
private static Color fg = Color.BLACK;
- private static Font font = new Font("SansSerif", Font.PLAIN, FONT_SIZE);
-
/*
* as JTextPane in Java, JLabel in javascript
*/
private long oldTextLength = -1;
- public static int logoSize = 32;
-
/*
* allow click in the initial splash screen to dismiss it
* immediately (not if opened from About menu)
{
try
{
- visible = false;
closeSplash();
} catch (Exception ex)
{
/**
* Constructor that displays the splash screen
*
- * @param isTransient
+ * @param isStartup
* if true the panel removes itself on click or after a few seconds;
- * if false it stays up until closed by the user
+ * if false it stays up until closed by the user (from Help..About menu)
*/
- public SplashScreen(boolean isTransient)
+ public SplashScreen(boolean isStartup)
{
- this.transientDialog = isTransient;
+ this.transientDialog = isStartup;
+ // we must get the image in JavaScript BEFORE starting the helper,
+ // as it will take a 1 ms clock tick to obtain width and height information.
+ image = ChannelProperties.getImage("banner");
+ logo = ChannelProperties.getImage("logo.48");
+ font = new Font("SansSerif", Font.PLAIN, FONT_SIZE);
+ helper = new StateHelper(this);
+ helper.next(STATE_INIT);
+ }
- if (Platform.isJS()) // BH 2019
- {
- splashText = new JLabel("");
- run();
- }
- else
- {
- /**
- * Java only
- *
- * @j2sIgnore
- */
- {
- splashText = new JTextPane();
- splashText.setBackground(bg);
- splashText.setForeground(fg);
- splashText.setFont(font);
- Thread t = new Thread(this);
- t.start();
- }
- }
+ protected void initSplashScreenWindow()
+ {
+ addMouseListener(closer);
+ waitForImages();
+ setLayout(new BorderLayout());
+ iframe = new JInternalFrame();
+ iframe.setFrameIcon(null);
+ iframe.setClosable(true);
+ iframe.setContentPane(this);
+ iframe.setLayer(JLayeredPane.PALETTE_LAYER);
+ SplashImage splashimg = new SplashImage(image);
+ imgPanel.add(splashimg, BorderLayout.CENTER);
+ add(imgPanel, BorderLayout.NORTH);
+ Desktop.getDesktopPane().add(iframe);
+ refreshText();
}
/**
- * ping the jalview version page then create and display the jalview
- * splashscreen window.
+ * Both Java and JavaScript have to wait for images, but this method will
+ * accomplish nothing for JavaScript. We have already taken care of image
+ * loading with our state loop in JavaScript.
+ *
*/
- void initSplashScreenWindow()
+ private void waitForImages()
{
- addMouseListener(closer);
-
- try
+ if (Platform.isJS())
+ return;
+ MediaTracker mt = new MediaTracker(this);
+ mt.addImage(image, 0);
+ mt.addImage(logo, 1);
+ do
{
- if (!Platform.isJS())
+ try
+ {
+ mt.waitForAll();
+ } catch (InterruptedException x)
{
- image = ChannelProperties.getImage("banner");
- Image logo = ChannelProperties.getImage("logo.48");
- MediaTracker mt = new MediaTracker(this);
- if (image != null)
- {
- mt.addImage(image, 0);
- }
- if (logo != null)
- {
- mt.addImage(logo, 1);
- }
- do
- {
- try
- {
- mt.waitForAll();
- } catch (InterruptedException x)
- {
- }
- if (mt.isErrorAny())
- {
- System.err.println("Error when loading images!");
- }
- } while (!mt.checkAll());
- Desktop.instance.setIconImages(ChannelProperties.getIconList());
}
- } catch (Exception ex)
+ if (mt.isErrorAny())
+ {
+ System.err.println("Error when loading images!");
+ break;
+ }
+ } while (!mt.checkAll());
+ if (logo != null)
{
+ Desktop.getInstance().setIconImage(logo);
}
-
this.setBackground(bg);
this.setForeground(fg);
this.setFont(font);
+ }
- iframe = new JInternalFrame();
- iframe.setFrameIcon(null);
- iframe.setClosable(true);
- this.setLayout(new BorderLayout());
- iframe.setContentPane(this);
- iframe.setLayer(JLayeredPane.PALETTE_LAYER);
- iframe.setBackground(bg);
- iframe.setForeground(fg);
- iframe.setFont(font);
-
- if (Platform.isJS())
+ /**
+ * update text in author text panel reflecting current version information
+ */
+ protected boolean refreshText()
+ {
+ String newtext = Desktop.getInstance().getAboutMessage();
+ // System.err.println("Text found: \n"+newtext+"\nEnd of newtext.");
+ if (oldTextLength == newtext.length())
{
- // ignore in JavaScript
+ return false;
+ }
+
+ iframe.setVisible(false);
+ oldTextLength = newtext.length();
+ if (Platform.isJS()) // BH 2019
+ {
+ /*
+ * SwingJS doesn't have HTMLEditorKit, required for a JTextPane
+ * to display formatted html, so we use a simple alternative
+ */
+ String text = "<html><br><img src=\""
+ + ChannelProperties.getImageURL("banner") + "\"/>" + newtext
+ + "<br></html>";
+ JLabel ta = new JLabel(text);
+ ta.setOpaque(true);
+ ta.setBackground(Color.white);
+ splashText = ta;
}
else
/**
* Java only
- *
+ *
* @j2sIgnore
*/
{
- ((JTextPane) splashText).setEditable(false);
- splashText.setBackground(bg);
- splashText.setForeground(fg);
- splashText.setFont(font);
-
- SplashImage splashimg = new SplashImage(image);
- iconimg.add(splashimg, BorderLayout.LINE_START);
- iconimg.setBackground(bg);
- add(iconimg, BorderLayout.NORTH);
+ JTextPane jtp = new JTextPane();
+ jtp.setEditable(false);
+ jtp.setBackground(bg);
+ jtp.setForeground(fg);
+ jtp.setFont(font);
+ jtp.setContentType("text/html");
+ jtp.setText("<html>" + newtext + "</html>");
+ jtp.addHyperlinkListener(this);
+ splashText = jtp;
}
- add(splashText, BorderLayout.CENTER);
splashText.addMouseListener(closer);
- Desktop.desktop.add(iframe);
- refreshText();
+
+ splashText.setVisible(true);
+ splashText.setSize(new Dimension(750,
+ 375 + logoSize + (Platform.isJS() ? 40 : 0)));
+ splashText.setBackground(bg);
+ splashText.setForeground(fg);
+ splashText.setFont(font);
+ add(splashText, BorderLayout.CENTER);
+ revalidate();
+ int width = Math.max(splashText.getWidth(), iconimg.getWidth());
+ int height = splashText.getHeight() + iconimg.getHeight();
+ iframe.setBounds((iframe.getParent().getWidth() - width) / 2,
+ (iframe.getParent().getHeight() - height) / 2, 750,
+ width,height);
+ iframe.validate();
+ iframe.setVisible(true);
+ return true;
}
- /**
- * update text in author text panel reflecting current version information
- */
- protected boolean refreshText()
+ protected void closeSplash()
{
- String newtext = Desktop.instance.getAboutMessage();
- // System.err.println("Text found: \n"+newtext+"\nEnd of newtext.");
- if (oldTextLength != newtext.length())
+ try
+ {
+
+ iframe.setClosed(true);
+ } catch (Exception ex)
{
- iframe.setVisible(false);
- oldTextLength = newtext.length();
- if (Platform.isJS()) // BH 2019
- {
- /*
- * SwingJS doesn't have HTMLEditorKit, required for a JTextPane
- * to display formatted html, so we use a simple alternative
- */
- String text = "<html><br><img src=\""
- + ChannelProperties.getImageURL("banner") + "\"/>" + newtext
- + "<br></html>";
- JLabel ta = new JLabel(text);
- ta.setOpaque(true);
- ta.setBackground(Color.white);
- splashText = ta;
- }
- else
- /**
- * Java only
- *
- * @j2sIgnore
- */
- {
- JTextPane jtp = new JTextPane();
- jtp.setEditable(false);
- jtp.setBackground(bg);
- jtp.setForeground(fg);
- jtp.setFont(font);
- jtp.setContentType("text/html");
- jtp.setText("<html>" + newtext + "</html>");
- jtp.addHyperlinkListener(this);
- splashText = jtp;
- }
- splashText.addMouseListener(closer);
-
- splashText.setVisible(true);
- splashText.setSize(new Dimension(750,
- 375 + logoSize + (Platform.isJS() ? 40 : 0)));
- splashText.setBackground(bg);
- splashText.setForeground(fg);
- splashText.setFont(font);
- add(splashText, BorderLayout.CENTER);
- revalidate();
- int width = Math.max(splashText.getWidth(), iconimg.getWidth());
- int height = splashText.getHeight() + iconimg.getHeight();
- iframe.setBounds(
- Math.max(0, (Desktop.instance.getWidth() - width) / 2),
- Math.max(0, (Desktop.instance.getHeight() - height) / 2),
- width, height);
- iframe.validate();
- iframe.setVisible(true);
- return true;
}
- return false;
}
/**
- * Create splash screen, display it and clear it off again.
+ * A simple state machine with just three states: init, loop, and done. Ideal
+ * for a simple while/sleep loop that works in Java and JavaScript
+ * identically.
+ *
*/
@Override
- public void run()
+ public boolean stateLoop()
{
- initSplashScreenWindow();
-
- long startTime = System.currentTimeMillis() / 1000;
-
- while (visible)
+ while (true)
{
- iframe.repaint();
- try
+ switch (helper.getState())
{
- Thread.sleep(500);
- } catch (Exception ex)
- {
- }
-
- if (transientDialog && ((System.currentTimeMillis() / 1000)
- - startTime) > SHOW_FOR_SECS)
- {
- visible = false;
- }
-
- if (visible && refreshText())
- {
- iframe.repaint();
- }
- if (!transientDialog)
- {
- return;
+ case STATE_INIT:
+ initSplashScreenWindow();
+ helper.setState(STATE_LOOP);
+ continue;
+ case STATE_LOOP:
+ if (!isVisible())
+ {
+ helper.setState(STATE_DONE);
+ continue;
+ }
+ if (refreshText())
+ {
+ iframe.repaint();
+ }
+ if (isStartup)
+ helper.delayedState(SHOW_FOR_SECS * 1000, STATE_DONE);
+ return true;
+ default:
+ case STATE_DONE:
+ setVisible(false);
+ closeSplash();
+ Desktop.getInstance().startDialogQueue();
+ return true;
}
}
-
- closeSplash();
- Desktop.instance.startDialogQueue();
- }
-
- /**
- * DOCUMENT ME!
- */
- public void closeSplash()
- {
- try
- {
-
- iframe.setClosed(true);
- } catch (Exception ex)
- {
- }
}
- public class SplashImage extends JPanel
+ private class SplashImage extends JPanel
{
Image image;
*/
package jalview.gui;
+import jalview.api.AlignViewportI;
+import jalview.api.AlignViewControllerGuiI;
+import jalview.api.FeatureSettingsControllerI;
+import jalview.api.SplitContainerI;
+import jalview.controller.FeatureSettingsControllerGuiI;
+import jalview.datamodel.AlignmentI;
+import jalview.jbgui.GAlignFrame;
+import jalview.jbgui.GSplitFrame;
+import jalview.structure.StructureSelectionManager;
+import jalview.util.MessageManager;
+import jalview.util.Platform;
+import jalview.viewmodel.AlignmentViewport;
+
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import javax.swing.event.InternalFrameAdapter;
import javax.swing.event.InternalFrameEvent;
-import jalview.api.AlignViewControllerGuiI;
-import jalview.api.FeatureSettingsControllerI;
-import jalview.api.SplitContainerI;
-import jalview.controller.FeatureSettingsControllerGuiI;
-import jalview.datamodel.AlignmentI;
-import jalview.jbgui.GAlignFrame;
-import jalview.jbgui.GSplitFrame;
-import jalview.structure.StructureSelectionManager;
-import jalview.util.MessageManager;
-import jalview.util.Platform;
-import jalview.viewmodel.AlignmentViewport;
-
/**
* An internal frame on the desktop that hosts a horizontally split view of
* linked DNA and Protein alignments. Additional views can be created in linked
// allow about 65 pixels for Desktop decorators on Windows
int newHeight = Math.min(height,
- Desktop.instance.getHeight() - DESKTOP_DECORATORS_HEIGHT);
+ Desktop.getInstance().getHeight() - DESKTOP_DECORATORS_HEIGHT);
if (newHeight != height)
{
int oldDividerLocation = getDividerLocation();
// TODO if CommandListener is only ever 1:1 for complementary views,
// may change broadcast pattern to direct messaging (more efficient)
final StructureSelectionManager ssm = StructureSelectionManager
- .getStructureSelectionManager(Desktop.instance);
+ .getStructureSelectionManager(Desktop.getInstance());
ssm.addCommandListener(((AlignFrame) getTopFrame()).getViewport());
ssm.addCommandListener(((AlignFrame) getBottomFrame()).getViewport());
}
topFrame.alignPanel.adjustAnnotationHeight();
bottomFrame.alignPanel.adjustAnnotationHeight();
- final AlignViewport topViewport = topFrame.viewport;
- final AlignViewport bottomViewport = bottomFrame.viewport;
+ final AlignViewportI topViewport = topFrame.viewport;
+ final AlignViewportI bottomViewport = bottomFrame.viewport;
final AlignmentI topAlignment = topViewport.getAlignment();
final AlignmentI bottomAlignment = bottomViewport.getAlignment();
boolean topAnnotations = topViewport.isShowAnnotation();
* Ctrl-W / Cmd-W - close view or window
*/
KeyStroke key_cmdW = KeyStroke.getKeyStroke(KeyEvent.VK_W,
- jalview.util.ShortcutKeyMaskExWrapper.getMenuShortcutKeyMaskEx(), false);
+ Platform.SHORTCUT_KEY_MASK, false);
action = new AbstractAction()
{
@Override
* Ctrl-T / Cmd-T open new view
*/
KeyStroke key_cmdT = KeyStroke.getKeyStroke(KeyEvent.VK_T,
- jalview.util.ShortcutKeyMaskExWrapper.getMenuShortcutKeyMaskEx(), false);
+ Platform.SHORTCUT_KEY_MASK, false);
AbstractAction action = new AbstractAction()
{
@Override
adjustLayout();
final StructureSelectionManager ssm = StructureSelectionManager
- .getStructureSelectionManager(Desktop.instance);
+ .getStructureSelectionManager(Desktop.getInstance());
ssm.addCommandListener(newTopPanel.av);
ssm.addCommandListener(newBottomPanel.av);
}
*/
protected void expandViews_actionPerformed()
{
- Desktop.instance.explodeViews(this);
+ Desktop.getInstance().explodeViews(this);
}
/**
*/
protected void gatherViews_actionPerformed()
{
- Desktop.instance.gatherViews(this);
+ Desktop.getInstance().gatherViews(this);
}
/**
* Ctrl-F / Cmd-F open Finder dialog, 'focused' on the right alignment
*/
KeyStroke key_cmdF = KeyStroke.getKeyStroke(KeyEvent.VK_F,
- jalview.util.ShortcutKeyMaskExWrapper.getMenuShortcutKeyMaskEx(), false);
+ Platform.SHORTCUT_KEY_MASK, false);
AbstractAction action = new AbstractAction()
{
@Override
{
return featureSettingsUI != null && !featureSettingsUI.isClosed();
}
-}
\ No newline at end of file
+}
import javax.swing.JTable;
import javax.swing.SwingUtilities;
import javax.swing.table.AbstractTableModel;
-
import jalview.api.structures.JalviewStructureDisplayI;
import jalview.bin.Cache;
import jalview.bin.Jalview;
// which FTS engine to use
data = StructureChooserQuerySource.getQuerySourceFor(selectedSeqs);
initDialog();
-
this.ap = ap;
this.selectedSequence = selectedSeq;
this.selectedSequences = selectedSeqs;
this.progressIndicator = (ap == null) ? null : ap.alignFrame;
init();
-
}
/**
// ensure a filter option is in force for search
populateFilterComboBox(true, cachedPDBExists);
-
// looks for any existing structures already loaded
// for the sequences (the cached ones)
// then queries the StructureChooserQuerySource to
*/
private void discoverStructureViews()
{
- if (Desktop.instance != null)
+ if (Desktop.getInstance() != null)
{
targetView.removeAllItems();
if (lastTargetedView != null && !lastTargetedView.isVisible())
lastTargetedView = null;
}
int linkedViewsAt = 0;
- for (StructureViewerBase view : Desktop.instance
+ for (StructureViewerBase view : Desktop.getInstance()
.getStructureViewers(null, null))
{
StructureViewer viewHandler = (lastTargetedView != null
discoveredStructuresSet = new LinkedHashSet<>();
HashSet<String> errors = new HashSet<>();
-
FilterOption selectedFilterOpt = ((FilterOption) cmb_filterOption
.getSelectedItem());
-
for (SequenceI seq : selectedSequences)
{
-
FTSRestResponse resultList;
try
{
{
getResultTable()
.setModel(data.getTableModel(discoveredStructuresSet));
-
noOfStructuresFound = discoveredStructuresSet.size();
lastDiscoveredStructuresSet = discoveredStructuresSet;
mainFrame.setTitle(MessageManager.formatMessage(
{
Thread filterThread = new Thread(new Runnable()
{
-
@Override
public void run()
{
for (SequenceI seq : selectedSequences)
{
-
FTSRestResponse resultList;
try
{
resultList = data.selectFirstRankedQuery(seq,
discoveredStructuresSet, wantedFields, fieldToFilterBy,
!chk_invertFilter.isSelected());
-
} catch (Exception e)
{
e.printStackTrace();
protected void populateFilterComboBox(boolean haveData,
boolean cachedPDBExist, FilterOption lastSel)
{
-
/*
* temporarily suspend the change listener behaviour
*/
cmb_filterOption.removeItemListener(this);
+
int selSet = -1;
cmb_filterOption.removeAllItems();
if (haveData)
cmb_filterOption.addItem(filter);
}
}
-
cmb_filterOption.addItem(
new FilterOption(MessageManager.getString("label.enter_pdb_id"),
"-", VIEWS_ENTER_ID, false, null));
cmb_filterOption.setSelectedItem(cachedOption);
}
}
+
if (selSet > -1)
{
cmb_filterOption.setSelectedIndex(selSet);
// otherwise, record selection
// and update the layout and dialog accordingly
lastSelected = selectedFilterOpt;
-
layout_switchableViews.show(pnl_switchableViews,
selectedFilterOpt.getView());
String filterTitle = mainFrame.getTitle();
{
validateSelections();
}
+
private FilterOption lastSelected=null;
/**
* Handles the state change event for the 'filter' combo-box and 'invert'
}
return found;
}
-
/**
* Handles the 'New View' action
*/
{
PDBEntry pdbEntry = ((PDBEntryTableModel) tbl_local_pdb
.getModel()).getPDBEntryAt(row).getPdbEntry();
-
pdbEntriesToView[count++] = pdbEntry;
SequenceI selectedSeq = (SequenceI) tbl_local_pdb
.getValueAt(row, refSeqColIndex);
PDBEntry fileEntry = new AssociatePdbFileWithSeq()
.associatePdbWithSeq(selectedPdbFileName,
DataSourceType.FILE, selectedSequence, true,
- Desktop.instance);
+ Desktop.getInstance());
sViewer = launchStructureViewer(ssm, new PDBEntry[] { fileEntry },
ap, new SequenceI[]
{
fetchStructuresMetaData();
// populateFilterComboBox(true, cachedPDBExists);
-
filterResultSet(
((FilterOption) cmb_filterOption.getSelectedItem())
.getValue());
{
progressBar.setProgressBar(message, id);
}
+
+ @Override
+ public void removeProgressBar(long id)
+ {
+ progressBar.removeProgressBar(id);
+ }
@Override
public void registerHandler(long id, IProgressIndicatorHandler handler)
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
-
import jalview.api.structures.JalviewStructureDisplayI;
import jalview.bin.Cache;
import jalview.datamodel.PDBEntry;
import jalview.datamodel.StructureViewerModel;
import jalview.structure.StructureSelectionManager;
+
/**
* A proxy for handling structure viewers, that orchestrates adding selected
* structures, associated with sequences in Jalview, to an existing viewer, or
*/
public class StructureViewer
{
+
+ static
+ {
+ Platform.loadStaticResource("core/core_jvjmol.z.js",
+ "org.jmol.viewer.Viewer");
+ }
+
+
+
+
private static final String UNKNOWN_VIEWER_TYPE = "Unknown structure viewer type ";
StructureSelectionManager ssm;
* Creates a new panel controlling a structure viewer
*
* @param type
+ * @param pdbf
+ * @param id
+ * @param sq
* @param alignPanel
* @param viewerData
* @param sessionFile
String sessionFile, String vid)
{
JalviewStructureDisplayI viewer = null;
+
switch (type)
{
case JMOL:
return viewer;
}
-
public boolean isBusy()
{
if (sview != null)
*/
protected List<StructureViewerBase> getViewersFor(AlignmentPanel alp)
{
- return Desktop.instance.getStructureViewers(alp, this.getClass());
+ return Desktop.getInstance().getStructureViewers(alp, this.getClass());
}
@Override
*/
if (e.isPopupTrigger())
{
- chooseSubtreeColour();
+ if (highlightNode != null) {
+ chooseSubtreeColour();
+ }
e.consume(); // prevent mouseClicked happening
}
}
{
final PropertyChangeListener listener = new PropertyChangeListener()
{
+ @SuppressWarnings("unchecked")
@Override
public void propertyChange(PropertyChangeEvent evt)
{
- if (evt.getPropertyName().equals("alignment"))
- {
+ switch (evt.getPropertyName()) {
+ case AlignmentViewport.PROPERTY_ALIGNMENT:
if (tree == null)
{
System.out.println("tree is null");
{
System.out.println(
"new alignment sequences vector value is null");
+ return;
}
tree.updatePlaceHolders((List<SequenceI>) evt.getNewValue());
treeCanvas.nameHash.clear(); // reset the mapping between canvas
// rectangles and leafnodes
repaint();
+ break;
}
}
};
frame = new JInternalFrame();
frame.setContentPane(this);
Desktop.addInternalFrame(frame,
- MessageManager.getString("label.user_defined_colours"),
- MY_FRAME_WIDTH, MY_FRAME_HEIGHT, true);
+ MessageManager.getString("label.user_defined_colours"), Desktop.FRAME_MAKE_VISIBLE,
+ MY_FRAME_WIDTH, MY_FRAME_HEIGHT, Desktop.FRAME_ALLOW_RESIZE, Desktop.FRAME_SET_MIN_SIZE_300);
}
/**
{
if (isNoSelectionMade())
{
- JvOptionPane.showMessageDialog(Desktop.desktop,
+ JvOptionPane.showMessageDialog(Desktop.getDesktopPane(),
MessageManager
.getString("label.no_colour_selection_in_scheme"),
MessageManager.getString("label.no_colour_selection_warn"),
String[] options = new String[] { title,
MessageManager.getString("label.dont_save_changes"), };
final String question = JvSwingUtils.wrapTooltip(true, message);
- int response = JvOptionPane.showOptionDialog(Desktop.desktop,
+ int response = JvOptionPane.showOptionDialog(Desktop.getDesktopPane(),
question, title, JvOptionPane.DEFAULT_OPTION,
JvOptionPane.PLAIN_MESSAGE, null, options, options[0]);
{
if (isNoSelectionMade())
{
- JvOptionPane.showMessageDialog(Desktop.desktop,
+ JvOptionPane.showMessageDialog(Desktop.getDesktopPane(),
MessageManager
.getString("label.no_colour_selection_in_scheme"),
MessageManager.getString("label.no_colour_selection_warn"),
String name = schemeName.getText().trim();
if (name.length() < 1)
{
- JvOptionPane.showInternalMessageDialog(Desktop.desktop,
+ JvOptionPane.showInternalMessageDialog(Desktop.getDesktopPane(),
MessageManager
.getString("label.user_colour_scheme_must_have_name"),
MessageManager.getString("label.no_name_colour_scheme"),
* @j2sIgnore
*/
{
- int reply = JvOptionPane.showInternalConfirmDialog(Desktop.desktop,
+ int reply = JvOptionPane.showInternalConfirmDialog(Desktop.getDesktopPane(),
MessageManager.formatMessage(
"label.colour_scheme_exists_overwrite", new Object[]
{ name, name }),
*/
package jalview.gui;
-import jalview.util.MessageManager;
-
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URL;
-import javax.swing.JOptionPane;
+import jalview.util.MessageManager;
public class UserQuestionnaireCheck implements Runnable
{
+ qid + "&rid=" + rid;
jalview.bin.Cache.log
.info("Prompting user for questionnaire at " + qurl);
- int reply = JvOptionPane.showInternalConfirmDialog(Desktop.desktop,
+ int reply = JvOptionPane.showInternalConfirmDialog(Desktop.getDesktopPane(),
MessageManager.getString("label.jalview_new_questionnaire"),
MessageManager.getString("label.jalview_user_survey"),
JvOptionPane.YES_NO_OPTION, JvOptionPane.QUESTION_MESSAGE);
}
} catch (InvalidSessionDocumentException e)
{
- JvOptionPane.showInternalMessageDialog(Desktop.desktop,
+ JvOptionPane.showInternalMessageDialog(Desktop.getDesktopPane(),
MessageManager.getString(
"label.vamsas_doc_couldnt_be_opened_as_new_session"),
VamsasAppDatastore vds = new VamsasAppDatastore(doc, vobj2jv, jv2vobj,
baseProvEntry(), alRedoState);
// wander through frames
- JInternalFrame[] frames = Desktop.desktop.getAllFrames();
+ JInternalFrame[] frames = Desktop.getDesktopPane().getAllFrames();
if (frames == null)
{
Cache.log.debug(
"Asking user if the vamsas session should be stored.");
int reply = JvOptionPane.showInternalConfirmDialog(
- Desktop.desktop,
+ Desktop.getDesktopPane(),
"The current VAMSAS session has unsaved data - do you want to save it ?",
"VAMSAS Session Shutdown",
JvOptionPane.YES_NO_OPTION,
if (reply == JvOptionPane.YES_OPTION)
{
Cache.log.debug("Prompting for vamsas store filename.");
- Desktop.instance.vamsasSave_actionPerformed(null);
+ Desktop.getInstance().vamsasSave_actionPerformed(null);
Cache.log
.debug("Finished attempt at storing document.");
}
public void disableGui(boolean b)
{
// JAL-3311 TODO: remove this class!
- // Desktop.instance.setVamsasUpdate(b);
+ // Desktop.getInstance().setVamsasUpdate(b);
}
Hashtable _backup_vobj2jv;
{
final IPickManager pm = vclient.getPickManager();
final StructureSelectionManager ssm = StructureSelectionManager
- .getStructureSelectionManager(Desktop.instance);
+ .getStructureSelectionManager(Desktop.getInstance());
final VamsasApplication me = this;
pm.registerMessageHandler(new IMessageHandler()
{
*/
package jalview.gui;
-import java.util.Locale;
+import jalview.jbgui.GWebserviceInfo;
+import jalview.util.MessageManager;
+import jalview.util.Platform;
+import jalview.ws.WSClientI;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.image.BufferedImage;
+import java.util.Locale;
import java.util.Vector;
import javax.swing.JComponent;
import javax.swing.text.html.HTMLEditorKit;
import javax.swing.text.html.StyleSheet;
-import jalview.jbgui.GWebserviceInfo;
-import jalview.util.ChannelProperties;
-import jalview.util.MessageManager;
-import jalview.ws.WSClientI;
-
/**
* Base class for web service client thread and gui TODO: create StAX parser to
* extract html body content reliably when preparing html formatted job statuses
public WebserviceInfo(String title, String info, int width, int height,
boolean makeVisible)
{
+ // no references
init(title, info, width, height, makeVisible);
}
{
frame = new JInternalFrame();
frame.setContentPane(this);
- Desktop.addInternalFrame(frame, title, makeVisible, width, height);
+ Desktop.addInternalFrame(frame, title, makeVisible, width, height, Desktop.FRAME_ALLOW_RESIZE, Desktop.FRAME_SET_MIN_SIZE_300);
frame.setClosable(false);
progressBar = new ProgressBar(statusPanel, statusBar);
titlePanel.add(titleText, BorderLayout.CENTER);
setStatus(currentStatus);
- Thread thread = new Thread(ap);
- thread.start();
- final WebserviceInfo thisinfo = this;
- frame.addInternalFrameListener(new InternalFrameAdapter()
+ if (!Platform.isJS())
{
- @Override
- public void internalFrameClosed(InternalFrameEvent evt)
- {
- // System.out.println("Shutting down webservice client");
- WSClientI service = thisinfo.getthisService();
- if (service != null && service.isCancellable())
- {
- service.cancelJob();
- }
- }
- });
+ // No animation for the moment//
+ Thread thread = new Thread(ap);
+ thread.start();
+ }
+ final WebserviceInfo thisinfo = this;
+ frame.addInternalFrameListener(
+ new InternalFrameAdapter()
+ {
+ @Override
+ public void internalFrameClosed(InternalFrameEvent evt)
+ {
+ // System.out.println("Shutting down webservice client");
+ WSClientI service = thisinfo.getthisService();
+ if (service != null && service.isCancellable())
+ {
+ service.cancelJob();
+ }
+ }
+ });
frame.validate();
}
@Override
public void run()
{
- JvOptionPane.showInternalMessageDialog(Desktop.desktop, message,
+ JvOptionPane.showInternalMessageDialog(Desktop.getDesktopPane(), message,
title, JvOptionPane.WARNING_MESSAGE);
}
{
progressBar.setProgressBar(message, id);
}
+
+ @Override
+ public void removeProgressBar(long id)
+ {
+ progressBar.removeProgressBar(id);
+ }
@Override
public void registerHandler(final long id,
*/
package jalview.gui;
+import jalview.gui.OptsAndParamsPage.OptionBox;
+import jalview.gui.OptsAndParamsPage.ParamBox;
+import jalview.util.MessageManager;
+import jalview.ws.api.UIinfo;
+import jalview.ws.params.ArgumentI;
+import jalview.ws.params.OptionI;
+import jalview.ws.params.ParamDatastoreI;
+import jalview.ws.params.ParameterI;
+import jalview.ws.params.WsParamSetI;
+
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.event.HierarchyEvent;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
-import java.awt.event.WindowEvent;
-import java.awt.event.WindowListener;
-import java.net.URL;
import java.util.Hashtable;
-import java.util.Iterator;
import java.util.List;
import java.util.Vector;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.CompletionStage;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
-import javax.swing.JSplitPane;
import javax.swing.JTextArea;
+import javax.swing.WindowConstants;
import javax.swing.border.TitledBorder;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
-import compbio.metadata.Argument;
-import compbio.metadata.Option;
-import compbio.metadata.Parameter;
-import compbio.metadata.Preset;
-import compbio.metadata.PresetManager;
-import compbio.metadata.RunnerConfig;
-import jalview.bin.Cache;
-import jalview.gui.OptsAndParamsPage.OptionBox;
-import jalview.gui.OptsAndParamsPage.ParamBox;
-import jalview.util.MessageManager;
-import jalview.ws.jws2.JabaParamStore;
-import jalview.ws.jws2.JabaPreset;
-import jalview.ws.jws2.Jws2Discoverer;
-import jalview.ws.jws2.jabaws2.Jws2Instance;
-import jalview.ws.params.ArgumentI;
-import jalview.ws.params.OptionI;
-import jalview.ws.params.ParamDatastoreI;
-import jalview.ws.params.ParameterI;
-import jalview.ws.params.WsParamSetI;
import net.miginfocom.swing.MigLayout;
/**
public class WsJobParameters extends JPanel implements ItemListener,
ActionListener, DocumentListener, OptsParametersContainerI
{
- URL linkImageURL = getClass().getResource("/images/link.gif");
+ private static final int PREFERRED_WIDTH = 540;
+
+ private static final int DEFAULT_HEIGHT = 640;
+
+ // the default parameter set shown to the user
+ private static final String SVC_DEF = "Defaults";
+
+ private int maxOptWidth = 200;
+
+ // URL linkImageURL = getClass().getResource("/images/link.gif");
- private static final String SVC_DEF = "Defaults"; // this is the null
- // parameter set as shown to
- // user
+ // TODO ABSRACT FROM JABAWS CLASSES
+ // completion stage representing whether start was clicked
+ private final CompletableFuture<Boolean> completionStage = new CompletableFuture<>();
+
/**
* manager for options and parameters.
*/
- OptsAndParamsPage opanp = new OptsAndParamsPage(this);
+ OptsAndParamsPage opanp;
- /**
+ /*
* panel containing job options
*/
- JPanel jobOptions = new JPanel();
+ JPanel optionsPanel = new JPanel();
- /**
+ /*
* panel containing job parameters
*/
- JPanel paramList = new JPanel();
-
- JPanel SetNamePanel = new JPanel();
-
- JPanel setDetails = new JPanel();
+ JPanel paramsPanel = new JPanel();
- JSplitPane settingsPanel = new JSplitPane();
-
- JPanel jobPanel = new JPanel();
-
- JScrollPane jobOptionsPane = new JScrollPane();
+ JPanel setNamePanel = new JPanel();
JButton createpref = new JButton();
JButton updatepref = new JButton();
- JButton startjob = new JButton();
-
- JButton canceljob = new JButton();
-
- JComboBox setName = new JComboBox();
+ JComboBox<String> setName = new JComboBox<>();
JTextArea setDescr = new JTextArea();
JScrollPane paramPane = new JScrollPane();
-
- // ScrollablePanel optsAndparams = new ScrollablePanel();
- JPanel optsAndparams = new JPanel();
-
- RunnerConfig serviceOptions;
+
+ JButton startjob = JvSwingUtils.makeButton(
+ MessageManager.getString("action.start_job"),
+ MessageManager.getString("label.start_job_current_settings"),
+ this::startjob_actionPerformed);
+ JButton canceljob = JvSwingUtils.makeButton(
+ MessageManager.getString("action.cancel_job"),
+ MessageManager.getString("label.cancel_job_close_dialog"),
+ this::canceljob_actionPerformed);
ParamDatastoreI paramStore;
- private int MAX_OPTWIDTH = 200;
+ // set true when 'Start Job' is clicked
+ boolean startJob = false;
- WsJobParameters(Jws2Instance service)
- {
- this(service, null);
- }
+ JFrame frame = null;
- public WsJobParameters(Jws2Instance service, WsParamSetI preset)
- {
- this(null, service, preset, null);
- }
+ UIinfo service;
- /**
- *
- * @param desktop
- * - if null, create new JFrame outside of desktop
- * @param service
- * @param preset
+ /*
+ * list of service presets in the gui
+ */
+ Hashtable<String, String> servicePresets = null;
+
+ /*
+ * set if dialog is being set - so handlers will avoid spurious events
*/
- public WsJobParameters(JFrame parent, Jws2Instance service,
- WsParamSetI preset, List<Argument> jobArgset)
+ boolean settingDialog = false;
+
+ private Hashtable<Object, Object> modifiedElements = new Hashtable<>();
+
+ String lastParmSet = null;
+
+ public WsJobParameters(ParamDatastoreI store, WsParamSetI preset,
+ List<ArgumentI> args)
{
- this(parent, null, service, preset, jobArgset);
+ super();
+
+ // parameters dialog in 'compact' format (help as tooltips)
+ opanp = new OptsAndParamsPage(this, true);
+ jbInit();
+ this.paramStore = store;
+ this.service = null;
+ init(preset, args);
+ validate();
}
/**
+ * Constructor given a set of parameters and presets, a service to be invoked,
+ * and a list of (Jabaws client) arguments
*
- * @param parent
* @param paramStorei
* @param service
* @param preset
* @param jobArgset
*/
- public WsJobParameters(JFrame parent, ParamDatastoreI paramStorei,
- Jws2Instance service, WsParamSetI preset,
- List<Argument> jobArgset)
+ public WsJobParameters(ParamDatastoreI paramStorei, UIinfo service,
+ WsParamSetI preset, List<ArgumentI> jobArgset)
{
super();
+ // parameters dialog in 'expanded' format (help text boxes)
+ opanp = new OptsAndParamsPage(this, false);
jbInit();
this.paramStore = paramStorei;
- if (paramStore == null)
+ if (paramStore == null && service != null)
{
paramStore = service.getParamStore();
}
this.service = service;
- // argSetModified(false);
- // populate parameter table
- initForService(service, preset, jobArgset);
- // display in new JFrame attached to parent.
+ initForService(preset, jobArgset);
validate();
}
- int response = -1;
-
- JDialog frame = null;
/**
- * shows a modal dialog containing the parameters.
+ * Shows a modal dialog containing the parameters and Start or Cancel options.
+ * Answers true if the job is started, false if cancelled.
*
* @return
*/
- public boolean showRunDialog()
+ public CompletionStage<Boolean> showRunDialog()
{
-
- frame = new JDialog(Desktop.instance, true);
-
- frame.setTitle(MessageManager.formatMessage("label.edit_params_for",
- new String[]
- { service.getActionText() }));
- Rectangle deskr = Desktop.instance.getBounds();
+ // Should JFrame hahve a parent of getDesktop ?
+ frame = new JFrame();
+ frame.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
+ if (service != null)
+ {
+ frame.setTitle(MessageManager.formatMessage("label.edit_params_for",
+ new String[] { service.getActionText() }));
+ }
+ Rectangle deskr = Desktop.getInstance().getBounds();
Dimension pref = this.getPreferredSize();
frame.setBounds(
new Rectangle((int) (deskr.getCenterX() - pref.width / 2),
}
});
+
frame.setVisible(true);
- if (response > 0)
- {
- return true;
- }
- return false;
+ return completionStage;
}
private void jbInit()
updatepref = JvSwingUtils.makeButton(
MessageManager.getString("action.update"),
MessageManager.getString("label.update_user_parameter_set"),
- new ActionListener()
- {
-
- @Override
- public void actionPerformed(ActionEvent e)
- {
- update_actionPerformed(e);
- }
- });
+ this::update_actionPerformed);
deletepref = JvSwingUtils.makeButton(
MessageManager.getString("action.delete"),
MessageManager.getString("label.delete_user_parameter_set"),
- new ActionListener()
- {
-
- @Override
- public void actionPerformed(ActionEvent e)
- {
- delete_actionPerformed(e);
- }
- });
+ this::delete_actionPerformed);
createpref = JvSwingUtils.makeButton(
MessageManager.getString("action.create"),
MessageManager.getString("label.create_user_parameter_set"),
- new ActionListener()
- {
-
- @Override
- public void actionPerformed(ActionEvent e)
- {
- create_actionPerformed(e);
- }
- });
+ this::create_actionPerformed);
revertpref = JvSwingUtils.makeButton(
MessageManager.getString("action.revert"),
MessageManager
.getString("label.revert_changes_user_parameter_set"),
- new ActionListener()
- {
+ this::revert_actionPerformed);
- @Override
- public void actionPerformed(ActionEvent e)
- {
- revert_actionPerformed(e);
- }
- });
- startjob = JvSwingUtils.makeButton(
- MessageManager.getString("action.start_job"),
- MessageManager.getString("label.start_job_current_settings"),
- new ActionListener()
- {
- @Override
- public void actionPerformed(ActionEvent e)
- {
- startjob_actionPerformed(e);
- }
- });
- canceljob = JvSwingUtils.makeButton(
- MessageManager.getString("action.cancel_job"),
- MessageManager.getString("label.cancel_job_close_dialog"),
- new ActionListener()
- {
- @Override
- public void actionPerformed(ActionEvent e)
- {
- canceljob_actionPerformed(e);
- }
- });
+ JPanel setDetails = new JPanel();
setDetails.setBorder(
new TitledBorder(MessageManager.getString("label.details")));
setDetails.setLayout(new BorderLayout());
setName.getEditor().addActionListener(this);
JPanel setNameInfo = new JPanel(new FlowLayout(FlowLayout.LEFT));
GridBagLayout gbl = new GridBagLayout();
- SetNamePanel.setLayout(gbl);
+ setNamePanel.setLayout(gbl);
JLabel setNameLabel = new JLabel(
MessageManager.getString("label.current_parameter_set_name"));
revertpref.setVisible(false);
createpref.setVisible(false);
JPanel setsavebuts = new JPanel();
- setsavebuts.setLayout(new FlowLayout(FlowLayout.LEFT)); // GridLayout(1,2));
- ((FlowLayout) setsavebuts.getLayout()).setHgap(10);
- ((FlowLayout) setsavebuts.getLayout()).setVgap(0);
+ setsavebuts.setLayout(new FlowLayout(FlowLayout.LEFT, 10, 0)); // GridLayout(1,2));
JPanel spacer = new JPanel();
spacer.setPreferredSize(new Dimension(2, 30));
setsavebuts.add(spacer);
// setsavebuts.setSize(new Dimension(150, 30));
JPanel buttonArea = new JPanel(new GridLayout(1, 1));
buttonArea.add(setsavebuts);
- SetNamePanel.add(setNameInfo);
+ setNamePanel.add(setNameInfo);
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridheight = 2;
gbl.setConstraints(setNameInfo, gbc);
- SetNamePanel.add(buttonArea);
+ setNamePanel.add(buttonArea);
gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 2;
// paramPane.setPreferredSize(new Dimension(360, 400));
// paramPane.setPreferredSize(null);
- jobOptions.setBorder(
+ optionsPanel.setBorder(
new TitledBorder(MessageManager.getString("label.options")));
- jobOptions.setOpaque(true);
- paramList.setBorder(
+ optionsPanel.setOpaque(true);
+ paramsPanel.setBorder(
new TitledBorder(MessageManager.getString("label.parameters")));
- paramList.setOpaque(true);
- JPanel bjo = new JPanel(new BorderLayout()),
- bjp = new JPanel(new BorderLayout());
- bjo.add(jobOptions, BorderLayout.CENTER);
- bjp.add(paramList, BorderLayout.CENTER);
- bjp.setOpaque(true);
- bjo.setOpaque(true);
+ paramsPanel.setOpaque(true);
// optsAndparams.setScrollableWidth(ScrollableSizeHint.FIT);
// optsAndparams.setScrollableHeight(ScrollableSizeHint.NONE);
// optsAndparams.setLayout(new BorderLayout());
+ JPanel optsAndparams = new JPanel();
optsAndparams.setLayout(new BorderLayout());
- optsAndparams.add(jobOptions, BorderLayout.NORTH);
- optsAndparams.add(paramList, BorderLayout.CENTER);
+ optsAndparams.add(optionsPanel, BorderLayout.NORTH);
+ optsAndparams.add(paramsPanel, BorderLayout.CENTER);
JPanel jp = new JPanel(new BorderLayout());
jp.add(optsAndparams, BorderLayout.CENTER);
paramPane.getViewport().setView(jp);
paramPane.setBorder(null);
setLayout(new BorderLayout());
+ JPanel jobPanel = new JPanel();
jobPanel.setPreferredSize(null);
jobPanel.setLayout(new BorderLayout());
jobPanel.add(setDetails, BorderLayout.NORTH);
jobPanel.add(paramPane, BorderLayout.CENTER);
// jobPanel.setOrientation(JSplitPane.VERTICAL_SPLIT);
- add(SetNamePanel, BorderLayout.NORTH);
+ add(setNamePanel, BorderLayout.NORTH);
add(jobPanel, BorderLayout.CENTER);
JPanel dialogpanel = new JPanel();
dialogpanel.add(canceljob);
// JAL-1580: setMaximumSize() doesn't work, so just size for the worst case:
// check for null is for JUnit usage
- final int windowHeight = Desktop.instance == null ? 540
- : Desktop.instance.getHeight();
+ final int windowHeight = Desktop.getInstance() == null ? DEFAULT_HEIGHT
+ : Desktop.getInstance().getHeight();
setPreferredSize(new Dimension(540, windowHeight));
add(dialogpanel, BorderLayout.SOUTH);
validate();
protected void canceljob_actionPerformed(ActionEvent e)
{
- response = 0;
+ startJob = false;
if (frame != null)
{
frame.setVisible(false);
}
+ completionStage.complete(false);
}
protected void startjob_actionPerformed(ActionEvent e)
{
- response = 1;
+ startJob = true;
if (frame != null)
{
frame.setVisible(false);
}
+ completionStage.complete(true);
}
- Jws2Instance service;
+ void initForService(WsParamSetI paramSet, List<ArgumentI> jobArgset)
+ {
+ settingDialog = true;
- /**
- * list of service presets in the gui
- */
- Hashtable servicePresets = null;
+ init(paramSet, jobArgset);
- /**
- * set if dialog is being set - so handlers will avoid spurious events
- */
- boolean settingDialog = false;
+ }
- void initForService(Jws2Instance service, WsParamSetI jabap,
- List<Argument> jabajobArgset)
+ void init(WsParamSetI p, List<ArgumentI> jobArgset)
{
- WsParamSetI p = null;
- List<ArgumentI> jobArgset = null;
- settingDialog = true;
- { // instantiate the abstract proxy for Jaba objects
- jobArgset = jabajobArgset == null ? null
- : JabaParamStore.getJwsArgsfromJaba(jabajobArgset);
- p = jabap; // (jabap != null) ? paramStore.getPreset(jabap.getName()) :
- // null;
- }
-
- Hashtable exnames = new Hashtable();
+ Hashtable<String, String> exnames = new Hashtable<>();
for (int i = 0, iSize = setName.getItemCount(); i < iSize; i++)
{
exnames.put(setName.getItemAt(i), setName.getItemAt(i));
}
- servicePresets = new Hashtable();
+ servicePresets = new Hashtable<>();
// Add the default entry - if not present already.
if (!exnames.contains(SVC_DEF))
{
exnames.put(SVC_DEF, SVC_DEF);
servicePresets.put(SVC_DEF, SVC_DEF);
}
- String curname = (p == null ? "" : p.getName());
+ // String curname = (p == null ? "" : p.getName());
for (WsParamSetI pr : paramStore.getPresets())
{
if (!pr.isModifiable())
}
- @SuppressWarnings("unchecked")
private void updateTable(WsParamSetI p, List<ArgumentI> jobArgset)
{
boolean setDefaultParams = false;
OptionI opt = (OptionI) myarg;
OptionBox ob = opanp.addOption(opt);
ob.resetToDefault(setDefaultParams);
- if (MAX_OPTWIDTH < ob.getPreferredSize().width)
+ if (maxOptWidth < ob.getPreferredSize().width)
{
- MAX_OPTWIDTH = ob.getPreferredSize().width;
+ maxOptWidth = ob.getPreferredSize().width;
}
ob.validate();
cw += ob.getPreferredSize().width + 5;
return modifiedElements.size() > 0;
}
- private Hashtable modifiedElements = new Hashtable();
/**
* reset gui and modification state settings
if (b && modifiedElements.size() > 0)
{
makeSetNameValid(!isUserPreset);
- SetNamePanel.revalidate();
+ setNamePanel.revalidate();
}
updateButtonDisplay();
}
// sync the gui with the preset database
for (int i = 0, iS = setName.getItemCount(); i < iS; i++)
{
- String snm = (String) setName.getItemAt(i);
+ String snm = setName.getItemAt(i);
if (snm.equals(nm))
{
makeupdate = true;
settingDialog = stn;
}
+ /**
+ * Rebuilds the Options and Parameters panels
+ */
@Override
public void refreshParamLayout()
{
- // optsAndparams.setPreferredSize(null);
- FlowLayout fl = new FlowLayout(FlowLayout.LEFT);
- int sep = fl.getVgap();
- boolean fh = true;
- int os = 0,
- s = jobOptions.getBorder().getBorderInsets(jobOptions).bottom
- + jobOptions.getBorder().getBorderInsets(jobOptions).top
- + 2 * sep;
- /**
- * final height for viewport
- */
- int finalh = s;
- int panewidth = paramPane.getViewport().getSize().width - 120
- - jobOptions.getBorder().getBorderInsets(jobOptions).left
- + jobOptions.getBorder().getBorderInsets(jobOptions).right;
-
- int w = 2 * fl.getHgap()
- + (MAX_OPTWIDTH > OptsAndParamsPage.PARAM_WIDTH ? MAX_OPTWIDTH
- : OptsAndParamsPage.PARAM_WIDTH);
- int hgap = fl.getHgap(), cw = hgap;
+ final int rightMargin = 40;
+ final int availableWidth = paramPane.getViewport().getSize().width
+ - rightMargin
+ - optionsPanel.getBorder().getBorderInsets(optionsPanel).left
+ + optionsPanel.getBorder().getBorderInsets(optionsPanel).right;
if (opanp.getOptSet().size() > 0)
{
+ int hgap = 5;
+ int currentWidth = hgap;
- jobOptions.setLayout(new MigLayout("", "", ""));
- jobOptions.removeAll();
+ /*
+ * layout constraint 'nogrid' prevents vertical column alignment,
+ * allowing controls to flow without extra space inserted to align
+ */
+ optionsPanel.setLayout(new MigLayout("nogrid", "", ""));
+ optionsPanel.removeAll();
+ JPanel lastAdded = null;
+ /*
+ * add each control in turn; if adding would overflow the right margin,
+ * remove and re-add the previous parameter with "wrap" (after)
+ * in order to start a new row
+ */
for (OptionBox pbox : opanp.getOptSet().values())
{
pbox.validate();
- cw += pbox.getSize().width + hgap;
- if (cw + 120 > panewidth)
- {
- jobOptions.add(pbox, "wrap");
- // System.out.println("Wrap on "+pbox.option.getName());
- cw = hgap + pbox.getSize().width;
- fh = true;
- }
- else
+ int boxWidth = pbox.getSize().width;
+ currentWidth += boxWidth + hgap;
+ boolean wrapAfterLast = currentWidth > availableWidth
+ && lastAdded != null;
+ // System.out.println(String.format(
+ // "%s width=%d, paneWidth=%d, currentWidth=%d, wrapAfterLast=%s",
+ // pbox.toString(), boxWidth, panewidth, currentWidth,
+ // wrapAfterLast));
+ if (wrapAfterLast)
{
- jobOptions.add(pbox);
- }
- if (fh)
- {
- finalh += pbox.getSize().height + fl.getVgap();
- fh = false;
+ optionsPanel.remove(lastAdded);
+ optionsPanel.add(lastAdded, "wrap");
+ currentWidth = hgap + boxWidth;
}
+ optionsPanel.add(pbox);
+ lastAdded = pbox;
}
- jobOptions.revalidate();
+ optionsPanel.revalidate();
}
else
{
- jobOptions.setVisible(false);
+ optionsPanel.setVisible(false);
}
- // Now layout the parameters assuming they occupy one column - to calculate
- // total height of options+parameters
- fl = new FlowLayout(FlowLayout.LEFT);
- // helpful hint from
- // http://stackoverflow.com/questions/2743177/top-alignment-for-flowlayout
- fl.setAlignOnBaseline(true);
if (opanp.getParamSet().size() > 0)
{
- paramList.removeAll();
- paramList.setLayout(new MigLayout("", "", ""));
- fh = true;
+ paramsPanel.removeAll();
+ paramsPanel.setLayout(new MigLayout("", "", ""));
+ int hgap = 5;
+ int currentWidth = hgap;
+
+ JPanel lastAdded = null;
for (ParamBox pbox : opanp.getParamSet().values())
{
pbox.validate();
- cw += pbox.getSize().width + hgap;
- if (cw + 160 > panewidth)
- {
- paramList.add(pbox, "wrap");
- cw = pbox.getSize().width + hgap;
- fh = true;
- }
- else
- {
- paramList.add(pbox);
- }
- if (fh)
+ int boxWidth = pbox.getSize().width;
+ currentWidth += boxWidth + hgap;
+ boolean wrapAfterLast = currentWidth > availableWidth
+ && lastAdded != null;
+ if (wrapAfterLast)
{
- finalh += pbox.getSize().height + fl.getVgap();
- fh = false;
+ paramsPanel.remove(lastAdded);
+ paramsPanel.add(lastAdded, "wrap");
+ currentWidth = pbox.getSize().width + hgap;
}
-
+ paramsPanel.add(pbox);
+ lastAdded = pbox;
}
+
/*
* s = 2 * sep; for (ParamBox pbox : opanp.getParamSet().values()) {
* pbox.validate(); s += sep +
* .getBorder().getBorderInsets(paramList).bottom+paramList
* .getBorder().getBorderInsets(paramList).top;
*/
- paramList.revalidate();
+ paramsPanel.revalidate();
}
else
{
- paramList.setVisible(false);
+ paramsPanel.setVisible(false);
}
// TODO: waste some time trying to eliminate any unnecessary .validate calls
// here
revalidate();
}
- /**
- * testing method - grab a service and parameter set and show the window
- *
- * @param args
- * @j2sIgnore
- */
- public static void main(String[] args)
- {
- jalview.ws.jws2.Jws2Discoverer disc = jalview.ws.jws2.Jws2Discoverer
- .getDiscoverer();
- int p = 0;
- if (args.length > 0)
- {
- Vector<String> services = new Vector<>();
- services.addElement(args[p++]);
- Jws2Discoverer.getDiscoverer().setServiceUrls(services);
- }
- try
- {
- disc.run();
- } catch (Exception e)
- {
- System.err.println("Aborting. Problem discovering services.");
- e.printStackTrace();
- return;
- }
- Jws2Instance lastserv = null;
- for (Jws2Instance service : disc.getServices())
- {
- lastserv = service;
- if (p >= args.length || service.serviceType.equalsIgnoreCase(args[p]))
- {
- if (lastserv != null)
- {
- List<Preset> prl = null;
- Preset pr = null;
- if (++p < args.length)
- {
- PresetManager prman = lastserv.getPresets();
- if (prman != null)
- {
- pr = prman.getPresetByName(args[p]);
- if (pr == null)
- {
- // just grab the last preset.
- prl = prman.getPresets();
- }
- }
- }
- else
- {
- PresetManager prman = lastserv.getPresets();
- if (prman != null)
- {
- prl = prman.getPresets();
- }
- }
- Iterator<Preset> en = (prl == null) ? null : prl.iterator();
- while (en != null && en.hasNext())
- {
- if (en != null)
- {
- if (!en.hasNext())
- {
- en = prl.iterator();
- }
- pr = en.next();
- }
- {
- System.out.println("Testing opts dupes for "
- + lastserv.getUri() + " : " + lastserv.getActionText()
- + ":" + pr.getName());
- List<Option> rg = lastserv.getRunnerConfig().getOptions();
- for (Option o : rg)
- {
- try
- {
- Option cpy = jalview.ws.jws2.ParameterUtils.copyOption(o);
- } catch (Exception e)
- {
- System.err.println("Failed to copy " + o.getName());
- e.printStackTrace();
- } catch (Error e)
- {
- System.err.println("Failed to copy " + o.getName());
- e.printStackTrace();
- }
- }
- }
- {
- System.out.println("Testing param dupes:");
- List<Parameter> rg = lastserv.getRunnerConfig()
- .getParameters();
- for (Parameter o : rg)
- {
- try
- {
- Parameter cpy = jalview.ws.jws2.ParameterUtils
- .copyParameter(o);
- } catch (Exception e)
- {
- System.err.println("Failed to copy " + o.getName());
- e.printStackTrace();
- } catch (Error e)
- {
- System.err.println("Failed to copy " + o.getName());
- e.printStackTrace();
- }
- }
- }
- {
- System.out.println("Testing param write:");
- List<String> writeparam = null, readparam = null;
- try
- {
- writeparam = jalview.ws.jws2.ParameterUtils
- .writeParameterSet(
- pr.getArguments(lastserv.getRunnerConfig()),
- " ");
- System.out.println("Testing param read :");
- List<Option> pset = jalview.ws.jws2.ParameterUtils
- .processParameters(writeparam,
- lastserv.getRunnerConfig(), " ");
- readparam = jalview.ws.jws2.ParameterUtils
- .writeParameterSet(pset, " ");
- Iterator<String> o = pr.getOptions().iterator(),
- s = writeparam.iterator(), t = readparam.iterator();
- boolean failed = false;
- while (s.hasNext() && t.hasNext())
- {
- String on = o.next(), sn = s.next(), st = t.next();
- if (!sn.equals(st))
- {
- System.out.println(
- "Original was " + on + " Phase 1 wrote " + sn
- + "\tPhase 2 wrote " + st);
- failed = true;
- }
- }
- if (failed)
- {
- System.out.println(
- "Original parameters:\n" + pr.getOptions());
- System.out.println(
- "Wrote parameters in first set:\n" + writeparam);
- System.out.println(
- "Wrote parameters in second set:\n" + readparam);
-
- }
- } catch (Exception e)
- {
- e.printStackTrace();
- }
- }
- WsJobParameters pgui = new WsJobParameters(lastserv,
- new JabaPreset(lastserv, pr));
- JFrame jf = new JFrame(MessageManager
- .formatMessage("label.ws_parameters_for", new String[]
- { lastserv.getActionText() }));
- JPanel cont = new JPanel(new BorderLayout());
- pgui.validate();
- cont.setPreferredSize(pgui.getPreferredSize());
- cont.add(pgui, BorderLayout.CENTER);
- jf.setLayout(new BorderLayout());
- jf.add(cont, BorderLayout.CENTER);
- jf.validate();
- final Thread thr = Thread.currentThread();
- jf.addWindowListener(new WindowListener()
- {
-
- @Override
- public void windowActivated(WindowEvent e)
- {
- // TODO Auto-generated method stub
-
- }
-
- @Override
- public void windowClosed(WindowEvent e)
- {
- }
-
- @Override
- public void windowClosing(WindowEvent e)
- {
- thr.interrupt();
-
- }
-
- @Override
- public void windowDeactivated(WindowEvent e)
- {
- // TODO Auto-generated method stub
-
- }
-
- @Override
- public void windowDeiconified(WindowEvent e)
- {
- // TODO Auto-generated method stub
-
- }
-
- @Override
- public void windowIconified(WindowEvent e)
- {
- // TODO Auto-generated method stub
-
- }
-
- @Override
- public void windowOpened(WindowEvent e)
- {
- // TODO Auto-generated method stub
-
- }
-
- });
- jf.setVisible(true);
- boolean inter = false;
- while (!inter)
- {
- try
- {
- Thread.sleep(10000);
- } catch (Exception e)
- {
- inter = true;
- }
- }
- jf.dispose();
- }
- }
- }
- }
- }
public boolean isServiceDefaults()
{
return opanp.getCurrentSettings();
}
- String lastParmSet = null;
/*
* Hashtable<String, Object[]> editedParams = new Hashtable<String,
int n = 0;
// remove any set names in the drop down menu that aren't either a reserved
// setting, or a user defined or service preset.
- Vector items = new Vector();
+ Vector<String> items = new Vector<>();
while (n < setName.getItemCount())
{
- String item = (String) setName.getItemAt(n);
+ String item = setName.getItemAt(n);
if (!item.equals(SVC_DEF) && !paramStore.presetExists(item))
{
setName.removeItemAt(n);
initArgSetModified();
syncSetNamesWithStore();
setName.setSelectedItem(lastParmSet);
- SetNamePanel.validate();
+ setNamePanel.validate();
validate();
settingDialog = false;
}
*/
protected void updateWebServiceMenus()
{
+ if (Desktop.getInstance() == null)
+ {
+ return;
+ }
for (AlignFrame alignFrame : Desktop.getAlignFrames())
{
- alignFrame.BuildWebServiceMenu();
+ alignFrame.buildWebServicesMenu();
}
}
@Override
public void itemStateChanged(ItemEvent e)
{
- if (e.getSource() == setName && e.getStateChange() == e.SELECTED)
+ if (e.getSource() == setName
+ && e.getStateChange() == ItemEvent.SELECTED)
{
final String setname = (String) setName.getSelectedItem();
- if (Cache.log.isDebugEnabled())
- {
- Cache.log.debug("Item state changed for " + setname
- + " (handling ? " + !settingDialog + ")");
- }
+ System.out.println("Item state changed for " + setname
+ + " (handling ? " + !settingDialog + ")");
if (settingDialog)
{
// ignore event
}
- private void _renameExistingPreset(String oldName, String curSetName2)
- {
- paramStore.updatePreset(oldName, curSetName2, setDescr.getText(),
- getJobParams());
- }
-
/**
* store current settings as given name. You should then reset gui.
*
*/
public class WsParamSetManager implements ParamManager
{
+ private static final String WS_PARAM_FILES = "WS_PARAM_FILES";
Hashtable<String, ParamDatastoreI> paramparsers = new Hashtable<>();
@Override
public WsParamSetI[] getParameterSet(String name, String serviceUrl,
boolean modifiable, boolean unmodifiable)
{
- String files = Cache.getProperty("WS_PARAM_FILES");
+ String files = Cache.getProperty(WS_PARAM_FILES);
if (files == null)
{
return null;
} catch (IOException e)
{
Cache.log.info("Failed to parse parameter file " + pfile
- + " (Check that all JALVIEW_WSPARAMFILES entries are valid!)",
+ + " (Check that all " + WS_PARAM_FILES
+ + " entries are valid!)",
e);
}
}
chooser.setDialogTitle(MessageManager
.getString("label.choose_filename_for_param_file"));
chooser.setToolTipText(MessageManager.getString("action.save"));
- int value = chooser.showSaveDialog(Desktop.instance);
+ int value = chooser.showSaveDialog(Desktop.getInstance());
if (value == JalviewFileChooser.APPROVE_OPTION)
{
outfile = chooser.getSelectedFile();
}
if (outfile != null)
{
- String paramFiles = jalview.bin.Cache.getDefault("WS_PARAM_FILES",
+ String paramFiles = jalview.bin.Cache.getDefault(WS_PARAM_FILES,
filename);
if (paramFiles.indexOf(filename) == -1)
{
}
paramFiles = paramFiles.concat(filename);
}
- Cache.setProperty("WS_PARAM_FILES", paramFiles);
+
+ Cache.setProperty(WS_PARAM_FILES, paramFiles);
WebServiceParameterSet paramxml = new WebServiceParameterSet();
{
return;
}
- String paramFiles = jalview.bin.Cache.getDefault("WS_PARAM_FILES", "");
+ String paramFiles = jalview.bin.Cache.getDefault(WS_PARAM_FILES, "");
if (paramFiles.indexOf(filename) > -1)
{
String nparamFiles = new String();
nparamFiles = nparamFiles.concat("|").concat(fl);
}
}
- jalview.bin.Cache.setProperty("WS_PARAM_FILES", nparamFiles);
+ jalview.bin.Cache.setProperty(WS_PARAM_FILES, nparamFiles);
}
try
File pfile = new File(filename);
if (pfile.exists() && pfile.canWrite())
{
- if (JvOptionPane.showConfirmDialog(Desktop.instance,
+ if (JvOptionPane.showConfirmDialog(Desktop.getInstance(),
"Delete the preset's file, too ?", "Delete User Preset ?",
JvOptionPane.OK_CANCEL_OPTION) == JvOptionPane.OK_OPTION)
{
*/
package jalview.gui;
+
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.net.URL;
+import java.util.ArrayList;
import java.util.List;
import java.util.Vector;
import javax.swing.JTextField;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableCellRenderer;
-
import jalview.bin.Cache;
import jalview.jbgui.GWsPreferences;
import jalview.util.MessageManager;
+import jalview.ws.WSDiscovererI;
import jalview.ws.jws2.Jws2Discoverer;
import jalview.ws.rest.RestServiceDescription;
private void initFromPreferences()
{
- wsUrls = Jws2Discoverer.getDiscoverer().getServiceUrls();
+ wsUrls = Jws2Discoverer.getInstance().getServiceUrls();
if (!wsUrls.isEmpty())
{
oldUrls = new Vector<String>(wsUrls);
int r = 0;
for (String url : wsUrls)
{
- int status = Jws2Discoverer.getDiscoverer().getServerStatusFor(url);
+ int status = Jws2Discoverer.getInstance().getServerStatusFor(url);
tdat[r][1] = Integer.valueOf(status);
tdat[r++][0] = url;
}
String t = new String("");
switch (((Integer) status).intValue())
{
- case 1:
+ case WSDiscovererI.STATUS_OK:
// cb.setSelected(true);
// cb.setBackground(
c = Color.green;
break;
- case 0:
+ case WSDiscovererI.STATUS_NO_SERVICES:
// cb.setSelected(true);
// cb.setBackground(
c = Color.lightGray;
break;
- case -1:
+ case WSDiscovererI.STATUS_INVALID:
// cb.setSelected(false);
// cb.setBackground(
c = Color.red;
break;
+ case WSDiscovererI.STATUS_UNKNOWN:
default:
// cb.setSelected(false);
// cb.setBackground(
private void updateServiceList()
{
- Jws2Discoverer.getDiscoverer().setServiceUrls(wsUrls);
+ Jws2Discoverer.getInstance().setServiceUrls(wsUrls);
}
private void updateRsbsServiceList()
boolean valid = false;
int resp = JvOptionPane.CANCEL_OPTION;
while (!valid && (resp = JvOptionPane.showInternalConfirmDialog(
- Desktop.desktop, panel, title,
+ Desktop.getDesktopPane(), panel, title,
JvOptionPane.OK_CANCEL_OPTION)) == JvOptionPane.OK_OPTION)
{
try
} catch (Exception e)
{
valid = false;
- JvOptionPane.showInternalMessageDialog(Desktop.desktop,
+ JvOptionPane.showInternalMessageDialog(Desktop.getDesktopPane(),
MessageManager.getString("label.invalid_url"));
}
}
if (valid && resp == JvOptionPane.OK_OPTION)
{
- int validate = JvOptionPane.showInternalConfirmDialog(Desktop.desktop,
+ int validate = JvOptionPane.showInternalConfirmDialog(Desktop.getDesktopPane(),
MessageManager.getString("info.validate_jabaws_server"),
MessageManager.getString("label.test_server"),
JvOptionPane.YES_NO_OPTION);
if (validate == JvOptionPane.OK_OPTION)
{
- if (Jws2Discoverer.testServiceUrl(foo))
+ if (Jws2Discoverer.getInstance().testServiceUrl(foo))
{
return foo.toString();
}
else
{
- int opt = JvOptionPane.showInternalOptionDialog(Desktop.desktop,
+ int opt = JvOptionPane.showInternalOptionDialog(Desktop.getDesktopPane(),
"The Server '" + foo.toString()
+ "' failed validation,\ndo you want to add it anyway? ",
"Server Validation Failed", JvOptionPane.YES_NO_OPTION,
}
else
{
- JvOptionPane.showInternalMessageDialog(Desktop.desktop,
+ JvOptionPane.showInternalMessageDialog(Desktop.getDesktopPane(),
MessageManager.getString(
"warn.server_didnt_pass_validation"));
}
if (lastrefresh != update)
{
lastrefresh = update;
- Desktop.instance.startServiceDiscovery(true); // wait around for all
+ Desktop.getInstance().startServiceDiscovery(true); // wait around for all
// threads to complete
updateList();
public void run()
{
long ct = System.currentTimeMillis();
- Desktop.instance.setProgressBar(MessageManager
+ Desktop.getInstance().setProgressBar(MessageManager
.getString("status.refreshing_web_service_menus"), ct);
if (lastrefresh != update)
{
lastrefresh = update;
- Desktop.instance.startServiceDiscovery(true);
+ Desktop.getInstance().startServiceDiscovery(true);
updateList();
}
- Desktop.instance.setProgressBar(null, ct);
+ Desktop.getInstance().setProgressBar(null, ct);
}
}).start();
/**
* state counters for ensuring that updates only happen if config has changed.
*/
- protected long update = 0;
-
- private long lastrefresh = 0;
+ private long update = 0, lastrefresh = 0;
/*
* (non-Javadoc)
@Override
protected void resetWs_actionPerformed(ActionEvent e)
{
- Jws2Discoverer.getDiscoverer().setServiceUrls(null);
- List<String> nwsUrls = Jws2Discoverer.getDiscoverer().getServiceUrls();
+ Jws2Discoverer.getInstance().setServiceUrls(null);
+ List<String> nwsUrls = Jws2Discoverer.getInstance().getServiceUrls();
if (!wsUrls.equals(nwsUrls))
{
update++;
--- /dev/null
+package jalview.hmmer;
+
+import jalview.analysis.AlignmentSorter;
+import jalview.datamodel.Alignment;
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.AlignmentOrder;
+import jalview.datamodel.AlignmentView;
+import jalview.datamodel.HiddenColumns;
+import jalview.datamodel.HiddenMarkovModel;
+import jalview.datamodel.SequenceI;
+import jalview.gui.AlignFrame;
+import jalview.gui.Desktop;
+import jalview.gui.JvOptionPane;
+import jalview.gui.SplitFrame;
+import jalview.io.DataSourceType;
+import jalview.io.StockholmFile;
+import jalview.util.FileUtils;
+import jalview.util.MessageManager;
+import jalview.viewmodel.seqfeatures.FeatureRendererSettings;
+import jalview.ws.params.ArgumentI;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Hashtable;
+import java.util.List;
+
+import javax.swing.JInternalFrame;
+
+public class HMMAlign extends HmmerCommand
+{
+ static final String HMMALIGN = "hmmalign";
+
+ private final AlignmentI dataset;
+
+ /**
+ * Constructor for the HMMAlignThread
+ *
+ * @param af
+ * @param args
+ */
+ public HMMAlign(AlignFrame af, List<ArgumentI> args)
+ {
+ super(af, args);
+ if (alignment.getDataset() != null)
+ {
+ dataset = alignment.getDataset();
+ }
+ else
+ {
+ dataset = null;
+ }
+ }
+
+ /**
+ * Runs the HMMAlignThread: the data on the alignment or group is exported,
+ * then the command is executed in the command line and then the data is
+ * imported and displayed in a new frame (if true). The command is executed
+ * for each segment of the alignment. Call this method directly to execute
+ * synchronously, or via start() in a new Thread for asynchronously.
+ */
+ @Override
+ public void run()
+ {
+ HiddenMarkovModel hmm = getHmmProfile();
+
+ long msgId = System.currentTimeMillis();
+ af.setProgressBar(MessageManager.getString("status.running_hmmalign"),
+ msgId);
+
+ // ensure alignments are the same length
+ alignment.padGaps();
+
+ AlignmentView msa = af.gatherSequencesForAlignment();
+ SequenceI[][] subAlignments = msa.getVisibleContigs(alignment.getGapCharacter());
+
+ List<AlignmentOrder> allOrders = new ArrayList<>();
+
+ SequenceI[][] allResults = new SequenceI[subAlignments.length][];
+ int job = 0;
+ for (SequenceI[] seqs : subAlignments)
+ {
+ Hashtable sequencesHash = stashSequences(seqs);
+ try
+ {
+ File modelFile = FileUtils.createTempFile("hmm", ".hmm");
+ File alignmentFile = FileUtils.createTempFile("output", ".sto");
+ File resultFile = FileUtils.createTempFile("input", ".sto");
+
+ exportStockholm(seqs, alignmentFile.getAbsoluteFile(), null);
+ exportHmm(hmm, modelFile.getAbsoluteFile());
+
+ boolean ran = runCommand(modelFile, alignmentFile, resultFile);
+ if (!ran)
+ {
+ JvOptionPane.showInternalMessageDialog(af, MessageManager
+ .formatMessage("warn.command_failed", "hmmalign"));
+ return;
+ }
+
+ SequenceI[] result = importData(resultFile, allOrders);
+ recoverSequences(sequencesHash, result);
+ allResults[job] = result;
+ modelFile.delete();
+ alignmentFile.delete();
+ resultFile.delete();
+ } catch (IOException e)
+ {
+ e.printStackTrace();
+ }
+ job++;
+ }
+
+ String title = "hmmalign to " + hmm.getConsensusSequence().getName();
+ displayResults(allResults, allOrders, msa, title);
+
+ af.setProgressBar("", msgId);
+ }
+
+ /**
+ * Executes the hmmalign command and returns true if successful, false if an
+ * error is detected
+ *
+ * @param modelFile
+ * the HMM to align to
+ * @param alignmentFile
+ * the sequences to align
+ * @param resultFile
+ * the file to hold the results of alignment
+ * @return
+ * @throws IOException
+ */
+ private boolean runCommand(File modelFile, File alignmentFile,
+ File resultFile) throws IOException
+ {
+ String command = getCommandPath(HMMALIGN);
+ if (command == null)
+ {
+ return false;
+ }
+ List<String> args = new ArrayList<>();
+ args.add(command);
+
+ if (params != null)
+ {
+ for (ArgumentI arg : params)
+ {
+ String name = arg.getName();
+ if (MessageManager.getString("label.trim_termini").equals(name))
+ {
+ args.add(ARG_TRIM);
+ }
+ }
+ }
+ args.add("-o");
+ args.add(getFilePath(resultFile, true));
+ args.add(getFilePath(modelFile, true));
+ args.add(getFilePath(alignmentFile, true));
+
+ return runCommand(args);
+ }
+
+ /**
+ * Imports the data from the file holding the output of hmmalign
+ *
+ * @param resultFile
+ * @param allOrders
+ * a list of alignment orders to add to
+ *
+ * @return
+ * @throws IOException
+ */
+ private SequenceI[] importData(File resultFile,
+ List<AlignmentOrder> allOrders) throws IOException
+ {
+ StockholmFile file = new StockholmFile(getFilePath(resultFile, false),
+ DataSourceType.FILE);
+ SequenceI[] result = file.getSeqsAsArray();
+ AlignmentOrder msaorder = new AlignmentOrder(result);
+ AlignmentSorter.recoverOrder(result);
+ allOrders.add(msaorder);
+
+ return result;
+ }
+
+ /**
+ * Displays the results of all 'jobs' in a new frame
+ *
+ * @param allResults
+ *
+ * @param allOrders
+ * @param msa
+ * @param title
+ */
+ private void displayResults(SequenceI[][] allResults,
+ List<AlignmentOrder> allOrders, AlignmentView msa, String title)
+ {
+ AlignmentOrder[] arrOrders = allOrders
+ .toArray(new AlignmentOrder[allOrders.size()]);
+ Object[] newview = msa.getUpdatedView(allResults, arrOrders,
+ alignment.getGapCharacter());
+ SequenceI[] seqs = (SequenceI[]) newview[0];
+ HiddenColumns hidden = (HiddenColumns) newview[1];
+ Alignment al = new Alignment(seqs);
+ al.setProperty("Alignment Program", "hmmalign");
+ if (dataset != null)
+ {
+ al.setDataset(dataset);
+ }
+
+ displayInNewFrame(al, allOrders, hidden, title);
+ }
+
+ /**
+ * Displays the results in a new frame
+ *
+ * @param al
+ * The alignment containing the results
+ * @param alorders
+ * The order of the sequences in the alignment on which the jobs were
+ * run
+ * @param hidden
+ * Hidden columns in the previous alignment
+ * @param title
+ */
+ private void displayInNewFrame(AlignmentI al,
+ List<AlignmentOrder> alorders, HiddenColumns hidden, String title)
+ {
+ AlignFrame alignFrame = new AlignFrame(al, hidden, AlignFrame.DEFAULT_WIDTH,
+ AlignFrame.DEFAULT_HEIGHT);
+ alignFrame.setTitle(title);
+
+ FeatureRendererSettings featureSettings = af.getFeatureRenderer()
+ .getSettings();
+ // initialise with same renderer settings as in parent alignframe.
+ alignFrame.getFeatureRenderer().transferSettings(featureSettings);
+
+ addSortByMenuItems(alignFrame, alorders);
+
+ // TODO: refactor retrieve and show as new splitFrame as Desktop method
+
+ /*
+ * If alignment was requested from one half of a SplitFrame, show in a
+ * SplitFrame with the other pane similarly aligned.
+ */
+ AlignFrame requestedBy = this.af;
+ if (requestedBy != null && requestedBy.getSplitViewContainer() != null
+ && requestedBy.getSplitViewContainer()
+ .getComplement(requestedBy) != null)
+ {
+ AlignmentI complement = requestedBy.getSplitViewContainer()
+ .getComplement(requestedBy);
+ String complementTitle = requestedBy.getSplitViewContainer()
+ .getComplementTitle(requestedBy);
+ // 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)
+ {
+ alignFrame.setTitle(this.af.getTitle());
+ AlignFrame af2 = new AlignFrame(copyComplement,
+ AlignFrame.DEFAULT_WIDTH, AlignFrame.DEFAULT_HEIGHT);
+ af2.setTitle(complementTitle);
+ String linkedTitle = MessageManager
+ .getString("label.linked_view_title");
+ JInternalFrame splitFrame = new SplitFrame(
+ al.isNucleotide() ? alignFrame : af2, al.isNucleotide() ? af2 : alignFrame);
+ Desktop.addInternalFrame(splitFrame, linkedTitle, -1, -1);
+ return;
+ }
+ }
+
+ /*
+ * Not from SplitFrame, or failed to created a complementary alignment
+ */
+ Desktop.addInternalFrame(alignFrame, alignFrame.getTitle(), AlignFrame.DEFAULT_WIDTH,
+ AlignFrame.DEFAULT_HEIGHT);
+ }
+
+ /**
+ * Adds sort order options to the AlignFrame menus
+ *
+ * @param alignFrame
+ * @param alorders
+ */
+ protected void addSortByMenuItems(AlignFrame alignFrame,
+ List<AlignmentOrder> alorders)
+ {
+ // update orders
+ if (alorders.size() == 1)
+ {
+ alignFrame.addSortByOrderMenuItem("hmmalign" + " Ordering", alorders.get(0));
+ }
+ else
+ {
+ // construct a non-redundant ordering set
+ List<String> names = new ArrayList<>();
+ for (int i = 0, l = alorders.size(); i < l; i++)
+ {
+ String orderName = " Region " + i;
+ int j = i + 1;
+
+ while (j < l)
+ {
+ if (alorders.get(i).equals(alorders.get(j)))
+ {
+ alorders.remove(j);
+ l--;
+ orderName += "," + j;
+ }
+ else
+ {
+ j++;
+ }
+ }
+
+ if (i == 0 && j == 1)
+ {
+ names.add("");
+ }
+ else
+ {
+ names.add(orderName);
+ }
+ }
+ for (int i = 0, l = alorders.size(); i < l; i++)
+ {
+ alignFrame.addSortByOrderMenuItem("hmmalign" + (names.get(i)) + " Ordering",
+ alorders.get(i));
+ }
+ }
+ }
+}
--- /dev/null
+package jalview.hmmer;
+
+import jalview.api.AlignViewportI;
+import jalview.bin.Cache;
+import jalview.datamodel.Alignment;
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.AnnotatedCollectionI;
+import jalview.datamodel.ResidueCount;
+import jalview.datamodel.SequenceGroup;
+import jalview.datamodel.SequenceI;
+import jalview.gui.AlignFrame;
+import jalview.gui.JvOptionPane;
+import jalview.io.DataSourceType;
+import jalview.io.FileParse;
+import jalview.io.HMMFile;
+import jalview.util.FileUtils;
+import jalview.util.MessageManager;
+import jalview.ws.params.ArgumentI;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Hashtable;
+import java.util.List;
+
+/**
+ * A class that runs the hmmbuild command as a separate process.
+ *
+ * @author gmcarstairs
+ *
+ */
+public class HMMBuild extends HmmerCommand
+{
+ static final String ARG_AMINO = "--amino";
+
+ static final String ARG_DNA = "--dna";
+
+ static final String ARG_RNA = "--rna";
+
+ /**
+ * Constructor
+ *
+ * @param alignFrame
+ * @param args
+ */
+ public HMMBuild(AlignFrame alignFrame, List<ArgumentI> args)
+ {
+ super(alignFrame, args);
+ }
+
+ /**
+ * Builds a HMM from an alignment (and/or groups), then imports and adds it to
+ * the alignment (and/or groups). Call this method directly to execute
+ * synchronously, or via start() in a new Thread for asynchronously.
+ */
+ @Override
+ public void run()
+ {
+ if (params == null || params.isEmpty())
+ {
+ Cache.log.error("No parameters to HMMBuild!|");
+ return;
+ }
+
+ long msgID = System.currentTimeMillis();
+ af.setProgressBar(MessageManager.getString("status.running_hmmbuild"),
+ msgID);
+
+ AlignViewportI viewport = af.getViewport();
+ try
+ {
+ /*
+ * run hmmbuild for alignment and/or groups as selected
+ */
+ List<AnnotatedCollectionI> runBuildFor = parseParameters(viewport);
+
+ for (AnnotatedCollectionI grp : runBuildFor)
+ {
+ runHMMBuild(grp);
+ }
+ } finally
+ {
+ af.setProgressBar("", msgID);
+ viewport.alignmentChanged(af.alignPanel);
+ af.buildColourMenu(); // to enable HMMER colour schemes
+ }
+ }
+
+ /**
+ * Scans the parameters to determine whether to run hmmmbuild for the whole
+ * alignment or specified subgroup(s) or both
+ *
+ * @param viewport
+ * @return
+ */
+ protected List<AnnotatedCollectionI> parseParameters(
+ AlignViewportI viewport)
+ {
+ List<AnnotatedCollectionI> runBuildFor = new ArrayList<>();
+ boolean foundArg = false;
+
+ for (ArgumentI arg : params)
+ {
+ String name = arg.getName();
+ if (MessageManager.getString("label.hmmbuild_for").equals(name))
+ {
+ foundArg = true;
+ String value = arg.getValue();
+
+ if (MessageManager.getString("label.alignment").equals(value))
+ {
+ runBuildFor.add(viewport.getAlignmentView(false)
+ .getVisibleAlignment('-'));
+ }
+ else if (MessageManager.getString("label.groups_and_alignment")
+ .equals(value))
+ {
+ runBuildFor.add(viewport.getAlignmentView(false)
+ .getVisibleAlignment('-'));
+ runBuildFor.addAll(viewport.getAlignment().getGroups());
+ }
+ else if (MessageManager.getString("label.groups").equals(value))
+ {
+ runBuildFor.addAll(viewport.getAlignment().getGroups());
+ }
+ else if (MessageManager.getString("label.selected_group")
+ .equals(value))
+ {
+ runBuildFor.add(viewport.getSelectionGroup());
+ }
+ }
+ else if (MessageManager.getString("label.use_reference")
+ .equals(name))
+ {
+ // todo disable this option if no RF annotation on alignment
+ if (!af.getViewport().hasReferenceAnnotation())
+ {
+ JvOptionPane.showInternalMessageDialog(af, MessageManager
+ .getString("warn.no_reference_annotation"));
+ // return;
+ }
+ }
+ }
+
+ /*
+ * default is to build for the whole alignment
+ */
+ if (!foundArg)
+ {
+ runBuildFor.add(alignment);
+ }
+
+ return runBuildFor;
+ }
+
+ /**
+ * Runs hmmbuild on the given sequences (alignment or group)
+ *
+ * @param grp
+ */
+ private void runHMMBuild(AnnotatedCollectionI ac)
+ {
+ File hmmFile = null;
+ File alignmentFile = null;
+ try
+ {
+ hmmFile = FileUtils.createTempFile("hmm", ".hmm");
+ alignmentFile = FileUtils.createTempFile("output", ".sto");
+
+ if (ac instanceof Alignment)
+ {
+ AlignmentI al = (Alignment) ac;
+ // todo pad gaps in an unaligned SequenceGroup as well?
+ if (!al.isAligned())
+ {
+ al.padGaps();
+ }
+ }
+
+ deleteHmmSequences(ac);
+
+ List<SequenceI> copy = new ArrayList<>();
+ if (ac instanceof Alignment)
+ {
+ copy.addAll(ac.getSequences());
+ }
+ else
+ {
+ SequenceI[] sel = ((SequenceGroup) ac)
+ .getSelectionAsNewSequences((AlignmentI) ac.getContext());
+ for (SequenceI seq : sel)
+ {
+ if (seq != null)
+ {
+ copy.add(seq);
+ }
+ }
+ }
+ // TODO rather than copy alignment data we should anonymize in situ -
+ // export/File import could use anonymization hash to reinstate references
+ // at import level ?
+
+ SequenceI[] copyArray = copy.toArray(new SequenceI[copy.size()]);
+ Hashtable sequencesHash = stashSequences(copyArray);
+
+ exportStockholm(copyArray, alignmentFile, ac);
+
+ recoverSequences(sequencesHash, copy.toArray(new SequenceI[] {}));
+
+ boolean ran = runCommand(alignmentFile, hmmFile, ac);
+ if (!ran)
+ {
+ JvOptionPane.showInternalMessageDialog(af, MessageManager
+ .formatMessage("warn.command_failed", "hmmbuild"));
+ return;
+ }
+ importData(hmmFile, ac);
+ } catch (Exception e)
+ {
+ e.printStackTrace();
+ } finally
+ {
+ if (hmmFile != null)
+ {
+ hmmFile.delete();
+ }
+ if (alignmentFile != null)
+ {
+ alignmentFile.delete();
+ }
+ }
+ }
+
+ /**
+ * Constructs and executes the hmmbuild command as a separate process
+ *
+ * @param sequencesFile
+ * the alignment from which the HMM is built
+ * @param hmmFile
+ * the output file to which the HMM is written
+ * @param group
+ * alignment or group for which the hmm is generated
+ *
+ * @return
+ * @throws IOException
+ */
+ private boolean runCommand(File sequencesFile, File hmmFile,
+ AnnotatedCollectionI group) throws IOException
+ {
+ String cmd = getCommandPath(HMMBUILD);
+ if (cmd == null)
+ {
+ return false; // executable not found
+ }
+ List<String> args = new ArrayList<>();
+ args.add(cmd);
+
+ /*
+ * HMM name (will be given to consensus sequence) is
+ * - as specified by an input parameter if set
+ * - else group name with _HMM appended (if for a group)
+ * - else align frame title with _HMM appended (if title is not too long)
+ * - else "Alignment_HMM"
+ */
+ String name = "";
+
+ if (params != null)
+ {
+ for (ArgumentI arg : params)
+ {
+ String argName = arg.getName();
+ switch (argName)
+ {
+ case "HMM Name":
+ name = arg.getValue().trim();
+ break;
+ case "Use Reference Annotation":
+ args.add("--hand");
+ break;
+ }
+ }
+ }
+
+ if (group instanceof SequenceGroup)
+ {
+ name = ((SequenceGroup) group).getName() + "_HMM";
+ }
+
+ if ("".equals(name))
+ {
+ if (af != null && af.getTitle().length() < 15)
+ {
+ name = af.getTitle();
+ }
+ else
+ {
+ name = "Alignment_HMM";
+ }
+ }
+
+ args.add("-n");
+ args.add(name.replace(' ', '_'));
+ if (!alignment.isNucleotide())
+ {
+ args.add(ARG_AMINO); // TODO check for rna
+ }
+ else
+ {
+ args.add(ARG_DNA);
+ }
+
+ args.add(getFilePath(hmmFile, true));
+ args.add(getFilePath(sequencesFile, true));
+
+ return runCommand(args);
+ }
+
+ /**
+ * Imports the .hmm file produced by hmmbuild, and inserts the HMM consensus
+ * sequence (with attached HMM profile) as the first sequence in the alignment
+ * or group for which it was generated
+ *
+ * @param hmmFile
+ * @param ac
+ * (optional) the group for which the hmm was generated
+ * @throws IOException
+ */
+ private void importData(File hmmFile, AnnotatedCollectionI ac)
+ throws IOException
+ {
+ if (hmmFile.length() == 0L)
+ {
+ Cache.log.error("Error: hmmbuild produced empty hmm file");
+ return;
+ }
+
+ HMMFile file = new HMMFile(
+ new FileParse(hmmFile.getAbsolutePath(), DataSourceType.FILE));
+ SequenceI hmmSeq = file.getHMM().getConsensusSequence();
+
+
+
+ ResidueCount counts = new ResidueCount(alignment.getSequences());
+ hmmSeq.getHMM().setBackgroundFrequencies(counts);
+
+ if (hmmSeq == null)
+ {
+ // hmmbuild failure not detected earlier
+ return;
+ }
+
+ if (ac instanceof SequenceGroup)
+ {
+ SequenceGroup grp = (SequenceGroup) ac;
+ char gapChar = alignment.getGapCharacter();
+ hmmSeq.insertCharAt(0, ac.getStartRes(), gapChar);
+ hmmSeq.insertCharAt(ac.getEndRes() + 1,
+ alignment.getWidth() - ac.getEndRes() - 1, gapChar);
+ SequenceI topSeq = grp.getSequencesInOrder(alignment)[0];
+ int topIndex = alignment.findIndex(topSeq);
+ alignment.insertSequenceAt(topIndex, hmmSeq);
+ ac.setSeqrep(hmmSeq);
+ grp.addSequence(hmmSeq, false);
+ }
+ else
+ {
+ alignment.insertSequenceAt(0, hmmSeq);
+ }
+ }
+}
--- /dev/null
+package jalview.hmmer;
+
+import jalview.bin.Cache;
+import jalview.datamodel.SequenceI;
+import jalview.gui.Preferences;
+import jalview.util.MessageManager;
+import jalview.viewmodel.AlignmentViewport;
+import jalview.ws.params.ArgumentI;
+import jalview.ws.params.ParamDatastoreI;
+import jalview.ws.params.WsParamSetI;
+import jalview.ws.params.simple.BooleanOption;
+import jalview.ws.params.simple.DoubleParameter;
+import jalview.ws.params.simple.FileParameter;
+import jalview.ws.params.simple.IntegerParameter;
+import jalview.ws.params.simple.LogarithmicParameter;
+import jalview.ws.params.simple.Option;
+import jalview.ws.params.simple.RadioChoiceParameter;
+import jalview.ws.params.simple.StringParameter;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Scanner;
+
+public final class HMMERParamStore implements ParamDatastoreI
+{
+ private static final String HMMBUILD = "hmmbuild";
+
+ private static final String HMMALIGN = "hmmalign";
+
+ private static final String HMMSEARCH = "hmmsearch";
+
+ private static final String JACKHMMER = "jackhmmer";
+
+ private String name;
+
+ private List<WsParamSetI> presets = new ArrayList<>();
+
+ private AlignmentViewport viewport;
+
+ private HMMERParamStore(String nam, AlignmentViewport av)
+ {
+ this.viewport = av;
+ this.name = nam;
+ }
+
+ public static HMMERParamStore forBuild(AlignmentViewport viewport)
+ {
+ return new HMMERParamStore(HMMBUILD, viewport);
+ }
+
+ public static HMMERParamStore forAlign(AlignmentViewport viewport)
+ {
+ return new HMMERParamStore(HMMALIGN, viewport);
+ }
+
+ public static HMMERParamStore forSearch(AlignmentViewport viewport)
+ {
+ return new HMMERParamStore(HMMSEARCH, viewport);
+ }
+
+ public static HMMERParamStore forJackhmmer(AlignmentViewport viewport)
+ {
+ return new HMMERParamStore(JACKHMMER, viewport);
+ }
+
+ @Override
+ public List<WsParamSetI> getPresets()
+ {
+ return presets;
+ }
+
+ @Override
+ public WsParamSetI getPreset(String nam)
+ {
+ return null;
+ }
+
+ @Override
+ public List<ArgumentI> getServiceParameters()
+ {
+ List<ArgumentI> args = new ArrayList<>();
+ switch (name)
+ {
+ case HMMSEARCH:
+ getHMMSearchParams(args);
+ break;
+ case HMMALIGN:
+ getHMMAlignParams(args);
+ break;
+ case HMMBUILD:
+ getHMMBuildParams(args);
+ break;
+ case JACKHMMER:
+ getJackhmmerParams(args);
+ default:
+ }
+
+ return args;
+ }
+
+ /**
+ * Answers default parameters for hmmsearch, taking into account any
+ * configured as user preferences
+ *
+ * @param args
+ */
+ private void getHMMSearchParams(List<ArgumentI> args)
+ {
+ /*
+ * 'Options'
+ */
+ args.add(new BooleanOption(
+ MessageManager.getString(HMMSearch.AUTO_ALIGN_SEQS_KEY),
+ MessageManager.getString("label.auto_align_seqs_desc"), false,
+ false, false, null));
+ args.add(new BooleanOption(
+ MessageManager.getString(HMMSearch.USE_ACCESSIONS_KEY),
+ MessageManager.getString("label.use_accessions_desc"), false,
+ false, true, null));
+ args.add(new BooleanOption(
+ MessageManager.getString(HMMSearch.TRIM_TERMINI_KEY),
+ MessageManager.getString("label.trim_termini_desc"), false,
+ false, true, null));
+ args.add(new BooleanOption(
+ MessageManager.getString(HMMSearch.RETURN_N_NEW_SEQ),
+ MessageManager.getString("label.check_for_new_sequences_desc"),
+ false, false, false, null));
+
+ /*
+ * 'Parameters'
+ */
+ addChoiceOfHmm(args);
+
+ // addChoiceOfDatabase(args);
+
+ String thisAlignment = MessageManager
+ .getString(HMMSearch.THIS_ALIGNMENT_KEY);
+ String database = MessageManager.getString("label.database");
+ args.add(new FileParameter(database, "", false, "", ""));
+ args.add(new IntegerParameter(
+ MessageManager.getString(HMMSearch.NUMBER_OF_RESULTS_KEY),
+ MessageManager.getString("label.number_of_results_desc"), true,
+ 100, 0, 100000));
+ args.add(new RadioChoiceParameter(
+ MessageManager.getString(HMMSearch.REPORTING_CUTOFF_KEY), null,
+ Arrays.asList(MessageManager.getString(HMMSearch.CUTOFF_EVALUE),
+ MessageManager.getString(HMMSearch.CUTOFF_SCORE)),
+ MessageManager.getString(HMMSearch.CUTOFF_EVALUE)));
+ args.add(new LogarithmicParameter(
+ MessageManager.getString(HMMSearch.REPORTING_SEQ_EVALUE_KEY),
+ MessageManager.getString("label.reporting_seq_e_value_desc"),
+ false, 1D,
+ 1E-100, 10D));
+ args.add(new LogarithmicParameter(
+ MessageManager.getString(HMMSearch.REPORTING_DOM_EVALUE_KEY),
+ MessageManager.getString("label.reporting_dom_e_value_desc"),
+ false, 1D,
+ 1E-100, 10D));
+ args.add(
+ new DoubleParameter(
+ MessageManager
+ .getString(HMMSearch.REPORTING_SEQ_SCORE_KEY),
+ MessageManager.getString(
+ "label.reporting_seq_score_desc"),
+ false,
+ 0d, 0d, 1000d));
+ args.add(
+ new DoubleParameter(
+ MessageManager
+ .getString(HMMSearch.REPORTING_DOM_SCORE_KEY),
+ MessageManager.getString(
+ "label.reporting_dom_score_desc"),
+ false,
+ 0d, 0d, 1000d));
+ args.add(new RadioChoiceParameter(
+ MessageManager.getString(HMMSearch.INCLUSION_THRESHOLD_KEY),
+ null,
+ Arrays.asList(MessageManager.getString(HMMSearch.CUTOFF_EVALUE),
+ MessageManager.getString(HMMSearch.CUTOFF_SCORE)),
+ MessageManager.getString(HMMSearch.CUTOFF_EVALUE)));
+ args.add(new LogarithmicParameter(
+ MessageManager.getString(HMMSearch.INCLUSION_SEQ_EVALUE_KEY),
+ MessageManager.getString("label.inclusion_seq_e_value_desc"),
+ false, 1D,
+ 1E-100, 10D));
+ args.add(new LogarithmicParameter(
+ MessageManager.getString(HMMSearch.INCLUSION_DOM_EVALUE_KEY),
+ MessageManager.getString("label.inclusion_dom_e_value_desc"),
+ false, 1D,
+ 1E-100, 10D));
+ args.add(new DoubleParameter(
+ MessageManager.getString(HMMSearch.INCLUSION_SEQ_SCORE_KEY),
+ MessageManager.getString("label.inclusion_seq_score_desc"),
+ false, 0d, 0d,
+ 1000d));
+ args.add(new DoubleParameter(
+ MessageManager.getString(HMMSearch.INCLUSION_DOM_SCORE_KEY),
+ MessageManager.getString("label.inclusion_dom_score_desc"),
+ false, 0d, 0d,
+ 1000d));
+ }
+
+ /**
+ * Answers default parameters for jackhmmer, taking into account any configured
+ * as user preferences
+ *
+ * @param args
+ */
+ private void getJackhmmerParams(List<ArgumentI> args)
+ {
+
+ /*
+ * 'Parameters'
+ */
+ addChoiceOfSequence(args);
+
+ // addChoiceOfDatabase(args);
+
+ String database = MessageManager.getString("label.database");
+ args.add(new FileParameter(database, "", false, "", ""));
+ args.add(new IntegerParameter(
+ MessageManager.getString(HMMSearch.NUMBER_OF_ITERATIONS),
+ MessageManager.getString("label.number_of_iterations_desc"),
+ true, 5, 1, 20));
+ args.add(new RadioChoiceParameter(
+ MessageManager.getString(JackHMMER.REPORTING_CUTOFF_KEY), null,
+ Arrays.asList(MessageManager.getString(JackHMMER.CUTOFF_NONE),
+ MessageManager.getString(JackHMMER.CUTOFF_EVALUE),
+ MessageManager.getString(JackHMMER.CUTOFF_SCORE)),
+ MessageManager.getString(JackHMMER.CUTOFF_EVALUE)));
+ args.add(new LogarithmicParameter(
+ MessageManager.getString(JackHMMER.REPORTING_SEQ_EVALUE_KEY),
+ MessageManager.getString("label.reporting_seq_e_value_desc"),
+ false, 1D,
+ 1E-38, 10D));
+ args.add(new LogarithmicParameter(
+ MessageManager.getString(JackHMMER.REPORTING_DOM_EVALUE_KEY),
+ MessageManager.getString(
+ "label.reporting_dom_e_value_desc"),
+ false, 1D,
+ 1E-38, 10D));
+ args.add(new DoubleParameter(
+ MessageManager.getString(JackHMMER.REPORTING_SEQ_SCORE_KEY),
+ MessageManager.getString("label.reporting_seq_score_desc"),
+ false, 0d, 0d,
+ 1000d));
+ args.add(new DoubleParameter(
+ MessageManager.getString(JackHMMER.REPORTING_DOM_SCORE_KEY),
+ MessageManager.getString("label.reporting_dom_score_desc"),
+ false, 0d, 0d,
+ 1000d));
+ args.add(new RadioChoiceParameter(
+ MessageManager.getString(HMMSearch.INCLUSION_THRESHOLD_KEY),
+ null,
+ Arrays.asList(MessageManager.getString(HMMSearch.CUTOFF_EVALUE),
+ MessageManager.getString(HMMSearch.CUTOFF_SCORE)),
+ MessageManager.getString(HmmerCommand.CUTOFF_EVALUE)));
+ args.add(new LogarithmicParameter(
+ MessageManager.getString(HMMSearch.INCLUSION_SEQ_EVALUE_KEY),
+ MessageManager.getString("label.inclusion_seq_e_value_desc"),
+ false, 1D, 1E-100, 10D));
+ args.add(new LogarithmicParameter(
+ MessageManager.getString(HMMSearch.INCLUSION_DOM_EVALUE_KEY),
+ MessageManager.getString("label.inclusion_dom_e_value_desc"),
+ false, 1D, 1E-100, 10D));
+ args.add(new DoubleParameter(
+ MessageManager.getString(HMMSearch.INCLUSION_SEQ_SCORE_KEY),
+ MessageManager.getString("label.inclusion_seq_score_desc"),
+ false, 0d, 0d, 1000d));
+ args.add(new DoubleParameter(
+ MessageManager.getString(HMMSearch.INCLUSION_DOM_SCORE_KEY),
+ MessageManager.getString("label.inclusion_dom_score_desc"),
+ false, 0d, 0d, 1000d));
+ }
+
+ /**
+ * Constructs a choice parameter for database to search; always includes 'this
+ * alignment', and also includes any databases held under user preferences key
+ * "HMMSEARCH_DBS" as a comma-delimited list
+ *
+ * @param args
+ */
+ protected void addChoiceOfDatabase(List<ArgumentI> args)
+ {
+ String names = Cache.getProperty(Preferences.HMMSEARCH_DBS);
+ if (names == null || names.isEmpty())
+ {
+ return;
+ }
+
+ List<String> filePaths = new ArrayList<>();
+ List<String> fileNames = new ArrayList<>();
+
+ String thisAlignment = MessageManager.getString(HMMSearch.THIS_ALIGNMENT_KEY);
+ filePaths.add(thisAlignment);
+ fileNames.add(thisAlignment);
+
+ Scanner nameScanner = new Scanner(names);
+ nameScanner.useDelimiter(Preferences.COMMA);
+
+ while (nameScanner.hasNext())
+ {
+ String next = nameScanner.next();
+ if ("null".equals(next))
+ {
+ Cache.setProperty(Preferences.HMMSEARCH_DBS, "");
+ }
+ else
+ {
+ filePaths.add(next);
+ int pos = next.lastIndexOf(File.separator);
+ String fileName = next.substring(pos + 1);
+ fileNames.add(fileName);
+ }
+ }
+ nameScanner.close();
+ ArgumentI databasesOption = new StringParameter(
+ MessageManager.getString(HMMSearch.DATABASE_KEY),
+ MessageManager.getString("label.database_for_hmmsearch"), true,
+ thisAlignment,
+ thisAlignment,
+ filePaths, fileNames);
+ args.add(databasesOption);
+ }
+
+ /**
+ * Answers default parameters for hmmalign, taking into account any configured
+ * as user preferences
+ *
+ * @param args
+ */
+ private void getHMMAlignParams(List<ArgumentI> args)
+ {
+ addChoiceOfHmm(args);
+
+ boolean def = Cache.getDefault(Preferences.HMMALIGN_TRIM_TERMINI,
+ false);
+ args.add(new BooleanOption(
+ MessageManager.getString("label.trim_termini"),
+ MessageManager.getString("label.trim_termini_desc"),
+ false, false, def, null));
+ }
+
+ /**
+ * Adds an argument representing the choice of HMM sequences (profiles)
+ * against which to perform align or search, provided at least one is found
+ *
+ * @param args
+ */
+ protected void addChoiceOfHmm(List<ArgumentI> args)
+ {
+ List<SequenceI> hmms = viewport.getAlignment().getHmmSequences();
+ if (!hmms.isEmpty())
+ {
+ List<String> options = new ArrayList<>();
+ for (SequenceI hmmSeq : hmms)
+ {
+ options.add(hmmSeq.getName());
+ }
+ String defseq = options.get(0);
+ ArgumentI arg = new StringParameter(
+ MessageManager.getString("label.use_hmm"), null, true, defseq,
+ defseq, options, null);
+ args.add(arg);
+ }
+ }
+
+ /**
+ * Adds an argument representing the choice of sequence against which to perform
+ * jackhmmer
+ *
+ * @param args
+ */
+ protected void addChoiceOfSequence(List<ArgumentI> args)
+ {
+ List<SequenceI> sequences = viewport.getAlignment().getSequences();
+
+ List<String> options = new ArrayList<>();
+
+ for (SequenceI seq : sequences)
+ {
+ options.add(seq.getName());
+ }
+
+ String defseq = options.get(0);
+ ArgumentI arg = new StringParameter(
+ MessageManager.getString("label.use_sequence"), null, true,
+ defseq,
+ defseq, options, null);
+ args.add(arg);
+ }
+
+ /**
+ * Answers default parameters for hmmbuild, taking into account any configured
+ * as user preferences
+ *
+ * @param args
+ */
+ private void getHMMBuildParams(List<ArgumentI> args)
+ {
+ /*
+ * name to give the computed alignment HMM consensus sequence
+ * (Jalview constructs group HMM consensus sequence names)
+ */
+ String defValue = "Alignment_HMM";
+ StringParameter nameParam = new StringParameter(MessageManager.getString("label.hmm_name"),
+ MessageManager.getString("label.hmm_name_desc"), true, defValue,
+ defValue);
+ args.add(nameParam);
+
+ /*
+ * only enable Use Reference Annotation if RF is present
+ */
+ if (viewport.hasReferenceAnnotation())
+ {
+ args.add(new BooleanOption(
+ MessageManager.getString("label.use_reference"),
+ MessageManager.getString("label.use_reference_desc"), true,
+ true, true, null));
+ }
+
+ /*
+ * choice of whether to compute HMM for alignment and/or group(s)
+ * - only if there are any groups
+ */
+ if (!viewport.getAlignment().getGroups().isEmpty())
+ {
+ List<String> options = new ArrayList<>();
+ options.add(MessageManager.getString("label.alignment"));
+ options.add(MessageManager.getString("label.groups_and_alignment"));
+ options.add(MessageManager.getString("label.groups"));
+ options.add(MessageManager.getString("label.selected_group"));
+ args.add(new Option(MessageManager.getString("label.hmmbuild_for"),
+ MessageManager.getString("label.hmmbuild_for_desc"), true,
+ MessageManager.getString("label.alignment"),
+ MessageManager.getString("label.alignment"), options, null));
+ }
+ }
+
+ @Override
+ public boolean presetExists(String forName)
+ {
+ return false;
+ }
+
+ @Override
+ public void deletePreset(String forName)
+ {
+ }
+
+ @Override
+ public void storePreset(String presetName, String text,
+ List<ArgumentI> jobParams)
+ {
+ }
+
+ @Override
+ public void updatePreset(String oldName, String presetName, String text,
+ List<ArgumentI> jobParams)
+ {
+ }
+
+ @Override
+ public WsParamSetI parseServiceParameterFile(String forName,
+ String description, String[] serviceURL, String parameters)
+ throws IOException
+ {
+ return null;
+ }
+
+ @Override
+ public String generateServiceParameterFile(WsParamSetI pset)
+ throws IOException
+ {
+ return null;
+ }
+
+}
--- /dev/null
+package jalview.hmmer;
+
+import jalview.ws.params.ArgumentI;
+import jalview.ws.params.WsParamSetI;
+
+import java.util.List;
+
+public class HMMERPreset implements WsParamSetI
+{
+
+ @Override
+ public String getName()
+ {
+ return null;
+ }
+
+ @Override
+ public String getDescription()
+ {
+ return null;
+ }
+
+ @Override
+ public String[] getApplicableUrls()
+ {
+ return null;
+ }
+
+ @Override
+ public String getSourceFile()
+ {
+ return null;
+ }
+
+ @Override
+ public void setSourceFile(String newfile)
+ {
+ }
+
+ @Override
+ public boolean isModifiable()
+ {
+ return false;
+ }
+
+ @Override
+ public List<ArgumentI> getArguments()
+ {
+ return null;
+ }
+
+ @Override
+ public void setArguments(List<ArgumentI> args)
+ {
+ }
+
+}
--- /dev/null
+package jalview.hmmer;
+
+import jalview.bin.Cache;
+import jalview.datamodel.Alignment;
+import jalview.datamodel.AlignmentAnnotation;
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.Annotation;
+import jalview.datamodel.HiddenMarkovModel;
+import jalview.datamodel.SequenceI;
+import jalview.gui.AlignFrame;
+import jalview.gui.Desktop;
+import jalview.gui.JvOptionPane;
+import jalview.io.DataSourceType;
+import jalview.io.FileParse;
+import jalview.io.StockholmFile;
+import jalview.util.FileUtils;
+import jalview.util.MessageManager;
+import jalview.ws.params.ArgumentI;
+import jalview.ws.params.simple.BooleanOption;
+import jalview.ws.params.simple.Option;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import javax.swing.JOptionPane;
+
+public class HMMSearch extends Search
+{
+
+ boolean realign = false;
+
+ boolean trim = false;
+
+ boolean returnNoOfNewSeqs = false;
+
+ int seqsToReturn = Integer.MAX_VALUE;
+
+
+ /**
+ * Constructor for the HMMSearchThread
+ *
+ * @param af
+ */
+ public HMMSearch(AlignFrame af, List<ArgumentI> args)
+ {
+ super(af, args);
+ }
+
+ /**
+ * Runs the HMMSearchThread: the data on the alignment or group is exported,
+ * then the command is executed in the command line and then the data is
+ * imported and displayed in a new frame. Call this method directly to execute
+ * synchronously, or via start() in a new Thread for asynchronously.
+ */
+ @Override
+ public void run()
+ {
+ HiddenMarkovModel hmm = getHmmProfile();
+ if (hmm == null)
+ {
+ // shouldn't happen if we got this far
+ Cache.log.error("Error: no hmm for hmmsearch");
+ return;
+ }
+
+ SequenceI hmmSeq = hmm.getConsensusSequence();
+ long msgId = System.currentTimeMillis();
+ af.setProgressBar(MessageManager.getString("status.running_search"),
+ msgId);
+
+ try
+ {
+ File hmmFile = FileUtils.createTempFile("hmm", ".hmm");
+ File hitsAlignmentFile = FileUtils.createTempFile("hitAlignment",
+ ".sto");
+ File searchOutputFile = FileUtils.createTempFile("searchOutput",
+ ".sto");
+
+ exportHmm(hmm, hmmFile.getAbsoluteFile());
+
+ boolean ran = runCommand(searchOutputFile, hitsAlignmentFile, hmmFile);
+ if (!ran)
+ {
+ JvOptionPane.showInternalMessageDialog(af, MessageManager
+ .formatMessage("warn.command_failed", "hmmsearch"));
+ return;
+ }
+
+ importData(hmmSeq, hitsAlignmentFile, hmmFile, searchOutputFile);
+ // TODO make realignment of search results a step at this level
+ // and make it conditional on this.realign
+ } catch (IOException | InterruptedException e)
+ {
+ e.printStackTrace();
+ }
+ finally
+ {
+ af.setProgressBar("", msgId);
+ }
+ }
+
+ /**
+ * Executes an hmmsearch with the given hmm as input. The database to be
+ * searched is a local file as specified by the 'Database' parameter, or the
+ * current alignment (written to file) if none is specified.
+ *
+ * @param searchOutputFile
+ * @param hitsAlignmentFile
+ * @param hmmFile
+ *
+ * @return
+ * @throws IOException
+ */
+ private boolean runCommand(File searchOutputFile, File hitsAlignmentFile,
+ File hmmFile) throws IOException
+ {
+ String command = getCommandPath(HMMSEARCH);
+ if (command == null)
+ {
+ return false;
+ }
+
+ List<String> args = new ArrayList<>();
+ args.add(command);
+ buildArguments(args, searchOutputFile, hitsAlignmentFile, hmmFile);
+
+ return runCommand(args);
+ }
+
+
+ /**
+ * Imports the data from the temporary file to which the output of hmmsearch
+ * was directed. The results are optionally realigned using hmmalign.
+ *
+ * @param hmmSeq
+ */
+ private void importData(SequenceI hmmSeq, File inputAlignmentTemp,
+ File hmmTemp, File searchOutputFile)
+ throws IOException, InterruptedException
+ {
+ BufferedReader br = new BufferedReader(
+ new FileReader(inputAlignmentTemp));
+ try
+ {
+ if (br.readLine() == null)
+ {
+ JOptionPane.showMessageDialog(af,
+ MessageManager.getString("label.no_sequences_found"));
+ return;
+ }
+ StockholmFile file = new StockholmFile(new FileParse(
+ inputAlignmentTemp.getAbsolutePath(), DataSourceType.FILE));
+ seqs = file.getSeqsAsArray();
+
+ readDomainTable(searchOutputFile, false);
+
+ if (searchAlignment)
+ {
+ recoverSequences(sequencesHash, seqs);
+ }
+
+ // look for PP cons and ref seq in alignment only annotation
+ AlignmentAnnotation modelpos = null, ppcons = null;
+ for (AlignmentAnnotation aa : file.getAnnotations())
+ {
+ if (aa.sequenceRef == null)
+ {
+ if (aa.label.equals("Reference Positions")) // RF feature type in
+ // stockholm parser
+ {
+ modelpos = aa;
+ }
+ if (aa.label.equals("Posterior Probability"))
+ {
+ ppcons = aa;
+ }
+ }
+ }
+
+
+ int seqCount = Math.min(seqs.length, seqsToReturn);
+ SequenceI[] hmmAndSeqs = new SequenceI[seqCount + 1];
+ hmmSeq = hmmSeq.deriveSequence(); // otherwise all bad things happen
+ hmmAndSeqs[0] = hmmSeq;
+ System.arraycopy(seqs, 0, hmmAndSeqs, 1, seqCount);
+ if (modelpos != null)
+ {
+ // TODO need - get ungapped sequence method
+ hmmSeq.setSequence(
+ hmmSeq.getDatasetSequence().getSequenceAsString());
+ Annotation[] refpos = modelpos.annotations;
+ // insert gaps to match with refseq positions
+ int gc = 0, lcol = 0;
+ for (int c = 0; c < refpos.length; c++)
+ {
+ if (refpos[c] != null && ("x".equals(refpos[c].displayCharacter)))
+ {
+ if (gc > 0)
+ {
+ hmmSeq.insertCharAt(lcol + 1, gc, '-');
+ }
+ gc = 0;
+ lcol = c;
+ }
+ else
+ {
+ gc++;
+ }
+ }
+ }
+
+ if (realign)
+ {
+ realignResults(hmmAndSeqs);
+ }
+ else
+ {
+ AlignmentI al = new Alignment(hmmAndSeqs);
+ if (ppcons != null)
+ {
+ al.addAnnotation(ppcons);
+ }
+ if (modelpos != null)
+ {
+ al.addAnnotation(modelpos);
+ }
+ AlignFrame alignFrame = new AlignFrame(al, AlignFrame.DEFAULT_WIDTH,
+ AlignFrame.DEFAULT_HEIGHT);
+ String ttl = "hmmSearch of " + databaseName + " using "
+ + hmmSeq.getName();
+ Desktop.addInternalFrame(alignFrame, ttl, AlignFrame.DEFAULT_WIDTH,
+ AlignFrame.DEFAULT_HEIGHT);
+
+ if (returnNoOfNewSeqs)
+ {
+ int nNew = checkForNewSequences();
+ JvOptionPane.showMessageDialog(af.alignPanel, nNew + " "
+ + MessageManager.getString("label.new_returned"));
+ }
+
+ }
+
+
+ hmmTemp.delete();
+ inputAlignmentTemp.delete();
+ searchOutputFile.delete();
+ } finally
+ {
+ if (br != null)
+ {
+ br.close();
+ }
+ }
+ }
+
+ private int checkForNewSequences()
+ {
+ int nNew = seqs.length;
+
+ for (SequenceI resultSeq : seqs)
+ {
+ for (SequenceI aliSeq : alignment.getSequencesArray())
+ {
+ if (resultSeq.getName().equals(aliSeq.getName()))
+ {
+ nNew--;
+ break;
+ }
+ }
+ }
+
+ return nNew;
+
+ }
+
+ /**
+ * Realigns the given sequences using hmmalign, to the HMM profile sequence
+ * which is the first in the array, and opens the results in a new frame
+ *
+ * @param hmmAndSeqs
+ */
+ protected void realignResults(SequenceI[] hmmAndSeqs)
+ {
+ /*
+ * and align the search results to the HMM profile
+ */
+ AlignmentI al = new Alignment(hmmAndSeqs);
+ AlignFrame frame = new AlignFrame(al, 1, 1);
+ List<ArgumentI> alignArgs = new ArrayList<>();
+ String alignTo = hmmAndSeqs[0].getName();
+ List<String> options = Collections.singletonList(alignTo);
+ Option option = new Option(MessageManager.getString("label.use_hmm"),
+ "", true, alignTo, alignTo, options, null);
+ alignArgs.add(option);
+ if (trim)
+ {
+ alignArgs.add(new BooleanOption(
+ MessageManager.getString(TRIM_TERMINI_KEY),
+ MessageManager.getString("label.trim_termini_desc"), true,
+ true, true, null));
+ }
+ HmmerCommand hmmalign = new HMMAlign(frame, alignArgs);
+ hmmalign.run();
+
+ if (returnNoOfNewSeqs)
+ {
+ int nNew = checkForNewSequences();
+ JvOptionPane.showMessageDialog(frame.alignPanel,
+ nNew + " " + MessageManager.getString("label.new_returned"));
+ }
+ }
+
+}
--- /dev/null
+package jalview.hmmer;
+
+import jalview.analysis.SeqsetUtils;
+import jalview.bin.Cache;
+import jalview.datamodel.Alignment;
+import jalview.datamodel.AlignmentAnnotation;
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.AnnotatedCollectionI;
+import jalview.datamodel.Annotation;
+import jalview.datamodel.HiddenMarkovModel;
+import jalview.datamodel.SequenceGroup;
+import jalview.datamodel.SequenceI;
+import jalview.gui.AlignFrame;
+import jalview.gui.JvOptionPane;
+import jalview.gui.Preferences;
+import jalview.io.FastaFile;
+import jalview.io.HMMFile;
+import jalview.io.StockholmFile;
+import jalview.util.FileUtils;
+import jalview.util.MessageManager;
+import jalview.util.Platform;
+import jalview.ws.params.ArgumentI;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.PrintWriter;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.Hashtable;
+import java.util.List;
+
+/**
+ * Base class for hmmbuild, hmmalign and hmmsearch
+ *
+ * @author TZVanaalten
+ *
+ */
+public abstract class HmmerCommand implements Runnable
+{
+ public static final String HMMBUILD = "hmmbuild";
+
+ protected final AlignFrame af;
+
+ protected final AlignmentI alignment;
+
+ protected final List<ArgumentI> params;
+
+ /*
+ * constants for i18n lookup of passed parameter names
+ */
+ static final String DATABASE_KEY = "label.database";
+
+ static final String THIS_ALIGNMENT_KEY = "label.this_alignment";
+
+ static final String USE_ACCESSIONS_KEY = "label.use_accessions";
+
+ static final String AUTO_ALIGN_SEQS_KEY = "label.auto_align_seqs";
+
+ static final String NUMBER_OF_RESULTS_KEY = "label.number_of_results";
+
+ static final String NUMBER_OF_ITERATIONS = "label.number_of_iterations";
+
+ static final String TRIM_TERMINI_KEY = "label.trim_termini";
+
+ static final String RETURN_N_NEW_SEQ = "label.check_for_new_sequences";
+
+ static final String REPORTING_CUTOFF_KEY = "label.reporting_cutoff";
+
+ static final String CUTOFF_NONE = "label.default";
+
+ static final String CUTOFF_SCORE = "label.score";
+
+ static final String CUTOFF_EVALUE = "label.evalue";
+
+ static final String REPORTING_SEQ_EVALUE_KEY = "label.reporting_seq_evalue";
+
+ static final String REPORTING_DOM_EVALUE_KEY = "label.reporting_dom_evalue";
+
+ static final String REPORTING_SEQ_SCORE_KEY = "label.reporting_seq_score";
+
+ static final String REPORTING_DOM_SCORE_KEY = "label.reporting_dom_score";
+
+ static final String INCLUSION_SEQ_EVALUE_KEY = "label.inclusion_seq_evalue";
+
+ static final String INCLUSION_DOM_EVALUE_KEY = "label.inclusion_dom_evalue";
+
+ static final String INCLUSION_SEQ_SCORE_KEY = "label.inclusion_seq_score";
+
+ static final String INCLUSION_DOM_SCORE_KEY = "label.inclusion_dom_score";
+
+ static final String ARG_TRIM = "--trim";
+
+ static final String INCLUSION_THRESHOLD_KEY = "label.inclusion_threshold";
+
+ /**
+ * Constructor
+ *
+ * @param alignFrame
+ * @param args
+ */
+ public HmmerCommand(AlignFrame alignFrame, List<ArgumentI> args)
+ {
+ af = alignFrame;
+ alignment = af.getViewport().getAlignment();
+ params = args;
+ }
+
+ /**
+ * Answers true if preference HMMER_PATH is set, and its value is the path to
+ * a directory that contains an executable <code>hmmbuild</code> or
+ * <code>hmmbuild.exe</code>, else false
+ *
+ * @return
+ */
+ public static boolean isHmmerAvailable()
+ {
+ File exec = FileUtils.getExecutable(HMMBUILD,
+ Cache.getProperty(Preferences.HMMER_PATH));
+ return exec != null;
+ }
+
+ /**
+ * Uniquifies the sequences when exporting and stores their details in a
+ * hashtable
+ *
+ * @param seqs
+ */
+ protected Hashtable stashSequences(SequenceI[] seqs)
+ {
+ return SeqsetUtils.uniquify(seqs, true);
+ }
+
+ /**
+ * Restores the sequence data lost by uniquifying
+ *
+ * @param hashtable
+ * @param seqs
+ */
+ protected void recoverSequences(Hashtable hashtable, SequenceI[] seqs)
+ {
+ SeqsetUtils.deuniquify(hashtable, seqs);
+ }
+
+ /**
+ * Runs a command as a separate process and waits for it to complete. Answers
+ * true if the process return status is zero, else false.
+ *
+ * @param commands
+ * the executable command and any arguments to it
+ * @throws IOException
+ */
+ public boolean runCommand(List<String> commands)
+ throws IOException
+ {
+ List<String> args = Platform.isWindowsAndNotJS() ? wrapWithCygwin(commands)
+ : commands;
+
+ try
+ {
+ ProcessBuilder pb = new ProcessBuilder(args);
+ pb.redirectErrorStream(true); // merge syserr to sysout
+ if (Platform.isWindowsAndNotJS())
+ {
+ String path = pb.environment().get("Path");
+ path = jalview.bin.Cache.getProperty("CYGWIN_PATH") + ";" + path;
+ pb.environment().put("Path", path);
+ }
+ final Process p = pb.start();
+ new Thread(new Runnable()
+ {
+ @Override
+ public void run()
+ {
+ BufferedReader input = new BufferedReader(
+ new InputStreamReader(p.getInputStream()));
+ try
+ {
+ String line = input.readLine();
+ while (line != null)
+ {
+ System.out.println(line);
+ line = input.readLine();
+ }
+ } catch (IOException e)
+ {
+ e.printStackTrace();
+ }
+ }
+ }).start();
+
+ p.waitFor();
+ int exitValue = p.exitValue();
+ if (exitValue != 0)
+ {
+ Cache.log.error("Command failed, return code = " + exitValue);
+ Cache.log.error("Command/args were: " + args.toString());
+ }
+ return exitValue == 0; // 0 is success, by convention
+ } catch (Exception e)
+ {
+ e.printStackTrace();
+ return false;
+ }
+ }
+
+ /**
+ * Converts the given command to a Cygwin "bash" command wrapper. The hmmer
+ * command and any arguments to it are converted into a single parameter to the
+ * bash command.
+ *
+ * @param commands
+ */
+ protected List<String> wrapWithCygwin(List<String> commands)
+ {
+ File bash = FileUtils.getExecutable("bash",
+ Cache.getProperty(Preferences.CYGWIN_PATH));
+ if (bash == null)
+ {
+ Cache.log.error("Cygwin shell not found");
+ return commands;
+ }
+
+ List<String> wrapped = new ArrayList<>();
+ // wrapped.add("C:\Users\tva\run");
+ wrapped.add(bash.getAbsolutePath());
+ wrapped.add("-c");
+
+ /*
+ * combine hmmbuild/search/align and arguments to a single string
+ */
+ StringBuilder sb = new StringBuilder();
+ for (String cmd : commands)
+ {
+ sb.append(" ").append(cmd);
+ }
+ wrapped.add(sb.toString());
+
+ return wrapped;
+ }
+
+ /**
+ * Exports an alignment, and reference (RF) annotation if present, to the
+ * specified file, in Stockholm format, removing all HMM sequences
+ *
+ * @param seqs
+ * @param toFile
+ * @param annotated
+ * @throws IOException
+ */
+ public void exportStockholm(SequenceI[] seqs, File toFile,
+ AnnotatedCollectionI annotated)
+ throws IOException
+ {
+ if (seqs == null)
+ {
+ return;
+ }
+ AlignmentI newAl = new Alignment(seqs);
+
+ if (!newAl.isAligned())
+ {
+ newAl.padGaps();
+ }
+
+ if (toFile != null && annotated != null)
+ {
+ AlignmentAnnotation[] annots = annotated.getAlignmentAnnotation();
+ if (annots != null)
+ {
+ for (AlignmentAnnotation annot : annots)
+ {
+ if (annot.label.contains("Reference") || "RF".equals(annot.label))
+ {
+ AlignmentAnnotation newRF;
+ if (annot.annotations.length > newAl.getWidth())
+ {
+ Annotation[] rfAnnots = new Annotation[newAl.getWidth()];
+ System.arraycopy(annot.annotations, 0, rfAnnots, 0,
+ rfAnnots.length);
+ newRF = new AlignmentAnnotation("RF", "Reference Positions",
+ rfAnnots);
+ }
+ else
+ {
+ newRF = new AlignmentAnnotation(annot);
+ }
+ newAl.addAnnotation(newRF);
+ }
+ }
+ }
+ }
+
+ for (SequenceI seq : newAl.getSequencesArray())
+ {
+ if (seq.getAnnotation() != null)
+ {
+ for (AlignmentAnnotation ann : seq.getAnnotation())
+ {
+ seq.removeAlignmentAnnotation(ann);
+ }
+ }
+ }
+
+ StockholmFile file = new StockholmFile(newAl);
+ String output = file.print(seqs, false);
+ PrintWriter writer = new PrintWriter(toFile);
+ writer.println(output);
+ writer.close();
+ }
+
+ /**
+ * Answers the full path to the given hmmer executable, or null if file cannot
+ * be found or is not executable
+ *
+ * @param cmd
+ * command short name e.g. hmmalign
+ * @return
+ * @throws IOException
+ */
+ protected String getCommandPath(String cmd)
+ throws IOException
+ {
+ String binariesFolder = Cache.getProperty(Preferences.HMMER_PATH);
+ // ensure any symlink to the directory is resolved:
+ binariesFolder = Paths.get(binariesFolder).toRealPath().toString();
+ File file = FileUtils.getExecutable(cmd, binariesFolder);
+ if (file == null && af != null)
+ {
+ JvOptionPane.showInternalMessageDialog(af, MessageManager
+ .formatMessage("label.executable_not_found", cmd));
+ }
+
+ return file == null ? null : getFilePath(file, true);
+ }
+
+ /**
+ * Exports an HMM to the specified file
+ *
+ * @param hmm
+ * @param hmmFile
+ * @throws IOException
+ */
+ public void exportHmm(HiddenMarkovModel hmm, File hmmFile)
+ throws IOException
+ {
+ if (hmm != null)
+ {
+ HMMFile file = new HMMFile(hmm);
+ PrintWriter writer = new PrintWriter(hmmFile);
+ writer.print(file.print());
+ writer.close();
+ }
+ }
+
+ // TODO is needed?
+ /**
+ * Exports a sequence to the specified file
+ *
+ * @param hmm
+ * @param hmmFile
+ * @throws IOException
+ */
+ public void exportSequence(SequenceI seq, File seqFile) throws IOException
+ {
+ if (seq != null)
+ {
+ FastaFile file = new FastaFile();
+ PrintWriter writer = new PrintWriter(seqFile);
+ writer.print(file.print(new SequenceI[] { seq }, false));
+ writer.close();
+ }
+ }
+
+ /**
+ * Answers the HMM profile for the profile sequence the user selected (default
+ * is just the first HMM sequence in the alignment)
+ *
+ * @return
+ */
+ protected HiddenMarkovModel getHmmProfile()
+ {
+ String alignToParamName = MessageManager.getString("label.use_hmm");
+ for (ArgumentI arg : params)
+ {
+ String name = arg.getName();
+ if (name.equals(alignToParamName))
+ {
+ String seqName = arg.getValue();
+ SequenceI hmmSeq = alignment.findName(seqName);
+ if (hmmSeq.hasHMMProfile())
+ {
+ return hmmSeq.getHMM();
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Answers the query sequence the user selected (default is just the first
+ * sequence in the alignment)
+ *
+ * @return
+ */
+ protected SequenceI getSequence()
+ {
+ String alignToParamName = MessageManager
+ .getString("label.use_sequence");
+ for (ArgumentI arg : params)
+ {
+ String name = arg.getName();
+ if (name.equals(alignToParamName))
+ {
+ String seqName = arg.getValue();
+ SequenceI seq = alignment.findName(seqName);
+ return seq;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Answers an absolute path to the given file, in a format suitable for
+ * processing by a hmmer command. On a Windows platform, the native Windows file
+ * path is converted to Cygwin format, by replacing '\'with '/' and drive letter
+ * X with /cygdrive/x.
+ *
+ * @param resultFile
+ * @param isInCygwin
+ * True if file is to be read/written from within the Cygwin
+ * shell. Should be false for any imports.
+ * @return
+ */
+ protected String getFilePath(File resultFile, boolean isInCygwin)
+ {
+ String path = resultFile.getAbsolutePath();
+ if (Platform.isWindowsAndNotJS() && isInCygwin)
+ {
+ // the first backslash escapes '\' for the regular expression argument
+ path = path.replaceAll("\\" + File.separator, "/");
+ int colon = path.indexOf(':');
+ if (colon > 0)
+ {
+ String drive = path.substring(0, colon);
+ path = path.replaceAll(drive + ":", "/cygdrive/" + drive);
+ }
+ }
+
+ return path;
+ }
+
+ /**
+ * A helper method that deletes any HMM consensus sequence from the given
+ * collection, and from the parent alignment if <code>ac</code> is a subgroup
+ *
+ * @param ac
+ */
+ void deleteHmmSequences(AnnotatedCollectionI ac)
+ {
+ List<SequenceI> hmmSeqs = ac.getHmmSequences();
+ for (SequenceI hmmSeq : hmmSeqs)
+ {
+ if (ac instanceof SequenceGroup)
+ {
+ ((SequenceGroup) ac).deleteSequence(hmmSeq, false);
+ AnnotatedCollectionI context = ac.getContext();
+ if (context != null && context instanceof AlignmentI)
+ {
+ ((AlignmentI) context).deleteSequence(hmmSeq);
+ }
+ }
+ else
+ {
+ ((AlignmentI) ac).deleteSequence(hmmSeq);
+ }
+ }
+ }
+
+ /**
+ * Sets the names of any duplicates within the given sequences to include their
+ * respective lengths. Deletes any duplicates that have the same name after this
+ * step
+ *
+ * @param seqs
+ */
+ void renameDuplicates(AlignmentI al)
+ {
+
+ SequenceI[] seqs = al.getSequencesArray();
+ List<Boolean> wasRenamed = new ArrayList<>();
+
+ for (SequenceI seq : seqs)
+ {
+ wasRenamed.add(false);
+ }
+
+ for (int i = 0; i < seqs.length; i++)
+ {
+ for (int j = 0; j < seqs.length; j++)
+ {
+ if (seqs[i].getName().equals(seqs[j].getName()) && i != j
+ && !wasRenamed.get(j))
+ {
+
+ wasRenamed.set(i, true);
+ String range = "/" + seqs[j].getStart() + "-" + seqs[j].getEnd();
+ // setting sequence name to include range - to differentiate between
+ // sequences of the same name. Currently have to include the range twice
+ // because the range is removed (once) when setting the name
+ // TODO come up with a better way of doing this
+ seqs[j].setName(seqs[j].getName() + range + range);
+ }
+
+ }
+ if (wasRenamed.get(i))
+ {
+ String range = "/" + seqs[i].getStart() + "-" + seqs[i].getEnd();
+ seqs[i].setName(seqs[i].getName() + range + range);
+ }
+ }
+
+ for (int i = 0; i < seqs.length; i++)
+ {
+ for (int j = 0; j < seqs.length; j++)
+ {
+ if (seqs[i].getName().equals(seqs[j].getName()) && i != j)
+ {
+ al.deleteSequence(j);
+ }
+ }
+ }
+ }
+
+}
--- /dev/null
+package jalview.hmmer;
+
+import jalview.bin.Cache;
+import jalview.datamodel.Alignment;
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.SequenceI;
+import jalview.gui.AlignFrame;
+import jalview.gui.Desktop;
+import jalview.gui.JvOptionPane;
+import jalview.io.DataSourceType;
+import jalview.io.FileParse;
+import jalview.io.StockholmFile;
+import jalview.util.FileUtils;
+import jalview.util.MessageManager;
+import jalview.ws.params.ArgumentI;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.swing.JOptionPane;
+
+public class JackHMMER extends Search
+{
+
+ SequenceI seq = null;
+
+ /**
+ * Constructor for the JackhmmerThread
+ *
+ * @param af
+ */
+ public JackHMMER(AlignFrame af, List<ArgumentI> args)
+ {
+ super(af, args);
+ }
+
+ /**
+ * Runs the JackhmmerThread: the data on the alignment or group is exported,
+ * then the command is executed in the command line and then the data is
+ * imported and displayed in a new frame. Call this method directly to execute
+ * synchronously, or via start() in a new Thread for asynchronously.
+ */
+ @Override
+ public void run()
+ {
+ seq = getSequence();
+ if (seq == null)
+ {
+ // shouldn't happen if we got this far
+ Cache.log.error("Error: no sequence for jackhmmer");
+ return;
+ }
+
+ long msgId = System.currentTimeMillis();
+ af.setProgressBar(MessageManager.getString("status.running_search"),
+ msgId);
+
+ try
+ {
+ File seqFile = FileUtils.createTempFile("seq", ".sto");
+ File hitsAlignmentFile = FileUtils.createTempFile("hitAlignment",
+ ".sto");
+ File searchOutputFile = FileUtils.createTempFile("searchOutput",
+ ".txt");
+
+ exportStockholm(new SequenceI[] { seq }, seqFile.getAbsoluteFile(),
+ null);
+
+ boolean ran = runCommand(searchOutputFile, hitsAlignmentFile,
+ seqFile);
+ if (!ran)
+ {
+ JvOptionPane.showInternalMessageDialog(af, MessageManager
+ .formatMessage("warn.command_failed", "jackhmmer"));
+ return;
+ }
+
+ importData(hitsAlignmentFile, seqFile, searchOutputFile);
+ // TODO make realignment of search results a step at this level
+ // and make it conditional on this.realign
+ } catch (IOException | InterruptedException e)
+ {
+ e.printStackTrace();
+ } finally
+ {
+ af.setProgressBar("", msgId);
+ }
+ }
+
+ /**
+ * Executes an jackhmmer search with the given sequence as input. The database
+ * to be searched is a local file as specified by the 'Database' parameter, or
+ * the current alignment (written to file) if none is specified.
+ *
+ * @param searchOutputFile
+ * @param hitsAlignmentFile
+ * @param seqFile
+ *
+ * @return
+ * @throws IOException
+ */
+ private boolean runCommand(File searchOutputFile, File hitsAlignmentFile,
+ File seqFile) throws IOException
+ {
+ String command = getCommandPath(JACKHMMER);
+ if (command == null)
+ {
+ return false;
+ }
+
+ List<String> args = new ArrayList<>();
+ args.add(command);
+ buildArguments(args, searchOutputFile, hitsAlignmentFile, seqFile);
+
+ return runCommand(args);
+ }
+
+ /**
+ * Imports the data from the temporary file to which the output of jackhmmer was
+ * directed.
+ */
+ private void importData(File inputAlignmentTemp, File seqTemp,
+ File searchOutputFile) throws IOException, InterruptedException
+ {
+ BufferedReader br = new BufferedReader(
+ new FileReader(inputAlignmentTemp));
+ try
+ {
+ if (br.readLine() == null)
+ {
+ JOptionPane.showMessageDialog(af,
+ MessageManager.getString("label.no_sequences_found"));
+ return;
+ }
+ StockholmFile file = new StockholmFile(new FileParse(
+ inputAlignmentTemp.getAbsolutePath(), DataSourceType.FILE));
+ seqs = file.getSeqsAsArray();
+
+ readDomainTable(searchOutputFile, true);
+
+ if (searchAlignment)
+ {
+ recoverSequences(sequencesHash, seqs);
+ }
+
+
+
+ int seqCount = seqs.length;
+
+
+ AlignmentI al = new Alignment(seqs);
+
+ AlignFrame alignFrame = new AlignFrame(al, AlignFrame.DEFAULT_WIDTH,
+ AlignFrame.DEFAULT_HEIGHT);
+ String ttl = "jackhmmer search of " + databaseName + " using "
+ + seqs[0].getName();
+ Desktop.addInternalFrame(alignFrame, ttl, AlignFrame.DEFAULT_WIDTH,
+ AlignFrame.DEFAULT_HEIGHT);
+
+ seqTemp.delete();
+ inputAlignmentTemp.delete();
+ searchOutputFile.delete();
+ } finally
+ {
+ if (br != null)
+ {
+ br.close();
+ }
+ }
+ }
+
+
+
+
+}
--- /dev/null
+package jalview.hmmer;
+
+import jalview.datamodel.Alignment;
+import jalview.datamodel.AlignmentAnnotation;
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.SequenceI;
+import jalview.gui.AlignFrame;
+import jalview.util.FileUtils;
+import jalview.util.MessageManager;
+import jalview.ws.params.ArgumentI;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.util.Hashtable;
+import java.util.List;
+import java.util.Scanner;
+
+public abstract class Search extends HmmerCommand
+{
+
+ static final String JACKHMMER = "jackhmmer";
+
+ static final String HMMSEARCH = "hmmsearch";
+
+ boolean realign = false;
+
+ boolean trim = false;
+
+ SequenceI[] seqs;
+
+ String databaseName;
+
+ boolean searchAlignment = true;
+
+ Hashtable sequencesHash;
+
+ public Search(AlignFrame alignFrame, List<ArgumentI> args)
+ {
+ super(alignFrame, args);
+ }
+
+ @Override
+ public void run()
+ {
+ }
+
+ /*
+ void readOutputFile(File inputTableTemp) throws IOException
+ {
+ BufferedReader br = new BufferedReader(new FileReader(inputTableTemp));
+
+
+ String line = "";
+ while (!line.startsWith("//"))
+ {
+
+ while (!line.startsWith(">> ") && !line.startsWith("//"))
+ {
+ line = br.readLine();
+ }
+
+ if (line.startsWith("//"))
+ {
+ break;
+ }
+
+ Scanner scanner = new Scanner(line);
+ String name = scanner.next();
+ name = scanner.next();
+
+ br.readLine();
+ br.readLine();
+
+ List<SequenceI> domains = new ArrayList<>();
+
+ for (SequenceI seq : seqs)
+ {
+ if (seq.getName().contains(name))
+ {
+ domains.add(seq);
+ }
+ }
+
+ if (domains.contains(getSequence()))
+ {
+ domains.remove(getSequence());
+ }
+
+ if (domains.size() > 0)
+ {
+ readOutputTable(br, domains);
+ }
+
+ line = br.readLine();
+ }
+
+ }
+
+
+ /**
+ * Reads in the scores table output by jackhmmer and adds annotation to
+ * sequences for E-value and bit score
+ *
+ * @param inputTableTemp
+ * @throws IOException
+ */
+ /*
+ void readOutputTable(BufferedReader br, List<SequenceI> seqs) throws IOException
+ {
+ String line = br.readLine();
+
+ while (!"".equals(line) && line != null)
+ {
+ if (" ------ inclusion threshold ------".equals(line))
+ {
+ line = br.readLine();
+ continue;
+ }
+
+ Scanner scanner = new Scanner(line);
+ scanner.next();
+ scanner.next();
+ String score = scanner.next();
+
+ scanner.next();
+
+ String evalue = scanner.next();
+
+ scanner.next();
+ scanner.next();
+ scanner.next();
+ scanner.next();
+
+ int start = scanner.nextInt();
+ int end = scanner.nextInt();
+
+ SequenceI seq = null;
+ for (SequenceI sequence : seqs)
+ {
+ if (sequence.getStart() >= start && sequence.getEnd() <= end)
+ {
+ seq = sequence;
+ break;
+ }
+ }
+
+ if (seq != null)
+ {
+ addScoreAnnotations(evalue, score, seq);
+ }
+
+ scanner.close();
+ line = br.readLine();
+ }
+ }
+ */
+
+ void readDomainTable(File inputTableTemp, boolean includesQuery)
+ throws IOException
+ {
+ BufferedReader br = new BufferedReader(new FileReader(inputTableTemp));
+
+ String line = br.readLine();
+ br.readLine();
+ br.readLine();
+ line = br.readLine();
+
+ int index;
+
+ if (includesQuery)
+ {
+ index = 1;
+ }
+ else
+ {
+ index = 0;
+ }
+ while (!line.startsWith("#"))
+ {
+ if (line.contains("inclusion threshold"))
+ {
+ line = br.readLine();
+ continue;
+ }
+
+ Scanner scanner = new Scanner(line);
+ String name = scanner.next();
+
+ for (int i = 0; i < 10; i++)
+ {
+ scanner.next();
+ }
+
+ String evalue = scanner.next();
+ scanner.next();
+ String score = scanner.next();
+
+ addScoreAnnotations(evalue, score, seqs[index]);
+ index++;
+
+ scanner.close();
+ line = br.readLine();
+ }
+ br.close();
+ }
+
+
+
+
+ void addScoreAnnotations(String eValue, String bitScore, SequenceI seq)
+ {
+ String label = "Search Scores";
+ String description = "Full sequence bit score and E-Value";
+
+ try
+ {
+ AlignmentAnnotation annot = new AlignmentAnnotation(label,
+ description, null);
+
+ annot.label = label;
+ annot.description = description;
+
+ annot.setCalcId(JACKHMMER);
+
+ double dEValue = Double.parseDouble(eValue);
+ annot.setEValue(dEValue);
+
+ double dBitScore = Double.parseDouble(bitScore);
+ annot.setBitScore(dBitScore);
+
+ annot.setSequenceRef(seq);
+ seq.addAlignmentAnnotation(annot);
+
+ } catch (NumberFormatException e)
+ {
+ System.err.println("Error parsing " + label + " from " + eValue
+ + " & " + bitScore);
+ }
+ }
+
+ void buildArguments(List<String> args, File searchOutputFile,
+ File hitsAlignmentFile, File queryFile) throws IOException
+ {
+ args.add("--domtblout");
+ args.add(getFilePath(searchOutputFile, true));
+ args.add("-A");
+ args.add(getFilePath(hitsAlignmentFile, true));
+
+ File databaseFile = null;
+
+ boolean useEvalueCutoff = false;
+ boolean useScoreCutoff = false;
+ String seqReportingEvalueCutoff = null;
+ String domReportingEvalueCutoff = null;
+ String seqReportingScoreCutoff = null;
+ String domReportingScoreCutoff = null;
+ String seqInclusionEvalueCutoff = null;
+ String domInclusionEvalueCutoff = null;
+ String seqInclusionScoreCutoff = null;
+ String domInclusionScoreCutoff = null;
+ databaseName = "Alignment";
+
+ if (params != null)
+ {
+ for (ArgumentI arg : params)
+ {
+ String name = arg.getName();
+
+ if (MessageManager.getString(REPORTING_CUTOFF_KEY).equals(name))
+ {
+ if (MessageManager.getString(CUTOFF_EVALUE)
+ .equals(arg.getValue()))
+ {
+ useEvalueCutoff = true;
+ }
+ else if (MessageManager.getString(CUTOFF_SCORE)
+ .equals(arg.getValue()))
+ {
+ useScoreCutoff = true;
+ }
+ }
+ else if (MessageManager.getString(REPORTING_SEQ_EVALUE_KEY)
+ .equals(name))
+ {
+ seqReportingEvalueCutoff = arg.getValue();
+ }
+ else if (MessageManager.getString(REPORTING_SEQ_SCORE_KEY)
+ .equals(name))
+ {
+ seqReportingScoreCutoff = arg.getValue();
+ }
+ else if (MessageManager.getString(REPORTING_DOM_EVALUE_KEY)
+ .equals(name))
+ {
+ domReportingEvalueCutoff = arg.getValue();
+ }
+ else if (MessageManager.getString(REPORTING_DOM_SCORE_KEY)
+ .equals(name))
+ {
+ domReportingScoreCutoff = arg.getValue();
+ }
+ else if (MessageManager.getString(INCLUSION_SEQ_EVALUE_KEY)
+ .equals(name))
+ {
+ seqInclusionEvalueCutoff = arg.getValue();
+ }
+ else if (MessageManager.getString(INCLUSION_SEQ_SCORE_KEY)
+ .equals(name))
+ {
+ seqInclusionScoreCutoff = arg.getValue();
+ }
+ else if (MessageManager.getString(INCLUSION_DOM_EVALUE_KEY)
+ .equals(name))
+ {
+ domInclusionEvalueCutoff = arg.getValue();
+ }
+ else if (MessageManager.getString(INCLUSION_DOM_SCORE_KEY)
+ .equals(name))
+ {
+ domInclusionScoreCutoff = arg.getValue();
+ }
+ else if (MessageManager.getString(DATABASE_KEY).equals(name))
+ {
+ databaseFile = new File(arg.getValue());
+ if (!arg.getValue().isEmpty())
+ {
+ searchAlignment = false;
+ }
+ }
+ else if (MessageManager.getString(NUMBER_OF_ITERATIONS)
+ .equals(name))
+ {
+ if (!arg.getValue().isEmpty())
+ {
+ args.add("-N");
+ args.add(arg.getValue());
+ }
+ }
+ }
+ }
+
+ if (useEvalueCutoff)
+ {
+ args.add("-E");
+ args.add(seqReportingEvalueCutoff);
+ args.add("--domE");
+ args.add(domReportingEvalueCutoff);
+
+ args.add("--incE");
+ args.add(seqInclusionEvalueCutoff);
+ args.add("--incdomE");
+ args.add(domInclusionEvalueCutoff);
+ }
+ else if (useScoreCutoff)
+ {
+ args.add("-T");
+ args.add(seqReportingScoreCutoff);
+ args.add("--domT");
+ args.add(domReportingScoreCutoff);
+
+ args.add("--incT");
+ args.add(seqInclusionEvalueCutoff);
+ args.add("--incdomT");
+ args.add(domInclusionEvalueCutoff);
+ }
+
+ // if (!dbFound || MessageManager.getString(THIS_ALIGNMENT_KEY)
+ // .equals(dbPath))
+ if (searchAlignment)
+ {
+ /*
+ * no external database specified for search, so
+ * export current alignment as 'database' to search
+ */
+ databaseFile = FileUtils.createTempFile("database", ".sto");
+ AlignmentI al = af.getViewport().getAlignment();
+ AlignmentI copy = new Alignment(al);
+
+ deleteHmmSequences(copy);
+
+ if (searchAlignment)
+ {
+ sequencesHash = stashSequences(copy.getSequencesArray());
+ }
+
+ exportStockholm(copy.getSequencesArray(), databaseFile, null);
+ }
+
+ args.add(getFilePath(queryFile, true));
+ args.add(getFilePath(databaseFile, true));
+ }
+}
*/
package jalview.httpserver;
+import jalview.bin.ApplicationSingletonProvider;
+import jalview.bin.ApplicationSingletonProvider.ApplicationSingletonI;
import jalview.rest.RestHandler;
import java.net.BindException;
* @author gmcarstairs
* @see http://eclipse.org/jetty/documentation/current/embedding-jetty.html
*/
-public class HttpServer
+public class HttpServer implements ApplicationSingletonI
{
- /*
- * 'context root' - actually just prefixed to the path for each handler for
- * now - see registerHandler
- */
- private static final String JALVIEW_PATH = "jalview";
-
- /*
- * Singleton instance of this server
- */
- private static HttpServer instance;
-
- /*
- * The Http server
- */
- private Server server;
-
- /*
- * Registered handlers for context paths
- */
- private HandlerCollection contextHandlers;
-
- /*
- * Lookup of ContextHandler by its wrapped handler
- */
- Map<Handler, ContextHandler> myHandlers = new HashMap<Handler, ContextHandler>();
-
- /*
- * The context root for the server
- */
- private URI contextRoot;
-
/**
* Returns the singleton instance of this class.
*
{
synchronized (HttpServer.class)
{
- if (instance == null)
- {
- instance = new HttpServer();
- }
- return instance;
+ return (HttpServer) ApplicationSingletonProvider.getInstance(HttpServer.class);
}
}
-
+
/**
* Private constructor to enforce use of singleton
*
registerHandler(RestHandler.getInstance());
}
+
+ /*
+ * 'context root' - actually just prefixed to the path for each handler for
+ * now - see registerHandler
+ */
+ private static final String JALVIEW_PATH = "jalview";
+
+ /*
+ * The Http server
+ */
+ private Server server;
+
+ /*
+ * Registered handlers for context paths
+ */
+ private HandlerCollection contextHandlers;
+
+ /*
+ * Lookup of ContextHandler by its wrapped handler
+ */
+ Map<Handler, ContextHandler> myHandlers = new HashMap<Handler, ContextHandler>();
+
+ /*
+ * The context root for the server
+ */
+ private URI contextRoot;
+
+
/**
* Start the http server
*
*/
protected void initData()
{
- seqs = new Vector<SequenceI>();
- annotations = new Vector<AlignmentAnnotation>();
- seqGroups = new ArrayList<SequenceGroup>();
+ seqs = new Vector<>();
+ annotations = new Vector<>();
+ seqGroups = new ArrayList<>();
parseCalled = false;
}
@Override
public void setSeqs(SequenceI[] s)
{
- seqs = new Vector<SequenceI>();
+ seqs = new Vector<>();
for (int i = 0; i < s.length; i++)
{
{
if (newickStrings == null)
{
- newickStrings = new Vector<String[]>();
+ newickStrings = new Vector<>();
}
newickStrings.addElement(new String[] { treeName, newickString });
}
{
seqs.add(seq);
}
+
+ /**
+ * Used only for hmmer statistics, so should probably be removed at some
+ * point. TODO remove this
+ *
+ * @return
+ */
+ public Vector<AlignmentAnnotation> getAnnotations()
+ {
+ return annotations;
+ }
+
}
*/
package jalview.io;
-import jalview.api.AlignExportSettingsI;
-import jalview.api.AlignmentViewPanel;
import jalview.api.FeatureSettingsModelI;
import jalview.datamodel.AlignmentI;
import jalview.datamodel.SequenceI;
import jalview.api.AlignExportSettingsI;
import jalview.api.AlignmentViewPanel;
-import jalview.api.FeatureSettingsModelI;
-import jalview.datamodel.AlignmentI;
import jalview.datamodel.SequenceI;
public interface AlignmentFileWriterI
{
this.selectedFile = selectedFile;
- if (selectedFile != null)
- {
- this.inFile = selectedFile.getPath();
- }
- this.inFile = file;
+ inFile = (selectedFile == null ? file : selectedFile.getPath());
try
{
if (fileFormat.isStructureFile())
--- /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.datamodel.Sequence;
+import jalview.datamodel.SequenceFeature;
+import jalview.datamodel.SequenceI;
+import jalview.util.MessageManager;
+
+import java.io.BufferedReader;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.IOException;
+import java.util.Hashtable;
+import java.util.Map;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
+import fr.orsay.lri.varna.exceptions.ExceptionFileFormatOrSyntax;
+import fr.orsay.lri.varna.exceptions.ExceptionLoadingFailed;
+import fr.orsay.lri.varna.exceptions.ExceptionPermissionDenied;
+
+/**
+ * Preliminary reader for Bioinformatics Sequence Markup Language
+ * http://www.bsml.org
+ *
+ * @author hansonr
+ *
+ */
+public class BSMLFile extends AlignFile
+{
+
+ public BSMLFile()
+ {
+ super();
+
+ }
+
+ public BSMLFile(String inFile, DataSourceType type) throws IOException
+ {
+ super(inFile, type);
+
+ }
+
+ public BSMLFile(FileParse source) throws IOException
+ {
+ super(source);
+
+ }
+
+ public BufferedReader CreateReader() throws FileNotFoundException
+ {
+ FileReader fr = null;
+ fr = new FileReader(inFile);
+
+ BufferedReader r = new BufferedReader(fr);
+ return r;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see jalview.io.AlignFile#parse()
+ */
+ @Override
+ public void parse() throws IOException
+ {
+ try
+ {
+ _parse();
+ } catch (ExceptionPermissionDenied pdx)
+ {
+ errormessage = MessageManager.formatMessage(
+ "exception.BSML_couldnt_access_datasource", new String[]
+ { pdx.getMessage() });
+ throw new IOException(pdx);
+ } catch (ExceptionLoadingFailed lf)
+ {
+ errormessage = MessageManager.formatMessage(
+ "exception.BSML_couldnt_process_data", new String[]
+ { lf.getMessage() });
+ throw new IOException(lf);
+ } catch (ExceptionFileFormatOrSyntax iff)
+ {
+ errormessage = MessageManager
+ .formatMessage("exception.BSML_invalid_file", new String[]
+ { iff.getMessage() });
+ throw new IOException(iff);
+ } catch (Exception x)
+ {
+ error = true;
+ errormessage = MessageManager.formatMessage(
+ "exception.BSML_problem_parsing_data", new String[]
+ { x.getMessage() });
+ throw new IOException(errormessage, x);
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ public void _parse()
+ throws ExceptionPermissionDenied, ExceptionLoadingFailed,
+ ExceptionFileFormatOrSyntax, ParserConfigurationException,
+ SAXException, IOException
+ {
+
+ DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
+
+ dbf.setIgnoringElementContentWhitespace(true);
+ dbf.setIgnoringComments(true);
+ dbf.setValidating(true);
+ dbf.setCoalescing(true);
+ dbf.setNamespaceAware(true);
+ dbf.setFeature("http://xml.org/sax/features/namespaces", false);
+ dbf.setFeature("http://xml.org/sax/features/validation", false);
+ dbf.setFeature(
+ "http://apache.org/xml/features/nonvalidating/load-dtd-grammar",
+ false);
+ dbf.setFeature(
+ "http://apache.org/xml/features/nonvalidating/load-external-dtd",
+ false);
+
+ DocumentBuilder db = dbf.newDocumentBuilder();
+
+ Map<String, SequenceI> htSeq = new Hashtable<>();
+ InputSource is = new InputSource(getReader());
+ Document d = db.parse(is);
+ NodeList sequences = d.getElementsByTagName("Sequence-data");
+ int n = sequences.getLength();
+ SequenceI[] sqs = new SequenceI[n];
+ for (int i = 0; i < n; i++)
+ {
+ Element e = (Element) sequences.item(i);
+ String s = e.getTextContent();
+ String id = e.getAttribute("seq-name");
+ SequenceI seq = sqs[i] = new Sequence(id, s, 1, s.length());
+ htSeq.put(id, seq);
+ // ?? sqs[i].setEnd(sqs[i].findPosition(sqs[i].getLength()));
+ }
+
+ sequences = d.getElementsByTagName("Sequence");
+ n = sequences.getLength();
+ for (int i = 0; i < n; i++)
+ {
+ Element e = (Element) sequences.item(i);
+ String mol = e.getAttribute("molecule"); // dna or rna
+ if (!"dna".equals(mol))
+ {
+ System.err.println("BSML molecule=rna not implemented");
+ continue;
+ }
+ String title = e.getAttribute("title");
+ SequenceI seq = htSeq.get(title);
+ if (seq == null)
+ {
+ continue;
+ }
+ NodeList features = e.getElementsByTagName("Feature");
+ int featureCount = features.getLength();
+ for (int f = 0; f < featureCount; f++)
+ {
+ Element feature = (Element) features.item(f);
+ // <Feature class="GENE" title="CPXV-GER_1980_EP4-211">
+ // <Interval-loc complement="0" endpos="217104" startpos="216643"/>
+ // <Resource id="GENE-ID:119705"/>
+ // </Feature>
+ Element iloc = (Element) feature
+ .getElementsByTagName("Interval-loc").item(0);
+ String complement = iloc.getAttribute("complement");
+ if (!"0".equals(complement))
+ {
+ // Jalview cannot handle complement genes (running backward on the
+ // complementary strand);
+ continue;
+ }
+ String fclass = feature.getAttribute("class");
+ if (!"GENE".equals(fclass))
+ {
+ // just processing GENE features for now;
+ continue;
+ }
+ String ftitle = feature.getAttribute("title");
+ int start = Integer.parseInt(iloc.getAttribute("startpos"));
+ int end = Integer.parseInt(iloc.getAttribute("endpos"));
+ SequenceFeature sf = new SequenceFeature("GENE", ftitle, start, end,
+ null);
+ seq.addSequenceFeature(sf);
+ }
+ setSeqs(sqs);
+ }
+
+ }
+
+ @Override
+ public String print(SequenceI[] s, boolean jvSuffix)
+ {
+ return "not yet implemented";
+ }
+
+}
*/
package jalview.io;
+
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import jalview.gui.JvOptionPane;
import jalview.util.MessageManager;
import jalview.util.Platform;
-
/*
* BackupFiles used for manipulating (naming rolling/deleting) backup/version files when an alignment or project file is saved.
* User configurable options are:
private static final String newTempFileSuffix = "_newfile";
private static final String oldTempFileSuffix = "_oldfile_tobedeleted";
-
public BackupFiles(String filename)
{
this(new File(filename));
}
Cache.trace("BACKUPFILES rollBackupFiles starting");
-
String dir = "";
File dirFile;
try
if (reverseOrder)
{
// backup style numbering
+
Cache.trace("BACKUPFILES rolling files in reverse order");
int tempMax = noMax ? -1 : max;
tempMax = i;
}
}
-
File previousFile = null;
File fileToBeDeleted = null;
for (int n = tempMax; n > 0; n--)
{
File oldestTempFile = nextTempFile(fileToBeDeleted.getName(),
dirFile);
-
if (fileToBeDeletedLMT > replacementFileLMT)
{
String fileToBeDeletedLMTString = sdf
boolean delete = true;
Cache.trace("BACKUPFILES fileToBeDeleted: " + fileToBeDeleted);
-
boolean newer = false;
if (replacementFile != null)
{
ret = ret & moveFileToFile(file, new File(latestBackupFilename));
Cache.debug("BACKUPFILES moving " + file + " to " + latestBackupFilename
+ " was " + (ret ? "" : "NOT ") + "successful");
+
if (tidyUp)
{
Cache.debug("BACKUPFILES tidying up files");
MessageManager.getString("label.delete"),
MessageManager.getString("label.rename") };
+ // TODO enable JvOptionPane to behave appropriately when batch/headless
confirmButton = Platform.isHeadless() ? JvOptionPane.YES_OPTION
- : JvOptionPane.showOptionDialog(Desktop.desktop,
+ : JvOptionPane.showOptionDialog(Desktop.getDesktopPane(),
messageSB.toString(),
MessageManager.getString(
"label.backupfiles_confirm_delete"),
- // "Confirm delete"
JvOptionPane.YES_NO_OPTION,
JvOptionPane.WARNING_MESSAGE, null, options,
options[0]);
MessageManager.getString("label.keep") };
confirmButton = Platform.isHeadless() ? JvOptionPane.YES_OPTION
- : JvOptionPane.showOptionDialog(Desktop.desktop,
- messageSB.toString(),
- MessageManager.getString(
- "label.backupfiles_confirm_delete"),
- // "Confirm delete"
- JvOptionPane.YES_NO_OPTION,
- JvOptionPane.WARNING_MESSAGE, null, options,
- options[0]);
+ : JvOptionPane.showOptionDialog(Desktop.getDesktopPane(),
+ messageSB.toString(),
+ MessageManager.getString("label.backupfiles_confirm_delete"),
+ JvOptionPane.YES_NO_OPTION, JvOptionPane.WARNING_MESSAGE,
+ null, options, options[0]);
}
+
// return should be TRUE if file is to be deleted
return (confirmButton == JvOptionPane.YES_OPTION);
}
}
int confirmButton = Platform.isHeadless() ? JvOptionPane.YES_OPTION
- : JvOptionPane.showConfirmDialog(Desktop.desktop,
+ : JvOptionPane.showConfirmDialog(Desktop.getDesktopPane(),
messageSB.toString(),
MessageManager.getString(
"label.backupfiles_confirm_delete"),
.append(MessageManager.getString("label.continue_operation"));
int confirmButton = Platform.isHeadless() ? JvOptionPane.OK_OPTION
- : JvOptionPane.showConfirmDialog(Desktop.desktop,
+ : JvOptionPane.showConfirmDialog(Desktop.getDesktopPane(),
messageSB.toString(),
MessageManager.getString(
"label.backupfiles_confirm_save_file"),
import jalview.json.binding.biojs.BioJSReleasePojo;
import jalview.json.binding.biojs.BioJSRepositoryPojo;
import jalview.util.MessageManager;
+import jalview.util.Platform;
import java.io.BufferedInputStream;
import java.io.BufferedReader;
private static TreeMap<String, File> bioJsMSAVersions;
- public static final String DEFAULT_DIR = System.getProperty("user.home")
- + File.separatorChar + ".biojs_templates" + File.separatorChar;
+ public static final String DEFAULT_DIR = Platform.getUserPath(".biojs_templates/");
public static final String BJS_TEMPLATES_LOCAL_DIRECTORY = jalview.bin.Cache
.getDefault("biojs_template_directory", DEFAULT_DIR);
--- /dev/null
+package jalview.io;
+
+import jalview.bin.Jalview;
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.ResidueCount;
+import jalview.datamodel.SequenceI;
+import jalview.gui.AlignmentPanel;
+import jalview.gui.Desktop;
+import jalview.gui.JvOptionPane;
+import jalview.util.MessageManager;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.MalformedURLException;
+
+import javax.swing.JFileChooser;
+
+public class CountReader
+{
+ public static ResidueCount getBackgroundFrequencies(AlignmentPanel ap, SequenceI seq) throws MalformedURLException, IOException
+ {
+ JFileChooser bkgdFreqChooser = new JFileChooser();
+
+ bkgdFreqChooser.showOpenDialog(ap);
+
+ File file = bkgdFreqChooser.getSelectedFile();
+ if (file == null)
+ {
+ return null;
+ }
+
+ IdentifyFile identifier = new IdentifyFile();
+ FileFormatI format = null;
+ try
+ {
+ format = identifier.identify(file.getPath(), DataSourceType.FILE);
+ } catch (Exception e)
+ {
+
+ }
+
+ if (format == null)
+ {
+ if (!Jalview.isHeadlessMode())
+ {
+ JvOptionPane.showInternalMessageDialog(Desktop.getInstance(),
+ MessageManager.getString("label.couldnt_read_data") + " in "
+ + file + "\n"
+ + AppletFormatAdapter.getSupportedFormats(),
+ MessageManager.getString("label.couldnt_read_data"),
+ JvOptionPane.WARNING_MESSAGE);
+ }
+ }
+
+ FileParse parser = new FileParse(file.getPath(), DataSourceType.FILE);
+ AlignmentI al = new FormatAdapter().readFromFile(parser, format);
+ parser.close();
+
+ ResidueCount counts = new ResidueCount(al.getSequences());
+
+ return counts;
+ }
+}
{
return true;
}
+ },
+ HMMER3("HMMER3", "hmm", true, true)
+ {
+ @Override
+ public AlignmentFileReaderI getReader(FileParse source)
+ throws IOException
+ {
+ return new HMMFile(source);
+ }
+
+ @Override
+ public AlignmentFileWriterI getWriter(AlignmentI al)
+ {
+ return new HMMFile();
+ }
+ }, BSML("BSML", "bbb", true, false)
+ {
+ @Override
+ public AlignmentFileReaderI getReader(FileParse source)
+ throws IOException
+ {
+ return new BSMLFile(source);
+ }
+
+ @Override
+ public AlignmentFileWriterI getWriter(AlignmentI al)
+ {
+ return null;
+ }
};
+
private boolean writable;
private boolean readable;
import java.util.Map;
import java.util.Set;
+import jalview.bin.ApplicationSingletonProvider;
+import jalview.bin.ApplicationSingletonProvider.ApplicationSingletonI;
+
/**
* A singleton registry of alignment file formats known to Jalview. On startup,
* the 'built-in' formats are added (from the FileFormat enum). Additional
* @author gmcarstairs
*
*/
-public class FileFormats
+public class FileFormats implements ApplicationSingletonI
{
- private static FileFormats instance = new FileFormats();
-
- /*
- * A lookup map of file formats by upper-cased name
- */
- private static Map<String, FileFormatI> formats;
-
- /*
- * Formats in this set are capable of being identified by IdentifyFile
- */
- private static Set<FileFormatI> identifiable;
-
public static FileFormats getInstance()
{
- return instance;
+ return (FileFormats) ApplicationSingletonProvider.getInstance(FileFormats.class);
}
/**
reset();
}
+ /*
+ * A lookup map of file formats by upper-cased name
+ */
+ private Map<String, FileFormatI> formats;
+
+ /*
+ * Formats in this set are capable of being identified by IdentifyFile
+ */
+ private Set<FileFormatI> identifiable;
+
+
/**
* Reset to just the built-in file formats packaged with Jalview. These are
* added (and will be shown in menus) in the order of their declaration in the
*/
package jalview.io;
+import java.awt.Dimension;
import java.io.File;
import java.io.IOException;
import java.util.StringTokenizer;
import jalview.schemes.ColourSchemeI;
import jalview.structure.StructureSelectionManager;
import jalview.util.MessageManager;
+import jalview.util.Platform;
import jalview.ws.utils.UrlDownloadClient;
+import java.util.ArrayList;
+import java.util.List;
public class FileLoader implements Runnable
{
+ private static final String TAB = "\t";
String file;
DataSourceType protocol;
return alignFrame;
}
- public void updateRecentlyOpened()
+ public void LoadFileOntoAlignmentWaitTillLoaded(AlignViewport viewport,
+ String file, DataSourceType sourceType, FileFormatI format)
{
Vector<String> recent = new Vector<>();
if (protocol == DataSourceType.PASTE)
+ this.viewport = viewport;
+ this.file = file;
+ this.protocol = sourceType;
+ this.format = format;
+ _LoadFileWaitTillLoaded();
+ }
+
+
+ /**
+ * Updates (or creates) the tab-separated list of recently opened files held
+ * under the given property name by inserting the filePath at the front of the
+ * list. Duplicates are removed, and the list is limited to 11 entries. The
+ * method returns the updated value of the property.
+ *
+ * @param filePath
+ * @param sourceType
+ */
+ public static String updateRecentlyOpened(String filePath,
+ DataSourceType sourceType)
+ {
+ if (sourceType != DataSourceType.FILE
+ && sourceType != DataSourceType.URL)
{
- // do nothing if the file was pasted in as text... there is no filename to
- // refer to it as.
- return;
+ return null;
}
- if (file != null
- && file.indexOf(System.getProperty("java.io.tmpdir")) > -1)
+ String propertyName = sourceType == DataSourceType.FILE ? "RECENT_FILE"
+ : "RECENT_URL";
+ String historyItems = Cache.getProperty(propertyName);
+ if (filePath != null
+ && filePath.indexOf(System.getProperty("java.io.tmpdir")) > -1)
{
// ignore files loaded from the system's temporary directory
- return;
+ return null;
}
- String type = protocol == DataSourceType.FILE ? "RECENT_FILE"
- : "RECENT_URL";
- String historyItems = Cache.getProperty(type);
-
- StringTokenizer st;
+ List<String> recent = new ArrayList<>();
if (historyItems != null)
{
- st = new StringTokenizer(historyItems, "\t");
+ StringTokenizer st = new StringTokenizer(historyItems, TAB);
while (st.hasMoreTokens())
{
- recent.addElement(st.nextToken().trim());
+ String trimmed = st.nextToken().trim();
+ recent.add(trimmed);
}
}
- if (recent.contains(file))
+ /*
+ * if file was already in the list, it moves to the top
+ */
+ if (recent.contains(filePath))
{
- recent.remove(file);
+ recent.remove(filePath);
}
- StringBuffer newHistory = new StringBuffer(file);
+ StringBuilder newHistory = new StringBuilder(filePath);
for (int i = 0; i < recent.size() && i < 10; i++)
{
- newHistory.append("\t");
- newHistory.append(recent.elementAt(i));
+ newHistory.append(TAB);
+ newHistory.append(recent.get(i));
}
- Cache.setProperty(type, newHistory.toString());
+ String newProperty = newHistory.toString();
+ Cache.setProperty(propertyName, newProperty);
- if (protocol == DataSourceType.FILE)
- {
- Cache.setProperty("DEFAULT_FILE_FORMAT", format.getName());
- }
+ return newProperty;
}
@Override
Runtime rt = Runtime.getRuntime();
try
{
- if (Desktop.instance != null)
+ if (Desktop.getInstance() != null)
{
- Desktop.instance.startLoading(file);
+ Desktop.getInstance().startLoading(file);
}
if (format == null)
{
if (format == null)
{
- Desktop.instance.stopLoading();
+ Desktop.getInstance().stopLoading();
System.err.println("The input file \"" + file
+ "\" has null or unidentifiable data content!");
if (!Jalview.isHeadlessMode())
{
- JvOptionPane.showInternalMessageDialog(Desktop.desktop,
+ JvOptionPane.showInternalMessageDialog(Desktop.getDesktopPane(),
MessageManager.getString("label.couldnt_read_data")
+ " in " + file + "\n"
+ AppletFormatAdapter.getSupportedFormats(),
}
// TODO: cache any stream datasources as a temporary file (eg. PDBs
// retrieved via URL)
- if (Desktop.desktop != null && Desktop.desktop.isShowMemoryUsage())
+ if (Desktop.getDesktopPane() != null && Desktop.getDesktopPane().isShowMemoryUsage())
{
System.gc();
memused = (rt.maxMemory() - rt.totalMemory() + rt.freeMemory()); // free
// register PDB entries with desktop's structure selection
// manager
StructureSelectionManager
- .getStructureSelectionManager(Desktop.instance)
+ .getStructureSelectionManager(Desktop.getInstance())
.registerPDBEntry(pdbe);
}
}
.getFeatureColourScheme();
if (viewport != null)
{
+ // TODO: test if this needs to be done after addAlignment ? (like in 2.11.2)
+ if (proxyColourScheme != null)
+ {
+ viewport.applyFeaturesStyle(proxyColourScheme);
+ }
// append to existing alignment
viewport.addAlignment(al, title);
- viewport.applyFeaturesStyle(proxyColourScheme);
+ if (source instanceof HMMFile)
+ {
+ AlignmentI alignment = viewport.getAlignment();
+ SequenceI seq = alignment
+ .getSequenceAt(alignment.getHeight() - 1);
+ if (seq.hasHMMProfile())
+ {
+ /*
+ * fudge: move HMM consensus sequence from last to first
+ */
+ alignment.deleteSequence(alignment.getAbsoluteHeight() - 1);
+ alignment.insertSequenceAt(0, seq);
+ }
+ viewport.getAlignPanel().adjustAnnotationHeight();
+ viewport.updateSequenceIdColours();
+ }
}
else
{
// add metadata and update ui
if (!(protocol == DataSourceType.PASTE))
{
- alignFrame.setFileName(file, format);
- alignFrame.setFileObject(selectedFile); // BH 2018 SwingJS
+ alignFrame.setFile(file, selectedFile, protocol, format);
}
if (proxyColourScheme != null)
{
// status in Jalview 3
// TODO: define 'virtual desktop' for benefit of headless scripts
// that perform queries to find the 'current working alignment'
- Desktop.addInternalFrame(alignFrame, title,
+
+ Dimension dim = Platform.getDimIfEmbedded(alignFrame,
AlignFrame.DEFAULT_WIDTH, AlignFrame.DEFAULT_HEIGHT);
+ alignFrame.setSize(dim);
+ Desktop.addInternalFrame(alignFrame, title, dim.width,
+ dim.height);
}
try
}
else
{
- if (Desktop.instance != null)
+ if (Desktop.getInstance() != null)
{
- Desktop.instance.stopLoading();
+ Desktop.getInstance().stopLoading();
}
final String errorMessage = MessageManager.getString(
"label.couldnt_load_file") + " " + title + "\n" + error;
// TODO: refactor FileLoader to be independent of Desktop / Applet GUI
// bits ?
- if (raiseGUI && Desktop.desktop != null)
+ if (raiseGUI && Desktop.getDesktopPane() != null)
{
javax.swing.SwingUtilities.invokeLater(new Runnable()
{
@Override
public void run()
{
- JvOptionPane.showInternalMessageDialog(Desktop.desktop,
+ JvOptionPane.showInternalMessageDialog(Desktop.getDesktopPane(),
errorMessage,
MessageManager
.getString("label.error_loading_file"),
}
}
- updateRecentlyOpened();
+ updateRecentlyOpened(file, protocol);
+
+ if (protocol == DataSourceType.FILE && format != null)
+ {
+ Cache.setProperty("DEFAULT_FILE_FORMAT", format.getName());
+ }
} catch (Exception er)
{
@Override
public void run()
{
- JvOptionPane.showInternalMessageDialog(Desktop.desktop,
+ JvOptionPane.showInternalMessageDialog(Desktop.getDesktopPane(),
MessageManager.formatMessage(
"label.problems_opening_file", new String[]
{ file }),
@Override
public void run()
{
- JvOptionPane.showInternalMessageDialog(Desktop.desktop,
+ JvOptionPane.showInternalMessageDialog(Desktop.getDesktopPane(),
MessageManager.formatMessage(
"warn.out_of_memory_loading_file", new String[]
{ file }),
// memory
// after
// load
- if (Desktop.desktop != null && Desktop.desktop.isShowMemoryUsage())
+ if (Desktop.getDesktopPane() != null && Desktop.getDesktopPane().isShowMemoryUsage())
{
if (alignFrame != null)
{
}
}
// remove the visual delay indicator
- if (Desktop.instance != null)
+ if (Desktop.getInstance() != null)
{
- Desktop.instance.stopLoading();
+ Desktop.getInstance().stopLoading();
}
}
--- /dev/null
+package jalview.io;
+
+import jalview.api.AlignExportSettingsI;
+import jalview.api.AlignmentViewPanel;
+import jalview.datamodel.HMMNode;
+import jalview.datamodel.HiddenMarkovModel;
+import jalview.datamodel.SequenceI;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Scanner;
+
+
+/**
+ * Adds capability to read in and write out HMMER3 files. .
+ *
+ *
+ * @author TZVanaalten
+ *
+ */
+public class HMMFile extends AlignFile
+ implements AlignmentFileReaderI, AlignmentFileWriterI
+{
+ private static final String TERMINATOR = "//";
+
+ /*
+ * keys to data in HMM file, used to store as properties of the HiddenMarkovModel
+ */
+ public static final String HMM = "HMM";
+
+ public static final String NAME = "NAME";
+
+ public static final String ACCESSION_NUMBER = "ACC";
+
+ public static final String DESCRIPTION = "DESC";
+
+ public static final String LENGTH = "LENG";
+
+ public static final String MAX_LENGTH = "MAXL";
+
+ public static final String ALPHABET = "ALPH";
+
+ public static final String DATE = "DATE";
+
+ public static final String COMMAND_LOG = "COM";
+
+ public static final String NUMBER_OF_SEQUENCES = "NSEQ";
+
+ public static final String EFF_NUMBER_OF_SEQUENCES = "EFFN";
+
+ public static final String CHECK_SUM = "CKSUM";
+
+ public static final String STATISTICS = "STATS";
+
+ public static final String COMPO = "COMPO";
+
+ public static final String GATHERING_THRESHOLD = "GA";
+
+ public static final String TRUSTED_CUTOFF = "TC";
+
+ public static final String NOISE_CUTOFF = "NC";
+
+ public static final String VITERBI = "VITERBI";
+
+ public static final String MSV = "MSV";
+
+ public static final String FORWARD = "FORWARD";
+
+ public static final String MAP = "MAP";
+
+ public static final String REFERENCE_ANNOTATION = "RF";
+
+ public static final String CONSENSUS_RESIDUE = "CONS";
+
+ public static final String CONSENSUS_STRUCTURE = "CS";
+
+ public static final String MASKED_VALUE = "MM";
+
+ private static final String ALPH_AMINO = "amino";
+
+ private static final String ALPH_DNA = "DNA";
+
+ private static final String ALPH_RNA = "RNA";
+
+ private static final String ALPHABET_AMINO = "ACDEFGHIKLMNPQRSTVWY";
+
+ private static final String ALPHABET_DNA = "ACGT";
+
+ private static final String ALPHABET_RNA = "ACGU";
+
+ private static final int NUMBER_OF_TRANSITIONS = 7;
+
+ private static final String SPACE = " ";
+
+ /*
+ * optional guide line added to an output HMMER file, purely for readability
+ */
+ private static final String TRANSITIONTYPELINE = " m->m m->i m->d i->m i->i d->m d->d";
+
+ private static String NL = System.lineSeparator();
+
+ private HiddenMarkovModel hmm;
+
+ // number of symbols in the alphabet used in the hidden Markov model
+ private int numberOfSymbols;
+
+ /**
+ * Constructor that parses immediately
+ *
+ * @param inFile
+ * @param type
+ * @throws IOException
+ */
+ public HMMFile(String inFile, DataSourceType type) throws IOException
+ {
+ super(inFile, type);
+ }
+
+ /**
+ * Constructor that parses immediately
+ *
+ * @param source
+ * @throws IOException
+ */
+ public HMMFile(FileParse source) throws IOException
+ {
+ super(source);
+ }
+
+ /**
+ * Default constructor
+ */
+ public HMMFile()
+ {
+ }
+
+ /**
+ * Constructor for HMMFile used for exporting
+ *
+ * @param hmm
+ */
+ public HMMFile(HiddenMarkovModel markov)
+ {
+ hmm = markov;
+ }
+
+ /**
+ * Returns the HMM produced by parsing a HMMER3 file
+ *
+ * @return
+ */
+ public HiddenMarkovModel getHMM()
+ {
+ return hmm;
+ }
+
+ /**
+ * Gets the name of the hidden Markov model
+ *
+ * @return
+ */
+ public String getName()
+ {
+ return hmm.getName();
+ }
+
+ /**
+ * Reads the data from HMM file into the HMM model
+ */
+ @Override
+ public void parse()
+ {
+ try
+ {
+ hmm = new HiddenMarkovModel();
+ parseHeaderLines(dataIn);
+ parseModel(dataIn);
+ } catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * Reads the header properties from a HMMER3 file and saves them in the
+ * HiddeMarkovModel. This method exits after reading the next line after the
+ * HMM line.
+ *
+ * @param input
+ * @throws IOException
+ */
+ void parseHeaderLines(BufferedReader input) throws IOException
+ {
+ boolean readingHeaders = true;
+ hmm.setFileHeader(input.readLine());
+ String line = input.readLine();
+ while (readingHeaders && line != null)
+ {
+ Scanner parser = new Scanner(line);
+ String next = parser.next();
+ if (ALPHABET.equals(next))
+ {
+ String alphabetType = parser.next();
+ hmm.setProperty(ALPHABET, alphabetType);
+ String alphabet = ALPH_DNA.equalsIgnoreCase(alphabetType)
+ ? ALPHABET_DNA
+ : (ALPH_RNA.equalsIgnoreCase(alphabetType) ? ALPHABET_RNA
+ : ALPHABET_AMINO);
+ numberOfSymbols = hmm.setAlphabet(alphabet);
+ }
+ else if (HMM.equals(next))
+ {
+ readingHeaders = false;
+ String symbols = line.substring(line.indexOf(HMM) + HMM.length());
+ numberOfSymbols = hmm.setAlphabet(symbols);
+ }
+ else if (STATISTICS.equals(next))
+ {
+ parser.next();
+ String key;
+ String value;
+ key = parser.next();
+ value = parser.next() + SPACE + SPACE + parser.next();
+ hmm.setProperty(key, value);
+ }
+ else
+ {
+ String key = next;
+ String value = parser.next();
+ while (parser.hasNext())
+ {
+ value = value + SPACE + parser.next();
+ }
+ hmm.setProperty(key, value);
+ }
+ parser.close();
+ line = input.readLine();
+ }
+ }
+
+ /**
+ * Parses the model data from the HMMER3 file. The input buffer should be
+ * positioned at the (optional) COMPO line if there is one, else at the insert
+ * emissions line for the BEGIN node of the model.
+ *
+ * @param input
+ * @throws IOException
+ */
+ void parseModel(BufferedReader input) throws IOException
+ {
+ /*
+ * specification says there must always be an HMM header (already read)
+ * and one more header (guide headings) which is skipped here
+ */
+ int nodeNo = 0;
+ String line = input.readLine();
+ List<HMMNode> nodes = new ArrayList<>();
+
+ while (line != null && !TERMINATOR.equals(line))
+ {
+ HMMNode node = new HMMNode();
+ nodes.add(node);
+ Scanner scanner = new Scanner(line);
+ String next = scanner.next();
+
+ /*
+ * expect COMPO (optional) for average match emissions
+ * or a node number followed by node's match emissions
+ */
+ if (COMPO.equals(next) || nodeNo > 0)
+ {
+ /*
+ * parse match emissions
+ */
+ double[] matches = parseDoubles(scanner, numberOfSymbols);
+ node.setMatchEmissions(matches);
+ if (!COMPO.equals(next))
+ {
+ int resNo = parseAnnotations(scanner, node);
+ if (resNo == 0)
+ {
+ /*
+ * no MAP annotation provided, just number off from 0 (begin node)
+ */
+ resNo = nodeNo;
+ }
+ node.setResidueNumber(resNo);
+ }
+ line = input.readLine();
+ }
+ scanner.close();
+
+ /*
+ * parse insert emissions
+ */
+ scanner = new Scanner(line);
+ double[] inserts = parseDoubles(scanner, numberOfSymbols);
+ node.setInsertEmissions(inserts);
+ scanner.close();
+
+ /*
+ * parse state transitions
+ */
+ line = input.readLine();
+ scanner = new Scanner(line);
+ double[] transitions = parseDoubles(scanner,
+ NUMBER_OF_TRANSITIONS);
+ node.setStateTransitions(transitions);
+ scanner.close();
+ line = input.readLine();
+
+ nodeNo++;
+ }
+
+ hmm.setNodes(nodes);
+ }
+
+ /**
+ * Parses the annotations on the match emission line and add them to the node.
+ * (See p109 of the HMMER User Guide (V3.1b2) for the specification.) Returns
+ * the residue position that the node maps to, if provided, else zero.
+ *
+ * @param scanner
+ * @param node
+ */
+ int parseAnnotations(Scanner scanner, HMMNode node)
+ {
+ int mapTo = 0;
+
+ /*
+ * map from hmm node to sequence position, if provided
+ */
+ if (scanner.hasNext())
+ {
+ String value = scanner.next();
+ if (!"-".equals(value))
+ {
+ try
+ {
+ mapTo = Integer.parseInt(value);
+ node.setResidueNumber(mapTo);
+ } catch (NumberFormatException e)
+ {
+ // ignore
+ }
+ }
+ }
+
+ /*
+ * hmm consensus residue if provided, else '-'
+ */
+ if (scanner.hasNext())
+ {
+ node.setConsensusResidue(scanner.next().charAt(0));
+ }
+
+ /*
+ * RF reference annotation, if provided, else '-'
+ */
+ if (scanner.hasNext())
+ {
+ node.setReferenceAnnotation(scanner.next().charAt(0));
+ }
+
+ /*
+ * 'm' for masked position, if provided, else '-'
+ */
+ if (scanner.hasNext())
+ {
+ node.setMaskValue(scanner.next().charAt(0));
+ }
+
+ /*
+ * structure consensus symbol, if provided, else '-'
+ */
+ if (scanner.hasNext())
+ {
+ node.setConsensusStructure(scanner.next().charAt(0));
+ }
+
+ return mapTo;
+ }
+
+ /**
+ * Fills an array of doubles parsed from an input line
+ *
+ * @param input
+ * @param numberOfElements
+ * @return
+ * @throws IOException
+ */
+ static double[] parseDoubles(Scanner input,
+ int numberOfElements) throws IOException
+ {
+ double[] values = new double[numberOfElements];
+ for (int i = 0; i < numberOfElements; i++)
+ {
+ if (!input.hasNext())
+ {
+ throw new IOException("Incomplete data");
+ }
+ String next = input.next();
+ if (next.contains("*"))
+ {
+ values[i] = Double.NEGATIVE_INFINITY;
+ }
+ else
+ {
+ double prob = Double.valueOf(next);
+ prob = Math.pow(Math.E, -prob);
+ values[i] = prob;
+ }
+ }
+ return values;
+ }
+
+ /**
+ * Returns a string to be added to the StringBuilder containing the entire
+ * output String.
+ *
+ * @param initialColumnSeparation
+ * The initial whitespace separation between the left side of the
+ * file and first character.
+ * @param columnSeparation
+ * The separation between subsequent data entries.
+ * @param data
+ * The list of data to be added to the String.
+ * @return
+ */
+ String addData(int initialColumnSeparation,
+ int columnSeparation, List<String> data)
+ {
+ String line = "";
+ boolean first = true;
+ for (String value : data)
+ {
+ int sep = first ? initialColumnSeparation : columnSeparation;
+ line += String.format("%" + sep + "s", value);
+ first = false;
+ }
+ return line;
+ }
+
+ /**
+ * Converts list of characters into a list of Strings.
+ *
+ * @param list
+ * @return Returns the list of Strings.
+ */
+ List<String> charListToStringList(List<Character> list)
+ {
+ List<String> strList = new ArrayList<>();
+ for (char value : list)
+ {
+ String strValue = Character.toString(value);
+ strList.add(strValue);
+ }
+ return strList;
+ }
+
+ /**
+ * Converts an array of doubles into a list of Strings, rounded to the nearest
+ * 5th decimal place
+ *
+ * @param doubles
+ * @param noOfDecimals
+ * @return
+ */
+ List<String> doublesToStringList(double[] doubles)
+ {
+ List<String> strList = new ArrayList<>();
+ for (double value : doubles)
+ {
+ String strValue;
+ if (value > 0)
+ {
+ strValue = String.format("%.5f", value);
+ }
+ else if (value == -0.00000d)
+ {
+ strValue = "0.00000";
+ }
+ else
+ {
+ strValue = "*";
+ }
+ strList.add(strValue);
+ }
+ return strList;
+ }
+
+ /**
+ * Appends model data in string format to the string builder
+ *
+ * @param output
+ */
+ void appendModelAsString(StringBuilder output)
+ {
+ output.append(HMM).append(" ");
+ String charSymbols = hmm.getSymbols();
+ for (char c : charSymbols.toCharArray())
+ {
+ output.append(String.format("%9s", c));
+ }
+ output.append(NL).append(TRANSITIONTYPELINE);
+
+ int length = hmm.getLength();
+
+ for (int nodeNo = 0; nodeNo <= length; nodeNo++)
+ {
+ String matchLine = String.format("%7s",
+ nodeNo == 0 ? COMPO : Integer.toString(nodeNo));
+
+ double[] doubleMatches = convertToLogSpace(
+ hmm.getNode(nodeNo).getMatchEmissions());
+ List<String> strMatches = doublesToStringList(doubleMatches);
+ matchLine += addData(10, 9, strMatches);
+
+ if (nodeNo != 0)
+ {
+ matchLine += SPACE + (hmm.getNodeMapPosition(nodeNo));
+ matchLine += SPACE + hmm.getConsensusResidue(nodeNo);
+ matchLine += SPACE + hmm.getReferenceAnnotation(nodeNo);
+ if (hmm.getFileHeader().contains("HMMER3/f"))
+ {
+ matchLine += SPACE + hmm.getMaskedValue(nodeNo);
+ matchLine += SPACE + hmm.getConsensusStructure(nodeNo);
+ }
+ }
+
+ output.append(NL).append(matchLine);
+
+ String insertLine = "";
+
+ double[] doubleInserts = convertToLogSpace(
+ hmm.getNode(nodeNo).getInsertEmissions());
+ List<String> strInserts = doublesToStringList(doubleInserts);
+ insertLine += addData(17, 9, strInserts);
+
+ output.append(NL).append(insertLine);
+
+ String transitionLine = "";
+ double[] doubleTransitions = convertToLogSpace(
+ hmm.getNode(nodeNo).getStateTransitions());
+ List<String> strTransitions = doublesToStringList(
+ doubleTransitions);
+ transitionLine += addData(17, 9, strTransitions);
+
+ output.append(NL).append(transitionLine);
+ }
+ }
+
+ /**
+ * Appends formatted HMM file properties to the string builder
+ *
+ * @param output
+ */
+ void appendProperties(StringBuilder output)
+ {
+ output.append(hmm.getFileHeader());
+
+ String format = "%n%-5s %1s";
+ appendProperty(output, format, NAME);
+ appendProperty(output, format, ACCESSION_NUMBER);
+ appendProperty(output, format, DESCRIPTION);
+ appendProperty(output, format, LENGTH);
+ appendProperty(output, format, MAX_LENGTH);
+ appendProperty(output, format, ALPHABET);
+ appendBooleanProperty(output, format, REFERENCE_ANNOTATION);
+ appendBooleanProperty(output, format, MASKED_VALUE);
+ appendBooleanProperty(output, format, CONSENSUS_RESIDUE);
+ appendBooleanProperty(output, format, CONSENSUS_STRUCTURE);
+ appendBooleanProperty(output, format, MAP);
+ appendProperty(output, format, DATE);
+ appendProperty(output, format, NUMBER_OF_SEQUENCES);
+ appendProperty(output, format, EFF_NUMBER_OF_SEQUENCES);
+ appendProperty(output, format, CHECK_SUM);
+ appendProperty(output, format, GATHERING_THRESHOLD);
+ appendProperty(output, format, TRUSTED_CUTOFF);
+ appendProperty(output, format, NOISE_CUTOFF);
+
+ if (hmm.getMSV() != null)
+ {
+ format = "%n%-19s %18s";
+ output.append(String.format(format, "STATS LOCAL MSV", hmm.getMSV()));
+
+ output.append(String.format(format, "STATS LOCAL VITERBI",
+ hmm.getViterbi()));
+
+ output.append(String.format(format, "STATS LOCAL FORWARD",
+ hmm.getForward()));
+ }
+ }
+
+ /**
+ * Appends 'yes' or 'no' for the given property, according to whether or not
+ * it is set in the HMM
+ *
+ * @param output
+ * @param format
+ * @param propertyName
+ */
+ private void appendBooleanProperty(StringBuilder output, String format,
+ String propertyName)
+ {
+ boolean set = hmm.getBooleanProperty(propertyName);
+ output.append(String.format(format, propertyName,
+ set ? HiddenMarkovModel.YES : HiddenMarkovModel.NO));
+ }
+
+ /**
+ * Appends the value of the given property to the output, if not null
+ *
+ * @param output
+ * @param format
+ * @param propertyName
+ */
+ private void appendProperty(StringBuilder output, String format,
+ String propertyName)
+ {
+ String value = hmm.getProperty(propertyName);
+ if (value != null)
+ {
+ output.append(String.format(format, propertyName, value));
+ }
+ }
+
+ @Override
+ public String print(SequenceI[] sequences, boolean jvsuffix)
+ {
+ if (sequences[0].getHMM() != null)
+ {
+ hmm = sequences[0].getHMM();
+ }
+ return print();
+ }
+
+ /**
+ * Prints the .hmm file to a String.
+ *
+ * @return
+ */
+ public String print()
+ {
+ StringBuilder output = new StringBuilder();
+ appendProperties(output);
+ output.append(NL);
+ appendModelAsString(output);
+ output.append(NL).append(TERMINATOR).append(NL);
+ return output.toString();
+ }
+
+ /**
+ * Converts the probabilities contained in an array into log space
+ *
+ * @param ds
+ */
+ double[] convertToLogSpace(double[] ds)
+ {
+ double[] converted = new double[ds.length];
+ for (int i = 0; i < ds.length; i++)
+ {
+ double prob = ds[i];
+ double logProb = -1 * Math.log(prob);
+
+ converted[i] = logProb;
+ }
+ return converted;
+ }
+
+ /**
+ * Returns the HMM sequence produced by reading a .hmm file.
+ */
+ @Override
+ public SequenceI[] getSeqsAsArray()
+ {
+ SequenceI hmmSeq = hmm.getConsensusSequence();
+ SequenceI[] seq = new SequenceI[1];
+ seq[0] = hmmSeq;
+ return seq;
+ }
+
+ @Override
+ public void setNewlineString(String newLine)
+ {
+ NL = newLine;
+ }
+
+ @Override
+ public void setExportSettings(AlignExportSettingsI exportSettings)
+ {
+
+ }
+
+ @Override
+ public void configureForView(AlignmentViewPanel viewpanel)
+ {
+
+ }
+
+ @Override
+ public boolean hasWarningMessage()
+ {
+ return false;
+ }
+
+ @Override
+ public String getWarningMessage()
+ {
+ return "warning message";
+ }
+
+}
+
package jalview.io;
import java.util.Locale;
-
import java.io.File;
import java.io.IOException;
reply = FileFormat.ScoreMatrix;
break;
}
+ if (data.startsWith("HMMER3"))
+ {
+ reply = FileFormat.HMMER3;
+ break;
+ }
if (data.startsWith("LOCUS"))
{
reply = FileFormat.GenBank;
reply = FileFormat.Rnaml;
break;
}
+ if (upper.substring(lessThan).startsWith("<BSML"))
+ {
+ reply = FileFormat.BSML;
+ break;
+ }
}
if ((data.length() < 1) || (data.indexOf("#") == 0))
import jalview.datamodel.DBRefEntry;
import jalview.datamodel.SequenceI;
+import jalview.util.Platform;
import java.util.List;
}
};
+ private static Regex VALIDATION_REGEX;
+
+ private static Regex getRegex()
+ {
+ return (VALIDATION_REGEX == null
+ ? VALIDATION_REGEX = Platform
+ .newRegex("\\s*((([-0-9]+).?)|FIRST|LAST|@)", null)
+ : VALIDATION_REGEX);
+ }
+
private resCode validResidueCode(String field)
{
Integer val = null;
- Regex r = new Regex(
- "\\s*((([-0-9]+).?)|FIRST|LAST|@)");
-
+ Regex r = getRegex();
if (!r.search(field))
{
return null; // invalid
import jalview.datamodel.SequenceNode;
import jalview.util.MessageManager;
+import jalview.util.Platform;
import java.io.BufferedReader;
import java.io.File;
import com.stevesoft.pat.Regex;
+// TODO This class does not conform to Java standards for field name capitalization.
+
/**
* Parse a new hanpshire style tree Caveats: NHX files are NOT supported and the
* tree distances and topology are unreliable when they are parsed. TODO: on
*/
public class NewickFile extends FileParse
{
- SequenceNode root;
+ private SequenceNode root;
private boolean HasBootstrap = false;
private boolean RootHasDistance = false;
// File IO Flags
- boolean ReplaceUnderscores = false;
+ private boolean ReplaceUnderscores = false;
+
+ private boolean printRootInfo = true;
+
+ private static final int REGEX_PERL_NODE_REQUIRE_QUOTE = 0;
+
+ private static final int REGEX_PERL_NODE_ESCAPE_QUOTE = 1;
+
+ private static final int REGEX_PERL_NODE_UNQUOTED_WHITESPACE = 2;
+
+ private static final int REGEX_MAJOR_SYMS = 3;
+
+ private static final int REGEX_QNODE_NAME = 4;
+
+ private static final int REGEX_COMMENT = 5;
+
+ private static final int REGEX_UQNODE_NAME = 6;
- boolean printRootInfo = true;
+ private static final int REGEX_NBOOTSTRAP = 7;
+
+ private static final int REGEX_NDIST = 8;
+
+ private static final int REGEX_NO_LINES = 9;
+
+ private static final int REGEX_PERL_EXPAND_QUOTES = 10;
+
+ private static final int REGEX_MAX = 11;
+
+ private static final Regex[] REGEX = new Regex[REGEX_MAX];
+
+ private static Regex getRegex(int id)
+ {
+ if (REGEX[id] == null)
+ {
+ String code = null;
+ String code2 = null;
+ String codePerl = null;
+ switch (id)
+ {
+ case REGEX_PERL_NODE_REQUIRE_QUOTE:
+ codePerl = "m/[\\[,:'()]/";
+ break;
+ case REGEX_PERL_NODE_ESCAPE_QUOTE:
+ codePerl = "s/'/''/";
+ break;
+ case REGEX_PERL_NODE_UNQUOTED_WHITESPACE:
+ codePerl = "s/\\/w/_/";
+ break;
+ case REGEX_PERL_EXPAND_QUOTES:
+ codePerl = "s/''/'/";
+ break;
+ case REGEX_MAJOR_SYMS:
+ code = "[(\\['),;]";
+ break;
+ case REGEX_QNODE_NAME:
+ code = "'([^']|'')+'";
+ break;
+ case REGEX_COMMENT:
+ code = "]";
+ break;
+ case REGEX_UQNODE_NAME:
+ code = "\\b([^' :;\\](),]+)";
+ break;
+ case REGEX_NBOOTSTRAP:
+ code = "\\s*([0-9+]+)\\s*:";
+ break;
+ case REGEX_NDIST:
+ code = ":([-0-9Ee.+]+)";
+ break;
+ case REGEX_NO_LINES:
+ code = "\n+";
+ code2 = "";
+ break;
+ default:
+ return null;
+ }
+ return codePerl == null ? Platform.newRegex(code, code2)
+ : Platform.newRegexPerl(codePerl);
+ }
+ return REGEX[id];
+ }
- private Regex[] NodeSafeName = new Regex[] {
- new Regex().perlCode("m/[\\[,:'()]/"), // test for
- // requiring
- // quotes
- new Regex().perlCode("s/'/''/"), // escaping quote
- // characters
- new Regex().perlCode("s/\\/w/_/") // unqoted whitespace
- // transformation
- };
- char QuoteChar = '\'';
+ private char quoteChar = '\'';
/**
* Creates a new NewickFile object.
*/
public void parse() throws IOException
{
+ Platform.ensureRegex();
String nf;
{ // fill nf with complete tree file
boolean ascending = false; // flag indicating that we are leaving the
// current node
- Regex majorsyms = new Regex(
- "[(\\['),;]");
+ Regex majorsyms = getRegex(REGEX_MAJOR_SYMS); // "[(\\['),;]"
int nextcp = 0;
int ncp = cp;
// Deal with quoted fields
case '\'':
- Regex qnodename = new Regex(
- "'([^']|'')+'");
+ Regex qnodename = getRegex(REGEX_QNODE_NAME);// "'([^']|'')+'");
if (qnodename.searchFrom(nf, fcp))
{
nodename = new String(
qnodename.stringMatched().substring(1, nl - 1));
// unpack any escaped colons
- Regex xpandquotes = Regex
- .perlCode("s/''/'/");
+ Regex xpandquotes = getRegex(REGEX_PERL_EXPAND_QUOTES);
String widernodename = xpandquotes.replaceAll(nodename);
nodename = widernodename;
// jump to after end of quoted nodename
* '"+nf.substring(cp,fcp)+"'"); }
*/
// verify termination.
- Regex comment = new Regex(
- "]");
+ Regex comment = getRegex(REGEX_COMMENT); // "]"
if (comment.searchFrom(nf, fcp))
{
// Skip the comment field
+ fstring.substring(cend + 1);
}
- Regex uqnodename = new Regex(
- "\\b([^' :;\\](),]+)");
- Regex nbootstrap = new Regex(
- "\\s*([0-9+]+)\\s*:");
- Regex ndist = new Regex(
- ":([-0-9Ee.+]+)");
+ Regex uqnodename = getRegex(REGEX_UQNODE_NAME);// "\\b([^' :;\\](),]+)"
+ Regex nbootstrap = getRegex(REGEX_NBOOTSTRAP);// "\\s*([0-9+]+)\\s*:");
+ Regex ndist = getRegex(REGEX_NDIST);// ":([-0-9Ee.+]+)");
if (!parsednodename && uqnodename.search(fstring)
&& ((uqnodename.matchedFrom(1) == 0) || (fstring
*/
char getQuoteChar()
{
- return QuoteChar;
+ return quoteChar;
}
/**
*/
char setQuoteChar(char c)
{
- char old = QuoteChar;
- QuoteChar = c;
+ char old = quoteChar;
+ quoteChar = c;
return old;
}
*/
private String nodeName(String name)
{
- if (NodeSafeName[0].search(name))
+ if (getRegex(REGEX_PERL_NODE_REQUIRE_QUOTE).search(name))
{
- return QuoteChar + NodeSafeName[1].replaceAll(name) + QuoteChar;
+ return quoteChar
+ + getRegex(REGEX_PERL_NODE_ESCAPE_QUOTE).replaceAll(name)
+ + quoteChar;
}
else
{
- return NodeSafeName[2].replaceAll(name);
+ return getRegex(REGEX_PERL_NODE_UNQUOTED_WHITESPACE).replaceAll(name);
}
}
trf.parse();
System.out.println("Original file :\n");
- Regex nonl = new Regex("\n+", "");
+ Regex nonl = getRegex(REGEX_NO_LINES);// "\n+", "");
System.out.println(nonl.replaceAll(newickfile.toString()) + "\n");
System.out.println("Parsed file.\n");
import jalview.datamodel.Sequence;
import jalview.datamodel.SequenceI;
import jalview.util.MessageManager;
+import jalview.util.Platform;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
dataName = dataName.substring(0, b - 1);
}
b = 0;
- Regex m = new Regex("[\\/]?([-A-Za-z0-9]+)\\.?");
+ Regex m = Platform.newRegex("[\\/]?([-A-Za-z0-9]+)\\.?");
String mm = dataName;
while (m.searchFrom(dataName, b))
{
import java.util.Map;
import jalview.api.FeatureColourI;
+import jalview.datamodel.AlignmentAnnotation;
import jalview.datamodel.DBRefEntry;
import jalview.datamodel.DBRefSource;
import jalview.datamodel.GeneLociI;
{
if (sb0.length() > 6)
{
- sb.append("<br/>");
+ sb.append("<br>");
}
sb.append(feature.getType()).append(" ").append(begin).append(":")
.append(end);
if (sb0.length() > 6)
{
- sb.append("<br/>");
+ sb.append("<br>");
}
// TODO: remove this hack to display link only features
boolean linkOnly = feature.getValue("linkonly") != null;
int linkindex = description.toLowerCase(Locale.ROOT).indexOf("<a ");
boolean hasLink = linkindex > -1
&& linkindex < MAX_DESCRIPTION_LENGTH;
- if (description.length() > MAX_DESCRIPTION_LENGTH && !hasLink)
+ if (
+ // BH suggestion maxlength == 0 &&
+ description.length() > MAX_DESCRIPTION_LENGTH && !hasLink)
{
description = description.substring(0, MAX_DESCRIPTION_LENGTH)
+ ELLIPSIS;
{
for (List<String> urllink : createLinksFrom(null, urlstring))
{
- sb.append("<br/> <a href=\""
+ sb.append("<br> <a href=\""
+ urllink.get(3)
+ "\" target=\""
+ urllink.get(0)
.equals(urllink.get(1).toLowerCase(Locale.ROOT)) ? urllink
.get(0) : (urllink.get(0) + ":" + urllink
.get(1)))
- + "</a><br/>");
+ + "</a><br>");
}
} catch (Exception x)
{
sb.append(tmp);
maxWidth = Math.max(maxWidth, tmp.length());
}
+
SequenceI ds = sequence;
while (ds.getDatasetSequence() != null)
{
ds = ds.getDatasetSequence();
}
+ /*
+ * add any annotation scores
+ */
+ AlignmentAnnotation[] anns = ds.getAnnotation();
+ for (int i = 0; anns != null && i < anns.length; i++)
+ {
+ AlignmentAnnotation aa = anns[i];
+ if (aa != null && aa.hasScore() && aa.sequenceRef != null)
+ {
+ sb.append("<br>").append(aa.label).append(": ")
+ .append(aa.getScore());
+ }
+ }
+
if (showDbRefs)
{
maxWidth = Math.max(maxWidth, appendDbRefs(sb, ds, summary));
maxWidth = Math.max(maxWidth, sz);
}
}
+
+
+ if (sequence.getAnnotation("Search Scores") != null)
+ {
+ sb.append("<br>");
+ String eValue = " E-Value: "
+ + sequence.getAnnotation("Search Scores")[0].getEValue();
+ String bitScore = " Bit Score: "
+ + sequence.getAnnotation("Search Scores")[0].getBitScore();
+ sb.append(eValue);
+ sb.append("<br>");
+ sb.append(bitScore);
+ maxWidth = Math.max(maxWidth, eValue.length());
+ maxWidth = Math.max(maxWidth, bitScore.length());
+ }
+ sb.append("<br>");
sb.append("</i>");
+
return maxWidth;
}
countForSource++;
if (countForSource == 1 || !summary)
{
- sb.append("<br/>");
+ sb.append("<br>");
}
if (countForSource <= MAX_REFS_PER_SOURCE || !summary)
{
}
if (moreSources)
{
- sb.append("<br/>").append(source).append(COMMA).append(ELLIPSIS);
+ sb.append("<br>").append(source).append(COMMA).append(ELLIPSIS);
}
if (ellipsis)
{
- sb.append("<br/>(");
+ sb.append("<br>(");
sb.append(MessageManager.getString("label.output_seq_details"));
sb.append(")");
}
*/
package jalview.io;
-import java.util.Locale;
+import jalview.analysis.Rna;
+import jalview.datamodel.AlignmentAnnotation;
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.Annotation;
+import jalview.datamodel.DBRefEntry;
+import jalview.datamodel.DBRefSource;
+import jalview.datamodel.Mapping;
+import jalview.datamodel.Sequence;
+import jalview.datamodel.SequenceFeature;
+import jalview.datamodel.SequenceI;
+import jalview.schemes.ResidueProperties;
+import jalview.util.Comparison;
+import jalview.util.DBRefUtils;
+import jalview.util.Format;
+import jalview.util.MessageManager;
+import jalview.util.Platform;
import java.io.BufferedReader;
import java.io.FileReader;
import java.util.Hashtable;
import java.util.LinkedHashMap;
import java.util.List;
+import java.util.Locale;
import java.util.Map;
import java.util.Vector;
import fr.orsay.lri.varna.exceptions.ExceptionUnmatchedClosingParentheses;
import fr.orsay.lri.varna.factories.RNAFactory;
import fr.orsay.lri.varna.models.rna.RNA;
-import jalview.analysis.Rna;
-import jalview.datamodel.AlignmentAnnotation;
-import jalview.datamodel.AlignmentI;
-import jalview.datamodel.Annotation;
-import jalview.datamodel.DBRefEntry;
-import jalview.datamodel.DBRefSource;
-import jalview.datamodel.Mapping;
-import jalview.datamodel.Sequence;
-import jalview.datamodel.SequenceFeature;
-import jalview.datamodel.SequenceI;
-import jalview.schemes.ResidueProperties;
-import jalview.util.Comparison;
-import jalview.util.DBRefUtils;
-import jalview.util.Format;
-import jalview.util.MessageManager;
// import org.apache.log4j.*;
{
private static final String ANNOTATION = "annotation";
-// private static final Regex OPEN_PAREN = new Regex("(<|\\[)", "(");
-//
-// private static final Regex CLOSE_PAREN = new Regex("(>|\\])", ")");
-
- public static final Regex DETECT_BRACKETS = new Regex(
- "(<|>|\\[|\\]|\\(|\\)|\\{|\\})");
-
+ private static final char UNDERSCORE = '_';
+
// WUSS extended symbols. Avoid ambiguity with protein SS annotations by using NOT_RNASS first.
+
public static final String RNASS_BRACKETS = "<>[](){}AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz";
+ public static final int REGEX_STOCKHOLM = 0;
+
+ public static final int REGEX_BRACKETS = 1;
// use the following regex to decide an annotations (whole) line is NOT an RNA
// SS (it contains only E,H,e,h and other non-brace/non-alpha chars)
- private static final Regex NOT_RNASS = new Regex(
- "^[^<>[\\](){}A-DF-Za-df-z]*$");
+ public static final int REGEX_NOT_RNASS = 2;
+
+ private static final int REGEX_ANNOTATION = 3;
+
+ private static final int REGEX_PFAM = 4;
+
+ private static final int REGEX_RFAM = 5;
+
+ private static final int REGEX_ALIGN_END = 6;
+
+ private static final int REGEX_SPLIT_ID = 7;
+
+ private static final int REGEX_SUBTYPE = 8;
+
+ private static final int REGEX_ANNOTATION_LINE = 9;
+
+ private static final int REGEX_REMOVE_ID = 10;
+
+ private static final int REGEX_OPEN_PAREN = 11;
+
+ private static final int REGEX_CLOSE_PAREN = 12;
+
+ public static final int REGEX_MAX = 13;
+
+ private static Regex REGEX[] = new Regex[REGEX_MAX];
+
+ /**
+ * Centralize all actual Regex instantialization in Platform.
+ * // JBPNote: Why is this 'centralisation' better ?
+ * @param id
+ * @return
+ */
+ private static Regex getRegex(int id)
+ {
+ if (REGEX[id] == null)
+ {
+ String pat = null, pat2 = null;
+ switch (id)
+ {
+ case REGEX_STOCKHOLM:
+ pat = "# STOCKHOLM ([\\d\\.]+)";
+ break;
+ case REGEX_BRACKETS:
+ // for reference; not used
+ pat = "(<|>|\\[|\\]|\\(|\\)|\\{|\\})";
+ break;
+ case REGEX_NOT_RNASS:
+ pat = "^[^<>[\\](){}A-DF-Za-df-z]*$";
+ break;
+ case REGEX_ANNOTATION:
+ pat = "(\\w+)\\s*(.*)";
+ break;
+ case REGEX_PFAM:
+ pat = "PF[0-9]{5}(.*)";
+ break;
+ case REGEX_RFAM:
+ pat = "RF[0-9]{5}(.*)";
+ break;
+ case REGEX_ALIGN_END:
+ pat = "^\\s*\\/\\/";
+ break;
+ case REGEX_SPLIT_ID:
+ pat = "(\\S+)\\/(\\d+)\\-(\\d+)";
+ break;
+ case REGEX_SUBTYPE:
+ pat = "(\\S+)\\s+(\\S*)\\s+(.*)";
+ break;
+ case REGEX_ANNOTATION_LINE:
+ pat = "#=(G[FSRC]?)\\s+(.*)";
+ break;
+ case REGEX_REMOVE_ID:
+ pat = "(\\S+)\\s+(\\S+)";
+ break;
+ case REGEX_OPEN_PAREN:
+ pat = "(<|\\[)";
+ pat2 = "(";
+ break;
+ case REGEX_CLOSE_PAREN:
+ pat = "(>|\\])";
+ pat2 = ")";
+ break;
+ default:
+ return null;
+ }
+ REGEX[id] = Platform.newRegex(pat, pat2);
+ }
+ return REGEX[id];
+ }
StringBuffer out; // output buffer
- AlignmentI al;
+ private AlignmentI al;
public StockholmFile()
{
}
/**
- * Creates a new StockholmFile object for output.
+ * Creates a new StockholmFile object for output
*/
public StockholmFile(AlignmentI al)
{
// First, we have to check that this file has STOCKHOLM format, i.e. the
// first line must match
- r = new Regex("# STOCKHOLM ([\\d\\.]+)");
+ r = getRegex(REGEX_STOCKHOLM);
if (!r.search(nextLine()))
{
throw new IOException(MessageManager
}
// We define some Regexes here that will be used regularily later
- rend = new Regex("^\\s*\\/\\/"); // Find the end of an alignment
- p = new Regex("(\\S+)\\/(\\d+)\\-(\\d+)"); // split sequence id in
+ rend = getRegex(REGEX_ALIGN_END);//"^\\s*\\/\\/"); // Find the end of an alignment
+ p = getRegex(REGEX_SPLIT_ID);//"(\\S+)\\/(\\d+)\\-(\\d+)"); // split sequence id in
// id/from/to
- s = new Regex("(\\S+)\\s+(\\S*)\\s+(.*)"); // Parses annotation subtype
- r = new Regex("#=(G[FSRC]?)\\s+(.*)"); // Finds any annotation line
- x = new Regex("(\\S+)\\s+(\\S+)"); // split id from sequence
+ s = getRegex(REGEX_SUBTYPE);// "(\\S+)\\s+(\\S*)\\s+(.*)"); // Parses
+ // annotation subtype
+ r = getRegex(REGEX_ANNOTATION_LINE);// "#=(G[FSRC]?)\\s+(.*)"); // Finds any
+ // annotation line
+ x = getRegex(REGEX_REMOVE_ID);// "(\\S+)\\s+(\\S+)"); // split id from
+ // sequence
// Convert all bracket types to parentheses (necessary for passing to VARNA)
- Regex openparen = new Regex("(<|\\[)", "(");
- Regex closeparen = new Regex("(>|\\])", ")");
+ Regex openparen = getRegex(REGEX_OPEN_PAREN);//"(<|\\[)", "(");
+ Regex closeparen = getRegex(REGEX_CLOSE_PAREN);//"(>|\\])", ")");
// // Detect if file is RNA by looking for bracket types
-// Regex detectbrackets = new Regex("(<|>|\\[|\\]|\\(|\\))");
+ // Regex detectbrackets = getRegex("(<|>|\\[|\\]|\\(|\\))");
rend.optimize();
p.optimize();
this.noSeqs = seqs.size();
String dbsource = null;
- Regex pf = new Regex("PF[0-9]{5}(.*)"); // Finds AC for Pfam
- Regex rf = new Regex("RF[0-9]{5}(.*)"); // Finds AC for Rfam
+ Regex pf = getRegex(REGEX_PFAM); // Finds AC for Pfam
+ Regex rf = getRegex(REGEX_RFAM); // Finds AC for Rfam
if (getAlignmentProperty("AC") != null)
{
String dbType = getAlignmentProperty("AC").toString();
if (accAnnotations != null && accAnnotations.containsKey("AC"))
{
- String dbr = (String) accAnnotations.get("AC");
- if (dbr != null)
- {
- // we could get very clever here - but for now - just try to
+ String dbr = (String) accAnnotations.get("AC");
+ if (dbr != null)
+ {
+ // we could get very clever here - but for now - just try to
// guess accession type from type of sequence, source of alignment plus
// structure
- // of accession
- guessDatabaseFor(seqO, dbr, dbsource);
+ // of accession
+ guessDatabaseFor(seqO, dbr, dbsource);
}
// else - do what ? add the data anyway and prompt the user to
// specify what references these are ?
*/
// Let's save the annotations, maybe we'll be able to do something
// with them later...
- Regex an = new Regex("(\\w+)\\s*(.*)");
+ Regex an = getRegex(REGEX_ANNOTATION);
if (an.search(annContent))
{
if (an.stringMatched(1).equals("NH"))
if (features.containsKey(this.id2type(type)))
{
// logger.debug("Found content for " + this.id2type(type));
- content = (Hashtable) features.get(this.id2type(type));
+ content = (Hashtable) features
+ .get(this.id2type(type));
}
else
{
// logger.debug("Creating new content holder for " +
// this.id2type(type));
content = new Hashtable();
- features.put(this.id2type(type), content);
+ features.put(id2type(type), content);
}
String ns = (String) content.get(ANNOTATION);
Vector<AlignmentAnnotation> annotation, String label,
String annots)
{
- String convert1, convert2 = null;
-
- // convert1 = OPEN_PAREN.replaceAll(annots);
- // convert2 = CLOSE_PAREN.replaceAll(convert1);
+ String convert1, convert2 = null;
+ // String convert1 = OPEN_PAREN.replaceAll(annots);
+ // String convert2 = CLOSE_PAREN.replaceAll(convert1);
// annots = convert2;
String type = label;
if (type.equalsIgnoreCase("secondary structure"))
{
ss = true;
- isrnass = !NOT_RNASS.search(annots); // sorry about the double negative
+ isrnass = !getRegex(REGEX_NOT_RNASS).search(annots); // sorry about the double
+ // negative
// here (it's easier for dealing with
// other non-alpha-non-brace chars)
}
for (int i = 0; i < annots.length(); i++)
{
String pos = annots.substring(i, i + 1);
+ // TODO 2.12 release: verify this Stockholm IO behaviour change in release notes
+ if (UNDERSCORE == pos.charAt(0))
+ {
+ pos = " ";
+ }
Annotation ann;
ann = new Annotation(pos, "", ' ', 0f); // 0f is 'valid' null - will not
// be written out
}
else
{
- for (int idb = 0; idb < seq.getDBRefs().size(); idb++)
+ for (int idb = 0; idb < ndb; idb++)
{
- DBRefEntry dbref = seq.getDBRefs().get(idb);
+ DBRefEntry dbref = seqrefs.get(idb);
dataRef.put(tmp, dbref_to_ac_record(dbref));
// if we put in a uniprot or EMBL record then we're done:
- if (isAA && DBRefSource.UNIPROT
- .equals(DBRefUtils.getCanonicalName(dbref.getSource())))
- {
- break;
- }
- if (!isAA && DBRefSource.EMBL
+ if ((isAA ? DBRefSource.UNIPROT : DBRefSource.EMBL)
.equals(DBRefUtils.getCanonicalName(dbref.getSource())))
{
break;
if (alAnot != null)
{
Annotation[] ann;
- for (int j = 0, nj = alAnot.length; j < nj; j++)
+ for (int j = 0; j < alAnot.length; j++)
{
- String key = type2id(alAnot[j].label);
- boolean isrna = alAnot[j].isValidStruc();
-
- if (isrna)
- {
- // hardwire to secondary structure if there is RNA secondary
- // structure on the annotation
- key = "SS";
- }
- if (key == null)
+ if (alAnot[j].annotations != null)
{
+ String key = type2id(alAnot[j].label);
+ boolean isrna = alAnot[j].isValidStruc();
- continue;
- }
+ if (isrna)
+ {
+ // hardwire to secondary structure if there is RNA secondary
+ // structure on the annotation
+ key = "SS";
+ }
+ if (key == null)
+ {
+ continue;
+ }
- // out.append("#=GR ");
- out.append(new Format("%-" + maxid + "s").form(
- "#=GR " + printId(seq, jvSuffix) + " " + key + " "));
- ann = alAnot[j].annotations;
- String sseq = "";
- for (int k = 0, nk = ann.length; k < nk; k++)
- {
- sseq += outputCharacter(key, k, isrna, ann, seq);
- }
- out.append(sseq);
- out.append(newline);
+ // out.append("#=GR ");
+ out.append(new Format("%-" + maxid + "s").form(
+ "#=GR " + printId(s[i], jvSuffix) + " " + key + " "));
+ ann = alAnot[j].annotations;
+ String sseq = "";
+ for (int k = 0; k < ann.length; k++)
+ {
+ sseq += outputCharacter(key, k, isrna, ann, s[i]);
+ }
+ out.append(sseq);
+ out.append(newline);
+ }
}
}
}
else
{
- key = type2id(aa.label.toLowerCase(Locale.ROOT));
+ key = type2id(aa.label.toLowerCase());
if (key == null)
{
label = aa.label;
: seq;
}
+ /**
+ * make a friendly ID string.
+ *
+ * @param dataName
+ * @return truncated dataName to after last '/'
+ */
+ private String safeName(String dataName)
+ {
+ int b = 0;
+ while ((b = dataName.indexOf("/")) > -1 && b < dataName.length())
+ {
+ dataName = dataName.substring(b + 1).trim();
+
+ }
+ int e = (dataName.length() - dataName.indexOf(".")) + 1;
+ dataName = dataName.substring(1, e).trim();
+ return dataName;
+ }
+
+
public String print()
{
out = new StringBuffer();
}
}
+
protected static String id2type(String id)
{
if (typeIds.containsKey(id))
"Warning : Unknown Stockholm annotation type: " + type);
return key;
}
-
- /**
- * make a friendly ID string.
- *
- * @param dataName
- * @return truncated dataName to after last '/'
- */
- private String safeName(String dataName)
- {
- int b = 0;
- while ((b = dataName.indexOf("/")) > -1 && b < dataName.length())
- {
- dataName = dataName.substring(b + 1).trim();
-
- }
- int e = (dataName.length() - dataName.indexOf(".")) + 1;
- dataName = dataName.substring(1, e).trim();
- return dataName;
- }
}
import jalview.io.vamsas.Rangetype;
import jalview.project.Jalview2XML;
import jalview.util.MessageManager;
+import jalview.util.jarInputStreamProvider;
import jalview.viewmodel.AlignmentViewport;
+import java.io.File;
import java.io.IOException;
import java.util.Enumeration;
import java.util.HashMap;
// /SAVE THE TREES
// /////////////////////////////////
// FIND ANY ASSOCIATED TREES
- if (Desktop.desktop != null)
+ if (Desktop.getDesktopPane() != null)
{
- javax.swing.JInternalFrame[] frames = Desktop.instance
+ javax.swing.JInternalFrame[] frames = Desktop.getInstance()
.getAllFrames();
for (int t = 0; t < frames.length; t++)
// and
// mapValuesToString
fromxml.setSkipList(skipList);
- jalview.util.jarInputStreamProvider jprovider = new jalview.util.jarInputStreamProvider()
+ jarInputStreamProvider jprovider = new jarInputStreamProvider()
{
@Override
"Returning client input stream for Jalview from Vamsas Document.");
return new JarInputStream(cappdata.getClientInputStream());
}
+
+ @Override
+ public File getFile()
+ {
+ return null;
+ }
};
if (dojvsync)
{
fromxml.setSkipList(skipList);
fromxml.setObjectMappingTables(mapKeysToString(vobj2jv),
mapValuesToString(jv2vobj));
- jalview.util.jarInputStreamProvider jarstream = new jalview.util.jarInputStreamProvider()
+ jarInputStreamProvider jarstream = new jarInputStreamProvider()
{
@Override
"Returning user input stream for Jalview from Vamsas Document.");
return new JarInputStream(cappdata.getUserInputStream());
}
+
+ @Override
+ public File getFile()
+ {
+ return null;
+ }
};
if (dojvsync)
{
if (mappings != null)
{
jalview.structure.StructureSelectionManager
- .getStructureSelectionManager(Desktop.instance)
+ .getStructureSelectionManager(Desktop.getInstance())
.registerMappings(mappings);
}
}
{
// This must be outside the run() body as java 1.5
// will not return any value from the OptionPane to the expired thread.
- int reply = JvOptionPane.showConfirmDialog(Desktop.desktop,
+ int reply = JvOptionPane.showConfirmDialog(Desktop.getDesktopPane(),
"Automatically update suggested ids?",
"Auto replace sequence ids", JvOptionPane.YES_NO_OPTION);
*/
package jalview.io.cache;
+import jalview.bin.ApplicationSingletonProvider;
+import jalview.bin.ApplicationSingletonProvider.ApplicationSingletonI;
import jalview.bin.Cache;
import java.util.Hashtable;
* @author tcnofoegbu
*
*/
-public class AppCache
+public class AppCache implements ApplicationSingletonI
{
+
+ public static AppCache getInstance()
+ {
+ return (AppCache) ApplicationSingletonProvider.getInstance(AppCache.class);
+ }
+
+ private AppCache()
+ {
+ cacheItems = new Hashtable<String, LinkedHashSet<String>>();
+ }
+
public static final String DEFAULT_LIMIT = "99";
public static final String CACHE_DELIMITER = ";";
- private static AppCache instance = null;
-
private static final String DEFAULT_LIMIT_KEY = ".DEFAULT_LIMIT";
private Hashtable<String, LinkedHashSet<String>> cacheItems;
- private AppCache()
- {
- cacheItems = new Hashtable<String, LinkedHashSet<String>>();
- }
/**
* Method to obtain all the cache items for a given cache key
}
/**
- * Returns a singleton instance of AppCache
- *
- * @return
- */
- public static AppCache getInstance()
- {
- if (instance == null)
- {
- instance = new AppCache();
- }
- return instance;
- }
-
- /**
* Method for persisting cache items for a given cache key
*
* @param cacheKey
String atts = gff[ATTRIBUTES_COL];
Map<String, List<String>> attributes = parseNameValuePairs(atts);
- SequenceOntologyI so = SequenceOntologyFactory.getInstance();
+ SequenceOntologyI so = SequenceOntologyFactory.getSequenceOntology();
if (so.isA(soTerm, SequenceOntologyI.PROTEIN_MATCH))
{
sf = processProteinMatch(attributes, seq, gff, align, newseqs,
desc = target.split(" ")[0];
}
- SequenceOntologyI so = SequenceOntologyFactory.getInstance();
+ SequenceOntologyI so = SequenceOntologyFactory.getSequenceOntology();
String type = sf.getType();
if (so.isA(type, SequenceOntologyI.SEQUENCE_VARIANT))
{
*/
public static boolean recognises(String[] columns)
{
- SequenceOntologyI so = SequenceOntologyFactory.getInstance();
+ SequenceOntologyI so = SequenceOntologyFactory.getSequenceOntology();
String type = columns[TYPE_COL];
if (so.isA(type, SequenceOntologyI.PROTEIN_MATCH)
|| (".".equals(columns[SOURCE_COL])
*/
package jalview.io.gff;
+import jalview.bin.ApplicationSingletonProvider;
+import jalview.bin.ApplicationSingletonProvider.ApplicationSingletonI;
+
/**
* 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
* @author gmcarstairs
*
*/
-public class SequenceOntologyFactory
+public class SequenceOntologyFactory implements ApplicationSingletonI
{
- private static SequenceOntologyI instance;
+ /**
+ * Answers an instance of this class for the current application context. Note
+ * that this supports running two JS 'applets' on the same page, one with the
+ * full Sequence Ontology (USE_FULL_SO = true) and one with a hard-coded
+ * subset (USE_FULL_SO = false). If this is overkill, could change this method
+ * to just return a common static instance.
+ *
+ * @return
+ */
+ private static synchronized SequenceOntologyFactory getInstance()
+ {
+ return (SequenceOntologyFactory) ApplicationSingletonProvider
+ .getInstance(SequenceOntologyFactory.class);
+ }
+
+ private SequenceOntologyFactory()
+ {
+ // private singleton
+ }
+
- public static synchronized SequenceOntologyI getInstance()
+ /**
+ * Answers the configured model of the Sequence Ontology.
+ *
+ * @return
+ */
+ public static synchronized SequenceOntologyI getSequenceOntology()
{
- if (instance == null)
- {
- instance = new SequenceOntologyLite();
- }
- return instance;
+ SequenceOntologyFactory f = getInstance();
+ return (f.sequenceOntology == null
+ ? f.sequenceOntology = new SequenceOntologyLite()
+ : f.sequenceOntology);
}
- public static void setInstance(SequenceOntologyI so)
+ /**
+ * For testng only
+ *
+ * @param so
+ */
+ public static void setSequenceOntology(SequenceOntologyI so)
{
- instance = so;
+ getInstance().sequenceOntology = so;
}
+
+
+ private SequenceOntologyI sequenceOntology;
+
}
*/
package jalview.io.packed;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
import java.util.Locale;
import jalview.api.FeatureColourI;
import jalview.io.IdentifyFile;
import jalview.io.packed.DataProvider.JvDataType;
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
public class ParsePackedSet
{
}
bindjvvobj(mapping, sequenceMapping);
jalview.structure.StructureSelectionManager
- .getStructureSelectionManager(Desktop.instance)
+ .getStructureSelectionManager(Desktop.getInstance())
.registerMapping(acf);
// Try to link up any conjugate database references in the two sequences
// matchConjugateDBRefs(from, to, mapping);
if (logger == null)
{
registry.put(name, logger = new Logger(name));
- logger.setLevel(Level.INFO);
+ logger.setLevel(Level.DEBUG);
}
return logger;
}
{
return isEnabled;
}
+
+ public void trace(Object o)
+ {
+ trace(o, null);
+ }
+
+ public void trace(Object o, Throwable e)
+ {
+ switch (level.level)
+ {
+ case Level.TRACE_INT:
+ log(o, e);
+ break;
+ }
+ }
public void debug(Object o)
{
{
switch (level.level)
{
- case Priority.FATAL_INT:
- case Priority.ERROR_INT:
- case Priority.WARN_INT:
- case Priority.INFO_INT:
case Priority.DEBUG_INT:
+ case Level.TRACE_INT:
log(o, e);
break;
}
{
switch (level.level)
{
- case Priority.FATAL_INT:
- case Priority.ERROR_INT:
- case Priority.WARN_INT:
case Priority.INFO_INT:
+ case Priority.DEBUG_INT:
+ case Level.TRACE_INT:
log(o, e);
break;
}
{
switch (level.level)
{
- case Priority.FATAL_INT:
- case Priority.ERROR_INT:
case Priority.WARN_INT:
+ case Priority.INFO_INT:
+ case Priority.DEBUG_INT:
+ case Level.TRACE_INT:
log(o, e);
break;
}
{
switch (level.level)
{
- case Priority.FATAL_INT:
case Priority.ERROR_INT:
+ case Priority.WARN_INT:
+ case Priority.INFO_INT:
+ case Priority.DEBUG_INT:
+ case Level.TRACE_INT:
log(o, e);
break;
}
switch (level.level)
{
case Priority.ERROR_INT:
- if (appender == null)
- {
- System.err.println(s);
- return;
- }
- break;
case Priority.WARN_INT:
if (appender == null)
{
System.err.println(s);
return;
}
- break;
case Priority.INFO_INT:
- if (appender == null)
- {
- System.out.println(s);
- return;
- }
- break;
case Priority.DEBUG_INT:
+ case Level.TRACE_INT:
if (appender == null)
{
System.out.println(s);
}
break;
}
- e.printStackTrace();
+ if (e != null)
+ {
+ e.printStackTrace();
+ }
appender.append(new LoggingEvent(this, s.toString(), level));
}
*/
package jalview.jbgui;
-import jalview.analysis.AnnotationSorter.SequenceAnnotationOrder;
-import jalview.analysis.GeneticCodeI;
-import jalview.analysis.GeneticCodes;
-import jalview.api.SplitContainerI;
-import jalview.bin.Cache;
-import jalview.gui.JvSwingUtils;
-import jalview.gui.Preferences;
-import jalview.io.FileFormats;
-import jalview.schemes.ResidueColourScheme;
-import jalview.util.MessageManager;
-import jalview.util.Platform;
-
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.GridLayout;
import java.awt.event.ActionListener;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
+import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
+import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import javax.swing.event.MenuEvent;
import javax.swing.event.MenuListener;
+import jalview.analysis.AnnotationSorter.SequenceAnnotationOrder;
+import jalview.analysis.GeneticCodeI;
+import jalview.analysis.GeneticCodes;
+import jalview.api.SplitContainerI;
+import jalview.bin.Cache;
+import jalview.gui.JvSwingUtils;
+import jalview.gui.Preferences;
+import jalview.hmmer.HmmerCommand;
+import jalview.io.FileFormatException;
+import jalview.io.FileFormats;
+import jalview.schemes.ResidueColourScheme;
+import jalview.util.MessageManager;
+import jalview.util.Platform;
+
+
@SuppressWarnings("serial")
public class GAlignFrame extends JInternalFrame
{
public JMenu webService = new JMenu();// BH 2019 was protected, but not
// sufficient for AlignFrame thread run
+ // JBP - followed suite for these other service related GUI elements.
+ // TODO: check we really need these to be public
+ public JMenu hmmerMenu = new JMenu();
- public JMenuItem webServiceNoServices;// BH 2019 was protected, but not
- // sufficient for AlignFrame thread run
+ public JMenuItem webServiceNoServices;
protected JCheckBoxMenuItem viewBoxesMenuItem = new JCheckBoxMenuItem();
protected JCheckBoxMenuItem normaliseSequenceLogo = new JCheckBoxMenuItem();
+ protected JCheckBoxMenuItem showInformationHistogram = new JCheckBoxMenuItem();
+
+ protected JCheckBoxMenuItem showHMMSequenceLogo = new JCheckBoxMenuItem();
+
+ protected JCheckBoxMenuItem normaliseHMMSequenceLogo = new JCheckBoxMenuItem();
+
protected JCheckBoxMenuItem applyAutoAnnotationSettings = new JCheckBoxMenuItem();
protected JMenuItem openFeatureSettings;
{
// for Web-page embedding using id=align-frame-div
- setName("jalview-alignment");
+ setName(Platform.getAppID("alignment"));
+
jbInit();
setJMenuBar(alignFrameMenuBar);
private void jbInit() throws Exception
{
initColourMenu();
-
+
JMenuItem saveAs = new JMenuItem(
MessageManager.getString("action.save_as"));
ActionListener al = new ActionListener()
saveAs_actionPerformed();
}
};
-
+
// FIXME getDefaultToolkit throws an exception in Headless mode
- KeyStroke keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_S,
- jalview.util.ShortcutKeyMaskExWrapper.getMenuShortcutKeyMaskEx()
- | jalview.util.ShortcutKeyMaskExWrapper.SHIFT_DOWN_MASK,
+ KeyStroke keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_S, Platform.SHORTCUT_KEY_MASK | InputEvent.SHIFT_DOWN_MASK,
false);
addMenuActionAndAccelerator(keyStroke, saveAs, al);
-
+
closeMenuItem.setText(MessageManager.getString("action.close"));
- keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_W,
- jalview.util.ShortcutKeyMaskExWrapper.getMenuShortcutKeyMaskEx(), false);
+ keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_W, Platform.SHORTCUT_KEY_MASK, false);
al = new ActionListener()
{
@Override
}
};
addMenuActionAndAccelerator(keyStroke, closeMenuItem, al);
-
+
JMenu editMenu = new JMenu(MessageManager.getString("action.edit"));
JMenu viewMenu = new JMenu(MessageManager.getString("action.view"));
JMenu annotationsMenu = new JMenu(
JMenu calculateMenu = new JMenu(
MessageManager.getString("action.calculate"));
webService.setText(MessageManager.getString("action.web_service"));
+
+ initHMMERMenu();
+
JMenuItem selectAllSequenceMenuItem = new JMenuItem(
MessageManager.getString("action.select_all"));
keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_A,
- jalview.util.ShortcutKeyMaskExWrapper.getMenuShortcutKeyMaskEx(), false);
+ Platform.SHORTCUT_KEY_MASK, false);
al = new ActionListener()
{
@Override
}
};
addMenuActionAndAccelerator(keyStroke, selectAllSequenceMenuItem, al);
-
+
JMenuItem deselectAllSequenceMenuItem = new JMenuItem(
MessageManager.getString("action.deselect_all"));
keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0, false);
}
};
addMenuActionAndAccelerator(keyStroke, deselectAllSequenceMenuItem, al);
-
+
JMenuItem invertSequenceMenuItem = new JMenuItem(
MessageManager.getString("action.invert_sequence_selection"));
keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_I,
- jalview.util.ShortcutKeyMaskExWrapper.getMenuShortcutKeyMaskEx(), false);
+ Platform.SHORTCUT_KEY_MASK, false);
al = new ActionListener()
{
@Override
}
};
addMenuActionAndAccelerator(keyStroke, invertSequenceMenuItem, al);
-
+
JMenuItem grpsFromSelection = new JMenuItem(
MessageManager.getString("action.make_groups_selection"));
grpsFromSelection.addActionListener(new ActionListener()
JMenuItem remove2LeftMenuItem = new JMenuItem(
MessageManager.getString("action.remove_left"));
keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_L,
- jalview.util.ShortcutKeyMaskExWrapper.getMenuShortcutKeyMaskEx(), false);
+ Platform.SHORTCUT_KEY_MASK, false);
al = new ActionListener()
{
@Override
}
};
addMenuActionAndAccelerator(keyStroke, remove2LeftMenuItem, al);
-
+
JMenuItem remove2RightMenuItem = new JMenuItem(
MessageManager.getString("action.remove_right"));
keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_R,
- jalview.util.ShortcutKeyMaskExWrapper.getMenuShortcutKeyMaskEx(), false);
+ Platform.SHORTCUT_KEY_MASK, false);
al = new ActionListener()
{
@Override
}
};
addMenuActionAndAccelerator(keyStroke, remove2RightMenuItem, al);
-
+
JMenuItem removeGappedColumnMenuItem = new JMenuItem(
MessageManager.getString("action.remove_empty_columns"));
keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_E,
- jalview.util.ShortcutKeyMaskExWrapper.getMenuShortcutKeyMaskEx(), false);
+ Platform.SHORTCUT_KEY_MASK, false);
al = new ActionListener()
{
@Override
}
};
addMenuActionAndAccelerator(keyStroke, removeGappedColumnMenuItem, al);
-
+
JMenuItem removeAllGapsMenuItem = new JMenuItem(
MessageManager.getString("action.remove_all_gaps"));
keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_E,
- jalview.util.ShortcutKeyMaskExWrapper.getMenuShortcutKeyMaskEx()
- | jalview.util.ShortcutKeyMaskExWrapper.SHIFT_DOWN_MASK,
+ Platform.SHORTCUT_KEY_MASK
+ | InputEvent.SHIFT_DOWN_MASK,
false);
al = new ActionListener()
{
}
};
addMenuActionAndAccelerator(keyStroke, removeAllGapsMenuItem, al);
-
+
JMenuItem justifyLeftMenuItem = new JMenuItem(
MessageManager.getString("action.left_justify_alignment"));
justifyLeftMenuItem.addActionListener(new ActionListener()
sortGroupMenuItem_actionPerformed(e);
}
});
-
+ JMenuItem sortEValueMenuItem = new JMenuItem(
+ MessageManager.getString("action.by_evalue"));
+ sortEValueMenuItem.addActionListener(new ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ sortEValueMenuItem_actionPerformed(e);
+ }
+ });
+ JMenuItem sortBitScoreMenuItem = new JMenuItem(
+ MessageManager.getString("action.by_bit_score"));
+ sortBitScoreMenuItem.addActionListener(new ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ sortBitScoreMenuItem_actionPerformed(e);
+ }
+ });
+
JMenuItem removeRedundancyMenuItem = new JMenuItem(
MessageManager.getString("action.remove_redundancy"));
keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_D,
- jalview.util.ShortcutKeyMaskExWrapper.getMenuShortcutKeyMaskEx(), false);
+ Platform.SHORTCUT_KEY_MASK, false);
al = new ActionListener()
{
@Override
};
addMenuActionAndAccelerator(keyStroke, removeRedundancyMenuItem, al);
+ JMenuItem filterByEValue = new JMenuItem(
+ MessageManager.getString("action.filter_by_evalue"));
+ filterByEValue.addActionListener(new ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ filterByEValue_actionPerformed();
+ }
+
+ });
+
+ JMenuItem filterByScore = new JMenuItem(
+ MessageManager.getString("action.filter_by_score"));
+ filterByScore.addActionListener(new ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ filterByScore_actionPerformed();
+ }
+
+ });
+
JMenuItem pairwiseAlignmentMenuItem = new JMenuItem(
MessageManager.getString("action.pairwise_alignment"));
pairwiseAlignmentMenuItem.addActionListener(new ActionListener()
pairwiseAlignmentMenuItem_actionPerformed(e);
}
});
-
+
this.getContentPane().setLayout(new BorderLayout());
alignFrameMenuBar.setFont(new java.awt.Font("Verdana", 0, 11));
statusBar.setBackground(Color.white);
statusBar.setFont(new java.awt.Font("Verdana", 0, 11));
statusBar.setBorder(BorderFactory.createLineBorder(Color.black));
statusBar.setText(MessageManager.getString("label.status_bar"));
+
outputTextboxMenu
.setText(MessageManager.getString("label.out_to_textbox"));
+
annotationPanelMenuItem.setActionCommand("");
annotationPanelMenuItem
.setText(MessageManager.getString("label.show_annotations"));
final JCheckBoxMenuItem sortAnnByLabel = new JCheckBoxMenuItem(
MessageManager.getString("label.sort_annotations_by_label"));
+
sortAnnBySequence.setSelected(
sortAnnotationsBy == SequenceAnnotationOrder.SEQUENCE_AND_LABEL);
sortAnnBySequence.addActionListener(new ActionListener()
colourTextMenuItem_actionPerformed(e);
}
});
-
+
JMenuItem htmlMenuItem = new JMenuItem(
MessageManager.getString("label.html"));
htmlMenuItem.addActionListener(new ActionListener()
htmlMenuItem_actionPerformed(e);
}
});
-
+
JMenuItem createBioJS = new JMenuItem(
MessageManager.getString("label.biojs_html_export"));
createBioJS.addActionListener(new java.awt.event.ActionListener()
bioJSMenuItem_actionPerformed(e);
}
});
-
+
JMenuItem overviewMenuItem = new JMenuItem(
MessageManager.getString("label.overview_window"));
overviewMenuItem.addActionListener(new ActionListener()
overviewMenuItem_actionPerformed(e);
}
});
-
+
undoMenuItem.setEnabled(false);
undoMenuItem.setText(MessageManager.getString("action.undo"));
keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_Z,
- jalview.util.ShortcutKeyMaskExWrapper.getMenuShortcutKeyMaskEx(), false);
+ Platform.SHORTCUT_KEY_MASK, false);
al = new ActionListener()
{
@Override
}
};
addMenuActionAndAccelerator(keyStroke, undoMenuItem, al);
-
+
redoMenuItem.setEnabled(false);
redoMenuItem.setText(MessageManager.getString("action.redo"));
keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_Y,
- jalview.util.ShortcutKeyMaskExWrapper.getMenuShortcutKeyMaskEx(), false);
+ Platform.SHORTCUT_KEY_MASK, false);
al = new ActionListener()
{
@Override
}
};
addMenuActionAndAccelerator(keyStroke, redoMenuItem, al);
-
+
wrapMenuItem.setText(MessageManager.getString("label.wrap"));
wrapMenuItem.addActionListener(new ActionListener()
{
wrapMenuItem_actionPerformed(e);
}
});
-
+
JMenuItem printMenuItem = new JMenuItem(
MessageManager.getString("action.print"));
keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_P,
- jalview.util.ShortcutKeyMaskExWrapper.getMenuShortcutKeyMaskEx(), false);
+ Platform.SHORTCUT_KEY_MASK, false);
al = new ActionListener()
{
@Override
}
};
addMenuActionAndAccelerator(keyStroke, printMenuItem, al);
-
+
renderGapsMenuItem
.setText(MessageManager.getString("action.show_gaps"));
renderGapsMenuItem.setState(true);
renderGapsMenuItem_actionPerformed(e);
}
});
-
+
JMenuItem findMenuItem = new JMenuItem(
MessageManager.getString("action.find"));
keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_F,
- jalview.util.ShortcutKeyMaskExWrapper.getMenuShortcutKeyMaskEx(), false);
+ Platform.SHORTCUT_KEY_MASK, false);
findMenuItem.setToolTipText(JvSwingUtils.wrapTooltip(true,
MessageManager.getString("label.find_tip")));
al = new ActionListener()
showSeqFeatures.setText(
MessageManager.getString("label.show_sequence_features"));
+
showSeqFeatures.addActionListener(new ActionListener()
{
@Override
.setText(MessageManager.getString("label.show_database_refs"));
showDbRefsMenuitem.addActionListener(new ActionListener()
{
-
+
@Override
public void actionPerformed(ActionEvent e)
{
showDbRefs_actionPerformed(e);
}
-
+
});
showNpFeatsMenuitem.setText(
MessageManager.getString("label.show_non_positional_features"));
showNpFeatsMenuitem.addActionListener(new ActionListener()
{
-
+
@Override
public void actionPerformed(ActionEvent e)
{
showNpFeats_actionPerformed(e);
}
-
+
});
showGroupConservation
.setText(MessageManager.getString("label.group_conservation"));
showGroupConservation.addActionListener(new ActionListener()
{
-
+
@Override
public void actionPerformed(ActionEvent e)
{
showGroupConservation_actionPerformed(e);
}
-
+
});
showGroupConsensus
.setText(MessageManager.getString("label.group_consensus"));
showGroupConsensus.addActionListener(new ActionListener()
{
-
+
@Override
public void actionPerformed(ActionEvent e)
{
showGroupConsensus_actionPerformed(e);
}
-
+
});
showConsensusHistogram.setText(
MessageManager.getString("label.show_consensus_histogram"));
showConsensusHistogram.addActionListener(new ActionListener()
{
-
+
@Override
public void actionPerformed(ActionEvent e)
{
showConsensusHistogram_actionPerformed(e);
}
-
+
});
showSequenceLogo
.setText(MessageManager.getString("label.show_consensus_logo"));
showSequenceLogo.addActionListener(new ActionListener()
{
-
+
@Override
public void actionPerformed(ActionEvent e)
{
showSequenceLogo_actionPerformed(e);
}
-
+
});
normaliseSequenceLogo
.setText(MessageManager.getString("label.norm_consensus_logo"));
normaliseSequenceLogo.addActionListener(new ActionListener()
{
-
+
@Override
public void actionPerformed(ActionEvent e)
{
normaliseSequenceLogo_actionPerformed(e);
}
-
+
});
applyAutoAnnotationSettings
.setText(MessageManager.getString("label.apply_all_groups"));
applyAutoAnnotationSettings_actionPerformed(e);
}
});
-
+
ButtonGroup buttonGroup = new ButtonGroup();
final JRadioButtonMenuItem showAutoFirst = new JRadioButtonMenuItem(
MessageManager.getString("label.show_first"));
sortAnnotations_actionPerformed();
}
});
-
+
JMenuItem deleteGroups = new JMenuItem(
MessageManager.getString("action.undefine_groups"));
keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_U,
- jalview.util.ShortcutKeyMaskExWrapper.getMenuShortcutKeyMaskEx(), false);
+ Platform.SHORTCUT_KEY_MASK, false);
al = new ActionListener()
{
@Override
}
};
addMenuActionAndAccelerator(keyStroke, deleteGroups, al);
-
+
JMenuItem annotationColumn = new JMenuItem(
MessageManager.getString("action.select_by_annotation"));
annotationColumn.addActionListener(new ActionListener()
annotationColumn_actionPerformed(e);
}
});
-
+
JMenuItem createGroup = new JMenuItem(
MessageManager.getString("action.create_group"));
keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_G,
- jalview.util.ShortcutKeyMaskExWrapper.getMenuShortcutKeyMaskEx(), false);
+ Platform.SHORTCUT_KEY_MASK, false);
al = new ActionListener()
{
@Override
}
};
addMenuActionAndAccelerator(keyStroke, createGroup, al);
-
+
JMenuItem unGroup = new JMenuItem(
MessageManager.getString("action.remove_group"));
keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_G,
- jalview.util.ShortcutKeyMaskExWrapper.getMenuShortcutKeyMaskEx()
- | jalview.util.ShortcutKeyMaskExWrapper.SHIFT_DOWN_MASK,
+ Platform.SHORTCUT_KEY_MASK
+ | InputEvent.SHIFT_DOWN_MASK,
false);
al = new ActionListener()
{
}
};
addMenuActionAndAccelerator(keyStroke, unGroup, al);
-
+
copy.setText(MessageManager.getString("action.copy"));
keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_C,
- jalview.util.ShortcutKeyMaskExWrapper.getMenuShortcutKeyMaskEx(), false);
+ Platform.SHORTCUT_KEY_MASK, false);
al = new ActionListener()
{
}
};
addMenuActionAndAccelerator(keyStroke, copy, al);
-
+
cut.setText(MessageManager.getString("action.cut"));
keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_X,
- jalview.util.ShortcutKeyMaskExWrapper.getMenuShortcutKeyMaskEx(), false);
+ Platform.SHORTCUT_KEY_MASK, false);
al = new ActionListener()
{
@Override
}
};
addMenuActionAndAccelerator(keyStroke, cut, al);
-
+
JMenuItem delete = new JMenuItem(
MessageManager.getString("action.delete"));
delete.addActionListener(new ActionListener()
delete_actionPerformed();
}
});
-
+
pasteMenu.setText(MessageManager.getString("action.paste"));
JMenuItem pasteNew = new JMenuItem(
MessageManager.getString("label.to_new_alignment"));
keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_V,
- jalview.util.ShortcutKeyMaskExWrapper.getMenuShortcutKeyMaskEx()
- | jalview.util.ShortcutKeyMaskExWrapper.SHIFT_DOWN_MASK,
+ Platform.SHORTCUT_KEY_MASK
+ | InputEvent.SHIFT_DOWN_MASK,
false);
al = new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
- pasteNew_actionPerformed(e);
+ try
+ {
+ pasteNew_actionPerformed(e);
+ } catch (IOException | InterruptedException e1)
+ {
+ // TODO Auto-generated catch block
+ e1.printStackTrace();
+ }
}
};
addMenuActionAndAccelerator(keyStroke, pasteNew, al);
-
+
JMenuItem pasteThis = new JMenuItem(
MessageManager.getString("label.to_this_alignment"));
keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_V,
- jalview.util.ShortcutKeyMaskExWrapper.getMenuShortcutKeyMaskEx(), false);
+ Platform.SHORTCUT_KEY_MASK, false);
al = new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
- pasteThis_actionPerformed(e);
+ try
+ {
+ pasteThis_actionPerformed(e);
+ } catch (IOException | InterruptedException e1)
+ {
+ // TODO Auto-generated catch block
+ e1.printStackTrace();
+ }
}
};
addMenuActionAndAccelerator(keyStroke, pasteThis, al);
-
+
JMenuItem createPNG = new JMenuItem("PNG");
createPNG.addActionListener(new ActionListener()
{
});
createPNG.setActionCommand(
MessageManager.getString("label.save_png_image"));
-
JMenuItem font = new JMenuItem(MessageManager.getString("action.font"));
font.addActionListener(new ActionListener()
{
createEPS(null);
}
});
-
+
JMenuItem createSVG = new JMenuItem("SVG");
createSVG.addActionListener(new ActionListener()
{
createSVG(null);
}
});
-
+
JMenuItem loadTreeMenuItem = new JMenuItem(
MessageManager.getString("label.load_associated_tree"));
loadTreeMenuItem.setActionCommand(
loadTreeMenuItem_actionPerformed(e);
}
});
-
+
scaleAbove.setVisible(false);
scaleAbove.setText(MessageManager.getString("action.scale_above"));
scaleAbove.addActionListener(new ActionListener()
.setText(MessageManager.getString("label.automatic_scrolling"));
followHighlightMenuItem.addActionListener(new ActionListener()
{
-
+
@Override
public void actionPerformed(ActionEvent e)
{
followHighlight_actionPerformed();
}
-
+
});
-
+
sortByTreeMenu
.setText(MessageManager.getString("action.by_tree_order"));
sort.setText(MessageManager.getString("action.sort"));
@Override
public void menuSelected(MenuEvent e)
{
- buildTreeSortMenu();
+ enableSortMenuOptions();
}
@Override
{
}
});
+ sortByTreeMenu.addMenuListener(new MenuListener()
+ {
+ @Override
+ public void menuSelected(MenuEvent e)
+ {
+ buildTreeSortMenu();
+ }
+
+ @Override
+ public void menuDeselected(MenuEvent e)
+ {
+ }
+
+ @Override
+ public void menuCanceled(MenuEvent e)
+ {
+ }
+ });
sortByAnnotScore
.setText(MessageManager.getString("label.sort_by_score"));
sort.add(sortByAnnotScore);
sort.addMenuListener(new javax.swing.event.MenuListener()
{
-
+
@Override
public void menuCanceled(MenuEvent e)
{
}
-
+
@Override
public void menuDeselected(MenuEvent e)
{
}
-
+
@Override
public void menuSelected(MenuEvent e)
{
showReverse_actionPerformed(true);
}
});
-
+
JMenuItem extractScores = new JMenuItem(
MessageManager.getString("label.extract_scores"));
extractScores.addActionListener(new ActionListener()
});
extractScores.setVisible(true);
// JBPNote: TODO: make gui for regex based score extraction
-
+
// for show products actions see AlignFrame.canShowProducts
showProducts.setText(MessageManager.getString("label.get_cross_refs"));
-
+
runGroovy.setText(MessageManager.getString("label.run_groovy"));
runGroovy.setToolTipText(
MessageManager.getString("label.run_groovy_tip"));
fetchSequence_actionPerformed();
}
});
-
+
JMenuItem associatedData = new JMenuItem(
MessageManager.getString("label.load_features_annotations"));
associatedData.addActionListener(new ActionListener()
@Override
public void actionPerformed(ActionEvent e)
{
- associatedData_actionPerformed(e);
+ try
+ {
+ associatedData_actionPerformed(e);
+ } catch (IOException | InterruptedException e1)
+ {
+ // TODO Auto-generated catch block
+ e1.printStackTrace();
+ }
}
});
loadVcf = new JMenuItem(
listenToViewSelections_actionPerformed(e);
}
});
-
+
JMenu addSequenceMenu = new JMenu(
MessageManager.getString("label.add_sequences"));
JMenuItem addFromFile = new JMenuItem(
hiddenMarkers_actionPerformed(e);
}
});
-
+
JMenuItem invertColSel = new JMenuItem(
MessageManager.getString("action.invert_column_selection"));
keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_I,
- jalview.util.ShortcutKeyMaskExWrapper.getMenuShortcutKeyMaskEx()
- | jalview.util.ShortcutKeyMaskExWrapper.ALT_DOWN_MASK,
+ Platform.SHORTCUT_KEY_MASK
+ | InputEvent.ALT_DOWN_MASK,
false);
al = new ActionListener()
{
}
};
addMenuActionAndAccelerator(keyStroke, invertColSel, al);
-
+
showComplementMenuItem.setVisible(false);
showComplementMenuItem.addActionListener(new ActionListener()
{
showComplement_actionPerformed(showComplementMenuItem.getState());
}
});
-
+
tabbedPane.addChangeListener(new javax.swing.event.ChangeListener()
{
@Override
tabbedPane_mousePressed(e);
}
}
-
+
@Override
public void mouseReleased(MouseEvent e)
{
tabbedPane_focusGained(e);
}
});
-
+
JMenuItem save = new JMenuItem(MessageManager.getString("action.save"));
keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_S,
- jalview.util.ShortcutKeyMaskExWrapper.getMenuShortcutKeyMaskEx(), false);
+ Platform.SHORTCUT_KEY_MASK, false);
al = new ActionListener()
{
@Override
}
};
addMenuActionAndAccelerator(keyStroke, save, al);
-
+
reload.setEnabled(false);
reload.setText(MessageManager.getString("action.reload"));
reload.addActionListener(new ActionListener()
reload_actionPerformed(e);
}
});
-
+
JMenuItem newView = new JMenuItem(
MessageManager.getString("action.new_view"));
keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_T,
- jalview.util.ShortcutKeyMaskExWrapper.getMenuShortcutKeyMaskEx(), false);
+ Platform.SHORTCUT_KEY_MASK, false);
al = new ActionListener()
{
@Override
}
};
addMenuActionAndAccelerator(keyStroke, newView, al);
-
+
tabbedPane.setToolTipText("<html><i>"
+ MessageManager.getString("label.rename_tab_eXpand_reGroup")
+ "</i></html>");
-
+
formatMenu.setText(MessageManager.getString("action.format"));
JMenu selectMenu = new JMenu(MessageManager.getString("action.select"));
idRightAlign_actionPerformed(e);
}
});
-
+
gatherViews.setEnabled(false);
gatherViews.setText(MessageManager.getString("action.gather_views"));
keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_G, 0, false);
}
};
addMenuActionAndAccelerator(keyStroke, gatherViews, al);
-
+
expandViews.setEnabled(false);
expandViews.setText(MessageManager.getString("action.expand_views"));
keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_X, 0, false);
}
};
addMenuActionAndAccelerator(keyStroke, expandViews, al);
-
+
JMenuItem pageSetup = new JMenuItem(
MessageManager.getString("action.page_setup"));
pageSetup.addActionListener(new ActionListener()
});
JMenuItem selectHighlighted = new JMenuItem(
MessageManager.getString("action.select_highlighted_columns"));
+ selectHighlighted.setToolTipText(JvSwingUtils.wrapTooltip(true,
+ MessageManager.getString("tooltip.select_highlighted_columns")));
+ al = new ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent actionEvent)
+ {
+ selectHighlightedColumns_actionPerformed(actionEvent);
+ }
+ };
+ JMenuItem Filter = new JMenuItem(
+ MessageManager.getString("action.select_highlighted_columns"));
selectHighlighted.setToolTipText(
MessageManager.getString("tooltip.select_highlighted_columns"));
al = new ActionListener()
MessageManager.getString("label.sequence_id_tooltip"));
JMenu autoAnnMenu = new JMenu(
MessageManager.getString("label.autocalculated_annotation"));
-
+
JMenu exportImageMenu = new JMenu(
MessageManager.getString("label.export_image"));
JMenu fileMenu = new JMenu(MessageManager.getString("action.file"));
alignFrameMenuBar.add(formatMenu);
alignFrameMenuBar.add(colourMenu);
alignFrameMenuBar.add(calculateMenu);
+ alignFrameMenuBar.add(webService);
if (!Platform.isJS())
{
- alignFrameMenuBar.add(webService);
+ alignFrameMenuBar.add(hmmerMenu);
}
-
+
fileMenu.add(fetchSequence);
fileMenu.add(addSequenceMenu);
fileMenu.add(reload);
}
fileMenu.addSeparator();
fileMenu.add(closeMenuItem);
-
+
pasteMenu.add(pasteNew);
pasteMenu.add(pasteThis);
editMenu.add(undoMenuItem);
// editMenu.add(justifyRightMenuItem);
// editMenu.addSeparator();
editMenu.add(padGapsMenuitem);
-
+ editMenu.addSeparator();
+ editMenu.add(filterByEValue);
+ editMenu.add(filterByScore);
+
showMenu.add(showAllColumns);
showMenu.add(showAllSeqs);
showMenu.add(showAllhidden);
viewMenu.add(alignmentProperties);
viewMenu.addSeparator();
viewMenu.add(overviewMenuItem);
-
+
annotationsMenu.add(annotationPanelMenuItem);
annotationsMenu.addSeparator();
annotationsMenu.add(showAllAlAnnotations);
sort.add(sortLengthMenuItem);
sort.add(sortGroupMenuItem);
sort.add(sortPairwiseMenuItem);
+ sort.add(sortEValueMenuItem);
+ sort.add(sortBitScoreMenuItem);
sort.add(sortByTreeMenu);
calculateMenu.add(sort);
calculateMenu.add(calculateTree);
calculateMenu.addSeparator();
calculateMenu.add(runGroovy);
}
-
webServiceNoServices = new JMenuItem(
MessageManager.getString("label.no_services"));
webService.add(webServiceNoServices);
this.getContentPane().add(statusPanel, java.awt.BorderLayout.SOUTH);
statusPanel.add(statusBar, null);
this.getContentPane().add(tabbedPane, java.awt.BorderLayout.CENTER);
-
+
formatMenu.add(font);
formatMenu.addSeparator();
formatMenu.add(wrapMenuItem);
// selectMenu.add(listenToViewSelections);
}
+ /**
+ * Constructs the entries on the HMMER menu
+ */
+ protected void initHMMERMenu()
+ {
+ /*
+ * hmmbuild
+ */
+ JMenu hmmBuild = new JMenu(MessageManager.getString("label.hmmbuild"));
+ JMenuItem hmmBuildSettings = new JMenuItem(
+ MessageManager.getString("label.edit_settings_and_run"));
+ hmmBuildSettings.addActionListener(new ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ hmmBuild_actionPerformed(false);
+ }
+ });
+ JMenuItem hmmBuildRun = new JMenuItem(MessageManager.formatMessage(
+ "label.action_with_default_settings", "hmmbuild"));
+ hmmBuildRun.addActionListener(new ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ hmmBuild_actionPerformed(true);
+ }
+ });
+ hmmBuild.add(hmmBuildRun);
+ hmmBuild.add(hmmBuildSettings);
+
+ /*
+ * hmmalign
+ */
+ JMenu hmmAlign = new JMenu(MessageManager.getString("label.hmmalign"));
+ JMenuItem hmmAlignRun = new JMenuItem(MessageManager.formatMessage(
+ "label.action_with_default_settings", "hmmalign"));
+ hmmAlignRun.addActionListener(new ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ hmmAlign_actionPerformed(true);
+ }
+ });
+ JMenuItem hmmAlignSettings = new JMenuItem(
+ MessageManager.getString("label.edit_settings_and_run"));
+ hmmAlignSettings.addActionListener(new ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ hmmAlign_actionPerformed(false);
+ }
+ });
+ hmmAlign.add(hmmAlignRun);
+ hmmAlign.add(hmmAlignSettings);
+
+ /*
+ * hmmsearch
+ */
+ JMenu hmmSearch = new JMenu(
+ MessageManager.getString("label.hmmsearch"));
+ JMenuItem hmmSearchSettings = new JMenuItem(
+ MessageManager.getString("label.edit_settings_and_run"));
+ hmmSearchSettings.addActionListener(new ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ hmmSearch_actionPerformed(false);
+ }
+ });
+ JMenuItem hmmSearchRun = new JMenuItem(MessageManager.formatMessage(
+ "label.action_with_default_settings", "hmmsearch"));
+ hmmSearchRun.addActionListener(new ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ hmmSearch_actionPerformed(true);
+ }
+ });
+ JMenuItem addDatabase = new JMenuItem(
+ MessageManager.getString("label.add_database"));
+ addDatabase.addActionListener(new ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ try
+ {
+ addDatabase_actionPerformed();
+ } catch (IOException e1)
+ {
+ e1.printStackTrace();
+ }
+ }
+ });
+ hmmSearch.add(hmmSearchRun);
+ hmmSearch.add(hmmSearchSettings);
+ // hmmSearch.add(addDatabase);
+
+ /*
+ * jackhmmer
+ */
+ JMenu jackhmmer = new JMenu(
+ MessageManager.getString("label.jackhmmer"));
+ JMenuItem jackhmmerSettings = new JMenuItem(
+ MessageManager.getString("label.edit_settings_and_run"));
+ jackhmmerSettings.addActionListener(new ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ jackhmmer_actionPerformed(false);
+ }
+ });
+ JMenuItem jackhmmerRun = new JMenuItem(MessageManager.formatMessage(
+ "label.action_with_default_settings", "jackhmmer"));
+ jackhmmerRun.addActionListener(new ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ jackhmmer_actionPerformed(true);
+ }
+
+ });
+ /*
+ JMenuItem addDatabase = new JMenuItem(
+ MessageManager.getString("label.add_database"));
+ addDatabase.addActionListener(new ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ try
+ {
+ addDatabase_actionPerformed();
+ } catch (IOException e1)
+ {
+ e1.printStackTrace();
+ }
+ }
+ });
+ */
+ jackhmmer.add(jackhmmerRun);
+ jackhmmer.add(jackhmmerSettings);
+ // hmmSearch.add(addDatabase);
+
+ /*
+ * top level menu
+ */
+ hmmerMenu.setText(MessageManager.getString("action.hmmer"));
+ hmmerMenu.setEnabled(HmmerCommand.isHmmerAvailable());
+ hmmerMenu.add(hmmBuild);
+ hmmerMenu.add(hmmAlign);
+ hmmerMenu.add(hmmSearch);
+ hmmerMenu.add(jackhmmer);
+
+ }
+
+ protected void enableSortMenuOptions()
+ {
+ }
+
protected void loadVcf_actionPerformed()
{
}
{
}
+ protected void sortEValueMenuItem_actionPerformed(ActionEvent e)
+ {
+ }
+
+ protected void sortBitScoreMenuItem_actionPerformed(ActionEvent e)
+ {
+ }
+
protected void removeRedundancyMenuItem_actionPerformed(ActionEvent e)
{
}
}
protected void pasteNew_actionPerformed(ActionEvent e)
+ throws IOException, InterruptedException
{
}
protected void pasteThis_actionPerformed(ActionEvent e)
+ throws IOException, InterruptedException
{
}
{
}
+ protected void hmmBuild_actionPerformed(boolean withDefaults)
+ {
+ }
+
+ protected void hmmSearch_actionPerformed(boolean withDefaults)
+ {
+ }
+
+ protected void jackhmmer_actionPerformed(boolean b)
+ {
+ }
+
+ protected void addDatabase_actionPerformed()
+ throws FileFormatException, IOException
+ {
+ }
+
+ protected void hmmAlign_actionPerformed(boolean withDefaults)
+ {
+ }
+
public void createPNG(java.io.File f)
{
}
{
}
+ protected void filterByEValue_actionPerformed()
+ {
+ }
+
+ protected void filterByScore_actionPerformed()
+ {
+ }
+
protected void scaleRight_actionPerformed(ActionEvent e)
{
}
}
public void associatedData_actionPerformed(ActionEvent e)
+ throws IOException, InterruptedException
{
}
protected void showComplement_actionPerformed(boolean complement)
{
}
+
+
}
import jalview.gui.JvSwingUtils;
import jalview.util.MessageManager;
+import jalview.util.Platform;
import java.awt.BorderLayout;
import java.awt.Font;
});
close.setAccelerator(javax.swing.KeyStroke.getKeyStroke(
java.awt.event.KeyEvent.VK_W,
- jalview.util.ShortcutKeyMaskExWrapper
- .getMenuShortcutKeyMaskEx(),
+ Platform.SHORTCUT_KEY_MASK,
false));
selectAll.setText(MessageManager.getString("action.select_all"));
selectAll.setAccelerator(javax.swing.KeyStroke.getKeyStroke(
java.awt.event.KeyEvent.VK_A,
- jalview.util.ShortcutKeyMaskExWrapper
- .getMenuShortcutKeyMaskEx(),
+ Platform.SHORTCUT_KEY_MASK,
false));
selectAll.addActionListener(new ActionListener()
{
save.setText(MessageManager.getString("action.save"));
save.setAccelerator(javax.swing.KeyStroke.getKeyStroke(
java.awt.event.KeyEvent.VK_S,
- jalview.util.ShortcutKeyMaskExWrapper
- .getMenuShortcutKeyMaskEx(),
+ Platform.SHORTCUT_KEY_MASK,
false));
save.addActionListener(new ActionListener()
{
});
copyItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(
java.awt.event.KeyEvent.VK_C,
- jalview.util.ShortcutKeyMaskExWrapper
- .getMenuShortcutKeyMaskEx(),
+ Platform.SHORTCUT_KEY_MASK,
false));
editMenubar.add(jMenu1);
*/
package jalview.jbgui;
-import jalview.gui.JvSwingUtils;
-import jalview.util.MessageManager;
-
import java.awt.BorderLayout;
import java.awt.Font;
-import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
+import jalview.gui.JvSwingUtils;
+import jalview.util.MessageManager;
+import jalview.util.Platform;
+
/**
* DOCUMENT ME!
*
selectAll.setText(MessageManager.getString("action.select_all"));
selectAll.setAccelerator(javax.swing.KeyStroke.getKeyStroke(
java.awt.event.KeyEvent.VK_A,
- jalview.util.ShortcutKeyMaskExWrapper.getMenuShortcutKeyMaskEx(), false));
+ Platform.SHORTCUT_KEY_MASK, false));
selectAll.addActionListener(new ActionListener()
{
@Override
save.setText(MessageManager.getString("action.save"));
save.setAccelerator(javax.swing.KeyStroke.getKeyStroke(
java.awt.event.KeyEvent.VK_S,
- jalview.util.ShortcutKeyMaskExWrapper.getMenuShortcutKeyMaskEx(), false));
+ Platform.SHORTCUT_KEY_MASK, false));
save.addActionListener(new ActionListener()
{
@Override
});
copyItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(
java.awt.event.KeyEvent.VK_C,
- jalview.util.ShortcutKeyMaskExWrapper.getMenuShortcutKeyMaskEx(), false));
+ Platform.SHORTCUT_KEY_MASK, false));
pasteMenu.setAccelerator(javax.swing.KeyStroke.getKeyStroke(
java.awt.event.KeyEvent.VK_V,
- jalview.util.ShortcutKeyMaskExWrapper.getMenuShortcutKeyMaskEx(), false));
+ Platform.SHORTCUT_KEY_MASK, false));
editMenubar.add(jMenu1);
editMenubar.add(editMenu);
textarea.setFont(new java.awt.Font("Monospaced", Font.PLAIN, 12));
public class GDesktop extends JFrame
{
- protected static JMenu windowMenu = new JMenu();
+ protected JMenu windowMenu = new JMenu();
JMenuBar desktopMenubar = new JMenuBar();
*/
private void jbInit() throws Exception
{
- setName("jalview-desktop");
+
+ setName(Platform.getAppID("desktop"));
FileMenu.setText(MessageManager.getString("action.file"));
HelpMenu.setText(MessageManager.getString("action.help"));
inputLocalFileMenuItem
.setText(MessageManager.getString("label.load_tree_from_file"));
inputLocalFileMenuItem.setAccelerator(
javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_O,
- jalview.util.ShortcutKeyMaskExWrapper.getMenuShortcutKeyMaskEx(),
+ Platform.SHORTCUT_KEY_MASK,
false));
inputLocalFileMenuItem
.addActionListener(new java.awt.event.ActionListener()
import jalview.util.ImageMaker.TYPE;
import jalview.util.MessageManager;
+import jalview.util.Platform;
import java.awt.BorderLayout;
import java.awt.Color;
private void jbInit() throws Exception
{
- setName("jalview-pca");
+ setName(Platform.getAppID("pca"));
this.getContentPane().setLayout(new BorderLayout());
JPanel jPanel2 = new JPanel();
jPanel2.setLayout(new FlowLayout());
*/
package jalview.jbgui;
+import jalview.bin.Cache;
+import jalview.fts.core.FTSDataColumnPreferences;
+import jalview.fts.core.FTSDataColumnPreferences.PreferenceSource;
+import jalview.fts.service.pdb.PDBFTSRestClient;
+import jalview.gui.Desktop;
+import jalview.gui.JalviewBooleanRadioButtons;
+import jalview.gui.JvOptionPane;
+import jalview.gui.JvSwingUtils;
+import jalview.gui.StructureViewer.ViewerType;
+import jalview.io.BackupFilenameParts;
+import jalview.io.BackupFiles;
+import jalview.io.BackupFilesPresetEntry;
+import jalview.io.IntKeyStringValueEntry;
+import jalview.util.MessageManager;
+import jalview.util.Platform;
+
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.util.Arrays;
import java.util.List;
+import javax.swing.AbstractButton;
import javax.swing.AbstractCellEditor;
import javax.swing.BorderFactory;
+import javax.swing.BoxLayout;
import javax.swing.ButtonGroup;
import javax.swing.DefaultListCellRenderer;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
+import javax.swing.JComponent;
import javax.swing.JFileChooser;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableCellRenderer;
-import jalview.bin.Cache;
-import jalview.fts.core.FTSDataColumnPreferences;
-import jalview.fts.core.FTSDataColumnPreferences.PreferenceSource;
-import jalview.fts.service.pdb.PDBFTSRestClient;
-import jalview.gui.Desktop;
-import jalview.gui.JalviewBooleanRadioButtons;
-import jalview.gui.JvOptionPane;
-import jalview.gui.JvSwingUtils;
-import jalview.gui.StructureViewer.ViewerType;
-import jalview.io.BackupFilenameParts;
-import jalview.io.BackupFiles;
-import jalview.io.BackupFilesPresetEntry;
-import jalview.io.IntKeyStringValueEntry;
-import jalview.util.MessageManager;
-import jalview.util.Platform;
-
/**
* Base class for the Preferences panel.
*
protected JCheckBox showConsensLogo = new JCheckBox();
+ protected JCheckBox showInformationHistogram = new JCheckBox();
+
+ protected JCheckBox showHMMLogo = new JCheckBox();
protected JCheckBox showDbRefTooltip = new JCheckBox();
protected JCheckBox showNpTooltip = new JCheckBox();
protected JCheckBox structFromPdb = new JCheckBox();
+
protected JCheckBox addSecondaryStructure = new JCheckBox();
protected JCheckBox addTempFactor = new JCheckBox();
protected JCheckBox sortByTree = new JCheckBox();
/*
+ * hmmer tab and components
+ */
+ protected JPanel hmmerTab;
+
+ protected JCheckBox hmmrTrimTermini;
+
+ protected AbstractButton hmmerBackgroundUniprot;
+
+ protected AbstractButton hmmerBackgroundAlignment;
+
+ protected JTextField hmmerSequenceCount;
+
+ protected JTextField hmmerPath;
+
+ protected JTextField cygwinPath;
+
+ /*
* Web Services tab
*/
protected JPanel wsTab = new JPanel();
+ protected JPanel slivkaTab = new JPanel();
/*
* Backups tab components
* a lot of these are member variables instead of local variables only so that they
private final JTabbedPane tabbedPane = new JTabbedPane();
private JLabel messageLabel = new JLabel("", JLabel.CENTER);
-
/**
* Creates a new GPreferences object.
*/
{
// final JTabbedPane tabbedPane = new JTabbedPane();
this.setLayout(new BorderLayout());
-
// message label at top
this.add(messageLabel, BorderLayout.NORTH);
-
JPanel okCancelPanel = initOkCancelPanel();
this.add(tabbedPane, BorderLayout.CENTER);
this.add(okCancelPanel, BorderLayout.SOUTH);
tabbedPane.add(initEditingTab(),
MessageManager.getString("label.editing"));
+ tabbedPane.add(initHMMERTab(), MessageManager.getString("label.hmmer"));
/*
* See WsPreferences for the real work of configuring this tab.
*/
{
wsTab.setLayout(new BorderLayout());
tabbedPane.add(wsTab, MessageManager.getString("label.web_services"));
+ slivkaTab.setLayout(new BorderLayout());
+ tabbedPane.add(slivkaTab, "Slivka Services");
}
/*
}
}
lastTab = tabbedPane.getSelectedComponent();
-
clearMessage();
}
}
/**
- * Initialises the Output tab
+ * Initialises the hmmer tabbed panel
+ *
+ * @return
+ */
+ private JPanel initHMMERTab()
+ {
+ hmmerTab = new JPanel();
+ hmmerTab.setLayout(new BoxLayout(hmmerTab, BoxLayout.Y_AXIS));
+ hmmerTab.setLayout(new MigLayout("flowy"));
+
+ /*
+ * path to hmmer binaries folder
+ */
+ JPanel installationPanel = new JPanel(new MigLayout("flowy"));
+ // new FlowLayout(FlowLayout.LEFT));
+ JvSwingUtils.createTitledBorder(installationPanel,
+ MessageManager.getString("label.installation"), true);
+ hmmerTab.add(installationPanel);
+ JLabel hmmerLocation = new JLabel(
+ MessageManager.getString("label.hmmer_location"));
+ hmmerLocation.setFont(LABEL_FONT);
+ final int pathFieldLength = 40;
+ hmmerPath = new JTextField(pathFieldLength);
+ hmmerPath.addMouseListener(new MouseAdapter()
+ {
+ @Override
+ public void mouseClicked(MouseEvent e)
+ {
+ if (e.getClickCount() == 2)
+ {
+ String chosen = openFileChooser(true);
+ if (chosen != null)
+ {
+ hmmerPath.setText(chosen);
+ validateHmmerPath();
+ }
+ }
+ }
+ });
+ installationPanel.add(hmmerLocation);
+ installationPanel.add(hmmerPath);
+
+ /*
+ * path to Cygwin binaries folder (for Windows)
+ */
+ if (Platform.isWindowsAndNotJS())
+ {
+ JLabel cygwinLocation = new JLabel(
+ MessageManager.getString("label.cygwin_location"));
+ cygwinLocation.setFont(LABEL_FONT);
+ cygwinPath = new JTextField(pathFieldLength);
+ cygwinPath.addMouseListener(new MouseAdapter()
+ {
+ @Override
+ public void mouseClicked(MouseEvent e)
+ {
+ if (e.getClickCount() == 2)
+ {
+ String chosen = openFileChooser(true);
+ if (chosen != null)
+ {
+ cygwinPath.setText(chosen);
+ validateCygwinPath();
+ }
+ }
+ }
+ });
+ installationPanel.add(cygwinLocation);
+ installationPanel.add(cygwinPath);
+ }
+
+ /*
+ * preferences for hmmalign
+ */
+ JPanel alignOptionsPanel = new JPanel(new MigLayout());
+ // new FlowLayout(FlowLayout.LEFT));
+ JvSwingUtils.createTitledBorder(alignOptionsPanel,
+ MessageManager.getString("label.hmmalign_options"), true);
+ hmmerTab.add(alignOptionsPanel);
+ hmmrTrimTermini = new JCheckBox();
+ hmmrTrimTermini.setFont(LABEL_FONT);
+ hmmrTrimTermini.setText(MessageManager.getString("label.trim_termini"));
+ alignOptionsPanel.add(hmmrTrimTermini);
+
+ /*
+ * preferences for hmmsearch
+ */
+ JPanel searchOptions = new JPanel(new MigLayout());
+ // FlowLayout(FlowLayout.LEFT));
+ JvSwingUtils.createTitledBorder(searchOptions,
+ MessageManager.getString("label.hmmsearch_options"), true);
+ hmmerTab.add(searchOptions);
+ JLabel sequencesToKeep = new JLabel(
+ MessageManager.getString("label.no_of_sequences"));
+ sequencesToKeep.setFont(LABEL_FONT);
+ searchOptions.add(sequencesToKeep);
+ hmmerSequenceCount = new JTextField(5);
+ searchOptions.add(hmmerSequenceCount);
+
+ /*
+ * preferences for Information Content annotation
+ */
+ // JPanel dummy = new JPanel(new FlowLayout(FlowLayout.LEFT));
+ JPanel annotationOptions = new JPanel(new MigLayout("left"));
+ JvSwingUtils.createTitledBorder(annotationOptions,
+ MessageManager.getString("label.information_annotation"), true);
+ // dummy.add(annotationOptions);
+ hmmerTab.add(annotationOptions);
+ ButtonGroup backgroundOptions = new ButtonGroup();
+ hmmerBackgroundUniprot = new JRadioButton(
+ MessageManager.getString("label.freq_uniprot"));
+ hmmerBackgroundUniprot.setFont(LABEL_FONT);
+ hmmerBackgroundAlignment = new JRadioButton(
+ MessageManager.getString("label.freq_alignment"));
+ hmmerBackgroundAlignment.setFont(LABEL_FONT);
+ backgroundOptions.add(hmmerBackgroundUniprot);
+ backgroundOptions.add(hmmerBackgroundAlignment);
+ backgroundOptions.setSelected(hmmerBackgroundUniprot.getModel(), true);
+ // disable buttons for now as annotation only uses Uniprot background
+ hmmerBackgroundAlignment.setEnabled(false);
+ hmmerBackgroundUniprot.setEnabled(false);
+ annotationOptions.add(hmmerBackgroundUniprot, "wrap");
+ annotationOptions.add(hmmerBackgroundAlignment);
+
+ return hmmerTab;
+ }
+
+ /**
+ * Initialises the Output tabbed panel.
*
* @return
*/
proxyAuth_actionPerformed();
}
});
-
setCustomProxyEnabled();
// Make proxy server panel
protColourLabel.setHorizontalAlignment(SwingConstants.LEFT);
protColourLabel.setText(
MessageManager.getString("label.prot_alignment_colour") + " ");
- JvSwingUtils.addtoLayout(coloursTab,
+ GPreferences.addtoLayout(coloursTab,
MessageManager
.getString("label.default_colour_scheme_for_alignment"),
protColourLabel, protColour);
nucColourLabel.setHorizontalAlignment(SwingConstants.LEFT);
nucColourLabel.setText(
MessageManager.getString("label.nuc_alignment_colour") + " ");
- JvSwingUtils.addtoLayout(coloursTab,
+ GPreferences.addtoLayout(coloursTab,
MessageManager
.getString("label.default_colour_scheme_for_alignment"),
nucColourLabel, nucColour);
annotationShding.setBorder(new TitledBorder(
MessageManager.getString("label.annotation_shading_default")));
annotationShding.setLayout(new GridLayout(1, 2));
- JvSwingUtils.addtoLayout(annotationShding,
+ GPreferences.addtoLayout(annotationShding,
MessageManager.getString(
"label.default_minimum_colour_annotation_shading"),
mincolourLabel, minColour);
- JvSwingUtils.addtoLayout(annotationShding,
+ GPreferences.addtoLayout(annotationShding,
MessageManager.getString(
"label.default_maximum_colour_annotation_shading"),
maxcolourLabel, maxColour);
structureTab.add(structFromPdb);
// indent checkboxes that are conditional on the first one
+
ypos += lineSpacing;
addSecondaryStructure.setFont(LABEL_FONT);
addSecondaryStructure
{
if (structureViewerPath.isEnabled() && e.getClickCount() == 2)
{
+ structureViewer_actionPerformed(
+ (String) structViewer.getSelectedItem());
+ }
+ });
+ structureTab.add(structViewer);
+ ypos += lineSpacing;
+ structureViewerPathLabel = new JLabel();
+ structureViewerPathLabel.setFont(LABEL_FONT);// new Font("SansSerif", 0,
+ // 11));
+ structureViewerPathLabel.setHorizontalAlignment(SwingConstants.LEFT);
+ structureViewerPathLabel.setText(MessageManager
+ .formatMessage("label.viewer_path", "Chimera(X)"));
+ structureViewerPathLabel
+ .setBounds(new Rectangle(10, ypos, 170, height));
+ structureViewerPathLabel.setEnabled(false);
+ structureTab.add(structureViewerPathLabel);
+
+ structureViewerPath.setFont(LABEL_FONT);
+ structureViewerPath.setText("");
+ structureViewerPath.setEnabled(false);
+ final String tooltip = JvSwingUtils.wrapTooltip(true,
+ MessageManager.getString("label.viewer_path_tip"));
+ structureViewerPath.setToolTipText(tooltip);
+ structureViewerPath.setBounds(new Rectangle(190, ypos, 290, height));
+ structureViewerPath.addMouseListener(new MouseAdapter()
+ {
+ if (structureViewerPath.isEnabled() && e.getClickCount() == 2)
+ {
String chosen = openFileChooser();
if (chosen != null)
{
viewerLabel.setVisible(false);
structViewer.setVisible(false);
}
-
return structureTab;
}
*
* @return
*/
- protected String openFileChooser()
+ protected String openFileChooser(boolean forFolder)
{
String choice = null;
JFileChooser chooser = new JFileChooser();
true);
}
+ if (forFolder)
+ {
+ chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
+ }
+
// chooser.setFileView(new JalviewFileView());
chooser.setDialogTitle(
MessageManager.getString("label.open_local_file"));
visualTab.add(fontNameCB);
visualTab.add(fontSizeCB);
visualTab.add(fontStyleCB);
-
+
if (Platform.isJS())
{
startupCheckbox.setVisible(false);
startupFileTextfield.setVisible(false);
}
-
+
return visualTab;
}
{
BackupFilesPresetEntry savedPreset = BackupFilesPresetEntry
.getSavedBackupEntry();
- enableBackupFiles.setSelected(
- Cache.getDefault(BackupFiles.ENABLED, !Platform.isJS()));
+ enableBackupFiles
+ .setSelected(Cache.getDefault(BackupFiles.ENABLED, !Platform.isJS()));
BackupFilesPresetEntry backupfilesCustomEntry = BackupFilesPresetEntry
.createBackupFilesPresetEntry(Cache
}
});
+
// enable checkbox 1 col
gbc.gridwidth = 1;
gbc.gridheight = 1;
presetsComboLabel = new JLabel(title + ":");
presetsPanel.add(presetsComboLabel, gbc);
- List<Object> entries = Arrays.asList(
- (Object[]) BackupFilesPresetEntry.backupfilesPresetEntries);
+ List<Object> entries = Arrays
+ .asList((Object[]) BackupFilesPresetEntry.backupfilesPresetEntries);
List<String> tooltips = Arrays.asList(
BackupFilesPresetEntry.backupfilesPresetEntryDescriptions);
backupfilesPresetsCombo = JvSwingUtils.buildComboWithTooltips(entries,
{
if (customiseCheckbox.isSelected())
{
- // got here by clicking on customiseCheckbox so don't change the
- // values
+ // got here by clicking on customiseCheckbox so don't change the values
backupfilesCustomOptionsSetEnabled();
}
else
private JPanel initBackupsTabFilenameExamplesPanel()
{
- String title = MessageManager.getString("label.scheme_examples");
+ String title = MessageManager
+ .getString("label.scheme_examples");
TitledBorder tb = new TitledBorder(title);
exampleFilesPanel.setBorder(tb);
exampleFilesPanel.setLayout(new GridBagLayout());
+
backupfilesExampleLabel.setEditable(false);
backupfilesExampleLabel
.setBackground(exampleFilesPanel.getBackground());
}
protected void setComboIntStringKey(
- JComboBox<Object> backupfilesPresetsCombo2, int key)
+ JComboBox<Object> backupfilesPresetsCombo2,
+ int key)
{
for (int i = 0; i < backupfilesPresetsCombo2.getItemCount(); i++)
{
boolean ret = false;
String warningMessage = MessageManager
.getString("label.warning_confirm_change_reverse");
- int confirm = JvOptionPane.showConfirmDialog(Desktop.desktop,
+ int confirm = JvOptionPane.showConfirmDialog(Desktop.getDesktopPane(),
warningMessage,
MessageManager.getString("label.change_increment_decrement"),
JvOptionPane.YES_NO_OPTION, JvOptionPane.WARNING_MESSAGE);
JPanel jp = new JPanel();
jp.setLayout(new FlowLayout());
- oldBackupFilesLabel.setText(
- MessageManager.getString("label.autodelete_old_backup_files"));
+ oldBackupFilesLabel
+ .setText(MessageManager
+ .getString("label.autodelete_old_backup_files"));
oldBackupFilesLabel.setFont(LABEL_FONT);
oldBackupFilesLabel.setHorizontalAlignment(SwingConstants.LEFT);
jp.add(oldBackupFilesLabel);
}
- // add some extra empty lines to pad out the example files box. ugh, please
- // tell
+ // add some extra empty lines to pad out the example files box. ugh, please tell
// me how to do this better
int remainingLines = lowersurround + uppersurround + 1 - lineNumber;
if (remainingLines > 0)
private void backupfilesKeepAllSetEnabled(boolean tryEnabled)
{
boolean enabled = tryEnabled && enableBackupFiles.isSelected()
- && customiseCheckbox.isSelected() && suffixTemplate.getText()
+ && customiseCheckbox.isSelected()
+ && suffixTemplate.getText()
.indexOf(BackupFiles.NUM_PLACEHOLDER) > -1;
keepfilesPanel.setEnabled(enabled);
backupfilesKeepAll.setEnabled(enabled);
* DOCUMENT ME!
*
* @param e
- * DOCUMENT ME!
+ * DOCUMENT ME!
*/
public void ok_actionPerformed(ActionEvent e)
{
* DOCUMENT ME!
*
* @param e
- * DOCUMENT ME!
+ * DOCUMENT ME!
*/
public void cancel_actionPerformed(ActionEvent e)
{
* DOCUMENT ME!
*
* @param e
- * DOCUMENT ME!
+ * DOCUMENT ME!
*/
public void annotations_actionPerformed(ActionEvent e)
{
}
}
+
+ protected void validateHmmerPath()
+ {
+ }
+
+ protected void validateCygwinPath()
+ {
+ }
+
+ /**
+ * A helper method to add a panel containing a label and a component to a
+ * panel
+ *
+ * @param panel
+ * @param tooltip
+ * @param label
+ * @param valBox
+ */
+ protected static void addtoLayout(JPanel panel, String tooltip,
+ JComponent label, JComponent valBox)
+ {
+ JPanel laypanel = new JPanel(new GridLayout(1, 2));
+ JPanel labPanel = new JPanel(new BorderLayout());
+ JPanel valPanel = new JPanel();
+ labPanel.setBounds(new Rectangle(7, 7, 158, 23));
+ valPanel.setBounds(new Rectangle(172, 7, 270, 23));
+ labPanel.add(label, BorderLayout.WEST);
+ valPanel.add(valBox);
+ laypanel.add(labPanel);
+ laypanel.add(valPanel);
+ valPanel.setToolTipText(tooltip);
+ labPanel.setToolTipText(tooltip);
+ valBox.setToolTipText(tooltip);
+ panel.add(laypanel);
+ panel.validate();
+ }
}
+
optionsPanel = new JPanel(new MigLayout("", "[fill]", "[fill]"));
JScrollPane optionView = new JScrollPane();
optionView.setViewportView(options);
- JvSwingUtils.mgAddtoLayout(dpane,
+ JvSwingUtils.addtoLayout(dpane,
MessageManager.getString("label.input_parameter_name"),
new JLabel(MessageManager.getString("label.name")), tok,
"grow,spanx 3,wrap");
cpanel = details;
name = new JTextArea(1, 12);
- JvSwingUtils.mgAddtoLayout(cpanel,
+ JvSwingUtils.addtoLayout(cpanel,
MessageManager
.getString("label.short_descriptive_name_for_service"),
new JLabel(MessageManager.getString("label.name")), name,
"wrap");
action = new JComboBox();
- JvSwingUtils.mgAddtoLayout(cpanel,
+ JvSwingUtils.addtoLayout(cpanel,
MessageManager.getString("label.function_service_performs"),
new JLabel(MessageManager.getString("label.service_action")),
action, "wrap");
descr = new JTextArea(4, 60);
descrVp = new JScrollPane();
descrVp.setViewportView(descr);
- JvSwingUtils.mgAddtoLayout(cpanel,
+ JvSwingUtils.addtoLayout(cpanel,
MessageManager.getString("label.brief_description_service"),
new JLabel(MessageManager.getString("label.description")),
descrVp, "wrap");
url = new JTextArea(2, 60);
urlVp = new JScrollPane();
urlVp.setViewportView(url);
- JvSwingUtils.mgAddtoLayout(cpanel,
+ JvSwingUtils.addtoLayout(cpanel,
MessageManager.getString("label.url_post_data_service"),
new JLabel(MessageManager.getString("label.post_url")), urlVp,
"wrap");
urlsuff = new JTextArea();
urlsuff.setColumns(60);
- JvSwingUtils.mgAddtoLayout(cpanel,
+ JvSwingUtils.addtoLayout(cpanel,
MessageManager.getString("label.optional_suffix"),
new JLabel(MessageManager.getString("label.url_suffix")),
urlsuff, "wrap");
}
});
gapChar = new JComboBox();
- JvSwingUtils.mgAddtoLayout(cpanel,
+ JvSwingUtils.addtoLayout(cpanel,
MessageManager.getString("label.preferred_gap_character"),
new JLabel(
MessageManager.getString("label.gap_character") + ":"),
return true;
}
- JvOptionPane.showInternalMessageDialog(jalview.gui.Desktop.desktop,
+ JvOptionPane.showInternalMessageDialog(jalview.gui.Desktop.getDesktopPane(),
MessageManager.getString("warn.url_must_contain"),
MessageManager.getString("label.invalid_url"),
JvOptionPane.WARNING_MESSAGE);
public void notifyDuplicate()
{
- JvOptionPane.showInternalMessageDialog(jalview.gui.Desktop.desktop,
+ JvOptionPane.showInternalMessageDialog(jalview.gui.Desktop.getDesktopPane(),
MessageManager.getString("warn.name_cannot_be_duplicate"),
MessageManager.getString("label.invalid_name"),
JvOptionPane.WARNING_MESSAGE);
*/
package jalview.jbgui;
+import jalview.api.structures.JalviewStructureDisplayI;
+import jalview.gui.ColourMenuHelper.ColourChangeListener;
+import jalview.util.ImageMaker.TYPE;
+import jalview.util.MessageManager;
+import jalview.util.Platform;
+
import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import javax.swing.JPanel;
import javax.swing.JRadioButtonMenuItem;
-import jalview.api.structures.JalviewStructureDisplayI;
-import jalview.gui.ColourMenuHelper.ColourChangeListener;
-import jalview.util.ImageMaker.TYPE;
-import jalview.util.MessageManager;
-
@SuppressWarnings("serial")
public abstract class GStructureViewer extends JInternalFrame
implements JalviewStructureDisplayI, ColourChangeListener
private void jbInit() throws Exception
{
- setName("jalview-structureviewer");
+ setName(Platform.getAppID("structureviewer"));
JMenuBar menuBar = new JMenuBar();
this.setJMenuBar(menuBar);
JMenu helpMenu = new JMenu();
helpMenu.setText(MessageManager.getString("action.help"));
helpItem = new JMenuItem();
+ helpItem.setText(MessageManager.getString("label.jmol_help"));
helpItem.addActionListener(new ActionListener()
{
@Override
import jalview.util.ImageMaker.TYPE;
import jalview.util.MessageManager;
+import jalview.util.Platform;
import java.awt.BorderLayout;
import java.awt.Color;
private void jbInit() throws Exception
{
- setName("jalview-tree");
+ setName(Platform.getAppID("tree"));
this.getContentPane().setLayout(borderLayout1);
this.setBackground(Color.white);
this.setFont(new java.awt.Font("Verdana", 0, 12));
*/
package jalview.jbgui;
-import jalview.bin.Jalview;
-import jalview.gui.JvSwingUtils;
-import jalview.util.MessageManager;
-
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import javax.swing.SwingConstants;
import javax.swing.colorchooser.AbstractColorChooserPanel;
+import jalview.gui.JvSwingUtils;
+import jalview.util.MessageManager;
+
/**
* DOCUMENT ME!
*
*/
package jalview.project;
-import java.util.Locale;
-
import static jalview.math.RotatableMatrix.Axis.X;
import static jalview.math.RotatableMatrix.Axis.Y;
import static jalview.math.RotatableMatrix.Axis.Z;
-import java.awt.Color;
-import java.awt.Font;
-import java.awt.Rectangle;
-import java.io.BufferedReader;
-import java.io.ByteArrayInputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.OutputStream;
-import java.io.OutputStreamWriter;
-import java.io.PrintWriter;
-import java.lang.reflect.InvocationTargetException;
-import java.math.BigInteger;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Enumeration;
-import java.util.GregorianCalendar;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Hashtable;
-import java.util.IdentityHashMap;
-import java.util.Iterator;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-import java.util.Vector;
-import java.util.jar.JarEntry;
-import java.util.jar.JarInputStream;
-import java.util.jar.JarOutputStream;
-
-import javax.swing.JInternalFrame;
-import javax.swing.SwingUtilities;
-import javax.xml.bind.JAXBContext;
-import javax.xml.bind.JAXBElement;
-import javax.xml.bind.Marshaller;
-import javax.xml.datatype.DatatypeConfigurationException;
-import javax.xml.datatype.DatatypeFactory;
-import javax.xml.datatype.XMLGregorianCalendar;
-import javax.xml.stream.XMLInputFactory;
-import javax.xml.stream.XMLStreamReader;
-
import jalview.analysis.Conservation;
import jalview.analysis.PCA;
import jalview.analysis.scoremodels.ScoreModels;
import jalview.analysis.scoremodels.SimilarityParams;
+import jalview.api.AlignmentViewPanel;
import jalview.api.FeatureColourI;
import jalview.api.ViewStyleI;
import jalview.api.analysis.ScoreModelI;
import jalview.datamodel.DBRefEntry;
import jalview.datamodel.GeneLocus;
import jalview.datamodel.GraphLine;
+import jalview.datamodel.HiddenMarkovModel;
import jalview.datamodel.PDBEntry;
import jalview.datamodel.Point;
import jalview.datamodel.RnaViewerModel;
import jalview.gui.AlignViewport;
import jalview.gui.AlignmentPanel;
import jalview.gui.AppVarna;
+import jalview.gui.ChimeraViewFrame;
import jalview.gui.Desktop;
+import jalview.gui.FeatureRenderer;
import jalview.gui.JvOptionPane;
import jalview.gui.OOMWarning;
import jalview.gui.PCAPanel;
import jalview.io.BackupFiles;
import jalview.io.DataSourceType;
import jalview.io.FileFormat;
+import jalview.io.HMMFile;
import jalview.io.NewickFile;
import jalview.math.Matrix;
import jalview.math.MatrixI;
import jalview.viewmodel.seqfeatures.FeatureRendererModel;
import jalview.viewmodel.seqfeatures.FeatureRendererSettings;
import jalview.viewmodel.seqfeatures.FeaturesDisplayed;
-import jalview.ws.jws2.Jws2Discoverer;
+import jalview.ws.api.ServiceWithParameters;
+import jalview.ws.jws2.PreferredServiceRegistry;
import jalview.ws.jws2.dm.AAConSettings;
-import jalview.ws.jws2.jabaws2.Jws2Instance;
import jalview.ws.params.ArgumentI;
import jalview.ws.params.AutoCalcSetting;
import jalview.ws.params.WsParamSetI;
import jalview.xml.binding.jalview.ThresholdType;
import jalview.xml.binding.jalview.VAMSAS;
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.Font;
+import java.awt.Rectangle;
+import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
+import java.math.BigInteger;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.GregorianCalendar;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Hashtable;
+import java.util.IdentityHashMap;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.Vector;
+import java.util.jar.JarEntry;
+import java.util.jar.JarInputStream;
+import java.util.jar.JarOutputStream;
+
+import javax.swing.JInternalFrame;
+import javax.swing.SwingUtilities;
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBElement;
+import javax.xml.bind.Marshaller;
+import javax.xml.datatype.DatatypeConfigurationException;
+import javax.xml.datatype.DatatypeFactory;
+import javax.xml.datatype.XMLGregorianCalendar;
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLStreamReader;
+
/**
* Write out the current jalview desktop state as a Jalview XML stream.
*
private static final String RNA_PREFIX = "rna_";
+ private static final String HMMER_PREFIX = "hmmer_";
private static final String UTF_8 = "UTF-8";
/**
private Map<RnaModel, String> rnaSessions = new HashMap<>();
/**
+ * contains last error message (if any) encountered by XML loader.
+ */
+ String errorMessage = null;
+
+ /**
+ * flag to control whether the Jalview2XML_V1 parser should be deferred to if
+ * exceptions are raised during project XML parsing
+ */
+ public boolean attemptversion1parse = false;
+
+ /*
+ * JalviewJS only -- to allow read file bytes to be saved in the
+ * created AlignFrame, allowing File | Reload of a project file to work
+ *
+ * BH 2019 JAL-3436
+ */
+ private File jarFile;
+
+ /**
* A helper method for safely using the value of an optional attribute that
* may be null if not present in the XML. Answers the boolean value, or false
* if null.
* @param _jmap
* @return
*/
- public SeqFref newMappingRef(final String sref,
+ protected SeqFref newMappingRef(final String sref,
final jalview.datamodel.Mapping _jmap)
{
SeqFref fref = new SeqFref(sref, "Mapping")
return fref;
}
- public SeqFref newAlcodMapRef(final String sref,
+ protected SeqFref newAlcodMapRef(final String sref,
final AlignedCodonFrame _cf,
final jalview.datamodel.Mapping _jmap)
{
return fref;
}
- public void resolveFrefedSequences()
+ protected void resolveFrefedSequences()
{
Iterator<SeqFref> nextFref = frefedSequence.iterator();
int toresolve = frefedSequence.size();
* core method for storing state for a set of AlignFrames.
*
* @param frames
- * - frames involving all data to be exported (including containing
- * splitframes)
+ * - frames involving all data to be exported (including those
+ * contained in splitframes, though not the split frames themselves)
* @param jout
* - project output stream
*/
for (int i = frames.size() - 1; i > -1; i--)
{
AlignFrame af = frames.get(i);
+ AlignViewport vp = af.getViewport();
// skip ?
if (skipList != null && skipList
- .containsKey(af.getViewport().getSequenceSetId()))
+ .containsKey(vp.getSequenceSetId()))
{
continue;
}
String shortName = makeFilename(af, shortNames);
- int apSize = af.getAlignPanels().size();
+ AlignmentI alignment = vp.getAlignment();
+ List<? extends AlignmentViewPanel> panels = af.getAlignPanels();
+ int apSize = panels.size();
for (int ap = 0; ap < apSize; ap++)
- {
- AlignmentPanel apanel = (AlignmentPanel) af.getAlignPanels()
- .get(ap);
+ {
+ AlignmentPanel apanel = (AlignmentPanel) panels.get(ap);
String fileName = apSize == 1 ? shortName : ap + shortName;
if (!fileName.endsWith(".xml"))
{
saveState(apanel, fileName, jout, viewIds);
- String dssid = getDatasetIdRef(
- af.getViewport().getAlignment().getDataset());
+ }
+ if (apSize > 0)
+ {
+ // BH moved next bit out of inner loop, not that it really matters.
+ // so we are testing to make sure we actually have an alignment,
+ // apparently.
+ String dssid = getDatasetIdRef(alignment.getDataset());
if (!dsses.containsKey(dssid))
{
+ // We have not already covered this data by reference from another
+ // frame.
dsses.put(dssid, af);
}
}
// create backupfiles object and get new temp filename destination
boolean doBackup = BackupFiles.getEnabled();
BackupFiles backupfiles = doBackup ? new BackupFiles(jarFile) : null;
- FileOutputStream fos = new FileOutputStream(
- doBackup ? backupfiles.getTempFilePath() : jarFile);
+ FileOutputStream fos = new FileOutputStream(doBackup ?
+ backupfiles.getTempFilePath() : jarFile);
JarOutputStream jout = new JarOutputStream(fos);
List<AlignFrame> frames = new ArrayList<>();
}
}
+ /**
+ * Each AlignFrame has a single data set associated with it. Note that none of
+ * these frames are split frames, because Desktop.getAlignFrames() collects
+ * top and bottom separately here.
+ *
+ * @param dsses
+ * @param fileName
+ * @param jout
+ */
private void writeDatasetFor(Hashtable<String, AlignFrame> dsses,
String fileName, JarOutputStream jout)
{
+ // Note that in saveAllFrames we have associated each specific dataset to
+ // ONE of its associated frames.
for (String dssids : dsses.keySet())
{
AlignFrame _af = dsses.get(dssids);
* @param out
* jar entry name
*/
- public JalviewModel saveState(AlignmentPanel ap, String fileName,
+ protected JalviewModel saveState(AlignmentPanel ap, String fileName,
JarOutputStream jout, List<String> viewIds)
{
return saveState(ap, fileName, false, jout, viewIds);
* @param out
* jar entry name
*/
- public JalviewModel saveState(AlignmentPanel ap, String fileName,
+ protected JalviewModel saveState(AlignmentPanel ap, String fileName,
boolean storeDS, JarOutputStream jout, List<String> viewIds)
{
if (viewIds == null)
else
{
vamsasSeq = createVamsasSequence(id, jds);
- // vamsasSet.addSequence(vamsasSeq);
+// vamsasSet.addSequence(vamsasSeq);
vamsasSet.getSequence().add(vamsasSeq);
vamsasSetIds.put(id, vamsasSeq);
seqRefIds.put(id, jds);
jseq.getFeatures().add(features);
}
+ /*
+ * save PDB entries for sequence
+ */
if (jdatasq.getAllPDBEntries() != null)
{
Enumeration<PDBEntry> en = jdatasq.getAllPDBEntries().elements();
* only view *should* be coped with sensibly.
*/
// This must have been loaded, is it still visible?
- JInternalFrame[] frames = Desktop.desktop.getAllFrames();
+ JInternalFrame[] frames = Desktop.getDesktopPane().getAllFrames();
String matchedFile = null;
for (int f = frames.length - 1; f > -1; f--)
{
saveRnaViewers(jout, jseq, jds, viewIds, ap, storeDS);
+ if (jds.hasHMMProfile())
+ {
+ saveHmmerProfile(jout, jseq, jds);
+ }
// jms.addJSeq(jseq);
object.getJSeq().add(jseq);
}
{
// FIND ANY ASSOCIATED TREES
// NOT IMPLEMENTED FOR HEADLESS STATE AT PRESENT
- if (Desktop.desktop != null)
+ if (Desktop.getDesktopPane() != null)
{
- JInternalFrame[] frames = Desktop.desktop.getAllFrames();
+ JInternalFrame[] frames = Desktop.getDesktopPane().getAllFrames();
for (int t = 0; t < frames.length; t++)
{
/*
* save PCA viewers
*/
- if (!storeDS && Desktop.desktop != null)
+ if (!storeDS && Desktop.getDesktopPane() != null)
{
- for (JInternalFrame frame : Desktop.desktop.getAllFrames())
+ for (JInternalFrame frame : Desktop.getDesktopPane().getAllFrames())
{
if (frame instanceof PCAPanel)
{
if (colourScheme instanceof jalview.schemes.UserColourScheme)
{
- jGroup.setColour(setUserColourScheme(colourScheme,
- userColours, object));
+ jGroup.setColour(
+ setUserColourScheme(colourScheme, userColours,
+ object));
}
else
{
}
}
- // jms.setJGroup(groups);
+ //jms.setJGroup(groups);
Object group;
for (JGroup grp : groups)
{
* save any filter for the feature type
*/
FeatureMatcherSetI filter = fr.getFeatureFilter(featureType);
- if (filter != null)
- {
- Iterator<FeatureMatcherI> filters = filter.getMatchers()
- .iterator();
+ if (filter != null) {
+ Iterator<FeatureMatcherI> filters = filter.getMatchers().iterator();
FeatureMatcherI firstFilter = filters.next();
- setting.setMatcherSet(Jalview2XML.marshalFilter(firstFilter,
- filters, filter.isAnded()));
+ setting.setMatcherSet(Jalview2XML.marshalFilter(
+ firstFilter, filters, filter.isAnded()));
}
/*
setting.setDisplay(
av.getFeaturesDisplayed().isVisible(featureType));
- float rorder = fr.getOrder(featureType);
+ float rorder = fr
+ .getOrder(featureType);
if (rorder > -1)
{
setting.setOrder(rorder);
Group g = new Group();
g.setName(grp);
g.setDisplay(((Boolean) fr.checkGroupVisibility(grp, false))
- .booleanValue());
+ .booleanValue());
// fs.addGroup(g);
fs.getGroup().add(g);
groupsAdded.addElement(grp);
}
return object;
}
+ /**
+ * Saves the HMMER profile associated with the sequence as a file in the jar,
+ * in HMMER format, and saves the name of the file as a child element of the
+ * XML sequence element
+ *
+ * @param jout
+ * @param xmlSeq
+ * @param seq
+ */
+ protected void saveHmmerProfile(JarOutputStream jout, JSeq xmlSeq,
+ SequenceI seq)
+ {
+ HiddenMarkovModel profile = seq.getHMM();
+ if (profile == null)
+ {
+ warn("Want to save HMM profile for " + seq.getName()
+ + " but none found");
+ return;
+ }
+ HMMFile hmmFile = new HMMFile(profile);
+ String hmmAsString = hmmFile.print();
+ String jarEntryName = HMMER_PREFIX + nextCounter();
+ try
+ {
+ writeJarEntry(jout, jarEntryName, hmmAsString.getBytes());
+ xmlSeq.setHmmerProfile(jarEntryName);
+ } catch (IOException e)
+ {
+ warn("Error saving HMM profile: " + e.getMessage());
+ }
+ }
+
/**
* Writes PCA viewer attributes and computed values to an XML model object and
* adds it to the JalviewModel. Any exceptions are reported by logging.
final SequenceI jds, List<String> viewIds, AlignmentPanel ap,
boolean storeDataset)
{
- if (Desktop.desktop == null)
+ if (Desktop.getDesktopPane() == null)
{
return;
}
- JInternalFrame[] frames = Desktop.desktop.getAllFrames();
+ JInternalFrame[] frames = Desktop.getDesktopPane().getAllFrames();
for (int f = frames.length - 1; f > -1; f--)
{
if (frames[f] instanceof AppVarna)
{
if (calcIdParam.getVersion().equals("1.0"))
{
- final String[] calcIds = calcIdParam.getServiceURL()
- .toArray(new String[0]);
- Jws2Instance service = Jws2Discoverer.getDiscoverer()
+ final String[] calcIds = calcIdParam.getServiceURL().toArray(new String[0]);
+ ServiceWithParameters service = PreferredServiceRegistry.getRegistry()
.getPreferredServiceFor(calcIds);
if (service != null)
{
argList = parmSet.getArguments();
parmSet = null;
}
- AAConSettings settings = new AAConSettings(
+ AutoCalcSetting settings = new AAConSettings(
calcIdParam.isAutoUpdate(), service, parmSet, argList);
av.setCalcIdSettingsFor(calcIdParam.getCalcId(), settings,
calcIdParam.isNeedsUpdate());
}
else
{
- warn("Cannot resolve a service for the parameters used in this project. Try configuring a JABAWS server.");
+ warn("Cannot resolve a service for the parameters used in this project. Try configuring a server in the Web Services preferences tab.");
return false;
}
}
}
if (ref.hasMap())
{
- Mapping mp = createVamsasMapping(ref.getMap(), parentseq, jds,
- recurse);
+ Mapping mp = createVamsasMapping(ref.getMap(), parentseq,
+ jds, recurse);
dbref.setMapping(mp);
}
vamsasSeq.getDBRef().add(dbref);
return ucs;
}
-
/**
* contains last error message (if any) encountered by XML loader.
*/
{
try
{
- SwingUtilities.invokeAndWait(new Runnable()
+// was invokeAndWait
+
+ // BH 2019 -- can't wait
+ SwingUtilities.invokeLater(new Runnable()
{
@Override
public void run()
System.err.println("Error loading alignment: " + x.getMessage());
}
}
+ this.jarFile = null;
return af;
}
- @SuppressWarnings("unused")
+ @SuppressWarnings("unused")
private jarInputStreamProvider createjarInputStreamProvider(
final Object ofile) throws MalformedURLException
{
-
- // BH 2018 allow for bytes already attached to File object
try
{
String file = (ofile instanceof File
: ofile.toString());
byte[] bytes = Platform.isJS() ? Platform.getFileBytes((File) ofile)
: null;
+ if (bytes != null)
+ {
+ this.jarFile = (File) ofile;
+ }
URL url = null;
errorMessage = null;
uniqueSetSuffix = null;
{
url = new URL(file);
}
- final URL _url = url;
return new jarInputStreamProvider()
{
-
@Override
public JarInputStream getJarInputStream() throws IOException
{
- if (bytes != null)
- {
- // System.out.println("Jalview2XML: opening byte jarInputStream for
- // bytes.length=" + bytes.length);
- return new JarInputStream(new ByteArrayInputStream(bytes));
- }
- if (_url != null)
- {
- // System.out.println("Jalview2XML: opening url jarInputStream for "
- // + _url);
- return new JarInputStream(_url.openStream());
- }
- else
- {
- // System.out.println("Jalview2XML: opening file jarInputStream for
- // " + file);
- return new JarInputStream(new FileInputStream(file));
- }
+ InputStream is = bytes != null ? new ByteArrayInputStream(bytes)
+ : (url != null ? url.openStream()
+ : new FileInputStream(file));
+ return new JarInputStream(is);
+ }
+
+ @Override
+ public File getFile()
+ {
+ return jarFile;
}
@Override
AlignFrame af = null, _af = null;
IdentityHashMap<AlignmentI, AlignmentI> importedDatasets = new IdentityHashMap<>();
Map<String, AlignFrame> gatherToThisFrame = new HashMap<>();
- final String file = jprovider.getFilename();
+ String fileName = jprovider.getFilename();
+ File file = jprovider.getFile();
+ List<AlignFrame> alignFrames = new ArrayList<>();
try
{
JarInputStream jin = null;
JarEntry jarentry = null;
int entryCount = 1;
+ // Look for all the entry names ending with ".xml"
+ // This includes all panels and at least one frame.
+// Platform.timeCheck(null, Platform.TIME_MARK);
do
{
jin = jprovider.getJarInputStream();
{
jarentry = jin.getNextJarEntry();
}
-
- if (jarentry != null && jarentry.getName().endsWith(".xml"))
- {
+ String name = (jarentry == null ? null : jarentry.getName());
+
+// System.out.println("Jalview2XML opening " + name);
+ if (name != null && name.endsWith(".xml"))
+ {
+ // DataSet for.... is read last.
+
+
+ // The question here is what to do with the two
+ // .xml files in the jvp file.
+ // Some number of them, "...Dataset for...", will be the
+ // Only AlignPanels and will have Viewport.
+ // One or more will be the source data, with the DBRefs.
+ //
+ // JVP file writing (above) ensures tha the AlignPanels are written
+ // first, then all relevant datasets (which are
+ // Jalview.datamodel.Alignment).
+ //
+
+// Platform.timeCheck("Jalview2XML JAXB " + name, Platform.TIME_MARK);
JAXBContext jc = JAXBContext
.newInstance("jalview.xml.binding.jalview");
XMLStreamReader streamReader = XMLInputFactory.newInstance()
.createXMLStreamReader(jin);
javax.xml.bind.Unmarshaller um = jc.createUnmarshaller();
- JAXBElement<JalviewModel> jbe = um.unmarshal(streamReader,
- JalviewModel.class);
- JalviewModel object = jbe.getValue();
+ JAXBElement<JalviewModel> jbe = um
+ .unmarshal(streamReader, JalviewModel.class);
+ JalviewModel model = jbe.getValue();
if (true) // !skipViewport(object))
{
- _af = loadFromObject(object, file, true, jprovider);
- if (_af != null && object.getViewport().size() > 0)
- // getJalviewModelSequence().getViewportCount() > 0)
+ // Q: Do we have to load from the model, even if it
+ // does not have a viewport, could we discover that early on?
+ // Q: Do we need to load this object?
+ _af = loadFromObject(model, fileName, file, true, jprovider);
+// Platform.timeCheck("Jalview2XML.loadFromObject",
+ // Platform.TIME_MARK);
+
+ if (_af != null)
{
+ alignFrames.add(_af);
+ }
+ if (_af != null && model.getViewport().size() > 0)
+ {
+
+ // That is, this is one of the AlignmentPanel models
if (af == null)
{
// store a reference to the first view
} catch (IOException ex)
{
ex.printStackTrace();
- errorMessage = "Couldn't locate Jalview XML file : " + file;
+ errorMessage = "Couldn't locate Jalview XML file : " + fileName;
System.err.println(
"Exception whilst loading jalview XML file : " + ex + "\n");
} catch (Exception ex)
{
// used to attempt to parse as V1 castor-generated xml
}
- if (Desktop.instance != null)
+ if (Desktop.getInstance() != null)
{
- Desktop.instance.stopLoading();
+ Desktop.getInstance().stopLoading();
}
if (af != null)
{
errorMessage = "Out of memory loading jalview XML file";
System.err.println("Out of memory whilst loading jalview XML file");
e.printStackTrace();
+ } finally
+ {
+ for (AlignFrame alf : alignFrames)
+ {
+ alf.alignPanel.setHoldRepaint(false);
+ }
}
/*
*/
for (AlignFrame fr : gatherToThisFrame.values())
{
- Desktop.instance.gatherViews(fr);
+ Desktop.getInstance().gatherViews(fr);
}
restoreSplitFrames();
{
if (ds.getCodonFrames() != null)
{
- StructureSelectionManager
- .getStructureSelectionManager(Desktop.instance)
+ Desktop.getStructureSelectionManager()
.registerMappings(ds.getCodonFrames());
}
}
reportErrors();
}
- if (Desktop.instance != null)
+ if (Desktop.getInstance() != null)
{
- Desktop.instance.stopLoading();
+ Desktop.getInstance().stopLoading();
}
return af;
*/
for (SplitFrame sf : gatherTo)
{
- Desktop.instance.gatherViews(sf);
+ Desktop.getInstance().gatherViews(sf);
}
splitFrameCandidates.clear();
@Override
public void run()
{
- JvOptionPane.showInternalMessageDialog(Desktop.desktop,
+ JvOptionPane.showInternalMessageDialog(Desktop.getDesktopPane(),
finalErrorMessage,
"Error " + (saving ? "saving" : "loading")
+ " Jalview file",
* @param prefix
* a prefix for the temporary file name, must be at least three
* characters long
- * @param suffixModel
+ * @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 suffixModel)
+ String jarEntryName, String prefix, String origFile)
{
+ BufferedReader in = null;
+ PrintWriter out = null;
String suffix = ".tmp";
- if (suffixModel == null)
+ if (origFile == null)
{
- suffixModel = jarEntryName;
+ origFile = jarEntryName;
}
- int sfpos = suffixModel.lastIndexOf(".");
- if (sfpos > -1 && sfpos < (suffixModel.length() - 1))
+ int sfpos = origFile.lastIndexOf(".");
+ if (sfpos > -1 && sfpos < (origFile.length() - 3))
{
- suffix = "." + suffixModel.substring(sfpos + 1);
+ suffix = "." + origFile.substring(sfpos + 1);
}
-
try (JarInputStream jin = jprovider.getJarInputStream())
{
+
JarEntry entry = null;
do
{
entry = jin.getNextJarEntry();
} while (entry != null && !entry.getName().equals(jarEntryName));
-
if (entry != null)
{
// in = new BufferedReader(new InputStreamReader(jin, UTF_8));
}
/**
- * Load alignment frame from jalview XML DOM object
+ * Load alignment frame from jalview XML DOM object. For a DOM object that
+ * includes one or more Viewport elements (one with a title that does NOT
+ * contain "Dataset for"), create the frame.
*
* @param jalviewModel
* DOM
- * @param file
+ * @param fileName
* filename source string
+ * @param file
* @param loadTreesAndStructures
* when false only create Viewport
* @param jprovider
* data source provider
* @return alignment frame created from view stored in DOM
*/
- AlignFrame loadFromObject(JalviewModel jalviewModel, String file,
- boolean loadTreesAndStructures, jarInputStreamProvider jprovider)
+ AlignFrame loadFromObject(JalviewModel jalviewModel, String fileName,
+ File file, boolean loadTreesAndStructures, jarInputStreamProvider jprovider)
{
- SequenceSet vamsasSet = jalviewModel.getVamsasModel().getSequenceSet()
- .get(0);
+ SequenceSet vamsasSet = jalviewModel.getVamsasModel().getSequenceSet().get(0);
List<Sequence> vamsasSeqs = vamsasSet.getSequence();
// JalviewModelSequence jms = object.getJalviewModelSequence();
if (tmpSeq.getStart() != jseq.getStart()
|| tmpSeq.getEnd() != jseq.getEnd())
{
- System.err.println(String.format(
- "Warning JAL-2154 regression: updating start/end for sequence %s from %d/%d to %d/%d",
- tmpSeq.getName(), tmpSeq.getStart(), tmpSeq.getEnd(),
- jseq.getStart(), jseq.getEnd()));
+ System.err.println(
+ String.format("Warning JAL-2154 regression: updating start/end for sequence %s from %d/%d to %d/%d",
+ tmpSeq.getName(), tmpSeq.getStart(),
+ tmpSeq.getEnd(), jseq.getStart(),
+ jseq.getEnd()));
}
}
else
{
entry.setProperty(prop.getName(), prop.getValue());
}
- StructureSelectionManager
- .getStructureSelectionManager(Desktop.instance)
+ Desktop.getStructureSelectionManager()
.registerPDBEntry(entry);
// adds PDBEntry to datasequence's set (since Jalview 2.10)
if (al.getSequenceAt(i).getDatasetSequence() != null)
}
}
}
+ /*
+ * load any HMMER profile
+ */
+ // TODO fix this
+
+ String hmmJarFile = jseqs.get(i).getHmmerProfile();
+ if (hmmJarFile != null && jprovider != null)
+ {
+ loadHmmerProfile(jprovider, hmmJarFile, al.getSequenceAt(i));
+ }
}
} // end !multipleview
else
{
// defer to later
- frefedSequence
- .add(newAlcodMapRef(map.getDnasq(), cf, mapping));
+ frefedSequence.add(
+ newAlcodMapRef(map.getDnasq(), cf, mapping));
}
}
}
}
}
}
+ // create the new AlignmentAnnotation
jalview.datamodel.AlignmentAnnotation jaa = null;
if (annotation.isGraph())
jaa._linecolour = firstColour;
}
// register new annotation
+ // Annotation graphs such as Conservation will not have id.
if (annotation.getId() != null)
{
annotationIds.put(annotation.getId(), jaa);
jaa.setCalcId(annotation.getCalcId());
if (annotation.getProperty().size() > 0)
{
- for (Annotation.Property prop : annotation.getProperty())
+ for (Annotation.Property prop : annotation
+ .getProperty())
{
jaa.setProperty(prop.getName(), prop.getValue());
}
// ///////////////////////////////
// LOAD VIEWPORT
- AlignFrame af = null;
- AlignViewport av = null;
// now check to see if we really need to create a new viewport.
if (multipleView && viewportsAdded.size() == 0)
{
boolean doGroupAnnColour = Jalview2XML.isVersionStringLaterThan("2.8.1",
jalviewModel.getVersion());
+ AlignFrame af = null;
AlignmentPanel ap = null;
- boolean isnewview = true;
+ AlignViewport av = null;
if (viewId != null)
{
// Check to see if this alignment already has a view id == viewId
{
for (int v = 0; v < views.length; v++)
{
- if (views[v].av.getViewId().equalsIgnoreCase(viewId))
+ ap = views[v];
+ av = ap.av;
+ if (av.getViewId().equalsIgnoreCase(viewId))
{
// recover the existing alignpanel, alignframe, viewport
- af = views[v].alignFrame;
- av = views[v].av;
- ap = views[v];
+ af = ap.alignFrame;
+ break;
// TODO: could even skip resetting view settings if we don't want to
// change the local settings from other jalview processes
- isnewview = false;
}
}
}
}
- if (isnewview)
+ if (af == null)
{
- af = loadViewport(file, jseqs, hiddenSeqs, al, jalviewModel, view,
+ af = loadViewport(fileName, file, jseqs, hiddenSeqs, al, jalviewModel, view,
uniqueSeqSetId, viewId, autoAlan);
av = af.getViewport();
+ // note that this only retrieves the most recently accessed
+ // tab of an AlignFrame.
ap = af.alignPanel;
}
*
* Not done if flag is false (when this method is used for New View)
*/
+ final AlignFrame af0 = af;
+ final AlignViewport av0 = av;
+ final AlignmentPanel ap0 = ap;
+// Platform.timeCheck("Jalview2XML.loadFromObject-beforetree",
+// Platform.TIME_MARK);
if (loadTreesAndStructures)
{
- loadTrees(jalviewModel, view, af, av, ap);
- loadPCAViewers(jalviewModel, ap);
- loadPDBStructures(jprovider, jseqs, af, ap);
- loadRnaViewers(jprovider, jseqs, ap);
+ if (!jalviewModel.getTree().isEmpty())
+ {
+ SwingUtilities.invokeLater(new Runnable()
+ {
+ @Override
+ public void run()
+ {
+// Platform.timeCheck(null, Platform.TIME_MARK);
+ loadTrees(jalviewModel, view, af0, av0, ap0);
+// Platform.timeCheck("Jalview2XML.loadTrees", Platform.TIME_MARK);
+ }
+ });
+ }
+ if (!jalviewModel.getPcaViewer().isEmpty())
+ {
+ SwingUtilities.invokeLater(new Runnable()
+ {
+ @Override
+ public void run()
+ {
+// Platform.timeCheck(null, Platform.TIME_MARK);
+ loadPCAViewers(jalviewModel, ap0);
+// Platform.timeCheck("Jalview2XML.loadPCA", Platform.TIME_MARK);
+ }
+ });
+ }
+ SwingUtilities.invokeLater(new Runnable()
+ {
+ @Override
+ public void run()
+ {
+// Platform.timeCheck(null, Platform.TIME_MARK);
+ loadPDBStructures(jprovider, jseqs, af0, ap0);
+// Platform.timeCheck("Jalview2XML.loadPDB", Platform.TIME_MARK);
+ }
+ });
+ SwingUtilities.invokeLater(new Runnable()
+ {
+ @Override
+ public void run()
+ {
+ loadRnaViewers(jprovider, jseqs, ap0);
+ }
+ });
}
// and finally return.
+ // but do not set holdRepaint true just yet, because this could be the
+ // initial frame with just its dataset.
return af;
}
/**
+ * Loads a HMMER profile from a file stored in the project, and associates it
+ * with the specified sequence
+ *
+ * @param jprovider
+ * @param hmmJarFile
+ * @param seq
+ */
+ protected void loadHmmerProfile(jarInputStreamProvider jprovider,
+ String hmmJarFile, SequenceI seq)
+ {
+ try
+ {
+ String hmmFile = copyJarEntry(jprovider, hmmJarFile, "hmm", null);
+ HMMFile parser = new HMMFile(hmmFile, DataSourceType.FILE);
+ HiddenMarkovModel hmmModel = parser.getHMM();
+ hmmModel = new HiddenMarkovModel(hmmModel, seq);
+ seq.setHMM(hmmModel);
+ } catch (IOException e)
+ {
+ warn("Error loading HMM profile for " + seq.getName() + ": "
+ + e.getMessage());
+ }
+ }
+
+ /**
* Instantiate and link any saved RNA (Varna) viewers. The state of the Varna
* panel is restored from separate jar entries, two (gapped and trimmed) per
* sequence and secondary structure.
* @param jseqs
* @param ap
*/
- private void loadRnaViewers(jarInputStreamProvider jprovider,
+ protected void loadRnaViewers(jarInputStreamProvider jprovider,
List<JSeq> jseqs, AlignmentPanel ap)
{
/*
* @param av
* @param ap
*/
- protected void loadTrees(JalviewModel jm, Viewport view, AlignFrame af,
- AlignViewport av, AlignmentPanel ap)
+ protected void loadTrees(JalviewModel jm, Viewport view,
+ AlignFrame af, AlignViewport av, AlignmentPanel ap)
{
// TODO result of automated refactoring - are all these parameters needed?
try
tree.getTitle(), safeInt(tree.getWidth()),
safeInt(tree.getHeight()), safeInt(tree.getXpos()),
safeInt(tree.getYpos()));
+ if (tp == null)
+ {
+ warn("There was a problem recovering stored Newick tree: \n"
+ + tree.getNewick());
+ continue;
+ }
if (tree.getId() != null)
{
// perhaps bind the tree id to something ?
tp.getTreeCanvas().setAssociatedPanel(ap); // af.alignPanel;
}
tp.getTreeCanvas().setApplyToAllViews(tree.isLinkToAllViews());
- if (tp == null)
- {
- warn("There was a problem recovering stored Newick tree: \n"
- + tree.getNewick());
- continue;
- }
tp.fitToWindow.setState(safeBoolean(tree.isFitToWindow()));
tp.fitToWindow_actionPerformed(null);
for (int s = 0; s < structureStateCount; s++)
{
// check to see if we haven't already created this structure view
- final StructureState structureState = pdbid.getStructureState()
- .get(s);
+ final StructureState structureState = pdbid
+ .getStructureState().get(s);
String sviewid = (structureState.getViewId() == null) ? null
: structureState.getViewId() + uniqueSetSuffix;
jalview.datamodel.PDBEntry jpdb = new jalview.datamodel.PDBEntry();
int height = safeInt(structureState.getHeight());
// Probably don't need to do this anymore...
- // Desktop.desktop.getComponentAt(x, y);
+ // Desktop.getDesktop().getComponentAt(x, y);
// TODO: NOW: check that this recovers the PDB file correctly.
String pdbFile = loadPDBFile(jprovider, pdbid.getId(),
pdbid.getFile());
colourByViewer &= structureState.isColourByJmol();
jmoldat.setColourByViewer(colourByViewer);
- if (jmoldat.getStateData().length() < structureState.getValue()
- /*Content()*/.length())
+ if (jmoldat.getStateData().length() < structureState
+ .getValue()/*Content()*/.length())
{
jmoldat.setStateData(structureState.getValue());// Content());
}
// TODO JAL-3619 show error dialog / offer an alternative viewer
Cache.log.error("Invalid structure viewer type: " + type);
}
- }
- /**
- * Generates a name for the entry in the project jar file to hold state
- * information for a structure viewer
- *
- * @param viewId
- * @return
- */
- protected String getViewerJarEntryName(String viewId)
- {
- return VIEWER_PREFIX + viewId;
}
/**
- * Returns any open frame that matches given structure viewer data. The match
- * is based on the unique viewId, or (for older project versions) the frame's
- * geometry.
+ * Creates a new structure viewer window
*
+ * @param viewerType
* @param viewerData
- * @return
+ * @param af
+ * @param jprovider
*/
- protected StructureViewerBase findMatchingViewer(
- Entry<String, StructureViewerModel> viewerData)
+ protected void createStructureViewer(ViewerType viewerType,
+ final Entry<String, StructureViewerModel> viewerData,
+ AlignFrame af, jarInputStreamProvider jprovider)
{
- final String sviewid = viewerData.getKey();
- final StructureViewerModel svattrib = viewerData.getValue();
- StructureViewerBase comp = null;
- JInternalFrame[] frames = getAllFrames();
- for (JInternalFrame frame : frames)
- {
- if (frame instanceof StructureViewerBase)
+ final StructureViewerModel viewerModel = viewerData.getValue();
+ String sessionFilePath = null;
+
+ if (viewerType == ViewerType.JMOL)
+ {
+ sessionFilePath = rewriteJmolSession(viewerModel, jprovider);
+ }
+ else
+ {
+ String viewerJarEntryName = getViewerJarEntryName(
+ viewerModel.getViewId());
+ sessionFilePath = copyJarEntry(jprovider, viewerJarEntryName,
+ "viewerSession", ".tmp");
+ }
+ final String sessionPath = sessionFilePath;
+ final String sviewid = viewerData.getKey();
+// BH again was invokeAndWait
+ // try
+ // {
+ javax.swing.SwingUtilities.invokeLater(new Runnable()
+ {
+ @Override
+ public void run()
+ {
+ JalviewStructureDisplayI sview = null;
+ try
+ {
+ sview = StructureViewer.createView(viewerType, af.alignPanel,
+ viewerModel, sessionPath, sviewid);
+ addNewStructureViewer(sview);
+ } catch (OutOfMemoryError ex)
+ {
+ new OOMWarning("Restoring structure view for " + viewerType,
+ (OutOfMemoryError) ex.getCause());
+ if (sview != null && sview.isVisible())
+ {
+ sview.closeViewer(false);
+ sview.setVisible(false);
+ sview.dispose();
+ }
+ }
+ }
+ });
+// } catch (InvocationTargetException | InterruptedException ex)
+// {
+// warn("Unexpected error when opening " + viewerType
+// + " structure viewer", ex);
+// }
+ }
+
+ /**
+ * Rewrites a Jmol session script, saves it to a temporary file, and returns
+ * the path of the file. "load file" commands are rewritten to change the
+ * original PDB file names to those created as the Jalview project is loaded.
+ *
+ * @param svattrib
+ * @param jprovider
+ * @return
+ */
+ private String rewriteJmolSession(StructureViewerModel svattrib,
+ jarInputStreamProvider jprovider)
+ {
+ String state = svattrib.getStateData(); // Jalview < 2.9
+ if (state == null || state.isEmpty()) // Jalview >= 2.9
+ {
+ String jarEntryName = getViewerJarEntryName(svattrib.getViewId());
+ state = readJarEntry(jprovider, jarEntryName);
+ }
+ // TODO or simpler? for each key in oldFiles,
+ // replace key.getPath() in state with oldFiles.get(key).getFilePath()
+ // (allowing for different path escapings)
+ StringBuilder rewritten = new StringBuilder(state.length());
+ int cp = 0, ncp, ecp;
+ Map<File, StructureData> oldFiles = svattrib.getFileData();
+ while ((ncp = state.indexOf("load ", cp)) > -1)
+ {
+ do
+ {
+ // look for next filename in load statement
+ rewritten.append(state.substring(cp,
+ ncp = (state.indexOf("\"", ncp + 1) + 1)));
+ String oldfilenam = state.substring(ncp,
+ ecp = state.indexOf("\"", ncp));
+ // recover the new mapping data for this old filename
+ // have to normalize filename - since Jmol and jalview do
+ // filename translation differently.
+ StructureData filedat = oldFiles.get(new File(oldfilenam));
+ if (filedat == null)
+ {
+ String reformatedOldFilename = oldfilenam.replaceAll("/", "\\\\");
+ filedat = oldFiles.get(new File(reformatedOldFilename));
+ }
+ rewritten.append(Platform.escapeBackslashes(filedat.getFilePath()));
+ rewritten.append("\"");
+ cp = ecp + 1; // advance beyond last \" and set cursor so we can
+ // look for next file statement.
+ } while ((ncp = state.indexOf("/*file*/", cp)) > -1);
+ }
+ if (cp > 0)
+ {
+ // just append rest of state
+ rewritten.append(state.substring(cp));
+ }
+ else
+ {
+ System.err.print("Ignoring incomplete Jmol state for PDB ids: ");
+ rewritten = new StringBuilder(state);
+ rewritten.append("; load append ");
+ for (File id : oldFiles.keySet())
+ {
+ // add pdb files that should be present in the viewer
+ StructureData filedat = oldFiles.get(id);
+ rewritten.append(" \"").append(filedat.getFilePath()).append("\"");
+ }
+ rewritten.append(";");
+ }
+
+ if (rewritten.length() == 0)
+ {
+ return null;
+ }
+ final String history = "history = ";
+ int historyIndex = rewritten.indexOf(history);
+ if (historyIndex > -1)
+ {
+ /*
+ * change "history = [true|false];" to "history = [1|0];"
+ */
+ historyIndex += history.length();
+ String val = rewritten.substring(historyIndex, historyIndex + 5);
+ if (val.startsWith("true"))
+ {
+ rewritten.replace(historyIndex, historyIndex + 4, "1");
+ }
+ else if (val.startsWith("false"))
+ {
+ rewritten.replace(historyIndex, historyIndex + 5, "0");
+ }
+ }
+
+ try
+ {
+ File tmp = File.createTempFile("viewerSession", ".tmp");
+ try (OutputStream os = new FileOutputStream(tmp))
+ {
+ InputStream is = new ByteArrayInputStream(
+ rewritten.toString().getBytes());
+ copyAll(is, os);
+ return tmp.getAbsolutePath();
+ }
+ } catch (IOException e)
+ {
+ Cache.log.error("Error restoring Jmol session: " + e.toString());
+ }
+ return null;
+ }
+
+ /**
+ * Generates a name for the entry in the project jar file to hold state
+ * information for a structure viewer
+ *
+ * @param viewId
+ * @return
+ */
+ protected String getViewerJarEntryName(String viewId)
+ {
+ return VIEWER_PREFIX + viewId;
+ }
+
+ /**
+ * Returns any open frame that matches given structure viewer data. The match
+ * is based on the unique viewId, or (for older project versions) the frame's
+ * geometry.
+ *
+ * @param viewerData
+ * @return
+ */
+ protected StructureViewerBase findMatchingViewer(
+ Entry<String, StructureViewerModel> viewerData)
+ {
+ final String sviewid = viewerData.getKey();
+ final StructureViewerModel svattrib = viewerData.getValue();
+ StructureViewerBase comp = null;
+ JInternalFrame[] frames = getAllFrames();
+ for (JInternalFrame frame : frames)
+ {
+ if (frame instanceof StructureViewerBase)
{
/*
* Post jalview 2.4 schema includes structure view id
{
try
{
- frames = Desktop.desktop.getAllFrames();
+ frames = Desktop.getDesktopPane().getAllFrames();
} catch (ArrayIndexOutOfBoundsException e)
{
// occasional No such child exceptions are thrown here...
}
}
- AlignFrame loadViewport(String file, List<JSeq> JSEQ,
+ AlignFrame loadViewport(String fileName, File file, List<JSeq> JSEQ,
List<SequenceI> hiddenSeqs, AlignmentI al, JalviewModel jm,
Viewport view, String uniqueSeqSetId, String viewId,
List<JvAnnotRow> autoAlan)
// }
;
- af.setFileName(file, FileFormat.Jalview);
+ af.alignPanel.setHoldRepaint(true);
+ af.setFile(fileName, file, null, FileFormat.Jalview);
+ af.setFileObject(jarFile); // BH 2019 JAL-3436
final AlignViewport viewport = af.getViewport();
for (int i = 0; i < JSEQ.size(); i++)
viewport.setViewName(view.getViewName());
af.setInitialTabVisible();
}
- af.setBounds(safeInt(view.getXpos()), safeInt(view.getYpos()),
- safeInt(view.getWidth()), safeInt(view.getHeight()));
+ int x = safeInt(view.getXpos());
+ int y = safeInt(view.getYpos());
+ int w = safeInt(view.getWidth());
+ int h = safeInt(view.getHeight());
+ // // BH we cannot let the title bar go off the top
+ // if (Platform.isJS())
+ // {
+ // x = Math.max(50 - w, x);
+ // y = Math.max(0, y);
+ // }
+
+ af.setBounds(x, y, w, h);
// startSeq set in af.alignPanel.updateLayout below
af.alignPanel.updateLayout();
ColourSchemeI cs = null;
String complementaryViewId = view.getComplementId();
if (complementaryViewId == null)
{
- Desktop.addInternalFrame(af, view.getTitle(),
+ Dimension dim = Platform.getDimIfEmbedded(af,
safeInt(view.getWidth()), safeInt(view.getHeight()));
+ Desktop.addInternalFrame(af, view.getTitle(), dim.width, dim.height);
// recompute any autoannotation
af.alignPanel.updateAnnotation(false, true);
reorderAutoannotation(af, al, autoAlan);
String id = object.getViewport().get(0).getSequenceSetId();
if (skipList.containsKey(id))
{
- if (Cache.log != null && Cache.log.isDebugEnabled())
- {
- Cache.log.debug("Skipping seuqence set id " + id);
- }
+ if (Cache.log != null && Cache.log.isDebugEnabled())
+ {
+ Cache.log.debug("Skipping seuqence set id " + id);
+ }
return true;
}
return false;
}
- public void addToSkipList(AlignFrame af)
+ protected void addToSkipList(AlignFrame af)
{
if (skipList == null)
{
skipList.put(af.getViewport().getSequenceSetId(), af);
}
- public void clearSkipList()
+ protected void clearSkipList()
{
if (skipList != null)
{
addDatasetRef(vamsasSet.getDatasetId(), ds);
}
}
- Vector<SequenceI> dseqs = null;
+ Vector dseqs = null;
if (!ignoreUnrefed)
{
// recovering an alignment View
SequenceI[] dsseqs = new SequenceI[dseqs.size()];
dseqs.copyInto(dsseqs);
ds = new jalview.datamodel.Alignment(dsseqs);
- debug("Created new dataset " + vamsasSet.getDatasetId()
- + " for alignment " + System.identityHashCode(al));
+// debug("Jalview2XML Created new dataset " + vamsasSet.getDatasetId()
+// + " for alignment " + System.identityHashCode(al));
addDatasetRef(vamsasSet.getDatasetId(), ds);
}
// set the dataset for the newly imported alignment.
}
}
}
-
/**
*
* @param vamsasSeq
viewportsAdded.clear();
- AlignFrame af = loadFromObject(jm, null, false, null);
+ AlignFrame af = loadFromObject(jm, null, null, false, null);
af.getAlignPanels().clear();
af.closeMenuItem_actionPerformed(true);
+ af.alignPanel.setHoldRepaint(false);
+ this.jarFile = null;
/*
* if(ap.av.getAlignment().getAlignmentAnnotation()!=null) { for(int i=0;
}
else
{
- Cache.log.debug("Ignoring " + jvobj.getClass() + " (ID = " + id);
+ Cache.log.debug("Ignoring " + jvobj.getClass() + " (ID = " + id);
}
}
}
axis.getXPos(), axis.getYPos(), axis.getZPos());
}
+ Dimension dim = Platform.getDimIfEmbedded(panel, 475, 450);
Desktop.addInternalFrame(panel, MessageManager.formatMessage(
- "label.calc_title", "PCA", modelName), 475, 450);
+ "label.calc_title", "PCA", modelName), dim.width,
+ dim.height);
}
} catch (Exception ex)
{
}
/**
- * Creates a new structure viewer window
- *
- * @param viewerType
- * @param viewerData
- * @param af
- * @param jprovider
- */
- protected void createStructureViewer(ViewerType viewerType,
- final Entry<String, StructureViewerModel> viewerData,
- AlignFrame af, jarInputStreamProvider jprovider)
- {
- final StructureViewerModel viewerModel = viewerData.getValue();
- String sessionFilePath = null;
-
- if (viewerType == ViewerType.JMOL)
- {
- sessionFilePath = rewriteJmolSession(viewerModel, jprovider);
- }
- else
- {
- String viewerJarEntryName = getViewerJarEntryName(
- viewerModel.getViewId());
- sessionFilePath = copyJarEntry(jprovider, viewerJarEntryName,
- "viewerSession", ".tmp");
- }
- final String sessionPath = sessionFilePath;
- final String sviewid = viewerData.getKey();
- try
- {
- SwingUtilities.invokeAndWait(new Runnable()
- {
- @Override
- public void run()
- {
- JalviewStructureDisplayI sview = null;
- try
- {
- sview = StructureViewer.createView(viewerType, af.alignPanel,
- viewerModel, sessionPath, sviewid);
- addNewStructureViewer(sview);
- } catch (OutOfMemoryError ex)
- {
- new OOMWarning("Restoring structure view for " + viewerType,
- (OutOfMemoryError) ex.getCause());
- if (sview != null && sview.isVisible())
- {
- sview.closeViewer(false);
- sview.setVisible(false);
- sview.dispose();
- }
- }
- }
- });
- } catch (InvocationTargetException | InterruptedException ex)
- {
- warn("Unexpected error when opening " + viewerType
- + " structure viewer", ex);
- }
- }
-
- /**
- * Rewrites a Jmol session script, saves it to a temporary file, and returns
- * the path of the file. "load file" commands are rewritten to change the
- * original PDB file names to those created as the Jalview project is loaded.
- *
- * @param svattrib
- * @param jprovider
- * @return
- */
- private String rewriteJmolSession(StructureViewerModel svattrib,
- jarInputStreamProvider jprovider)
- {
- String state = svattrib.getStateData(); // Jalview < 2.9
- if (state == null || state.isEmpty()) // Jalview >= 2.9
- {
- String jarEntryName = getViewerJarEntryName(svattrib.getViewId());
- state = readJarEntry(jprovider, jarEntryName);
- }
- // TODO or simpler? for each key in oldFiles,
- // replace key.getPath() in state with oldFiles.get(key).getFilePath()
- // (allowing for different path escapings)
- StringBuilder rewritten = new StringBuilder(state.length());
- int cp = 0, ncp, ecp;
- Map<File, StructureData> oldFiles = svattrib.getFileData();
- while ((ncp = state.indexOf("load ", cp)) > -1)
- {
- do
- {
- // look for next filename in load statement
- rewritten.append(state.substring(cp,
- ncp = (state.indexOf("\"", ncp + 1) + 1)));
- String oldfilenam = state.substring(ncp,
- ecp = state.indexOf("\"", ncp));
- // recover the new mapping data for this old filename
- // have to normalize filename - since Jmol and jalview do
- // filename translation differently.
- StructureData filedat = oldFiles.get(new File(oldfilenam));
- if (filedat == null)
- {
- String reformatedOldFilename = oldfilenam.replaceAll("/", "\\\\");
- filedat = oldFiles.get(new File(reformatedOldFilename));
- }
- rewritten.append(Platform.escapeBackslashes(filedat.getFilePath()));
- rewritten.append("\"");
- cp = ecp + 1; // advance beyond last \" and set cursor so we can
- // look for next file statement.
- } while ((ncp = state.indexOf("/*file*/", cp)) > -1);
- }
- if (cp > 0)
- {
- // just append rest of state
- rewritten.append(state.substring(cp));
- }
- else
- {
- System.err.print("Ignoring incomplete Jmol state for PDB ids: ");
- rewritten = new StringBuilder(state);
- rewritten.append("; load append ");
- for (File id : oldFiles.keySet())
- {
- // add pdb files that should be present in the viewer
- StructureData filedat = oldFiles.get(id);
- rewritten.append(" \"").append(filedat.getFilePath()).append("\"");
- }
- rewritten.append(";");
- }
-
- if (rewritten.length() == 0)
- {
- return null;
- }
- final String history = "history = ";
- int historyIndex = rewritten.indexOf(history);
- if (historyIndex > -1)
- {
- /*
- * change "history = [true|false];" to "history = [1|0];"
- */
- historyIndex += history.length();
- String val = rewritten.substring(historyIndex, historyIndex + 5);
- if (val.startsWith("true"))
- {
- rewritten.replace(historyIndex, historyIndex + 4, "1");
- }
- else if (val.startsWith("false"))
- {
- rewritten.replace(historyIndex, historyIndex + 5, "0");
- }
- }
-
- try
- {
- File tmp = File.createTempFile("viewerSession", ".tmp");
- try (OutputStream os = new FileOutputStream(tmp))
- {
- InputStream is = new ByteArrayInputStream(
- rewritten.toString().getBytes());
- copyAll(is, os);
- return tmp.getAbsolutePath();
- }
- } catch (IOException e)
- {
- Cache.log.error("Error restoring Jmol session: " + e.toString());
- }
- return null;
- }
-
- /**
* Populates an XML model of the feature colour scheme for one feature type
*
* @param featureType
* @param fcol
* @return
*/
- public static Colour marshalColour(String featureType,
- FeatureColourI fcol)
+ public static Colour marshalColour(
+ String featureType, FeatureColourI fcol)
{
Colour col = new Colour();
if (fcol.isSimpleColour())
boolean and)
{
jalview.xml.binding.jalview.FeatureMatcherSet result = new jalview.xml.binding.jalview.FeatureMatcherSet();
-
if (filters.hasNext())
{
/*
}
result.setMatchCondition(matcherModel);
}
-
return result;
}
* @param matcherSetModel
* @return
*/
- public static FeatureMatcherSetI parseFilter(String featureType,
+ public static FeatureMatcherSetI parseFilter(
+ String featureType,
jalview.xml.binding.jalview.FeatureMatcherSet matcherSetModel)
{
FeatureMatcherSetI result = new FeatureMatcherSet();
featureType, e.getMessage()));
// return as much as was parsed up to the error
}
-
return result;
}
* @throws IllegalStateException
* if AND and OR conditions are mixed
*/
- protected static void parseFilterConditions(FeatureMatcherSetI matcherSet,
+ protected static void parseFilterConditions(
+ FeatureMatcherSetI matcherSet,
jalview.xml.binding.jalview.FeatureMatcherSet matcherSetModel,
boolean and)
{
else if (filterBy == FilterBy.BY_SCORE)
{
matchCondition = FeatureMatcher.byScore(cond, pattern);
-
}
else if (filterBy == FilterBy.BY_ATTRIBUTE)
{
matchCondition = FeatureMatcher.byAttribute(cond, pattern,
attNames);
}
-
/*
* note this throws IllegalStateException if AND-ing to a
* previously OR-ed compound condition, or vice versa
public static FeatureColourI parseColour(Colour colourModel)
{
FeatureColourI colour = null;
-
if (colourModel.getMax() != null)
{
Color mincol = null;
Color maxcol = null;
Color noValueColour = null;
-
try
{
mincol = new Color(Integer.parseInt(colourModel.getMinRGB(), 16));
maxcol = new Color(Integer.parseInt(colourModel.getRGB(), 16));
} catch (Exception e)
{
- Cache.log.warn("Couldn't parse out graduated feature color.", e);
+ Cache.log.warn("Couldn't parse out graduated feature color.", e);
}
-
NoValueColour noCol = colourModel.getNoValueColour();
if (noCol == NoValueColour.MIN)
{
{
noValueColour = maxcol;
}
-
colour = new FeatureColour(maxcol, mincol, maxcol, noValueColour,
safeFloat(colourModel.getMin()),
safeFloat(colourModel.getMax()));
Color color = new Color(Integer.parseInt(colourModel.getRGB(), 16));
colour = new FeatureColour(color);
}
-
return colour;
}
}
import jalview.datamodel.Annotation;
import jalview.datamodel.ColumnSelection;
import jalview.datamodel.HiddenColumns;
+import jalview.datamodel.HiddenMarkovModel;
import jalview.datamodel.ProfilesI;
import jalview.schemes.ColourSchemeI;
import jalview.schemes.NucleotideColourScheme;
import jalview.schemes.ResidueProperties;
import jalview.schemes.ZappoColourScheme;
import jalview.util.Platform;
+import jalview.workers.InformationThread;
import java.awt.BasicStroke;
import java.awt.Color;
private final boolean USE_FILL_ROUND_RECT = Platform.isAMacAndNotJS();
- boolean av_renderHistogram = true, av_renderProfile = true,
- av_normaliseProfile = false;
+ // todo remove these flags, read from group/viewport where needed
+ boolean av_renderHistogram = true;
+
+ boolean av_renderProfile = true;
+
+ boolean av_normaliseProfile = false;
+
+ boolean av_infoHeight = false;
ResidueShaderI profcolour = null;
private boolean av_ignoreGapsConsensus;
+ private boolean av_ignoreBelowBackground;
+
/**
* attributes set from AwtRenderPanelI
*/
complementConsensus = av.getComplementConsensusHash();
hStrucConsensus = av.getRnaStructureConsensusHash();
av_ignoreGapsConsensus = av.isIgnoreGapsConsensus();
+ av_ignoreBelowBackground = av.isIgnoreBelowBackground();
+ av_infoHeight = av.isInfoLetterHeight();
}
+
+
/**
* Returns profile data; the first element is the profile type, the second is
* the number of distinct values, the third the total count, and the remainder
// properties/rendering attributes as a global 'alignment group' which holds
// all vis settings for the alignment as a whole rather than a subset
//
- if (aa.autoCalculated && (aa.label.startsWith("Consensus")
- || aa.label.startsWith("cDNA Consensus")))
+ if (InformationThread.HMM_CALC_ID.equals(aa.getCalcId()))
+ {
+ HiddenMarkovModel hmm = aa.sequenceRef.getHMM();
+ return AAFrequency.extractHMMProfile(hmm, column,
+ av_ignoreBelowBackground, av_infoHeight); // TODO check if this follows standard
+ // pipeline
+ }
+ if (aa.autoCalculated
+ && (aa.label.startsWith("Consensus") || aa.label
+ .startsWith("cDNA Consensus")))
{
boolean forComplement = aa.label.startsWith("cDNA Consensus");
- if (aa.groupRef != null && aa.groupRef.consensusData != null
+ if (aa.groupRef != null && aa.groupRef.getConsensusData() != null
&& aa.groupRef.isShowSequenceLogo())
{
// TODO? group consensus for cDNA complement
return AAFrequency.extractProfile(
- aa.groupRef.consensusData.get(column),
- aa.groupRef.getIgnoreGapsConsensus());
+ aa.groupRef.getConsensusData().get(column),
+ aa.groupRef.getIgnoreGapsConsensus());
}
// TODO extend annotation row to enable dynamic and static profile data to
// be stored
renderProfile = av_renderProfile;
normaliseProfile = av_normaliseProfile;
}
+ else if (InformationThread.HMM_CALC_ID.equals(row.getCalcId()))
+ {
+ if (row.groupRef != null)
+ {
+ renderHistogram = row.groupRef.isShowInformationHistogram();
+ renderProfile = row.groupRef.isShowHMMSequenceLogo();
+ normaliseProfile = row.groupRef.isNormaliseHMMSequenceLogo();
+ }
+ else
+ {
+ renderHistogram = av.isShowInformationHistogram();
+ renderProfile = av.isShowHMMSequenceLogo();
+ normaliseProfile = av.isNormaliseHMMSequenceLogo();
+ }
+ }
+ else if (row == consensusAnnot || row == structConsensusAnnot
+ || row == complementConsensusAnnot)
+ {
+ renderHistogram = av_renderHistogram;
+ renderProfile = av_renderProfile;
+ normaliseProfile = av_normaliseProfile;
+ }
Annotation[] row_annotations = row.annotations;
if (!row.visible)
* This file is part of Jalview.
*
* Jalview is free software: you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
+ * modify it under the terms of the GNU General License
* as published by the Free Software Foundation, either version 3
* of the License, or (at your option) any later version.
*
* Jalview is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE. See the GNU General Public License for more details.
+ * PURPOSE. See the GNU General License for more details.
*
- * You should have received a copy of the GNU General Public License
+ * You should have received a copy of the GNU General License
* along with Jalview. If not, see <http://www.gnu.org/licenses/>.
* The Jalview Authors are detailed in the 'AUTHORS' file.
*/
public interface ResidueShaderI
{
+ void setConsensus(ProfilesI cons);
- public abstract void setConsensus(ProfilesI cons);
+ boolean conservationApplied();
- public abstract boolean conservationApplied();
+ void setConservationApplied(boolean conservationApplied);
- public abstract void setConservationApplied(boolean conservationApplied);
+ void setConservation(Conservation cons);
- public abstract void setConservation(Conservation cons);
-
- public abstract void alignmentChanged(AnnotatedCollectionI alignment,
+ void alignmentChanged(AnnotatedCollectionI alignment,
Map<SequenceI, SequenceCollectionI> hiddenReps);
/**
* @param consensusThreshold
* @param ignoreGaps
*/
- public abstract void setThreshold(int consensusThreshold,
+ void setThreshold(int consensusThreshold,
boolean ignoreGaps);
- public abstract void setConservationInc(int i);
+ void setConservationInc(int i);
- public abstract int getConservationInc();
+ int getConservationInc();
/**
* Get the percentage threshold for this colour scheme
*
* @return Returns the percentage threshold
*/
- public abstract int getThreshold();
+ int getThreshold();
/**
* Returns the possibly context dependent colour for the given symbol at the
* @param seq
* @return
*/
- public abstract Color findColour(char symbol, int position,
+ Color findColour(char symbol, int position,
SequenceI seq);
- public abstract ColourSchemeI getColourScheme();
+ ColourSchemeI getColourScheme();
- public abstract void setColourScheme(ColourSchemeI cs);
+ void setColourScheme(ColourSchemeI cs);
}
\ No newline at end of file
*/
package jalview.rest;
+import jalview.bin.ApplicationSingletonProvider;
+import jalview.bin.ApplicationSingletonProvider.ApplicationSingletonI;
import jalview.httpserver.AbstractRequestHandler;
import java.io.IOException;
import javax.servlet.http.HttpServletResponse;
/**
- * A simple handler to process (or delegate) HTTP requests on /jalview/rest
+ * A simple handler to process (or delegate) HTTP requests on /jalview/rest.
*/
public class RestHandler extends AbstractRequestHandler
+ implements ApplicationSingletonI
{
private static final String MY_PATH = "rest";
private static final String MY_NAME = "Rest";
/**
- * Singleton instance of this class
- */
- private static RestHandler instance = null;
-
- /**
* Returns the singleton instance of this class
*
* @return
{
synchronized (RestHandler.class)
{
- if (instance == null)
- {
- instance = new RestHandler();
- }
+ return (RestHandler) ApplicationSingletonProvider.getInstance(RestHandler.class);
}
- return instance;
}
/**
public class AnnotationColourGradient extends FollowerColourScheme
{
+ /**
+ * map positional scores to transparency rather than colour
+ */
+ boolean positionToTransparency = true;
+
+ /**
+ * compute shade based on annotation row score
+ */
+ boolean perLineScore = true;
+
public static final int NO_THRESHOLD = -1;
public static final int BELOW_THRESHOLD = 0;
acg.predefinedColours = predefinedColours;
acg.seqAssociated = seqAssociated;
acg.noGradient = noGradient;
+ acg.positionToTransparency = positionToTransparency;
+ acg.perLineScore = perLineScore;
return acg;
}
AnnotatedCollectionI alcontext = alignment instanceof AlignmentI
? alignment
: alignment.getContext();
- boolean f = true, rna = false;
- for (AlignmentAnnotation alan : alcontext
- .findAnnotation(annotation.getCalcId()))
+ boolean f = true, sf = true, rna = false;
+ long plcount = 0, ancount = 0;
+ for (AlignmentAnnotation alan : alcontext.findAnnotation(annotation
+ .getCalcId()))
{
if (alan.sequenceRef != null
&& (alan.label != null && annotation != null
&& alan.label.equals(annotation.label)))
{
+ ancount++;
if (!rna && alan.isRNA())
{
rna = true;
aamin = alan.graphMin;
}
f = false;
+ if (alan.score == alan.score)
+ {
+ if (sf || alan.score < plmin)
+ {
+ plmin = alan.score;
+ }
+ if (sf || alan.score > plmax)
+ {
+ plmax = alan.score;
+ }
+ sf = false;
+ plcount++;
+ }
}
}
+ if (plcount > 0 && plcount == ancount)
+ {
+ perLineScore = plcount == ancount;
+ aamax=plmax;
+ }
+ else
+ {
+ perLineScore = false;
+ }
if (rna)
{
ColourSchemeProperty.initRnaHelicesShading(1 + (int) aamax);
}
}
- float aamin = 0f, aamax = 0f;
+ /**
+ * positional annotation max/min
+ */
+ double aamin = 0.0, aamax = 0.0;
+
+ /**
+ * per line score max/min
+ */
+ double plmin = Double.NaN, plmax = Double.NaN;
public AlignmentAnnotation getAnnotation()
{
}
}
- int dr = (int) (redRange * range + redMin);
- int dg = (int) (greenRange * range + greenMin);
- int db = (int) (blueRange * range + blueMin);
-
- return new Color(dr, dg, db);
+ // midtr sets the ceiling for bleaching out the shading
+ int trans = 0, midtr = 239;
+ if (perLineScore)
+ {
+ trans = (int) ((1f - range) * midtr);
+ range = (float) ((ann.score - plmin) / (plmax - aamin));
+ }
+ int dr = (int) (redRange * range + redMin),
+ dg = (int) (greenRange * range + greenMin),
+ db = (int) (blueRange * range + blueMin);
+ if (ann.score == ann.score && positionToTransparency)
+ {
+ return new Color(Math.min(dr + trans, midtr), Math.min(dg
+ + trans, midtr), Math.min(db + trans, midtr));
+ }
+ else
+ {
+ return new Color(dr, dg, db);
+ }
}
public boolean isPredefinedColours()
import java.util.Locale;
import jalview.api.AlignViewportI;
+import jalview.bin.ApplicationSingletonProvider;
+import jalview.bin.ApplicationSingletonProvider.ApplicationSingletonI;
import jalview.datamodel.AnnotatedCollectionI;
import jalview.datamodel.SequenceCollectionI;
import jalview.datamodel.SequenceI;
+import jalview.util.ColorUtils;
+import java.awt.Color;
import java.util.LinkedHashMap;
import java.util.Map;
-public class ColourSchemes
+public class ColourSchemes implements ApplicationSingletonI
{
- /*
- * singleton instance of this class
- */
- private static ColourSchemes instance = new ColourSchemes();
-
- /*
- * a map from scheme name (lower-cased) to an instance of it
- */
- private Map<String, ColourSchemeI> schemes;
/**
* Returns the singleton instance of this class
*/
public static ColourSchemes getInstance()
{
- return instance;
+ return (ColourSchemes) ApplicationSingletonProvider
+ .getInstance(ColourSchemes.class);
}
private ColourSchemes()
}
/**
+ * ColourSchemeProperty "static"
+ */
+ public Color[] rnaHelices = null;
+
+ /**
+ * delete the existing cached RNA helices colours
+ */
+ public static void resetRnaHelicesShading()
+ {
+ getInstance().rnaHelices = null;
+ }
+
+ public static void initRnaHelicesShading(int n)
+ {
+ int i = 0;
+ ColourSchemes j = getInstance();
+
+ if (j.rnaHelices == null)
+ {
+ j.rnaHelices = new Color[n + 1];
+ }
+ else if (j.rnaHelices != null && j.rnaHelices.length <= n)
+ {
+ Color[] t = new Color[n + 1];
+ System.arraycopy(j.rnaHelices, 0, t, 0, j.rnaHelices.length);
+ i = j.rnaHelices.length;
+ j.rnaHelices = t;
+ }
+ else
+ {
+ return;
+ }
+ // Generate random colors and store
+ for (; i <= n; i++)
+ {
+ j.rnaHelices[i] = ColorUtils.generateRandomColor(Color.white);
+ }
+ }
+
+ /**
+ * a map from scheme name (lower-cased) to an instance of it
+ */
+ private Map<String, ColourSchemeI> schemes;
+
+ /**
* Loads an instance of each standard or user-defined colour scheme
*
* @return
import jalview.api.FeatureColourI;
import jalview.api.FeatureSettingsModelI;
+import jalview.datamodel.features.FeatureMatcherSetI;
/**
* An adapter class that may be extended to instantiate feature colour schemes
return false;
}
+ @Override
+ public FeatureMatcherSetI getFeatureFilters(String type)
+ {
+ return null;
+ }
+
}
--- /dev/null
+package jalview.schemes;
+
+import jalview.api.AlignViewportI;
+import jalview.datamodel.AnnotatedCollectionI;
+import jalview.datamodel.HiddenMarkovModel;
+import jalview.datamodel.SequenceI;
+import jalview.util.ColorUtils;
+import jalview.util.Comparison;
+
+import java.awt.Color;
+import java.io.BufferedReader;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+
+
+
+public class HMMMatchScoreColourScheme extends ResidueColourScheme
+{
+
+ private Map<Character, Map<Integer, Map<String, Double>>> probabilities;
+
+ private List<Integer> ranges;
+
+ private static double binSize;
+
+ public class MatchProbReader
+ {
+ private BufferedReader reader;
+
+ MatchProbReader() throws FileNotFoundException
+ {
+ reader = new BufferedReader(
+ new FileReader("resources/ProbabilityOfMatch"));
+ }
+
+ /*
+ public Map<Character, Map<String, Double>> getProbabilities() throws IOException
+ {
+ Map<Character, Map<String, Double>> probabilities = new HashMap<>();
+
+ String[] alphabet = reader.readLine().split("\\,");
+ for (int i = 1; i < alphabet.length - 1; i++)
+ {
+ probabilities.put(alphabet[i].replaceAll("\\ ", "").charAt(0),
+ new HashMap<>());
+ }
+
+ String line = reader.readLine();
+ while(line != null)
+ {
+ String[] contents = line.split("\\,");
+
+ for(int i = 1; i < contents.length; i++)
+ {
+ probabilities.get(alphabet[i].replaceAll("\\ ", "").charAt(0))
+ .put(contents[0], Double
+ .valueOf(contents[i].replaceAll("\\ ", "")));
+ }
+ line = reader.readLine();
+
+ }
+ reader.close();
+ return probabilities;
+ }
+ */
+
+ public Map<Character, Map<Integer, Map<String, Double>>> getProbabilities()
+ throws IOException
+ {
+
+ Map<Character, Map<Integer, Map<String, Double>>> probabilities = new HashMap<>();
+
+ ranges = new ArrayList<>();
+ ranges.add(0);
+
+ binSize = Double.valueOf((reader.readLine().replaceAll("\\ ", "")));
+ String line = reader.readLine();
+ char c = line.charAt(0);
+
+ while (line != null)
+ {
+ line = reader.readLine();
+ while (line != null && line.split("\\,").length != 1)
+ {
+ String[] llrs = line.split("\\,");
+ String[] counts = reader.readLine().split("\\,");
+ int range = Integer.valueOf(llrs[0]);
+
+ if (!ranges.contains(range))
+ {
+ ranges.add(range);
+ }
+ if (!probabilities.containsKey(c))
+ {
+ probabilities.put(c, new HashMap<>());
+ }
+ probabilities.get(c).put(range, new HashMap<>());
+
+ for (int i = 1; i < llrs.length; i++)
+ {
+ probabilities.get(c).get(range).put(
+ llrs[i].replaceAll("\\ ", ""),
+ Double.valueOf(counts[i].replaceAll("\\ ", "")));
+ }
+
+ line = reader.readLine();
+ }
+ if (line != null)
+ {
+ c = line.charAt(0);
+ }
+ }
+
+ return probabilities;
+ }
+
+ }
+
+ private static final Color INSERTION_COLOUR = Color.white;
+
+ /*
+ * the aligned HMM consensus sequence to use as reference for colouring
+ */
+ private SequenceI hmmSeq;
+
+ private HiddenMarkovModel hmm;
+
+ private Map<Character, Float> frequencies;
+
+ /**
+ * Constructor given a list of Hidden Markov Model consensus sequences. The
+ * first sequence provides the HMM profile from which we can read the emission
+ * probabilities that determine the colour.
+ *
+ * @param hmmSeqs
+ * @throws IOException
+ */
+ public HMMMatchScoreColourScheme(List<SequenceI> hmmSeqs)
+ {
+ hmmSeq = hmmSeqs.isEmpty() ? null : hmmSeqs.get(0);
+ hmm = hmmSeq == null ? null : hmmSeq.getHMM();
+
+ try
+ {
+ MatchProbReader probabilityReader = new MatchProbReader();
+ probabilities = probabilityReader.getProbabilities();
+ } catch (IOException e)
+ {
+ System.out.println(e.getStackTrace());
+ }
+ }
+
+ /**
+ * Default constructor (required by ColourSchemes.loadColourSchemes)
+ */
+ public HMMMatchScoreColourScheme()
+ {
+ }
+
+ @Override
+ public Color findColour(char symbol, int column, SequenceI seq,
+ String consensusResidue, float pid)
+ {
+ if (seq == null)
+ {
+ return null;
+ }
+ return findColour(symbol, column, seq.gapMap().length);
+ }
+
+ // TODO change documentation
+ /**
+ * Returns the colour at a particular symbol at a column in the alignment:
+ * <ul>
+ * <li>white for a gap</li>
+ * <li>red for an insertion</li>
+ * <li>orange for negative information content</li>
+ * <li>white to blue for increasing information content</li>
+ * </ul>
+ *
+ * @param symbol
+ * @param column
+ * @return
+ */
+ private Color findColour(char symbol, int column, int length)
+ {
+ if (getHmm() == null || Comparison.isGap(symbol))
+ {
+ return Color.white;
+ }
+ if (Comparison.isGap(hmmSeq.getCharAt(column)))
+ {
+ return INSERTION_COLOUR;
+ }
+ if (Character.isLowerCase(symbol))
+ {
+ symbol = Character.toUpperCase(symbol);
+ }
+
+ double prob = 0;
+ if (hmm.getBackgroundFrequencies().containsKey(symbol))
+ {
+ int lengthBin = getLengthBin(length);
+
+ double llr = Math
+ .log(getHmm().getMatchEmissionProbability(column, symbol)
+ / hmm.getBackgroundFrequencies().get(symbol));
+
+ if (!probabilities.containsKey(symbol)
+ || !probabilities.get(symbol).get(lengthBin)
+ .containsKey(format(llr)))
+ {
+ return new Color(140, 140, 140);
+ }
+
+
+ prob = probabilities.get(symbol).get(lengthBin).get(format(llr));
+ }
+ else
+ {
+ return new Color(140, 140, 140);
+ }
+
+ Color colour = Color.ORANGE;
+ if (prob >= 0.5)
+ {
+
+ colour = ColorUtils.getGraduatedColour((float) prob, 0.5f,
+ Color.WHITE, 1f,
+ Color.blue);
+ }
+ else
+ {
+ colour = ColorUtils.getGraduatedColour((float) prob, 0f, Color.red,
+ 0.5f, Color.WHITE);
+ }
+
+ return colour;
+ }
+
+ public static String format(Double d)
+ {
+ String formatArg = String.valueOf(binSize);
+
+ // if bin size, need format "%.n" where n is number of decimal places
+ if (binSize < 1)
+ {
+ formatArg = "." + formatArg.split("\\.")[1].length();
+ }
+
+ Double rounded = Math.round(d / binSize) * binSize;
+ String formatted = String.format("%" + formatArg + "f", rounded);
+
+ // format sometimes returns a number rounded to 0 as -0
+ // this ensures output will always be 0
+ if (Double.valueOf(formatted) == 0)
+ {
+ formatted = "0";
+ }
+ return formatted;
+
+ }
+
+ /**
+ * Answers the maximum possible value of information score (log ratio), for use
+ * in scaling a graduated colour range
+ *
+ * @return
+ */
+ protected float getMaxInformationScore()
+ {
+ return 0f;
+ }
+
+ /**
+ * Answers a new colour scheme instance based on the HMM of the first sequence
+ * in ac that has an HMM
+ */
+ @Override
+ public ColourSchemeI getInstance(AlignViewportI viewport,
+ AnnotatedCollectionI ac)
+ {
+ return newInstance(ac);
+ }
+
+ /**
+ * Constructor given a sequence collection
+ *
+ * @param ac
+ */
+ public HMMMatchScoreColourScheme(AnnotatedCollectionI ac)
+ {
+ this(ac.getHmmSequences());
+ }
+
+ /**
+ * Answers a new instance of the colour scheme for the given HMM
+ *
+ * @param ac
+ * @return
+ */
+ protected HMMMatchScoreColourScheme newInstance(AnnotatedCollectionI ac)
+ {
+ return new HMMMatchScoreColourScheme(ac);
+ }
+
+ @Override
+ public boolean isSimple()
+ {
+ return false;
+ }
+
+ /**
+ * Answers true if the sequence collection has an HMM consensus sequence and
+ * that the first HMM sequence contains background frequencies, else false
+ */
+ @Override
+ public boolean isApplicableTo(AnnotatedCollectionI ac)
+ {
+ return !ac.getHmmSequences().isEmpty() && ac.getHmmSequences().get(0)
+ .getHMM().getBackgroundFrequencies() != null;
+ }
+
+ protected Map<Character, Float> getFrequencies()
+ {
+ return frequencies;
+ }
+
+ protected void setFrequencies(Map<Character, Float> frequencies)
+ {
+ this.frequencies = frequencies;
+ }
+
+ protected HiddenMarkovModel getHmm()
+ {
+ return hmm;
+ }
+
+ protected SequenceI getHmmSequence()
+ {
+ return hmmSeq;
+ }
+
+ @Override
+ public String getSchemeName()
+ {
+ return JalviewColourScheme.HMMMatchScore.toString();
+ }
+
+ private int getLengthBin(int l)
+ {
+ for (int i = 1; i < ranges.size(); i++)
+ {
+ if (l >= ranges.get(i - 1) && l < ranges.get(i))
+ {
+ return ranges.get(i);
+ }
+ }
+ return -1;
+ }
+}
+
+
--- /dev/null
+package jalview.schemes;
+
+import jalview.api.AlignViewportI;
+import jalview.datamodel.AnnotatedCollectionI;
+import jalview.datamodel.HiddenMarkovModel;
+import jalview.datamodel.SequenceI;
+import jalview.util.ColorUtils;
+import jalview.util.Comparison;
+
+import java.awt.Color;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Base class for colour schemes based on a selected Hidden Markov Model. The
+ * colour is with reference to an HMM consensus sequence and HMM profile
+ * <ul>
+ * <li>white for a gap</li>
+ * <li>red for an insertion (position is gapped in the HMM consensus)</li>
+ * <li>orange for negative information content</li>
+ * <li>white to blue for increasing information content</li>
+ * </ul>
+ * where information content is the log ratio
+ *
+ * <pre>
+ * log(profile match emission probability / residue background probability)
+ * </pre>
+ *
+ * Sub-class implementations use either global ('Uniprot') or local
+ * ('alignment') background frequencies.
+ *
+ * @author tzvanaalten
+ * @author gmcarstairs
+ */
+public abstract class HmmerColourScheme extends ResidueColourScheme
+{
+ private static final Color INSERTION_COLOUR = new Color(230, 0, 0); // reddish
+
+ /*
+ * the aligned HMM consensus sequence to use as reference for colouring
+ */
+ private SequenceI hmmSeq;
+
+ private HiddenMarkovModel hmm;
+
+ private Map<Character, Float> frequencies;
+
+ /**
+ * Constructor given a list of Hidden Markov Model consensus sequences. The
+ * first sequence provides the HMM profile from which we can read the emission
+ * probabilities that determine the colour.
+ *
+ * @param hmmSeqs
+ */
+ public HmmerColourScheme(List<SequenceI> hmmSeqs)
+ {
+ hmmSeq = hmmSeqs.isEmpty() ? null : hmmSeqs.get(0);
+ hmm = hmmSeq == null ? null : hmmSeq.getHMM();
+ }
+
+ /**
+ * Default constructor (required by ColourSchemes.loadColourSchemes)
+ */
+ public HmmerColourScheme()
+ {
+ }
+
+ @Override
+ public Color findColour(char symbol, int column, SequenceI seq,
+ String consensusResidue, float pid)
+ {
+ return findColour(symbol, column);
+ }
+
+ /**
+ * Returns the colour at a particular symbol at a column in the alignment:
+ * <ul>
+ * <li>white for a gap</li>
+ * <li>red for an insertion</li>
+ * <li>orange for negative information content</li>
+ * <li>white to blue for increasing information content</li>
+ * </ul>
+ *
+ * @param symbol
+ * @param column
+ * @return
+ */
+ private Color findColour(char symbol, int column)
+ {
+ if (getHmm() == null || Comparison.isGap(symbol))
+ {
+ return Color.white;
+ }
+ if (Comparison.isGap(hmmSeq.getCharAt(column)))
+ {
+ return INSERTION_COLOUR;
+ }
+ if (Character.isLowerCase(symbol))
+ {
+ symbol = Character.toUpperCase(symbol);
+ }
+
+ final double prob = getHmm().getMatchEmissionProbability(column,
+ symbol);
+
+ Float freq = 0f;
+
+ if (!frequencies.containsKey(symbol))
+ {
+ return Color.WHITE;
+ }
+ else
+ {
+ freq = frequencies.get(symbol);
+ }
+
+ /*
+ * Orange if match emission probability is less than background probability
+ */
+ double infoRatio = prob / freq.floatValue();
+ Color colour = Color.ORANGE;
+ if (infoRatio >= 1)
+ {
+ /*
+ * log-scale graduated shade of blue if prob is greater than background
+ */
+ float infoLog = (float) Math.log(infoRatio);
+ colour = ColorUtils.getGraduatedColour(infoLog, 0, Color.WHITE,
+ getMaxInformationScore(), Color.blue);
+ }
+
+ return colour;
+ }
+
+ /**
+ * Answers the maximum possible value of information score (log ratio), for
+ * use in scaling a graduated colour range
+ *
+ * @return
+ */
+ abstract float getMaxInformationScore();
+
+ /**
+ * Answers a new colour scheme instance based on the HMM of the first sequence
+ * in ac that has an HMM
+ */
+ @Override
+ public ColourSchemeI getInstance(AlignViewportI viewport,
+ AnnotatedCollectionI ac)
+ {
+ return newInstance(ac);
+ }
+
+ /**
+ * Answers a new instance of the colour scheme for the given HMM
+ *
+ * @param ac
+ * @return
+ */
+ protected abstract HmmerColourScheme newInstance(AnnotatedCollectionI ac);
+
+ @Override
+ public boolean isSimple()
+ {
+ return false;
+ }
+
+ /**
+ * Answers true if the sequence collection has an HMM consensus sequence, else
+ * false
+ */
+ @Override
+ public boolean isApplicableTo(AnnotatedCollectionI ac)
+ {
+ return !ac.getHmmSequences().isEmpty();
+ }
+
+ protected Map<Character, Float> getFrequencies()
+ {
+ return frequencies;
+ }
+
+ protected void setFrequencies(Map<Character, Float> frequencies)
+ {
+ this.frequencies = frequencies;
+ }
+
+ protected HiddenMarkovModel getHmm()
+ {
+ return hmm;
+ }
+
+ protected SequenceI getHmmSequence()
+ {
+ return hmmSeq;
+ }
+}
--- /dev/null
+package jalview.schemes;
+
+import jalview.api.AlignViewportI;
+import jalview.datamodel.AnnotatedCollectionI;
+import jalview.datamodel.SequenceCollectionI;
+
+/**
+ * An HMM colour scheme that uses global ('Uniprot') background frequencies for
+ * residues
+ *
+ * @author tzvanaalten
+ */
+public class HmmerGlobalBackground extends HmmerColourScheme
+{
+ /*
+ * The highest possible log ratio is when match emission probability in
+ * the HMM model is 1, and background (for W) is 0.0109 giving
+ * log(1/0.0109) = log(91.743) = 4.519
+ */
+ private static final float MAX_LOG_RATIO = 4.519f;
+
+ /**
+ * Constructor given a sequence collection
+ *
+ * @param ac
+ */
+ public HmmerGlobalBackground(SequenceCollectionI ac)
+ {
+ super(ac.getHmmSequences());
+ String alphabetType = getHmm() == null
+ ? ResidueProperties.ALPHABET_AMINO
+ : getHmm().getAlphabetType();
+ setFrequencies(
+ ResidueProperties.backgroundFrequencies.get(alphabetType));
+ }
+
+ /**
+ * Default constructor (required by ColourSchemes.loadColourSchemes)
+ */
+ public HmmerGlobalBackground()
+ {
+ }
+
+ @Override
+ public String getSchemeName()
+ {
+ return JalviewColourScheme.HMMERU.toString();
+ }
+
+ @Override
+ protected HmmerColourScheme newInstance(AnnotatedCollectionI ac)
+ {
+ return new HmmerGlobalBackground(ac);
+ }
+
+ @Override
+ float getMaxInformationScore()
+ {
+ return MAX_LOG_RATIO;
+ }
+
+ /**
+ * Answers a new colour scheme instance based on the HMM of the first sequence
+ * in alignment that has an HMM
+ */
+ @Override
+ public ColourSchemeI getInstance(AlignViewportI viewport,
+ AnnotatedCollectionI ac)
+ {
+ return newInstance(ac);
+ }
+
+}
--- /dev/null
+package jalview.schemes;
+
+import jalview.datamodel.AnnotatedCollectionI;
+import jalview.datamodel.ResidueCount;
+import jalview.datamodel.SequenceCollectionI;
+import jalview.datamodel.SequenceI;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * An HMM colour scheme that uses local (alignment or sub-group) background
+ * frequencies for residues
+ *
+ * @author tzvanaalten
+ */
+public class HmmerLocalBackground extends HmmerColourScheme
+{
+ float logTotalCount;
+
+ /**
+ * Constructor given a sequence collection
+ *
+ * @param ac
+ */
+ public HmmerLocalBackground(AnnotatedCollectionI ac)
+ {
+ super(ac.getHmmSequences());
+ countFrequencies(ac);
+ }
+
+ /**
+ * Default constructor (required by ColourSchemes.loadColourSchemes)
+ */
+ public HmmerLocalBackground()
+ {
+ }
+
+ @Override
+ public String getSchemeName()
+ {
+ return JalviewColourScheme.HMMERA.toString();
+ }
+
+ /**
+ * Counts and stores the relative frequency of every residue in the alignment
+ * (apart from any HMM consensus sequences)
+ *
+ * @param sc
+ */
+ public void countFrequencies(SequenceCollectionI sc)
+ {
+ // TODO or total counts in Consensus Profile (how do we get at it?)?
+ Map<Character, Float> freqs = new HashMap<>();
+
+ /*
+ * count symbols, excluding any HMM consensus sequences
+ */
+ ResidueCount counts = new ResidueCount();
+ List<SequenceI> seqs = sc.getSequences();
+ for (SequenceI seq : seqs)
+ {
+ if (!seq.hasHMMProfile())
+ {
+ for (char c : seq.getSequence())
+ {
+ counts.add(c);
+ }
+ }
+ }
+ int total = counts.getTotalResidueCount(); // excludes gaps
+
+ for (char symbol : counts.getSymbolCounts().symbols)
+ {
+ double freq = counts.getCount(symbol) / (double) total;
+ freqs.put(symbol, (float) freq);
+ }
+
+ setFrequencies(freqs);
+
+ logTotalCount = (float) Math.log(total);
+ }
+
+ @Override
+ float getMaxInformationScore()
+ {
+ return logTotalCount;
+ }
+
+ @Override
+ protected HmmerColourScheme newInstance(AnnotatedCollectionI ac)
+ {
+ return new HmmerLocalBackground(ac);
+ }
+}
PurinePyrimidine("Purine/Pyrimidine", PurinePyrimidineColourScheme.class),
RNAHelices("RNA Helices", RNAHelicesColour.class),
TCoffee("T-Coffee Scores", TCoffeeColourScheme.class),
- IdColour("Sequence ID", IdColourScheme.class);
+ IdColour("Sequence ID", IdColourScheme.class),
+ HMMERU("HMMER-Uniprot", HmmerGlobalBackground.class),
+ HMMERA("HMMER-Alignment", HmmerLocalBackground.class),
+ HMMMatchScore("HMM Match Score", HMMMatchScoreColourScheme.class);
// RNAInteraction("RNA Interaction type", RNAInteractionColourScheme.class)
private String name;
public class ResidueProperties
{
+ // alphabet names used in Hidden Markov Model files
+ public static final String ALPHABET_RNA = "RNA";
+
+ public static final String ALPHABET_DNA = "DNA";
+
+ public static final String ALPHABET_AMINO = "amino";
+
// Stores residue codes/names and colours and other things
public static final int[] aaIndex; // aaHash version 2.1.1 and below
// lookup from modified amino acid (e.g. MSE) to canonical form (e.g. MET)
public static final Map<String, String> modifications = new HashMap<>();
+ // residue background frequencies across different alphabets
+ public static final Map<String, Map<Character, Float>> backgroundFrequencies = new HashMap<>();
+
static
{
aaIndex = new int[255];
}
+ static
+ {
+ Map<Character, Float> amino = new HashMap<>();
+ amino.put('A', 0.0826f);
+ amino.put('Q', 0.0393f);
+ amino.put('L', 0.0965f);
+ amino.put('S', 0.0661f);
+ amino.put('R', 0.0553f);
+ amino.put('E', 0.0674f);
+ amino.put('K', 0.0582f);
+ amino.put('T', 0.0535f);
+ amino.put('N', 0.0406f);
+ amino.put('G', 0.0708f);
+ amino.put('M', 0.0241f);
+ amino.put('W', 0.0109f);
+ amino.put('D', 0.0546f);
+ amino.put('H', 0.0227f);
+ amino.put('F', 0.0386f);
+ amino.put('Y', 0.0292f);
+ amino.put('C', 0.0137f);
+ amino.put('I', 0.0593f);
+ amino.put('P', 0.0472f);
+ amino.put('V', 0.0686f);
+ backgroundFrequencies.put(ALPHABET_AMINO, amino);
+ // todo: these don't match https://www.ebi.ac.uk/uniprot/TrEMBLstats - what
+ // are they?
+ }
+
+ // TODO get correct frequencies
+
+ static
+ {
+ Map<Character, Float> dna = new HashMap<>();
+ dna.put('A', 0.25f);
+ dna.put('C', 0.25f);
+ dna.put('T', 0.25f);
+ dna.put('G', 0.25f);
+ backgroundFrequencies.put(ALPHABET_DNA, dna);
+
+ }
+
+ static
+ {
+ Map<Character, Float> rna = new HashMap<>();
+ rna.put('A', 0.25f);
+ rna.put('C', 0.25f);
+ rna.put('T', 0.25f);
+ rna.put('G', 0.25f);
+ backgroundFrequencies.put(ALPHABET_RNA, rna);
+
+ }
+
public static String getCanonicalAminoAcid(String aA)
{
String canonical = modifications.get(aA);
*/
package jalview.structure;
+
import java.util.Locale;
+import jalview.bin.ApplicationSingletonProvider;
+import jalview.bin.ApplicationSingletonProvider.ApplicationSingletonI;
+
+
import jalview.datamodel.PDBEntry;
import jalview.datamodel.PDBEntry.Type;
* @author tcofoegbu
*
*/
-public class StructureImportSettings
+public class StructureImportSettings implements ApplicationSingletonI
{
+ private StructureImportSettings()
+ {
+ // private singleton
+ }
+
+ private static StructureImportSettings getInstance()
+ {
+ return (StructureImportSettings) ApplicationSingletonProvider
+ .getInstance(StructureImportSettings.class);
+ }
/**
* 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;
+ private boolean visibleChainAnnotation = false;
/**
* Set true to predict secondary structure (using JMol for protein, Annotate3D
* Set true (with predictSecondaryStructure=true) to predict secondary
* structure using an external service (currently Annotate3D for RNA only)
*/
- private static boolean externalSecondaryStructure = false;
+ private boolean externalSecondaryStructure = false;
private static boolean showSeqFeatures = true;
* 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;
+ private PDBEntry.Type defaultStructureFileFormat = Type.PDB; // TODO 2.12 should be mmCIF now ?
/**
* Determines the parser used for parsing PDB format file. Possible options
* are : JMolParser|JalveiwParser
*/
- private static StructureParser defaultPDBFileParser = StructureParser.JMOL_PARSER;
+ private 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;
+ StructureImportSettings s = getInstance();
+ s.visibleChainAnnotation = addAlignmentAnnotations;
+ s.processSecStr = processSecStr;
+ s.externalSecondaryStructure = externalSecStr;
+ s.showSeqFeatures = true;
}
public static boolean isVisibleChainAnnotation()
{
- return visibleChainAnnotation;
+ return getInstance().visibleChainAnnotation;
}
public static void setVisibleChainAnnotation(
boolean visibleChainAnnotation)
{
- StructureImportSettings.visibleChainAnnotation = visibleChainAnnotation;
+ getInstance().visibleChainAnnotation = visibleChainAnnotation;
}
public static boolean isProcessSecondaryStructure()
{
- return processSecStr;
+ return getInstance().processSecStr;
}
public static void setProcessSecondaryStructure(
boolean processSecondaryStructure)
{
- StructureImportSettings.processSecStr = processSecondaryStructure;
+ getInstance().processSecStr = processSecondaryStructure;
}
public static boolean isExternalSecondaryStructure()
{
- return externalSecondaryStructure;
+ return getInstance().externalSecondaryStructure;
}
public static void setExternalSecondaryStructure(
boolean externalSecondaryStructure)
{
- StructureImportSettings.externalSecondaryStructure = externalSecondaryStructure;
+ getInstance().externalSecondaryStructure = externalSecondaryStructure;
}
public static boolean isShowSeqFeatures()
{
- return showSeqFeatures;
+ return getInstance().showSeqFeatures;
}
public static void setShowSeqFeatures(boolean showSeqFeatures)
{
- StructureImportSettings.showSeqFeatures = showSeqFeatures;
+ getInstance().showSeqFeatures = showSeqFeatures;
}
public static PDBEntry.Type getDefaultStructureFileFormat()
{
- return defaultStructureFileFormat;
+ return getInstance().defaultStructureFileFormat;
}
public static void setDefaultStructureFileFormat(
String defaultStructureFileFormat)
{
- StructureImportSettings.defaultStructureFileFormat = PDBEntry.Type
+ getInstance().defaultStructureFileFormat = PDBEntry.Type
.valueOf(defaultStructureFileFormat.toUpperCase(Locale.ROOT));
}
public static String getDefaultPDBFileParser()
{
- return defaultPDBFileParser.toString();
+ return getInstance().defaultPDBFileParser.toString();
}
public static void setDefaultPDBFileParser(
StructureParser defaultPDBFileParser)
{
- StructureImportSettings.defaultPDBFileParser = defaultPDBFileParser;
+ getInstance().defaultPDBFileParser = defaultPDBFileParser;
}
public static void setDefaultPDBFileParser(String defaultPDBFileParser)
{
- StructureImportSettings.defaultPDBFileParser = StructureParser
+ getInstance().defaultPDBFileParser = StructureParser
.valueOf(defaultPDBFileParser.toUpperCase(Locale.ROOT));
}
*/
package jalview.structure;
-import java.io.PrintStream;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Enumeration;
-import java.util.HashMap;
-import java.util.IdentityHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Vector;
-
import jalview.analysis.AlignSeq;
import jalview.api.StructureSelectionManagerProvider;
+import jalview.bin.ApplicationSingletonProvider;
+import jalview.bin.ApplicationSingletonProvider.ApplicationSingletonI;
import jalview.bin.Cache;
import jalview.commands.CommandI;
import jalview.commands.EditCommand;
import jalview.ws.sifts.SiftsClient;
import jalview.ws.sifts.SiftsException;
import jalview.ws.sifts.SiftsSettings;
+
+import java.io.PrintStream;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.IdentityHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Vector;
+
import mc_view.Atom;
import mc_view.PDBChain;
import mc_view.PDBfile;
-public class StructureSelectionManager
+public class StructureSelectionManager implements ApplicationSingletonI
{
public final static String NEWLINE = System.lineSeparator();
- static IdentityHashMap<StructureSelectionManagerProvider, StructureSelectionManager> instances;
-
private List<StructureMapping> mappings = new ArrayList<>();
private boolean processSecondaryStructure = false;
private List<SelectionListener> sel_listeners = new ArrayList<>();
+ /*
+ * instances of this class scoped by some context class
+ */
+ private IdentityHashMap<StructureSelectionManagerProvider, StructureSelectionManager> selectionManagers;
+
+ /**
+ * Answers an instance of this class for the current application (Java or JS
+ * 'applet') scope
+ *
+ * @return
+ */
+ private static StructureSelectionManager getInstance()
+ {
+ return (StructureSelectionManager) ApplicationSingletonProvider
+ .getInstance(StructureSelectionManager.class);
+ }
+
+ /**
+ * Private constructor as all 'singleton' instances are managed here or by
+ * ApplicationSingletonProvider
+ */
+ private StructureSelectionManager()
+ {
+ selectionManagers = new IdentityHashMap<>();
+ }
+
+ /**
+ * Answers an instance of this class for the current application (Java or JS
+ * 'applet') scope, and scoped to the specified context
+ *
+ * @param context
+ * @return
+ */
+ public static StructureSelectionManager getStructureSelectionManager(
+ StructureSelectionManagerProvider context)
+ {
+ return getInstance().getInstanceForContext(context);
+ }
+
+ /**
+ * Answers an instance of this class scoped to the given context. The instance
+ * is created on the first request for the context, thereafter the same
+ * instance is returned. Note that the context may be null (this is the case
+ * when running headless without a Desktop).
+ *
+ * @param context
+ * @return
+ */
+ StructureSelectionManager getInstanceForContext(
+ StructureSelectionManagerProvider context)
+ {
+ StructureSelectionManager instance = selectionManagers.get(context);
+ if (instance == null)
+ {
+ instance = new StructureSelectionManager();
+ selectionManagers.put(context, instance);
+ }
+ return instance;
+ }
+
+
/**
* @return true if will try to use external services for processing secondary
* structure
|| pdbIdFileName.containsKey(idOrFile);
}
- private static StructureSelectionManager nullProvider = null;
-
- public static StructureSelectionManager getStructureSelectionManager(
- StructureSelectionManagerProvider context)
- {
- if (context == null)
- {
- if (nullProvider == null)
- {
- if (instances != null)
- {
- throw new Error(MessageManager.getString(
- "error.implementation_error_structure_selection_manager_null"),
- new NullPointerException(MessageManager
- .getString("exception.ssm_context_is_null")));
- }
- else
- {
- nullProvider = new StructureSelectionManager();
- }
- return nullProvider;
- }
- }
- if (instances == null)
- {
- instances = new java.util.IdentityHashMap<>();
- }
- StructureSelectionManager instance = instances.get(context);
- if (instance == null)
- {
- if (nullProvider != null)
- {
- instance = nullProvider;
- }
- else
- {
- instance = new StructureSelectionManager();
- }
- instances.put(context, instance);
- }
- return instance;
- }
-
/**
* flag controlling whether SeqMappings are relayed from received sequence
* mouse over events to other sequences
return relaySeqMappings;
}
- Vector listeners = new Vector();
+ Vector<Object> listeners = new Vector<>();
/**
* register a listener for alignment sequence mouseover events
* Import structure data and register a structure mapping for broadcasting
* colouring, mouseovers and selection events (convenience wrapper).
*
+ * This is the standard entry point.
+ *
* @param sequence
* - one or more sequences to be mapped to pdbFile
* @param targetChains
* broadcasting colouring, mouseovers and selection events (convenience
* wrapper).
*
+ *
+ *
* @param forStructureView
- * when true, record the mapping for use in mouseOvers
+ * when true (testng only), record the mapping for use in mouseOvers
+ * (testng only)
* @param sequence
* - one or more sequences to be mapped to pdbFile
* @param targetChains
* mapping operation
* @return null or the structure data parsed as a pdb file
*/
- synchronized public StructureFile computeMapping(
+ synchronized private StructureFile computeMapping(
boolean forStructureView, SequenceI[] sequenceArray,
String[] targetChainIds, String pdbFile, DataSourceType sourceType,
IProgressIndicator progress)
{
ds = ds.getDatasetSequence();
}
- ;
if (ds.getAnnotation() != null)
{
for (AlignmentAnnotation ala : ds.getAnnotation())
if (s != null)
{
result = s;
- }
}
}
+ }
return result;
}
}
/**
- * Resets this object to its initial state by removing all registered
- * listeners, codon mappings, PDB file mappings
+ * Reset this object to its initial state by removing all registered
+ * listeners, codon mappings, PDB file mappings.
+ *
+ * Called only by Desktop and testng.
+ *
*/
public void resetAll()
{
}
}
- public void addSelectionListener(SelectionListener selecter)
+ public List<SelectionListener> getListeners() {
+ return sel_listeners;
+ }
+
+ public void addSelectionListener(SelectionListener selecter)
{
if (!sel_listeners.contains(selecter))
{
{
slis.viewPosition(startRes, endRes, startSeq, endSeq, source);
}
- ;
+
}
}
}
+
/**
- * release all references associated with this manager provider
+ * Removes the instance associated with this provider
*
- * @param jalviewLite
+ * @param provider
*/
- public static void release(StructureSelectionManagerProvider jalviewLite)
+
+ public static void release(StructureSelectionManagerProvider provider)
{
- // synchronized (instances)
- {
- if (instances == null)
- {
- return;
- }
- StructureSelectionManager mnger = (instances.get(jalviewLite));
- if (mnger != null)
- {
- instances.remove(jalviewLite);
- try
- {
- /* bsoares 2019-03-20 finalize deprecated, no apparent external
- * resources to close
- */
- // mnger.finalize();
- } catch (Throwable x)
- {
- }
- }
- }
+ getInstance().selectionManagers.remove(provider);
}
-
+
public void registerPDBEntry(PDBEntry pdbentry)
{
if (pdbentry.getFile() != null
package jalview.urls;
+import jalview.bin.ApplicationSingletonProvider;
+import jalview.bin.ApplicationSingletonProvider.ApplicationSingletonI;
+
/**
* Holds settings for identifiers.org e.g. url, download location
- *
- * @author $author$
- * @version $Revision$
*/
-public class IdOrgSettings
+public class IdOrgSettings implements ApplicationSingletonI
{
- private static String url;
+ private String url;
+
+ private String location;
+
+ private static IdOrgSettings getInstance()
+ {
+ return (IdOrgSettings) ApplicationSingletonProvider
+ .getInstance(IdOrgSettings.class);
+ }
- private static String location;
+ private IdOrgSettings()
+ {
+ // private singleton
+ }
public static void setUrl(String seturl)
{
- url = seturl;
+ getInstance().url = seturl;
}
public static void setDownloadLocation(String setloc)
{
- location = setloc;
+ getInstance().location = setloc;
}
public static String getUrl()
{
- return url;
+ return getInstance().url;
}
public static String getDownloadLocation()
{
- return location;
+ return getInstance().location;
}
}
}
} catch (IOException | ParseException e)
{
- // unnecessary e.printStackTrace();
- // Note how in JavaScript we can grab the first bytes from any file reader.
- // Typical report here is "NetworkError" because the file does not exist.
- // "https://." is coming from System.getProperty("user.home"), but this could
- // be set by the page developer to anything, of course.
errorMessage = e.toString();
idData.clear();
}
colour = colour.trim();
Color col = null;
- try
- {
- int value = Integer.parseInt(colour, 16);
- col = new Color(value);
- } catch (NumberFormatException ex)
+ if (StringUtils.isHexString(colour))
{
+ try
+ {
+ int value = Integer.parseInt(colour, 16);
+ col = new Color(value);
+ } catch (NumberFormatException ex)
+ {
+ }
}
if (col == null)
*/
public static final boolean isGap(char c)
{
- return (c == GAP_DASH || c == GAP_DOT || c == GAP_SPACE) ? true : false;
+ return (c == GAP_DASH || c == GAP_DOT || c == GAP_SPACE);
}
/**
};
+ private static Regex PARSE_REGEX;
+
+ private static Regex getParseRegex()
+ {
+ return (PARSE_REGEX == null ? PARSE_REGEX = Platform.newRegex(
+ "([0-9][0-9A-Za-z]{3})\\s*(.?)\\s*;\\s*([0-9]+)-([0-9]+)")
+ : PARSE_REGEX);
+ }
+
/**
* Parses a DBRefEntry and adds it to the sequence, also a PDBEntry if the
* database is PDB.
* Check for PFAM style stockhom PDB accession id citation e.g.
* "1WRI A; 7-80;"
*/
- Regex r = new com.stevesoft.pat.Regex(
- "([0-9][0-9A-Za-z]{3})\\s*(.?)\\s*;\\s*([0-9]+)-([0-9]+)");
+ Regex r = getParseRegex();
if (r.search(acn.trim()))
{
String pdbid = r.stringMatched(1);
--- /dev/null
+package jalview.util;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.DirectoryStream;
+import java.nio.file.FileSystems;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.PathMatcher;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * Miscellaneous file-related functions
+ */
+public final class FileUtils
+{
+
+ /**
+ * Answers the executable file for the given command, or null if not found or
+ * not executable. The path to the executable is the command name prefixed by
+ * the given folder path, optionally with .exe appended.
+ *
+ * @param cmd
+ * command short name, for example hmmbuild
+ * @param binaryPath
+ * parent folder for the executable
+ * @return
+ */
+ public static File getExecutable(String cmd, String binaryPath)
+ {
+ File file = new File(binaryPath, cmd);
+ if (!file.canExecute())
+ {
+ file = new File(binaryPath, cmd + ".exe");
+ {
+ if (!file.canExecute())
+ {
+ file = null;
+ }
+ }
+ }
+ return file;
+ }
+
+ /**
+ * Answers the path to the folder containing the given executable file, by
+ * searching the PATH environment variable. Answers null if no such executable
+ * can be found.
+ *
+ * @param cmd
+ * @return
+ */
+ public static String getPathTo(String cmd)
+ {
+ String paths = System.getenv("PATH");
+ // backslash is to escape regular expression argument
+ for (String path : paths.split("\\" + File.pathSeparator))
+ {
+ if (getExecutable(cmd, path) != null)
+ {
+ return path;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * A convenience method to create a temporary file that is deleted on exit of
+ * the JVM
+ *
+ * @param prefix
+ * @param suffix
+ * @return
+ * @throws IOException
+ */
+ public static File createTempFile(String prefix, String suffix)
+ throws IOException
+ {
+ File f = File.createTempFile(prefix, suffix);
+ f.deleteOnExit();
+ return f;
+ }
+
+ /**
+ * Answers a (possibly empty) list of file paths found by searching below
+ * <code>from</code> that match the supplied regular expression
+ * <code>pattern</code>. Results may include <code>from</code> itself if it
+ * matches. If an exception occurs it is written to syserr and any results up to
+ * that point are returned. Note that the regular expression match applies to
+ * the whole path of any matched file.
+ * <p>
+ * WARNING: because the whole directory tree below <code>from</code> is
+ * searched, this method may be slow if used for a high level directory, or may
+ * exit prematurely if security or other exceptions occur.
+ *
+ * <pre>
+ * Example:
+ * findMatchingPaths(Paths.get("C:/Program Files"), ".*/chimera.exe$")
+ * </pre>
+ *
+ * @param from
+ * @param pattern
+ *
+ * @return
+ * @see https://stackoverflow.com/questions/794381/how-to-find-files-that-match-a-wildcard-string-in-java/31685610#comment62441832_31685610
+ */
+ public static List<String> findMatchingPaths(Path from, String pattern)
+ {
+ List<String> matches = new ArrayList<>();
+ PathMatcher pathMatcher = FileSystems.getDefault()
+ .getPathMatcher("regex:" + pattern);
+ try
+ {
+ Files.walk(from).filter(pathMatcher::matches)
+ .forEach(m -> matches.add(m.toString()));
+ } catch (IOException e)
+ {
+ System.err.println(
+ "Error searching for " + pattern + " : " + e.toString());
+ }
+
+ return matches;
+ }
+
+ /**
+ * Answers a (possibly empty) list of paths to files below the given root path,
+ * that match the given pattern. The pattern should be a '/' delimited set of
+ * glob patterns, each of which is used to match child file names (not full
+ * paths). Note that 'directory spanning' glob patterns (**) are <em>not</em>
+ * supported by this method.
+ * <p>
+ * For example
+ *
+ * <pre>
+ * findMatches("C:\\", "Program Files*/Chimera*/bin/{chimera,chimera.exe}"
+ * </pre>
+ *
+ * would match "C:\Program Files\Chimera 1.11\bin\chimera.exe" and "C:\Program
+ * Files (x86)\Chimera 1.10.1\bin\chimera"
+ *
+ * @param root
+ * @param pattern
+ * @return
+ * @see https://docs.oracle.com/javase/tutorial/essential/io/fileOps.html#glob
+ */
+ public static List<String> findMatches(String root, String pattern)
+ {
+ List<String> results = new ArrayList<>();
+ try
+ {
+ Path from = Paths.get(root);
+ findMatches(results, from, Arrays.asList(pattern.split("/")));
+ } catch (Throwable e)
+ {
+ // Paths.get can throw IllegalArgumentException
+ System.err.println(String.format("Error searching %s for %s: %s",
+ root, pattern, e.toString()));
+ }
+
+ return results;
+ }
+
+ /**
+ * A helper method that performs recursive search of file patterns and adds any
+ * 'leaf node' matches to the results list
+ *
+ * @param results
+ * @param from
+ * @param patterns
+ */
+ protected static void findMatches(List<String> results, Path from,
+ List<String> patterns)
+ {
+ if (patterns.isEmpty())
+ {
+ /*
+ * reached end of recursion with all components matched
+ */
+ results.add(from.toString());
+ return;
+ }
+
+ String pattern = patterns.get(0);
+ try (DirectoryStream<Path> dirStream = Files.newDirectoryStream(from,
+ pattern))
+ {
+ dirStream.forEach(p -> {
+
+ /*
+ * matched a next level file - search below it
+ * (ignore non-directory non-leaf matches)
+ */
+ List<String> subList = patterns.subList(1, patterns.size());
+ if (subList.isEmpty() || p.toFile().isDirectory())
+ {
+ findMatches(results, p, subList);
+ }
+ });
+ } catch (IOException e)
+ {
+ System.err.println(String.format("Error searching %s: %s", pattern,
+ e.toString()));
+ }
+ }
+}
--- /dev/null
+package jalview.util;
+
+import jalview.datamodel.AlignmentAnnotation;
+import jalview.datamodel.HiddenMarkovModel;
+import jalview.datamodel.SequenceI;
+import jalview.io.DataSourceType;
+import jalview.io.FileParse;
+import jalview.io.HMMFile;
+import jalview.io.StockholmFile;
+import jalview.schemes.ResidueProperties;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Random;
+import java.util.Scanner;
+import java.util.Vector;
+
+/**
+ * Processes probability data. The file indexes used in this program represent
+ * the index of the location of a family or hmm in their respective files,
+ * starting from 0.
+ *
+ * @author TZVanaalten
+ *
+ */
+public class HMMProbabilityDistributionAnalyser
+{
+ AlignmentAnnotation reference = null;
+
+ Vector<SequenceI> sequences;
+
+ HiddenMarkovModel hmm;
+
+ // contains the raw data produced
+ List<ArrayList<Double>> raw = new ArrayList<>();
+
+ // contains binned data
+ Map<String, Double> binned = new HashMap<>();
+
+ // location of the family file
+ String families = "/media/sf_Shared_Folder/PFAM/Family/SeedFamilies.seed";
+
+ // location of the file containing the family-clan links
+ final static String FAMILIESTOCLAN = "/media/sf_Shared_Folder/PFAM/Family/Clanlinks.dat";
+
+ // location of the HMM file
+ String hmms = "/media/sf_Shared_Folder/PFAM/HMMs/Pfam-A.hmm";
+
+ // suffix for raw file
+ final static String RAW = "/Raw.csv";
+
+ // suffix for binned file
+ final static String BINNED = "/Binned.csv";
+
+ // normalisation scale
+ final static double SCALE = 1;
+
+ // current position in file
+ int currentFilePosition = 0;
+
+ final static String NL = "\n";
+
+ Random generator = new Random();
+
+ // current directory
+ String currentFolder;
+
+ boolean keepRaw = false;
+
+ /**
+ * Sets the working directory.
+ *
+ * @param path
+ */
+ public void setFolder(String path)
+ {
+ currentFolder = path;
+ }
+
+ /**
+ * Moves a buffered reader forward in the file by a certain amount of entries.
+ * Each entry in the file is delimited by '//'.
+ *
+ * @param index
+ * The index of the location in the file.
+ * @param br
+ * @throws IOException
+ */
+ public void moveLocationBy(int index, BufferedReader br)
+ throws IOException
+ {
+ for (int i = 0; i < index; i++)
+ {
+ String line = br.readLine();
+ while (!"//".equals(line))
+ {
+ line = br.readLine();
+
+ }
+ }
+
+ }
+
+ /**
+ * Analyses a specified number of families and then saves the data. Before
+ * analysing the data, the previous saved data will be imported and after
+ * analysing this, the data is exported back into the file. The file must be
+ * in flat file format.
+ *
+ * @param increments
+ * The number of families to read before saving.
+ * @throws IOException
+ */
+ public void run(int increments, boolean keepRawData) throws IOException
+ {
+ keepRaw = keepRawData;
+ try
+ {
+ readPreviousData(currentFolder);
+ BufferedReader posReader = new BufferedReader(
+ new FileReader(currentFolder + "/CurrentPosition.txt"));
+
+ String line = posReader.readLine();
+ posReader.close();
+ currentFilePosition = Integer.parseInt(line);
+ } catch (Exception e)
+ {
+ System.out.println("No previous data found");
+ }
+
+
+
+ BufferedReader inputSTO = new BufferedReader(new FileReader(families));
+ BufferedReader inputHMM = new BufferedReader(new FileReader(hmms));
+
+
+
+ moveLocationBy(currentFilePosition, inputHMM);
+ moveLocationBy(currentFilePosition, inputSTO);
+
+ int filesRead = 0;
+ int i = 0;
+ while (filesRead < increments)
+ {
+
+ readStockholm(inputSTO);
+
+ readHMM(inputHMM);
+
+ int count = countValidResidues();
+ processData(count);
+ filesRead++;
+
+ currentFilePosition++;
+ System.out.println(i);
+ i++;
+ }
+
+ PrintWriter p = new PrintWriter(
+ new File(currentFolder + "/CurrentPosition.txt"));
+ p.print(currentFilePosition);
+ p.close();
+ exportData(currentFolder);
+ raw.clear();
+ binned.clear();
+
+ }
+
+ /**
+ * Analyses all families and then saves the data. Before analysing the data,
+ * the previous saved data will be imported and after analysing this, the data
+ * is exported back into the file. The file must be in flat file format.
+ *
+ * @param increments
+ * The number of families to read before saving.
+ * @throws IOException
+ */
+ public void runToEnd(int minCount, int maxCount, boolean keepRawData,
+ boolean forClans)
+ throws IOException
+ {
+ keepRaw = keepRawData;
+ BufferedReader inputSTO = null;
+ BufferedReader inputHMM = null;
+ int size = 0;
+ int files = 1;
+ try
+ {
+ if (forClans)
+ {
+ files = 603;
+ }
+ int filesRead = 0;
+ for (int clan = 0; clan < files; clan++)
+ {
+ System.out.println(clan);
+ String clanPath = "";
+ int numberOfFamilies = 0;
+ if (forClans)
+ {
+ clanPath = currentFolder + "/Clan" + clan;
+ if (!new File(clanPath).exists())
+ {
+ continue;
+ }
+ BufferedReader famCountReader = new BufferedReader(
+ new FileReader(clanPath + "/NumberOfFamilies.txt"));
+ numberOfFamilies = Integer.parseInt(famCountReader.readLine());
+ }
+ else
+ {
+ numberOfFamilies = 1;
+ }
+
+ for (int fam = 0; fam < numberOfFamilies; fam++)
+ {
+ if (forClans)
+ {
+ families = clanPath + "/Families/Fam" + fam + ".sto";
+ hmms = clanPath + "/HMMs/HMM" + fam + ".hmm";
+ }
+
+ inputSTO = new BufferedReader(new FileReader(families));
+ inputHMM = new BufferedReader(new FileReader(hmms));
+
+
+ int i = 0;
+ boolean endReached = atEnd(inputSTO);
+ while (!endReached)
+ {
+ readStockholm(inputSTO);
+ readHMM(inputHMM);
+
+ int count = countValidResidues();
+ if (count >= minCount && count < maxCount)
+ {
+ processData(count);
+ }
+ filesRead++;
+ System.out.println(filesRead);
+ endReached = atEnd(inputSTO);
+ }
+ }
+ }
+ } catch (Exception e)
+ {
+ e.printStackTrace();
+ } finally
+ {
+ exportData(currentFolder);
+ raw.clear();
+ binned.clear();
+ }
+ }
+
+ /**
+ * Reads the previous data from both files
+ *
+ * @param source
+ * @throws IOException
+ */
+ public void readPreviousData(String source) throws IOException
+ {
+ readBinned(source);
+ if (keepRaw)
+ {
+ readRaw(source);
+ }
+ }
+
+ /**
+ * Reads the previous data from the binned file.
+ *
+ * @param source
+ * @throws IOException
+ */
+ public void readBinned(String source) throws IOException
+ {
+ BufferedReader input = new BufferedReader(
+ new FileReader(source + BINNED));
+ String line = input.readLine();
+ binned = new HashMap<>();
+ while (!("".equals(line) || line == null))
+ {
+ Scanner scanner = new Scanner(line);
+ scanner.useDelimiter(",");
+ String key = scanner.next();
+ String value = scanner.next();
+ binned.put(key, Double.valueOf(value));
+ scanner.close();
+ line = input.readLine();
+ }
+
+ input.close();
+ }
+
+ /**
+ * Reads the previous data from the raw file.
+ *
+ * @param source
+ * @throws IOException
+ */
+ public void readRaw(String source) throws IOException
+ {
+ BufferedReader input = new BufferedReader(new FileReader(source + RAW));
+ String line = input.readLine();
+ if (line == null)
+ {
+ input.close();
+ return;
+ }
+ Scanner numberScanner = new Scanner(line);
+ numberScanner.useDelimiter(",");
+ raw = new ArrayList<>();
+ while (numberScanner.hasNext())
+ {
+ numberScanner.next();
+ raw.add(new ArrayList<Double>());
+ }
+ numberScanner.close();
+
+ line = input.readLine();
+ while (!("".equals(line) || line == null))
+ {
+ Scanner scanner = new Scanner(line);
+ scanner.useDelimiter(",");
+
+ int i = 0;
+ while (scanner.hasNext())
+ {
+ String value;
+ value = scanner.next();
+ if (!value.equals("EMPTY"))
+ {
+ raw.get(i).add(Double.parseDouble(value));
+ }
+ else
+ {
+ raw.get(i).add(null);
+ }
+
+ i++;
+ }
+ scanner.close();
+ line = input.readLine();
+ }
+
+ input.close();
+ }
+
+ /**
+ * Counts the number of valid residues in the sequence.
+ *
+ * @return
+ */
+ public int countValidResidues()
+ {
+ int count = 0;
+
+ for (int width = 0; width < sequences.size(); width++)
+ {
+ for (int length = 1; length < hmm.getLength() + 1; length++)
+ {
+ char symbol;
+ int alignPos;
+ alignPos = hmm.getNodeMapPosition(length);
+
+ symbol = sequences.get(width).getCharAt(alignPos);
+ if (ResidueProperties.backgroundFrequencies.get("amino")
+ .containsKey(symbol))
+ {
+ count++;
+ }
+ }
+ }
+
+ return count;
+ }
+
+ /**
+ * Processes data, and stores it in both a raw and binned format.
+ *
+ * @param count
+ */
+ public void processData(int count)
+ {
+ int rawPos = 0;
+ if (keepRaw)
+ {
+ raw.add(new ArrayList<Double>());
+ rawPos = raw.size() - 1;
+ }
+ Double total = 0d;
+ for (int width = 0; width < sequences.size(); width++)
+ {
+ for (int length = 1; length < hmm.getLength() + 1; length++)
+ {
+ char symbol;
+ int alignPos;
+ alignPos = hmm.getNodeMapPosition(length);
+
+ symbol = sequences.get(width).getCharAt(alignPos);
+ if (ResidueProperties.backgroundFrequencies.get("amino")
+ .containsKey(symbol))
+ {
+ Double prob;
+ Float bfreq;
+ Double llr;
+ prob = hmm.getMatchEmissionProbability(alignPos, symbol);
+ bfreq = ResidueProperties.backgroundFrequencies.get("amino")
+ .get(symbol);
+ if (prob == 0 || bfreq == 0)
+ {
+ System.out.println("error");
+ }
+ llr = Math.log(prob / bfreq);
+ if (keepRaw)
+ {
+ raw.get(rawPos).add(llr);
+ }
+
+ String output;
+ output = String.format("%.1f", llr);
+ total += Double.parseDouble(output);
+ if ("-0.0".equals(output))
+ {
+ output = "0.0";
+ }
+ if (binned.containsKey(output))
+ {
+ double prev = binned.get(output);
+ prev += (SCALE / count);
+ binned.put(output, prev);
+
+ }
+ else
+ {
+ binned.put(output, SCALE / count);
+ }
+ }
+ }
+ }
+ System.out.println(total / count);
+ }
+
+
+ /**
+ * Reads in the sequence data from a Stockholm file.
+ *
+ * @param source
+ * @throws IOException
+ */
+ public void readStockholm(BufferedReader inputSTO) throws IOException
+ {
+ FileParse parserSTO = new FileParse(inputSTO, "", DataSourceType.FILE);
+ StockholmFile file = new StockholmFile(parserSTO);
+ Vector<AlignmentAnnotation> annots = file.getAnnotations();
+
+ for (AlignmentAnnotation annot : annots)
+ {
+ if (annot.label.contains("Reference"))
+ {
+ reference = annot;
+ }
+ }
+ sequences = file.getSeqs();
+ }
+
+ /**
+ * Reads in the HMM data from a HMMer file.
+ *
+ * @param source
+ * @throws IOException
+ */
+ public void readHMM(BufferedReader inputHMM) throws IOException
+ {
+ FileParse parserHMM = new FileParse(inputHMM, "", DataSourceType.FILE);
+ HMMFile file = new HMMFile(parserHMM);
+ hmm = file.getHMM();
+
+
+ }
+
+ /**
+ * Exports both the binned and raw data into separate files.
+ *
+ * @param location
+ * @throws FileNotFoundException
+ */
+ public void exportData(String location) throws FileNotFoundException
+ {
+ PrintWriter writerBin = new PrintWriter(new File(location + BINNED));
+ for (Map.Entry<String, Double> entry : binned.entrySet())
+ {
+ writerBin.println(entry.getKey() + "," + entry.getValue());
+ }
+ writerBin.close();
+ if (keepRaw)
+ {
+
+ PrintWriter writerRaw = new PrintWriter(new File(location + RAW));
+
+ StringBuilder identifier = new StringBuilder();
+
+ for (int i = 1; i < raw.size() + 1; i++)
+ {
+ identifier.append("Fam " + i + ",");
+ }
+
+ writerRaw.println(identifier);
+
+ boolean rowIsEmpty = false;
+ int row = 0;
+ while (!rowIsEmpty)
+ {
+ rowIsEmpty = true;
+ StringBuilder string = new StringBuilder();
+ for (int column = 0; column < raw.size(); column++)
+ {
+ if (raw.get(column).size() <= row)
+ {
+ string.append("EMPTY,");
+ }
+ else
+ {
+ string.append(raw.get(column).get(row) + ",");
+ rowIsEmpty = false;
+ }
+ }
+ row++;
+ writerRaw.println(string);
+ }
+ writerRaw.close();
+
+ }
+
+ }
+
+ /**
+ * Prints the specified family on the console.
+ *
+ * @param index
+ * @throws IOException
+ */
+ public void printFam(int index) throws IOException
+ {
+ BufferedReader br = new BufferedReader(new FileReader(families));
+
+ moveLocationBy(index, br);
+
+ String line = br.readLine();
+
+ while (!"//".equals(line))
+ {
+ System.out.println(line);
+ line = br.readLine();
+ }
+ System.out.println(line);
+ br.close();
+
+ }
+
+ /**
+ * Prints the specified HMM on the console.
+ *
+ * @param index
+ * @throws IOException
+ */
+ public void printHMM(int index) throws IOException
+ {
+ BufferedReader br = new BufferedReader(new FileReader(hmms));
+
+ moveLocationBy(index, br);
+
+ String line = br.readLine();
+
+ while (!"//".equals(line))
+ {
+ System.out.println(line);
+ line = br.readLine();
+ }
+ System.out.println(line);
+ br.close();
+
+ }
+
+ /**
+ * Prints the specified family to a .sto file.
+ *
+ * @param index
+ * @throws IOException
+ */
+ public void exportFam(int index, String location) throws IOException
+ {
+ BufferedReader br = new BufferedReader(new FileReader(families));
+
+ moveLocationBy(index, br);
+
+ String line = br.readLine();
+ PrintWriter writer = new PrintWriter(
+ new FileOutputStream(new File(location), true));
+ while (!"//".equals(line))
+ {
+ writer.println(line);
+ line = br.readLine();
+ }
+ writer.println(line);
+ writer.close();
+ br.close();
+
+ }
+
+ public void exportFile(BufferedReader br, String location, boolean append)
+ throws IOException
+ {
+ String line = br.readLine();
+ PrintWriter writer = new PrintWriter(
+ new FileOutputStream(location, append));
+ while (!"//".equals(line))
+ {
+ writer.println(line);
+ line = br.readLine();
+ }
+ writer.println(line);
+ writer.close();
+
+
+ }
+
+ public String getHMMName(int index) throws IOException
+ {
+ String name;
+
+ BufferedReader nameFinder = new BufferedReader(new FileReader(hmms));
+
+ moveLocationBy(index, nameFinder);
+
+ nameFinder.readLine();
+
+ Scanner scanner = new Scanner(nameFinder.readLine());
+ name = scanner.next();
+ name = scanner.next();
+ scanner.close();
+ return name;
+ }
+
+ public String getFamilyName(int index) throws IOException
+ {
+ String name;
+
+ BufferedReader nameFinder = new BufferedReader(
+ new FileReader(families));
+
+ moveLocationBy(index, nameFinder);
+
+ nameFinder.readLine();
+
+ Scanner scanner = new Scanner(nameFinder.readLine());
+ name = scanner.next();
+ name = scanner.next();
+ name = scanner.next();
+ scanner.close();
+ return name;
+ }
+
+ /**
+ * Prints the specified family to a .hmm file.
+ *
+ * @param index
+ * @throws IOException
+ */
+ public void exportHMM(int index, String location) throws IOException
+ {
+
+
+ BufferedReader br = new BufferedReader(new FileReader(hmms));
+
+ moveLocationBy(index, br);
+
+ String line = br.readLine();
+
+ PrintWriter writer = new PrintWriter(
+ new FileOutputStream(new File(location), true));
+ while (!"//".equals(line))
+ {
+ writer.println(line);
+ line = br.readLine();
+ }
+ writer.println(line);
+ writer.close();
+ br.close();
+
+ }
+
+ /**
+ * Clears all raw, binned and current position data in the current directory.
+ *
+ * @throws FileNotFoundException
+ */
+ public void clear() throws FileNotFoundException
+ {
+ PrintWriter pos = new PrintWriter(
+ currentFolder + "/CurrentPosition.txt");
+ pos.println("0");
+
+ PrintWriter raw = new PrintWriter(currentFolder + RAW);
+
+ PrintWriter bin = new PrintWriter(currentFolder + BINNED);
+
+ pos.close();
+ bin.close();
+ raw.close();
+ }
+
+ public void sortIntoClans(String directory) throws IOException
+ {
+ BufferedReader clanFinder = new BufferedReader(new FileReader(FAMILIESTOCLAN));
+ BufferedReader familyReader = new BufferedReader(
+ new FileReader(families));
+ BufferedReader hmmReader = new BufferedReader(new FileReader(hmms));
+ int families = 0;
+ // moveLocationBy(7000, familyReader);
+ // moveLocationBy(7000, clanFinder);
+ // moveLocationBy(7000, hmmReader);
+ HashMap<String, Integer> clanIndexes = new HashMap<>();
+ ArrayList<Integer> familyCounts = new ArrayList<>();
+ int filePos = 0;
+ int clanCount = 0;
+ String line;
+ line = clanFinder.readLine();
+
+ while (!"".equals(line) && !" ".equals(line) && line != null)
+ {
+ String clanName;
+ boolean inClan = false;
+ while (!(line.indexOf("//") > -1))
+ {
+
+ if (line.indexOf("#=GF CL") > -1)
+ {
+ families++;
+ System.out.println(families);
+ inClan = true;
+ Scanner scanner = new Scanner(line);
+ scanner.next();
+ scanner.next();
+ clanName = scanner.next();
+ scanner.close();
+
+ if (!clanIndexes.containsKey(clanName))
+ {
+ clanIndexes.put(clanName, clanCount);
+ clanCount++;
+ familyCounts.add(0);
+ }
+
+
+ Integer clanI = clanIndexes.get(clanName);
+ String clanPath = directory + "/Clan" + clanI.toString();
+ createFolders(clanPath);
+
+ int index = clanIndexes.get(clanName);
+ exportFile(familyReader,
+ clanPath + "/Families/Fam" + familyCounts.get(index)
+ + ".sto",
+ false);
+ exportFile(hmmReader,
+ clanPath + "/HMMs/HMM" + familyCounts.get(index) + ".hmm",
+ false);
+
+ int count = familyCounts.get(index);
+ count++;
+ familyCounts.set(index, count);
+ }
+ line = clanFinder.readLine();
+
+ }
+ if (!inClan)
+ {
+ moveLocationBy(1, familyReader);
+ moveLocationBy(1, hmmReader);
+ }
+ filePos++;
+ // System.out.println(filePos + " files read.");
+ line = clanFinder.readLine();
+
+ }
+ clanFinder.close();
+
+ for (int clan = 0; clan < clanCount; clan++)
+ {
+ PrintWriter writer = new PrintWriter(
+ directory + "/Clan" + clan + "/NumberOfFamilies.txt");
+ int count = familyCounts.get(clan);
+ writer.print(count);
+ writer.close();
+ }
+
+ }
+
+ public String getFamilies()
+ {
+ return families;
+ }
+
+ public void setFamilies(String families)
+ {
+ this.families = currentFolder + families;
+ }
+
+ public String getHmms()
+ {
+ return hmms;
+ }
+
+ public void setHmms(String hmms)
+ {
+ this.hmms = currentFolder + hmms;
+ }
+
+ public void alignWithinClan(String exportLocation, String clansLocation)
+ throws IOException, InterruptedException
+ {
+ int alignmentsExported = 0;
+ for (int clan = 0; clan < 604; clan++)
+ {
+ System.out.println(clan);
+ int famCount = 0;
+ String clanPath = clansLocation + "/Clan" + clan;
+ int numberOfFamilies;
+ BufferedReader br = new BufferedReader(
+ new FileReader(clanPath + "/NumberOfFamilies.txt"));
+ String line = br.readLine();
+ numberOfFamilies = Integer.parseInt(line);
+ br.close();
+ if (numberOfFamilies == 1)
+ {
+ continue;
+ }
+ final String commandExportLocation = exportLocation + "/Clan" + clan;
+ createFolders(commandExportLocation);
+ for (int family = 0; family < numberOfFamilies; family++)
+ {
+ famCount++;
+ ArrayList<Integer> indexes = new ArrayList<>();
+ for (int i = 0; i < numberOfFamilies; i++)
+ {
+ if (i != family)
+ {
+ indexes.add(i);
+ }
+ }
+
+ int hmmIndex = getRandom(indexes);
+ String famPath = clanPath + "/Families/Fam" + family + ".sto";
+ String hmmPath = clanPath + "/HMMs/HMM" + hmmIndex + ".hmm";
+ String command = "/media/sf_Shared_Folder/hmmer/binaries/hmmalign --mapali "
+ + clanPath + "/Families/Fam" + hmmIndex + ".sto"
+ + " --trim ";
+ command += hmmPath + " ";
+ command += famPath;
+ final int familyIndex = family;
+ final Process p = Runtime.getRuntime().exec(command);
+
+ new Thread(new Runnable()
+ {
+ @Override
+ public void run()
+ {
+ BufferedReader input = new BufferedReader(
+ new InputStreamReader(p.getInputStream()));
+ String line = null;
+
+ try
+ {
+ PrintWriter writer = new PrintWriter(commandExportLocation
+ + "/Families/Fam" + familyIndex + ".sto");
+ String lastLine = "";
+ boolean dataFound = false;
+ while ((line = input.readLine()) != null)
+ {
+ if (line.contains("#=GR") && !dataFound)
+ {
+ writer.println(lastLine);
+ dataFound = true;
+ }
+ if (line.contains("#") || dataFound || " ".equals(line)
+ || "".equals(line) || "//".equals(line))
+ {
+ writer.println(line);
+ }
+ lastLine = line;
+ }
+ writer.close();
+ } catch (IOException e)
+ {
+ e.printStackTrace();
+ }
+ }
+ }).start();
+
+ p.waitFor();
+
+ BufferedReader hmmExporter = new BufferedReader(
+ new FileReader(hmmPath));
+
+ exportFile(hmmExporter,
+ commandExportLocation + "/HMMs/HMM" + family + ".hmm",
+ false);
+
+ alignmentsExported++;
+
+
+ }
+ PrintWriter writer = new PrintWriter(
+ commandExportLocation + "/NumberOfFamilies.txt");
+ writer.print(famCount);
+ writer.close();
+ }
+
+ }
+
+ public boolean atEnd(BufferedReader br) throws IOException
+ {
+ boolean end = false;
+ br.mark(80);
+ String line = br.readLine();
+ if ("".equals(line) || line == null)
+ {
+ end = true;
+ }
+ br.reset();
+ return end;
+ }
+
+ public int getRandom(ArrayList<Integer> list)
+ {
+ if (!(list.size() > 0))
+ {
+ System.out.println("Error - size = " + list.size());
+ }
+ int index = generator.nextInt(list.size());
+ int value = list.get(index);
+ list.remove(index);
+ return value;
+ }
+
+ public void createFolders(String clanPath)
+ {
+ File clanFolder = new File(clanPath);
+ if (!clanFolder.exists())
+ {
+ clanFolder.mkdir();
+ }
+
+ File famFolder = new File(clanPath + "/Families");
+ File hmmFolder = new File(clanPath + "/HMMs");
+ if (!famFolder.exists())
+ {
+ famFolder.mkdir();
+ hmmFolder.mkdir();
+ }
+ }
+}
+
+
+
+
*/
package jalview.util;
+import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
}
return false;
}
-
public static boolean startsWithHttpOrHttps(String file)
{
return file.startsWith("http://") || file.startsWith("https://");
}
-
/**
* wrapper to get/post to a URL or check headers
* @param url
return connection.getResponseCode() == 200;
}
+ /**
+ * download from given URL and return a pointer to temporary file
+ */
+ public static File fetchURLToTemp(String url) throws OutOfMemoryError,
+ IOException
+ {
+ long time = System.currentTimeMillis();
+ URL rcall = new URL(url);
+
+ InputStream is = new BufferedInputStream(rcall.openStream());
+ File outFile = null;
+ try
+ {
+ outFile = File.createTempFile("jalview", ".xml");
+ outFile.deleteOnExit();
+ if (outFile.length() == 0)
+ {
+ outFile.delete();
+ return null;
+ }
+ } catch (Exception ex)
+ {
+ }
+
+ if (outFile != null)
+ {
+ FileOutputStream fio = new FileOutputStream(outFile);
+ byte[] bb = new byte[32 * 1024];
+ int l;
+ while ((l = is.read(bb)) > 0)
+ {
+ fio.write(bb, 0, l);
+ }
+ fio.close();
+ is.close();
+ return outFile;
+ }
+ else
+ {
+ return null;
+ }
+ }
}
for (int[] range : map.getFromRanges())
{
- addRange(range, fromShifts);
+ MappingUtils.addRange(range, fromShifts);
}
for (int[] range : map.getToRanges())
{
- addRange(range, toShifts);
+ MappingUtils.addRange(range, toShifts);
}
}
/**
- * Adds the given range to a list of ranges. If the new range just extends
- * existing ranges, the current endpoint is updated instead.
- *
- * @param range
- * @param addTo
- */
- static void addRange(int[] range, List<int[]> addTo)
- {
- /*
- * list is empty - add to it!
- */
- if (addTo.size() == 0)
- {
- addTo.add(range);
- return;
- }
-
- int[] last = addTo.get(addTo.size() - 1);
- boolean lastForward = last[1] >= last[0];
- boolean newForward = range[1] >= range[0];
-
- /*
- * contiguous range in the same direction - just update endpoint
- */
- if (lastForward == newForward && last[1] == range[0])
- {
- last[1] = range[1];
- return;
- }
-
- /*
- * next range starts at +1 in forward sense - update endpoint
- */
- if (lastForward && newForward && range[0] == last[1] + 1)
- {
- last[1] = range[1];
- return;
- }
-
- /*
- * next range starts at -1 in reverse sense - update endpoint
- */
- if (!lastForward && !newForward && range[0] == last[1] - 1)
- {
- last[1] = range[1];
- return;
- }
-
- /*
- * just add the new range
- */
- addTo.add(range);
- }
-
- /**
* Returns true if mapping is from forward strand, false if from reverse
* strand. Result is just based on the first 'from' range that is not a single
* position. Default is true unless proven to be false. Behaviour is not well
*/
package jalview.util;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
import jalview.analysis.AlignmentSorter;
import jalview.api.AlignViewportI;
import jalview.commands.CommandI;
import jalview.datamodel.SequenceGroup;
import jalview.datamodel.SequenceI;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
/**
* Helper methods for manipulations involving sequence mappings.
*
while (regions.hasNext())
{
mapHiddenColumns(regions.next(), codonFrames, newHidden,
- fromSequences, toSequences, fromGapChar);
+ fromSequences,
+ toSequences, fromGapChar);
}
return; // mappedColumns;
}
int min = Math.min(range[0], range[1]);
int max = Math.max(range[0], range[1]);
-
+
return (min <= queryRange[0] && max >= queryRange[0]
&& min <= queryRange[1] && max >= queryRange[1]);
}
* a list of (single) [start, end] ranges
* @return
*/
- public static void removeEndPositions(int positions, List<int[]> ranges)
+ public static void removeEndPositions(int positions,
+ List<int[]> ranges)
{
int toRemove = positions;
Iterator<int[]> it = new ReverseListIterator<>(ranges);
/*
* not coded for [start1, end1, start2, end2, ...]
*/
- System.err.println(
- "MappingUtils.removeEndPositions doesn't handle multiple ranges");
+ System.err
+ .println("MappingUtils.removeEndPositions doesn't handle multiple ranges");
return;
}
/*
* not coded for a reverse strand range (end < start)
*/
- System.err.println(
- "MappingUtils.removeEndPositions doesn't handle reverse strand");
+ System.err
+ .println("MappingUtils.removeEndPositions doesn't handle reverse strand");
return;
}
if (length > toRemove)
}
}
}
+ /**
+ * Adds the given range to a list of ranges. If the new range just extends
+ * existing ranges, the current endpoint is updated instead.
+ *
+ * @param range
+ * @param addTo
+ */
+ public static void addRange(int[] range, List<int[]> addTo)
+ {
+ /*
+ * list is empty - add to it!
+ */
+ if (addTo.size() == 0)
+ {
+ addTo.add(range);
+ return;
+ }
+
+ int[] last = addTo.get(addTo.size() - 1);
+ boolean lastForward = last[1] >= last[0];
+ boolean newForward = range[1] >= range[0];
+
+ /*
+ * contiguous range in the same direction - just update endpoint
+ */
+ if (lastForward == newForward && last[1] == range[0])
+ {
+ last[1] = range[1];
+ return;
+ }
+
+ /*
+ * next range starts at +1 in forward sense - update endpoint
+ */
+ if (lastForward && newForward && range[0] == last[1] + 1)
+ {
+ last[1] = range[1];
+ return;
+ }
+
+ /*
+ * next range starts at -1 in reverse sense - update endpoint
+ */
+ if (!lastForward && !newForward && range[0] == last[1] - 1)
+ {
+ last[1] = range[1];
+ return;
+ }
+
+ /*
+ * just add the new range
+ */
+ addTo.add(range);
+ }
/**
* Converts a list of {@code start-end} ranges to a single array of
// Locale.setDefault(loc);
/* Getting messages for GV */
log.info("Getting messages for lang: " + loc);
- Control control = Control.getControl(Control.FORMAT_PROPERTIES);
- rb = ResourceBundle.getBundle("lang.Messages", loc, control);
+ rb = ResourceBundle.getBundle("lang.Messages", Platform.getLocaleOrNone(loc), Control.getControl(Control.FORMAT_PROPERTIES));
// if (log.isLoggable(Level.FINEST))
// {
// // this might take a while, so we only do it if it will be shown
} catch (Exception e)
{
String msg = "I18N missing: " + loc + "\t" + key;
- logWarning(key, msg);
+ logWarning(key, msg);
}
return value;
}
} catch (Exception x)
{
String msg = "I18N missing key with root " + keyroot + ": " + loc + "\t"
- + smkey;
- logWarning(smkey, msg);
+ + smkey;
+ logWarning(smkey, msg);
}
return name;
}
*/
private static void logWarning(String key, String msg)
{
- if (!reportedMissing.contains(key))
- {
+ if (!reportedMissing.contains(key))
+ {
reportedMissing.add(key);
- log.info(msg);
- }
+ log.info(msg);
+ }
}
}
*/
package jalview.util;
-import jalview.javascript.json.JSON;
+import java.awt.Component;
+import java.awt.Dimension;
+import java.awt.GraphicsEnvironment;
import java.awt.Toolkit;
+import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.io.BufferedReader;
import java.io.File;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
+import java.lang.reflect.Method;
import java.net.URL;
+import java.nio.channels.Channels;
+import java.nio.channels.ReadableByteChannel;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.StandardCopyOption;
+import java.nio.file.attribute.BasicFileAttributes;
+import java.util.Date;
+import java.util.Locale;
+import java.util.Map;
import java.util.Properties;
+import java.util.logging.ConsoleHandler;
+import java.util.logging.Level;
+import java.util.logging.Logger;
import javax.swing.SwingUtilities;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
+import com.stevesoft.pat.Regex;
+
+import jalview.bin.Jalview;
+import jalview.javascript.json.JSON;
+import swingjs.api.JSUtilI;
/**
* System platform information used by Applet and Application
*
private static Boolean isNoJSMac = null, isNoJSWin = null, isMac = null,
isWin = null, isLinux = null;
+
private static Boolean isHeadless = null;
+ private static swingjs.api.JSUtilI jsutil;
+
+ static
+ {
+ if (isJS)
+ {
+ try
+ {
+ // this is ok - it's a highly embedded method in Java; the deprecation
+ // is
+ // really a recommended best practice.
+ jsutil = ((JSUtilI) Class.forName("swingjs.JSUtil").newInstance());
+ } catch (InstantiationException | IllegalAccessException
+ | ClassNotFoundException e)
+ {
+ e.printStackTrace();
+ }
+ }
+ }
+
/**
* added to group mouse events into Windows and nonWindows (mac, unix, linux)
*
: isMac);
}
+ public static int SHORTCUT_KEY_MASK = (Platform.isMac()
+ ? KeyEvent.META_DOWN_MASK
+ : KeyEvent.CTRL_DOWN_MASK);
+
+ static
+ {
+ if (!GraphicsEnvironment.isHeadless())
+ {
+ // Using non-deprecated Extended key mask modifiers, but Java 8 has no
+ // getMenuShortcutKeyMaskEx method
+ Toolkit tk = Toolkit.getDefaultToolkit();
+ Method method = null;
+ try
+ {
+ method = tk.getClass().getMethod("getMenuShortcutKeyMaskEx");
+ } catch (Exception e)
+ {
+ System.err.println(
+ "Could not find Toolkit method getMenuShortcutKeyMaskEx. Trying getMenuShortcutKeyMask.");
+ }
+ if (method == null)
+ {
+ try
+ {
+ method = tk.getClass().getMethod("getMenuShortcutKeyMask");
+ } catch (Exception e)
+ {
+ System.err.println(
+ "Could not find Toolkit method getMenuShortcutKeyMaskEx or getMenuShortcutKeyMask.");
+ e.printStackTrace();
+ }
+ }
+ if (method != null)
+ {
+ try
+ {
+ method.setAccessible(true);
+ SHORTCUT_KEY_MASK = ((int) method.invoke(tk, new Object[0]));
+ } catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ }
+ if (SHORTCUT_KEY_MASK <= 0xF)
+ {
+ // shift this into the extended region (was Java 8)
+ SHORTCUT_KEY_MASK = SHORTCUT_KEY_MASK << 6;
+ }
+ }
+ }
/**
* added to group mouse events into Windows and nonWindows (mac, unix, linux)
*
}
/**
- * Check if we are on a Microsoft plaform...
+ * Check if we are on a Microsoft platform...
*
* @return true if we have to cope with another platform variation
*/
*/
protected static boolean isControlDown(MouseEvent e, boolean aMac)
{
- if (!aMac)
- {
- return e.isControlDown();
-
- // Jalview 2.11 code below: above is as amended for JalviewJS
- // /*
- // * answer false for right mouse button
- // */
- // if (e.isPopupTrigger())
- // {
- // return false;
- // }
- // return
- // (jalview.util.ShortcutKeyMaskExWrapper.getMenuShortcutKeyMaskEx() //
- // .getMenuShortcutKeyMaskEx()
- // & jalview.util.ShortcutKeyMaskExWrapper
- // .getModifiersEx(e)) != 0; // getModifiers()) != 0;
- }
- // answer false for right mouse button
- // shortcut key will be META for a Mac
- return !e.isPopupTrigger()
- && (Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()
- & e.getModifiers()) != 0;
- // could we use e.isMetaDown() here?
+ //
+ // System.out.println(e.isPopupTrigger()
+ // + " " + ((SHORTCUT_KEY_MASK & e.getModifiersEx()) != 0)
+ // + " " + e.isControlDown());
+ return (aMac
+ ? !e.isPopupTrigger()
+ && (SHORTCUT_KEY_MASK & e.getModifiersEx()) != 0
+ : e.isControlDown());
}
// BH: I don't know about that previous method. Here is what SwingJS uses.
public static long time, mark, set, duration;
+ /**
+ * typical usage:
+ *
+ * Platform.timeCheck(null, Platform.TIME_MARK);
+ *
+ * ...
+ *
+ * Platform.timeCheck("some message", Platform.TIME_MARK);
+ *
+ * reset...[set/mark]n...get
+ *
+ * @param msg
+ * @param mode
+ */
public static void timeCheck(String msg, int mode)
{
long t = System.currentTimeMillis();
{
case TIME_RESET:
time = mark = t;
+ duration = 0;
if (msg != null)
{
System.err.println("Platform: timer reset\t\t\t" + msg);
case TIME_MARK:
if (set > 0)
{
+ // total time between set/mark points
duration += (t - set);
}
else
public static void cacheFileData(String path, Object data)
{
- if (!isJS() || data == null)
+ if (isJS && data != null)
{
- return;
+ jsutil.cachePathData(path, data);
}
- /**
- * @j2sNative
- *
- * swingjs.JSUtil.cacheFileData$S$O(path, data);
- *
- */
}
public static void cacheFileData(File file)
{
- byte[] data;
- if (!isJS() || (data = Platform.getFileBytes(file)) == null)
+ if (isJS)
{
- return;
+ byte[] data = Platform.getFileBytes(file);
+ {
+ if (data != null)
+ {
+ cacheFileData(file.toString(), data);
+ }
+ }
}
- cacheFileData(file.toString(), data);
}
public static byte[] getFileBytes(File f)
{
- return /** @j2sNative f && swingjs.JSUtil.getFileAsBytes$O(f) || */
- null;
+ return (isJS && f != null ? jsutil.getBytes(f) : null);
}
public static byte[] getFileAsBytes(String fileStr)
{
- byte[] bytes = null;
- // BH 2018 hack for no support for access-origin
- /**
- * @j2sNative bytes = swingjs.JSUtil.getFileAsBytes$O(fileStr)
- */
- cacheFileData(fileStr, bytes);
- return bytes;
+ if (isJS && fileStr != null)
+ {
+ byte[] bytes = (byte[]) jsutil.getFile(fileStr, false);
+ cacheFileData(fileStr, bytes);
+ return bytes;
+ }
+ return null;
}
- @SuppressWarnings("unused")
public static String getFileAsString(String url)
{
- String ret = null;
- /**
- * @j2sNative
- *
- * ret = swingjs.JSUtil.getFileAsString$S(url);
- *
- *
- */
- cacheFileData(url, ret);
- return ret;
+ if (isJS && url != null)
+ {
+ String ret = (String) jsutil.getFile(url, true);
+ cacheFileData(url, ret);
+ return ret;
+ }
+ return null;
}
public static boolean setFileBytes(File f, String urlstring)
{
- if (!isJS())
+ if (isJS && f != null && urlstring != null)
{
- return false;
+ @SuppressWarnings("unused")
+ byte[] bytes = getFileAsBytes(urlstring);
+ jsutil.setFileBytes(f, bytes);
+ return true;
}
- @SuppressWarnings("unused")
- byte[] bytes = getFileAsBytes(urlstring);
- // TODO temporary doubling of 秘bytes and _bytes;
- // just remove _bytes when new transpiler has been installed
- /**
- * @j2sNative f.\u79d8bytes = f._bytes = bytes;
- */
- return true;
+ return false;
}
public static void addJ2SBinaryType(String ext)
{
- /**
- * @j2sNative
- *
- * J2S._binaryTypes.push("." + ext + "?");
- *
- */
+ if (isJS)
+ {
+ jsutil.addBinaryFileType(ext);
+ }
}
/**
* @param url
* @return true if window has been opened
*/
- public static boolean openURL(String url)
+ public static boolean openURL(String url) throws IOException
{
if (!isJS())
{
public static String getUniqueAppletID()
{
- /**
- * @j2sNative return swingjs.JSUtil.getApplet$()._uniqueId;
- *
- */
- return null;
+ return (isJS ? (String) jsutil.getAppletAttribute("_uniqueId") : null);
}
*/
public static void readInfoProperties(String prefix, Properties p)
{
- if (!isJS())
+ if (isJS)
{
- return;
- }
- String id = getUniqueAppletID();
- String key = "", value = "";
- /**
- * @j2sNative var info = swingjs.JSUtil.getApplet$().__Info || {}; for (var
- * key in info) { if (key.indexOf(prefix) == 0) { value = "" +
- * info[key];
- */
+ String id = getUniqueAppletID();
- System.out.println(
- "Platform id=" + id + " reading Info." + key + " = " + value);
- p.put(id + "_" + key, value);
+ String key = "";
+ String value = "";
+ @SuppressWarnings("unused")
+ Object info = jsutil.getAppletAttribute("__Info");
+ /**
+ * @j2sNative for (key in info) { value = info[key];
+ */
- /**
- * @j2sNative
- *
- *
- * } }
- */
+ if (key.indexOf(prefix) == 0)
+ {
+ System.out.println("Platform id=" + id + " reading Info." + key
+ + " = " + value);
+ p.put(key, value);
+
+ }
+
+ /**
+ * @j2sNative }
+ */
+ }
}
public static void setAjaxJSON(URL url)
public static Object parseJSON(String json) throws ParseException
{
- return (isJS() ? JSON.parse(json)
- : new JSONParser().parse(json));
+ return (isJS() ? JSON.parse(json) : new JSONParser().parse(json));
}
public static Object parseJSON(Reader r)
* @param is
* @param outFile
* @throws IOException
- * if the file cannot be created or there is a problem
- * reading the input stream.
+ * if the file cannot be created or there is a problem reading the
+ * input stream.
*/
public static void streamToFile(InputStream is, File outFile)
throws IOException
{
- if (isJS() && /**
- * @j2sNative outFile.setBytes$O && outFile.setBytes$O(is) &&
- */
- true)
+ if (isJS)
{
+ jsutil.setFileBytes(outFile, is);
return;
}
FileOutputStream fio = new FileOutputStream(outFile);
public static void addJ2SDirectDatabaseCall(String domain)
{
- if (isJS())
+ if (isJS)
{
+ jsutil.addDirectDatabaseCall(domain);
System.out.println(
- "Platform adding known access-control-allow-origin * for domain "
- + domain);
- /**
- * @j2sNative
- *
- * J2S.addDirectDatabaseCall(domain);
- */
+ "Platform adding known access-control-allow-origin * for domain "
+ + domain);
}
}
+ /**
+ * Allow for URL-line command arguments. Untested.
+ *
+ */
public static void getURLCommandArguments()
{
+
try {
/**
* Retrieve the first query field as command arguments to Jalview. Include
} catch (Throwable t)
{
}
+
}
/**
- * A (case sensitive) file path comparator that ignores the difference between /
- * and \
+ * A (case sensitive) file path comparator that ignores the difference between
+ * / and \
*
* @param path1
* @param path2
String p2 = path2.replace('\\', '/');
return p1.equals(p2);
}
+ ///////////// JAL-3253 Applet additions //////////////
+
+ /**
+ * Retrieve the object's embedded size from a div's style on a page if
+ * embedded in SwingJS.
+ *
+ * @param frame
+ * JFrame or JInternalFrame
+ * @param defaultWidth
+ * use -1 to return null (no default size)
+ * @param defaultHeight
+ * @return the embedded dimensions or null (no default size or not embedded)
+ */
+ public static Dimension getDimIfEmbedded(Component frame,
+ int defaultWidth, int defaultHeight)
+ {
+ Dimension d = null;
+ if (isJS)
+ {
+ d = (Dimension) getEmbeddedAttribute(frame, "dim");
+ }
+ return (d == null && defaultWidth >= 0
+ ? new Dimension(defaultWidth, defaultHeight)
+ : d);
+
+ }
+
+ public static Regex newRegex(String regex)
+ {
+ return newRegex(regex, null);
+ }
+
+ public static Regex newRegex(String searchString, String replaceString)
+ {
+ ensureRegex();
+ return (replaceString == null ? new Regex(searchString)
+ : new Regex(searchString, replaceString));
+ }
+
+ public static Regex newRegexPerl(String code)
+ {
+ ensureRegex();
+ return Regex.perlCode(code);
+ }
+
+ /**
+ * Initialize Java debug logging. A representative sample -- adapt as desired.
+ */
+ public static void startJavaLogging()
+ {
+ /**
+ * @j2sIgnore
+ */
+ {
+ logClass("java.awt.EventDispatchThread", "java.awt.EventQueue",
+ "java.awt.Component", "java.awt.focus.Component",
+ "java.awt.event.Component",
+ "java.awt.focus.DefaultKeyboardFocusManager");
+ }
+ }
+
+ /**
+ * Initiate Java logging for a given class. Only for Java, not JavaScript;
+ * Allows debugging of complex event processing.
+ *
+ * @param className
+ */
+ public static void logClass(String... classNames)
+ {
+ /**
+ * @j2sIgnore
+ *
+ *
+ */
+ {
+ Logger rootLogger = Logger.getLogger("");
+ rootLogger.setLevel(Level.ALL);
+ ConsoleHandler consoleHandler = new ConsoleHandler();
+ consoleHandler.setLevel(Level.ALL);
+ for (int i = classNames.length; --i >= 0;)
+ {
+ Logger logger = Logger.getLogger(classNames[i]);
+ logger.setLevel(Level.ALL);
+ logger.addHandler(consoleHandler);
+ }
+ }
+ }
+
+ /**
+ * load a resource -- probably a core file -- if and only if a particular
+ * class has not been instantialized. We use a String here because if we used
+ * a .class object, that reference itself would simply load the class, and we
+ * want the core package to include that as well.
+ *
+ * @param resourcePath
+ * @param className
+ */
+ public static void loadStaticResource(String resourcePath,
+ String className)
+ {
+ if (isJS)
+ {
+ jsutil.loadResourceIfClassUnknown(resourcePath, className);
+ }
+ }
+
+ public static void ensureRegex()
+ {
+ if (isJS)
+ {
+ loadStaticResource("core/core_stevesoft.z.js",
+ "com.stevesoft.pat.Regex");
+ }
+ }
+
+ /**
+ * Set the "app" property of the HTML5 applet object, for example,
+ * "testApplet.app", to point to the Jalview instance. This will be the object
+ * that page developers use that is similar to the original Java applet object
+ * that was accessed via LiveConnect.
+ *
+ * @param j
+ */
+ public static void setAppClass(Object j)
+ {
+ if (isJS)
+ {
+ jsutil.setAppClass(j);
+ }
+ }
+
+ /**
+ *
+ * If this frame is embedded in a web page, return a known type.
+ *
+ * @param frame
+ * a JFrame or JInternalFrame
+ * @param type
+ * "name", "node", "init", "dim", or any DOM attribute, such as "id"
+ * @return null if frame is not embedded.
+ */
+ public static Object getEmbeddedAttribute(Component frame, String type)
+ {
+ return (isJS ? jsutil.getEmbeddedAttribute(frame, type) : null);
+ }
+
+ public static void stackTrace()
+ {
+ try
+ {
+ throw new NullPointerException();
+ } catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+
+ }
+
+ public static URL getDocumentBase()
+ {
+ return (isJS ? jsutil.getDocumentBase() : null);
+ }
+
+ public static URL getCodeBase()
+ {
+ return (isJS ? jsutil.getCodeBase() : null);
+ }
+
+ public static String getUserPath(String subpath)
+ {
+ char sep = File.separatorChar;
+ return System.getProperty("user.home") + sep
+ + subpath.replace('/', sep);
+ }
+
+ /**
+ * This method enables checking if a cached file has exceeded a certain
+ * threshold(in days)
+ *
+ * @param file
+ * the cached file
+ * @param noOfDays
+ * the threshold in days
+ * @return
+ */
+ public static boolean isFileOlderThanThreshold(File file, int noOfDays)
+ {
+ if (isJS())
+ {
+ // not meaningful in SwingJS -- this is a session-specific temp file. It
+ // doesn't have a timestamp.
+ return false;
+ }
+ Path filePath = file.toPath();
+ BasicFileAttributes attr;
+ int diffInDays = 0;
+ try
+ {
+ attr = Files.readAttributes(filePath, BasicFileAttributes.class);
+ diffInDays = (int) ((new Date().getTime()
+ - attr.lastModifiedTime().toMillis())
+ / (1000 * 60 * 60 * 24));
+ // System.out.println("Diff in days : " + diffInDays);
+ } catch (IOException e)
+ {
+ e.printStackTrace();
+ }
+ return noOfDays <= diffInDays;
+ }
+
+ /**
+ * Get the leading integer part of a string that begins with an integer.
+ *
+ * @param input
+ * - the string input to process
+ * @param failValue
+ * - value returned if unsuccessful
+ * @return
+ */
+ public static int getLeadingIntegerValue(String input, int failValue)
+ {
+ if (input == null)
+ {
+ return failValue;
+ }
+ if (isJS)
+ {
+ int val = /** @j2sNative 1 ? parseInt(input) : */
+ 0;
+ return (val == val + 0 ? val : failValue);
+ }
+ // JavaScript does not support Regex ? lookahead
+ String[] parts = input.split("(?=\\D)(?<=\\d)");
+ if (parts != null && parts.length > 0 && parts[0].matches("[0-9]+"))
+ {
+ return Integer.valueOf(parts[0]);
+ }
+ return failValue;
+ }
+
+ public static Map<String, Object> getAppletInfoAsMap()
+ {
+ return (isJS ? jsutil.getAppletInfoAsMap() : null);
+ }
+
+ /**
+ * Get the SwingJS applet ID and combine that with the frameType
+ *
+ * @param frameType
+ * "alignment", "desktop", etc., or null
+ * @return
+ */
+ public static String getAppID(String frameType)
+ {
+
+ String id = Jalview.getInstance().j2sAppletID;
+ if (id == null)
+ {
+ Jalview.getInstance().j2sAppletID = id = (isJS
+ ? (String) jsutil.getAppletAttribute("_id")
+ : "jalview");
+ }
+ return id + (frameType == null ? "" : "-" + frameType);
+ }
+
+ /**
+ * Option to avoid unnecessary seeking of nonexistent resources in JavaScript.
+ * Works in Java as well.
+ *
+ * @param loc
+ * @return
+ */
+ public static Locale getLocaleOrNone(Locale loc)
+ {
+ return (isJS && loc.getLanguage() == "en" ? new Locale("") : loc);
+ }
+
+ /**
+ * From UrlDownloadClient; trivial in JavaScript; painful in Java.
+ *
+ * @param urlstring
+ * @param outfile
+ * @throws IOException
+ */
+ public static void download(String urlstring, String outfile)
+ throws IOException
+ {
+ Path temp = null;
+ try (InputStream is = new URL(urlstring).openStream())
+ {
+ if (isJS)
+ { // so much easier!
+ streamToFile(is, new File(outfile));
+ return;
+ }
+ temp = Files.createTempFile(".jalview_", ".tmp");
+ try (FileOutputStream fos = new FileOutputStream(temp.toString());
+ ReadableByteChannel rbc = Channels.newChannel(is))
+ {
+ fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);
+ // copy tempfile to outfile once our download completes
+ // incase something goes wrong
+ Files.copy(temp, Paths.get(outfile),
+ StandardCopyOption.REPLACE_EXISTING);
+ }
+ } catch (IOException e)
+ {
+ throw e;
+ } finally
+ {
+ try
+ {
+ if (temp != null)
+ {
+ Files.deleteIfExists(temp);
+ }
+ } catch (IOException e)
+ {
+ System.out.println("Exception while deleting download temp file: "
+ + e.getMessage());
+ }
+ }
+ }
}
--- /dev/null
+package jalview.util;
+
+import java.io.IOException;
+import java.util.Scanner;
+
+/**
+ * This class contains the brain of the analyser program, and contains a number
+ * of commands for the processing of data.
+ *
+ * @author TZVanaalten
+ *
+ */
+
+public class ProbabilityAnalyserKickstarter
+{
+
+ public static void main(String[] args)
+ throws IOException, InterruptedException
+ {
+
+ // this does all of the processing
+ HMMProbabilityDistributionAnalyser analyser = new HMMProbabilityDistributionAnalyser();
+
+ boolean running = true;
+ System.out.println("ACTIVATED");
+ while (running)
+ {
+ Scanner keyboard = new Scanner(System.in);
+ String command = keyboard.nextLine();
+
+ Scanner inputScanner = new Scanner(command);
+ // prints family to console. Syntax is printFam <index>
+ if (command.indexOf("printFam") > -1)
+ {
+ try
+ {
+ inputScanner.next();
+ int index = inputScanner.nextInt();
+ analyser.printFam(index);
+ continue;
+ } catch (Exception e)
+ {
+ System.out.println("Command failed");
+ }
+
+ }
+ // prints HMM to console. Syntax is printHMM <index>
+ if (command.indexOf("printHMM") > -1)
+ {
+ try
+ {
+ inputScanner.next();
+ int index = inputScanner.nextInt();
+ analyser.printHMM(index);
+ continue;
+ } catch (Exception e)
+ {
+ System.out.println("Command failed");
+ }
+ }
+ // prints family to file in current folder. Syntax is exportFam <index>.
+ if (command.indexOf("exportFam") > -1)
+ {
+ try
+ {
+ inputScanner.next();
+ int index = inputScanner.nextInt();
+ String location = inputScanner.next();
+ analyser.exportFam(index, location);
+ continue;
+ } catch (Exception e)
+ {
+ System.out.println("Command failed");
+ }
+ }
+ // prints HMM to file in current folder. Syntax is exportHMM <index>.
+ if (command.indexOf("exportHMM") > -1)
+ {
+ try
+ {
+ inputScanner.next();
+ int index = inputScanner.nextInt();
+ String location = inputScanner.next();
+ analyser.exportHMM(index, location);
+ continue;
+ } catch (Exception e)
+ {
+ System.out.println("Command failed");
+ }
+ }
+ // Processes data. Syntax is run <number of loops> <increments>. The
+ // number loops specifies the number of increments the program will run.
+ // After each increment, the data stored currently in the program is
+ // exported and re-read back into the program. This is to ensure that the
+ // program can be terminated without losing a large quantity of data. The
+ // increment is the number of families read per 'save'.
+ if (command.indexOf("run") > -1 && !(command.indexOf("ToEnd") > -1))
+ {
+ try
+ {
+
+ inputScanner.next();
+
+ int loops = inputScanner.nextInt();
+ int increments = inputScanner.nextInt();
+ boolean keepRaw = inputScanner.nextBoolean();
+
+ for (int i = 0; i < loops; i++)
+ {
+ analyser.run(increments, keepRaw);
+ System.out.println("Saved");
+ }
+ System.out.println("Task completed");
+ continue;
+ } catch (Exception e)
+ {
+ System.out.println("Command failed");
+ }
+ continue;
+ }
+ if ((command.indexOf("runToEnd") > -1))
+ {
+ try
+ {
+
+ inputScanner.next();
+ int minCount = inputScanner.nextInt();
+ int maxCount = inputScanner.nextInt();
+ boolean keepRaw = inputScanner.nextBoolean();
+ boolean forClans = inputScanner.nextBoolean();
+ analyser.runToEnd(minCount, maxCount, keepRaw, forClans);
+ System.out.println("Task completed");
+ } catch (Exception e)
+ {
+ System.out.println("Command failed");
+ }
+ continue;
+ }
+ // terminates program. Syntax is terminate.
+ if (command.indexOf("terminate") > -1)
+ {
+ running = false;
+ continue;
+ }
+ // clears files in current directory (Only a specific set of files).
+ // Syntax is clear.
+ if (command.indexOf("clear") > -1)
+ {
+ analyser.clear();
+ continue;
+ }
+ // changes current directory. Syntax is cd <directory>
+ if (command.indexOf("cd") > -1)
+ {
+ try
+ {
+ inputScanner.next();
+ analyser.setFolder(inputScanner.next());
+ } catch (Exception e)
+ {
+ System.out.println("Command failed");
+
+ }
+ continue;
+ }
+
+ if (command.indexOf("getFamName") > -1)
+ {
+ try
+ {
+ inputScanner.next();
+ System.out.println(analyser.getFamilyName(inputScanner.nextInt()));
+
+ } catch (Exception e)
+ {
+ System.out.println("Command failed");
+ }
+ continue;
+ }
+ if (command.indexOf("sortIntoClans") > -1)
+ {
+ inputScanner.next();
+ analyser.sortIntoClans(inputScanner.next());
+ continue;
+
+ }
+ if (command.indexOf("setFamilies") > -1)
+ {
+ inputScanner.next();
+ analyser.setFamilies(inputScanner.next());
+ continue;
+
+ }
+
+ if (command.indexOf("setHMMs") > -1)
+ {
+ inputScanner.next();
+ analyser.setHmms(inputScanner.next());
+ continue;
+
+ }
+
+ if (command.indexOf("alignWithinClans") > -1)
+ {
+ inputScanner.next();
+ String export = inputScanner.next();
+ String clans = inputScanner.next();
+ analyser.alignWithinClan(export, clans);
+ continue;
+
+ }
+
+ System.out.println("Unrecognised command");
+ }
+
+
+
+
+ }
+
+}
*/
package jalview.util;
-import java.awt.event.MouseEvent;
-
public class ShortcutKeyMaskExWrapper
{
-
- private static final Float specversion;
-
- private static final float modern;
-
- public static final int SHIFT_DOWN_MASK;
-
- public static final int ALT_DOWN_MASK;
-
- private static final ShortcutKeyMaskExWrapperI wrapper;
-
- static
- {
- specversion = Platform.isJS() ? Float.valueOf(8)
- : Float.parseFloat(
- System.getProperty("java.specification.version"));
- modern = 11;
-
- if (specversion >= modern)
- {
- wrapper = new jalview.util.ShortcutKeyMaskExWrapper11();
- SHIFT_DOWN_MASK = jalview.util.ShortcutKeyMaskExWrapper11.SHIFT_DOWN_MASK;
- ALT_DOWN_MASK = jalview.util.ShortcutKeyMaskExWrapper11.ALT_DOWN_MASK;
- }
- else
- {
- wrapper = new jalview.util.ShortcutKeyMaskExWrapper8();
- SHIFT_DOWN_MASK = jalview.util.ShortcutKeyMaskExWrapper8.SHIFT_DOWN_MASK;
- ALT_DOWN_MASK = jalview.util.ShortcutKeyMaskExWrapper8.ALT_DOWN_MASK;
- }
- }
-
- public static int getMenuShortcutKeyMaskEx()
- {
- return wrapper.getMenuShortcutKeyMaskEx();
- }
-
- public static int getModifiersEx(MouseEvent e)
- {
- return wrapper.getModifiersEx(e);
- }
+//
+// public static int SHIFT_DOWN_MASK = KeyEvent.SHIFT_DOWN_MASK;
+//
+// public static int ALT_DOWN_MASK = KeyEvent.ALT_DOWN_MASK;
+//
+// public static int SHORTCUT_KEY_MASK = (Platform.isMac() ? KeyEvent.META_DOWN_MASK : KeyEvent.CTRL_DOWN_MASK);
+//
+// static
+// {
+// if (!GraphicsEnvironment.isHeadless())
+// {
+// try
+// {
+//
+// Class<? extends Toolkit> tk = Toolkit.getDefaultToolkit().getClass();
+// Method method = tk.getMethod("getMenuShortcutKeyMaskEx");
+// if (method == null)
+// method = tk.getMethod("getMenuShortcutKeyMask");
+// SHORTCUT_KEY_MASK = ((int) method.invoke(tk, new Object[0]));
+// if (SHORTCUT_KEY_MASK <= 0xF)
+// {
+// // shift this into the extended region (was Java 8)
+// SHORTCUT_KEY_MASK = SHORTCUT_KEY_MASK << 6;
+// }
+// } catch (Exception e)
+// {
+// }
+// }
+// }
+//
+// public static int getMenuShortcutKeyMaskEx()
+// {
+// return SHORTCUT_KEY_MASK;
+// }
}
public interface ShortcutKeyMaskExWrapperI
{
- public static int SHIFT_DOWN_MASK = 0;
-
- public static int ALT_DOWN_MASK = 0;
public int getMenuShortcutKeyMaskEx();
}
/**
- * Returns the last part of 'input' after the last occurrence of 'token'. For
- * example to extract only the filename from a full path or URL.
- *
- * @param input
- * @param token
- * a delimiter which must be in regular expression format
- * @return
- */
- public static String getLastToken(String input, String token)
- {
- if (input == null)
- {
- return null;
- }
- if (token == null)
- {
- return input;
- }
- String[] st = input.split(token);
- return st[st.length - 1];
- }
-
- /**
* Parses the input string into components separated by the delimiter. Unlike
* String.split(), this method will ignore occurrences of the delimiter which
* are nested within single quotes in name-value pair values, e.g. a='b,c'.
}
return enc;
}
+
+ /**
+ * Answers true if the string is not empty and consists only of digits, or
+ * characters 'a'-'f' or 'A'-'F', else false
+ *
+ * @param s
+ * @return
+ */
+ public static boolean isHexString(String s)
+ {
+ int j = s.length();
+ if (j == 0)
+ {
+ return false;
+ }
+ for (int i = 0; i < j; i++)
+ {
+ int c = s.charAt(i);
+ if (!(c >= '0' && c <= '9' || c >= 'a' && c <= 'f' || c >= 'A' && c <= 'F'))
+ {
+ return false;
+ }
+ }
+ return true;
+ }
}
*/
package jalview.util;
+import java.io.File;
import java.io.IOException;
import java.util.jar.JarInputStream;
* with it
*/
String getFilename();
+
+ /**
+ * @return jarFile name if from SwingJS
+ */
+ File getFile();
}
import jalview.analysis.Conservation;
import jalview.analysis.TreeModel;
import jalview.api.AlignCalcManagerI;
+import jalview.api.AlignCalcManagerI2;
+import jalview.api.AlignCalcWorkerI;
import jalview.api.AlignExportSettingsI;
import jalview.api.AlignViewportI;
import jalview.api.AlignmentViewPanel;
import jalview.util.MessageManager;
import jalview.viewmodel.styles.ViewStyle;
import jalview.workers.AlignCalcManager;
+import jalview.workers.AlignCalcManager2;
import jalview.workers.ComplementConsensusThread;
import jalview.workers.ConsensusThread;
+import jalview.workers.InformationThread;
import jalview.workers.StrucConsensusThread;
import java.awt.Color;
public abstract class AlignmentViewport
implements AlignViewportI, CommandListener, VamsasSource
{
+ public static final String PROPERTY_ALIGNMENT = "alignment";
+ public static final String PROPERTY_SEQUENCE = "sequence";
protected ViewportRanges ranges;
protected ViewStyleI viewStyle = new ViewStyle();
* alignment displayed in the viewport. Please use get/setter
*/
protected AlignmentI alignment;
+
+ /*
+ * probably unused indicator that view is of a dataset rather than an
+ * alignment
+ */
+
+ protected boolean ignoreBelowBackGroundFrequencyCalculation = false;
+
+ protected boolean infoLetterHeight = false;
+
+ protected AlignmentAnnotation occupancy;
+
+ /**
+ * results of alignment consensus analysis for visible portion of view
+ */
+ protected ProfilesI consensusProfiles;
+
+ /**
+ * HMM profile for the alignment
+ */
+ protected ProfilesI hmmProfiles;
public AlignmentViewport(AlignmentI al)
{
*/
protected boolean isDataset = false;
+
public void setDataset(boolean b)
{
isDataset = b;
protected ColumnSelection colSel = new ColumnSelection();
- public boolean autoCalculateConsensus = true;
+ protected boolean autoCalculateConsensusAndConservation = true;
+
+ public boolean getAutoCalculateConsensusAndConservation()
+ { // BH 2019.07.24
+ return autoCalculateConsensusAndConservation;
+ }
+
+ public void setAutoCalculateConsensusAndConservation(boolean b)
+ {
+ autoCalculateConsensusAndConservation = b;
+ }
protected boolean autoCalculateStrucConsensus = true;
+ public boolean getAutoCalculateStrucConsensus()
+ { // BH 2019.07.24
+ return autoCalculateStrucConsensus;
+ }
+
+ public void setAutoCalculateStrucConsensus(boolean b)
+ {
+ autoCalculateStrucConsensus = b;
+ }
protected boolean ignoreGapsInConsensusCalculation = false;
protected ResidueShaderI residueShading = new ResidueShader();
+
@Override
public void setGlobalColourScheme(ColourSchemeI cs)
{
return residueShading;
}
+
protected AlignmentAnnotation consensus;
protected AlignmentAnnotation complementConsensus;
protected Conservation hconservation = null;
+
@Override
public void setConservation(Conservation cons)
{
}
@Override
+ public void setHmmProfiles(ProfilesI info)
+ {
+ hmmProfiles = info;
+ }
+
+ @Override
+ public ProfilesI getHmmProfiles()
+ {
+ return hmmProfiles;
+ }
+
+ @Override
public Hashtable<String, Object>[] getComplementConsensusHash()
{
return hcomplementConsensus;
return strucConsensus;
}
- protected AlignCalcManagerI calculator = new AlignCalcManager();
+ protected AlignCalcManagerI2 calculator = new AlignCalcManager2();
/**
* trigger update of conservation annotation
// see note in mantis : issue number 8585
if (alignment.isNucleotide()
|| (conservation == null && quality == null)
- || !autoCalculateConsensus)
+ || !autoCalculateConsensusAndConservation)
{
return;
}
- if (calculator.getRegisteredWorkersOfClass(
- jalview.workers.ConservationThread.class) == null)
+ if (calculator.getWorkersOfClass(
+ jalview.workers.ConservationThread.class).isEmpty())
{
calculator.registerWorker(
new jalview.workers.ConservationThread(this, ap));
public void updateConsensus(final AlignmentViewPanel ap)
{
// see note in mantis : issue number 8585
- if (consensus == null || !autoCalculateConsensus)
+ if (consensus == null || !autoCalculateConsensusAndConservation)
{
return;
}
- if (calculator
- .getRegisteredWorkersOfClass(ConsensusThread.class) == null)
+ if (calculator.getWorkersOfClass(ConsensusThread.class).isEmpty())
{
calculator.registerWorker(new ConsensusThread(this, ap));
}
}
if (doConsensus)
{
- if (calculator.getRegisteredWorkersOfClass(
- ComplementConsensusThread.class) == null)
+ if (calculator.getWorkersOfClass(ComplementConsensusThread.class).isEmpty())
{
- calculator
- .registerWorker(new ComplementConsensusThread(this, ap));
+ calculator.registerWorker(new ComplementConsensusThread(this, ap));
}
}
}
}
+ @Override
+ public void initInformationWorker(final AlignmentViewPanel ap)
+ {
+ if (calculator.getWorkersOfClass(InformationThread.class).isEmpty())
+ {
+ calculator.registerWorker(new InformationThread(this, ap));
+ }
+ }
// --------START Structure Conservation
public void updateStrucConsensus(final AlignmentViewPanel ap)
{
{
return;
}
- if (calculator.getRegisteredWorkersOfClass(
- StrucConsensusThread.class) == null)
+ if (calculator.getWorkersOfClass(StrucConsensusThread.class).isEmpty())
{
calculator.registerWorker(new StrucConsensusThread(this, ap));
}
{
return false;
}
- if (calculator.workingInvolvedWith(alignmentAnnotation))
+ if (calculator.isWorkingWithAnnotation(alignmentAnnotation))
{
// System.err.println("grey out ("+alignmentAnnotation.label+")");
return true;
strucConsensus = null;
conservation = null;
quality = null;
+ consensusProfiles = null;
groupConsensus = null;
groupConservation = null;
hconsensus = null;
hconservation = null;
hcomplementConsensus = null;
gapcounts = null;
+ calculator.shutdown();
calculator = null;
residueShading = null; // may hold a reference to Consensus
changeSupport = null;
ranges = null;
currentTree = null;
selectionGroup = null;
- colSel = null;
setAlignment(null);
}
}
@Override
- public AlignCalcManagerI getCalcManager()
+ public AlignCalcManagerI2 getCalcManager()
{
return calculator;
}
protected boolean showConsensusHistogram = true;
/**
+ * should hmm profile be rendered by default
+ */
+ protected boolean hmmShowSequenceLogo = false;
+
+ /**
+ * should hmm profile be rendered normalised to row height
+ */
+ protected boolean hmmNormaliseSequenceLogo = false;
+
+ /**
+ * should information histograms be rendered by default
+ */
+ protected boolean hmmShowHistogram = true;
+
+ /**
* @return the showConsensusProfile
*/
@Override
}
/**
+ * @return the showInformationProfile
+ */
+ @Override
+ public boolean isShowHMMSequenceLogo()
+ {
+ return hmmShowSequenceLogo;
+ }
+
+ /**
* @param showSequenceLogo
* the new value
*/
// TODO: decouple settings setting from calculation when refactoring
// annotation update method from alignframe to viewport
this.showSequenceLogo = showSequenceLogo;
- calculator.updateAnnotationFor(ConsensusThread.class);
- calculator.updateAnnotationFor(ComplementConsensusThread.class);
- calculator.updateAnnotationFor(StrucConsensusThread.class);
+ for (AlignCalcWorkerI worker : calculator.getWorkers())
+ {
+ if (worker.getClass().equals(ConsensusThread.class) ||
+ worker.getClass().equals(ComplementConsensusThread.class) ||
+ worker.getClass().equals(StrucConsensusThread.class))
+ {
+ worker.updateAnnotation();
+ }
+ }
}
this.showSequenceLogo = showSequenceLogo;
}
+ public void setShowHMMSequenceLogo(boolean showHMMSequenceLogo)
+ {
+ if (showHMMSequenceLogo != this.hmmShowSequenceLogo)
+ {
+ this.hmmShowSequenceLogo = showHMMSequenceLogo;
+ // TODO: updateAnnotation if description (tooltip) will show
+ // profile in place of information content?
+ // calculator.updateAnnotationFor(InformationThread.class);
+ }
+ this.hmmShowSequenceLogo = showHMMSequenceLogo;
+ }
/**
* @param showConsensusHistogram
* the showConsensusHistogram to set
}
/**
+ * @param showInformationHistogram
+ */
+ public void setShowInformationHistogram(boolean showInformationHistogram)
+ {
+ this.hmmShowHistogram = showInformationHistogram;
+ }
+
+ /**
* @return the showGroupConservation
*/
public boolean isShowGroupConservation()
}
/**
+ *
+ * @return flag to indicate if the information content histogram should be
+ * rendered by default
+ */
+ @Override
+ public boolean isShowInformationHistogram()
+ {
+ return this.hmmShowHistogram;
+ }
+
+ /**
* when set, updateAlignment will always ensure sequences are of equal length
*/
private boolean padGaps = false;
ignoreGapsInConsensusCalculation);
}
}
+ }
+
+ public void setIgnoreBelowBackground(boolean b, AlignmentViewPanel ap)
+ {
+ ignoreBelowBackGroundFrequencyCalculation = b;
+ }
+ public void setInfoLetterHeight(boolean b, AlignmentViewPanel ap)
+ {
+ infoLetterHeight = b;
}
private long sgrouphash = -1, colselhash = -1;
* checks current colsel against record of last hash value, and optionally
* updates record.
*
- * @param b
+ * @param updateHash
* update the record of last hash value
* @return true if colsel changed since last call (when b is true)
*/
- public boolean isColSelChanged(boolean b)
+ public boolean isColSelChanged(boolean updateHash)
{
int hc = (colSel == null || colSel.isEmpty()) ? -1 : colSel.hashCode();
if (hc != -1 && hc != colselhash)
{
- if (b)
+ if (updateHash)
{
colselhash = hc;
}
return true;
}
+ notifySequence();
return false;
}
return ignoreGapsInConsensusCalculation;
}
+ @Override
+ public boolean isIgnoreBelowBackground()
+ {
+ return ignoreBelowBackGroundFrequencyCalculation;
+ }
+
+ @Override
+ public boolean isInfoLetterHeight()
+ {
+ return infoLetterHeight;
+ }
// property change stuff
// JBPNote Prolly only need this in the applet version.
private PropertyChangeSupport changeSupport = new PropertyChangeSupport(
}
}
- /**
- * Property change listener for changes in alignment
- *
- * @param prop
- * DOCUMENT ME!
- * @param oldvalue
- * DOCUMENT ME!
- * @param newvalue
- * DOCUMENT ME!
- */
- public void firePropertyChange(String prop, Object oldvalue,
- Object newvalue)
- {
- changeSupport.firePropertyChange(prop, oldvalue, newvalue);
- }
// common hide/show column stuff
ranges.setStartEndSeq(startSeq, endSeq + tmp.size());
- firePropertyChange("alignment", null, alignment.getSequences());
// used to set hasHiddenRows/hiddenRepSequences here, after the property
// changed event
+ notifySequence();
sendSelection();
}
}
ranges.setStartEndSeq(startSeq, endSeq + tmp.size());
- firePropertyChange("alignment", null, alignment.getSequences());
+ notifyAlignment();
sendSelection();
}
}
setSequenceAnnotationsVisible(seq[i], false);
}
ranges.setStartSeq(startSeq);
- firePropertyChange("alignment", null, alignment.getSequences());
+ notifyAlignment();
}
}
{
alignment.padGaps();
}
- if (autoCalculateConsensus)
+ if (autoCalculateConsensusAndConservation)
{
updateConsensus(ap);
}
- if (hconsensus != null && autoCalculateConsensus)
+ if (hconsensus != null && autoCalculateConsensusAndConservation)
{
updateConservation(ap);
}
updateAllColourSchemes();
calculator.restartWorkers();
- // alignment.adjustSequenceAnnotations();
}
/**
boolean showprf = isShowSequenceLogo();
boolean showConsHist = isShowConsensusHistogram();
boolean normLogo = isNormaliseSequenceLogo();
+ boolean showHMMPrf = isShowHMMSequenceLogo();
+ boolean showInfoHist = isShowInformationHistogram();
+ boolean normHMMLogo = isNormaliseHMMSequenceLogo();
/**
* TODO reorder the annotation rows according to group/sequence ordering on
sg.setshowSequenceLogo(showprf);
sg.setShowConsensusHistogram(showConsHist);
sg.setNormaliseSequenceLogo(normLogo);
+ sg.setShowHMMSequenceLogo(showHMMPrf);
+ sg.setShowInformationHistogram(showInfoHist);
+ sg.setNormaliseHMMSequenceLogo(normHMMLogo);
}
if (conv)
{
return sq;
}
+ public boolean hasReferenceAnnotation()
+ {
+ AlignmentAnnotation[] annots = this.alignment.getAlignmentAnnotation();
+ for (AlignmentAnnotation annot : annots)
+ {
+ if ("RF".equals(annot.label) || annot.label.contains("Reference"))
+ {
+ return true;
+ }
+ }
+ return false;
+ }
@Override
public void setCurrentTree(TreeModel tree)
{
return ed;
}
+ @Override
+ public boolean isNormaliseSequenceLogo()
+ {
+ return normaliseSequenceLogo;
+ }
+
+ public void setNormaliseSequenceLogo(boolean state)
+ {
+ normaliseSequenceLogo = state;
+ }
+
+ @Override
+ public boolean isNormaliseHMMSequenceLogo()
+ {
+ return hmmNormaliseSequenceLogo;
+ }
+
+ public void setNormaliseHMMSequenceLogo(boolean state)
+ {
+ hmmNormaliseSequenceLogo = state;
+ }
/**
* flag set to indicate if structure views might be out of sync with sequences
* in the alignment
return (alignment.getHiddenColumns().getVisContigsIterator(start, end,
false));
}
+ /**
+ * Filters out sequences with an eValue higher than the specified value. The
+ * filtered sequences are hidden or deleted. Sequences with no eValues are also
+ * filtered out.
+ *
+ * @param eValue
+ * @param delete
+ */
+ public void filterByEvalue(double eValue)
+ {
+ for (SequenceI seq : alignment.getSequencesArray())
+ {
+ if ((seq.getAnnotation("Search Scores") == null
+ || seq.getAnnotation("Search Scores")[0].getEValue() > eValue)
+ && seq.getHMM() == null)
+ {
+ hideSequence(new SequenceI[] { seq });
+ }
+ }
+ }
+
+ /**
+ * Filters out sequences with an score lower than the specified value. The
+ * filtered sequences are hidden or deleted.
+ *
+ * @param score
+ * @param delete
+ */
+ public void filterByScore(double score)
+ {
+ for (SequenceI seq : alignment.getSequencesArray())
+ {
+ if ((seq.getAnnotation("Search Scores") == null
+ || seq.getAnnotation("Search Scores")[0]
+ .getBitScore() < score)
+ && seq.getHMM() == null)
+ {
+ hideSequence(new SequenceI[] { seq });
+ }
+ }
+ }
+
+ /**
+ * Notify TreePanel and AlignmentPanel of some sort of alignment change.
+ */
+ public void notifyAlignment()
+ {
+ changeSupport.firePropertyChange(PROPERTY_ALIGNMENT, null, alignment.getSequences());
+ }
+
+ /**
+ * Notify AlignmentPanel of a sequence column selection or visibility changes.
+ */
+ public void notifySequence()
+ {
+ changeSupport.firePropertyChange(PROPERTY_SEQUENCE, null, null);
+ }
}
import jalview.datamodel.HiddenColumns;
import jalview.datamodel.HiddenSequences;
+import java.awt.Dimension;
import java.awt.Graphics;
public abstract class OverviewDimensions
* true if the annotation panel is to be shown, false otherwise
*/
public OverviewDimensions(ViewportRanges ranges,
- boolean showAnnotationPanel)
+ boolean showAnnotationPanel, Dimension dim)
{
+ if (!showAnnotationPanel)
+ {
+ graphHeight = 0;
+ }
+
// scale the initial size of overviewpanel to shape of alignment
float initialScale = (float) ranges.getAbsoluteAlignmentWidth()
/ (float) ranges.getAbsoluteAlignmentHeight();
- if (!showAnnotationPanel)
+ if (dim != null)
{
- graphHeight = 0;
+ width = dim.width;
+ sequencesHeight = dim.height;
+ return;
}
if (ranges.getAbsoluteAlignmentWidth() > ranges
*/
package jalview.viewmodel;
+import java.awt.Dimension;
+
import jalview.api.AlignmentColsCollectionI;
import jalview.api.AlignmentRowsCollectionI;
import jalview.datamodel.AlignmentI;
private int ydiff; // when dragging, difference in alignment units between
// start sequence and original mouse click position
+ /**
+ * for testng only
+ *
+ * @param vpranges
+ * @param showAnnotationPanel
+ */
+ @Deprecated
+ public OverviewDimensionsHideHidden(ViewportRanges vpranges, boolean showAnnotationPanel) {
+ this(vpranges, showAnnotationPanel, null);
+ }
+
public OverviewDimensionsHideHidden(ViewportRanges vpranges,
- boolean showAnnotationPanel)
+ boolean showAnnotationPanel, Dimension dim)
{
- super(vpranges, showAnnotationPanel);
+ super(vpranges, showAnnotationPanel, dim);
ranges = vpranges;
resetAlignmentDims();
}
*/
package jalview.viewmodel;
+import java.awt.Dimension;
+
import jalview.api.AlignmentColsCollectionI;
import jalview.api.AlignmentRowsCollectionI;
import jalview.datamodel.AlignmentI;
private int ydiff; // when dragging, difference in alignment units between
// start sequence and original mouse click position
+
+ /**
+ * for testng only
+ *
+ * @param vpranges
+ * @param showAnnotationPanel
+ */
+ @Deprecated
+ public OverviewDimensionsShowHidden(ViewportRanges vpranges, boolean showAnnotationPanel) {
+ this(vpranges, showAnnotationPanel, null);
+ }
+
/**
* Create an OverviewDimensions object
*
* true if the annotation panel is to be shown, false otherwise
*/
public OverviewDimensionsShowHidden(ViewportRanges vpranges,
- boolean showAnnotationPanel)
+ boolean showAnnotationPanel, Dimension dim)
{
- super(vpranges, showAnnotationPanel);
+ super(vpranges, showAnnotationPanel, dim);
ranges = vpranges;
resetAlignmentDims();
}
* Set first residue visible in the viewport, and retain the current width.
* Fires a property change event.
*
- * @param res
+ * @param res
* residue position
*/
public void setStartRes(int res)
int[] oldvalues = updateStartEndRes(start, end);
int oldstartres = oldvalues[0];
int oldendres = oldvalues[1];
+
+ if (oldstartres == startRes && oldendres == endRes)
+ {
+ return; // BH 2019.07.27 standard check for no changes
+ }
+ // "STARTRES" is a misnomer here -- really "STARTORENDRES"
+ // note that this could be "no change" if the range is just being expanded
changeSupport.firePropertyChange(STARTRES, oldstartres, startRes);
if (oldstartres == startRes)
{
+ // only caught in ViewportRangesTest
+ // No listener cares about this
+ // "ENDRES" is a misnomer here -- really "ENDONLYRES"
+ // BH 2019.07.27 adds end change check
+ // fire only if only the end is changed
// event won't be fired if start positions are same
// fire an event for the end positions in case they changed
- changeSupport.firePropertyChange(ENDRES, oldendres, endRes);
+ changeSupport.firePropertyChange(ENDRES, oldendres, endRes);
}
}
*/
public void setStartEndSeq(int start, int end)
{
- // System.out.println("ViewportRange setStartEndSeq " + start + " " + end);
int[] oldvalues = updateStartEndSeq(start, end);
int oldstartseq = oldvalues[0];
int oldendseq = oldvalues[1];
*/
private int[] updateStartEndSeq(int start, int end)
{
- int oldstartseq = this.startSeq;
- int visibleHeight = getVisibleAlignmentHeight();
- if (start > visibleHeight - 1)
- {
- startSeq = Math.max(visibleHeight - 1, 0);
- }
- else if (start < 0)
- {
- startSeq = 0;
- }
- else
- {
- startSeq = start;
- }
+// if (end == 3 && this.endSeq == 14 || end == 13 && this.endSeq == 3) {
+// new NullPointerException().printStackTrace(System.out);
+// System.out.println("ViewportRange updateStartEndSeq " + start + " " + end + " " + Thread.currentThread());
+// }
+ int oldstartseq = this.startSeq;
int oldendseq = this.endSeq;
- if (end >= visibleHeight)
- {
- endSeq = Math.max(visibleHeight - 1, 0);
- }
- else if (end < 0)
- {
- endSeq = 0;
- }
- else
- {
- endSeq = end;
- }
+ int max = getVisibleAlignmentHeight() - 1;
+ startSeq = Math.max(0, Math.min(start, max));
+ endSeq = Math.max(0, Math.min(end, max));
return new int[] { oldstartseq, oldendseq };
}
*/
public void setViewportStartAndWidth(int start, int w)
{
- int vpstart = start;
- if (vpstart < 0)
- {
- vpstart = 0;
- }
-
- /*
- * if not wrapped, don't leave white space at the right margin
- */
+ int vpstart = Math.max(0, start);
+
if (!wrappedMode)
{
- if ((w <= getVisibleAlignmentWidth())
- && (vpstart + w - 1 > getVisibleAlignmentWidth() - 1))
+ // if not wrapped, don't leave white space at the right margin
+ int maxStart = getVisibleAlignmentWidth() - w;
+ if (maxStart >= 0)
{
- vpstart = getVisibleAlignmentWidth() - w;
+ vpstart = Math.min(vpstart, maxStart);
}
}
*/
public void setViewportStartAndHeight(int start, int h)
{
- int vpstart = start;
-
- int visHeight = getVisibleAlignmentHeight();
- if (vpstart < 0)
- {
- vpstart = 0;
- }
- else if (h <= visHeight && vpstart + h > visHeight)
- // viewport height is less than the full alignment and we are running off
- // the bottom
+ int vpstart = Math.max(0, start);
+ int maxStart = getVisibleAlignmentHeight() - h;
+ if (maxStart > 0)
{
- vpstart = visHeight - h;
+ // can't start higher than vertical extent will allow
+ // (viewport height is less than the full alignment
+ // and we are running off the bottom)
+ vpstart = Math.min(vpstart, maxStart);
}
- // System.out.println("ViewportRanges setviewportStartAndHeight " + vpstart
- // + " " + start + " " + h + " " + getVisibleAlignmentHeight());
-
setStartEndSeq(vpstart, vpstart + h - 1);
}
return maxScroll;
}
+
+
+ @Override
+ public String toString() {
+ return "[ViewportRange " + startSeq + "-" + endSeq + ", "+ startRes + "-" + endRes + "]";
+ }
}
import jalview.api.AlignCalcManagerI;
import jalview.api.AlignCalcWorkerI;
+import jalview.bin.Cache;
import jalview.datamodel.AlignmentAnnotation;
import java.util.ArrayList;
import java.util.Collections;
+import java.util.HashMap;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.List;
/*
* list of registered workers
*/
- private volatile List<AlignCalcWorkerI> restartable;
+ private final List<AlignCalcWorkerI> restartable = Collections
+ .synchronizedList(new ArrayList<AlignCalcWorkerI>());
/*
* types of worker _not_ to run (for example, because they have
* previously thrown errors)
*/
- private volatile List<Class<? extends AlignCalcWorkerI>> blackList;
+ private final List<Class<? extends AlignCalcWorkerI>> blackList = Collections
+ .synchronizedList(new ArrayList<Class<? extends AlignCalcWorkerI>>());
/*
* global record of calculations in progress
*/
- private volatile List<AlignCalcWorkerI> inProgress;
+ private final List<AlignCalcWorkerI> inProgress = Collections
+ .synchronizedList(new ArrayList<AlignCalcWorkerI>());
/*
* record of calculations pending or in progress in the current context
*/
- private volatile Map<Class<? extends AlignCalcWorkerI>, List<AlignCalcWorkerI>> updating;
+ private final Map<Class<? extends AlignCalcWorkerI>, List<AlignCalcWorkerI>> updating =
+ new Hashtable<Class<? extends AlignCalcWorkerI>, List<AlignCalcWorkerI>>();
/*
* workers that have run to completion so are candidates for visual-only
* update of their results
*/
- private HashSet<AlignCalcWorkerI> canUpdate;
+ private HashSet<AlignCalcWorkerI> canUpdate = new HashSet<>();;
- /**
- * Constructor
- */
- public AlignCalcManager()
+ private static boolean listContains(List<AlignCalcWorkerI> upd,
+ AlignCalcWorkerI worker)
{
- 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>();
+ // avoid use of 'Contains' in case
+ for (AlignCalcWorkerI _otherworker : upd)
+ {
+ if (_otherworker == upd)
+ {
+ return true;
+ }
+ }
+ return false;
}
-
@Override
- public void notifyStart(AlignCalcWorkerI worker)
+ public void notifyStarted(AlignCalcWorkerI worker)
{
synchronized (updating)
{
}
synchronized (upd)
{
- upd.add(worker);
+ if (listContains(upd, worker))
+ {
+ Cache.log.debug(
+ "Ignoring second call to notifyStart for worker "
+ + worker);
+ }
+ else
+ {
+ upd.add(worker);
+ }
}
}
}
@Override
public boolean isPending(AlignCalcWorkerI workingClass)
{
- List<AlignCalcWorkerI> upd;
synchronized (updating)
{
- upd = updating.get(workingClass.getClass());
- if (upd == null)
- {
- return false;
- }
- synchronized (upd)
- {
- if (upd.size() > 1)
- {
- return true;
- }
- }
- return false;
+ List<AlignCalcWorkerI> upd = updating.get(workingClass.getClass());
+ return upd != null && upd.size() > 1;
}
}
{
synchronized (inProgress)
{
- if (inProgress.contains(worker))
+ if (listContains(inProgress, worker))
{
return false; // worker is already working, so ask caller to wait around
}
{
synchronized (inProgress)
{
- // System.err.println("Worker " + worker + " marked as complete.");
+ Cache.log.debug("Worker " + worker + " marked as complete.");
inProgress.remove(worker);
List<AlignCalcWorkerI> upd = updating.get(worker.getClass());
if (upd != null)
{
if (!isDisabled(worker))
{
- Thread tw = new Thread(worker);
+ Thread tw = new Thread(() -> {
+ try
+ {
+ worker.run();
+ } catch (Throwable e)
+ {
+ e.printStackTrace();
+ }
+ });
tw.setName(worker.getClass().toString());
tw.start();
}
}
}
+ public int getQueueLength() {
+ return inProgress.size();
+ }
+
@Override
public void registerWorker(AlignCalcWorkerI worker)
{
synchronized (restartable)
{
- if (!restartable.contains(worker))
+ if (!listContains(restartable, worker))
{
restartable.add(worker);
}
public List<AlignCalcWorkerI> getRegisteredWorkersOfClass(
Class<? extends AlignCalcWorkerI> workerClass)
{
- List<AlignCalcWorkerI> workingClass = new ArrayList<AlignCalcWorkerI>();
+ List<AlignCalcWorkerI> workingClass = new ArrayList<>();
synchronized (canUpdate)
{
for (AlignCalcWorkerI worker : canUpdate)
}
@Override
- public void removeRegisteredWorkersOfClass(
+ public void removeWorkersOfClass(
Class<? extends AlignCalcWorkerI> typeToRemove)
{
- List<AlignCalcWorkerI> removable = new ArrayList<AlignCalcWorkerI>();
- Set<AlignCalcWorkerI> toremovannot = new HashSet<AlignCalcWorkerI>();
+ List<AlignCalcWorkerI> removable = new ArrayList<>();
+ Set<AlignCalcWorkerI> toremovannot = new HashSet<>();
synchronized (restartable)
{
for (AlignCalcWorkerI worker : restartable)
* first just find those to remove (to avoid
* ConcurrentModificationException)
*/
- List<AlignCalcWorkerI> toRemove = new ArrayList<AlignCalcWorkerI>();
+ List<AlignCalcWorkerI> toRemove = new ArrayList<>();
for (AlignCalcWorkerI worker : restartable)
{
if (worker.involves(ann))
--- /dev/null
+package jalview.workers;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.NoSuchElementException;
+import java.util.Objects;
+import java.util.WeakHashMap;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+
+import static java.lang.String.format;
+import static java.util.Collections.synchronizedMap;
+import static java.util.Collections.unmodifiableList;
+
+import java.util.ArrayList;
+
+import jalview.api.AlignCalcListener;
+import jalview.api.AlignCalcManagerI2;
+import jalview.api.AlignCalcWorkerI;
+import jalview.api.PollableAlignCalcWorkerI;
+import jalview.bin.Cache;
+import jalview.datamodel.AlignmentAnnotation;
+
+public class AlignCalcManager2 implements AlignCalcManagerI2
+{
+ private abstract class WorkerManager
+ {
+ protected volatile boolean enabled = true;
+
+ protected AlignCalcWorkerI worker;
+
+ WorkerManager(AlignCalcWorkerI worker)
+ {
+ this.worker = worker;
+ }
+
+ protected AlignCalcWorkerI getWorker()
+ {
+ return worker;
+ }
+
+ boolean isEnabled()
+ {
+ return enabled;
+ }
+
+ void setEnabled(boolean enabled)
+ {
+ this.enabled = enabled;
+ }
+
+ synchronized void restart()
+ {
+ if (!isEnabled())
+ {
+ return;
+ }
+ if (!isRegistered())
+ {
+ setEnabled(false);
+ }
+ if (isWorking())
+ {
+ cancel();
+ }
+ submit();
+ }
+
+ protected boolean isRegistered()
+ {
+ return registered.containsKey(getWorker());
+ }
+
+ abstract boolean isWorking();
+
+ protected abstract void submit();
+
+ abstract void cancel();
+ }
+
+ private class SimpleWorkerManager extends WorkerManager
+ {
+ private Future<?> task = null;
+
+ SimpleWorkerManager(AlignCalcWorkerI worker)
+ {
+ super(worker);
+ }
+
+ @Override
+ boolean isWorking()
+ {
+ return task != null && !task.isDone();
+ }
+
+ @Override
+ protected void submit()
+ {
+ if (task != null && !(task.isDone() || task.isCancelled()))
+ {
+ throw new IllegalStateException(
+ "Cannot submit new task if the prevoius one is still running");
+ }
+ Cache.log.debug(
+ format("Worker %s queued", getWorker().getClass().getName()));
+ task = executor.submit(() -> {
+ try
+ {
+ Cache.log.debug(format("Worker %s started",
+ getWorker().getClass().getName()));
+ getWorker().run();
+ Cache.log.debug(format("Worker %s finished",
+ getWorker().getClass().getName()));
+ } catch (InterruptedException e)
+ {
+ Cache.log.debug(format("Worker %s interrupted",
+ getWorker().getClass().getName()));
+ } catch (Throwable th)
+ {
+ Cache.log.debug(format("Worker %s failed",
+ getWorker().getClass().getName()), th);
+ } finally
+ {
+ if (!isRegistered())
+ {
+ // delete worker reference so garbage collector can remove it
+ worker = null;
+ }
+ }
+ });
+ }
+
+ @Override
+ synchronized void cancel()
+ {
+ if (!isWorking())
+ {
+ return;
+ }
+ Cache.log.debug(format("Cancelling worker %s",
+ getWorker().getClass().getName()));
+ task.cancel(true);
+ }
+ }
+
+ private class PollableWorkerManager extends WorkerManager
+ {
+ private Future<?> task = null;
+
+ PollableWorkerManager(PollableAlignCalcWorkerI worker)
+ {
+ super(worker);
+ }
+
+ @Override
+ protected PollableAlignCalcWorkerI getWorker()
+ {
+ return (PollableAlignCalcWorkerI) super.getWorker();
+ }
+
+ @Override
+ boolean isWorking()
+ {
+ return task != null && !task.isDone();
+ }
+
+ protected void submit()
+ {
+ if (task != null && !(task.isDone() || task.isCancelled()))
+ {
+ throw new IllegalStateException(
+ "Cannot submit new task if the prevoius one is still running");
+ }
+ Cache.log.debug(
+ format("Worker %s queued", getWorker().getClass().getName()));
+ final var runnable = new Runnable()
+ {
+ private boolean started = false;
+
+ private boolean completed = false;
+
+ Future<?> future = null;
+
+ @Override
+ public void run()
+ {
+ try
+ {
+ if (!started)
+ {
+ Cache.log.debug(format("Worker %s started",
+ getWorker().getClass().getName()));
+ getWorker().startUp();
+ started = true;
+ }
+ else if (!completed)
+ {
+ Cache.log.debug(format("Polling worker %s",
+ getWorker().getClass().getName()));
+ if (getWorker().poll())
+ {
+ Cache.log.debug(format("Worker %s finished",
+ getWorker().getClass().getName()));
+ completed = true;
+ }
+ }
+ } catch (Throwable th)
+ {
+ Cache.log.debug(format("Worker %s failed",
+ getWorker().getClass().getName()), th);
+ completed = true;
+ }
+ if (completed)
+ {
+ final var worker = getWorker();
+ if (!isRegistered())
+ PollableWorkerManager.super.worker = null;
+ Cache.log.debug(format("Finalizing completed worker %s",
+ worker.getClass().getName()));
+ worker.done();
+ // almost impossible, but the future may be null at this point
+ // let it throw NPE to cancel forcefully
+ future.cancel(false);
+ }
+ }
+ };
+ runnable.future = task = executor.scheduleWithFixedDelay(runnable, 10,
+ 1000, TimeUnit.MILLISECONDS);
+ }
+
+ synchronized protected void cancel()
+ {
+ if (!isWorking())
+ {
+ return;
+ }
+ Cache.log.debug(format("Cancelling worker %s",
+ getWorker().getClass().getName()));
+ task.cancel(false);
+ executor.submit(() -> {
+ final var worker = getWorker();
+ if (!isRegistered())
+ PollableWorkerManager.super.worker = null;
+ if (worker != null)
+ {
+ worker.cancel();
+ Cache.log.debug(format("Finalizing cancelled worker %s",
+ worker.getClass().getName()));
+ worker.done();
+ }
+ });
+ }
+ }
+
+ private final ScheduledExecutorService executor = Executors
+ .newSingleThreadScheduledExecutor();
+
+ private final Map<AlignCalcWorkerI, WorkerManager> registered = synchronizedMap(
+ new HashMap<>());
+
+ private final Map<AlignCalcWorkerI, WorkerManager> oneshot = synchronizedMap(
+ new WeakHashMap<>());
+
+ private final List<AlignCalcListener> listeners = new CopyOnWriteArrayList<>();
+
+ private WorkerManager createManager(AlignCalcWorkerI worker)
+ {
+ if (worker instanceof PollableAlignCalcWorkerI)
+ {
+ return new PollableWorkerManager((PollableAlignCalcWorkerI) worker);
+ }
+ else
+ {
+ return new SimpleWorkerManager(worker);
+ }
+ }
+
+ @Override
+ public void registerWorker(AlignCalcWorkerI worker)
+ {
+ Objects.requireNonNull(worker);
+ WorkerManager manager = createManager(worker);
+ registered.putIfAbsent(worker, manager);
+ startWorker(worker);
+ }
+
+ @Override
+ public List<AlignCalcWorkerI> getWorkers()
+ {
+ List<AlignCalcWorkerI> result = new ArrayList<>(registered.size());
+ result.addAll(registered.keySet());
+ return result;
+ }
+
+ @Override
+ public List<AlignCalcWorkerI> getWorkersOfClass(
+ Class<? extends AlignCalcWorkerI> cls)
+ {
+ List<AlignCalcWorkerI> collected = new ArrayList<>();
+ for (var worker : getWorkers())
+ {
+ if (worker.getClass().equals(cls))
+ {
+ collected.add(worker);
+ }
+ }
+ return unmodifiableList(collected);
+ }
+
+ @Override
+ public void removeWorker(AlignCalcWorkerI worker)
+ {
+ if (worker.isDeletable())
+ {
+ registered.remove(worker);
+ }
+ }
+
+ @Override
+ public void removeWorkerForAnnotation(AlignmentAnnotation annot)
+ {
+ synchronized (registered)
+ {
+ for (var worker : getWorkers())
+ {
+ if (worker.involves(annot))
+ {
+ removeWorker(worker);
+ }
+ }
+ }
+ }
+
+ @Override
+ public void removeWorkersOfClass(Class<? extends AlignCalcWorkerI> cls)
+ {
+ synchronized (registered)
+ {
+ for (var worker : getWorkers())
+ {
+ if (worker.getClass().equals(cls))
+ {
+ removeWorker(worker);
+ }
+ }
+ }
+ }
+
+ @Override
+ public void disableWorker(AlignCalcWorkerI worker)
+ {
+ // Null pointer check might be needed
+ registered.get(worker).setEnabled(false);
+ }
+
+ @Override
+ public void enableWorker(AlignCalcWorkerI worker)
+ {
+ // Null pointer check might be needed
+ registered.get(worker).setEnabled(true);
+ }
+
+ @Override
+ public boolean isDisabled(AlignCalcWorkerI worker)
+ {
+ if (registered.containsKey(worker))
+ {
+ return !registered.get(worker).isEnabled();
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ @Override
+ public boolean isWorking(AlignCalcWorkerI worker)
+ {
+ var manager = registered.get(worker);
+ if (manager == null)
+ manager = oneshot.get(worker);
+ if (manager == null)
+ return false;
+ else
+ return manager.isWorking();
+ }
+
+ @Override
+ public boolean isWorkingWithAnnotation(AlignmentAnnotation annot)
+ {
+ synchronized (registered)
+ {
+ for (var entry : registered.entrySet())
+ if (entry.getKey().involves(annot) && entry.getValue().isWorking())
+ return true;
+ }
+ synchronized (oneshot)
+ {
+ for (var entry : registered.entrySet())
+ if (entry.getKey().involves(annot) && entry.getValue().isWorking())
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public boolean isWorking()
+ {
+ synchronized (registered)
+ {
+ for (var manager : registered.values())
+ if (manager.isWorking())
+ return true;
+ }
+ synchronized (oneshot)
+ {
+ for (var manager : oneshot.values())
+ if (manager.isWorking())
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public void startWorker(AlignCalcWorkerI worker)
+ {
+ Objects.requireNonNull(worker);
+ var manager = registered.get(worker);
+ if (manager == null)
+ {
+ Cache.log.warn("Starting unregistered worker " + worker);
+ manager = createManager(worker);
+ oneshot.put(worker, manager);
+ }
+ manager.restart();
+ }
+
+ @Override
+ public void restartWorkers()
+ {
+ synchronized (registered)
+ {
+ for (var manager : registered.values())
+ {
+ manager.restart();
+ }
+ }
+ }
+
+ @Override
+ public void cancelWorker(AlignCalcWorkerI worker)
+ {
+ Objects.requireNonNull(worker);
+ var manager = registered.get(worker);
+ if (manager == null)
+ manager = oneshot.get(worker);
+ if (manager == null)
+ {
+ throw new NoSuchElementException();
+ }
+ manager.cancel();
+ }
+
+ private void notifyQueued(AlignCalcWorkerI worker)
+ {
+ for (AlignCalcListener listener : listeners)
+ {
+ listener.workerQueued(worker);
+ }
+ }
+
+ private void notifyStarted(AlignCalcWorkerI worker)
+ {
+ for (AlignCalcListener listener : listeners)
+ {
+ listener.workerStarted(worker);
+ }
+ }
+
+ private void notifyCompleted(AlignCalcWorkerI worker)
+ {
+ for (AlignCalcListener listener : listeners)
+ {
+ try
+ {
+ listener.workerCompleted(worker);
+ } catch (RuntimeException e)
+ {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ private void notifyCancelled(AlignCalcWorkerI worker)
+ {
+ for (AlignCalcListener listener : listeners)
+ {
+ try
+ {
+ listener.workerCancelled(worker);
+ } catch (RuntimeException e)
+ {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ private void notifyExceptional(AlignCalcWorkerI worker,
+ Throwable throwable)
+ {
+ for (AlignCalcListener listener : listeners)
+ {
+ try
+ {
+ listener.workerExceptional(worker, throwable);
+ } catch (RuntimeException e)
+ {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ @Override
+ public void addAlignCalcListener(AlignCalcListener listener)
+ {
+ listeners.add(listener);
+ }
+
+ @Override
+ public void removeAlignCalcListener(AlignCalcListener listener)
+ {
+ listeners.remove(listener);
+ }
+
+ @Override
+ public void shutdown()
+ {
+ executor.shutdownNow();
+ listeners.clear();
+ registered.clear();
+ }
+
+}
package jalview.workers;
import jalview.api.AlignCalcManagerI;
+import jalview.api.AlignCalcManagerI2;
import jalview.api.AlignCalcWorkerI;
import jalview.api.AlignViewportI;
import jalview.api.AlignmentViewPanel;
*/
protected AlignViewportI alignViewport;
- protected AlignCalcManagerI calcMan;
+ protected AlignCalcManagerI2 calcMan;
protected AlignmentViewPanel ap;
{
if (calcMan != null)
{
- calcMan.workerComplete(this);
+ calcMan.cancelWorker(this);
+ calcMan.removeWorker(this);
}
alignViewport = null;
calcMan = null;
}
}
+ public AlignViewportI getAlignViewport()
+ {
+ return alignViewport;
+ }
}
@Override
public void run()
{
- try
+ if (alignViewport.isClosed())
{
- calcMan.notifyStart(this);
-
- while (!calcMan.notifyWorking(this))
- {
- try
- {
- Thread.sleep(200);
- } catch (InterruptedException ex)
- {
- ex.printStackTrace();
- }
- }
- if (alignViewport.isClosed())
- {
- abortAndDestroy();
- return;
- }
+ abortAndDestroy();
+ return;
+ }
- // removeAnnotation();
+ // removeAnnotation();
AlignmentI alignment = alignViewport.getAlignment();
- if (alignment != null)
+ if (alignment != null)
+ {
+ try
{
- try
+ List<AlignmentAnnotation> anns = counter.calculateAnnotation(
+ alignment, new FeatureRenderer(alignViewport));
+ for (AlignmentAnnotation ann : anns)
{
- List<AlignmentAnnotation> anns = counter.calculateAnnotation(
- alignment, new FeatureRenderer(alignViewport));
- for (AlignmentAnnotation ann : anns)
+ 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))
{
- 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);
+ ourAnnots.add(theAnn);
}
- } catch (IndexOutOfBoundsException x)
- {
- // probable race condition. just finish and return without any fuss.
- return;
+ // alignment.addAnnotation(ann);
}
+ } catch (IndexOutOfBoundsException x)
+ {
+ // probable race condition. just finish and return without any fuss.
+ return;
}
- } catch (OutOfMemoryError error)
- {
- ap.raiseOOMWarning("calculating annotations", error);
- calcMan.disableWorker(this);
- } finally
- {
- calcMan.workerComplete(this);
}
if (ap != null)
public void run()
{
boolean annotationAdded = false;
- try
+ if (alignViewport.isClosed())
{
- calcMan.notifyStart(this);
+ abortAndDestroy();
+ return;
+ }
- while (!calcMan.notifyWorking(this))
+ if (alignViewport.getAlignment() != null)
+ {
+ try
{
- try
- {
- Thread.sleep(200);
- } catch (InterruptedException ex)
- {
- ex.printStackTrace();
- }
- }
- if (alignViewport.isClosed())
+ annotationAdded = computeAnnotations();
+ } catch (IndexOutOfBoundsException x)
{
- abortAndDestroy();
+ // probable race condition. just finish and return without any fuss.
return;
}
-
- if (alignViewport.getAlignment() != null)
- {
- try
- {
- annotationAdded = computeAnnotations();
- } catch (IndexOutOfBoundsException x)
- {
- // probable race condition. just finish and return without any fuss.
- return;
- }
- }
- } catch (OutOfMemoryError error)
- {
- ap.raiseOOMWarning("calculating feature counts", error);
- calcMan.disableWorker(this);
- } finally
- {
- calcMan.workerComplete(this);
}
if (ap != null)
@Override
public void run()
{
- if (calcMan.isPending(this))
+ AlignmentAnnotation consensus = getConsensusAnnotation();
+ AlignmentAnnotation gap = getGapAnnotation();
+ if ((consensus == null && gap == null))
{
return;
}
- calcMan.notifyStart(this);
- // long started = System.currentTimeMillis();
- try
+ if (alignViewport.isClosed())
{
- AlignmentAnnotation consensus = getConsensusAnnotation();
- AlignmentAnnotation gap = getGapAnnotation();
- if ((consensus == null && gap == null) || calcMan.isPending(this))
- {
- calcMan.workerComplete(this);
- return;
- }
- while (!calcMan.notifyWorking(this))
- {
- // System.err.println("Thread
- // (Consensus"+Thread.currentThread().getName()+") Waiting around.");
- try
- {
- if (ap != null)
- {
- ap.paintAlignment(false, false);
- }
- Thread.sleep(200);
- } catch (Exception ex)
- {
- ex.printStackTrace();
- }
- }
- if (alignViewport.isClosed())
- {
- abortAndDestroy();
- return;
- }
- AlignmentI alignment = alignViewport.getAlignment();
+ abortAndDestroy();
+ return;
+ }
+ AlignmentI alignment = alignViewport.getAlignment();
- int aWidth = -1;
+ int aWidth = -1;
- if (alignment == null || (aWidth = alignment.getWidth()) < 0)
- {
- calcMan.workerComplete(this);
- return;
- }
+ if (alignment == null || (aWidth = alignment.getWidth()) < 0)
+ {
+ return;
+ }
- eraseConsensus(aWidth);
- computeConsensus(alignment);
- updateResultAnnotation(true);
+ eraseConsensus(aWidth);
+ computeConsensus(alignment);
+ updateResultAnnotation(true);
- if (ap != null)
- {
- ap.paintAlignment(true, true);
- }
- } catch (OutOfMemoryError error)
+ if (ap != null)
{
- calcMan.disableWorker(this);
- ap.raiseOOMWarning("calculating consensus", error);
- } finally
- {
- /*
- * e.g. ArrayIndexOutOfBoundsException can happen due to a race condition
- * - alignment was edited at same time as calculation was running
- */
- calcMan.workerComplete(this);
+ ap.paintAlignment(true, true);
}
}
protected void deriveConsensus(AlignmentAnnotation consensusAnnotation,
ProfilesI hconsensus)
{
-
long nseq = getSequences().length;
AAFrequency.completeConsensus(consensusAnnotation, hconsensus,
hconsensus.getStartColumn(), hconsensus.getEndColumn() + 1,
@Override
public void run()
{
- try
+ if ((alignViewport == null) || (calcMan == null)
+ || (alignViewport.isClosed()))
{
- calcMan.notifyStart(this); // updatingConservation = true;
-
- while ((calcMan != null) && (!calcMan.notifyWorking(this)))
- {
- try
- {
- if (ap != null)
- {
- // ap.paintAlignment(false);
- }
- Thread.sleep(200);
- } catch (Exception ex)
- {
- ex.printStackTrace();
- }
- }
- if ((alignViewport == null) || (calcMan == null)
- || (alignViewport.isClosed()))
- {
- abortAndDestroy();
- return;
- }
- List<AlignmentAnnotation> ourAnnot = new ArrayList<>();
- AlignmentI alignment = alignViewport.getAlignment();
- conservation = alignViewport.getAlignmentConservationAnnotation();
- quality = alignViewport.getAlignmentQualityAnnot();
- ourAnnot.add(conservation);
- ourAnnot.add(quality);
- ourAnnots = ourAnnot;
- ConsPercGaps = alignViewport.getConsPercGaps();
- // AlignViewport.UPDATING_CONSERVATION = true;
-
- if (alignment == null || (alWidth = alignment.getWidth()) < 0)
- {
- calcMan.workerComplete(this);
- // .updatingConservation = false;
- // AlignViewport.UPDATING_CONSERVATION = false;
+ abortAndDestroy();
+ return;
+ }
+ List<AlignmentAnnotation> ourAnnot = new ArrayList<>();
+ AlignmentI alignment = alignViewport.getAlignment();
+ conservation = alignViewport.getAlignmentConservationAnnotation();
+ quality = alignViewport.getAlignmentQualityAnnot();
+ ourAnnot.add(conservation);
+ ourAnnot.add(quality);
+ ourAnnots = ourAnnot;
+ ConsPercGaps = alignViewport.getConsPercGaps();
+ // AlignViewport.UPDATING_CONSERVATION = true;
- return;
- }
- try
- {
- cons = Conservation.calculateConservation("All",
- alignment.getSequences(), 0, alWidth - 1, false,
- ConsPercGaps, quality != null);
- } catch (IndexOutOfBoundsException x)
- {
- // probable race condition. just finish and return without any fuss.
- calcMan.workerComplete(this);
- return;
- }
- updateResultAnnotation(true);
- } catch (OutOfMemoryError error)
+ if (alignment == null || (alWidth = alignment.getWidth()) < 0)
{
- ap.raiseOOMWarning("calculating conservation", error);
- calcMan.disableWorker(this);
- // alignViewport.conservation = null;
- // this.alignViewport.quality = null;
-
+ // .updatingConservation = false;
+ // AlignViewport.UPDATING_CONSERVATION = false;
+ return;
+ }
+ try
+ {
+ cons = Conservation.calculateConservation("All",
+ alignment.getSequences(), 0, alWidth - 1, false,
+ ConsPercGaps, quality != null);
+ } catch (IndexOutOfBoundsException x)
+ {
+ // probable race condition. just finish and return without any fuss.
+ return;
}
- calcMan.workerComplete(this);
+ updateResultAnnotation(true);
if ((alignViewport == null) || (calcMan == null)
|| (alignViewport.isClosed()))
--- /dev/null
+package jalview.workers;
+
+import jalview.analysis.AAFrequency;
+import jalview.api.AlignViewportI;
+import jalview.api.AlignmentViewPanel;
+import jalview.datamodel.AlignmentAnnotation;
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.Annotation;
+import jalview.datamodel.HiddenMarkovModel;
+import jalview.datamodel.ProfilesI;
+import jalview.datamodel.SequenceGroup;
+import jalview.datamodel.SequenceI;
+import jalview.util.MessageManager;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * This class calculates HMM Information Content annotations, based on any HMM
+ * consensus sequences and their HMM models. HMM consensus sequences may be
+ * present for the whole alignment, or subgroups of it.
+ *
+ */
+public class InformationThread extends AlignCalcWorker
+{
+ public static final String HMM_CALC_ID = "HMM";
+
+ /**
+ * Constructor
+ *
+ * @param alignViewport
+ * @param alignPanel
+ */
+ public InformationThread(AlignViewportI alignViewport,
+ AlignmentViewPanel alignPanel)
+ {
+ super(alignViewport, alignPanel);
+ }
+
+ /**
+ * Recomputes Information annotations for any HMM consensus sequences (for
+ * alignment and/or groups)
+ */
+ @Override
+ public void run()
+ {
+ if (alignViewport.getAlignment().getHmmSequences().isEmpty())
+ {
+ return;
+ }
+ if (alignViewport.isClosed())
+ {
+ abortAndDestroy();
+ return;
+ }
+
+ AlignmentI alignment = alignViewport.getAlignment();
+ int aWidth = alignment == null ? -1 : alignment.getWidth();
+ if (aWidth < 0)
+ {
+ return;
+ }
+
+ /*
+ * compute information profiles for any HMM consensus sequences
+ * for the alignment or sub-groups
+ */
+ computeProfiles(alignment);
+
+ /*
+ * construct the corresponding annotations
+ */
+ updateAnnotation();
+
+ if (ap != null)
+ {
+ ap.adjustAnnotationHeight();
+ ap.paintAlignment(true, true);
+ }
+ }
+
+ /**
+ * Computes HMM profiles for any HMM consensus sequences (for alignment or
+ * subgroups). Any alignment profile computed is stored on the viewport, any
+ * group profile computed is stored on the respective sequence group.
+ *
+ * @param alignment
+ * @see AlignViewportI#setHmmProfiles(ProfilesI)
+ */
+ protected void computeProfiles(AlignmentI alignment)
+ {
+ int width = alignment.getWidth();
+
+ /*
+ * alignment HMM profile
+ */
+ List<SequenceI> seqs = alignment.getHmmSequences();
+ if (!seqs.isEmpty())
+ {
+ HiddenMarkovModel hmm = seqs.get(0).getHMM();
+ ProfilesI hmmProfiles = AAFrequency.calculateHMMProfiles(hmm, width,
+ 0, width, alignViewport.isIgnoreBelowBackground(),
+ alignViewport.isInfoLetterHeight());
+ alignViewport.setHmmProfiles(hmmProfiles);
+ }
+
+ /*
+ * group HMM profiles
+ */
+ List<SequenceGroup> groups = alignment.getGroups();
+ for (SequenceGroup group : groups)
+ {
+ seqs = group.getHmmSequences();
+ if (!seqs.isEmpty())
+ {
+ HiddenMarkovModel hmm = seqs.get(0).getHMM();
+ ProfilesI hmmProfiles = AAFrequency.calculateHMMProfiles(hmm, width,
+ 0, width, group.isIgnoreBelowBackground(),
+ group.isUseInfoLetterHeight());
+ group.setHmmProfiles(hmmProfiles);
+ }
+ }
+ }
+
+ /**
+ * gets the sequences on the alignment on the viewport.
+ *
+ * @return
+ */
+ protected SequenceI[] getSequences()
+ {
+ return alignViewport.getAlignment().getSequencesArray();
+ }
+
+ /**
+ * Get the Gap annotation for the alignment
+ *
+ * @return
+ */
+ protected AlignmentAnnotation getGapAnnotation()
+ {
+ return alignViewport.getAlignmentGapAnnotation();
+ }
+
+ /**
+ * Computes Information Content annotation for any HMM consensus sequences
+ * (for alignment or groups), and updates (or adds) the annotation to the
+ * sequence and the alignment
+ */
+ @Override
+ public void updateAnnotation()
+ {
+ AlignmentI alignment = alignViewport.getAlignment();
+
+ float maxInformation = 0f;
+ List<AlignmentAnnotation> infos = new ArrayList<>();
+
+ /*
+ * annotation for alignment HMM consensus if present
+ */
+ List<SequenceI> hmmSeqs = alignment.getHmmSequences();
+ if (!hmmSeqs.isEmpty())
+ {
+ ProfilesI profile = alignViewport.getHmmProfiles();
+ float m = updateInformationAnnotation(hmmSeqs.get(0), profile, null,
+ infos);
+ maxInformation = Math.max(maxInformation, m);
+ }
+
+ /*
+ * annotation for group HMM consensus if present
+ */
+ for (SequenceGroup group : alignment.getGroups())
+ {
+ hmmSeqs = group.getHmmSequences();
+ if (!hmmSeqs.isEmpty())
+ {
+ ProfilesI profiles = group.getHmmProfiles();
+ float m = updateInformationAnnotation(hmmSeqs.get(0), profiles,
+ group, infos);
+ maxInformation = Math.max(maxInformation, m);
+ }
+ }
+
+ /*
+ * maxInformation holds the maximum value of information score;
+ * set this as graphMax in all annotations to scale them all the same
+ */
+ for (AlignmentAnnotation ann : infos)
+ {
+ ann.graphMax = maxInformation;
+ }
+ }
+
+ /**
+ * Updates (and first constructs if necessary) an HMM Profile information
+ * content annotation for a sequence. The <code>group</code> argument is null
+ * for the whole alignment annotation, not null for a subgroup annotation. The
+ * updated annotation is added to the <code>infos</code> list. Answers the
+ * maximum information content value of any annotation (for use as a scaling
+ * factor for display).
+ *
+ * @param seq
+ * @param profile
+ * @param group
+ * @param infos
+ * @return
+ */
+ protected float updateInformationAnnotation(SequenceI seq,
+ ProfilesI profile, SequenceGroup group,
+ List<AlignmentAnnotation> infos)
+ {
+ if (seq == null || profile == null)
+ {
+ return 0f;
+ }
+
+ AlignmentAnnotation ann = findOrCreateAnnotation(seq, group);
+
+ seq.addAlignmentAnnotation(ann);
+ infos.add(ann);
+
+ float max = AAFrequency.completeInformation(ann, profile,
+ profile.getStartColumn(), profile.getEndColumn() + 1);
+
+ return max;
+ }
+
+ /**
+ * A helper method that first searches for the HMM annotation that matches the
+ * group reference (null for the whole alignment annotation). If found, its
+ * sequence reference is updated to the given sequence (the recomputed HMM
+ * consensus sequence). If not found, it is created. This supports both
+ * creating the annotation the first time hmmbuild is run, and updating it if
+ * hmmbuild is re-run.
+ *
+ * @param seq
+ * @param group
+ * @return
+ */
+ AlignmentAnnotation findOrCreateAnnotation(SequenceI seq,
+ SequenceGroup group)
+ {
+ /*
+ * can't use Alignment.findOrCreateAnnotation here because we
+ * want to update, rather than match on, the sequence ref
+ */
+ AlignmentAnnotation info = null;
+
+ AlignmentI alignment = alignViewport.getAlignment();
+ AlignmentAnnotation[] anns = alignment.getAlignmentAnnotation();
+ if (anns != null)
+ {
+ for (AlignmentAnnotation ann : anns)
+ {
+ if (HMM_CALC_ID.equals(ann.getCalcId()) && group == ann.groupRef)
+ {
+ info = ann;
+ info.setSequenceRef(seq);
+ info.label = seq.getName(); // in case group name changed!
+ break;
+ }
+ }
+ }
+
+ if (info == null)
+ {
+ int aWidth = alignment.getWidth();
+ String desc = MessageManager
+ .getString("label.information_description");
+ float graphMax = 6.52f; // todo where does this value derive from?
+ info = new AlignmentAnnotation(seq.getName(), desc,
+ new Annotation[aWidth], 0f, graphMax,
+ AlignmentAnnotation.BAR_GRAPH);
+ info.setCalcId(HMM_CALC_ID);
+ info.setSequenceRef(seq);
+ info.groupRef = group;
+ info.hasText = true;
+ alignment.addAnnotation(info);
+ }
+
+ return info;
+ }
+}
@Override
public void run()
{
- try
- {
- if (calcMan.isPending(this))
- {
- return;
- }
- calcMan.notifyStart(this);
- while (!calcMan.notifyWorking(this))
- {
- try
- {
- if (ap != null)
- {
- // ap.paintAlignment(false);
- }
-
- Thread.sleep(200);
- } catch (Exception ex)
- {
- ex.printStackTrace();
- }
- }
if (alignViewport.isClosed())
{
abortAndDestroy();
if (alignment == null || (aWidth = alignment.getWidth()) < 0)
{
- calcMan.workerComplete(this);
return;
}
strucConsensus = alignViewport.getAlignmentStrucConsensusAnnotation();
if (rnaStruc == null || !rnaStruc.isValidStruc())
{
- calcMan.workerComplete(this);
return;
}
alignment.getWidth(), hStrucConsensus, true, rnaStruc);
} catch (ArrayIndexOutOfBoundsException x)
{
- calcMan.workerComplete(this);
return;
}
alignViewport.setRnaStructureConsensusHash(hStrucConsensus);
// TODO AlignmentAnnotation rnaStruc!!!
updateResultAnnotation(true);
- } catch (OutOfMemoryError error)
- {
- calcMan.disableWorker(this);
-
- // consensus = null;
- // hconsensus = null;
- ap.raiseOOMWarning("calculating RNA structure consensus", error);
- } finally
- {
- calcMan.workerComplete(this);
- if (ap != null)
- {
- ap.paintAlignment(true, true);
- }
- }
}
import java.util.ArrayList;
import java.util.List;
-public abstract class AWSThread extends Thread
+import static java.lang.String.format;
+
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import javax.swing.Timer;
+
+public abstract class AWSThread
{
+
+ private javax.swing.Timer timer;
/**
* view that this job was associated with
/**
* are there jobs still running in this thread.
+ *
+ * fixme: initialize with an empty array?
*/
protected boolean jobComplete = false;
/**
* one or more jobs being managed by this thread.
*/
- protected AWsJob jobs[] = null;
+ protected AWsJob[] jobs = null;
/**
* full name of service
*/
private AlignFrame alignFrame;
- /**
- * generic web service job/subjob poll loop
- */
- @Override
- public void run()
+ public void start()
{
- JobStateSummary jstate = null;
if (jobs == null)
{
jobComplete = true;
+ Cache.log.debug(
+ "WebServiceJob poll loop finished with no jobs created.");
+ wsInfo.setStatus(WebserviceInfo.STATE_STOPPED_ERROR);
+ wsInfo.appendProgressText(
+ MessageManager.getString("info.no_jobs_ran"));
+ wsInfo.setFinishedNoResults();
+ return;
}
- while (!jobComplete)
+ timer = new Timer(5000, new ActionListener()
{
- jstate = new JobStateSummary();
- for (int j = 0; j < jobs.length; j++)
+
+ @Override
+ public void actionPerformed(ActionEvent e)
{
-
- if (!jobs[j].submitted && jobs[j].hasValidInput())
+ JobStateSummary jstate = new JobStateSummary();
+ for (final AWsJob job : jobs)
{
- StartJob(jobs[j]);
- }
-
- if (jobs[j].submitted && !jobs[j].subjobComplete)
- {
- try
+ if (!job.submitted && job.hasValidInput())
{
- pollJob(jobs[j]);
- if (!jobs[j].hasResponse())
- {
- throw (new Exception(
- "Timed out when communicating with server\nTry again later.\n"));
- }
- jalview.bin.Cache.log.debug("Job " + j + " Result state "
- + jobs[j].getState() + "(ServerError="
- + jobs[j].isServerError() + ")");
- } catch (Exception ex)
+ StartJob(job);
+ }
+ Cache.log.debug(format(
+ "Job %s is %ssubmitted", job, job.submitted ? "" : "not "));
+ if (job.submitted && !job.subjobComplete)
{
- // Deal with Transaction exceptions
- wsInfo.appendProgressText(jobs[j].jobnum, MessageManager
- .formatMessage("info.server_exception", new Object[]
- { WebServiceName, ex.getMessage() }));
- // always output the exception's stack trace to the log
- Cache.log.warn(WebServiceName + " job(" + jobs[j].jobnum
- + ") Server exception.");
- // todo: could limit trace to cause if this is a SOAPFaultException.
- ex.printStackTrace();
-
- if (jobs[j].allowedServerExceptions > 0)
+ Cache.log.debug(format(
+ "Polling Job %s Result state was:%s(ServerError=%b)",
+ job, job.getState(), job.isServerError()));
+ try
{
- jobs[j].allowedServerExceptions--;
- Cache.log.debug("Sleeping after a server exception.");
- try
+ pollJob(job);
+ if (!job.hasResponse())
+ throw new Exception("Timed out when communicating with server. Try again later.");
+ else
+ Cache.log.debug(format("Job %s Result state:%s(ServerError=%b)",
+ job, job.getState(), job.isServerError()));
+ } catch (Exception exc)
+ {
+ // Deal with Transaction exceptions
+ wsInfo.appendProgressText(job.jobnum, MessageManager
+ .formatMessage("info.server_exception", WebServiceName,
+ exc.getMessage()));
+ // always output the exception's stack trace to the log
+ Cache.log.warn(format("%s job(%s) Server exception.",
+ WebServiceName, job.jobnum));
+ exc.printStackTrace();
+
+ if (job.allowedServerExceptions > 0)
{
- Thread.sleep(5000);
- } catch (InterruptedException ex1)
+ job.allowedServerExceptions--;
+ }
+ else
{
+ Cache.log.warn(format("Dropping job %s %s", job, job.jobId));
+ job.subjobComplete = true;
+ wsInfo.setStatus(job.jobnum, WebserviceInfo.STATE_STOPPED_SERVERERROR);
}
- }
- else
+ } catch (OutOfMemoryError oomerror)
{
- Cache.log.warn("Dropping job " + j + " " + jobs[j].jobId);
- jobs[j].subjobComplete = true;
- wsInfo.setStatus(jobs[j].jobnum,
- WebserviceInfo.STATE_STOPPED_SERVERERROR);
+ jobComplete = true;
+ job.subjobComplete = true;
+ job.clearResponse();
+ wsInfo.setStatus(job.jobnum, WebserviceInfo.STATE_STOPPED_ERROR);
+ Cache.log.error(format("Out of memory when retrieving Job %s id:%s/%s",
+ job, WsUrl, job.jobId), oomerror);
+ new jalview.gui.OOMWarning("retrieving result for " + WebServiceName, oomerror);
+ System.gc();
}
- } catch (OutOfMemoryError er)
- {
- jobComplete = true;
- jobs[j].subjobComplete = true;
- jobs[j].clearResponse(); // may contain out of date result data
- wsInfo.setStatus(jobs[j].jobnum,
- WebserviceInfo.STATE_STOPPED_ERROR);
- Cache.log.error("Out of memory when retrieving Job " + j
- + " id:" + WsUrl + "/" + jobs[j].jobId, er);
- new jalview.gui.OOMWarning(
- "retrieving result for " + WebServiceName, er);
- System.gc();
}
+ jstate.updateJobPanelState(wsInfo, OutputHeader, job);
}
- jstate.updateJobPanelState(wsInfo, OutputHeader, jobs[j]);
- }
- // Decide on overall state based on collected jobs[] states
- updateGlobalStatus(jstate);
- if (!jobComplete)
- {
- try
- {
- Thread.sleep(5000);
- } catch (InterruptedException e)
+ // Decide on overall state based on collected jobs[] states
+ updateGlobalStatus(jstate);
+ if (jobComplete)
{
- Cache.log.debug("Interrupted sleep waiting for next job poll.",
- e);
+ timer.stop();
+ // jobs should never be null at this point
+ parseResult(); // tidy up and make results available to user
+
}
- // System.out.println("I'm alive "+alTitle);
}
- }
- if (jobComplete && jobs != null)
- {
- parseResult(); // tidy up and make results available to user
- }
- else
- {
- Cache.log.debug(
- "WebServiceJob poll loop finished with no jobs created.");
- wsInfo.setStatus(WebserviceInfo.STATE_STOPPED_ERROR);
- wsInfo.appendProgressText(
- MessageManager.getString("info.no_jobs_ran"));
- wsInfo.setFinishedNoResults();
- }
+ });
+ timer.setInitialDelay(0);
+ timer.start();
}
protected void updateGlobalStatus(JobStateSummary jstate)
}
}
}
-
- public AWSThread()
- {
- super();
- }
-
- public AWSThread(Runnable target)
- {
- super(target);
- }
-
- public AWSThread(String name)
- {
- super(name);
- }
-
- public AWSThread(ThreadGroup group, Runnable target)
- {
- super(group, target);
- }
-
- public AWSThread(ThreadGroup group, String name)
- {
- super(group, name);
- }
-
- public AWSThread(Runnable target, String name)
- {
- super(target, name);
- }
-
- public AWSThread(ThreadGroup group, Runnable target, String name)
+
+ public void interrupt()
{
- super(group, target, name);
+ timer.stop();
}
/**
}
}
- public AWSThread(ThreadGroup group, Runnable target, String name,
- long stackSize)
- {
- super(group, target, name, stackSize);
- }
-
/**
*
* @return gap character to use for any alignment generation
*
* @param alignFrame
* reference for copying mappings across
- * @param wsInfo
+ * @param wsinfo
* gui attachment point
* @param input
* input data for the calculation
.getCodonFrames();
if (cf != null)
{
- codonframe = new ArrayList<AlignedCodonFrame>();
+ codonframe = new ArrayList<>();
codonframe.addAll(cf);
}
}
*/
package jalview.ws;
+import jalview.ws.params.ArgumentI;
+import jalview.ws.params.WsParamSetI;
+
+import java.util.Hashtable;
+import java.util.List;
+import java.util.Map;
+
/**
* Generic properties for an individual job within a Web Service Client thread.
* Derived from jalview web services version 1 statuses, and revised for Jws2.
*/
protected boolean subjobComplete = false;
+ protected WsParamSetI preset = null;
+
+ protected List<ArgumentI> arguments = null;
+
+ protected Hashtable<String, Map> SeqNames = new Hashtable();
+
public AWsJob()
{
}
String state = "";
return state;
}
+
+ public void setPreset(WsParamSetI jobpreset)
+ {
+ preset = jobpreset;
+ }
+
+ public void setArguments(List<ArgumentI> paramset)
+ {
+ arguments = paramset;
+
+ }
+
+ public boolean isPresetJob()
+ {
+ return preset!=null && arguments==null;
+ }
+
+ public List<ArgumentI> getArguments()
+ {
+ return arguments;
+ }
+
+ public WsParamSetI getPreset()
+ {
+ return preset;
+ }
+
+ long nextChunk = 0;
+
+ /**
+ * update the record of the last position in the log file read for this job
+ *
+ * @param nextChunk
+ */
+ public void setnextChunk(long nextChunk)
+ {
+ this.nextChunk = nextChunk;
+ }
+
+ public long getNextChunk()
+ {
+ return nextChunk;
+ }
}
* bookkeeper class for the WebServiceInfo GUI, maintaining records of web
* service jobs handled by the window and reflecting any status updates.
*
+ * TODO: separate from the GUI cleanly since it also holds logic for
+ * interpreting failure states
+ *
* @author JimP
*
*/
*/
package jalview.ws;
+import jalview.bin.ApplicationSingletonProvider;
+import jalview.bin.ApplicationSingletonProvider.ApplicationSingletonI;
import jalview.ext.ensembl.EnsemblGene;
import jalview.ws.dbsources.EmblCdsSource;
import jalview.ws.dbsources.EmblSource;
* This implements the run-time discovery of sequence database clients.
*
*/
-public class SequenceFetcher extends ASequenceFetcher
+public class SequenceFetcher extends ASequenceFetcher implements ApplicationSingletonI
{
+ /*
+ * set a mock fetcher here for testing only - reset to null afterwards
+ */
+ private static SequenceFetcher mockFetcher;
+
+ /**
+ * 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 setMockFetcher(SequenceFetcher sf)
+ {
+ mockFetcher = sf;
+ }
+
+ /**
+ * Returns a new SequenceFetcher singleton, or a mock object if one has been
+ * set.
+ *
+ * @return
+ */
+ public static SequenceFetcher getInstance()
+ {
+ return mockFetcher != null ? mockFetcher
+ : (SequenceFetcher) ApplicationSingletonProvider
+ .getInstance(SequenceFetcher.class);
+ }
+
/**
* Thread safe construction of database proxies TODO: extend to a configurable
* database plugin mechanism where classes are instantiated by reflection and
+++ /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;
- }
-}
--- /dev/null
+package jalview.ws;
+
+import java.util.Collection;
+import java.util.EventListener;
+
+import jalview.ws.api.ServiceWithParameters;
+
+@FunctionalInterface
+public interface ServiceChangeListener extends EventListener
+{
+ public void servicesChanged(WSDiscovererI discoverer,
+ Collection<? extends ServiceWithParameters> services);
+}
*/
package jalview.ws;
+import jalview.bin.Cache;
+import jalview.gui.AlignFrame;
+import jalview.gui.Desktop;
import jalview.gui.WebserviceInfo;
+import jalview.gui.WsJobParameters;
+import jalview.util.MessageManager;
+import jalview.ws.api.ServiceWithParameters;
+import jalview.ws.api.UIinfo;
+import jalview.ws.params.ArgumentI;
+import jalview.ws.params.ParamDatastoreI;
+import jalview.ws.params.WsParamSetI;
+
+import java.util.List;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.CompletionStage;
public abstract class WSClient // implements WSMenuEntryProviderI
{
protected WebserviceInfo wsInfo;
/**
+ * the root object for the service client
+ */
+ protected UIinfo serviceHandle;
+
+ /**
* total number of jobs managed by this web service client instance.
*/
int jobsRunning = 0;
* mappings between abstract interface names and menu entries
*/
protected java.util.Hashtable ServiceActions;
+
+ /**
+ * alignFrame associated with this client
+ */
+ protected AlignFrame alignFrame;
{
ServiceActions = new java.util.Hashtable();
ServiceActions.put("MsaWS", "Multiple Sequence Alignment");
ServiceActions.put("SecStrPred", "Secondary Structure Prediction");
};
+ /**
+ * The preset for the job executed by this client (may be null)
+ */
+ protected WsParamSetI preset;
+
+ /**
+ * The parameters for the job executed by this client (may be null)
+ */
+ protected List<ArgumentI> paramset;
+
public WSClient()
{
}
+
+ /**
+ * base constructor for a web service with parameters. Extending classes
+ * should implement this constructor with additional logic to verify that
+ * preset and arguments are compatible with the service being configured.
+ *
+ * @param _alignFrame
+ * @param preset
+ * @param arguments
+ */
+ public WSClient(AlignFrame _alignFrame, WsParamSetI preset,
+ List<ArgumentI> arguments)
+ {
+ alignFrame = _alignFrame;
+ this.preset = preset;
+ this.paramset = arguments;
+ }
+
+ protected WebserviceInfo setWebService(UIinfo serv, boolean b)
+ {
+ WebServiceName = serv.getName();
+ WebServiceJobTitle = serv.getActionText();
+ WsURL = serv.getHostURL();
+ if (!b)
+ {
+ return new WebserviceInfo(WebServiceJobTitle,
+ WebServiceJobTitle + " using service hosted at "
+ + WsURL + "\n"
+ + (serv.getDescription() != null
+ ? serv.getDescription()
+ : ""),
+ false);
+ }
+ return null;
+ }
+
+ /**
+ * called to open a parameter editing dialog for parameterised services
+ *
+ * @param sh
+ * @param editParams
+ * @return
+ */
+ protected CompletionStage<Boolean> processParams(ServiceWithParameters sh,
+ boolean editParams)
+ {
+ return processParams(sh, editParams, false);
+ }
+
+ protected CompletionStage<Boolean> processParams(ServiceWithParameters sh,
+ boolean editParams, boolean adjustingExisting)
+ {
+
+ if (editParams)
+ {
+ // always do this
+ sh.initParamStore(Desktop.getUserParameterStore());
+
+ WsJobParameters jobParams = (preset == null && paramset != null
+ && paramset.size() > 0)
+ ? new WsJobParameters((ParamDatastoreI) null, sh,
+ (WsParamSetI) null, paramset)
+ : new WsJobParameters((ParamDatastoreI) null, sh,
+ preset, (List<ArgumentI>) null);
+ if (adjustingExisting)
+ {
+ jobParams.setName(MessageManager
+ .getString("label.adjusting_parameters_for_calculation"));
+ }
+ var stage = jobParams.showRunDialog();
+ return stage.thenApply((startJob) -> {
+ if (startJob)
+ {
+ WsParamSetI prset = jobParams.getPreset();
+ if (prset == null)
+ {
+ paramset = jobParams.isServiceDefaults() ? null
+ : jobParams.getJobParams();
+ this.preset = null;
+ }
+ else
+ {
+ this.preset = prset; // ((JabaPreset) prset).p;
+ paramset = null; // no user supplied parameters.
+ }
+ }
+ return startJob;
+ });
+
+ }
+ return CompletableFuture.completedFuture(true);
+ }
+
}
--- /dev/null
+package jalview.ws;
+
+import jalview.ws.api.ServiceWithParameters;
+
+import java.net.URL;
+import java.util.List;
+import java.util.concurrent.CompletableFuture;
+
+public interface WSDiscovererI
+{
+ public static final int STATUS_OK = 1;
+ public static final int STATUS_NO_SERVICES = 0;
+ public static final int STATUS_INVALID = -1;
+ public static final int STATUS_UNKNOWN = -2;
+
+ public void setServiceUrls(List<String> wsUrls);
+
+ public List<String> getServiceUrls();
+
+ public List<ServiceWithParameters> getServices();
+
+ public boolean testServiceUrl(URL url);
+
+ public int getServerStatusFor(String url);
+
+ public void addServiceChangeListener(ServiceChangeListener listener);
+
+ public void removeServiceChangeListener(ServiceChangeListener listener);
+
+ public CompletableFuture<WSDiscovererI> startDiscoverer();
+
+ public String getErrorMessages();
+
+ public boolean hasServices();
+
+ public boolean isRunning();
+}
--- /dev/null
+package jalview.ws.api;
+
+import jalview.ws.gui.WsJob;
+
+public interface CancellableI
+{
+ public boolean cancel(WsJob job);
+}
--- /dev/null
+package jalview.ws.api;
+
+import jalview.math.MatrixI;
+import jalview.ws.params.InvalidArgumentException;
+
+import java.io.IOError;
+import java.rmi.ServerError;
+
+public interface DistanceMatrixResultI
+{
+
+ public MatrixI getDistanceMatrixFor(JobId jobId)
+ throws InvalidArgumentException, ServerError, IOError;
+
+
+}
\ No newline at end of file
--- /dev/null
+package jalview.ws.api;
+
+public interface JalviewServiceEndpointProviderI
+{
+
+ /**
+ *
+ * @return endpoint instance implementing one or more jalview.ws.api
+ * interfaces
+ */
+ Object getEndpoint();
+
+}
--- /dev/null
+package jalview.ws.api;
+
+import jalview.gui.WebserviceInfo;
+import jalview.ws.gui.WsJob;
+
+public interface JalviewWebServiceI
+{
+
+ void updateStatus(WsJob job);
+
+ /**
+ * Retrieve any additional log information for the job and update WsJob's
+ * progress. Results won't be retrieved until progress updates have finished.
+ *
+ * @param job
+ * @return true if Job's stdout/progress panel was added to
+ * @throws Exception
+ */
+ boolean updateJobProgress(WsJob job) throws Exception;
+
+ boolean handleSubmitError(Throwable _lex, WsJob j, WebserviceInfo wsInfo)
+ throws Exception, Error;
+
+ boolean handleCollectionException(Exception e, WsJob msjob,
+ WebserviceInfo wsInfo);
+
+}
--- /dev/null
+package jalview.ws.api;
+
+import java.util.Date;
+
+public class JobId
+{
+ // TODO: JobId could include sequenceI anonymisation stuff
+ // TODO: getProgress() -> input stream to log file for job.
+ private String serviceType;
+
+ private String serviceImpl;
+
+ private String jobId;
+ // TODO: java2script instant
+ private String creationTime=null;
+
+ public JobId(String serviceType, String serviceImpl, String id)
+ {
+ this.serviceType = serviceType;
+ this.serviceImpl = serviceImpl;
+ jobId = id;
+ /*
+ * @j2sIgnore
+ */
+ {
+// creationTime = Date.from(Instant.now()).toString();
+ }
+ if (creationTime==null)
+ {
+ creationTime = new Date().toString(); // j2s only
+ }
+ }
+
+ @Override
+ public String toString()
+ {
+ return "" + serviceType + ":" + serviceImpl + ":" + jobId + "\nCreated "
+ + creationTime;
+ }
+ /**
+ * a stringified version of the Job Id that can be saved in project.
+ */
+ public String getURI()
+ {
+ return jobId;
+ }
+
+ public String getServiceType()
+ {
+ return serviceType;
+ }
+
+ public String getServiceImpl()
+ {
+ return serviceImpl;
+ }
+
+ public String getJobId()
+ {
+ return jobId;
+ }
+
+ public String getCreationTime()
+ {
+ return creationTime;
+ }
+}
--- /dev/null
+package jalview.ws.api;
+
+import jalview.datamodel.SequenceI;
+import jalview.ws.params.ArgumentI;
+import jalview.ws.params.WsParamSetI;
+
+import java.util.List;
+
+/**
+ * MSA analysis interface
+ *
+ * @author jprocter
+ *
+ * Generic job submission/management model: - A service instance
+ * implements one or more analysis interfaces, a status interface, a
+ * progress interface, and one or more results interface, plus any
+ * informational/descriptional interfaces - analysis interfaces return
+ * JobId or throw exceptions/errors.
+ *
+ *
+ */
+public interface MsaI
+{
+ /**
+ * Given a set of sequences
+ *
+ * @param toalign
+ * @param parameters
+ * @param list
+ * @return JobId or exceptions are thrown.
+ * @throws Throwable
+ */
+ public JobId align(List<SequenceI> toalign, WsParamSetI parameters,
+ List<ArgumentI> list)
+ throws Throwable;
+}
--- /dev/null
+package jalview.ws.api;
+
+import jalview.datamodel.AlignmentI;
+import jalview.ws.params.InvalidArgumentException;
+
+import java.io.IOError;
+import java.rmi.ServerError;
+
+public interface MsaResultI
+{
+ public AlignmentI getAlignmentFor(JobId jobId)
+ throws InvalidArgumentException, ServerError, IOError;
+}
\ No newline at end of file
--- /dev/null
+package jalview.ws.api;
+
+import jalview.analysis.NJTree;
+import jalview.datamodel.SequenceI;
+import jalview.ws.params.InvalidArgumentException;
+import jalview.ws.params.WsParamSetI;
+
+import java.io.IOError;
+import java.rmi.ServerError;
+import java.util.List;
+
+public interface MsaWithGuideTreeI
+{
+ /**
+ * Given a set of sequences
+ *
+ * @param toalign
+ * @param parameters
+ * @return JobId or exceptions are thrown.
+ */
+ public JobId align(List<SequenceI> toalign, NJTree guideTree,
+ WsParamSetI parameters)
+ throws InvalidArgumentException, ServerError, IOError;
+}
\ No newline at end of file
--- /dev/null
+package jalview.ws.api;
+
+/**
+ * A simple parameterisable multiple sequence alignment service
+ *
+ * @author jprocter
+ *
+ */
+public interface MultipleSequenceAlignmentI
+ extends JalviewWebServiceI, MsaI, MsaResultI
+{
+
+}
--- /dev/null
+package jalview.ws.api;
+
+import jalview.api.FeatureColourI;
+import jalview.datamodel.AlignmentAnnotation;
+import jalview.datamodel.SequenceI;
+import jalview.datamodel.features.FeatureMatcherSetI;
+import jalview.ws.params.ArgumentI;
+import jalview.ws.params.WsParamSetI;
+
+import java.util.List;
+import java.util.Map;
+
+public interface SequenceAnnotationServiceI extends JalviewWebServiceI
+{
+
+
+ /**
+ * submit sequences to service with no parameters, or preset or parameter set.
+ * Nb- almost the same as the 'align' method in the Msa service :)
+ *
+ * @param seqs
+ * @param preset
+ * @param paramset
+ * @return
+ * @throws Throwable
+ */
+ JobId submitToService(List<SequenceI> seqs, WsParamSetI preset,
+ List<ArgumentI> paramset) throws Throwable;
+
+ /**
+ * materialise annotation and features for sequences input to the service
+ *
+ * @param job
+ * @param seqs
+ * - features and alignment annotation added to these will be
+ * imported to the dataset for the alignment
+ * @param featureColours
+ * - container for feature colours - any defined will be merged with
+ * viewport
+ * @param featureFilters
+ * - container for filters - any defined will be merged with viewport
+ * @return sequence and alignment annotation rows that should be made
+ * visible/updated on alignment
+ * @throws Throwable
+ */
+ List<AlignmentAnnotation> getAnnotationResult(JobId job,
+ List<SequenceI> seqs, Map<String, FeatureColourI> featureColours,
+ Map<String, FeatureMatcherSetI> featureFilters) throws Throwable;
+
+
+}
--- /dev/null
+package jalview.ws.api;
+
+import jalview.bin.Cache;
+import jalview.gui.AlignFrame;
+import jalview.ws.jws2.MsaWSClient;
+import jalview.ws.jws2.SequenceAnnotationWSClient;
+import jalview.ws.params.ParamManager;
+
+import javax.swing.JMenu;
+
+public abstract class ServiceWithParameters extends UIinfo
+{
+
+ protected jalview.ws.uimodel.AlignAnalysisUIText aaui;
+
+ public ServiceWithParameters(String serviceType, String action,
+ String name, String description, String hosturl)
+ {
+ super(serviceType, action, name, description, hosturl);
+ }
+
+ public abstract void initParamStore(ParamManager userParameterStore);
+
+ public jalview.ws.uimodel.AlignAnalysisUIText getAlignAnalysisUI()
+ {
+ return aaui;
+ }
+
+ public void setAlignAnalysisUI(
+ jalview.ws.uimodel.AlignAnalysisUIText aaui)
+ {
+ this.aaui = aaui;
+ }
+
+ public boolean isInteractiveUpdate()
+ {
+ return aaui != null && aaui.isAA();
+ }
+ // config flags for SeqAnnotationServiceCalcWorker
+
+ public boolean isProteinService()
+ {
+ return aaui == null ? true : aaui.isPr();
+ }
+
+ public boolean isNucleotideService()
+ {
+ return aaui == null ? false : aaui.isNa();
+ }
+
+ public boolean isNeedsAlignedSequences()
+ {
+ return aaui == null ? false : aaui.isNeedsAlignedSeqs();
+ }
+
+ public boolean isAlignmentAnalysis()
+ {
+ return aaui == null ? false : aaui.isAA();
+ }
+
+ public boolean isFilterSymbols()
+ {
+ return aaui != null ? aaui.isFilterSymbols() : true;
+ }
+
+ public int getMinimumInputSequences()
+ {
+ return aaui != null ? aaui.getMinimumSequences() : 1;
+ }
+
+ public String getNameURI()
+ {
+ return "java:" + getName();
+ }
+
+ public String getUri()
+ {
+ // TODO verify that service parameter sets in projects are consistent with
+ // Jalview 2.10.4
+ // this is only valid for Jaba 1.0 - this formula might have to change!
+ return getHostURL()
+ + (getHostURL().lastIndexOf("/") == (getHostURL().length() - 1)
+ ? ""
+ : "/")
+ + getName();
+ }
+
+ protected enum ServiceClient
+ {
+ MSAWSCLIENT, SEQUENCEANNOTATIONWSCLIENT;
+ };
+
+ protected ServiceClient style = null;
+
+ public void attachWSMenuEntry(JMenu atpoint, AlignFrame alignFrame)
+ {
+ switch (style)
+ {
+ case MSAWSCLIENT:
+ new MsaWSClient().attachWSMenuEntry(atpoint, this, alignFrame);
+ break;
+ case SEQUENCEANNOTATIONWSCLIENT:
+ new SequenceAnnotationWSClient().attachWSMenuEntry(atpoint, this,
+ alignFrame);
+ break;
+ default:
+ Cache.log.warn("Implementation error ? Service " + getName()
+ + " has Unknown service style " + style);
+ }
+ }
+}
--- /dev/null
+package jalview.ws.api;
+
+import jalview.analysis.NJTree;
+import jalview.ws.params.InvalidArgumentException;
+
+import java.io.IOError;
+import java.rmi.ServerError;
+
+public interface TreeResultI
+{
+
+ public NJTree getTreeFor(JobId jobId)
+ throws InvalidArgumentException, ServerError, IOError;
+}
\ No newline at end of file
--- /dev/null
+package jalview.ws.api;
+
+import jalview.ws.params.ParamDatastoreI;
+
+/**
+ * Service UI Info { Action, Specific Name of Service, Brief Description }
+ */
+
+public class UIinfo
+{
+ private String ServiceType;
+
+ public UIinfo(String serviceType, String action, String name,
+ String description, String hosturl)
+ {
+ this.setServiceType(serviceType == null ? "" : serviceType);
+ this.Action = action == null ? "" : action;
+ this.description = description == null ? "" : description;
+ this.Name = name == null ? "" : name;
+ this.hostURL = hosturl;
+ }
+
+ /**
+ * The type of analysis the service performs
+ */
+ public String getServiceType()
+ {
+ return ServiceType;
+ }
+
+ public void setServiceType(String serviceType)
+ {
+ ServiceType = serviceType;
+ }
+
+ /**
+ * The action when the service performs the analysis
+ */
+ public String getAction()
+ {
+ return Action;
+ }
+
+ public void setAction(String action)
+ {
+ Action = action;
+ }
+
+ /**
+ * name shown to user
+ *
+ * @return
+ */
+ public String getName()
+ {
+ return Name;
+ }
+
+ public void setName(String name)
+ {
+ Name = name;
+ }
+
+ /**
+ * Detailed description (may include references, URLs, html,etc)
+ *
+ * @return
+ */
+ public String getDescription()
+ {
+ return description;
+ }
+
+ public void setDescription(String description)
+ {
+ this.description = description;
+ }
+
+ @Override
+ public boolean equals(Object object)
+ {
+ if (object == null || !(object instanceof UIinfo))
+ {
+ return false;
+ }
+ UIinfo other = (UIinfo) object;
+
+ return (ServiceType == null && other.getServiceType() == null
+ || ServiceType != null && other.getServiceType() != null
+ && ServiceType.equals(other.getServiceType()))
+ && (hostURL == null && other.getHostURL() == null
+ || hostURL != null && other.getHostURL() != null
+ && hostURL.equals(other.getHostURL()))
+ && (Name == null && other.getName() == null
+ || Name != null && other.getName() != null
+ && Name.equals(other.getName()))
+ && (Action == null && other.getAction() == null
+ || Action != null && other.getAction() != null
+ && Action.equals(other.getAction()))
+ && (description == null && other.getDescription() == null
+ || description != null && other.getDescription() != null
+ && description.equals(other.getDescription()));
+ }
+
+ /**
+ * @return short description of what the service will do
+ */
+ public String getActionText()
+ {
+ return getAction() + " with " + getName();
+ }
+
+ String Action;
+
+ String Name;
+
+ String description;
+
+ String hostURL;
+
+ public String getHostURL()
+ {
+ return hostURL;
+ }
+
+ public ParamDatastoreI getParamStore()
+ {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ /**
+ *
+ * @return true if the service has parameters (ie is instance of
+ * jalview.ws.api.ServiceWithParameters)
+ */
+ public boolean hasParameters()
+ {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ private String docUrl = null;
+
+ /**
+ * set the URL that will be offered to show documentation for the service
+ *
+ * @param url
+ */
+ public void setDocumentationUrl(String url)
+ {
+ docUrl = url;
+ }
+
+ public boolean hasDocumentationUrl()
+ {
+ return docUrl != null && docUrl.length() > 7;
+ }
+
+ public String getDocumentationUrl()
+ {
+ return docUrl;
+ }
+}
\ No newline at end of file
--- /dev/null
+package jalview.ws.api;
+
+public interface WSAnnotationCalcManagerI
+{
+
+}
return getEmblSequenceRecords(DBRefSource.EMBLCDS, queries);
}
+
/**
* cDNA for LDHA_CHICK swissprot sequence
*/
*/
public abstract class EmblFlatfileSource extends EbiFileRetrievedProxy
{
- private static final Regex ACCESSION_REGEX = new Regex("^[A-Z]+[0-9]+");
+ private static final Regex ACCESSION_REGEX = null;
@Override
public String getDbVersion()
@Override
public Regex getAccessionValidator()
{
+ if (ACCESSION_REGEX == null)
+ {
+ ACCESSION_REGEX = Platform.newRegex("^[A-Z]+[0-9]+");
+ }
return ACCESSION_REGEX;
}
import jalview.datamodel.AlignmentI;
import jalview.datamodel.DBRefSource;
+
/**
* @author JimP
*
public AlignmentI getSequenceRecords(String queries) throws Exception
{
return getEmblSequenceRecords(DBRefSource.EMBL, queries);
+
}
/**
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
-import com.stevesoft.pat.Regex;
-
import jalview.analysis.SequenceIdMatcher;
import jalview.bin.Cache;
import jalview.datamodel.Alignment;
import jalview.util.DnaUtils;
import jalview.util.MapList;
import jalview.util.MappingUtils;
+import jalview.util.MessageManager;
import jalview.ws.ebi.EBIFetchClient;
import jalview.xml.binding.embl.EntryType;
import jalview.xml.binding.embl.EntryType.Feature;
*
* @deprecated endpoint withdrawn August 2020 (JAL-3692), use EmblFlatfileSource
*/
+
public abstract class EmblXmlSource extends EbiFileRetrievedProxy
{
+ // TODO: delete class or update tyhis validator for 2.12 style Platform.regex
private static final Regex ACCESSION_REGEX = new Regex("^[A-Z]+[0-9]+");
-
/*
* JAL-1856 Embl returns this text for query not found
*/
{
return new int[] {};
}
-
try
{
List<int[]> ranges = DnaUtils.parseLocation(location);
}
return getAccessionValidator().search(accession);
}
-
/**
* 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
}
int expectedCdsLength = proteinLength * 3;
int exonLength = MappingUtils.getLength(Arrays.asList(exon));
-
/*
* if exon length matches protein, or is shorter, or longer by the
* length of a stop codon (3 bases), then leave it unchanged
{
return exon;
}
-
int origxon[];
int sxpos = -1;
int endxon = 0;
// .println("Truncating final exon interval on region by "
// + (cdspos - cdslength));
}
-
/*
* shrink the final exon - reduce end position if forward
* strand, increase it if reverse
break;
}
}
-
if (sxpos != -1)
{
// and trim the exon interval set if necessary
import jalview.io.PDBFeatureSettings;
import jalview.structure.StructureImportSettings;
import jalview.util.MessageManager;
+import jalview.util.Platform;
import jalview.ws.ebi.EBIFetchClient;
import java.io.File;
private static final int PDB_ID_LENGTH = 4;
+ private static Regex ACCESSION_REGEX;
+
public Pdb()
{
super();
@Override
public Regex getAccessionValidator()
{
- return new Regex("([1-9][0-9A-Za-z]{3}):?([ _A-Za-z0-9]?)");
+ if (ACCESSION_REGEX == null)
+ {
+ ACCESSION_REGEX = Platform
+ .newRegex("([1-9][0-9A-Za-z]{3}):?([ _A-Za-z0-9]?)");
+ }
+ return ACCESSION_REGEX;
}
/*
package jalview.ws.dbsources;
import java.util.Locale;
-
import jalview.bin.Cache;
import jalview.datamodel.Alignment;
import jalview.datamodel.AlignmentI;
private static final String DEFAULT_UNIPROT_DOMAIN = "https://www.uniprot.org";
private static final String BAR_DELIMITER = "|";
+ private static Regex ACCESSION_REGEX;
/**
* Constructor
@Override
public Regex getAccessionValidator()
{
- return new Regex("([A-Z]+[0-9]+[A-Z0-9]+|[A-Z0-9]+_[A-Z0-9]+)");
+ if (ACCESSION_REGEX == null)
+ {
+ ACCESSION_REGEX = Platform
+ .newRegex("([A-Z]+[0-9]+[A-Z0-9]+|[A-Z0-9]+_[A-Z0-9]+)");
+ }
+ return ACCESSION_REGEX;
}
/*
// use/backoff logic to retry when the server tells us to go away
if (urlconn.getResponseCode() == 200)
{
- InputStream istr = urlconn.getInputStream();
- List<Entry> entries = getUniprotEntries(istr);
- if (entries != null)
+ List<SequenceI> seqs = new ArrayList<>();
+ for (Entry entry : entries)
{
- List<SequenceI> seqs = new ArrayList<>();
- for (Entry entry : entries)
- {
- seqs.add(uniprotEntryToSequence(entry));
- }
- al = new Alignment(seqs.toArray(new SequenceI[seqs.size()]));
+ seqs.add(uniprotEntryToSequence(entry));
}
+ al = new Alignment(seqs.toArray(new SequenceI[seqs.size()]));
}
+
stopQuery();
return al;
--- /dev/null
+package jalview.ws.ebi;
+
+import jalview.datamodel.AlignmentAnnotation;
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.Annotation;
+import jalview.datamodel.SequenceFeature;
+import jalview.datamodel.SequenceGroup;
+import jalview.datamodel.SequenceI;
+import jalview.io.FileParse;
+import jalview.viewmodel.AlignmentViewport;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.json.simple.JSONArray;
+import org.json.simple.JSONObject;
+import org.json.simple.parser.JSONParser;
+
+public class HmmerJSONProcessor
+{
+ /**
+ * result to be annotated. may not be null
+ */
+ AlignmentI resultAl;
+
+ /**
+ * viewport on the alignment. may be null at construction time
+ */
+ AlignmentViewport viewAl = null;
+
+ public HmmerJSONProcessor(AlignmentI searchResult)
+ {
+ resultAl = searchResult;
+ }
+
+ public void parseFrom(FileParse jsonsource) throws IOException,
+ OutOfMemoryError
+ {
+ JSONParser hmmerResultParser = new JSONParser();
+ Object jsonResults = null;
+ try
+ {
+ jsonResults = hmmerResultParser.parse(jsonsource.getReader());
+ } catch (Exception p)
+ {
+ throw new IOException("While parsing from " + jsonsource.getInFile(),
+ p);
+ }
+ if (jsonResults == null)
+ {
+ throw new IOException("No data at" + jsonsource.getInFile());
+ }
+ if (!(jsonResults instanceof JSONObject))
+ {
+ throw new IOException("Unexpected JSON model at "
+ + jsonsource.getInFile());
+ }
+ try
+ {
+ JSONObject hmmsearchr = (JSONObject) ((JSONObject) jsonResults)
+ .get("results");
+ // now process the hits
+ addStatistics((JSONObject) hmmsearchr.get("stats"));
+ JSONArray jsonArray = (JSONArray) hmmsearchr.get("hits");
+ long p = 1;
+ for (Object hit : jsonArray)
+ {
+ JSONObject hmmhit = (JSONObject) hit;
+ addHit(hmmhit, p++);
+ }
+ } catch (ClassCastException q)
+ {
+ throw new IOException("Unexpected JSON model content at "
+ + jsonsource.getInFile(), q);
+ }
+ }
+
+ /**
+ *
+ * @param object
+ * - actually a JSONObject key value set of search statistics.
+ */
+ public void addStatistics(JSONObject stats)
+ {
+ for (Object stat : stats.keySet())
+ {
+ String key = (String) stat;
+ Object val = stats.get(key);
+ resultAl.setProperty(key, "" + val);
+ }
+ }
+
+ // encodings for JSON keys
+ /**
+ * score becomes sequence associated AlignmentAnnotation
+ */
+ private String[] score = { "aliId", "ali_IdCount", "bitscore", "ievalue",
+ "aliSim", "aliSimCount", "aliL", "aliSim", "ievalue", "cevalue" };
+
+ /**
+ * attrib becomes numeric or binary attribute for sequence with respect to
+ * this hmmsearch run
+ */
+ private String[] attrib = { "bias", "oasc", "is_included", "is_reported" };
+
+ /**
+ * name of the hmmsearch query
+ */
+ private String[] label = { "alihmmname" // (query label?)},
+ };
+
+ /**
+ * integer attributes for each
+ */
+ private String[] ipos = { "alihmmfrom", "alihmmto" }, pos_l = {
+ "alimline", "alimodel", "alirfline" };
+
+ /**
+ * positional quantitative annotation encoded as strings.
+ */
+ private String[] pos_nscore = { "alippline" };
+
+ //
+ // mapping of keys to types of property on sequence
+ //
+ public void addHit(JSONObject hmmrhit, long p)
+ {
+ String sname = (String) hmmrhit.get("name");
+ SequenceI[] hits = resultAl.findSequenceMatch(sname);
+ if (hits == null)
+ {
+ System.err.println("No seq for " + sname);
+ }
+ double pvalue = (Double) hmmrhit.get("pvalue");
+
+ double evalue = Double.valueOf("" + hmmrhit.get("evalue"));
+ for (Object domainhit : ((JSONArray) hmmrhit.get("domains")))
+ {
+ JSONObject dhit = (JSONObject) domainhit;
+ // dhit.get(key)
+
+ // alihmmfrom,alihmmto alimodel
+ long alihmmfrom = (long) dhit.get("alihmmfrom"), alihmmto = (long) dhit
+ .get("alihmmto"), alisqfrom = (long) dhit.get("alisqfrom"), alisqto = (long) dhit
+ .get("alisqto");
+
+ // alisqfrom,alisqto,aliaseq
+
+ // alippline
+ String aliaseq = (String) dhit.get("aliaseq"), alimodel = (String) dhit
+ .get("alimodel"), ppline = (String) dhit.get("alippline");
+ //
+ int found = 0;
+ SequenceI firsthit = null;
+ for (SequenceI hitseq : hits)
+ {
+ // match alisqfrom,alisqto,seq
+ if (hitseq.getStart() == alisqfrom && hitseq.getEnd() == alisqto)
+ {
+ if (found == 0)
+ {
+ firsthit = hitseq;
+ }
+ found++; // annotated a sequence
+ AlignmentAnnotation alipp = parsePosteriorProb(ppline);
+ AlignmentAnnotation pval = new AlignmentAnnotation("p-value",
+ "hmmer3 pvalue", pvalue);
+ AlignmentAnnotation eval = new AlignmentAnnotation("e-value",
+ "hmmer3 evalue", evalue);
+ pval.setCalcId("HMMER3");
+ eval.setCalcId("HMMER3");
+ alipp.setCalcId("HMMER3");
+ hitseq.addAlignmentAnnotation(pval);
+ hitseq.addAlignmentAnnotation(eval);
+ alipp.createSequenceMapping(hitseq, hitseq.getStart(), false);
+ hitseq.addAlignmentAnnotation(alipp);
+ String arch;
+ hitseq.addSequenceFeature(new SequenceFeature(
+ "Pfam Domain Architecture", (hmmrhit.get("archindex"))
+ + " " + (arch = (String) hmmrhit.get("arch")), 0,
+ 0,
+ (hmmrhit.get("archScore") != null ? Integer
+ .valueOf((String) hmmrhit.get("archScore")) : 0f),
+ "HMMER3"));
+ addArchGroup(hitseq, arch);
+ alipp.setScore(Double.valueOf("" + dhit.get("bitscore")));
+ alipp.adjustForAlignment();
+ resultAl.addAnnotation(pval);
+ resultAl.addAnnotation(eval);
+ resultAl.addAnnotation(alipp);
+ alipp.validateRangeAndDisplay();
+ }
+ }
+ // look for other sequences represented by this hit and create rep groups
+ // could be in "pdbs", or ..
+ addRedundantSeqGroup(firsthit, alisqfrom, alisqto,
+ (JSONArray) hmmrhit.get("seqs"), true);
+ }
+ }
+
+ /**
+ * series of operations to perform for the viewpanel associated with the
+ * alignment
+ */
+ private List<Runnable> viewOps = new ArrayList<Runnable>();
+
+ public void updateView(AlignmentViewport view)
+ {
+ viewAl = view;
+ for (Runnable op : viewOps)
+ {
+ op.run();
+ }
+ }
+
+ private void addRedundantSeqGroup(final SequenceI firsthit,
+ long alisqfrom, long alisqto, JSONArray others, boolean justDelete)
+ {
+ if (others != null)
+ {
+ final SequenceGroup repgroup = new SequenceGroup();
+ repgroup.setSeqrep(firsthit);
+ repgroup.addOrRemove(firsthit, false);
+ repgroup.setStartRes(0);
+ repgroup.setEndRes(resultAl.getWidth() - 1);
+ for (Object otherseq : others.toArray(new JSONObject[0]))
+ {
+ String repseq = (String) ((JSONObject) otherseq).get("dn");
+ SequenceI[] other = resultAl.findSequenceMatch(repseq);
+ if (other != null && other.length > 0)
+ {
+ if (justDelete)
+ {
+ for (SequenceI oth : other)
+ {
+ resultAl.deleteSequence(oth);
+ }
+ ;
+ }
+ else
+ {
+ int ofound = 0;
+ for (SequenceI oth : other)
+ {
+ if (oth.getStart() == alisqfrom && oth.getEnd() == alisqto)
+ {
+ ofound++;
+ repgroup.addSequence(oth, false);
+ }
+ }
+ if (ofound == 0)
+ {
+ System.err.println("Warn - no match for redundant hit "
+ + repseq + "/" + alisqfrom + "-" + alisqto);
+ }
+ if (ofound > 1)
+ {
+ System.err
+ .println("Warn - multiple matches for redundant hit "
+ + repseq + "/" + alisqfrom + "-" + alisqto);
+ }
+ }
+ }
+ }
+ if (repgroup.getSequences().size() > 1)
+ {
+ // queue a hide operation
+ final HmmerJSONProcessor me = this;
+ viewOps.add(new Runnable()
+ {
+ @Override
+ public void run()
+ {
+ me.viewAl.hideRepSequences(firsthit, repgroup);
+ }
+ });
+ }
+ }
+ }
+
+ Map<String, SequenceGroup> groups = new HashMap<String, SequenceGroup>();
+
+ private void addArchGroup(SequenceI seqToAdd, String groupNam)
+ {
+ SequenceGroup sg = groups.get(groupNam);
+ if (sg == null)
+ {
+ sg = new SequenceGroup();
+ sg.setName(groupNam);
+ sg.addSequence(seqToAdd, false);
+ sg.setStartRes(0);
+ sg.setEndRes(resultAl.getWidth() - 1);
+ groups.put(groupNam, sg);
+ resultAl.addGroup(sg);
+ }
+ else
+ {
+ sg.addSequence(seqToAdd, false);
+ }
+ }
+
+ private AlignmentAnnotation parsePosteriorProb(String ppline)
+ {
+ Annotation[] ae = new Annotation[ppline.length()];
+ int spos = 0;
+ for (int i = 0, iSize = ppline.length(); i < iSize; i++)
+ {
+ char pp = ppline.charAt(i);
+ if (pp == '*')
+ {
+ ae[spos++] = new Annotation(10f);
+ }
+ else
+ {
+ if (pp >= '0' && pp <= '9')
+ {
+ ae[spos++] = new Annotation(Integer.valueOf("" + pp));
+ }
+ }
+ }
+ AlignmentAnnotation pprob = new AlignmentAnnotation(
+ "Posterior Probability",
+ "Likelihood of HMM fit at each hit position.", ae);
+ pprob.graph = AlignmentAnnotation.BAR_GRAPH;
+ pprob.visible = false;
+ return pprob;
+ }
+}
--- /dev/null
+package jalview.ws.ebi;
+
+import jalview.datamodel.AlignmentI;
+import jalview.io.AppletFormatAdapter;
+import jalview.io.DataSourceType;
+import jalview.io.FileFormat;
+import jalview.io.FileParse;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.regex.Matcher;
+
+import org.apache.axis.transport.http.HTTPConstants;
+import org.apache.http.Header;
+import org.apache.http.HttpResponse;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.impl.client.DefaultHttpClient;
+import org.apache.http.util.EntityUtils;
+import org.json.JSONArray;
+import org.json.JSONObject;
+
+import compbio.util.FileUtil;
+
+public class hmmerClient
+{
+ /**
+ * URLs for ebi api
+ */
+ static String baseUrl = "http://www.ebi.ac.uk/Tools/hmmer",
+ jackH = "/search/jackhmmer", phmmer = "/search/phmmer",
+ hmmscan = "/search/hmmscan", hmmsearch = "/search/hmmsearch";
+
+ static String edseq = ">2abl_A mol:protein length:163 ABL TYROSINE KINASE\nMGPSENDPNLFVALYDFVASGDNTLSITKGEKLRVLGYNHNGEWCEAQTKNGQGWVPSNYITPVNSLEKHS\nWYHGPVSRNAAEYLLSSGINGSFLVRESESSPGQRSISLRYEGRVYHYRINTASDGKLYVSSESRFNTLAE\nLVHHHSTVADGLITTLHYPAP";
+
+ public static void main(String[] args)
+ {
+ String instr = edseq;
+ if (args.length > 0)
+ {
+ try
+ {
+ instr = FileUtil.readFileToString(new File(args[0]));
+ } catch (Exception f)
+ {
+ f.printStackTrace();
+ return;
+ }
+ }
+ String res = new hmmerClient().submitJackhmmerSearch(instr,
+ "jackhmmer", "pdb", 5);
+ if (res == null)
+ {
+ throw new Error("Failed.");
+ }
+ System.out.println("Result\n" + res);
+ return;
+ }
+
+ /**
+ *
+ * @param input
+ * - fasta or other formatted sequence or alignment
+ * @param algo
+ * - jackhmmer
+ * @param db
+ * - pdb, uniprot, etc.
+ * @param niter
+ * number of iterations
+ * @return job id
+ */
+ String submitJackhmmerSearch(String input, String algo, String db,
+ int niter)
+ {
+ JSONObject inparam = new JSONObject();
+ HttpPost jackhp = new HttpPost(baseUrl + jackH);
+ String lastiter = null;
+ try
+ {
+ inparam.put("algo", algo);
+ inparam.put("seq", input);
+ inparam.put("seqdb", db);
+ inparam.put("iterations", niter);
+ // #Now POST the request and generate the search job.
+ // dumb json post service
+ jackhp.setHeader("content-type", "application/json");
+ jackhp.setEntity(new StringEntity(inparam.toString()));
+ } catch (Exception f)
+ {
+ f.printStackTrace();
+ return null;
+ }
+ HttpResponse r = null;
+ try
+ {
+ DefaultHttpClient httpCl = new DefaultHttpClient();
+
+ r = httpCl.execute(jackhp);
+
+ } catch (Exception x)
+ {
+ System.err.println("Submit failed.");
+ x.printStackTrace();
+ }
+ if (r.getStatusLine().getStatusCode() != 201)
+ {
+ throw new Error(r.toString());
+ }
+ // get uid for job
+ String jobid = null, redir = null;
+ try
+ {
+ JSONObject res = new JSONObject(EntityUtils.toString(r.getEntity()));
+ jobid = res.getString("job_id");
+
+ Header[] loc;
+ if ((loc = r.getHeaders(HTTPConstants.HEADER_LOCATION)) != null
+ && loc.length > 0)
+ {
+ if (loc.length > 1)
+ {
+ System.err
+ .println("Ignoring additional "
+ + (loc.length - 1)
+ + " location(s) provided in response header ( next one is '"
+ + loc[1].getValue() + "' )");
+ }
+ redir = loc[0].getValue();
+ }
+ } catch (Exception x)
+ {
+ System.err.println("job id extraction failed.");
+ x.printStackTrace();
+ }
+ int tries = 0;
+ boolean finished = false;
+ JSONObject jobstate = null;
+ do
+ {
+ try
+ {
+ DefaultHttpClient httpCl = new DefaultHttpClient();
+
+ HttpGet jackcheck = new HttpGet(redir);
+ jackcheck.setHeader("content-type", "application/json");
+ r = httpCl.execute(jackcheck);
+ switch (r.getStatusLine().getStatusCode())
+ {
+ case 200:
+ jobstate = new JSONObject(EntityUtils.toString(r.getEntity()));
+ String st = jobstate.getString("status");
+ if ("DONE".equals(st))
+ {
+ finished = true;
+ }
+ if ("ERROR".equals(st))
+ {
+ System.err.println("Error");
+ finished = true;
+ }
+ if ("PEND".equals(st) || "RUN".equals("st"))
+ {
+ JSONArray iters = jobstate.getJSONArray("result");
+ lastiter = iters.getJSONObject(iters.length() - 1).getString(
+ "uuid");
+ if (lastiter.length() > 0)
+ {
+ java.util.regex.Pattern p = java.util.regex.Pattern
+ .compile(".+(\\d+)");
+ Matcher m = p.matcher(lastiter);
+ if (m.matches())
+ {
+ System.out.println("On iteration " + m.group(1));
+ }
+ }
+ }
+ break;
+
+ default:
+ tries++;
+ Thread.sleep(2000);
+ }
+ } catch (Exception q)
+ {
+ q.printStackTrace();
+ return null;
+ }
+ } while (!finished && tries < 50);
+
+ if (!finished)
+ {
+ System.err.println("Giving up with job " + jobid + " at " + redir);
+ return null;
+ }
+ // get results
+ // http://www.ebi.ac.uk/Tools/hmmer/download/60048B38-7CEC-11E5-A230-CED6D26C98AD.5/score?format=csv
+ // 1gri_A 1gri_A 217 jackhmmer - 163 4.7e-62 212.4 0.1 1 2 4.4e-46 2.1e-43
+ // 151.758316040039 0.04 11 151 3 139 1 150 0.94 GROWTH FACTOR BOUND PROTEIN
+ // 2 1cj1_J 1gri_B
+ // 1gri_A 1gri_A 217 jackhmmer - 163 4.7e-62 212.4 0.1 2 2 1.6e-17 7.9e-15
+ // 58.8796501159668 0.01 7 66 157 215 153 216 0.95 GROWTH FACTOR BOUND
+ // PROTEIN 2 1cj1_J 1gri_B
+ // 4h1o_A 4h1o_A 560 jackhmmer - 163 2.1e-57 197.3 0.0 1 2 7.5e-28 3.6e-25
+ // 92.4921493530273 0.00 65 161 20 122 17 124 0.95 Tyrosine-protein
+ // phosphatase non-receptor typ 4h1o_A
+ //
+ // 4h1o_A 4h1o_A 560 jackhmmer - 163 2.1e-57 197.3 0.0 2 2 7.6e-31 3.7e-28
+ // 102.219146728516 0.03 66 161 127 236 124 238 0.94 Tyrosine-protein
+ // phosphatase non-receptor typ 4h1o_A
+ //
+ // $ua->get( $rootUrl."/results/".$lastIteration->{uuid} . "/score"
+ return lastiter;
+ /*
+ * * #Job should have finished, but we may have converged, so get the last
+ * job. my $results = $json->decode( $response->content ); my $lastIteration
+ * = pop( @{ $results->{result} } ); #Now fetch the results of the last
+ * iteration my $searchResult = $ua->get( $rootUrl."/results/" .
+ * $lastIteration->{uuid} . "/score", 'Accept' => 'application/json' );
+ * unless( $searchResult->status_line eq "200 OK"){ die
+ * "Failed to get search results\n"; }
+ *
+ * #Decode the content of the full set of results $results = $json->decode(
+ * $searchResult->content ); print
+ * "Matched ".$results->{'results'}->{'stats'}->{'nincluded'}." sequences
+ * ($lastIteration->{uuid})!\n"; #Now do something more interesting with the
+ * results......
+ */
+ }
+
+ /**
+ * retrieve an alignment annotated with scores from JackHmmer
+ *
+ * @param jobid
+ * @param dataset
+ * @return
+ */
+ AlignmentI retrieveJackhmmerResult(String jobid, AlignmentI dataset)
+ throws OutOfMemoryError, IOException
+ {
+ AlignmentI searchResult = null;
+
+ // get results
+
+ searchResult = new AppletFormatAdapter().readFile(baseUrl
+ + "/download/" + jobid + "/score?format=afa&t=.gz",
+ DataSourceType.URL, FileFormat.Fasta);
+
+ // TODO extract gapped columns as '.' - inserts to query profile
+
+ // TODO match up jackhammer results to dataset.
+
+ // do scores
+ FileParse jsonsource = new FileParse(baseUrl + "/download/" + jobid
+ + "/score?format=json", DataSourceType.URL);
+ if (!jsonsource.isValid())
+ {
+ throw new IOException("Couldn't access scores for Jackhammer results");
+ }
+ readJackhmmerScores(searchResult, jsonsource);
+ return searchResult;
+ }
+
+ /**
+ * // 1gri_A 1gri_A 217 jackhmmer - 163 4.7e-62 212.4 0.1 1 2 4.4e-46 2.1e-43
+ *
+ * // 151.758316040039 0.04 11 151 3 139 1 150 0.94 GROWTH FACTOR BOUND
+ * PROTEIN // 2 1cj1_J 1gri_B // 1gri_A 1gri_A 217 jackhmmer - 163 4.7e-62
+ * 212.4 0.1 2 2 1.6e-17 7.9e-15 // 58.8796501159668 0.01 7 66 157 215 153 216
+ * 0.95 GROWTH FACTOR BOUND // PROTEIN 2 1cj1_J 1gri_B // 4h1o_A 4h1o_A 560
+ * jackhmmer - 163 2.1e-57 197.3 0.0 1 2 7.5e-28 3.6e-25 // 92.4921493530273
+ * 0.00 65 161 20 122 17 124 0.95 Tyrosine-protein // phosphatase non-receptor
+ * typ 4h1o_A
+ */
+ private static String[] _hmmsearchcols = new String[] { "acc", "name", "" };
+
+ private void readJackhmmerScores(AlignmentI searchResult,
+ FileParse jsonsource) throws IOException, OutOfMemoryError
+ {
+ HmmerJSONProcessor hjp = new HmmerJSONProcessor(searchResult);
+ hjp.parseFrom(jsonsource);
+
+ // http://www.ebi.ac.uk/Tools/hmmer/download/60048B38-7CEC-11E5-A230-CED6D26C98AD.5/score?format=csv
+ // 1gri_A 1gri_A 217 jackhmmer - 163 4.7e-62 212.4 0.1 1 2 4.4e-46 2.1e-43
+ // 151.758316040039 0.04 11 151 3 139 1 150 0.94 GROWTH FACTOR BOUND PROTEIN
+ // 2 1cj1_J 1gri_B
+ // 1gri_A 1gri_A 217 jackhmmer - 163 4.7e-62 212.4 0.1 2 2 1.6e-17 7.9e-15
+ // 58.8796501159668 0.01 7 66 157 215 153 216 0.95 GROWTH FACTOR BOUND
+ // PROTEIN 2 1cj1_J 1gri_B
+ // 4h1o_A 4h1o_A 560 jackhmmer - 163 2.1e-57 197.3 0.0 1 2 7.5e-28 3.6e-25
+ // 92.4921493530273 0.00 65 161 20 122 17 124 0.95 Tyrosine-protein
+ // phosphatase non-receptor typ 4h1o_A
+ // each line scores a fragment
+ // so for a combined score ?
+
+ /**
+ * for a sequence q sort any t against q according to overallScore(q,t)
+ * maxFragment(q,t) in sequence features parlance: for alignment
+ * s.getFeature("overallScore",q) -> range on q and range on s
+ *
+ *
+ */
+
+ // 151.758316040039 0.04 11 151 3 139 1 150 0.94 GROWTH FACTOR BOUND PROTEIN
+ // 2 1cj1_J 1gri_B
+ // 1gri_A 1gri_A 217 jackhmmer - 163 4.7e-62 212.4 0.1 2 2 1.6e-17 7.9e-15
+ // 58.8796501159668 0.01 7 66 157 215 153 216 0.95 GROWTH FACTOR BOUND
+ // PROTEIN 2 1cj1_J 1gri_B
+ // 4h1o_A 4h1o_A 560 jackhmmer - 163 2.1e-57 197.3 0.0 1 2 7.5e-28 3.6e-25
+ // 92.4921493530273 0.00 65 161 20 122 17 124 0.95 Tyrosine-protein
+ // phosphatase non-receptor typ 4h1o_A
+ //
+ // 4h1o_A 4h1o_A 560 jackhmmer - 163 2.1e-57 197.3 0.0 2 2 7.6e-31 3.7e-28
+ // 102.219146728516 0.03 66 161 127 236 124 238 0.94 Tyrosine-protein
+ // phosphatase non-receptor typ 4h1o_A
+
+ }
+
+}
--- /dev/null
+package jalview.ws.gui;
+
+import jalview.api.FeatureRenderer;
+import jalview.datamodel.AlignmentAnnotation;
+import jalview.datamodel.SequenceI;
+
+import java.util.List;
+import java.util.Map;
+
+public class AnnotationWsJob extends WsJob
+{
+ /**
+ * sequences (anonymised)
+ */
+ List<SequenceI> seqs;
+
+ /**
+ * mapping to original sequences
+ */
+ Map<String, SequenceI> seqNames;
+
+ /**
+ * first column in the segment of the alignment view that was submitted
+ */
+ int startPos;
+
+ public int getStartPos()
+ {
+ return startPos;
+ }
+
+ public void setStartPos(int startPos)
+ {
+ this.startPos = startPos;
+ }
+
+ /**
+ * outputs
+ */
+ List<AlignmentAnnotation> annotation = null;
+
+ boolean transferSequenceFeatures = false;
+
+ public boolean isTransferSequenceFeatures()
+ {
+ return transferSequenceFeatures;
+ }
+
+ public void setTransferSequenceFeatures(boolean transferSequenceFeatures)
+ {
+ this.transferSequenceFeatures = transferSequenceFeatures;
+ }
+
+ public List<AlignmentAnnotation> getAnnotation()
+ {
+ return annotation;
+ }
+
+ public void setAnnotation(List<AlignmentAnnotation> annotation)
+ {
+ this.annotation = annotation;
+ }
+
+ @Override
+ public boolean hasResults()
+ {
+ return (isSubmitted() && isFinished()
+ && (annotation != null || transferSequenceFeatures));
+ }
+
+ public List<SequenceI> getSeqs()
+ {
+ return seqs;
+ }
+
+ public void setSeqs(List<SequenceI> seqs)
+ {
+ this.seqs = seqs;
+ }
+
+ public Map<String, SequenceI> getSeqNames()
+ {
+ return seqNames;
+ }
+
+ public void setSeqNames(Map<String, SequenceI> seqNames)
+ {
+ this.seqNames = seqNames;
+ }
+
+ /**
+ * configured by the WS framework just before results are collected
+ */
+ FeatureRenderer featureRenderer;
+
+ public void setFeatureRenderer(FeatureRenderer fr)
+ {
+ this.featureRenderer = fr;
+ }
+ public FeatureRenderer getFeatureRenderer()
+ {
+ // TODO Auto-generated method stub
+ return featureRenderer;
+ }
+
+}
--- /dev/null
+package jalview.ws.gui;
+
+import jalview.analysis.AlignSeq;
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.AlignmentOrder;
+import jalview.datamodel.Sequence;
+import jalview.datamodel.SequenceI;
+import jalview.util.MessageManager;
+import jalview.ws.jws2.dm.JabaWsParamSet;
+import jalview.ws.params.ArgumentI;
+
+import java.util.ArrayList;
+import java.util.Vector;
+
+class MsaWSJob extends WsJob
+{
+ /**
+ * holds basic MSA analysis configuration - todo - encapsulate
+ */
+ private final MsaWSThread msaWSThread;
+
+ long lastChunk = 0;
+
+ /**
+ * input
+ */
+ ArrayList<SequenceI> seqs = new ArrayList<>();
+
+ /**
+ * output
+ */
+ AlignmentI alignment;
+
+ // set if the job didn't get run - then the input is simply returned to the
+ // user
+ private boolean returnInput = false;
+
+ /**
+ * MsaWSJob
+ *
+ * @param jobNum
+ * int
+ * @param msaWSThread
+ * TODO - abstract the properties provided by the thread
+ * @param jobId
+ * String
+ */
+ public MsaWSJob(MsaWSThread msaWSThread, int jobNum, SequenceI[] inSeqs)
+ {
+ this.msaWSThread = msaWSThread;
+ this.jobnum = jobNum;
+ if (!prepareInput(inSeqs, 2))
+ {
+ submitted = true;
+ subjobComplete = true;
+ returnInput = true;
+ } else
+ {
+ validInput = true;
+ }
+
+ }
+
+ Vector<String[]> emptySeqs = new Vector();
+
+ /**
+ * prepare input sequences for MsaWS service
+ *
+ * @param seqs
+ * jalview sequences to be prepared
+ * @param minlen
+ * minimum number of residues required for this MsaWS service
+ * @return true if seqs contains sequences to be submitted to service.
+ */
+ // TODO: return compbio.seqs list or nothing to indicate validity.
+ private boolean prepareInput(SequenceI[] seqs, int minlen)
+ {
+ // TODO: service specific input data is generated in this method - for
+ // JABAWS it is client-side
+ // prepared, but for Slivka it could be uploaded at this stage.
+
+ int nseqs = 0;
+ if (minlen < 0)
+ {
+ throw new Error(MessageManager.getString(
+ "error.implementation_error_minlen_must_be_greater_zero"));
+ }
+ for (int i = 0; i < seqs.length; i++)
+ {
+ if (seqs[i].getEnd() - seqs[i].getStart() > minlen - 1)
+ {
+ nseqs++;
+ }
+ }
+ boolean valid = nseqs > 1; // need at least two seqs
+ Sequence seq;
+ for (int i = 0, n = 0; i < seqs.length; i++)
+ {
+ String newname = jalview.analysis.SeqsetUtils.unique_name(i); // same
+ // for
+ // any
+ // subjob
+ SeqNames.put(newname,
+ jalview.analysis.SeqsetUtils.SeqCharacterHash(seqs[i]));
+ if (valid && seqs[i].getEnd() - seqs[i].getStart() > minlen - 1)
+ {
+ // make new input sequence with or without gaps
+ seq = new Sequence(newname,
+ (this.msaWSThread.submitGaps) ? seqs[i].getSequenceAsString()
+ : AlignSeq.extractGaps(
+ jalview.util.Comparison.GapChars,
+ seqs[i].getSequenceAsString()));
+ this.seqs.add(seq);
+ }
+ else
+ {
+ String empty = null;
+ if (seqs[i].getEnd() >= seqs[i].getStart())
+ {
+ empty = (this.msaWSThread.submitGaps) ? seqs[i].getSequenceAsString()
+ : AlignSeq.extractGaps(jalview.util.Comparison.GapChars,
+ seqs[i].getSequenceAsString());
+ }
+ emptySeqs.add(new String[] { newname, empty });
+ }
+ }
+ return valid;
+ }
+
+ /**
+ *
+ * @return true if getAlignment will return a valid alignment result.
+ */
+ @Override
+ public boolean hasResults()
+ {
+ if (subjobComplete && isFinished() && (alignment != null
+ || (emptySeqs != null && emptySeqs.size() > 0)))
+ {
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ *
+ * get the alignment including any empty sequences in the original order
+ * with original ids. Caller must access the alignment.getMetadata() object
+ * to annotate the final result passsed to the user.
+ *
+ * @return { SequenceI[], AlignmentOrder }
+ */
+ public Object[] getAlignment()
+ {
+ // TODO: make this generic based on MsaResultI
+ // TODO: decide if the data loss for this return signature is avoidable
+ // (ie should we just return AlignmentI instead ?)
+ if (hasResults())
+ {
+ SequenceI[] alseqs = null;
+ char alseq_gapchar = '-';
+ int alseq_l = 0;
+ alseqs = new SequenceI[alignment.getSequences().size()];
+ if (alignment.getSequences().size() > 0)
+ {
+ for (SequenceI seq : alignment
+ .getSequences())
+ {
+ alseqs[alseq_l++] = new Sequence(seq);
+ }
+ alseq_gapchar = alignment.getGapCharacter();
+
+ }
+ // add in the empty seqs.
+ if (emptySeqs.size() > 0)
+ {
+ SequenceI[] t_alseqs = new SequenceI[alseq_l + emptySeqs.size()];
+ // get width
+ int i, w = 0;
+ if (alseq_l > 0)
+ {
+ for (i = 0, w = alseqs[0].getLength(); i < alseq_l; i++)
+ {
+ if (w < alseqs[i].getLength())
+ {
+ w = alseqs[i].getLength();
+ }
+ t_alseqs[i] = alseqs[i];
+ alseqs[i] = null;
+ }
+ }
+ // check that aligned width is at least as wide as emptySeqs width.
+ int ow = w, nw = w;
+ for (i = 0, w = emptySeqs.size(); i < w; i++)
+ {
+ String[] es = emptySeqs.get(i);
+ if (es != null && es[1] != null)
+ {
+ int sw = es[1].length();
+ if (nw < sw)
+ {
+ nw = sw;
+ }
+ }
+ }
+ // make a gapped string.
+ StringBuffer insbuff = new StringBuffer(w);
+ for (i = 0; i < nw; i++)
+ {
+ insbuff.append(alseq_gapchar);
+ }
+ if (ow < nw)
+ {
+ for (i = 0; i < alseq_l; i++)
+ {
+ int sw = t_alseqs[i].getLength();
+ if (nw > sw)
+ {
+ // pad at end
+ alseqs[i].setSequence(t_alseqs[i].getSequenceAsString()
+ + insbuff.substring(0, sw - nw));
+ }
+ }
+ }
+ for (i = 0, w = emptySeqs.size(); i < w; i++)
+ {
+ String[] es = emptySeqs.get(i);
+ if (es[1] == null)
+ {
+ t_alseqs[i + alseq_l] = new jalview.datamodel.Sequence(es[0],
+ insbuff.toString(), 1, 0);
+ }
+ else
+ {
+ if (es[1].length() < nw)
+ {
+ t_alseqs[i + alseq_l] = new jalview.datamodel.Sequence(
+ es[0],
+ es[1] + insbuff.substring(0, nw - es[1].length()),
+ 1, 1 + es[1].length());
+ }
+ else
+ {
+ t_alseqs[i + alseq_l] = new jalview.datamodel.Sequence(
+ es[0], es[1]);
+ }
+ }
+ }
+ alseqs = t_alseqs;
+ }
+ AlignmentOrder msaorder = new AlignmentOrder(alseqs);
+ // always recover the order - makes parseResult()'s life easier.
+ jalview.analysis.AlignmentSorter.recoverOrder(alseqs);
+ // account for any missing sequences
+ jalview.analysis.SeqsetUtils.deuniquify(SeqNames, alseqs);
+ return new Object[] { alseqs, msaorder };
+ }
+ return null;
+ }
+
+ /**
+ * mark subjob as cancelled and set result object appropriatly
+ */
+ void cancel()
+ {
+ cancelled = true;
+ subjobComplete = true;
+ alignment = null;
+ }
+
+ /**
+ *
+ * @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
+ // sequence alignment.
+ // TODO: check type of sequences are valid for this service
+ if (seqs != null && seqs.size() >= 2) // two or more sequences is valid ?
+ {
+ return true;
+ }
+ return false;
+ }
+
+ StringBuffer jobProgress = new StringBuffer();
+
+ @Override
+ public void setStatus(String string)
+ {
+ jobProgress.setLength(0);
+ jobProgress.append(string);
+ }
+
+ @Override
+ public String getStatus()
+ {
+ return jobProgress.toString();
+ }
+
+ @Override
+ public boolean hasStatus()
+ {
+ return jobProgress != null;
+ }
+
+ /**
+ * @return the lastChunk
+ */
+ public long getLastChunk()
+ {
+ return lastChunk;
+ }
+
+ /**
+ * @param lastChunk
+ * the lastChunk to set
+ */
+ public void setLastChunk(long lastChunk)
+ {
+ this.lastChunk = lastChunk;
+ }
+
+ String alignmentProgram = null;
+
+ public String getAlignmentProgram()
+ {
+ return alignmentProgram;
+ }
+
+ public boolean hasArguments()
+ {
+ return (arguments != null && arguments.size() > 0)
+ || (preset != null && preset instanceof JabaWsParamSet);
+ }
+
+ /**
+ * add a progess header to status string containing presets/args used
+ */
+ public void addInitialStatus()
+ {
+ // TODO: decide if it is useful to report 'JABAWS format' argument lists
+ // rather than generic Jalview service arguments
+ if (preset != null)
+ {
+ jobProgress.append(
+ "Using " + (preset.isModifiable() ? "Server" : "User")
+ + "Preset: " + preset.getName());
+ for (ArgumentI opt : preset.getArguments())
+ {
+ jobProgress.append(opt.getName() + " " + opt.getValue() + "\n");
+ }
+ }
+ else
+ {
+ if (arguments != null && arguments.size() > 0)
+ {
+ jobProgress.append("With custom parameters : \n");
+ // merge arguments with preset's own arguments.
+ for (ArgumentI opt : arguments)
+ {
+ jobProgress.append(opt.getName() + " " + opt.getValue() + "\n");
+ }
+ }
+ jobProgress.append("\nJob Output:\n");
+ }
+ }
+}
\ No newline at end of file
* along with Jalview. If not, see <http://www.gnu.org/licenses/>.
* The Jalview Authors are detailed in the 'AUTHORS' file.
*/
-package jalview.ws.jws2;
+package jalview.ws.gui;
-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.HiddenColumns;
-import jalview.datamodel.Sequence;
import jalview.datamodel.SequenceI;
import jalview.gui.AlignFrame;
import jalview.gui.Desktop;
import jalview.gui.SplitFrame;
import jalview.gui.WebserviceInfo;
import jalview.util.MessageManager;
+import jalview.ws.AWSThread;
import jalview.ws.AWsJob;
import jalview.ws.JobStateSummary;
import jalview.ws.WSClientI;
-import jalview.ws.jws2.dm.JabaWsParamSet;
+import jalview.ws.api.CancellableI;
+import jalview.ws.api.JobId;
+import jalview.ws.api.MultipleSequenceAlignmentI;
+import jalview.ws.gui.WsJob.JobState;
+import jalview.ws.params.ArgumentI;
import jalview.ws.params.WsParamSetI;
import java.util.ArrayList;
-import java.util.Hashtable;
import java.util.List;
-import java.util.Map;
-import java.util.Vector;
import javax.swing.JInternalFrame;
-import compbio.data.msa.MsaWS;
-import compbio.metadata.Argument;
-import compbio.metadata.ChunkHolder;
-import compbio.metadata.JobStatus;
-import compbio.metadata.Preset;
-
-class MsaWSThread extends AWS2Thread implements WSClientI
+public class MsaWSThread extends AWSThread implements WSClientI
{
boolean submitGaps = false; // pass sequences including gaps to alignment
// order
- class MsaWSJob extends JWs2Job
- {
- long lastChunk = 0;
-
- WsParamSetI preset = null;
-
- List<Argument> arguments = null;
-
- /**
- * input
- */
- ArrayList<compbio.data.sequence.FastaSequence> seqs = new ArrayList<compbio.data.sequence.FastaSequence>();
-
- /**
- * output
- */
- compbio.data.sequence.Alignment alignment;
-
- // set if the job didn't get run - then the input is simply returned to the
- // user
- private boolean returnInput = false;
-
- /**
- * MsaWSJob
- *
- * @param jobNum
- * int
- * @param jobId
- * String
- */
- public MsaWSJob(int jobNum, SequenceI[] inSeqs)
- {
- this.jobnum = jobNum;
- if (!prepareInput(inSeqs, 2))
- {
- submitted = true;
- subjobComplete = true;
- returnInput = true;
- }
-
- }
-
- Hashtable<String, Map> SeqNames = new Hashtable();
-
- Vector<String[]> emptySeqs = new Vector();
-
- /**
- * prepare input sequences for MsaWS service
- *
- * @param seqs
- * jalview sequences to be prepared
- * @param minlen
- * minimum number of residues required for this MsaWS service
- * @return true if seqs contains sequences to be submitted to service.
- */
- // TODO: return compbio.seqs list or nothing to indicate validity.
- private boolean prepareInput(SequenceI[] seqs, int minlen)
- {
- int nseqs = 0;
- if (minlen < 0)
- {
- throw new Error(MessageManager.getString(
- "error.implementation_error_minlen_must_be_greater_zero"));
- }
- for (int i = 0; i < seqs.length; i++)
- {
- if (seqs[i].getEnd() - seqs[i].getStart() > minlen - 1)
- {
- nseqs++;
- }
- }
- boolean valid = nseqs > 1; // need at least two seqs
- compbio.data.sequence.FastaSequence seq;
- for (int i = 0, n = 0; i < seqs.length; i++)
- {
-
- String newname = jalview.analysis.SeqsetUtils.unique_name(i); // same
- // for
- // any
- // subjob
- SeqNames.put(newname,
- jalview.analysis.SeqsetUtils.SeqCharacterHash(seqs[i]));
- if (valid && seqs[i].getEnd() - seqs[i].getStart() > minlen - 1)
- {
- // make new input sequence with or without gaps
- seq = new compbio.data.sequence.FastaSequence(newname,
- (submitGaps) ? seqs[i].getSequenceAsString()
- : AlignSeq.extractGaps(
- jalview.util.Comparison.GapChars,
- seqs[i].getSequenceAsString()));
- this.seqs.add(seq);
- }
- else
- {
- String empty = null;
- if (seqs[i].getEnd() >= seqs[i].getStart())
- {
- empty = (submitGaps) ? seqs[i].getSequenceAsString()
- : AlignSeq.extractGaps(jalview.util.Comparison.GapChars,
- seqs[i].getSequenceAsString());
- }
- emptySeqs.add(new String[] { newname, empty });
- }
- }
- return valid;
- }
-
- /**
- *
- * @return true if getAlignment will return a valid alignment result.
- */
- @Override
- public boolean hasResults()
- {
- if (subjobComplete && isFinished() && (alignment != null
- || (emptySeqs != null && emptySeqs.size() > 0)))
- {
- return true;
- }
- return false;
- }
-
- /**
- *
- * get the alignment including any empty sequences in the original order
- * with original ids. Caller must access the alignment.getMetadata() object
- * to annotate the final result passsed to the user.
- *
- * @return { SequenceI[], AlignmentOrder }
- */
- public Object[] getAlignment()
- {
- // is this a generic subjob or a Jws2 specific Object[] return signature
- if (hasResults())
- {
- SequenceI[] alseqs = null;
- char alseq_gapchar = '-';
- int alseq_l = 0;
- if (alignment.getSequences().size() > 0)
- {
- alseqs = new SequenceI[alignment.getSequences().size()];
- for (compbio.data.sequence.FastaSequence seq : alignment
- .getSequences())
- {
- alseqs[alseq_l++] = new Sequence(seq.getId(),
- seq.getSequence());
- }
- alseq_gapchar = alignment.getMetadata().getGapchar();
-
- }
- // add in the empty seqs.
- if (emptySeqs.size() > 0)
- {
- SequenceI[] t_alseqs = new SequenceI[alseq_l + emptySeqs.size()];
- // get width
- int i, w = 0;
- if (alseq_l > 0)
- {
- for (i = 0, w = alseqs[0].getLength(); i < alseq_l; i++)
- {
- if (w < alseqs[i].getLength())
- {
- w = alseqs[i].getLength();
- }
- t_alseqs[i] = alseqs[i];
- alseqs[i] = null;
- }
- }
- // check that aligned width is at least as wide as emptySeqs width.
- int ow = w, nw = w;
- for (i = 0, w = emptySeqs.size(); i < w; i++)
- {
- String[] es = emptySeqs.get(i);
- if (es != null && es[1] != null)
- {
- int sw = es[1].length();
- if (nw < sw)
- {
- nw = sw;
- }
- }
- }
- // make a gapped string.
- StringBuffer insbuff = new StringBuffer(w);
- for (i = 0; i < nw; i++)
- {
- insbuff.append(alseq_gapchar);
- }
- if (ow < nw)
- {
- for (i = 0; i < alseq_l; i++)
- {
- int sw = t_alseqs[i].getLength();
- if (nw > sw)
- {
- // pad at end
- alseqs[i].setSequence(t_alseqs[i].getSequenceAsString()
- + insbuff.substring(0, sw - nw));
- }
- }
- }
- for (i = 0, w = emptySeqs.size(); i < w; i++)
- {
- String[] es = emptySeqs.get(i);
- if (es[1] == null)
- {
- t_alseqs[i + alseq_l] = new jalview.datamodel.Sequence(es[0],
- insbuff.toString(), 1, 0);
- }
- else
- {
- if (es[1].length() < nw)
- {
- t_alseqs[i + alseq_l] = new jalview.datamodel.Sequence(
- es[0],
- es[1] + insbuff.substring(0, nw - es[1].length()),
- 1, 1 + es[1].length());
- }
- else
- {
- t_alseqs[i + alseq_l] = new jalview.datamodel.Sequence(
- es[0], es[1]);
- }
- }
- }
- alseqs = t_alseqs;
- }
- AlignmentOrder msaorder = new AlignmentOrder(alseqs);
- // always recover the order - makes parseResult()'s life easier.
- jalview.analysis.AlignmentSorter.recoverOrder(alseqs);
- // account for any missing sequences
- jalview.analysis.SeqsetUtils.deuniquify(SeqNames, alseqs);
- return new Object[] { alseqs, msaorder };
- }
- return null;
- }
-
- /**
- * mark subjob as cancelled and set result object appropriatly
- */
- void cancel()
- {
- cancelled = true;
- subjobComplete = true;
- alignment = null;
- }
-
- /**
- *
- * @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
- // sequence alignment.
- if (seqs != null && seqs.size() >= 2) // two or more sequences is valid ?
- {
- return true;
- }
- return false;
- }
-
- StringBuffer jobProgress = new StringBuffer();
-
- public void setStatus(String string)
- {
- jobProgress.setLength(0);
- jobProgress.append(string);
- }
-
- @Override
- public String getStatus()
- {
- return jobProgress.toString();
- }
-
- @Override
- public boolean hasStatus()
- {
- return jobProgress != null;
- }
-
- /**
- * @return the lastChunk
- */
- public long getLastChunk()
- {
- return lastChunk;
- }
-
- /**
- * @param lastChunk
- * the lastChunk to set
- */
- public void setLastChunk(long lastChunk)
- {
- this.lastChunk = lastChunk;
- }
-
- String alignmentProgram = null;
-
- public String getAlignmentProgram()
- {
- return alignmentProgram;
- }
-
- public boolean hasArguments()
- {
- return (arguments != null && arguments.size() > 0)
- || (preset != null && preset instanceof JabaWsParamSet);
- }
-
- public List<Argument> getJabaArguments()
- {
- List<Argument> newargs = new ArrayList<Argument>();
- if (preset != null && preset instanceof JabaWsParamSet)
- {
- newargs.addAll(((JabaWsParamSet) preset).getjabaArguments());
- }
- if (arguments != null && arguments.size() > 0)
- {
- newargs.addAll(arguments);
- }
- return newargs;
- }
-
- /**
- * add a progess header to status string containing presets/args used
- */
- public void addInitialStatus()
- {
- if (preset != null)
- {
- jobProgress.append("Using "
- + (preset instanceof JabaPreset ? "Server" : "User")
- + "Preset: " + preset.getName());
- if (preset instanceof JabaWsParamSet)
- {
- for (Argument opt : ((JabaWsParamSet) preset).getjabaArguments())
- {
- jobProgress.append(
- opt.getName() + " " + opt.getDefaultValue() + "\n");
- }
- }
- }
- if (arguments != null && arguments.size() > 0)
- {
- jobProgress.append("With custom parameters : \n");
- // merge arguments with preset's own arguments.
- for (Argument opt : arguments)
- {
- jobProgress.append(
- opt.getName() + " " + opt.getDefaultValue() + "\n");
- }
- }
- jobProgress.append("\nJob Output:\n");
- }
-
- public boolean isPresetJob()
- {
- return preset != null && preset instanceof JabaPreset;
- }
-
- public Preset getServerPreset()
- {
- return (isPresetJob()) ? ((JabaPreset) preset).p : null;
- }
- }
-
String alTitle; // name which will be used to form new alignment window.
AlignmentI dataset; // dataset to which the new alignment will be
// associated.
- @SuppressWarnings("unchecked")
- MsaWS server = null;
+ MultipleSequenceAlignmentI server = null;
/**
* set basic options for this (group) of Msa jobs
* @param presorder
* boolean
*/
- private MsaWSThread(MsaWS server, String wsUrl, WebserviceInfo wsinfo,
+ private MsaWSThread(MultipleSequenceAlignmentI server, String wsUrl,
+ WebserviceInfo wsinfo,
jalview.gui.AlignFrame alFrame, AlignmentView alview,
String wsname, boolean subgaps, boolean presorder)
{
}
/**
- * create one or more Msa jobs to align visible seuqences in _msa
+ * create one or more Msa jobs to align visible sequences in _msa
*
* @param title
* String
* @param seqset
* Alignment
*/
- MsaWSThread(MsaWS server2, WsParamSetI preset, List<Argument> paramset,
+ public MsaWSThread(MultipleSequenceAlignmentI server2, WsParamSetI preset,
+ List<ArgumentI> paramset,
String wsUrl, WebserviceInfo wsinfo,
jalview.gui.AlignFrame alFrame, String wsname, String title,
AlignmentView _msa, boolean subgaps, boolean presorder,
if (conmsa != null)
{
int nvalid = 0, njobs = conmsa.length;
- jobs = new MsaWSJob[njobs];
+ jobs = new AWsJob[njobs];
for (int j = 0; j < njobs; j++)
{
if (j != 0)
{
- jobs[j] = new MsaWSJob(wsinfo.addJobPane(), conmsa[j]);
+ jobs[j] = new MsaWSJob(this, wsinfo.addJobPane(), conmsa[j]);
}
else
{
- jobs[j] = new MsaWSJob(0, conmsa[j]);
+ jobs[j] = new MsaWSJob(this, 0, conmsa[j]);
}
- if (((MsaWSJob) jobs[j]).hasValidInput())
+ if (jobs[j].hasValidInput())
{
nvalid++;
}
- ((MsaWSJob) jobs[j]).preset = preset;
- ((MsaWSJob) jobs[j]).arguments = paramset;
+ jobs[j].setPreset(preset);
+ jobs[j].setArguments(paramset);
((MsaWSJob) jobs[j]).alignmentProgram = wsname;
if (njobs > 0)
{
@Override
public boolean isCancellable()
{
- return true;
+ return server instanceof CancellableI;
}
@Override
public void cancelJob()
{
+ // TODO decide if when some jobs are not cancellable to shut down the thread
+ // anyhow ?
if (!jobComplete && jobs != null)
{
boolean cancelled = true;
String cancelledMessage = "";
try
{
- boolean cancelledJob = server.cancelJob(jobs[job].getJobId());
- if (true) // cancelledJob || true)
+ CancellableI service = (CancellableI) server;
+ boolean cancelledJob = service.cancel((WsJob) jobs[job]);
+ if (cancelledJob)
{
// CANCELLED_JOB
- // if the Jaba server indicates the job can't be cancelled, its
- // because its running on the server's local execution engine
- // so we just close the window anyway.
cancelledMessage = "Job cancelled.";
((MsaWSJob) jobs[job]).cancel(); // TODO: refactor to avoid this
// ugliness -
// this is standard code, but since the interface doesn't comprise of a
// basic one that implements (getJobStatus, pullExecStatistics) we have to
// repeat the code for all jw2s services.
- j.setjobStatus(server.getJobStatus(job.getJobId()));
- updateJobProgress(j);
- }
-
- /**
- *
- * @param j
- * @return true if more job progress data was available
- * @throws Exception
- */
- protected boolean updateJobProgress(MsaWSJob j) throws Exception
- {
- StringBuffer response = j.jobProgress;
- long lastchunk = j.getLastChunk();
- boolean changed = false;
- do
- {
- j.setLastChunk(lastchunk);
- ChunkHolder chunk = server.pullExecStatistics(j.getJobId(),
- lastchunk);
- if (chunk != null)
- {
- changed |= chunk.getChunk().length() > 0;
- response.append(chunk.getChunk());
- lastchunk = chunk.getNextPosition();
- try
- {
- Thread.sleep(50);
- } catch (InterruptedException x)
- {
- }
- ;
- }
- ;
- } while (lastchunk >= 0 && j.getLastChunk() != lastchunk);
- return changed;
+ server.updateStatus(j);
+ server.updateJobProgress(j);
}
@Override
if (j.seqs == null || j.seqs.size() == 0)
{
// special case - selection consisted entirely of empty sequences...
- j.setjobStatus(JobStatus.FINISHED);
+ j.setState(JobState.FINISHED);
j.setStatus(MessageManager.getString("label.empty_alignment_job"));
}
try
{
j.addInitialStatus(); // list the presets/parameters used for the job in
// status
- if (j.isPresetJob())
+ try
{
- j.setJobId(server.presetAlign(j.seqs, j.getServerPreset()));
- }
- else if (j.hasArguments())
- {
- j.setJobId(server.customAlign(j.seqs, j.getJabaArguments()));
- }
- else
+ JobId jobHandle = server.align(j.seqs, j.getPreset(),
+ j.getArguments());
+ if (jobHandle != null)
+ {
+ j.setJobHandle(jobHandle);
+ }
+
+ } catch (Throwable throwable)
{
- j.setJobId(server.align(j.seqs));
+ if (!server.handleSubmitError(throwable, j, wsInfo))
+ {
+ if (throwable instanceof Exception)
+ {
+ throw ((Exception) throwable);
+ }
+ if (throwable instanceof Error)
+ {
+ throw ((Error) throwable);
+ }
+ }
}
-
+ ///// generic
if (j.getJobId() != null)
{
j.setSubmitted(true);
new String[]
{ WsUrl }));
}
- } catch (compbio.metadata.UnsupportedRuntimeException _lex)
- {
- lex = _lex;
- wsInfo.appendProgressText(MessageManager.formatMessage(
- "info.job_couldnt_be_run_server_doesnt_support_program",
- new String[]
- { _lex.getMessage() }));
- wsInfo.warnUser(_lex.getMessage(),
- MessageManager.getString("warn.service_not_supported"));
- wsInfo.setStatus(WebserviceInfo.STATE_STOPPED_SERVERERROR);
- wsInfo.setStatus(j.getJobnum(),
- WebserviceInfo.STATE_STOPPED_SERVERERROR);
- } catch (compbio.metadata.LimitExceededException _lex)
- {
- lex = _lex;
- wsInfo.appendProgressText(MessageManager.formatMessage(
- "info.job_couldnt_be_run_exceeded_hard_limit", new String[]
- { _lex.getMessage() }));
- wsInfo.warnUser(_lex.getMessage(),
- MessageManager.getString("warn.input_is_too_big"));
- wsInfo.setStatus(WebserviceInfo.STATE_STOPPED_ERROR);
- wsInfo.setStatus(j.getJobnum(), WebserviceInfo.STATE_STOPPED_ERROR);
- } catch (compbio.metadata.WrongParameterException _lex)
- {
- lex = _lex;
- wsInfo.warnUser(_lex.getMessage(),
- MessageManager.getString("warn.invalid_job_param_set"));
- wsInfo.appendProgressText(MessageManager.formatMessage(
- "info.job_couldnt_be_run_incorrect_param_setting",
- new String[]
- { _lex.getMessage() }));
- wsInfo.setStatus(WebserviceInfo.STATE_STOPPED_ERROR);
- wsInfo.setStatus(j.getJobnum(), WebserviceInfo.STATE_STOPPED_ERROR);
- } catch (Error e)
+ }
+ //// jabaws specific
+
+ //// generic
+ catch (Error e)
{
// For unexpected errors
System.err.println(WebServiceName
{
try
{
- jpchanged = updateJobProgress(msjob);
+ jpchanged = server.updateJobProgress(msjob);
jpex = false;
if (jpchanged)
{
System.out.println("*** End of status");
}
+ ///// jabaws specific(ish) Get Result from Server when available
try
{
- msjob.alignment = server.getResult(msjob.getJobId());
- } catch (compbio.metadata.ResultNotAvailableException e)
- {
- // job has failed for some reason - probably due to invalid
- // parameters
- Cache.log.debug(
- "Results not available for finished job - marking as broken job.",
- e);
- msjob.jobProgress.append(
- "\nResult not available. Probably due to invalid input or parameter settings. Server error message below:\n\n"
- + e.getLocalizedMessage());
- msjob.setjobStatus(JobStatus.FAILED);
+ msjob.alignment = server.getAlignmentFor(msjob.getJobHandle());
} catch (Exception e)
{
- Cache.log.error("Couldn't get Alignment for job.", e);
- // TODO: Increment count and retry ?
- msjob.setjobStatus(JobStatus.UNDEFINED);
+ if (!server.handleCollectionException(e, msjob, wsInfo))
+ {
+ Cache.log.error("Couldn't get Alignment for job.", e);
+ // TODO: Increment count and retry ?
+ msjob.setState(JobState.SERVERERROR);
+ }
}
}
finalState.updateJobPanelState(wsInfo, OutputHeader, jobs[j]);
&& jobs[j].hasResults())
{
results++;
- compbio.data.sequence.Alignment alignment = ((MsaWSJob) jobs[j]).alignment;
- if (alignment != null)
- {
- // server.close(jobs[j].getJobnum());
- // wsInfo.appendProgressText(jobs[j].getJobnum(),
- // "\nAlignment Object Method Notes\n");
- // wsInfo.appendProgressText(jobs[j].getJobnum(),
- // "Calculated with
- // "+alignment.getMetadata().getProgram().toString());
- // JBPNote The returned files from a webservice could be
- // hidden behind icons in the monitor window that,
- // when clicked, pop up their corresponding data
- }
}
}
} catch (Exception ex)
void displayResults(boolean newFrame)
{
// view input or result data for each block
- List<AlignmentOrder> alorders = new ArrayList<AlignmentOrder>();
+ List<AlignmentOrder> alorders = new ArrayList<>();
SequenceI[][] results = new SequenceI[jobs.length][];
AlignmentOrder[] orders = new AlignmentOrder[jobs.length];
String lastProgram = null;
if (newFrame)
{
displayInNewFrame(al, alorders, hidden);
-
}
else
{
else
{
// construct a non-redundant ordering set
- List<String> names = new ArrayList<String>();
+ List<String> names = new ArrayList<>();
for (int i = 0, l = alorders.size(); i < l; i++)
{
String orderName = " Region " + i;
--- /dev/null
+/**
+ *
+ */
+package jalview.ws.gui;
+
+import jalview.ws.AWsJob;
+import jalview.ws.api.JobId;
+
+/**
+ * Bean that holds state for a job
+ *
+ * @author jprocter
+ *
+ */
+public class WsJob extends AWsJob
+{
+
+ public enum JobState
+ {
+ INVALID, READY, SUBMITTED, QUEUED, RUNNING, FINISHED, BROKEN, FAILED,
+ UNKNOWN, SERVERERROR, CANCELLED;
+ };
+
+ JobState state = JobState.UNKNOWN;
+
+ boolean hasResults = false, validInput = false;
+ /* (non-Javadoc)
+ * @see jalview.ws.AWsJob#hasResults()
+ */
+ @Override
+ public boolean hasResults()
+ {
+ return hasResults;
+ }
+
+ /* (non-Javadoc)
+ * @see jalview.ws.AWsJob#hasValidInput()
+ */
+ @Override
+ public boolean hasValidInput()
+ {
+ return validInput;
+ }
+
+ /* (non-Javadoc)
+ * @see jalview.ws.AWsJob#isRunning()
+ */
+ @Override
+ public boolean isRunning()
+ {
+ return JobState.RUNNING.equals(state);
+ }
+
+ /* (non-Javadoc)
+ * @see jalview.ws.AWsJob#isQueued()
+ */
+ @Override
+ public boolean isQueued()
+ {
+ return JobState.QUEUED.equals(state);
+ }
+
+ /* (non-Javadoc)
+ * @see jalview.ws.AWsJob#isFinished()
+ */
+ @Override
+ public boolean isFinished()
+ {
+ // TODO isSubjobComplete and finished flags mean same thing ?
+ return JobState.FINISHED.equals(state);
+ }
+
+ /* (non-Javadoc)
+ * @see jalview.ws.AWsJob#isFailed()
+ */
+ @Override
+ public boolean isFailed()
+ {
+ return JobState.FAILED.equals(state);
+ }
+
+ /* (non-Javadoc)
+ * @see jalview.ws.AWsJob#isBroken()
+ */
+ @Override
+ public boolean isBroken()
+ {
+ return JobState.BROKEN.equals(state);
+ }
+
+ /* (non-Javadoc)
+ * @see jalview.ws.AWsJob#isServerError()
+ */
+ @Override
+ public boolean isServerError()
+ {
+ return JobState.SERVERERROR.equals(state);
+ }
+
+ /* (non-Javadoc)
+ * @see jalview.ws.AWsJob#hasStatus()
+ */
+ @Override
+ public boolean hasStatus()
+ {
+ return status != null && status.length() > 0;
+ }
+
+ /* (non-Javadoc)
+ * @see jalview.ws.AWsJob#getStatus()
+ */
+ @Override
+ public String getStatus()
+ {
+ return status;
+ }
+
+ /* (non-Javadoc)
+ * @see jalview.ws.AWsJob#hasResponse()
+ */
+ @Override
+ public boolean hasResponse()
+ {
+ // TODO Auto-generated method stub
+ return hasStatus();
+ }
+
+ /* (non-Javadoc)
+ * @see jalview.ws.AWsJob#clearResponse()
+ */
+ @Override
+ public void clearResponse()
+ {
+ status = "";
+ }
+
+ /* (non-Javadoc)
+ * @see jalview.ws.AWsJob#getState()
+ */
+ @Override
+ public String getState()
+ {
+ return state.toString();
+ }
+
+ /**
+ * @return the current JobState
+ */
+ public JobState getJobState()
+ {
+ return state;
+ }
+
+ /**
+ * set the job state
+ *
+ * @param state
+ */
+ public void setState(JobState state)
+ {
+ this.state = state;
+ }
+
+ String status = "";
+
+ /**
+ * Set the log for this job
+ *
+ * @parag log
+ */
+ public void setStatus(String log)
+ {
+ status = log;
+
+ }
+
+ /*
+ * bean holding submission info for a next-gen ws job
+ */
+ JobId jobHandle = null;
+
+ /**
+ * stash the handle for the job and mark it as submitted
+ *
+ * @param align
+ */
+ public void setJobHandle(JobId align)
+ {
+ jobHandle = align;
+ setJobId(jobHandle.getJobId());
+ submitted = true;
+
+ }
+
+ public JobId getJobHandle()
+ {
+ return jobHandle;
+ }
+
+}
import java.util.List;
import org.apache.james.mime4j.MimeException;
-import org.apache.james.mime4j.descriptor.BodyDescriptor;
import org.apache.james.mime4j.parser.ContentHandler;
-import org.apache.james.mime4j.parser.Field;
+import org.apache.james.mime4j.stream.BodyDescriptor;
+import org.apache.james.mime4j.stream.Field;
/**
* ContentHandler for parsing mime encoded messages into Jalview objects. TODO:
/**
* sources for data to be parsed
*/
- List<DataProvider> dataItems = new ArrayList<DataProvider>();
+ List<DataProvider> dataItems = new ArrayList<>();
@Override
public void body(BodyDescriptor arg0, InputStream arg1)
// TODO Auto-generated method stub
return null;
}
-
}
*/
package jalview.ws.jws1;
-import jalview.gui.JvOptionPane;
-import jalview.util.MessageManager;
-
import java.net.URL;
import java.util.Hashtable;
import java.util.StringTokenizer;
import ext.vamsas.RegistryServiceSoapBindingStub;
import ext.vamsas.ServiceHandle;
import ext.vamsas.ServiceHandles;
+import jalview.bin.Cache;
+import jalview.bin.ApplicationSingletonProvider;
+import jalview.bin.ApplicationSingletonProvider.ApplicationSingletonI;
+import jalview.gui.JvOptionPane;
+import jalview.util.MessageManager;
-public class Discoverer implements Runnable
+public class Discoverer implements Runnable, ApplicationSingletonI
{
+
+ public static Discoverer getInstance()
+ {
+ return (Discoverer) ApplicationSingletonProvider.getInstance(Discoverer.class);
+ }
+
+ private Discoverer()
+ {
+ // use getInstance()
+ }
+
ext.vamsas.IRegistry registry; // the root registry service.
private java.beans.PropertyChangeSupport changeSupport = new java.beans.PropertyChangeSupport(
return server;
}
- static private java.net.URL RootServiceURL = null;
+ private java.net.URL RootServiceURL = null;
- static public Vector<URL> ServiceURLList = null;
+ private Vector<URL> ServiceURLList = null;
- static private boolean reallyDiscoverServices = true;
+ public Vector<URL> getServiceURLList() {
+ return ServiceURLList;
+ }
+
+ private boolean reallyDiscoverServices = true;
- public static java.util.Hashtable<String, Vector<ServiceHandle>> services = null;
+ private java.util.Hashtable<String, Vector<ServiceHandle>> services = null;
// stored by
// abstractServiceType
// string
- public static java.util.Vector<ServiceHandle> serviceList = null;
+ public java.util.Vector<ServiceHandle> serviceList = null;
- static private Vector<URL> getDiscoveryURLS()
+ private Vector<URL> getDiscoveryURLS()
{
Vector<URL> urls = new Vector<>();
String RootServiceURLs = jalview.bin.Cache.getDefault("DISCOVERY_URLS",
*/
static public void doDiscovery()
{
+ getInstance().discovery();
+ }
+
+ private void discovery()
+ {
jalview.bin.Cache.log
.debug("(Re)-Initialising the discovery URL list.");
try
{
+ Discoverer d = getInstance();
reallyDiscoverServices = jalview.bin.Cache
.getDefault("DISCOVERY_START", false);
if (reallyDiscoverServices)
// JBPNote - should do this a better way!
if (f.getFaultReason().indexOf("(407)") > -1)
{
- if (jalview.gui.Desktop.desktop != null)
+ if (jalview.gui.Desktop.getDesktopPane() != null)
{
- JvOptionPane.showMessageDialog(jalview.gui.Desktop.desktop,
+ JvOptionPane.showMessageDialog(jalview.gui.Desktop.getDesktopPane(),
MessageManager.getString("label.set_proxy_settings"),
MessageManager
.getString("label.proxy_authorization_failed"),
* Hashtable
* @return boolean
*/
- static private boolean buildServiceLists(ServiceHandle[] sh,
+ private boolean buildServiceLists(ServiceHandle[] sh,
Vector<ServiceHandle> cat,
Hashtable<String, Vector<ServiceHandle>> sscat)
{
@Override
public void run()
{
- final Discoverer discoverer = this;
- Thread discoverThread = new Thread()
- {
- @Override
- public void run()
- {
- Discoverer.doDiscovery();
- discoverer.discoverServices();
- }
- };
- discoverThread.start();
+ Cache.log.info("Discovering jws1 services");
+ Discoverer.doDiscovery();
+ discoverServices();
}
/**
* binding service abstract name to handler class
*/
- private static Hashtable<String, WS1Client> serviceClientBindings;
+ private Hashtable<String, WS1Client> serviceClientBindings;
public static WS1Client getServiceClient(ServiceHandle sh)
{
+ return getInstance().getClient(sh);
+ }
+
+ /**
+ * notes on discovery service 1. need to allow multiple discovery source urls.
+ * 2. user interface to add/control list of urls in preferences notes on
+ * wsclient discovery 1. need a classpath property with list of additional
+ * plugin directories 2. optional config to cite specific bindings between
+ * class name and Abstract service name. 3. precedence for automatic discovery
+ * by using getAbstractName for WSClient - user added plugins override default
+ * plugins ? notes on wsclient gui code for gui attachment now moved to
+ * wsclient implementation. Needs more abstraction but approach seems to work.
+ * is it possible to 'generalise' the data retrieval calls further ? current
+ * methods are very specific (gatherForMSA or gatherForSeqOrMsaSecStrPred),
+ * new methods for conservation (group or alignment), treecalc (aligned
+ * profile), seqannot (sequences selected from dataset, annotation back to
+ * dataset).
+ *
+ */
+
+ private WS1Client getClient(ServiceHandle sh)
+ {
if (serviceClientBindings == null)
{
// get a list from Config or create below
}
return instance;
}
- /**
- * notes on discovery service 1. need to allow multiple discovery source urls.
- * 2. user interface to add/control list of urls in preferences notes on
- * wsclient discovery 1. need a classpath property with list of additional
- * plugin directories 2. optional config to cite specific bindings between
- * class name and Abstract service name. 3. precedence for automatic discovery
- * by using getAbstractName for WSClient - user added plugins override default
- * plugins ? notes on wsclient gui code for gui attachment now moved to
- * wsclient implementation. Needs more abstraction but approach seems to work.
- * is it possible to 'generalise' the data retrieval calls further ? current
- * methods are very specific (gatherForMSA or gatherForSeqOrMsaSecStrPred),
- * new methods for conservation (group or alignment), treecalc (aligned
- * profile), seqannot (sequences selected from dataset, annotation back to
- * dataset).
- *
- */
+
+ public static Hashtable<String, Vector<ServiceHandle>> getServices()
+ {
+ return getInstance().services;
+ }
}
WsURL = "http://www.compbio.dundee.ac.uk/JalviewWS/services/jpred";
WebserviceInfo wsInfo = new WebserviceInfo(WebServiceJobTitle,
- WebServiceReference, true);
+ WebServiceReference, Desktop.FRAME_MAKE_VISIBLE);
return wsInfo;
}
} catch (Exception ex)
{
- JvOptionPane.showMessageDialog(Desktop.desktop,
+ JvOptionPane.showMessageDialog(Desktop.getDesktopPane(),
MessageManager.formatMessage(
"label.secondary_structure_prediction_service_couldnt_be_located",
new String[]
*/
ext.vamsas.MuscleWS server;
- AlignFrame alignFrame;
-
/**
* Creates a new MsaWSClient object that uses a service given by an externally
* retrieved ServiceHandle
alignFrame = _alignFrame;
if (!sh.getAbstractName().equals("MsaWS"))
{
- JvOptionPane.showMessageDialog(Desktop.desktop,
+ JvOptionPane.showMessageDialog(Desktop.getDesktopPane(),
MessageManager.formatMessage(
"label.service_called_is_not_msa_service",
new String[]
if ((wsInfo = setWebService(sh)) == null)
{
- JvOptionPane.showMessageDialog(Desktop.desktop, MessageManager
+ JvOptionPane.showMessageDialog(Desktop.getDesktopPane(), MessageManager
.formatMessage("label.msa_service_is_unknown", new String[]
{ sh.getName() }),
MessageManager.getString("label.internal_jalview_error"),
import jalview.ws.JobStateSummary;
import jalview.ws.WSClientI;
-import java.util.Hashtable;
import java.util.Vector;
import vamsas.objects.simple.MsaResult;
}
- Hashtable SeqNames = new Hashtable();
-
Vector emptySeqs = new Vector();
/**
*/
ext.vamsas.SeqSearchI server;
- AlignFrame alignFrame;
-
/**
* Creates a new MsaWSClient object that uses a service given by an externally
* retrieved ServiceHandle
// name to service client name
if (!sh.getAbstractName().equals(this.getServiceActionKey()))
{
- JvOptionPane.showMessageDialog(Desktop.desktop,
+ JvOptionPane.showMessageDialog(Desktop.getDesktopPane(),
MessageManager.formatMessage(
"label.service_called_is_not_seq_search_service",
new String[]
if ((wsInfo = setWebService(sh)) == null)
{
- JvOptionPane.showMessageDialog(Desktop.desktop,
+ JvOptionPane.showMessageDialog(Desktop.getDesktopPane(),
MessageManager.formatMessage(
"label.seq_search_service_is_unknown", new String[]
{ sh.getName() }),
import jalview.ws.WSClientI;
import java.util.HashMap;
-import java.util.Hashtable;
import java.util.Map;
import java.util.Vector;
}
- Hashtable SeqNames = new Hashtable();
-
Vector emptySeqs = new Vector();
/**
package jalview.ws.jws1;
import jalview.gui.AlignFrame;
+import jalview.gui.Desktop;
import jalview.gui.WebserviceInfo;
import jalview.util.MessageManager;
import jalview.ws.WSClient;
WebserviceInfo wsInfo = null;
if (!headless)
{
- wsInfo = new WebserviceInfo(WebServiceJobTitle, WebServiceReference,
- true);
+ wsInfo = new WebserviceInfo(WebServiceJobTitle, WebServiceReference,
+ Desktop.FRAME_MAKE_VISIBLE);
}
return wsInfo;
}
+++ /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.jws2;
-
-import jalview.datamodel.AlignmentAnnotation;
-import jalview.gui.AlignFrame;
-import jalview.util.MessageManager;
-import jalview.ws.jws2.jabaws2.Jws2Instance;
-import jalview.ws.params.WsParamSetI;
-import jalview.ws.uimodel.AlignAnalysisUIText;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.TreeSet;
-
-import compbio.data.sequence.FastaSequence;
-import compbio.data.sequence.Score;
-import compbio.metadata.Argument;
-
-public class AAConClient extends JabawsCalcWorker
-{
-
- public AAConClient(Jws2Instance service, AlignFrame alignFrame,
- WsParamSetI preset, List<Argument> paramset)
- {
- super(service, alignFrame, preset, paramset);
- submitGaps = true;
- alignedSeqs = true;
- nucleotidesAllowed = false;
- proteinAllowed = true;
- filterNonStandardResidues = true;
- gapMap = new boolean[0];
- initViewportParams();
- }
-
- @Override
- public String getServiceActionText()
- {
- return "calculating Amino acid consensus using AACon service";
- }
-
- /**
- * update the consensus annotation from the sequence profile data using
- * current visualization settings.
- */
-
- @Override
- public void updateResultAnnotation(boolean immediate)
- {
- if (immediate || !calcMan.isWorking(this) && scoremanager != null)
- {
- Map<String, TreeSet<Score>> scoremap = scoremanager.asMap();
- int alWidth = alignViewport.getAlignment().getWidth();
- ArrayList<AlignmentAnnotation> ourAnnot = new ArrayList<>();
- for (String score : scoremap.keySet())
- {
- Set<Score> scores = scoremap.get(score);
- for (Score scr : scores)
- {
- if (scr.getRanges() != null && scr.getRanges().size() > 0)
- {
- /**
- * annotation in range annotation = findOrCreate(scr.getMethod(),
- * true, null, null); Annotation[] elm = new Annotation[alWidth];
- * Iterator<Float> vals = scr.getScores().iterator(); for (Range rng
- * : scr.getRanges()) { float val = vals.next().floatValue(); for
- * (int i = rng.from; i <= rng.to; i++) { elm[i] = new
- * Annotation("", "", ' ', val); } } annotation.annotations = elm;
- * annotation.validateRangeAndDisplay();
- */
- }
- else
- {
- createAnnotationRowsForScores(ourAnnot, getCalcId(), alWidth,
- scr);
- }
- }
- }
-
- if (ourAnnot.size() > 0)
- {
- updateOurAnnots(ourAnnot);
- }
- }
- }
-
- @Override
- boolean checkValidInputSeqs(boolean dynamic, List<FastaSequence> seqs)
- {
- return (seqs.size() > 1);
- }
-
- @Override
- public String getCalcId()
- {
- return CALC_ID;
- }
-
- private static String CALC_ID = "jabaws2.AACon";
-
- public static AlignAnalysisUIText getAlignAnalysisUITest()
- {
- return new AlignAnalysisUIText(
- compbio.ws.client.Services.AAConWS.toString(),
- jalview.ws.jws2.AAConClient.class, CALC_ID, false, true, true,
- MessageManager.getString("label.aacon_calculations"),
- MessageManager.getString("tooltip.aacon_calculations"),
- MessageManager.getString("label.aacon_settings"),
- MessageManager.getString("tooltip.aacon_settings"));
- }
-}
+++ /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.jws2;
-
-import jalview.api.FeatureColourI;
-import jalview.bin.Cache;
-import jalview.datamodel.AlignmentAnnotation;
-import jalview.datamodel.GraphLine;
-import jalview.datamodel.SequenceFeature;
-import jalview.datamodel.SequenceI;
-import jalview.gui.AlignFrame;
-import jalview.schemes.FeatureColour;
-import jalview.util.ColorUtils;
-import jalview.ws.jws2.jabaws2.Jws2Instance;
-import jalview.ws.params.WsParamSetI;
-
-import java.awt.Color;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Hashtable;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-import compbio.data.sequence.FastaSequence;
-import compbio.data.sequence.Range;
-import compbio.data.sequence.Score;
-import compbio.data.sequence.ScoreManager.ScoreHolder;
-import compbio.metadata.Argument;
-
-public class AADisorderClient extends JabawsCalcWorker
-{
-
- private static final String THRESHOLD = "THRESHOLD";
-
- private static final String RANGE = "RANGE";
-
- String typeName;
-
- String methodName;
-
- String groupName;
-
- AlignFrame af;
-
- public AADisorderClient(Jws2Instance sh, AlignFrame alignFrame,
- WsParamSetI thePreset, List<Argument> paramset)
- {
- super(sh, alignFrame, thePreset, paramset);
- af = alignFrame;
- typeName = sh.action;
- methodName = sh.serviceType;
-
- submitGaps = false;
- alignedSeqs = false;
- nucleotidesAllowed = false;
- proteinAllowed = true;
- bySequence = true;
- }
-
- @Override
- public String getServiceActionText()
- {
- return "Submitting amino acid sequences for disorder prediction.";
- }
-
- @Override
- boolean checkValidInputSeqs(boolean dynamic, List<FastaSequence> seqs)
- {
- return (seqs.size() > 0);
- }
-
- private static Map<String, Map<String, String[]>> featureMap;
-
- private static Map<String, Map<String, Map<String, Object>>> annotMap;
-
- private static String DONTCOMBINE = "DONTCOMBINE";
-
- private static String INVISIBLE = "INVISIBLE";
- static
- {
- // TODO: turn this into some kind of configuration file that's a bit easier
- // to edit
- featureMap = new HashMap<>();
- Map<String, String[]> fmap;
- featureMap.put(compbio.ws.client.Services.IUPredWS.toString(),
- fmap = new HashMap<>());
- fmap.put("Glob",
- new String[]
- { "Globular Domain", "Predicted globular domain" });
- featureMap.put(compbio.ws.client.Services.JronnWS.toString(),
- fmap = new HashMap<>());
- featureMap.put(compbio.ws.client.Services.DisemblWS.toString(),
- fmap = new HashMap<>());
- fmap.put("REM465", new String[] { "REM465", "Missing density" });
- fmap.put("HOTLOOPS", new String[] { "HOTLOOPS", "Flexible loops" });
- fmap.put("COILS", new String[] { "COILS", "Random coil" });
- featureMap.put(compbio.ws.client.Services.GlobPlotWS.toString(),
- fmap = new HashMap<>());
- fmap.put("GlobDoms",
- new String[]
- { "Globular Domain", "Predicted globular domain" });
- fmap.put("Disorder",
- new String[]
- { "Protein Disorder", "Probable unstructured peptide region" });
- Map<String, Map<String, Object>> amap;
- annotMap = new HashMap<>();
- annotMap.put(compbio.ws.client.Services.GlobPlotWS.toString(),
- amap = new HashMap<>());
- amap.put("Dydx", new HashMap<String, Object>());
- amap.get("Dydx").put(DONTCOMBINE, DONTCOMBINE);
- amap.get("Dydx").put(THRESHOLD, new double[] { 1, 0 });
- amap.get("Dydx").put(RANGE, new float[] { -1, +1 });
-
- amap.put("SmoothedScore", new HashMap<String, Object>());
- amap.get("SmoothedScore").put(INVISIBLE, INVISIBLE);
- amap.put("RawScore", new HashMap<String, Object>());
- amap.get("RawScore").put(INVISIBLE, INVISIBLE);
- annotMap.put(compbio.ws.client.Services.DisemblWS.toString(),
- amap = new HashMap<>());
- amap.put("COILS", new HashMap<String, Object>());
- amap.put("HOTLOOPS", new HashMap<String, Object>());
- amap.put("REM465", new HashMap<String, Object>());
- amap.get("COILS").put(THRESHOLD, new double[] { 1, 0.516 });
- amap.get("COILS").put(RANGE, new float[] { 0, 1 });
-
- amap.get("HOTLOOPS").put(THRESHOLD, new double[] { 1, 0.6 });
- amap.get("HOTLOOPS").put(RANGE, new float[] { 0, 1 });
- amap.get("REM465").put(THRESHOLD, new double[] { 1, 0.1204 });
- amap.get("REM465").put(RANGE, new float[] { 0, 1 });
-
- annotMap.put(compbio.ws.client.Services.IUPredWS.toString(),
- amap = new HashMap<>());
- amap.put("Long", new HashMap<String, Object>());
- amap.put("Short", new HashMap<String, Object>());
- amap.get("Long").put(THRESHOLD, new double[] { 1, 0.5 });
- amap.get("Long").put(RANGE, new float[] { 0, 1 });
- amap.get("Short").put(THRESHOLD, new double[] { 1, 0.5 });
- amap.get("Short").put(RANGE, new float[] { 0, 1 });
- annotMap.put(compbio.ws.client.Services.JronnWS.toString(),
- amap = new HashMap<>());
- amap.put("JRonn", new HashMap<String, Object>());
- amap.get("JRonn").put(THRESHOLD, new double[] { 1, 0.5 });
- amap.get("JRonn").put(RANGE, new float[] { 0, 1 });
- }
-
- @Override
- public void updateResultAnnotation(boolean immediate)
- {
-
- if (immediate || !calcMan.isWorking(this) && scoremanager != null)
- {
- Map<String, String[]> featureTypeMap = featureMap
- .get(service.serviceType);
- Map<String, Map<String, Object>> annotTypeMap = annotMap
- .get(service.serviceType);
- boolean dispFeatures = false;
- Map<String, Object> fc = new Hashtable<>();
- List<AlignmentAnnotation> ourAnnot = new ArrayList<>();
- /**
- * grouping for any annotation rows created
- */
- int graphGroup = 1;
- if (alignViewport.getAlignment().getAlignmentAnnotation() != null)
- {
- for (AlignmentAnnotation ala : alignViewport.getAlignment()
- .getAlignmentAnnotation())
- {
- if (ala.graphGroup > graphGroup)
- {
- graphGroup = ala.graphGroup;
- }
- }
- }
-
- for (String seqId : seqNames.keySet())
- {
- boolean sameGroup = false;
- SequenceI dseq, aseq, seq = seqNames.get(seqId);
- int base = seq.findPosition(start) - 1;
- aseq = seq;
- while ((dseq = seq).getDatasetSequence() != null)
- {
- seq = seq.getDatasetSequence();
- }
- ScoreHolder scores = null;
- try
- {
- scores = scoremanager.getAnnotationForSequence(seqId);
- } catch (Exception q)
- {
- Cache.log
- .info("Couldn't recover disorder prediction for sequence "
- + seq.getName() + "(Prediction name was " + seqId
- + ")"
- + "\nSee http://issues.jalview.org/browse/JAL-1319 for one possible reason why disorder predictions might fail.");
- }
- float last = Float.NaN, val = Float.NaN;
- int lastAnnot = ourAnnot.size();
- if (scores != null && scores.scores != null)
- {
- for (Score scr : scores.scores)
- {
-
- if (scr.getRanges() != null && scr.getRanges().size() > 0)
- {
- Iterator<Float> vals = scr.getScores().iterator();
- // make features on sequence
- for (Range rn : scr.getRanges())
- {
-
- SequenceFeature sf;
- String[] type = featureTypeMap.get(scr.getMethod());
- if (type == null)
- {
- // create a default type for this feature
- type = new String[] {
- typeName + " (" + scr.getMethod() + ")",
- service.getActionText() };
- }
- if (vals.hasNext())
- {
- val = vals.next().floatValue();
- sf = new SequenceFeature(type[0], type[1],
- base + rn.from, base + rn.to, val, methodName);
- }
- else
- {
- sf = new SequenceFeature(type[0], type[1],
- base + rn.from, base + rn.to, methodName);
- }
- dseq.addSequenceFeature(sf);
- if (last != val && !Float.isNaN(last))
- {
- fc.put(sf.getType(), sf);
- }
- last = val;
- dispFeatures = true;
- }
- }
- else
- {
- if (scr.getScores().size() == 0)
- {
- continue;
- }
- String typename, calcName;
- AlignmentAnnotation annot = createAnnotationRowsForScores(
- ourAnnot,
- typename = service.serviceType + " ("
- + scr.getMethod() + ")",
- calcName = service.getServiceTypeURI() + "/"
- + scr.getMethod(),
- aseq, base + 1, scr);
- annot.graph = AlignmentAnnotation.LINE_GRAPH;
-
- Map<String, Object> styleMap = (annotTypeMap == null) ? null
- : annotTypeMap.get(scr.getMethod());
-
- annot.visible = (styleMap == null
- || styleMap.get(INVISIBLE) == null);
- double[] thrsh = (styleMap == null) ? null
- : (double[]) styleMap.get(THRESHOLD);
- float[] range = (styleMap == null) ? null
- : (float[]) styleMap.get(RANGE);
- if (range != null)
- {
- annot.graphMin = range[0];
- annot.graphMax = range[1];
- }
- if (styleMap == null || styleMap.get(DONTCOMBINE) == null)
- {
- {
- if (!sameGroup)
- {
- graphGroup++;
- sameGroup = true;
- }
-
- annot.graphGroup = graphGroup;
- }
- }
-
- annot.description = "<html>" + service.getActionText()
- + " - raw scores";
- if (thrsh != null)
- {
- String threshNote = (thrsh[0] > 0 ? "Above " : "Below ")
- + thrsh[1] + " indicates disorder";
- annot.threshold = new GraphLine((float) thrsh[1],
- threshNote, Color.red);
- annot.description += "<br/>" + threshNote;
- }
- annot.description += "</html>";
- Color col = ColorUtils
- .createColourFromName(typeName + scr.getMethod());
- for (int p = 0, ps = annot.annotations.length; p < ps; p++)
- {
- if (annot.annotations[p] != null)
- {
- annot.annotations[p].colour = col;
- }
- }
- annot._linecolour = col;
- // finally, update any dataset annotation
- replaceAnnotationOnAlignmentWith(annot, typename, calcName,
- aseq);
- }
- }
- }
- if (lastAnnot + 1 == ourAnnot.size())
- {
- // remove singleton alignment annotation row
- ourAnnot.get(lastAnnot).graphGroup = -1;
- }
- }
- {
- if (dispFeatures)
- {
- jalview.api.FeatureRenderer fr = ((jalview.gui.AlignmentPanel) ap)
- .cloneFeatureRenderer();
- for (String ft : fc.keySet())
- {
- FeatureColourI gc = fr.getFeatureStyle(ft);
- if (gc.isSimpleColour())
- {
- // set graduated color as fading to white for minimum, and
- // autoscaling to values on alignment
- FeatureColourI ggc = new FeatureColour(gc.getColour(),
- Color.white, gc.getColour(), Color.white,
- Float.MIN_VALUE, Float.MAX_VALUE);
- ggc.setAutoScaled(true);
- fr.setColour(ft, ggc);
- }
- }
- // TODO: JAL-1150 - create sequence feature settings API for defining
- // styles and enabling/disabling feature overlay on alignment panel
- ((jalview.gui.AlignmentPanel) ap).updateFeatureRendererFrom(fr);
- if (af.alignPanel == ap)
- {
- // only do this if the alignFrame is currently showing this view.
- af.setShowSeqFeatures(true);
- }
- }
- if (ourAnnot.size() > 0)
- {
- // Modify the visible annotation on the alignment viewport with the
- // new alignment annotation rows created.
- updateOurAnnots(ourAnnot);
- ap.adjustAnnotationHeight();
- ap.paintAlignment(true, true);
- }
- }
- }
- }
-
- @Override
- public String getCalcId()
- {
- // Disorder predictions are not dynamically updated so we return null
- return 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.ws.jws2;
-
-import jalview.analysis.AlignSeq;
-import jalview.analysis.SeqsetUtils;
-import jalview.api.AlignViewportI;
-import jalview.api.AlignmentViewPanel;
-import jalview.datamodel.AlignmentAnnotation;
-import jalview.datamodel.AlignmentI;
-import jalview.datamodel.AnnotatedCollectionI;
-import jalview.datamodel.SequenceI;
-import jalview.gui.AlignFrame;
-import jalview.gui.IProgressIndicator;
-import jalview.gui.IProgressIndicatorHandler;
-import jalview.schemes.ResidueProperties;
-import jalview.workers.AlignCalcWorker;
-import jalview.ws.jws2.dm.AAConSettings;
-import jalview.ws.jws2.dm.JabaWsParamSet;
-import jalview.ws.jws2.jabaws2.Jws2Instance;
-import jalview.ws.params.WsParamSetI;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import compbio.data.sequence.FastaSequence;
-import compbio.metadata.Argument;
-import compbio.metadata.ChunkHolder;
-import compbio.metadata.JobStatus;
-import compbio.metadata.JobSubmissionException;
-import compbio.metadata.Option;
-import compbio.metadata.ResultNotAvailableException;
-
-public abstract class AbstractJabaCalcWorker extends AlignCalcWorker
-{
-
- protected Jws2Instance service;
-
- protected WsParamSetI preset;
-
- protected List<Argument> arguments;
-
- protected IProgressIndicator guiProgress;
-
- protected boolean submitGaps = true;
-
- /**
- * by default, we filter out non-standard residues before submission
- */
- protected boolean filterNonStandardResidues = true;
-
- /**
- * Recover any existing parameters for this service
- */
- protected void initViewportParams()
- {
- if (getCalcId() != null)
- {
- ((jalview.gui.AlignViewport) alignViewport).setCalcIdSettingsFor(
- getCalcId(),
- new AAConSettings(true, service, this.preset,
- (arguments != null)
- ? JabaParamStore.getJwsArgsfromJaba(arguments)
- : null),
- true);
- }
- }
-
- /**
- *
- * @return null or a string used to recover all annotation generated by this
- * worker
- */
- public abstract String getCalcId();
-
- public WsParamSetI getPreset()
- {
- return preset;
- }
-
- public List<Argument> getArguments()
- {
- return arguments;
- }
-
- /**
- * reconfigure and restart the AAConClient. This method will spawn a new
- * thread that will wait until any current jobs are finished, modify the
- * parameters and restart the conservation calculation with the new values.
- *
- * @param newpreset
- * @param newarguments
- */
- public void updateParameters(final WsParamSetI newpreset,
- final List<Argument> newarguments)
- {
- preset = newpreset;
- arguments = newarguments;
- calcMan.startWorker(this);
- initViewportParams();
- }
-
- public List<Option> getJabaArguments()
- {
- List<Option> newargs = new ArrayList<>();
- if (preset != null && preset instanceof JabaWsParamSet)
- {
- newargs.addAll(((JabaWsParamSet) preset).getjabaArguments());
- }
- if (arguments != null && arguments.size() > 0)
- {
- for (Argument rg : arguments)
- {
- if (Option.class.isAssignableFrom(rg.getClass()))
- {
- newargs.add((Option) rg);
- }
- }
- }
- return newargs;
- }
-
- protected boolean alignedSeqs = true;
-
- protected boolean nucleotidesAllowed = false;
-
- protected boolean proteinAllowed = false;
-
- /**
- * record sequences for mapping result back to afterwards
- */
- protected boolean bySequence = false;
-
- protected Map<String, SequenceI> seqNames;
-
- protected boolean[] gapMap;
-
- int realw;
-
- protected int start;
-
- int end;
-
- public AbstractJabaCalcWorker(AlignViewportI alignViewport,
- AlignmentViewPanel alignPanel)
- {
- super(alignViewport, alignPanel);
- }
-
- public AbstractJabaCalcWorker(Jws2Instance service, AlignFrame alignFrame,
- WsParamSetI preset, List<Argument> paramset)
- {
- this(alignFrame.getCurrentView(), alignFrame.alignPanel);
- this.guiProgress = alignFrame;
- this.preset = preset;
- this.arguments = paramset;
- this.service = service;
- }
-
- /**
- *
- * @return true if the submission thread should attempt to submit data
- */
- abstract boolean hasService();
-
- volatile String rslt = "JOB NOT DEFINED";
-
- @Override
- public void run()
- {
- if (!hasService())
- {
- return;
- }
- long progressId = -1;
-
- int serverErrorsLeft = 3;
-
- StringBuffer msg = new StringBuffer();
- try
- {
- if (checkDone())
- {
- return;
- }
- List<compbio.data.sequence.FastaSequence> seqs = getInputSequences(
- alignViewport.getAlignment(),
- bySequence ? alignViewport.getSelectionGroup() : null);
-
- if (seqs == null || !checkValidInputSeqs(true, seqs))
- {
- calcMan.workerComplete(this);
- return;
- }
-
- AlignmentAnnotation[] aa = alignViewport.getAlignment()
- .getAlignmentAnnotation();
- if (guiProgress != null)
- {
- guiProgress.setProgressBar("JABA " + getServiceActionText(),
- progressId = System.currentTimeMillis());
- }
- rslt = submitToService(seqs);
- if (guiProgress != null)
- {
- guiProgress.registerHandler(progressId,
- new IProgressIndicatorHandler()
- {
-
- @Override
- public boolean cancelActivity(long id)
- {
- cancelCurrentJob();
- return true;
- }
-
- @Override
- public boolean canCancel()
- {
- return true;
- }
- });
- }
- boolean finished = false;
- long rpos = 0;
- do
- {
- JobStatus status = getJobStatus(rslt);
- if (status.equals(JobStatus.FINISHED))
- {
- finished = true;
- }
- if (calcMan.isPending(this) && isInteractiveUpdate())
- {
- finished = true;
- // cancel this job and yield to the new job
- try
- {
- if (cancelJob(rslt))
- {
- System.err.println("Cancelled AACon job: " + rslt);
- }
- else
- {
- System.err.println("FAILED TO CANCEL AACon job: " + rslt);
- }
-
- } catch (Exception x)
- {
-
- }
- rslt = "CANCELLED JOB";
- return;
- }
- long cpos;
- ChunkHolder stats = null;
- do
- {
- cpos = rpos;
- boolean retry = false;
- do
- {
- try
- {
- stats = pullExecStatistics(rslt, rpos);
- } catch (Exception x)
- {
-
- if (x.getMessage().contains(
- "Position in a file could not be negative!"))
- {
- // squash index out of bounds exception- seems to happen for
- // disorder predictors which don't (apparently) produce any
- // progress information and JABA server throws an exception
- // because progress length is -1.
- stats = null;
- }
- else
- {
- if (--serverErrorsLeft > 0)
- {
- retry = true;
- try
- {
- Thread.sleep(200);
- } catch (InterruptedException q)
- {
- }
- ;
- }
- else
- {
- throw x;
- }
- }
- }
- } while (retry);
- if (stats != null)
- {
- System.out.print(stats.getChunk());
- msg.append(stats);
- rpos = stats.getNextPosition();
- }
- } while (stats != null && rpos > cpos);
-
- if (!finished && status.equals(JobStatus.FAILED))
- {
- try
- {
- Thread.sleep(200);
- } catch (InterruptedException x)
- {
- }
- ;
- }
- } while (!finished);
- if (serverErrorsLeft > 0)
- {
- try
- {
- Thread.sleep(200);
- } catch (InterruptedException x)
- {
- }
- if (collectAnnotationResultsFor(rslt))
- {
- jalview.bin.Cache.log.debug("Updating result annotation from Job "
- + rslt + " at " + service.getUri());
- updateResultAnnotation(true);
- ap.adjustAnnotationHeight();
- }
- }
- }
-
- catch (JobSubmissionException x)
- {
-
- System.err.println(
- "submission error with " + getServiceActionText() + " :");
- x.printStackTrace();
- calcMan.disableWorker(this);
- } catch (ResultNotAvailableException x)
- {
- System.err.println("collection error:\nJob ID: " + rslt);
- x.printStackTrace();
- calcMan.disableWorker(this);
-
- } catch (OutOfMemoryError error)
- {
- calcMan.disableWorker(this);
-
- // consensus = null;
- // hconsensus = null;
- ap.raiseOOMWarning(getServiceActionText(), error);
- } catch (Exception x)
- {
- calcMan.disableWorker(this);
-
- // consensus = null;
- // hconsensus = null;
- System.err
- .println("Blacklisting worker due to unexpected exception:");
- x.printStackTrace();
- } finally
- {
-
- calcMan.workerComplete(this);
- if (ap != null)
- {
- calcMan.workerComplete(this);
- if (guiProgress != null && progressId != -1)
- {
- guiProgress.setProgressBar("", progressId);
- }
- // TODO: may not need to paintAlignment again !
- ap.paintAlignment(false, false);
- }
- if (msg.length() > 0)
- {
- // TODO: stash message somewhere in annotation or alignment view.
- // code below shows result in a text box popup
- /*
- * jalview.gui.CutAndPasteTransfer cap = new
- * jalview.gui.CutAndPasteTransfer(); cap.setText(msg.toString());
- * jalview.gui.Desktop.addInternalFrame(cap,
- * "Job Status for "+getServiceActionText(), 600, 400);
- */
- }
- }
-
- }
-
- /**
- * validate input for dynamic/non-dynamic update context
- *
- * @param dynamic
- * @param seqs
- * @return true if input is valid
- */
- abstract boolean checkValidInputSeqs(boolean dynamic,
- List<FastaSequence> seqs);
-
- abstract String submitToService(
- List<compbio.data.sequence.FastaSequence> seqs)
- throws JobSubmissionException;
-
- abstract boolean cancelJob(String rslt) throws Exception;
-
- abstract JobStatus getJobStatus(String rslt) throws Exception;
-
- abstract ChunkHolder pullExecStatistics(String rslt, long rpos);
-
- abstract boolean collectAnnotationResultsFor(String rslt)
- throws ResultNotAvailableException;
-
- public void cancelCurrentJob()
- {
- try
- {
- String id = rslt;
- if (cancelJob(rslt))
- {
- System.err.println("Cancelled job " + id);
- }
- else
- {
- System.err.println("Job " + id + " couldn't be cancelled.");
- }
- } catch (Exception q)
- {
- q.printStackTrace();
- }
- }
-
- /**
- * Interactive updating. Analysis calculations that work on the currently
- * displayed alignment data should cancel existing jobs when the input data
- * has changed.
- *
- * @return true if a running job should be cancelled because new input data is
- * available for analysis
- */
- abstract boolean isInteractiveUpdate();
-
- public List<FastaSequence> getInputSequences(AlignmentI alignment,
- AnnotatedCollectionI inputSeqs)
- {
- if (alignment == null || alignment.getWidth() <= 0
- || alignment.getSequences() == null || alignment.isNucleotide()
- ? !nucleotidesAllowed
- : !proteinAllowed)
- {
- return null;
- }
- if (inputSeqs == null || inputSeqs.getWidth() <= 0
- || inputSeqs.getSequences() == null
- || inputSeqs.getSequences().size() < 1)
- {
- inputSeqs = alignment;
- }
-
- List<compbio.data.sequence.FastaSequence> seqs = new ArrayList<>();
-
- int minlen = 10;
- int ln = -1;
- if (bySequence)
- {
- seqNames = new HashMap<>();
- }
- gapMap = new boolean[0];
- start = inputSeqs.getStartRes();
- end = inputSeqs.getEndRes();
-
- for (SequenceI sq : (inputSeqs.getSequences()))
- {
- if (bySequence
- ? sq.findPosition(end + 1)
- - sq.findPosition(start + 1) > minlen - 1
- : sq.getEnd() - sq.getStart() > minlen - 1)
- {
- String newname = SeqsetUtils.unique_name(seqs.size() + 1);
- // make new input sequence with or without gaps
- if (seqNames != null)
- {
- seqNames.put(newname, sq);
- }
- FastaSequence seq;
- if (submitGaps)
- {
- seqs.add(seq = new compbio.data.sequence.FastaSequence(newname,
- sq.getSequenceAsString()));
- if (gapMap == null || gapMap.length < seq.getSequence().length())
- {
- boolean[] tg = gapMap;
- gapMap = new boolean[seq.getLength()];
- System.arraycopy(tg, 0, gapMap, 0, tg.length);
- for (int p = tg.length; p < gapMap.length; p++)
- {
- gapMap[p] = false; // init as a gap
- }
- }
- for (int apos : sq.gapMap())
- {
- char sqc = sq.getCharAt(apos);
- if (!filterNonStandardResidues
- || (sq.isProtein() ? ResidueProperties.aaIndex[sqc] < 20
- : ResidueProperties.nucleotideIndex[sqc] < 5))
- {
- gapMap[apos] = true; // aligned and real amino acid residue
- }
- ;
- }
- }
- else
- {
- seqs.add(seq = new compbio.data.sequence.FastaSequence(newname,
- AlignSeq.extractGaps(jalview.util.Comparison.GapChars,
- sq.getSequenceAsString(start, end + 1))));
- }
- if (seq.getSequence().length() > ln)
- {
- ln = seq.getSequence().length();
- }
- }
- }
- if (alignedSeqs && submitGaps)
- {
- realw = 0;
- for (int i = 0; i < gapMap.length; i++)
- {
- if (gapMap[i])
- {
- realw++;
- }
- }
- // try real hard to return something submittable
- // TODO: some of AAcon measures need a minimum of two or three amino
- // acids at each position, and AAcon doesn't gracefully degrade.
- for (int p = 0; p < seqs.size(); p++)
- {
- FastaSequence sq = seqs.get(p);
- int l = sq.getSequence().length();
- // strip gapped columns
- char[] padded = new char[realw],
- orig = sq.getSequence().toCharArray();
- for (int i = 0, pp = 0; i < realw; pp++)
- {
- if (gapMap[pp])
- {
- if (orig.length > pp)
- {
- padded[i++] = orig[pp];
- }
- else
- {
- padded[i++] = '-';
- }
- }
- }
- seqs.set(p, new compbio.data.sequence.FastaSequence(sq.getId(),
- new String(padded)));
- }
- }
- return seqs;
- }
-
- @Override
- public void updateAnnotation()
- {
- updateResultAnnotation(false);
- }
-
- public abstract void updateResultAnnotation(boolean immediate);
-
- public abstract String getServiceActionText();
-
- /**
- * notify manager that we have started, and wait for a free calculation slot
- *
- * @return true if slot is obtained and work still valid, false if another
- * thread has done our work for us.
- */
- protected boolean checkDone()
- {
- calcMan.notifyStart(this);
- ap.paintAlignment(false, false);
- while (!calcMan.notifyWorking(this))
- {
- if (calcMan.isWorking(this))
- {
- return true;
- }
- try
- {
- if (ap != null)
- {
- ap.paintAlignment(false, false);
- }
-
- Thread.sleep(200);
- } catch (Exception ex)
- {
- ex.printStackTrace();
- }
- }
- if (alignViewport.isClosed())
- {
- abortAndDestroy();
- return true;
- }
- return false;
- }
-
- protected void updateOurAnnots(List<AlignmentAnnotation> ourAnnot)
- {
- List<AlignmentAnnotation> our = ourAnnots;
- ourAnnots = ourAnnot;
- AlignmentI alignment = alignViewport.getAlignment();
- if (our != null)
- {
- if (our.size() > 0)
- {
- for (AlignmentAnnotation an : our)
- {
- if (!ourAnnots.contains(an))
- {
- // remove the old annotation
- alignment.deleteAnnotation(an);
- }
- }
- }
- our.clear();
-
- ap.adjustAnnotationHeight();
- }
- }
-
-}
public class JabaParamStore implements ParamDatastoreI
{
- Hashtable<String, JabaWsParamSet> editedParams = new Hashtable<String, JabaWsParamSet>();
+ Hashtable<String, JabaWsParamSet> editedParams = new Hashtable<>();
private Jws2Instance service;
List<WsParamSetI> prefs = new ArrayList<>();
if (servicePresets == null)
{
- servicePresets = new Hashtable<String, JabaPreset>();
+ servicePresets = new Hashtable<>();
PresetManager prman;
if ((prman = service.getPresets()) != null)
{
public static List<ArgumentI> getJwsArgsfromJaba(List jabargs,
boolean sortByOpt)
{
- List<ArgumentI> rgs = new ArrayList<ArgumentI>();
- List<String> rgnames = new ArrayList<String>();
+ List<ArgumentI> rgs = new ArrayList<>();
+ List<String> rgnames = new ArrayList<>();
for (Object rg : jabargs)
{
ArgumentI narg = null;
boolean found = false;
for (String url : urls)
{
- if (service.getServiceTypeURI().equals(url)
+ if (service.getNameURI().equals(url)
|| service.getUri().equalsIgnoreCase(url))
{
found = true;
wsp.setDescription(descr);
wsp.setApplicableUrls(urls.clone());
- List<String> lines = new ArrayList<String>();
+ List<String> lines = new ArrayList<>();
StringTokenizer st = new StringTokenizer(parameterfile, "\n");
while (st.hasMoreTokens())
{
throw new Error(MessageManager
.getString("error.cannot_set_params_for_ws_preset"));
}
+
+ public Preset getJabaPreset()
+ {
+ return p;
+ }
}
--- /dev/null
+package jalview.ws.jws2;
+
+import jalview.gui.WsJobParameters;
+import jalview.util.MessageManager;
+import jalview.ws.api.ServiceWithParameters;
+import jalview.ws.jws2.jabaws2.Jws2Instance;
+
+import java.awt.BorderLayout;
+import java.awt.event.WindowEvent;
+import java.awt.event.WindowListener;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Vector;
+
+import javax.swing.JFrame;
+import javax.swing.JPanel;
+
+import compbio.metadata.Option;
+import compbio.metadata.Parameter;
+import compbio.metadata.Preset;
+import compbio.metadata.PresetManager;
+
+public class JabaWsParamTest
+{
+
+ /**
+ * testing method - grab a service and parameter set and show the window
+ *
+ * @param args
+ */
+ public static void main(String[] args)
+ {
+ jalview.ws.jws2.Jws2Discoverer disc = jalview.ws.jws2.Jws2Discoverer
+ .getInstance();
+ int p = 0;
+ if (args.length > 0)
+ {
+ Vector<String> services = new Vector<>();
+ services.addElement(args[p++]);
+ Jws2Discoverer.getInstance().setServiceUrls(services);
+ }
+ try
+ {
+ disc.run();
+ } catch (Exception e)
+ {
+ System.err.println("Aborting. Problem discovering services.");
+ e.printStackTrace();
+ return;
+ }
+ Jws2Instance lastserv = null;
+ for (ServiceWithParameters service : disc.getServices())
+ {
+ // this will fail for non-JABAWS services !
+ lastserv = (Jws2Instance) service;
+ if (p >= args.length || service.getName().equalsIgnoreCase(args[p]))
+ {
+ if (lastserv != null)
+ {
+ List<Preset> prl = null;
+ Preset pr = null;
+ if (++p < args.length)
+ {
+ PresetManager prman = lastserv.getPresets();
+ if (prman != null)
+ {
+ pr = prman.getPresetByName(args[p]);
+ if (pr == null)
+ {
+ // just grab the last preset.
+ prl = prman.getPresets();
+ }
+ }
+ }
+ else
+ {
+ PresetManager prman = lastserv.getPresets();
+ if (prman != null)
+ {
+ prl = prman.getPresets();
+ }
+ }
+ Iterator<Preset> en = (prl == null) ? null : prl.iterator();
+ while (en != null && en.hasNext())
+ {
+ if (en != null)
+ {
+ if (!en.hasNext())
+ {
+ en = prl.iterator();
+ }
+ pr = en.next();
+ }
+ {
+ System.out.println("Testing opts dupes for "
+ + lastserv.getUri() + " : " + lastserv.getActionText()
+ + ":" + pr.getName());
+ List<Option> rg = lastserv.getRunnerConfig().getOptions();
+ for (Option o : rg)
+ {
+ try
+ {
+ Option cpy = jalview.ws.jws2.ParameterUtils.copyOption(o);
+ } catch (Exception e)
+ {
+ System.err.println("Failed to copy " + o.getName());
+ e.printStackTrace();
+ } catch (Error e)
+ {
+ System.err.println("Failed to copy " + o.getName());
+ e.printStackTrace();
+ }
+ }
+ }
+ {
+ System.out.println("Testing param dupes:");
+ List<Parameter> rg = lastserv.getRunnerConfig()
+ .getParameters();
+ for (Parameter o : rg)
+ {
+ try
+ {
+ Parameter cpy = jalview.ws.jws2.ParameterUtils
+ .copyParameter(o);
+ } catch (Exception e)
+ {
+ System.err.println("Failed to copy " + o.getName());
+ e.printStackTrace();
+ } catch (Error e)
+ {
+ System.err.println("Failed to copy " + o.getName());
+ e.printStackTrace();
+ }
+ }
+ }
+ {
+ System.out.println("Testing param write:");
+ List<String> writeparam = null, readparam = null;
+ try
+ {
+ writeparam = jalview.ws.jws2.ParameterUtils
+ .writeParameterSet(
+ pr.getArguments(lastserv.getRunnerConfig()),
+ " ");
+ System.out.println("Testing param read :");
+ List<Option> pset = jalview.ws.jws2.ParameterUtils
+ .processParameters(writeparam,
+ lastserv.getRunnerConfig(), " ");
+ readparam = jalview.ws.jws2.ParameterUtils
+ .writeParameterSet(pset, " ");
+ Iterator<String> o = pr.getOptions().iterator(),
+ s = writeparam.iterator(), t = readparam.iterator();
+ boolean failed = false;
+ while (s.hasNext() && t.hasNext())
+ {
+ String on = o.next(), sn = s.next(), st = t.next();
+ if (!sn.equals(st))
+ {
+ System.out.println(
+ "Original was " + on + " Phase 1 wrote " + sn
+ + "\tPhase 2 wrote " + st);
+ failed = true;
+ }
+ }
+ if (failed)
+ {
+ System.out.println(
+ "Original parameters:\n" + pr.getOptions());
+ System.out.println(
+ "Wrote parameters in first set:\n" + writeparam);
+ System.out.println(
+ "Wrote parameters in second set:\n" + readparam);
+
+ }
+ } catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ }
+ WsJobParameters pgui = new WsJobParameters(null, lastserv,
+ new JabaPreset(lastserv, pr), null);
+ JFrame jf = new JFrame(MessageManager
+ .formatMessage("label.ws_parameters_for", new String[]
+ { lastserv.getActionText() }));
+ JPanel cont = new JPanel(new BorderLayout());
+ pgui.validate();
+ cont.setPreferredSize(pgui.getPreferredSize());
+ cont.add(pgui, BorderLayout.CENTER);
+ jf.setLayout(new BorderLayout());
+ jf.add(cont, BorderLayout.CENTER);
+ jf.validate();
+ final Thread thr = Thread.currentThread();
+ jf.addWindowListener(new WindowListener()
+ {
+
+ @Override
+ public void windowActivated(WindowEvent e)
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void windowClosed(WindowEvent e)
+ {
+ }
+
+ @Override
+ public void windowClosing(WindowEvent e)
+ {
+ thr.interrupt();
+
+ }
+
+ @Override
+ public void windowDeactivated(WindowEvent e)
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void windowDeiconified(WindowEvent e)
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void windowIconified(WindowEvent e)
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void windowOpened(WindowEvent e)
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ });
+ jf.setVisible(true);
+ boolean inter = false;
+ while (!inter)
+ {
+ try
+ {
+ Thread.sleep(10000);
+ } catch (Exception e)
+ {
+ inter = true;
+ }
+ ;
+ }
+ jf.dispose();
+ }
+ }
+ }
+ }
+ }
+
+}
+++ /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.jws2;
-
-import jalview.datamodel.AlignmentAnnotation;
-import jalview.datamodel.Annotation;
-import jalview.datamodel.SequenceI;
-import jalview.gui.AlignFrame;
-import jalview.util.MessageManager;
-import jalview.ws.jws2.jabaws2.Jws2Instance;
-import jalview.ws.params.WsParamSetI;
-
-import java.util.Iterator;
-import java.util.List;
-
-import compbio.data.msa.SequenceAnnotation;
-import compbio.data.sequence.Score;
-import compbio.data.sequence.ScoreManager;
-import compbio.metadata.Argument;
-import compbio.metadata.ChunkHolder;
-import compbio.metadata.JobStatus;
-import compbio.metadata.JobSubmissionException;
-import compbio.metadata.ResultNotAvailableException;
-import compbio.metadata.WrongParameterException;
-
-public abstract class JabawsCalcWorker extends AbstractJabaCalcWorker
-{
-
- @SuppressWarnings("unchecked")
- protected SequenceAnnotation aaservice;
-
- protected ScoreManager scoremanager;
-
- public JabawsCalcWorker(Jws2Instance service, AlignFrame alignFrame,
- WsParamSetI preset, List<Argument> paramset)
- {
- super(service, alignFrame, preset, paramset);
- aaservice = (SequenceAnnotation) service.service;
- }
-
- @Override
- ChunkHolder pullExecStatistics(String rslt, long rpos)
- {
- return aaservice.pullExecStatistics(rslt, rpos);
- }
-
- @Override
- boolean collectAnnotationResultsFor(String rslt)
- throws ResultNotAvailableException
- {
- scoremanager = aaservice.getAnnotation(rslt);
- if (scoremanager != null)
- {
- return true;
- }
- return false;
- }
-
- @Override
- boolean cancelJob(String rslt) throws Exception
- {
- return aaservice.cancelJob(rslt);
- }
-
- @Override
- protected JobStatus getJobStatus(String rslt) throws Exception
- {
- return aaservice.getJobStatus(rslt);
- }
-
- @Override
- boolean hasService()
- {
- return aaservice != null;
- }
-
- @Override
- protected boolean isInteractiveUpdate()
- {
- return this instanceof AAConClient;
- }
-
- @Override
- protected String submitToService(
- List<compbio.data.sequence.FastaSequence> seqs)
- throws JobSubmissionException
- {
- String rslt;
- if (preset == null && arguments == null)
- {
- rslt = aaservice.analize(seqs);
- }
- else
- {
- try
- {
- rslt = aaservice.customAnalize(seqs, getJabaArguments());
- } catch (WrongParameterException x)
- {
- throw new JobSubmissionException(MessageManager.getString(
- "exception.jobsubmission_invalid_params_set"), x);
-
- }
- }
- return rslt;
- }
-
- protected void createAnnotationRowsForScores(
- List<AlignmentAnnotation> ourAnnot, String calcId, int alWidth,
- Score scr)
- {
- // simple annotation row
- AlignmentAnnotation annotation = alignViewport.getAlignment()
- .findOrCreateAnnotation(scr.getMethod(), calcId, true, null,
- null);
- if (alWidth == gapMap.length) // scr.getScores().size())
- {
- constructAnnotationFromScore(annotation, 0, alWidth, scr);
- ourAnnot.add(annotation);
- }
- }
-
- protected AlignmentAnnotation createAnnotationRowsForScores(
- List<AlignmentAnnotation> ourAnnot, String typeName,
- String calcId, SequenceI dseq, int base, Score scr)
- {
- System.out.println("Creating annotation on dseq:" + dseq.getStart()
- + " base is " + base + " and length=" + dseq.getLength()
- + " == " + scr.getScores().size());
- // AlignmentAnnotation annotation = new AlignmentAnnotation(
- // scr.getMethod(), typeName, new Annotation[]
- // {}, 0, -1, AlignmentAnnotation.LINE_GRAPH);
- // annotation.setCalcId(calcId);
- AlignmentAnnotation annotation = alignViewport.getAlignment()
- .findOrCreateAnnotation(typeName, calcId, false, dseq, null);
- constructAnnotationFromScore(annotation, 0, dseq.getLength(), scr);
- annotation.createSequenceMapping(dseq, base, false);
- annotation.adjustForAlignment();
- dseq.addAlignmentAnnotation(annotation);
- ourAnnot.add(annotation);
- return annotation;
- }
-
- protected void replaceAnnotationOnAlignmentWith(
- AlignmentAnnotation newAnnot, String typeName, String calcId,
- SequenceI aSeq)
- {
- SequenceI dsseq = aSeq.getDatasetSequence();
- while (dsseq.getDatasetSequence() != null)
- {
- dsseq = dsseq.getDatasetSequence();
- }
- // look for same annotation on dataset and lift this one over
- List<AlignmentAnnotation> dsan = dsseq.getAlignmentAnnotations(calcId,
- typeName);
- if (dsan != null && dsan.size() > 0)
- {
- for (AlignmentAnnotation dssan : dsan)
- {
- dsseq.removeAlignmentAnnotation(dssan);
- }
- }
- AlignmentAnnotation dssan = new AlignmentAnnotation(newAnnot);
- dsseq.addAlignmentAnnotation(dssan);
- dssan.adjustForAlignment();
- }
-
- private void constructAnnotationFromScore(AlignmentAnnotation annotation,
- int base, int alWidth, Score scr)
- {
- Annotation[] elm = new Annotation[alWidth];
- Iterator<Float> vals = scr.getScores().iterator();
- float m = 0f, x = 0f;
- for (int i = 0; vals.hasNext(); i++)
- {
- float val = vals.next().floatValue();
- if (i == 0)
- {
- m = val;
- x = val;
- }
- else
- {
- if (m > val)
- {
- m = val;
- }
- ;
- if (x < val)
- {
- x = val;
- }
- }
- // if we're at a gapped column then skip to next ungapped position
- if (gapMap != null && gapMap.length > 0)
- {
- while (!gapMap[i])
- {
- elm[i++] = new Annotation("", "", ' ', Float.NaN);
- }
- }
- elm[i] = new Annotation("", "" + val, ' ', val);
- }
-
- annotation.annotations = elm;
- annotation.belowAlignment = true;
- if (x < 0)
- {
- x = 0;
- }
- x += (x - m) * 0.1;
- annotation.graphMax = x;
- annotation.graphMin = m;
- annotation.validateRangeAndDisplay();
- }
-
-}
+++ /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.jws2;
-
-import jalview.api.AlignViewportI;
-import jalview.api.AlignmentViewPanel;
-import jalview.datamodel.AlignmentAnnotation;
-import jalview.datamodel.Annotation;
-import jalview.datamodel.SequenceI;
-import jalview.gui.AlignFrame;
-import jalview.util.MessageManager;
-import jalview.ws.jws2.jabaws2.Jws2Instance;
-import jalview.ws.params.WsParamSetI;
-
-import java.util.Iterator;
-import java.util.List;
-
-import compbio.data.msa.MsaWS;
-import compbio.data.sequence.Alignment;
-import compbio.data.sequence.Score;
-import compbio.metadata.Argument;
-import compbio.metadata.ChunkHolder;
-import compbio.metadata.JobStatus;
-import compbio.metadata.JobSubmissionException;
-import compbio.metadata.ResultNotAvailableException;
-import compbio.metadata.WrongParameterException;
-
-public abstract class JabawsMsaInterfaceAlignCalcWorker
- extends AbstractJabaCalcWorker
-{
-
- @SuppressWarnings("unchecked")
- protected MsaWS msaservice;
-
- protected Alignment msascoreset;
-
- public JabawsMsaInterfaceAlignCalcWorker(AlignViewportI alignViewport,
- AlignmentViewPanel alignPanel)
- {
- super(alignViewport, alignPanel);
- }
-
- public JabawsMsaInterfaceAlignCalcWorker(Jws2Instance service,
- AlignFrame alignFrame, WsParamSetI preset,
- List<Argument> paramset)
- {
- this(alignFrame.getCurrentView(), alignFrame.alignPanel);
- this.guiProgress = alignFrame;
- this.preset = preset;
- this.arguments = paramset;
- this.service = service;
- msaservice = (MsaWS) service.service;
-
- }
-
- @Override
- ChunkHolder pullExecStatistics(String rslt, long rpos)
- {
- return msaservice.pullExecStatistics(rslt, rpos);
- }
-
- @Override
- boolean collectAnnotationResultsFor(String rslt)
- throws ResultNotAvailableException
- {
- msascoreset = msaservice.getResult(rslt);
- if (msascoreset != null)
- {
- return true;
- }
- return false;
- }
-
- @Override
- boolean cancelJob(String rslt) throws Exception
- {
- return msaservice.cancelJob(rslt);
- }
-
- @Override
- protected JobStatus getJobStatus(String rslt) throws Exception
- {
- return msaservice.getJobStatus(rslt);
- }
-
- @Override
- boolean hasService()
- {
- return msaservice != null;
- }
-
- @Override
- protected boolean isInteractiveUpdate()
- {
- return false; // this instanceof AAConClient;
- }
-
- @Override
- protected String submitToService(
- List<compbio.data.sequence.FastaSequence> seqs)
- throws JobSubmissionException
- {
- String rslt;
- if (preset == null && arguments == null)
- {
- rslt = msaservice.align(seqs);
- }
- else
- {
- try
- {
- rslt = msaservice.customAlign(seqs, getJabaArguments());
- } catch (WrongParameterException x)
- {
- throw new JobSubmissionException(MessageManager.getString(
- "exception.jobsubmission_invalid_params_set"), x);
- }
- }
- return rslt;
- }
-
- protected void createAnnotationRowsForScores(
- List<AlignmentAnnotation> ourAnnot, String calcId, int alWidth,
- Score scr)
- {
- // simple annotation row
- AlignmentAnnotation annotation = alignViewport.getAlignment()
- .findOrCreateAnnotation(scr.getMethod(), calcId, true, null,
- null);
- if (alWidth == gapMap.length) // scr.getScores().size())
- {
- constructAnnotationFromScore(annotation, 0, alWidth, scr);
- ourAnnot.add(annotation);
- }
- }
-
- protected AlignmentAnnotation createAnnotationRowsForScores(
- List<AlignmentAnnotation> ourAnnot, String typeName,
- String calcId, SequenceI dseq, int base, Score scr)
- {
- System.out.println("Creating annotation on dseq:" + dseq.getStart()
- + " base is " + base + " and length=" + dseq.getLength()
- + " == " + scr.getScores().size());
- // AlignmentAnnotation annotation = new AlignmentAnnotation(
- // scr.getMethod(), typeName, new Annotation[]
- // {}, 0, -1, AlignmentAnnotation.LINE_GRAPH);
- // annotation.setCalcId(calcId);
- AlignmentAnnotation annotation = alignViewport.getAlignment()
- .findOrCreateAnnotation(typeName, calcId, false, dseq, null);
- constructAnnotationFromScore(annotation, 0, dseq.getLength(), scr);
- annotation.createSequenceMapping(dseq, base, false);
- annotation.adjustForAlignment();
- dseq.addAlignmentAnnotation(annotation);
- ourAnnot.add(annotation);
- return annotation;
- }
-
- private void constructAnnotationFromScore(AlignmentAnnotation annotation,
- int base, int alWidth, Score scr)
- {
- Annotation[] elm = new Annotation[alWidth];
- Iterator<Float> vals = scr.getScores().iterator();
- float m = 0f, x = 0f;
- for (int i = 0; vals.hasNext(); i++)
- {
- float val = vals.next().floatValue();
- if (i == 0)
- {
- m = val;
- x = val;
- }
- else
- {
- if (m > val)
- {
- m = val;
- }
- ;
- if (x < val)
- {
- x = val;
- }
- }
- // if we're at a gapped column then skip to next ungapped position
- if (gapMap != null && gapMap.length > 0)
- {
- while (!gapMap[i])
- {
- elm[i++] = new Annotation("", "", ' ', Float.NaN);
- }
- }
- elm[i] = new Annotation("", "" + val, ' ', val);
- }
-
- annotation.annotations = elm;
- annotation.belowAlignment = true;
- if (x < 0)
- {
- x = 0;
- }
- x += (x - m) * 0.1;
- annotation.graphMax = x;
- annotation.graphMin = m;
- annotation.validateRangeAndDisplay();
- }
-
-}
*/
package jalview.ws.jws2;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
+import jalview.gui.AlignFrame;
+import jalview.ws.api.ServiceWithParameters;
+import jalview.ws.params.ArgumentI;
+import jalview.ws.params.WsParamSetI;
+
import java.util.List;
-import javax.swing.JCheckBoxMenuItem;
import javax.swing.JMenu;
-import javax.swing.JMenuItem;
-import javax.swing.event.MenuEvent;
-import javax.swing.event.MenuListener;
-
-import compbio.metadata.Argument;
-import jalview.api.AlignCalcWorkerI;
-import jalview.bin.Cache;
-import jalview.gui.AlignFrame;
-import jalview.gui.Desktop;
-import jalview.gui.JvSwingUtils;
-import jalview.gui.WebserviceInfo;
-import jalview.gui.WsJobParameters;
-import jalview.util.MessageManager;
-import jalview.ws.jws2.dm.AAConSettings;
-import jalview.ws.jws2.dm.JabaWsParamSet;
-import jalview.ws.jws2.jabaws2.Jws2Instance;
-import jalview.ws.params.WsParamSetI;
-import jalview.ws.uimodel.AlignAnalysisUIText;
/**
* provides metadata for a jabaws2 service instance - resolves names, etc.
*/
public abstract class Jws2Client extends jalview.ws.WSClient
{
- protected AlignFrame alignFrame;
-
- protected WsParamSetI preset;
-
- protected List<Argument> paramset;
+ /**
+ * instantiate a new service client. preset and arguments are assumed to be
+ * valid for the service
+ *
+ * @param _alignFrame
+ * @param preset
+ * @param arguments
+ */
public Jws2Client(AlignFrame _alignFrame, WsParamSetI preset,
- List<Argument> arguments)
+ List<ArgumentI> arguments)
{
- alignFrame = _alignFrame;
- this.preset = preset;
- if (preset != null)
- {
- if (!((preset instanceof JabaPreset)
- || preset instanceof JabaWsParamSet))
- {
- /*
- * { this.preset = ((JabaPreset) preset).p; } else if (preset instanceof
- * JabaWsParamSet) { List<Argument> newargs = new ArrayList<Argument>();
- * JabaWsParamSet pset = ((JabaWsParamSet) preset); for (Option opt :
- * pset.getjabaArguments()) { newargs.add(opt); } if (arguments != null
- * && arguments.size() > 0) { // merge arguments with preset's own
- * arguments. for (Argument opt : arguments) { newargs.add(opt); } }
- * paramset = newargs; } else {
- */
- throw new Error(MessageManager.getString(
- "error.implementation_error_can_only_instantiate_jaba_param_sets"));
- }
- }
- else
- {
- // just provided with a bunch of arguments
- this.paramset = arguments;
- }
- }
-
- boolean processParams(Jws2Instance sh, boolean editParams)
- {
- return processParams(sh, editParams, false);
- }
-
- protected boolean processParams(Jws2Instance sh, boolean editParams,
- boolean adjustingExisting)
- {
-
- if (editParams)
- {
- if (sh.paramStore == null)
- {
- sh.paramStore = new JabaParamStore(sh,
- Desktop.getUserParameterStore());
- }
- WsJobParameters jobParams = (preset == null && paramset != null
- && paramset.size() > 0)
- ? new WsJobParameters(null, sh, null, paramset)
- : new WsJobParameters(sh, preset);
- if (adjustingExisting)
- {
- jobParams.setName(MessageManager
- .getString("label.adjusting_parameters_for_calculation"));
- }
- if (!jobParams.showRunDialog())
- {
- return false;
- }
- WsParamSetI prset = jobParams.getPreset();
- if (prset == null)
- {
- paramset =
- /* JAL-3739 always take values from input form */
- /* jobParams.isServiceDefaults() ? null : */
- JabaParamStore.getJabafromJwsArgs(jobParams.getJobParams());
- this.preset = null;
- }
- else
- {
- this.preset = prset; // ((JabaPreset) prset).p;
- paramset = null; // no user supplied parameters.
- }
- }
- return true;
+ super(_alignFrame, preset, arguments);
}
// anonymous constructor - used for headless method calls only
}
- protected WebserviceInfo setWebService(Jws2Instance serv, boolean b)
- {
- // serviceHandle = serv;
- String serviceInstance = serv.action; // serv.service.getClass().getName();
- WebServiceName = serv.serviceType;
- WebServiceJobTitle = serv.getActionText();
- WsURL = serv.hosturl;
- if (!b)
- {
- return new WebserviceInfo(WebServiceJobTitle,
- WebServiceJobTitle + " using service hosted at "
- + serv.hosturl + "\n"
- + (serv.description != null ? serv.description : ""),
- false);
- }
- return null;
- }
/*
* Jws2Instance serviceHandle; (non-Javadoc)
* @param service
* @param alignFrame
*/
- abstract void attachWSMenuEntry(JMenu wsmenu, final Jws2Instance service,
+ abstract void attachWSMenuEntry(JMenu wsmenu,
+ final ServiceWithParameters service,
final AlignFrame alignFrame);
- protected boolean registerAAConWSInstance(final JMenu wsmenu,
- final Jws2Instance service, final AlignFrame alignFrame)
- {
- final AlignAnalysisUIText aaui = service.getAlignAnalysisUI(); // null ; //
- // AlignAnalysisUIText.aaConGUI.get(service.serviceType.toString());
- if (aaui == null)
- {
- // not an instantaneous calculation GUI type service
- return false;
- }
- // create the instaneous calculation GUI bits and update state if existing
- // GUI elements already present
-
- JCheckBoxMenuItem _aaConEnabled = null;
- for (int i = 0; i < wsmenu.getItemCount(); i++)
- {
- JMenuItem item = wsmenu.getItem(i);
- if (item instanceof JCheckBoxMenuItem
- && item.getText().equals(aaui.getAAconToggle()))
- {
- _aaConEnabled = (JCheckBoxMenuItem) item;
- }
- }
- // is there an aaCon worker already present - if so, set it to use the
- // given service handle
- {
- List<AlignCalcWorkerI> aaconClient = alignFrame.getViewport()
- .getCalcManager()
- .getRegisteredWorkersOfClass(aaui.getClient());
- if (aaconClient != null && aaconClient.size() > 0)
- {
- AbstractJabaCalcWorker worker = (AbstractJabaCalcWorker) aaconClient
- .get(0);
- if (!worker.service.hosturl.equals(service.hosturl))
- {
- // javax.swing.SwingUtilities.invokeLater(new Runnable()
- {
- // @Override
- // public void run()
- {
- removeCurrentAAConWorkerFor(aaui, alignFrame);
- buildCurrentAAConWorkerFor(aaui, alignFrame, service);
- }
- } // );
- }
- }
- }
-
- // is there a service already registered ? there shouldn't be if we are
- // being called correctly
- if (_aaConEnabled == null)
- {
- final JCheckBoxMenuItem aaConEnabled = new JCheckBoxMenuItem(
- aaui.getAAconToggle());
-
- aaConEnabled.setToolTipText(
- JvSwingUtils.wrapTooltip(true, aaui.getAAconToggleTooltip()));
- aaConEnabled.addActionListener(new ActionListener()
- {
- @Override
- public void actionPerformed(ActionEvent arg0)
- {
- List<AlignCalcWorkerI> aaconClient = alignFrame.getViewport()
- .getCalcManager()
- .getRegisteredWorkersOfClass(aaui.getClient());
- if (aaconClient != null && aaconClient.size() > 0)
- {
- removeCurrentAAConWorkerFor(aaui, alignFrame);
- }
- else
- {
- buildCurrentAAConWorkerFor(aaui, alignFrame);
-
- }
- }
-
- });
- wsmenu.add(aaConEnabled);
- final JMenuItem modifyParams = new JMenuItem(
- aaui.getAAeditSettings());
- modifyParams.setToolTipText(JvSwingUtils.wrapTooltip(true,
- aaui.getAAeditSettingsTooltip()));
- modifyParams.addActionListener(new ActionListener()
- {
-
- @Override
- public void actionPerformed(ActionEvent arg0)
- {
- showAAConAnnotationSettingsFor(aaui, alignFrame);
- }
- });
- wsmenu.add(modifyParams);
- wsmenu.addMenuListener(new MenuListener()
- {
-
- @Override
- public void menuSelected(MenuEvent arg0)
- {
- // TODO: refactor to the implementing class.
- if (alignFrame.getViewport().getAlignment().isNucleotide()
- ? aaui.isNa()
- : aaui.isPr())
- {
- aaConEnabled.setEnabled(true);
- modifyParams.setEnabled(true);
- }
- else
- {
- aaConEnabled.setEnabled(false);
- modifyParams.setEnabled(false);
- }
- List<AlignCalcWorkerI> aaconClient = alignFrame.getViewport()
- .getCalcManager()
- .getRegisteredWorkersOfClass(aaui.getClient());
- if (aaconClient != null && aaconClient.size() > 0)
- {
- aaConEnabled.setSelected(true);
- }
- else
- {
- aaConEnabled.setSelected(false);
- }
- }
-
- @Override
- public void menuDeselected(MenuEvent arg0)
- {
- // TODO Auto-generated method stub
-
- }
-
- @Override
- public void menuCanceled(MenuEvent arg0)
- {
- // TODO Auto-generated method stub
-
- }
- });
-
- }
- return true;
- }
-
- private static void showAAConAnnotationSettingsFor(
- final AlignAnalysisUIText aaui, AlignFrame alignFrame)
- {
- /*
- * preferred settings Whether AACon is automatically recalculated Which
- * AACon server to use What parameters to use
- */
- // could actually do a class search for this too
- AAConSettings fave = (AAConSettings) alignFrame.getViewport()
- .getCalcIdSettingsFor(aaui.getCalcId());
- if (fave == null)
- {
- fave = createDefaultAAConSettings(aaui);
- }
- new SequenceAnnotationWSClient(fave, alignFrame, true);
-
- }
-
- private static void buildCurrentAAConWorkerFor(
- final AlignAnalysisUIText aaui, AlignFrame alignFrame)
- {
- buildCurrentAAConWorkerFor(aaui, alignFrame, null);
- }
-
- private static void buildCurrentAAConWorkerFor(
- final AlignAnalysisUIText aaui, AlignFrame alignFrame,
- Jws2Instance service)
- {
- /*
- * preferred settings Whether AACon is automatically recalculated Which
- * AACon server to use What parameters to use
- */
- AAConSettings fave = (AAConSettings) alignFrame.getViewport()
- .getCalcIdSettingsFor(aaui.getCalcId());
- if (fave == null)
- {
- fave = createDefaultAAConSettings(aaui, service);
- }
- else
- {
- if (service != null
- && !fave.getService().hosturl.equals(service.hosturl))
- {
- Cache.log.debug("Changing AACon service to " + service.hosturl
- + " from " + fave.getService().hosturl);
- fave.setService(service);
- }
- }
- new SequenceAnnotationWSClient(fave, alignFrame, false);
- }
-
- private static AAConSettings createDefaultAAConSettings(
- AlignAnalysisUIText aaui)
- {
- return createDefaultAAConSettings(aaui, null);
- }
-
- private static AAConSettings createDefaultAAConSettings(
- AlignAnalysisUIText aaui, Jws2Instance service)
- {
- if (service != null)
- {
- if (!service.serviceType.toString()
- .equals(compbio.ws.client.Services.AAConWS.toString()))
- {
- Cache.log.warn(
- "Ignoring invalid preferred service for AACon calculations (service type was "
- + service.serviceType + ")");
- service = null;
- }
- else
- {
- // check service is actually in the list of currently avaialable
- // services
- if (!Jws2Discoverer.getDiscoverer().getServices().contains(service))
- {
- // it isn't ..
- service = null;
- }
- }
- }
- if (service == null)
- {
- // get the default service for AACon
- service = Jws2Discoverer.getDiscoverer().getPreferredServiceFor(null,
- aaui.getServiceType());
- }
- if (service == null)
- {
- // TODO raise dialog box explaining error, and/or open the JABA
- // preferences menu.
- throw new Error(
- MessageManager.getString("error.no_aacon_service_found"));
- }
- return new AAConSettings(true, service, null, null);
- }
-
- private static void removeCurrentAAConWorkerFor(AlignAnalysisUIText aaui,
- AlignFrame alignFrame)
- {
- alignFrame.getViewport().getCalcManager()
- .removeRegisteredWorkersOfClass(aaui.getClient());
- }
}
--- /dev/null
+package jalview.ws.jws2;
+
+import jalview.api.AlignCalcWorkerI;
+import jalview.bin.Cache;
+import jalview.gui.AlignFrame;
+import jalview.gui.JvSwingUtils;
+import jalview.util.MessageManager;
+import jalview.ws.api.ServiceWithParameters;
+import jalview.ws.jws2.dm.AAConSettings;
+import jalview.ws.jws2.jabaws2.Jws2Instance;
+import jalview.ws.params.AutoCalcSetting;
+import jalview.ws.uimodel.AlignAnalysisUIText;
+
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.util.List;
+
+import javax.swing.JCheckBoxMenuItem;
+import javax.swing.JMenu;
+import javax.swing.JMenuItem;
+import javax.swing.event.MenuEvent;
+import javax.swing.event.MenuListener;
+
+public class Jws2ClientFactory
+{
+ static boolean registerAAConWSInstance(final JMenu wsmenu,
+ final ServiceWithParameters service, final AlignFrame alignFrame)
+ {
+ final AlignAnalysisUIText aaui = service.getAlignAnalysisUI(); // null
+ // ; //
+ // AlignAnalysisUIText.aaConGUI.get(service.serviceType.toString());
+ if (aaui == null)
+ {
+ // not an instantaneous calculation GUI type service
+ return false;
+ }
+ // create the instaneous calculation GUI bits and update state if existing
+ // GUI elements already present
+
+ JCheckBoxMenuItem _aaConEnabled = null;
+ for (int i = 0; i < wsmenu.getItemCount(); i++)
+ {
+ JMenuItem item = wsmenu.getItem(i);
+ if (item instanceof JCheckBoxMenuItem
+ && item.getText().equals(aaui.getAAconToggle()))
+ {
+ _aaConEnabled = (JCheckBoxMenuItem) item;
+ }
+ }
+ // is there an aaCon worker already present - if so, set it to use the
+ // given service handle
+ {
+ List<AlignCalcWorkerI> aaconClient = alignFrame.getViewport()
+ .getCalcManager()
+ .getWorkersOfClass(aaui.getClient());
+ if (aaconClient != null && aaconClient.size() > 0)
+ {
+ SeqAnnotationServiceCalcWorker worker = (SeqAnnotationServiceCalcWorker) aaconClient
+ .get(0);
+ if (!worker.service.getHostURL().equals(service.getHostURL()))
+ {
+ // javax.swing.SwingUtilities.invokeLater(new Runnable()
+ {
+ // @Override
+ // public void run()
+ {
+ removeCurrentAAConWorkerFor(aaui, alignFrame);
+ buildCurrentAAConWorkerFor(aaui, alignFrame, service);
+ }
+ } // );
+ }
+ }
+ }
+
+ // is there a service already registered ? there shouldn't be if we are
+ // being called correctly
+ if (_aaConEnabled == null)
+ {
+ final JCheckBoxMenuItem aaConEnabled = new JCheckBoxMenuItem(
+ aaui.getAAconToggle());
+
+ aaConEnabled.setToolTipText(
+ JvSwingUtils.wrapTooltip(true, aaui.getAAconToggleTooltip()));
+ aaConEnabled.addActionListener(new ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent arg0)
+ {
+
+ List<AlignCalcWorkerI> aaconClient = alignFrame.getViewport()
+ .getCalcManager()
+ .getWorkersOfClass(SeqAnnotationServiceCalcWorker.class);
+ if (aaconClient != null)
+ {
+ for (AlignCalcWorkerI worker : aaconClient)
+ {
+ if (((SeqAnnotationServiceCalcWorker) worker).getService()
+ .getClass().equals(aaui.getClient()))
+ {
+ removeCurrentAAConWorkerFor(aaui, alignFrame);
+ return;
+ }
+ }
+ }
+ buildCurrentAAConWorkerFor(aaui, alignFrame);
+ }
+
+ });
+ wsmenu.add(aaConEnabled);
+ final JMenuItem modifyParams = new JMenuItem(
+ aaui.getAAeditSettings());
+ modifyParams.setToolTipText(JvSwingUtils.wrapTooltip(true,
+ aaui.getAAeditSettingsTooltip()));
+ modifyParams.addActionListener(new ActionListener()
+ {
+
+ @Override
+ public void actionPerformed(ActionEvent arg0)
+ {
+ showAAConAnnotationSettingsFor(aaui, alignFrame);
+ }
+ });
+ wsmenu.add(modifyParams);
+ wsmenu.addMenuListener(new MenuListener()
+ {
+
+ @Override
+ public void menuSelected(MenuEvent arg0)
+ {
+ // TODO: refactor to the implementing class.
+ if (alignFrame.getViewport().getAlignment().isNucleotide()
+ ? aaui.isNa()
+ : aaui.isPr())
+ {
+ aaConEnabled.setEnabled(true);
+ modifyParams.setEnabled(true);
+ }
+ else
+ {
+ aaConEnabled.setEnabled(false);
+ modifyParams.setEnabled(false);
+ return;
+ }
+ List<AlignCalcWorkerI> aaconClient = alignFrame.getViewport()
+ .getCalcManager()
+ .getWorkersOfClass(SeqAnnotationServiceCalcWorker.class);
+
+ boolean serviceEnabled = false;
+ if (aaconClient != null)
+ {
+ // NB code duplicatino again!
+ for (AlignCalcWorkerI _worker : aaconClient)
+ {
+ SeqAnnotationServiceCalcWorker worker = (SeqAnnotationServiceCalcWorker) _worker;
+ // this could be cleaner ?
+ if (worker.hasService()
+ && aaui.getClient()
+ .equals(worker.getService().getClass()))
+ {
+ serviceEnabled = true;
+ }
+ }
+ }
+ aaConEnabled.setSelected(serviceEnabled);
+ }
+
+ @Override
+ public void menuDeselected(MenuEvent arg0)
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void menuCanceled(MenuEvent arg0)
+ {
+ // TODO Auto-generated method stub
+
+ }
+ });
+
+ }
+ return true;
+ }
+
+ private static void showAAConAnnotationSettingsFor(
+ final AlignAnalysisUIText aaui, AlignFrame alignFrame)
+ {
+ /*
+ * preferred settings Whether AACon is automatically recalculated Which
+ * AACon server to use What parameters to use
+ */
+ // could actually do a class search for this too
+ AutoCalcSetting fave = alignFrame.getViewport()
+ .getCalcIdSettingsFor(aaui.getCalcId());
+ if (fave == null)
+ {
+ fave = createDefaultAAConSettings(aaui);
+ }
+ new SequenceAnnotationWSClient(fave, alignFrame, true);
+
+ }
+
+ private static void buildCurrentAAConWorkerFor(
+ final AlignAnalysisUIText aaui, AlignFrame alignFrame)
+ {
+ buildCurrentAAConWorkerFor(aaui, alignFrame, null);
+ }
+
+ private static void buildCurrentAAConWorkerFor(
+ final AlignAnalysisUIText aaui, AlignFrame alignFrame,
+ ServiceWithParameters service)
+ {
+ /*
+ * preferred settings Whether AACon is automatically recalculated Which
+ * AACon server to use What parameters to use
+ */
+ AutoCalcSetting fave = alignFrame.getViewport()
+ .getCalcIdSettingsFor(aaui.getCalcId());
+ if (fave == null)
+ {
+ fave = createDefaultAAConSettings(aaui, service);
+ }
+ else
+ {
+ if (service != null && !fave.getService().getHostURL()
+ .equals(service.getHostURL()))
+ {
+ Cache.log.debug("Changing AACon service to " + service.getHostURL()
+ + " from " + fave.getService().getHostURL());
+ fave.setService(service);
+ }
+ }
+ new SequenceAnnotationWSClient(fave, alignFrame, false);
+ }
+
+ private static AutoCalcSetting createDefaultAAConSettings(
+ AlignAnalysisUIText aaui)
+ {
+ return createDefaultAAConSettings(aaui, null);
+ }
+
+ private static AutoCalcSetting createDefaultAAConSettings(
+ AlignAnalysisUIText aaui, ServiceWithParameters service)
+ {
+ if (service != null)
+ {
+ // if (!service.getServiceType()
+ // .equals(compbio.ws.client.Services.AAConWS.toString()))
+ // {
+ // Cache.log.warn(
+ // "Ignoring invalid preferred service for AACon calculations (service
+ // type was "
+ // + service.getServiceType() + ")");
+ // service = null;
+ // }
+ // else
+ {
+ // check service is actually in the list of currently avaialable
+ // services
+ if (!PreferredServiceRegistry.getRegistry().contains(service))
+ {
+ // it isn't ..
+ service = null;
+ }
+ }
+ }
+ if (service == null)
+ {
+ // get the default service for AACon
+ service = PreferredServiceRegistry.getRegistry().getPreferredServiceFor(null,
+ aaui.getServiceType());
+ }
+ if (service == null)
+ {
+ // TODO raise dialog box explaining error, and/or open the JABA
+ // preferences menu.
+ throw new Error(
+ MessageManager.getString("error.no_aacon_service_found"));
+ }
+ return service instanceof Jws2Instance
+ ? new AAConSettings(true, service, null, null)
+ : new AutoCalcSetting(service, null, null, true);
+ }
+
+ private static void removeCurrentAAConWorkerFor(AlignAnalysisUIText aaui,
+ AlignFrame alignFrame)
+ {
+ alignFrame.getViewport().getCalcManager()
+ .removeWorkersOfClass(aaui.getClient());
+ }
+}
\ No newline at end of file
package jalview.ws.jws2;
import jalview.bin.Cache;
+import jalview.bin.ApplicationSingletonProvider;
+import jalview.bin.ApplicationSingletonProvider.ApplicationSingletonI;
import jalview.gui.AlignFrame;
-import jalview.gui.Desktop;
-import jalview.gui.JvSwingUtils;
import jalview.util.MessageManager;
-import jalview.ws.WSMenuEntryProviderI;
+import jalview.ws.ServiceChangeListener;
+import jalview.ws.WSDiscovererI;
+import jalview.ws.api.ServiceWithParameters;
import jalview.ws.jws2.jabaws2.Jws2Instance;
import jalview.ws.params.ParamDatastoreI;
-import java.awt.Color;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
+import java.util.Collections;
import java.util.HashSet;
-import java.util.Hashtable;
import java.util.List;
-import java.util.Map;
import java.util.Set;
import java.util.StringTokenizer;
import java.util.Vector;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.CopyOnWriteArraySet;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+import java.util.concurrent.FutureTask;
import javax.swing.JMenu;
-import javax.swing.JMenuItem;
import compbio.ws.client.Services;
* @author JimP
*
*/
-public class Jws2Discoverer implements Runnable, WSMenuEntryProviderI
+public class Jws2Discoverer implements WSDiscovererI, Runnable, ApplicationSingletonI
{
+
+ /**
+ * Returns the singleton instance of this class.
+ *
+ * @return
+ */
+ public static Jws2Discoverer getInstance()
+ {
+ return (Jws2Discoverer) ApplicationSingletonProvider
+ .getInstance(Jws2Discoverer.class);
+ }
+
public static final String COMPBIO_JABAWS = "http://www.compbio.dundee.ac.uk/jabaws";
/*
private final static String JWS2HOSTURLS = "JWS2HOSTURLS";
/*
- * Singleton instance
- */
- private static Jws2Discoverer discoverer;
-
- /*
* Override for testing only
*/
- private static List<String> testUrls = null;
+ private List<String> testUrls = null;
// preferred url has precedence over others
private String preferredUrl;
-
- private PropertyChangeSupport changeSupport = new PropertyChangeSupport(
- this);
-
+
+ private Set<ServiceChangeListener> serviceListeners = new CopyOnWriteArraySet<>();
private Vector<String> invalidServiceUrls = null;
private Vector<String> urlsWithoutServices = null;
private volatile boolean running = false;
private volatile boolean aborted = false;
-
- private Thread oldthread = null;
+
+ private volatile Thread oldthread = null;
/**
* holds list of services.
{
}
- /**
- * change listeners are notified of "services" property changes
- *
- * @param listener
- * to be added that consumes new services Hashtable object.
- */
- public void addPropertyChangeListener(
- java.beans.PropertyChangeListener listener)
+
+ @Override
+ public void addServiceChangeListener(ServiceChangeListener listener)
{
- changeSupport.addPropertyChangeListener(listener);
+ serviceListeners.add(listener);
}
- /**
- *
- *
- * @param listener
- * to be removed
- */
- public void removePropertyChangeListener(
- java.beans.PropertyChangeListener listener)
+ @Override
+ public void removeServiceChangeListener(ServiceChangeListener listener)
{
- changeSupport.removePropertyChangeListener(listener);
+ serviceListeners.remove(listener);
+ }
+
+ private void notifyServiceListeners(List<? extends ServiceWithParameters> services)
+ {
+ if (services == null) services = this.services;
+ for (var listener : serviceListeners) {
+ listener.servicesChanged(this, services);
+ }
}
/**
ignoredServices.add(ignored);
}
- changeSupport.firePropertyChange("services", services,
- new Vector<Jws2Instance>());
+ notifyServiceListeners(Collections.emptyList());
oldthread = Thread.currentThread();
try
{
- Class foo = getClass().getClassLoader()
- .loadClass("compbio.ws.client.Jws2Client");
+ getClass().getClassLoader().loadClass("compbio.ws.client.Jws2Client");
} catch (ClassNotFoundException e)
{
System.err.println(
for (Jws2Instance svc : services)
{
svcs[ipos] = svc;
- spos[ipos++] = 1000 * svcUrls.indexOf(svc.getHost()) + 1
- + svctypes.indexOf(svc.serviceType);
+ spos[ipos++] = 1000 * svcUrls.indexOf(svc.getHostURL()) + 1
+ + svctypes.indexOf(svc.getName());
}
jalview.util.QuickSort.sort(spos, svcs);
services = new Vector<>();
for (Jws2Instance svc : svcs)
{
- if (!ignoredServices.contains(svc.serviceType))
+ if (!ignoredServices.contains(svc.getName()))
{
services.add(svc);
}
}
oldthread = null;
running = false;
- changeSupport.firePropertyChange("services", new Vector<Jws2Instance>(),
- services);
+ notifyServiceListeners(services);
}
/**
}
/**
- * attach all available web services to the appropriate submenu in the given
- * JMenu
- */
- @Override
- public void attachWSMenuEntry(JMenu wsmenu, final AlignFrame alignFrame)
- {
- // dynamically regenerate service list.
- populateWSMenuEntry(wsmenu, alignFrame, null);
- }
-
- private boolean isRecalculable(String action)
- {
- return (action != null && action.equalsIgnoreCase("conservation"));
- }
-
- private void populateWSMenuEntry(JMenu jws2al,
- final AlignFrame alignFrame, String typeFilter)
- {
- if (running || services == null || services.size() == 0)
- {
- return;
- }
-
- /**
- * eventually, JWS2 services will appear under the same align/etc submenus.
- * for moment we keep them separate.
- */
- JMenu atpoint;
- List<Jws2Instance> enumerableServices = new ArrayList<>();
- // jws2al.removeAll();
- Map<String, Jws2Instance> preferredHosts = new HashMap<>();
- Map<String, List<Jws2Instance>> alternates = new HashMap<>();
- for (Jws2Instance service : services.toArray(new Jws2Instance[0]))
- {
- if (!isRecalculable(service.action))
- {
- // add 'one shot' services to be displayed using the classic menu
- // structure
- enumerableServices.add(service);
- }
- else
- {
- if (!preferredHosts.containsKey(service.serviceType))
- {
- Jws2Instance preferredInstance = getPreferredServiceFor(
- alignFrame, service.serviceType);
- if (preferredInstance != null)
- {
- preferredHosts.put(service.serviceType, preferredInstance);
- }
- else
- {
- preferredHosts.put(service.serviceType, service);
- }
- }
- List<Jws2Instance> ph = alternates.get(service.serviceType);
- if (preferredHosts.get(service.serviceType) != service)
- {
- if (ph == null)
- {
- ph = new ArrayList<>();
- }
- ph.add(service);
- alternates.put(service.serviceType, ph);
- }
- }
-
- }
-
- // create GUI element for classic services
- addEnumeratedServices(jws2al, alignFrame, enumerableServices);
- // and the instantaneous services
- for (final Jws2Instance service : preferredHosts.values())
- {
- atpoint = JvSwingUtils.findOrCreateMenu(jws2al, service.action);
- JMenuItem hitm;
- if (atpoint.getItemCount() > 1)
- {
- // previous service of this type already present
- atpoint.addSeparator();
- }
- atpoint.add(hitm = new JMenuItem(service.getHost()));
- hitm.setForeground(Color.blue);
- hitm.addActionListener(new ActionListener()
- {
-
- @Override
- public void actionPerformed(ActionEvent e)
- {
- Desktop.showUrl(service.getHost());
- }
- });
- hitm.setToolTipText(JvSwingUtils.wrapTooltip(false,
- MessageManager.getString("label.open_jabaws_web_page")));
-
- service.attachWSMenuEntry(atpoint, alignFrame);
- if (alternates.containsKey(service.serviceType))
- {
- atpoint.add(hitm = new JMenu(
- MessageManager.getString("label.switch_server")));
- hitm.setToolTipText(JvSwingUtils.wrapTooltip(false,
- MessageManager.getString("label.choose_jabaws_server")));
- for (final Jws2Instance sv : alternates.get(service.serviceType))
- {
- JMenuItem itm;
- hitm.add(itm = new JMenuItem(sv.getHost()));
- itm.setForeground(Color.blue);
- itm.addActionListener(new ActionListener()
- {
-
- @Override
- public void actionPerformed(ActionEvent arg0)
- {
- new Thread(new Runnable()
- {
- @Override
- public void run()
- {
- setPreferredServiceFor(alignFrame, sv.serviceType,
- sv.action, sv);
- changeSupport.firePropertyChange("services",
- new Vector<Jws2Instance>(), services);
- }
- }).start();
-
- }
- });
- }
- }
- }
- }
-
- /**
- * add services using the Java 2.5/2.6/2.7 system which optionally creates
- * submenus to index by host and service program type
- */
- private void addEnumeratedServices(final JMenu jws2al,
- final AlignFrame alignFrame,
- List<Jws2Instance> enumerableServices)
- {
- boolean byhost = Cache.getDefault("WSMENU_BYHOST", false),
- bytype = Cache.getDefault("WSMENU_BYTYPE", false);
- /**
- * eventually, JWS2 services will appear under the same align/etc submenus.
- * for moment we keep them separate.
- */
- JMenu atpoint;
-
- List<String> hostLabels = new ArrayList<>();
- Hashtable<String, String> lasthostFor = new Hashtable<>();
- Hashtable<String, ArrayList<Jws2Instance>> hosts = new Hashtable<>();
- ArrayList<String> hostlist = new ArrayList<>();
- for (Jws2Instance service : enumerableServices)
- {
- ArrayList<Jws2Instance> hostservices = hosts.get(service.getHost());
- if (hostservices == null)
- {
- hosts.put(service.getHost(),
- hostservices = new ArrayList<>());
- hostlist.add(service.getHost());
- }
- hostservices.add(service);
- }
- // now add hosts in order of the given array
- for (String host : hostlist)
- {
- Jws2Instance orderedsvcs[] = hosts.get(host)
- .toArray(new Jws2Instance[1]);
- String sortbytype[] = new String[orderedsvcs.length];
- for (int i = 0; i < sortbytype.length; i++)
- {
- sortbytype[i] = orderedsvcs[i].serviceType;
- }
- jalview.util.QuickSort.sort(sortbytype, orderedsvcs);
- for (final Jws2Instance service : orderedsvcs)
- {
- atpoint = JvSwingUtils.findOrCreateMenu(jws2al, service.action);
- String type = service.serviceType;
- if (byhost)
- {
- atpoint = JvSwingUtils.findOrCreateMenu(atpoint, host);
- if (atpoint.getToolTipText() == null)
- {
- atpoint.setToolTipText(MessageManager
- .formatMessage("label.services_at", new String[]
- { host }));
- }
- }
- if (bytype)
- {
- atpoint = JvSwingUtils.findOrCreateMenu(atpoint, type);
- if (atpoint.getToolTipText() == null)
- {
- atpoint.setToolTipText(service.getActionText());
- }
- }
- if (!byhost && !hostLabels.contains(
- host + service.serviceType + service.getActionText()))
- // !hostLabels.contains(host + (bytype ?
- // service.serviceType+service.getActionText() : "")))
- {
- // add a marker indicating where this service is hosted
- // relies on services from the same host being listed in a
- // contiguous
- // group
- JMenuItem hitm;
- if (hostLabels.contains(host))
- {
- atpoint.addSeparator();
- }
- else
- {
- hostLabels.add(host);
- }
- if (lasthostFor.get(service.action) == null
- || !lasthostFor.get(service.action).equals(host))
- {
- atpoint.add(hitm = new JMenuItem(host));
- hitm.setForeground(Color.blue);
- hitm.addActionListener(new ActionListener()
- {
-
- @Override
- public void actionPerformed(ActionEvent e)
- {
- Desktop.showUrl(service.getHost());
- }
- });
- hitm.setToolTipText(
- JvSwingUtils.wrapTooltip(true, MessageManager
- .getString("label.open_jabaws_web_page")));
- lasthostFor.put(service.action, host);
- }
- hostLabels.add(
- host + service.serviceType + service.getActionText());
- }
-
- service.attachWSMenuEntry(atpoint, alignFrame);
- }
- }
- }
-
- /**
*
* @param args
* @j2sIgnore
*/
public static void main(String[] args)
{
+ Jws2Discoverer instance = getInstance();
if (args.length > 0)
{
- testUrls = new ArrayList<>();
+ instance.testUrls = new ArrayList<>();
for (String url : args)
{
- testUrls.add(url);
+ instance.testUrls.add(url);
}
}
- Thread runner = getDiscoverer()
- .startDiscoverer(new PropertyChangeListener()
- {
-
- @Override
- public void propertyChange(PropertyChangeEvent evt)
- {
- if (getDiscoverer().services != null)
- {
- System.out.println("Changesupport: There are now "
- + getDiscoverer().services.size() + " services");
- int i = 1;
- for (Jws2Instance instance : getDiscoverer().services)
- {
- System.out.println("Service " + i++ + " "
- + instance.getClass() + "@" + instance.getHost()
- + ": " + instance.getActionText());
- }
-
- }
- }
- });
- while (runner.isAlive())
- {
- try
- {
- Thread.sleep(50);
- } catch (InterruptedException e)
+ var discoverer = getInstance();
+ discoverer.addServiceChangeListener((_discoverer, _services) -> {
+ if (discoverer.services != null)
{
+ System.out.println("Changesupport: There are now "
+ + discoverer.services.size() + " services");
+ int i = 1;
+ for (ServiceWithParameters s_instance : discoverer.services)
+ {
+ System.out.println(
+ "Service " + i++ + " " + s_instance.getClass()
+ + "@" + s_instance.getHostURL() + ": "
+ + s_instance.getActionText());
+ }
+
}
+ });
+ try
+ {
+ discoverer.startDiscoverer().get();
+ } catch (InterruptedException | ExecutionException e)
+ {
}
try
{
}
}
- /**
- * Returns the singleton instance of this class.
- *
- * @return
- */
- public static Jws2Discoverer getDiscoverer()
- {
- if (discoverer == null)
- {
- discoverer = new Jws2Discoverer();
- }
- return discoverer;
- }
+ @Override
public boolean hasServices()
{
return !running && services != null && services.size() > 0;
}
+ @Override
public boolean isRunning()
{
return running;
}
+ @Override
public void setServiceUrls(List<String> wsUrls)
{
if (wsUrls != null && !wsUrls.isEmpty())
*
* @return
*/
+ @Override
public List<String> getServiceUrls()
{
if (testUrls != null)
return urls;
}
- public Vector<Jws2Instance> getServices()
+ @Override
+ public Vector<ServiceWithParameters> getServices()
{
- return (services == null) ? new Vector<>()
- : new Vector<>(services);
+ return (services == null) ? new Vector<>() : new Vector<>(services);
}
/**
* @param foo
* @return
*/
- public static boolean testServiceUrl(URL foo)
+ @Override
+ public boolean testServiceUrl(URL foo)
{
try
{
* @param changeSupport2
* @return new thread
*/
- public Thread startDiscoverer(PropertyChangeListener changeSupport2)
+ @Override
+ public CompletableFuture<WSDiscovererI> startDiscoverer()
{
/* if (restart())
{
{
setAborted(true);
}
- addPropertyChangeListener(changeSupport2);
- Thread thr = new Thread(this);
- thr.start();
- return thr;
+ CompletableFuture<WSDiscovererI> task = CompletableFuture
+ .supplyAsync(() -> {
+ run();
+ return Jws2Discoverer.this;
+ });
+ return task;
}
/**
* @return a human readable report of any problems with the service URLs used
* for discovery
*/
+ @Override
public String getErrorMessages()
{
if (!isRunning() && !isAborted())
return null;
}
+ @Override
public int getServerStatusFor(String url)
{
if (validServiceUrls != null && validServiceUrls.contains(url))
{
- return 1;
+ return STATUS_OK;
}
if (urlsWithoutServices != null && urlsWithoutServices.contains(url))
{
- return 0;
+ return STATUS_NO_SERVICES;
}
if (invalidServiceUrls != null && invalidServiceUrls.contains(url))
{
- return -1;
- }
- return -2;
- }
-
- /**
- * pick the user's preferred service based on a set of URLs (jaba server
- * locations) and service URIs (specifying version and service interface
- * class)
- *
- * @param serviceURL
- * @return null or best match for given uri/ls.
- */
- public Jws2Instance getPreferredServiceFor(String[] serviceURLs)
- {
- HashSet<String> urls = new HashSet<>();
- urls.addAll(Arrays.asList(serviceURLs));
- Jws2Instance match = null;
- if (services != null)
- {
- for (Jws2Instance svc : services)
- {
- if (urls.contains(svc.getServiceTypeURI()))
- {
- if (match == null)
- {
- // for moment we always pick service from server ordered first in
- // user's preferences
- match = svc;
- }
- if (urls.contains(svc.getUri()))
- {
- // stop and return - we've matched type URI and URI for service
- // endpoint
- return svc;
- }
- }
- }
- }
- return match;
- }
-
- Map<String, Map<String, String>> preferredServiceMap = new HashMap<>();
-
- /**
- * get current preferred service of the given type, or global default
- *
- * @param af
- * null or a specific alignFrame
- * @param serviceType
- * Jws2Instance.serviceType for service
- * @return null if no service of this type is available, the preferred service
- * for the serviceType and af if specified and if defined.
- */
- public Jws2Instance getPreferredServiceFor(AlignFrame af,
- String serviceType)
- {
- String serviceurl = null;
- synchronized (preferredServiceMap)
- {
- String afid = (af == null) ? "" : af.getViewport().getSequenceSetId();
- Map<String, String> prefmap = preferredServiceMap.get(afid);
- if (afid.length() > 0 && prefmap == null)
- {
- // recover global setting, if any
- prefmap = preferredServiceMap.get("");
- }
- if (prefmap != null)
- {
- serviceurl = prefmap.get(serviceType);
- }
-
- }
- Jws2Instance response = null;
- for (Jws2Instance svc : services)
- {
- if (svc.serviceType.equals(serviceType))
- {
- if (serviceurl == null || serviceurl.equals(svc.getHost()))
- {
- response = svc;
- break;
- }
- }
- }
- return response;
- }
-
- public void setPreferredServiceFor(AlignFrame af, String serviceType,
- String serviceAction, Jws2Instance selectedServer)
- {
- String afid = (af == null) ? "" : af.getViewport().getSequenceSetId();
- if (preferredServiceMap == null)
- {
- preferredServiceMap = new HashMap<>();
- }
- Map<String, String> prefmap = preferredServiceMap.get(afid);
- if (prefmap == null)
- {
- prefmap = new HashMap<>();
- preferredServiceMap.put(afid, prefmap);
+ return STATUS_INVALID;
}
- prefmap.put(serviceType, selectedServer.getHost());
- prefmap.put(serviceAction, selectedServer.getHost());
- }
-
- public void setPreferredServiceFor(String serviceType,
- String serviceAction, Jws2Instance selectedServer)
- {
- setPreferredServiceFor(null, serviceType, serviceAction,
- selectedServer);
+ return STATUS_UNKNOWN;
}
/**
*/
package jalview.ws.jws2;
-import java.util.Locale;
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.AlignmentView;
+import jalview.gui.AlignFrame;
+import jalview.gui.Desktop;
+import jalview.gui.JvOptionPane;
+import jalview.gui.JvSwingUtils;
+import jalview.util.MessageManager;
+import jalview.ws.WSMenuEntryProviderI;
+import jalview.ws.api.JalviewServiceEndpointProviderI;
+import jalview.ws.api.MultipleSequenceAlignmentI;
+import jalview.ws.api.ServiceWithParameters;
+import jalview.ws.gui.MsaWSThread;
+import jalview.ws.params.ArgumentI;
+import jalview.ws.params.WsParamSetI;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.List;
+import java.util.Locale;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
import javax.swing.ToolTipManager;
-import compbio.data.msa.MsaWS;
-import compbio.metadata.Argument;
-import jalview.datamodel.AlignmentI;
-import jalview.datamodel.AlignmentView;
-import jalview.gui.AlignFrame;
-import jalview.gui.Desktop;
-import jalview.gui.JvOptionPane;
-import jalview.gui.JvSwingUtils;
-import jalview.util.MessageManager;
-import jalview.ws.jws2.jabaws2.Jws2Instance;
-import jalview.ws.params.WsParamSetI;
/**
- * DOCUMENT ME!
+ * MsaWSClient
*
- * @author $author$
+ * Instantiates web service menu items for multiple alignment services, and
+ * holds logic for constructing a web service thread.
+ *
+ * TODO remove dependency on Jws2Client methods for creating AACon service UI
+ * elements.
+ *
+ * @author Jim Procter et al
* @version $Revision$
*/
-public class MsaWSClient extends Jws2Client
+public class MsaWSClient extends Jws2Client implements WSMenuEntryProviderI
{
/**
- * server is a WSDL2Java generated stub for an archetypal MsaWSI service.
+ * server is a proxy class implementing the core methods for submitting,
+ * monitoring and retrieving results from a multiple sequence alignment
+ * service
*/
- MsaWS server;
+ MultipleSequenceAlignmentI server;
- public MsaWSClient(Jws2Instance sh, String altitle,
+ public MsaWSClient(ServiceWithParameters sh, String altitle,
jalview.datamodel.AlignmentView msa, boolean submitGaps,
boolean preserveOrder, AlignmentI seqdataset,
AlignFrame _alignFrame)
// TODO Auto-generated constructor stub
}
- public MsaWSClient(Jws2Instance sh, WsParamSetI preset, String altitle,
+ public MsaWSClient(ServiceWithParameters sh, WsParamSetI preset,
+ String altitle,
jalview.datamodel.AlignmentView msa, boolean submitGaps,
boolean preserveOrder, AlignmentI seqdataset,
AlignFrame _alignFrame)
* DOCUMENT ME!
*/
- public MsaWSClient(Jws2Instance sh, WsParamSetI preset,
- List<Argument> arguments, boolean editParams, String altitle,
+ public MsaWSClient(ServiceWithParameters sh, WsParamSetI preset,
+ List<ArgumentI> arguments, boolean editParams, String altitle,
jalview.datamodel.AlignmentView msa, boolean submitGaps,
boolean preserveOrder, AlignmentI seqdataset,
AlignFrame _alignFrame)
{
super(_alignFrame, preset, arguments);
- if (!processParams(sh, editParams))
- {
- return;
- }
-
- if (!(sh.service instanceof MsaWS))
- {
- // redundant at mo - but may change
- JvOptionPane.showMessageDialog(Desktop.desktop,
- MessageManager.formatMessage(
- "label.service_called_is_not_msa_service",
- new String[]
- { sh.serviceType }),
- MessageManager.getString("label.internal_jalview_error"),
- JvOptionPane.WARNING_MESSAGE);
-
- return;
- }
- server = (MsaWS) sh.service;
- if ((wsInfo = setWebService(sh, false)) == null)
- {
- JvOptionPane.showMessageDialog(Desktop.desktop, MessageManager
- .formatMessage("label.msa_service_is_unknown", new String[]
- { sh.serviceType }),
- MessageManager.getString("label.internal_jalview_error"),
- JvOptionPane.WARNING_MESSAGE);
-
- return;
- }
-
- startMsaWSClient(altitle, msa, submitGaps, preserveOrder, seqdataset);
+ processParams(sh, editParams).thenAccept((startJob) -> {
+ if (!startJob)
+ return;
+
+ if (!(sh instanceof JalviewServiceEndpointProviderI
+ && ((JalviewServiceEndpointProviderI) sh)
+ .getEndpoint() instanceof MultipleSequenceAlignmentI))
+ {
+ // redundant at mo - but may change
+ JvOptionPane.showMessageDialog(Desktop.getDesktopPane(),
+ MessageManager.formatMessage(
+ "label.service_called_is_not_msa_service",
+ new String[]
+ { sh.getName() }),
+ MessageManager.getString("label.internal_jalview_error"),
+ JvOptionPane.WARNING_MESSAGE);
+
+ return;
+ }
+ serviceHandle = sh;
+ server = (MultipleSequenceAlignmentI) ((JalviewServiceEndpointProviderI) sh)
+ .getEndpoint();
+ if ((wsInfo = setWebService(sh, false)) == null)
+ {
+ JvOptionPane.showMessageDialog(Desktop.getDesktopPane(), MessageManager
+ .formatMessage("label.msa_service_is_unknown", new String[]
+ { sh.getName() }),
+ MessageManager.getString("label.internal_jalview_error"),
+ JvOptionPane.WARNING_MESSAGE);
+
+ return;
+ }
+
+ startMsaWSClient(altitle, msa, submitGaps, preserveOrder, seqdataset);
+ });
}
@Override
public void attachWSMenuEntry(JMenu rmsawsmenu,
- final Jws2Instance service, final AlignFrame af)
+ final Jws2Instance service, final AlignFrame alignFrame)
{
- if (registerAAConWSInstance(rmsawsmenu, service, af))
+ if (registerAAConWSInstance(rmsawsmenu, service, alignFrame))
{
// Alignment dependent analysis calculation WS gui
return;
}
+ serviceHandle = service;
setWebService(service, true); // headless
+ attachWSMenuEntry(rmsawsmenu, alignFrame);
+ }
+
+ @Override
+ public void attachWSMenuEntry(JMenu wsmenu, AlignFrame alignFrame)
+ {
boolean finished = true, submitGaps = false;
- JMenu msawsmenu = rmsawsmenu;
+ /**
+ * temp variables holding msa service submenu or root service menu
+ */
+ JMenu msawsmenu = wsmenu;
+ JMenu rmsawsmenu = wsmenu;
String svcname = WebServiceName;
if (svcname.endsWith("WS"))
{
rmsawsmenu.add(msawsmenu);
calcName = "";
}
- boolean hasparams = service.hasParameters();
+ boolean hasparams = serviceHandle.hasParameters();
+ ServiceWithParameters service = (ServiceWithParameters) serviceHandle;
do
{
String action = "Align ";
@Override
public void actionPerformed(ActionEvent e)
{
- AlignmentView msa = af.gatherSequencesForAlignment();
+ AlignmentView msa = alignFrame.gatherSequencesForAlignment();
if (msa != null)
{
- new MsaWSClient(service, af.getTitle(), msa, withGaps,
+ new MsaWSClient(service, alignFrame.getTitle(), msa, withGaps,
true,
- af.getViewport().getAlignment().getDataset(),
- af);
+ alignFrame.getViewport().getAlignment().getDataset(),
+ alignFrame);
}
}
@Override
public void actionPerformed(ActionEvent e)
{
- AlignmentView msa = af.gatherSequencesForAlignment();
+ AlignmentView msa = alignFrame.gatherSequencesForAlignment();
if (msa != null)
{
- startJob(service, af, withGaps, msa);
+ new MsaWSClient(service, null, null, true,
+ alignFrame.getTitle(), msa, withGaps, true,
+ alignFrame.getViewport().getAlignment().getDataset(),
+ alignFrame);
}
}
final int showToolTipFor = ToolTipManager.sharedInstance()
.getDismissDelay();
- for (final WsParamSetI preSet : presets)
+ for (final WsParamSetI preset : presets)
{
- final JMenuItem methodR = new JMenuItem(preSet.getName());
+ final JMenuItem methodR = new JMenuItem(preset.getName());
final int QUICK_TOOLTIP = 1500;
// JAL-1582 shorten tooltip display time in these menu items as
// they can obscure other options
});
String tooltip = JvSwingUtils.wrapTooltip(true, "<strong>"
- + (preSet.isModifiable()
+ + (preset.isModifiable()
? MessageManager.getString("label.user_preset")
: MessageManager
.getString("label.service_preset"))
- + "</strong><br/>" + preSet.getDescription());
+ + "</strong><br/>" + preset.getDescription());
methodR.setToolTipText(tooltip);
methodR.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
- AlignmentView msa = af
+ AlignmentView msa = alignFrame
.gatherSequencesForAlignment();
if (msa != null)
{
- MsaWSClient msac = new MsaWSClient(service, preSet,
- af.getTitle(), msa, false, true,
- af.getViewport().getAlignment()
+ MsaWSClient msac = new MsaWSClient(service, preset,
+ alignFrame.getTitle(), msa, false, true,
+ alignFrame.getViewport().getAlignment()
.getDataset(),
- af);
+ alignFrame);
}
}
}
} while (!finished);
}
-
- protected void startJob(final Jws2Instance service, final AlignFrame af,
- final boolean withGaps, AlignmentView msa)
- {
- try {
- new MsaWSClient(service, null, null, true,
- af.getTitle(), msa, withGaps, true,
- af.getViewport().getAlignment().getDataset(),
- af);
- } catch (Exception e) {
- JvOptionPane.showMessageDialog(alignFrame, e.getMessage(),
- MessageManager.getString("label.state_job_error"),
- JvOptionPane.WARNING_MESSAGE);
-
- }
- }
}
public static List<String> writeParameterSet(List<Option> optSet,
String pseparator)
{
- List<String> pset = new ArrayList<String>();
+ List<String> pset = new ArrayList<>();
for (Option o : optSet)
{
pset.add(o.toCommand(pseparator));
public static List<Option> processParameters(List<String> params,
RunnerConfig options, String pseparator)
{
- List<Option> chosenOptions = new ArrayList<Option>();
+ List<Option> chosenOptions = new ArrayList<>();
for (String param : params)
{
String oname = null;
--- /dev/null
+package jalview.ws.jws2;
+
+import jalview.ws.api.ServiceWithParameters;
+
+@FunctionalInterface
+public interface PreferredServiceChangeListener
+{
+ public void preferredServiceChanged(ServiceWithParameters newValue);
+}
--- /dev/null
+package jalview.ws.jws2;
+
+import jalview.bin.Cache;
+import jalview.gui.AlignFrame;
+import jalview.gui.Desktop;
+import jalview.gui.JvSwingUtils;
+import jalview.util.MessageManager;
+import jalview.ws.api.ServiceWithParameters;
+
+import java.awt.Color;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+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 javax.swing.JMenu;
+import javax.swing.JMenuItem;
+
+public class PreferredServiceRegistry
+{
+
+ private static PreferredServiceRegistry us = new PreferredServiceRegistry();
+
+ public static PreferredServiceRegistry getRegistry()
+ {
+ if (us == null)
+ {
+ us = new PreferredServiceRegistry();
+ }
+ return us;
+ }
+
+ List<ServiceWithParameters> ourServices = new ArrayList<>();
+
+ /**
+ * forget about any known services
+ */
+ public void clearServices()
+ {
+ ourServices.clear();
+ }
+
+ public void populateWSMenuEntry(List<ServiceWithParameters> services,
+ PreferredServiceChangeListener changeListener, JMenu menu,
+ final AlignFrame alignFrame, String typeFilter)
+ {
+ /**
+ * eventually, JWS2 services will appear under the same align/etc submenus.
+ * for moment we keep them separate.
+ */
+ ourServices.addAll(services);
+ JMenu atpoint;
+
+ List<ServiceWithParameters> oneshotServices = new ArrayList<>();
+ List<ServiceWithParameters> interactiveServices = new ArrayList<>();
+ Map<String, ServiceWithParameters> preferredHosts = new HashMap<>();
+ Map<String, List<ServiceWithParameters>> alternates = new HashMap<>();
+
+ for (var service : services)
+ {
+ if (service.isInteractiveUpdate())
+ interactiveServices.add(service);
+ else
+ oneshotServices.add(service);
+ }
+ for (var service : interactiveServices)
+ {
+ if (!preferredHosts.containsKey(service.getName()))
+ {
+ var preferred = getPreferredServiceFor(alignFrame, service.getName());
+ preferredHosts.put(service.getName(), (preferred != null) ? preferred : service);
+ }
+ var ph = alternates.getOrDefault(service.getName(), new ArrayList<>());
+ if (!preferredHosts.containsValue(service))
+ {
+ ph.add(service);
+ alternates.putIfAbsent(service.getName(), ph);
+ }
+ }
+
+ // create GUI element for classic services
+ addEnumeratedServices(menu, alignFrame, oneshotServices);
+ // and the instantaneous services
+ for (final ServiceWithParameters service : preferredHosts.values())
+ {
+ atpoint = JvSwingUtils.findOrCreateMenu(menu,
+ service.getServiceType());
+ if (atpoint.getItemCount() > 1)
+ {
+ // previous service of this type already present
+ atpoint.addSeparator();
+ }
+ JMenuItem hitm;
+ atpoint.add(hitm = new JMenuItem(service.getHostURL()));
+ hitm.setForeground(Color.blue);
+ hitm.addActionListener(e -> Desktop.showUrl(service.getHostURL()));
+ hitm.setToolTipText(JvSwingUtils.wrapTooltip(false,
+ MessageManager.getString("label.open_jabaws_web_page")));
+
+ service.attachWSMenuEntry(atpoint, alignFrame);
+ if (alternates.containsKey(service.getName()))
+ {
+ atpoint.add(hitm = new JMenu(
+ MessageManager.getString("label.switch_server")));
+ hitm.setToolTipText(JvSwingUtils.wrapTooltip(false,
+ MessageManager.getString("label.choose_jabaws_server")));
+ for (final ServiceWithParameters sv : alternates
+ .get(service.getName()))
+ {
+ JMenuItem itm;
+ hitm.add(itm = new JMenuItem(sv.getHostURL()));
+ itm.setForeground(Color.blue);
+ itm.addActionListener(e -> {
+ setPreferredServiceFor(alignFrame, sv.getName(), sv.getServiceType(), sv);
+ changeListener.preferredServiceChanged(sv);
+ });
+ }
+ }
+ }
+ }
+
+ /**
+ * add services using the Java 2.5/2.6/2.7 system which optionally creates
+ * submenus to index by host and service program type
+ */
+ private void addEnumeratedServices(final JMenu jws2al,
+ final AlignFrame alignFrame,
+ List<ServiceWithParameters> enumerableServices)
+ {
+ boolean byhost = Cache.getDefault("WSMENU_BYHOST", false),
+ bytype = Cache.getDefault("WSMENU_BYTYPE", false);
+ /**
+ * eventually, JWS2 services will appear under the same align/etc submenus.
+ * for moment we keep them separate.
+ */
+ JMenu atpoint;
+
+ List<String> hostLabels = new ArrayList<>();
+ Hashtable<String, String> lasthostFor = new Hashtable<>();
+ Hashtable<String, ArrayList<ServiceWithParameters>> hosts = new Hashtable<>();
+ ArrayList<String> hostlist = new ArrayList<>();
+ for (ServiceWithParameters service : enumerableServices)
+ {
+ ArrayList<ServiceWithParameters> hostservices = hosts
+ .get(service.getHostURL());
+ if (hostservices == null)
+ {
+ hosts.put(service.getHostURL(), hostservices = new ArrayList<>());
+ hostlist.add(service.getHostURL());
+ }
+ hostservices.add(service);
+ }
+ // now add hosts in order of the given array
+ for (String host : hostlist)
+ {
+ ServiceWithParameters orderedsvcs[] = hosts.get(host)
+ .toArray(new ServiceWithParameters[1]);
+ String sortbytype[] = new String[orderedsvcs.length];
+ for (int i = 0; i < sortbytype.length; i++)
+ {
+ sortbytype[i] = orderedsvcs[i].getName();
+ }
+ jalview.util.QuickSort.sort(sortbytype, orderedsvcs);
+ for (final ServiceWithParameters service : orderedsvcs)
+ {
+ atpoint = JvSwingUtils.findOrCreateMenu(jws2al,
+ service.getAction());
+ String type = service.getName();
+ if (byhost)
+ {
+ atpoint = JvSwingUtils.findOrCreateMenu(atpoint, host);
+ if (atpoint.getToolTipText() == null)
+ {
+ atpoint.setToolTipText(MessageManager
+ .formatMessage("label.services_at", new String[]
+ { host }));
+ }
+ }
+ if (bytype)
+ {
+ atpoint = JvSwingUtils.findOrCreateMenu(atpoint, type);
+ if (atpoint.getToolTipText() == null)
+ {
+ atpoint.setToolTipText(service.getActionText());
+ }
+ }
+ if (!byhost && !hostLabels.contains(
+ host + service.getName() + service.getActionText()))
+ // !hostLabels.contains(host + (bytype ?
+ // service.serviceType+service.getActionText() : "")))
+ {
+ // add a marker indicating where this service is hosted
+ // relies on services from the same host being listed in a
+ // contiguous
+ // group
+ JMenuItem hitm;
+ if (hostLabels.contains(host))
+ {
+ atpoint.addSeparator();
+ }
+ else
+ {
+ hostLabels.add(host);
+ }
+ if (lasthostFor.get(service.getAction()) == null
+ || !lasthostFor.get(service.getAction()).equals(host))
+ {
+ atpoint.add(hitm = new JMenuItem(host));
+ hitm.setForeground(Color.blue);
+ hitm.addActionListener(new ActionListener()
+ {
+
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ Desktop.showUrl(service.getHostURL());
+ }
+ });
+ hitm.setToolTipText(
+ JvSwingUtils.wrapTooltip(true, MessageManager
+ .getString("label.open_jabaws_web_page")));
+ lasthostFor.put(service.getAction(), host);
+ }
+ hostLabels
+ .add(host + service.getName() + service.getActionText());
+ }
+
+ service.attachWSMenuEntry(atpoint, alignFrame);
+ }
+ }
+ }
+
+ /**
+ * pick the user's preferred service based on a set of URLs (jaba server
+ * locations) and service URIs (specifying version and service interface
+ * class)
+ *
+ * @param serviceURL
+ * @return null or best match for given uri/ls.
+ */
+ public ServiceWithParameters getPreferredServiceFor(String[] serviceURLs)
+ {
+ HashSet<String> urls = new HashSet<>();
+ urls.addAll(Arrays.asList(serviceURLs));
+ ServiceWithParameters match = null;
+
+ if (ourServices != null)
+ {
+ for (ServiceWithParameters svc : ourServices)
+ {
+ // TODO getNameURI Should return a versioned URI for the service, but
+ // doesn't as of 2.11
+ if (urls.contains(svc.getNameURI()))
+ {
+ if (match == null)
+ {
+ // for moment we always pick service from server ordered first in
+ // user's preferences
+ match = svc;
+ }
+ if (urls.contains(svc.getUri()))
+ {
+ // stop and return - we've matched type URI and URI for service
+ // endpoint
+ return svc;
+ }
+ }
+ }
+ }
+ return match;
+ }
+
+ Map<String, Map<String, String>> preferredServiceMap = new HashMap<>();
+
+ /**
+ * get current preferred endpoint of the given Jabaws service, or global
+ * default
+ *
+ * @param af
+ * null or a specific alignFrame
+ * @param serviceName
+ * ServiceWithParameters.getName() for service
+ * @return null if no service of this type is available, the preferred service
+ * for the serviceType and af if specified and if defined.
+ */
+ public ServiceWithParameters getPreferredServiceFor(AlignFrame af,
+ String serviceName)
+ {
+ String serviceurl = null;
+ synchronized (preferredServiceMap)
+ {
+ String afid = (af == null) ? "" : af.getViewport().getSequenceSetId();
+ Map<String, String> prefmap = preferredServiceMap.get(afid);
+ if (afid.length() > 0 && prefmap == null)
+ {
+ // recover global setting, if any
+ prefmap = preferredServiceMap.get("");
+ }
+ if (prefmap != null)
+ {
+ serviceurl = prefmap.get(serviceName);
+ }
+
+ }
+ ServiceWithParameters response = null;
+ for (ServiceWithParameters svc : ourServices)
+ {
+ if (svc.getName().equals(serviceName))
+ {
+ if (serviceurl == null || serviceurl.equals(svc.getHostURL()))
+ {
+ response = svc;
+ break;
+ }
+ }
+ }
+ return response;
+ }
+
+ public void setPreferredServiceFor(AlignFrame af, String serviceName,
+ String serviceAction, ServiceWithParameters selectedServer)
+ {
+ // TODO: pull out and generalise for the selectedServer's attributes
+ String afid = (af == null) ? "" : af.getViewport().getSequenceSetId();
+ if (preferredServiceMap == null)
+ {
+ preferredServiceMap = new HashMap<>();
+ }
+ Map<String, String> prefmap = preferredServiceMap.get(afid);
+ if (prefmap == null)
+ {
+ prefmap = new HashMap<>();
+ preferredServiceMap.put(afid, prefmap);
+ }
+ prefmap.put(serviceName, selectedServer.getHostURL());
+ prefmap.put(serviceAction, selectedServer.getHostURL());
+ }
+
+ public void setPreferredServiceFor(String serviceType,
+ String serviceAction, ServiceWithParameters selectedServer)
+ {
+ setPreferredServiceFor(null, serviceType, serviceAction,
+ selectedServer);
+ }
+
+ public boolean contains(ServiceWithParameters service)
+ {
+ return ourServices.contains(service);
+ }
+
+}
--- /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.jws2;
+
+import jalview.analysis.AlignSeq;
+import jalview.analysis.AlignmentAnnotationUtils;
+import jalview.analysis.SeqsetUtils;
+import jalview.api.AlignViewportI;
+import jalview.api.AlignmentViewPanel;
+import jalview.api.FeatureColourI;
+import jalview.api.PollableAlignCalcWorkerI;
+import jalview.bin.Cache;
+import jalview.datamodel.AlignmentAnnotation;
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.AnnotatedCollectionI;
+import jalview.datamodel.Annotation;
+import jalview.datamodel.ContiguousI;
+import jalview.datamodel.Mapping;
+import jalview.datamodel.SequenceI;
+import jalview.datamodel.features.FeatureMatcherSetI;
+import jalview.gui.AlignFrame;
+import jalview.gui.Desktop;
+import jalview.gui.IProgressIndicator;
+import jalview.gui.IProgressIndicatorHandler;
+import jalview.gui.JvOptionPane;
+import jalview.gui.WebserviceInfo;
+import jalview.schemes.FeatureSettingsAdapter;
+import jalview.schemes.ResidueProperties;
+import jalview.util.MapList;
+import jalview.util.MessageManager;
+import jalview.workers.AlignCalcWorker;
+import jalview.ws.JobStateSummary;
+import jalview.ws.api.CancellableI;
+import jalview.ws.api.JalviewServiceEndpointProviderI;
+import jalview.ws.api.JobId;
+import jalview.ws.api.SequenceAnnotationServiceI;
+import jalview.ws.api.ServiceWithParameters;
+import jalview.ws.api.WSAnnotationCalcManagerI;
+import jalview.ws.gui.AnnotationWsJob;
+import jalview.ws.jws2.dm.AAConSettings;
+import jalview.ws.params.ArgumentI;
+import jalview.ws.params.WsParamSetI;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class SeqAnnotationServiceCalcWorker extends AlignCalcWorker
+ implements WSAnnotationCalcManagerI, PollableAlignCalcWorkerI
+{
+
+ protected ServiceWithParameters service;
+
+ protected WsParamSetI preset;
+
+ protected List<ArgumentI> arguments;
+
+ protected IProgressIndicator guiProgress;
+
+ protected boolean submitGaps = true;
+
+ /**
+ * by default, we filter out non-standard residues before submission
+ */
+ protected boolean filterNonStandardResidues = true;
+
+ /**
+ * Recover any existing parameters for this service
+ */
+ protected void initViewportParams()
+ {
+ if (getCalcId() != null)
+ {
+ ((jalview.gui.AlignViewport) alignViewport).setCalcIdSettingsFor(
+ getCalcId(),
+ new AAConSettings(true, service, this.preset, arguments),
+ true);
+ }
+ }
+
+ /**
+ *
+ * @return null or a string used to recover all annotation generated by this
+ * worker
+ */
+ public String getCalcId()
+ {
+ return service.getAlignAnalysisUI() == null ? null
+ : service.getAlignAnalysisUI().getCalcId();
+ }
+
+ public WsParamSetI getPreset()
+ {
+ return preset;
+ }
+
+ public List<ArgumentI> getArguments()
+ {
+ return arguments;
+ }
+
+ /**
+ * reconfigure and restart the AAConClient. This method will spawn a new
+ * thread that will wait until any current jobs are finished, modify the
+ * parameters and restart the conservation calculation with the new values.
+ *
+ * @param newpreset
+ * @param newarguments
+ */
+ public void updateParameters(final WsParamSetI newpreset,
+ final List<ArgumentI> newarguments)
+ {
+ preset = newpreset;
+ arguments = newarguments;
+ calcMan.startWorker(this);
+ initViewportParams();
+ }
+ protected boolean alignedSeqs = true;
+
+ protected boolean nucleotidesAllowed = false;
+
+ protected boolean proteinAllowed = false;
+
+ /**
+ * record sequences for mapping result back to afterwards
+ */
+ protected boolean bySequence = false;
+
+ protected Map<String, SequenceI> seqNames;
+
+ // TODO: convert to bitset
+ protected boolean[] gapMap;
+
+ int realw;
+
+ protected int start;
+
+ int end;
+
+ private AlignFrame alignFrame;
+
+ public boolean[] getGapMap()
+ {
+ return gapMap;
+ }
+
+ public SeqAnnotationServiceCalcWorker(ServiceWithParameters service,
+ AlignFrame alignFrame,
+ WsParamSetI preset, List<ArgumentI> paramset)
+ {
+ super(alignFrame.getCurrentView(), alignFrame.alignPanel);
+ // TODO: both these fields needed ?
+ this.alignFrame = alignFrame;
+ this.guiProgress = alignFrame;
+ this.preset = preset;
+ this.arguments = paramset;
+ this.service = service;
+ try
+ {
+ annotService = (jalview.ws.api.SequenceAnnotationServiceI) ((JalviewServiceEndpointProviderI) service)
+ .getEndpoint();
+ } catch (ClassCastException cce)
+ {
+ annotService = null;
+ JvOptionPane.showMessageDialog(Desktop.getInstance(),
+ MessageManager.formatMessage(
+ "label.service_called_is_not_an_annotation_service",
+ new String[]
+ { service.getName() }),
+ MessageManager.getString("label.internal_jalview_error"),
+ JvOptionPane.WARNING_MESSAGE);
+
+ }
+ cancellable = CancellableI.class.isInstance(annotService);
+ // configure submission flags
+ proteinAllowed = service.isProteinService();
+ nucleotidesAllowed = service.isNucleotideService();
+ alignedSeqs = service.isNeedsAlignedSequences();
+ bySequence = !service.isAlignmentAnalysis();
+ filterNonStandardResidues = service.isFilterSymbols();
+ min_valid_seqs = service.getMinimumInputSequences();
+ submitGaps = service.isAlignmentAnalysis();
+
+ if (service.isInteractiveUpdate())
+ {
+ initViewportParams();
+ }
+ }
+
+ /**
+ *
+ * @return true if the submission thread should attempt to submit data
+ */
+ public boolean hasService()
+ {
+ return annotService != null;
+ }
+
+ protected SequenceAnnotationServiceI annotService;
+ protected final boolean cancellable;
+
+ volatile JobId rslt = null;
+
+ AnnotationWsJob running = null;
+
+ private int min_valid_seqs;
+
+
+ private long progressId = -1;
+ JobStateSummary job = null;
+ WebserviceInfo info = null;
+ List<SequenceI> seqs = null;
+
+ @Override public void startUp() throws Throwable
+ {
+ if (alignViewport.isClosed())
+ {
+ abortAndDestroy();
+ return;
+ }
+ if (!hasService())
+ {
+ return;
+ }
+
+ StringBuffer msg = new StringBuffer();
+ job = new JobStateSummary();
+ info = new WebserviceInfo("foo", "bar", false);
+
+ seqs = getInputSequences(
+ alignViewport.getAlignment(),
+ bySequence ? alignViewport.getSelectionGroup() : null);
+
+ if (seqs == null || !checkValidInputSeqs(seqs))
+ {
+ jalview.bin.Cache.log.debug(
+ "Sequences for analysis service were null or not valid");
+ return;
+ }
+
+ if (guiProgress != null)
+ {
+ guiProgress.setProgressBar(service.getActionText(),
+ progressId = System.currentTimeMillis());
+ }
+ jalview.bin.Cache.log.debug("submitted " + seqs.size()
+ + " sequences to " + service.getActionText());
+
+ rslt = annotService.submitToService(seqs, getPreset(),
+ getArguments());
+ if (rslt == null)
+ {
+ return;
+ }
+ // TODO: handle job submission error reporting here.
+ Cache.log.debug("Service " + service.getUri() + "\nSubmitted job ID: "
+ + rslt);
+ // ///
+ // otherwise, construct WsJob and any UI handlers
+ running = new AnnotationWsJob();
+ running.setJobHandle(rslt);
+ running.setSeqNames(seqNames);
+ running.setStartPos(start);
+ running.setSeqs(seqs);
+ job.updateJobPanelState(info, "", running);
+ if (guiProgress != null)
+ {
+ guiProgress.registerHandler(progressId,
+ new IProgressIndicatorHandler()
+ {
+
+ @Override
+ public boolean cancelActivity(long id)
+ {
+ calcMan.cancelWorker(SeqAnnotationServiceCalcWorker.this);
+ return true;
+ }
+
+ @Override
+ public boolean canCancel()
+ {
+ return cancellable;
+ }
+ });
+ }
+ }
+
+ @Override public boolean poll() throws Throwable
+ {
+ boolean finished = false;
+
+ Cache.log.debug("Updating status for annotation service.");
+ annotService.updateStatus(running);
+ job.updateJobPanelState(info, "", running);
+ if (running.isSubjobComplete())
+ {
+ Cache.log.debug(
+ "Finished polling analysis service job: status reported is "
+ + running.getState());
+ finished = true;
+ }
+ else
+ {
+ Cache.log.debug("Status now " + running.getState());
+ }
+
+ // pull any stats - some services need to flush log output before
+ // results are available
+ Cache.log.debug("Updating progress log for annotation service.");
+
+ try
+ {
+ annotService.updateJobProgress(running);
+ } catch (Throwable thr)
+ {
+ Cache.log.debug("Ignoring exception during progress update.",
+ thr);
+ }
+ Cache.log.debug("Result of poll: " + running.getStatus());
+
+
+ if (finished)
+ {
+ Cache.log.debug("Job poll loop exited. Job is " + running.getState());
+ if (running.isFinished())
+ {
+ // expect there to be results to collect
+ // configure job with the associated view's feature renderer, if one
+ // exists.
+ // TODO: here one would also grab the 'master feature renderer' in order
+ // to enable/disable
+ // features automatically according to user preferences
+ running.setFeatureRenderer(
+ ((jalview.gui.AlignmentPanel) ap).cloneFeatureRenderer());
+ Cache.log.debug("retrieving job results.");
+ final Map<String, FeatureColourI> featureColours = new HashMap<>();
+ final Map<String, FeatureMatcherSetI> featureFilters = new HashMap<>();
+ List<AlignmentAnnotation> returnedAnnot = annotService
+ .getAnnotationResult(running.getJobHandle(), seqs,
+ featureColours, featureFilters);
+
+ Cache.log.debug("Obtained " + (returnedAnnot == null ? "no rows"
+ : ("" + returnedAnnot.size())));
+ Cache.log.debug("There were " + featureColours.size()
+ + " feature colours and " + featureFilters.size()
+ + " filters defined.");
+
+ // TODO
+ // copy over each annotation row reurned and also defined on each
+ // sequence, excluding regions not annotated due to gapMap/column
+ // visibility
+
+ // update calcId if it is not already set on returned annotation
+ if (returnedAnnot != null)
+ {
+ for (AlignmentAnnotation aa : returnedAnnot)
+ {
+ // assume that any CalcIds already set
+ if (getCalcId() != null && aa.getCalcId() == null
+ || "".equals(aa.getCalcId()))
+ {
+ aa.setCalcId(getCalcId());
+ }
+ // autocalculated annotation are created by interactive alignment
+ // analysis services
+ aa.autoCalculated = service.isAlignmentAnalysis()
+ && service.isInteractiveUpdate();
+ }
+ }
+
+ running.setAnnotation(returnedAnnot);
+
+ if (running.hasResults())
+ {
+ jalview.bin.Cache.log.debug("Updating result annotation from Job "
+ + rslt + " at " + service.getUri());
+ updateResultAnnotation(true);
+ if (running.isTransferSequenceFeatures())
+ {
+ // TODO
+ // look at each sequence and lift over any features, excluding
+ // regions
+ // not annotated due to gapMap/column visibility
+
+ jalview.bin.Cache.log.debug(
+ "Updating feature display settings and transferring features from Job "
+ + rslt + " at " + service.getUri());
+ // TODO: consider merge rather than apply here
+ alignViewport.applyFeaturesStyle(new FeatureSettingsAdapter()
+ {
+ @Override
+ public FeatureColourI getFeatureColour(String type)
+ {
+ return featureColours.get(type);
+ }
+
+ @Override
+ public FeatureMatcherSetI getFeatureFilters(String type)
+ {
+ return featureFilters.get(type);
+ }
+
+ @Override
+ public boolean isFeatureDisplayed(String type)
+ {
+ return featureColours.containsKey(type);
+ }
+
+ });
+ // TODO: JAL-1150 - create sequence feature settings API for
+ // defining
+ // styles and enabling/disabling feature overlay on alignment panel
+
+ if (alignFrame.alignPanel == ap)
+ {
+ alignViewport.setShowSequenceFeatures(true);
+ alignFrame.setMenusForViewport();
+ }
+ }
+ ap.adjustAnnotationHeight();
+ }
+ }
+ Cache.log.debug("Annotation Service Worker thread finished.");
+
+ }
+
+ return finished;
+ }
+
+ @Override public void cancel()
+ {
+ cancelCurrentJob();
+ }
+
+ @Override public void done()
+ {
+ if (ap != null)
+ {
+ if (guiProgress != null && progressId != -1)
+ {
+ guiProgress.removeProgressBar(progressId);
+ }
+ // TODO: may not need to paintAlignment again !
+ ap.paintAlignment(false, false);
+ }
+ }
+
+ /**
+ * validate input for dynamic/non-dynamic update context TODO: move to
+ * analysis interface ?
+ * @param seqs
+ *
+ * @return true if input is valid
+ */
+ boolean checkValidInputSeqs(List<SequenceI> seqs)
+ {
+ int nvalid = 0;
+ for (SequenceI sq : seqs)
+ {
+ if (sq.getStart() <= sq.getEnd()
+ && (sq.isProtein() ? proteinAllowed : nucleotidesAllowed))
+ {
+ if (submitGaps
+ || sq.getLength() == (sq.getEnd() - sq.getStart() + 1))
+ {
+ nvalid++;
+ }
+ }
+ }
+ return nvalid >= min_valid_seqs;
+ }
+
+ public void cancelCurrentJob()
+ {
+ try
+ {
+ String id = running.getJobId();
+ if (cancellable && ((CancellableI) annotService).cancel(running))
+ {
+ System.err.println("Cancelled job " + id);
+ }
+ else
+ {
+ System.err.println("Job " + id + " couldn't be cancelled.");
+ }
+ } catch (Exception q)
+ {
+ q.printStackTrace();
+ }
+ }
+
+ /**
+ * Interactive updating. Analysis calculations that work on the currently
+ * displayed alignment data should cancel existing jobs when the input data
+ * has changed.
+ *
+ * @return true if a running job should be cancelled because new input data is
+ * available for analysis
+ */
+ boolean isInteractiveUpdate()
+ {
+ return service.isInteractiveUpdate();
+ }
+
+ /**
+ * decide what sequences will be analysed TODO: refactor to generate
+ * List<SequenceI> for submission to service interface
+ *
+ * @param alignment
+ * @param inputSeqs
+ * @return
+ */
+ public List<SequenceI> getInputSequences(AlignmentI alignment,
+ AnnotatedCollectionI inputSeqs)
+ {
+ if (alignment == null || alignment.getWidth() <= 0
+ || alignment.getSequences() == null || alignment.isNucleotide()
+ ? !nucleotidesAllowed
+ : !proteinAllowed)
+ {
+ return null;
+ }
+ if (inputSeqs == null || inputSeqs.getWidth() <= 0
+ || inputSeqs.getSequences() == null
+ || inputSeqs.getSequences().size() < 1)
+ {
+ inputSeqs = alignment;
+ }
+
+ List<SequenceI> seqs = new ArrayList<>();
+
+ int minlen = 10;
+ int ln = -1;
+ if (bySequence)
+ {
+ seqNames = new HashMap<>();
+ }
+ gapMap = new boolean[0];
+ start = inputSeqs.getStartRes();
+ end = inputSeqs.getEndRes();
+ // TODO: URGENT! unify with JPred / MSA code to handle hidden regions
+ // correctly
+ // TODO: push attributes into WsJob instance (so they can be safely
+ // persisted/restored
+ for (SequenceI sq : (inputSeqs.getSequences()))
+ {
+ if (bySequence
+ ? sq.findPosition(end + 1)
+ - sq.findPosition(start + 1) > minlen - 1
+ : sq.getEnd() - sq.getStart() > minlen - 1)
+ {
+ String newname = SeqsetUtils.unique_name(seqs.size() + 1);
+ // make new input sequence with or without gaps
+ if (seqNames != null)
+ {
+ seqNames.put(newname, sq);
+ }
+ SequenceI seq;
+ if (submitGaps)
+ {
+ seqs.add(seq = new jalview.datamodel.Sequence(newname,
+ sq.getSequenceAsString()));
+ if (gapMap == null || gapMap.length < seq.getLength())
+ {
+ boolean[] tg = gapMap;
+ gapMap = new boolean[seq.getLength()];
+ System.arraycopy(tg, 0, gapMap, 0, tg.length);
+ for (int p = tg.length; p < gapMap.length; p++)
+ {
+ gapMap[p] = false; // init as a gap
+ }
+ }
+ for (int apos : sq.gapMap())
+ {
+ char sqc = sq.getCharAt(apos);
+ if (!filterNonStandardResidues
+ || (sq.isProtein() ? ResidueProperties.aaIndex[sqc] < 20
+ : ResidueProperties.nucleotideIndex[sqc] < 5))
+ {
+ gapMap[apos] = true; // aligned and real amino acid residue
+ }
+ ;
+ }
+ }
+ else
+ {
+ // TODO: add ability to exclude hidden regions
+ seqs.add(seq = new jalview.datamodel.Sequence(newname,
+ AlignSeq.extractGaps(jalview.util.Comparison.GapChars,
+ sq.getSequenceAsString(start, end + 1))));
+ // for annotation need to also record map to sequence start/end
+ // position in range
+ // then transfer back to original sequence on return.
+ }
+ if (seq.getLength() > ln)
+ {
+ ln = seq.getLength();
+ }
+ }
+ }
+ if (alignedSeqs && submitGaps)
+ {
+ realw = 0;
+ for (int i = 0; i < gapMap.length; i++)
+ {
+ if (gapMap[i])
+ {
+ realw++;
+ }
+ }
+ // try real hard to return something submittable
+ // TODO: some of AAcon measures need a minimum of two or three amino
+ // acids at each position, and AAcon doesn't gracefully degrade.
+ for (int p = 0; p < seqs.size(); p++)
+ {
+ SequenceI sq = seqs.get(p);
+ // strip gapped columns
+ char[] padded = new char[realw],
+ orig = sq.getSequence();
+ for (int i = 0, pp = 0; i < realw; pp++)
+ {
+ if (gapMap[pp])
+ {
+ if (orig.length > pp)
+ {
+ padded[i++] = orig[pp];
+ }
+ else
+ {
+ padded[i++] = '-';
+ }
+ }
+ }
+ seqs.set(p, new jalview.datamodel.Sequence(sq.getName(),
+ new String(padded)));
+ }
+ }
+ return seqs;
+ }
+
+ @Override
+ public void updateAnnotation()
+ {
+ updateResultAnnotation(false);
+ }
+
+ public void updateResultAnnotation(boolean immediate)
+ {
+ if ((immediate || !calcMan.isWorking(this)) && running != null
+ && running.hasResults())
+ {
+ List<AlignmentAnnotation> ourAnnot = running.getAnnotation(),
+ newAnnots = new ArrayList<>();
+ //
+ // update graphGroup for all annotation
+ //
+ /**
+ * find a graphGroup greater than any existing ones this could be a method
+ * provided by alignment Alignment.getNewGraphGroup() - returns next
+ * unused graph group
+ */
+ int graphGroup = 1;
+ if (alignViewport.getAlignment().getAlignmentAnnotation() != null)
+ {
+ for (AlignmentAnnotation ala : alignViewport.getAlignment()
+ .getAlignmentAnnotation())
+ {
+ if (ala.graphGroup > graphGroup)
+ {
+ graphGroup = ala.graphGroup;
+ }
+ }
+ }
+ /**
+ * update graphGroup in the annotation rows returned from service
+ */
+ // TODO: look at sequence annotation rows and update graph groups in the
+ // case of reference annotation.
+ for (AlignmentAnnotation ala : ourAnnot)
+ {
+ if (ala.graphGroup > 0)
+ {
+ ala.graphGroup += graphGroup;
+ }
+ SequenceI aseq = null;
+
+ /**
+ * transfer sequence refs and adjust gapmap
+ */
+ if (ala.sequenceRef != null)
+ {
+ SequenceI seq = running.getSeqNames()
+ .get(ala.sequenceRef.getName());
+ aseq = seq;
+ while (seq.getDatasetSequence() != null)
+ {
+ seq = seq.getDatasetSequence();
+ }
+ }
+ Annotation[] resAnnot = ala.annotations,
+ gappedAnnot = new Annotation[Math.max(
+ alignViewport.getAlignment().getWidth(),
+ gapMap.length)];
+ for (int p = 0, ap = start; ap < gappedAnnot.length; ap++)
+ {
+ if (gapMap != null && gapMap.length > ap && !gapMap[ap])
+ {
+ gappedAnnot[ap] = new Annotation("", "", ' ', Float.NaN);
+ }
+ else if (p < resAnnot.length)
+ {
+ gappedAnnot[ap] = resAnnot[p++];
+ }
+ }
+ ala.sequenceRef = aseq;
+ ala.annotations = gappedAnnot;
+ AlignmentAnnotation newAnnot = getAlignViewport().getAlignment()
+ .updateFromOrCopyAnnotation(ala);
+ if (aseq != null)
+ {
+
+ aseq.addAlignmentAnnotation(newAnnot);
+ newAnnot.adjustForAlignment();
+
+ AlignmentAnnotationUtils.replaceAnnotationOnAlignmentWith(
+ newAnnot, newAnnot.label, newAnnot.getCalcId());
+ }
+ newAnnots.add(newAnnot);
+
+ }
+ for (SequenceI sq : running.getSeqs())
+ {
+ if (!sq.getFeatures().hasFeatures()
+ && (sq.getDBRefs() == null || sq.getDBRefs().size() == 0))
+ {
+ continue;
+ }
+ running.setTransferSequenceFeatures(true);
+ SequenceI seq = running.getSeqNames().get(sq.getName());
+ SequenceI dseq;
+ ContiguousI seqRange = seq.findPositions(start, end);
+
+ while ((dseq = seq).getDatasetSequence() != null)
+ {
+ seq = seq.getDatasetSequence();
+ }
+ List<ContiguousI> sourceRange = new ArrayList();
+ if (gapMap != null && gapMap.length >= end)
+ {
+ int lastcol = start, col = start;
+ do
+ {
+ if (col == end || !gapMap[col])
+ {
+ if (lastcol <= (col - 1))
+ {
+ seqRange = seq.findPositions(lastcol, col);
+ sourceRange.add(seqRange);
+ }
+ lastcol = col + 1;
+ }
+ } while (++col <= end);
+ }
+ else
+ {
+ sourceRange.add(seq.findPositions(start, end));
+ }
+ int i = 0;
+ int source_startend[] = new int[sourceRange.size() * 2];
+
+ for (ContiguousI range : sourceRange)
+ {
+ source_startend[i++] = range.getBegin();
+ source_startend[i++] = range.getEnd();
+ }
+ Mapping mp = new Mapping(
+ new MapList(source_startend, new int[]
+ { seq.getStart(), seq.getEnd() }, 1, 1));
+ dseq.transferAnnotation(sq, mp);
+
+ }
+ updateOurAnnots(newAnnots);
+ }
+ }
+
+ protected void updateOurAnnots(List<AlignmentAnnotation> ourAnnot)
+ {
+ List<AlignmentAnnotation> our = ourAnnots;
+ ourAnnots = ourAnnot;
+ AlignmentI alignment = alignViewport.getAlignment();
+ if (our != null)
+ {
+ if (our.size() > 0)
+ {
+ for (AlignmentAnnotation an : our)
+ {
+ if (!ourAnnots.contains(an))
+ {
+ // remove the old annotation
+ alignment.deleteAnnotation(an);
+ }
+ }
+ }
+ our.clear();
+ }
+
+ // validate rows and update Alignmment state
+ for (AlignmentAnnotation an : ourAnnots)
+ {
+ alignViewport.getAlignment().validateAnnotation(an);
+ }
+ // TODO: may need a menu refresh after this
+ // af.setMenusForViewport();
+ ap.adjustAnnotationHeight();
+
+ }
+
+ public SequenceAnnotationServiceI getService()
+ {
+ return annotService;
+ }
+
+}
*/
package jalview.ws.jws2;
-import java.util.Locale;
-
import jalview.api.AlignCalcWorkerI;
import jalview.gui.AlignFrame;
import jalview.gui.Desktop;
import jalview.gui.JvSwingUtils;
import jalview.util.MessageManager;
-import jalview.ws.jws2.dm.AAConSettings;
-import jalview.ws.jws2.jabaws2.Jws2Instance;
+import jalview.ws.api.ServiceWithParameters;
+import jalview.ws.params.AutoCalcSetting;
import jalview.ws.params.WsParamSetI;
import jalview.ws.uimodel.AlignAnalysisUIText;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.List;
+import java.util.Locale;
+
import javax.swing.JMenu;
import javax.swing.JMenuItem;
// TODO Auto-generated constructor stub
}
- public SequenceAnnotationWSClient(final Jws2Instance sh,
+ public SequenceAnnotationWSClient(final ServiceWithParameters sh,
AlignFrame alignFrame, WsParamSetI preset, boolean editParams)
{
super(alignFrame, preset, null);
// dan think. Do I need to change this method to run RNAalifold through the
// GUI
- public void initSequenceAnnotationWSClient(final Jws2Instance sh,
- AlignFrame alignFrame, WsParamSetI preset, boolean editParams)
+ private void initSequenceAnnotationWSClient(final ServiceWithParameters sh,
+ AlignFrame alignFrame, final WsParamSetI preset, boolean editParams)
{
// dan changed! dan test. comment out if conditional
// if (alignFrame.getViewport().getAlignment().isNucleotide())
// columns
List<AlignCalcWorkerI> clnts = alignFrame.getViewport()
- .getCalcManager().getRegisteredWorkersOfClass(clientClass);
- AbstractJabaCalcWorker worker;
- if (clnts == null || clnts.size() == 0)
+ .getCalcManager()
+ .getWorkersOfClass(SeqAnnotationServiceCalcWorker.class);
+
+ SeqAnnotationServiceCalcWorker tmpworker = null;
+ if (clnts != null)
{
- if (!processParams(sh, editParams))
+ for (AlignCalcWorkerI _worker : clnts)
{
- return;
+ tmpworker = (SeqAnnotationServiceCalcWorker) _worker;
+ if (tmpworker.hasService()
+ && tmpworker.getService().getClass().equals(clientClass))
+ {
+ break;
+ }
+ tmpworker = null;
}
- try
- {
- worker = (AbstractJabaCalcWorker) (clientClass
- .getConstructor(new Class[]
- { Jws2Instance.class, AlignFrame.class, WsParamSetI.class,
- List.class })
- .newInstance(new Object[]
- { sh, alignFrame, this.preset, paramset }));
- } catch (Exception x)
- {
- x.printStackTrace();
- throw new Error(
+ }
+ final var worker = tmpworker;
+ if (worker == null)
+ {
+ processParams(sh, editParams).thenAccept((startJob) -> {
+ if (startJob)
+ {
+ final SeqAnnotationServiceCalcWorker worker_;
+ try
+ {
+ worker_ = new SeqAnnotationServiceCalcWorker(sh, alignFrame, this.preset,
+ paramset);
+ } catch (Exception x)
+ {
+ x.printStackTrace();
+ throw new Error(
MessageManager.getString("error.implementation_error"),
x);
- }
- alignFrame.getViewport().getCalcManager().registerWorker(worker);
- alignFrame.getViewport().getCalcManager().startWorker(worker);
+ }
+ alignFrame.getViewport().getCalcManager().registerWorker(worker_);
+ // also starts the worker
+ startSeqAnnotationWorker(sh, alignFrame, preset, editParams);
+ }
+ });
}
else
{
- worker = (AbstractJabaCalcWorker) clnts.get(0);
+ WsParamSetI preset_;
if (editParams)
{
paramset = worker.getArguments();
- preset = worker.getPreset();
+ preset_ = worker.getPreset();
+ }
+ else
+ {
+ preset_ = preset;
}
+ processParams(sh, editParams, true).thenAccept((startJob) -> {
+ if (startJob)
+ {
+ // reinstate worker if it was blacklisted (might have happened due
+ // to
+ // invalid parameters)
+ alignFrame.getViewport().getCalcManager().enableWorker(worker);
+ worker.updateParameters(this.preset, paramset);
+ startSeqAnnotationWorker(sh, alignFrame, preset_, editParams);
+ }
+ });
- if (!processParams(sh, editParams, true))
+ if (!processParams(sh, editParams, true).toCompletableFuture().join())
{
return;
}
- // reinstate worker if it was blacklisted (might have happened due to
- // invalid parameters)
- alignFrame.getViewport().getCalcManager().enableWorker(worker);
- worker.updateParameters(this.preset, paramset);
}
}
if (sh.action.toLowerCase(Locale.ROOT).contains("disorder"))
{
// build IUPred style client. take sequences, returns annotation per
// sequence.
- if (!processParams(sh, editParams))
- {
- return;
- }
-
- alignFrame.getViewport().getCalcManager().startWorker(
- new AADisorderClient(sh, alignFrame, preset, paramset));
+ processParams(sh, editParams).thenAccept((startJob) -> {
+ if (startJob)
+ {
+ alignFrame.getViewport().getCalcManager().startWorker(
+ new SeqAnnotationServiceCalcWorker(sh, alignFrame, preset, paramset));
+ }
+ });
}
}
- public SequenceAnnotationWSClient(AAConSettings fave,
+ public SequenceAnnotationWSClient(AutoCalcSetting fave,
AlignFrame alignFrame, boolean b)
{
- super(alignFrame, fave.getPreset(), fave.getJobArgset());
+ super(alignFrame, fave.getPreset(), fave.getArgumentSet());
initSequenceAnnotationWSClient(fave.getService(), alignFrame,
fave.getPreset(), b);
}
* @see jalview.ws.jws2.Jws2Client#attachWSMenuEntry(javax.swing.JMenu,
* jalview.ws.jws2.jabaws2.Jws2Instance, jalview.gui.AlignFrame)
*/
- public void attachWSMenuEntry(JMenu wsmenu, final Jws2Instance service,
+ @Override
+ public void attachWSMenuEntry(JMenu wsmenu,
+ final ServiceWithParameters service,
final AlignFrame alignFrame)
{
- if (registerAAConWSInstance(wsmenu, service, alignFrame))
+ if (Jws2ClientFactory.registerAAConWSInstance(wsmenu,
+ service, alignFrame))
{
// Alignment dependent analysis calculation WS gui
return;
}
boolean hasparams = service.hasParameters();
- // Assume name ends in WS
- String calcName = service.serviceType.substring(0,
- service.serviceType.length() - 2);
+ String calcName = service.getName();
+ if (calcName.endsWith("WS"))
+ {
+ // Remove "WS" suffix
+ calcName = calcName.substring(0, calcName.length() - 2);
+ }
JMenuItem annotservice = new JMenuItem(MessageManager.formatMessage(
"label.calcname_with_default_settings", new String[]
@Override
public void actionPerformed(ActionEvent e)
{
- new SequenceAnnotationWSClient(service, alignFrame, null, false);
+ new SequenceAnnotationWSClient(service, alignFrame,
+ null, false);
}
});
wsmenu.add(annotservice);
annotservice.addActionListener(new ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
- new SequenceAnnotationWSClient(service, alignFrame, null, true);
+ new SequenceAnnotationWSClient(service, alignFrame,
+ null, true);
}
});
wsmenu.add(annotservice);
+ "</strong><br/>" + preset.getDescription()));
methodR.addActionListener(new ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
- new SequenceAnnotationWSClient(service, alignFrame, preset,
+ new SequenceAnnotationWSClient(service,
+ alignFrame, preset,
false);
}
{
annotservice = new JMenuItem(
MessageManager.getString("label.view_documentation"));
- if (service.docUrl != null)
+ if (service != null && service.hasDocumentationUrl())
{
annotservice.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent arg0)
{
- Desktop.instance.showUrl(service.docUrl);
+ Desktop.getInstance().showUrl(service.getDocumentationUrl());
}
});
annotservice.setToolTipText(
JvSwingUtils.wrapTooltip(true, MessageManager.formatMessage(
"label.view_service_doc_url", new String[]
- { service.docUrl, service.docUrl })));
+ { service.getDocumentationUrl(),
+ service.getDocumentationUrl() })));
wsmenu.add(annotservice);
}
}
*/
package jalview.ws.jws2.dm;
-import jalview.util.MessageManager;
+import jalview.ws.api.ServiceWithParameters;
import jalview.ws.jws2.JabaParamStore;
-import jalview.ws.jws2.JabaPreset;
import jalview.ws.jws2.ParameterUtils;
-import jalview.ws.jws2.jabaws2.Jws2Instance;
import jalview.ws.params.ArgumentI;
import jalview.ws.params.WsParamSetI;
-import java.util.ArrayList;
import java.util.List;
-import compbio.metadata.Argument;
import compbio.metadata.Option;
/**
*/
public class AAConSettings extends jalview.ws.params.AutoCalcSetting
{
- Jws2Instance service;
-
- public AAConSettings(boolean autoUpdate, Jws2Instance service,
+ public AAConSettings(boolean autoUpdate, ServiceWithParameters service2,
WsParamSetI preset, List<ArgumentI> jobArgset)
{
- super(preset, jobArgset, autoUpdate);
- this.service = service;
- }
-
- public Jws2Instance getService()
- {
- return service;
- }
-
- public void setService(Jws2Instance service)
- {
- this.service = service;
- if (preset != null)
- {
- // migrate preset to new service
- for (String url : preset.getApplicableUrls())
- {
- if (url.equals(service.getUri()))
- {
- return;
- }
- }
- WsParamSetI pr = service.getParamStore().getPreset(preset.getName());
- if (pr instanceof JabaPreset && preset instanceof JabaPreset)
- {
- // easy - Presets are identical (we assume)
- preset = pr;
- return;
- }
- List<ArgumentI> oldargs = new ArrayList<ArgumentI>(),
- newargs = new ArrayList<ArgumentI>();
- oldargs.addAll(preset.getArguments());
- // need to compare parameters
- for (ArgumentI newparg : pr.getArguments())
- {
- if (!oldargs.remove(newparg))
- {
- newargs.add(newparg);
- }
- }
- if (oldargs.size() == 0 && newargs.size() == 0)
- {
- // exact match.
- preset = pr;
- return;
- }
- // Try even harder to migrate arguments.
- throw new Error(MessageManager
- .getString("error.parameter_migration_not_implemented_yet"));
- }
- }
-
- public List<Argument> getJobArgset()
- {
- return jobArgset == null ? null
- : JabaParamStore.getJabafromJwsArgs(jobArgset);
- }
-
- public void setJobArgset(List<Argument> jobArgset)
- {
- // TODO: test if parameters valid for service
- this.jobArgset = jobArgset == null ? null
- : JabaParamStore.getJwsArgsfromJaba(jobArgset);
+ super(service2, preset, jobArgset, autoUpdate);
}
+ @Override
public String getWsParamFile()
{
List<Option> opts = null;
}
return pset.toString();
}
-
- @Override
- public String getServiceURI()
- {
- return service.getServiceTypeURI();
- }
-
- @Override
- public String[] getServiceURLs()
- {
- return new String[] { service.getUri() };
- }
}
return opt;
}
+ @Override
+ public List<String> getDisplayNames()
+ {
+ return null; // not supported for Jaba options
+ }
+
}
--- /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.jws2.jabaws2;
+
+import jalview.api.FeatureColourI;
+import jalview.datamodel.AlignmentAnnotation;
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.features.FeatureMatcherSetI;
+import jalview.util.MessageManager;
+import jalview.ws.uimodel.AlignAnalysisUIText;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeSet;
+
+import compbio.data.sequence.Score;
+
+public class AAConClient extends JabawsAnnotationInstance
+{
+ // configuration for factory
+ public static String getServiceActionText()
+ {
+ return "calculating Amino acid consensus using AACon service";
+ }
+
+
+
+ private static String CALC_ID = "jabaws2.AACon";
+
+ public static AlignAnalysisUIText getAlignAnalysisUIText()
+ {
+ return new AlignAnalysisUIText(
+ compbio.ws.client.Services.AAConWS.toString(),
+ AAConClient.class, CALC_ID, false, true, true, true,
+ true, 2, MessageManager.getString("label.aacon_calculations"),
+ MessageManager.getString("tooltip.aacon_calculations"),
+ MessageManager.getString("label.aacon_settings"),
+ MessageManager.getString("tooltip.aacon_settings"));
+ }
+
+ // instance
+ public AAConClient(Jws2Instance handle)
+ {
+ super(handle);
+ }
+
+ @Override
+ List<AlignmentAnnotation> annotationFromScoreManager(AlignmentI seqs,
+ Map<String, FeatureColourI> featureColours,
+ Map<String, FeatureMatcherSetI> featureFilters)
+ {
+ return aacons_annotation(seqs.getWidth(), seqs, null);
+ }
+
+ private List<AlignmentAnnotation> aacons_annotation(int alWidth,
+ AlignmentI alignViewport, boolean[] gapMap)
+ {
+ Map<String, TreeSet<Score>> scoremap = scoremanager.asMap();
+ ArrayList<AlignmentAnnotation> ourAnnot = new ArrayList<>();
+ for (String score : scoremap.keySet())
+ {
+ Set<Score> scores = scoremap.get(score);
+ for (Score scr : scores)
+ {
+ if (scr.getRanges() != null && scr.getRanges().size() > 0)
+ {
+ /**
+ * annotation in range annotation = findOrCreate(scr.getMethod(),
+ * true, null, null); Annotation[] elm = new Annotation[alWidth];
+ * Iterator<Float> vals = scr.getScores().iterator(); for (Range rng :
+ * scr.getRanges()) { float val = vals.next().floatValue(); for (int i
+ * = rng.from; i <= rng.to; i++) { elm[i] = new Annotation("", "", '
+ * ', val); } } annotation.annotations = elm;
+ * annotation.validateRangeAndDisplay();
+ */
+ }
+ else
+ {
+ createAnnotationRowsForScores(alignViewport, null, ourAnnot,
+ getCalcId(),
+ scr.getScores().size(), scr);
+ }
+ }
+ }
+ return ourAnnot;
+ }
+
+}
--- /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.jws2.jabaws2;
+
+import jalview.analysis.AlignmentAnnotationUtils;
+import jalview.api.FeatureColourI;
+import jalview.bin.Cache;
+import jalview.datamodel.AlignmentAnnotation;
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.GraphLine;
+import jalview.datamodel.SequenceFeature;
+import jalview.datamodel.SequenceI;
+import jalview.datamodel.features.FeatureMatcherSetI;
+import jalview.schemes.FeatureColour;
+import jalview.util.ColorUtils;
+
+import java.awt.Color;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import compbio.data.sequence.Range;
+import compbio.data.sequence.Score;
+import compbio.data.sequence.ScoreManager.ScoreHolder;
+
+public class AADisorderClient extends JabawsAnnotationInstance
+{
+ // static configuration
+ public static String getServiceActionText()
+ {
+ return "Submitting amino acid sequences for disorder prediction.";
+ }
+
+ // minSeq = 1; protein only, no gaps
+
+ // instance
+ public AADisorderClient(Jws2Instance handle)
+ {
+ super(handle);
+
+ }
+
+ @Override
+ List<AlignmentAnnotation> annotationFromScoreManager(AlignmentI seqs,
+ Map<String, FeatureColourI> featureColours,
+ Map<String, FeatureMatcherSetI> featureFilters)
+ {
+
+ Map<String, String[]> featureTypeMap = featureMap.get(our.getName());
+ Map<String, Map<String, Object>> annotTypeMap = annotMap
+ .get(our.getName());
+ boolean dispFeatures = false;
+ Map<String, SequenceFeature> fc = new Hashtable<>(),
+ fex = new Hashtable();
+ List<AlignmentAnnotation> ourAnnot = new ArrayList<>();
+ int graphGroup = 1, lastAnnot = 0;
+
+ for (SequenceI seq : seqs.getSequences())
+ {
+ String seqId = seq.getName();
+ boolean sameGroup = false;
+ SequenceI dseq, aseq;
+ int base = seq.findPosition(0) - 1;
+ aseq = seq;
+ while ((dseq = seq).getDatasetSequence() != null)
+ {
+ seq = seq.getDatasetSequence();
+ }
+ ScoreHolder scores = null;
+ try
+ {
+ scores = scoremanager.getAnnotationForSequence(seqId);
+ } catch (Exception q)
+ {
+ Cache.log.info("Couldn't recover disorder prediction for sequence "
+ + seq.getName() + "(Prediction name was " + seqId + ")"
+ + "\nSee http://issues.jalview.org/browse/JAL-1319 for one possible reason why disorder predictions might fail.",
+ q);
+ }
+ float last = Float.NaN, val = Float.NaN;
+ if (scores != null && scores.scores != null)
+ {
+ for (Score scr : scores.scores)
+ {
+
+ if (scr.getRanges() != null && scr.getRanges().size() > 0)
+ {
+ Iterator<Float> vals = scr.getScores().iterator();
+ // make features on sequence
+ for (Range rn : scr.getRanges())
+ {
+ // TODO: Create virtual feature settings
+ SequenceFeature sf;
+ String[] type = featureTypeMap.get(scr.getMethod());
+ if (type == null)
+ {
+ // create a default type for this feature
+ type = new String[] {
+ typeName + " (" + scr.getMethod() + ")",
+ our.getActionText() };
+ }
+ if (vals.hasNext())
+ {
+ val = vals.next().floatValue();
+ sf = new SequenceFeature(type[0], type[1], base + rn.from,
+ base + rn.to, val, methodName);
+ }
+ else
+ {
+ sf = new SequenceFeature(type[0], type[1], base + rn.from,
+ base + rn.to, methodName);
+ }
+ dseq.addSequenceFeature(sf);
+ // mark feature as requiring a graduated colourscheme if has
+ // variable scores
+ if (!Float.isNaN(last) && !Float.isNaN(val) && last != val)
+ {
+ fc.put(sf.getType(), sf);
+ } else
+ {
+ fex.put(sf.getType(), sf);
+ }
+ last = val;
+ dispFeatures = true;
+ }
+ }
+ else
+ {
+ if (scr.getScores().size() == 0)
+ {
+ continue;
+ }
+ String typename, calcName;
+ AlignmentAnnotation annot = createAnnotationRowsForScores(
+ seqs, null, ourAnnot,
+ typename = our.getName() + " (" + scr.getMethod() + ")",
+ calcName = our.getNameURI() + "/" + scr.getMethod(),
+ aseq, base + 1, scr);
+ annot.graph = AlignmentAnnotation.LINE_GRAPH;
+
+ Map<String, Object> styleMap = (annotTypeMap == null) ? null
+ : annotTypeMap.get(scr.getMethod());
+
+ annot.visible = (styleMap == null
+ || styleMap.get(INVISIBLE) == null);
+ double[] thrsh = (styleMap == null) ? null
+ : (double[]) styleMap.get(THRESHOLD);
+ float[] range = (styleMap == null) ? null
+ : (float[]) styleMap.get(RANGE);
+ if (range != null)
+ {
+ annot.graphMin = range[0];
+ annot.graphMax = range[1];
+ }
+ if (styleMap == null || styleMap.get(DONTCOMBINE) == null)
+ {
+ {
+ if (!sameGroup)
+ {
+ graphGroup++;
+ sameGroup = true;
+ }
+
+ annot.graphGroup = graphGroup;
+ }
+ }
+
+ annot.description = "<html>" + our.getActionText()
+ + " - raw scores";
+ if (thrsh != null)
+ {
+ String threshNote = (thrsh[0] > 0 ? "Above " : "Below ")
+ + thrsh[1] + " indicates disorder";
+ annot.threshold = new GraphLine((float) thrsh[1], threshNote,
+ Color.red);
+ annot.description += "<br/>" + threshNote;
+ }
+ annot.description += "</html>";
+ Color col = ColorUtils
+ .createColourFromName(typeName + scr.getMethod());
+ for (int p = 0, ps = annot.annotations.length; p < ps; p++)
+ {
+ if (annot.annotations[p] != null)
+ {
+ annot.annotations[p].colour = col;
+ }
+ }
+ annot._linecolour = col;
+ // finally, update any dataset annotation
+ AlignmentAnnotationUtils.replaceAnnotationOnAlignmentWith(annot,
+ typename, calcName);
+ }
+ }
+ }
+ if (lastAnnot + 1 == ourAnnot.size())
+ {
+ // remove singleton alignment annotation row
+ ourAnnot.get(lastAnnot).graphGroup = -1;
+ }
+ }
+ {
+ if (dispFeatures)
+ {
+ // TODO: virtual feature settings
+ // feature colours need to merged with current viewport's colours
+ // simple feature colours promoted to colour-by-score ranges using
+ // currently assigned or created feature colour
+ for (String ft : fex.keySet())
+ {
+ Color col = ColorUtils.createColourFromName(ft);
+ // set graduated color as fading to white for minimum, and
+ // autoscaling to values on alignment
+
+ FeatureColourI ggc;
+ if (fc.get(ft) != null)
+ {
+ ggc = new FeatureColour(col, Color.white, col,
+
+ Color.white, Float.MIN_VALUE, Float.MAX_VALUE);
+ ggc.setAutoScaled(true);
+ }
+ else
+ {
+ ggc = new FeatureColour(col);
+ }
+ featureColours.put(ft, ggc);
+ }
+
+ }
+ return ourAnnot;
+ }
+ }
+
+ private static final String THRESHOLD = "THRESHOLD";
+
+ private static final String RANGE = "RANGE";
+
+ String typeName;
+
+ String methodName;
+
+ String groupName;
+
+ private static Map<String, Map<String, String[]>> featureMap;
+
+ private static Map<String, Map<String, Map<String, Object>>> annotMap;
+
+ private static String DONTCOMBINE = "DONTCOMBINE";
+
+ private static String INVISIBLE = "INVISIBLE";
+ static
+ {
+ // TODO: turn this into some kind of configuration file that's a bit easier
+ // to edit
+ featureMap = new HashMap<>();
+ Map<String, String[]> fmap;
+ featureMap.put(compbio.ws.client.Services.IUPredWS.toString(),
+ fmap = new HashMap<>());
+ fmap.put("Glob",
+ new String[]
+ { "Globular Domain", "Predicted globular domain" });
+ featureMap.put(compbio.ws.client.Services.JronnWS.toString(),
+ fmap = new HashMap<>());
+ featureMap.put(compbio.ws.client.Services.DisemblWS.toString(),
+ fmap = new HashMap<>());
+ fmap.put("REM465", new String[] { "REM465", "Missing density" });
+ fmap.put("HOTLOOPS", new String[] { "HOTLOOPS", "Flexible loops" });
+ fmap.put("COILS", new String[] { "COILS", "Random coil" });
+ featureMap.put(compbio.ws.client.Services.GlobPlotWS.toString(),
+ fmap = new HashMap<>());
+ fmap.put("GlobDoms",
+ new String[]
+ { "Globular Domain", "Predicted globular domain" });
+ fmap.put("Disorder",
+ new String[]
+ { "Protein Disorder", "Probable unstructured peptide region" });
+ Map<String, Map<String, Object>> amap;
+ annotMap = new HashMap<>();
+ annotMap.put(compbio.ws.client.Services.GlobPlotWS.toString(),
+ amap = new HashMap<>());
+ amap.put("Dydx", new HashMap<String, Object>());
+ amap.get("Dydx").put(DONTCOMBINE, DONTCOMBINE);
+ amap.get("Dydx").put(THRESHOLD, new double[] { 1, 0 });
+ amap.get("Dydx").put(RANGE, new float[] { -1, +1 });
+
+ amap.put("SmoothedScore", new HashMap<String, Object>());
+ amap.get("SmoothedScore").put(INVISIBLE, INVISIBLE);
+ amap.put("RawScore", new HashMap<String, Object>());
+ amap.get("RawScore").put(INVISIBLE, INVISIBLE);
+ annotMap.put(compbio.ws.client.Services.DisemblWS.toString(),
+ amap = new HashMap<>());
+ amap.put("COILS", new HashMap<String, Object>());
+ amap.put("HOTLOOPS", new HashMap<String, Object>());
+ amap.put("REM465", new HashMap<String, Object>());
+ amap.get("COILS").put(THRESHOLD, new double[] { 1, 0.516 });
+ amap.get("COILS").put(RANGE, new float[] { 0, 1 });
+
+ amap.get("HOTLOOPS").put(THRESHOLD, new double[] { 1, 0.6 });
+ amap.get("HOTLOOPS").put(RANGE, new float[] { 0, 1 });
+ amap.get("REM465").put(THRESHOLD, new double[] { 1, 0.1204 });
+ amap.get("REM465").put(RANGE, new float[] { 0, 1 });
+
+ annotMap.put(compbio.ws.client.Services.IUPredWS.toString(),
+ amap = new HashMap<>());
+ amap.put("Long", new HashMap<String, Object>());
+ amap.put("Short", new HashMap<String, Object>());
+ amap.get("Long").put(THRESHOLD, new double[] { 1, 0.5 });
+ amap.get("Long").put(RANGE, new float[] { 0, 1 });
+ amap.get("Short").put(THRESHOLD, new double[] { 1, 0.5 });
+ amap.get("Short").put(RANGE, new float[] { 0, 1 });
+ annotMap.put(compbio.ws.client.Services.JronnWS.toString(),
+ amap = new HashMap<>());
+ amap.put("JRonn", new HashMap<String, Object>());
+ amap.get("JRonn").put(THRESHOLD, new double[] { 1, 0.5 });
+ amap.get("JRonn").put(RANGE, new float[] { 0, 1 });
+ }
+
+}
--- /dev/null
+package jalview.ws.jws2.jabaws2;
+
+import jalview.api.FeatureColourI;
+import jalview.datamodel.Alignment;
+import jalview.datamodel.AlignmentAnnotation;
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.Annotation;
+import jalview.datamodel.SequenceI;
+import jalview.datamodel.features.FeatureMatcherSetI;
+import jalview.util.MessageManager;
+import jalview.ws.api.JobId;
+import jalview.ws.api.SequenceAnnotationServiceI;
+import jalview.ws.jws2.JabaParamStore;
+import jalview.ws.jws2.JabaPreset;
+import jalview.ws.params.ArgumentI;
+import jalview.ws.params.WsParamSetI;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import compbio.data.msa.SequenceAnnotation;
+import compbio.data.sequence.FastaSequence;
+import compbio.data.sequence.Score;
+import compbio.data.sequence.ScoreManager;
+import compbio.metadata.JobSubmissionException;
+import compbio.metadata.WrongParameterException;
+
+public abstract class JabawsAnnotationInstance
+ extends JabawsServiceInstance<SequenceAnnotation>
+ implements SequenceAnnotationServiceI
+{
+
+ /**
+ * holds last results obtained when non-null. TODO: remove this as a field ?
+ */
+ protected ScoreManager scoremanager = null;
+
+ public JabawsAnnotationInstance(Jws2Instance handle)
+ {
+ super(handle);
+ }
+
+
+ /**
+ *
+ * @return the calcId for this Jabaws Service (convenience method).
+ *
+ * TODO: decide if this is really convenient since manager and
+ * instance have same method !
+ */
+ public String getCalcId()
+ {
+ return our.getAlignAnalysisUI() == null ? null
+ : our.getAlignAnalysisUI().getCalcId();
+ }
+
+ @Override
+ public JobId submitToService(List<SequenceI> seqs, WsParamSetI preset,
+ List<ArgumentI> arguments) throws Throwable
+ {
+ String rslt = null;
+ scoremanager = null;
+ List<FastaSequence> jabaseqs = new ArrayList(seqs.size());
+ for (SequenceI seq : seqs)
+ {
+ jabaseqs.add(
+ new FastaSequence(seq.getName(), seq.getSequenceAsString()));
+ }
+ if (preset == null && arguments == null)
+ {
+ rslt = service.analize(jabaseqs);
+ }
+ if (preset != null)
+ {
+ if (preset instanceof JabaPreset)
+ {
+ // TODO: verify behaviour is really the same, since preset analyze was
+ // never called in Jalview 2.11.x
+ rslt = service.presetAnalize(jabaseqs,
+ ((JabaPreset) preset).getJabaPreset());
+ }
+ else
+ {
+ rslt = service.customAnalize(jabaseqs,
+ JabaParamStore.getJabafromJwsArgs(preset.getArguments()));
+ }
+ }
+ else if (arguments != null && arguments.size() > 0)
+ {
+ try
+ {
+ rslt = service.customAnalize(jabaseqs,
+ JabaParamStore.getJabafromJwsArgs(arguments));
+ } catch (WrongParameterException x)
+ {
+ throw new JobSubmissionException(MessageManager.getString(
+ "exception.jobsubmission_invalid_params_set"), x);
+
+ }
+ }
+
+ if (rslt == null)
+ {
+ return null;
+ }
+ return new JobId(our.getServiceType(), our.getName(), rslt);
+ }
+
+
+ @Override
+ public
+ List<AlignmentAnnotation> getAnnotationResult(JobId job,
+ List<SequenceI> seqs, Map<String, FeatureColourI> featureColours,
+ Map<String, FeatureMatcherSetI> featureFilters) throws Throwable
+ {
+ if (scoremanager == null)
+ {
+ // TODO: raise annotation unavailable exception ?
+ scoremanager = service.getAnnotation(job.getJobId());
+ }
+ if (scoremanager == null)
+ {
+ return List.of();
+ }
+ /**
+ * dummy alignment to perform annotation on
+ */
+ AlignmentI newal = new Alignment(seqs.toArray(new SequenceI[0]));
+ List<AlignmentAnnotation> ourAnnot = annotationFromScoreManager(newal,
+ featureColours, featureFilters);
+ return ourAnnot;
+ }
+
+ /**
+ * service specific annotation creation method
+ *
+ * @param seqs
+ * - sequences to be annotated with results
+ * @param featureColours
+ * - - updated with any colours imported during result processing
+ * @param featureFilters
+ * - updated with any filters imported during result processing
+ *
+ * @return
+ */
+ abstract List<AlignmentAnnotation> annotationFromScoreManager(
+ AlignmentI seqs, Map<String, FeatureColourI> featureColours,
+ Map<String, FeatureMatcherSetI> featureFilters);
+
+
+ /**
+ * create and complete an annotation row from a JABAWS score object
+ *
+ * @param alignViewport
+ * @param gapMap
+ * @param ourAnnot
+ * @param calcId
+ * @param alWidth
+ * @param scr
+ */
+
+ protected void createAnnotationRowsForScores(AlignmentI al_result,
+ boolean[] gapMap, List<AlignmentAnnotation> ourAnnot,
+ String calcId,
+ int alWidth, Score scr)
+ {
+ // simple annotation row
+ AlignmentAnnotation annotation = al_result
+ .findOrCreateAnnotation(scr.getMethod(), calcId, true, null,
+ null);
+ if (gapMap == null || alWidth == gapMap.length) // scr.getScores().size())
+ {
+ constructAnnotationFromScore(gapMap, annotation, 0,
+ alWidth, scr);
+ ourAnnot.add(annotation);
+ }
+ }
+
+ /**
+ * create a sequence associated annotation row for JABAWS score object scr
+ *
+ * @param alignViewport
+ * @param gapMap
+ * @param ourAnnot
+ * @param typeName
+ * @param calcId
+ * @param dseq
+ * @param base
+ * @param scr
+ * @return
+ */
+ protected AlignmentAnnotation createAnnotationRowsForScores(
+ AlignmentI alignment, boolean[] gapMap,
+ List<AlignmentAnnotation> ourAnnot, String typeName,
+ String calcId, SequenceI dseq, int base, Score scr)
+ {
+ System.out.println("Creating annotation on dseq:" + dseq.getStart()
+ + " base is " + base + " and length=" + dseq.getLength()
+ + " == " + scr.getScores().size());
+ // AlignmentAnnotation annotation = new AlignmentAnnotation(
+ // scr.getMethod(), typeName, new Annotation[]
+ // {}, 0, -1, AlignmentAnnotation.LINE_GRAPH);
+ // annotation.setCalcId(calcId);
+ AlignmentAnnotation annotation = alignment
+ .findOrCreateAnnotation(typeName, calcId, false, dseq, null);
+ constructAnnotationFromScore(gapMap, annotation, 0, dseq.getLength(),
+ scr);
+ annotation.createSequenceMapping(dseq, base, false);
+ annotation.adjustForAlignment();
+ dseq.addAlignmentAnnotation(annotation);
+ ourAnnot.add(annotation);
+ return annotation;
+ }
+
+ /**
+ * create column annotation elements from Jabaws score object
+ *
+ * @param gapMap
+ * @param annotation
+ * @param base
+ * @param alWidth
+ * @param scr
+ * JABAWS score object
+ */
+ protected void constructAnnotationFromScore(boolean[] gapMap,
+ AlignmentAnnotation annotation,
+ int base, int alWidth, Score scr)
+ {
+ Annotation[] elm = new Annotation[alWidth];
+ Iterator<Float> vals = scr.getScores().iterator();
+ float m = 0f, x = 0f;
+ for (int i = 0; vals.hasNext(); i++)
+ {
+ float val = vals.next().floatValue();
+ if (i == 0)
+ {
+ m = val;
+ x = val;
+ }
+ else
+ {
+ if (m > val)
+ {
+ m = val;
+ }
+ ;
+ if (x < val)
+ {
+ x = val;
+ }
+ }
+ // if we're at a gapped column then skip to next ungapped position
+ if (gapMap != null && gapMap.length > 0)
+ {
+ // if gapMap is a different length to the result then it may be out of
+ // sync with the job.
+ while (i < gapMap.length && !gapMap[i])
+ {
+ elm[i++] = new Annotation("", "", ' ', Float.NaN);
+ }
+ }
+ elm[i] = new Annotation("", "" + val, ' ', val);
+ }
+
+ annotation.annotations = elm;
+ annotation.belowAlignment = true;
+ if (x < 0)
+ {
+ x = 0;
+ }
+ x += (x - m) * 0.1;
+ annotation.graphMax = x;
+ annotation.graphMin = m;
+ annotation.validateRangeAndDisplay();
+ }
+
+}
--- /dev/null
+package jalview.ws.jws2.jabaws2;
+
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.Sequence;
+import jalview.datamodel.SequenceI;
+import jalview.ws.api.CancellableI;
+import jalview.ws.api.JobId;
+import jalview.ws.api.MultipleSequenceAlignmentI;
+import jalview.ws.jws2.JabaParamStore;
+import jalview.ws.jws2.JabaPreset;
+import jalview.ws.params.ArgumentI;
+import jalview.ws.params.InvalidArgumentException;
+import jalview.ws.params.WsParamSetI;
+
+import java.io.IOError;
+import java.rmi.ServerError;
+import java.util.ArrayList;
+import java.util.List;
+
+import compbio.data.sequence.Alignment;
+import compbio.data.sequence.FastaSequence;
+import compbio.metadata.ResultNotAvailableException;
+
+public class JabawsMsaInstance
+ extends JabawsServiceInstance<compbio.data.msa.MsaWS>
+ implements MultipleSequenceAlignmentI, CancellableI
+{
+ @Override
+ public JobId align(List<SequenceI> toalign, WsParamSetI parameters,
+ List<ArgumentI> arguments) throws Throwable
+ {
+ List<compbio.data.sequence.FastaSequence> seqs = new ArrayList<>();
+ for (SequenceI seq : toalign)
+ {
+ seqs.add(new FastaSequence(seq.getName(), seq.getSequenceAsString()));
+ }
+ String jobid = null;
+ if (parameters != null)
+ {
+ if (parameters instanceof JabaPreset)
+ {
+ jobid = service.presetAlign(seqs,
+ ((JabaPreset) parameters).getJabaPreset());
+ }
+ else
+ {
+ jobid = service.customAlign(seqs, JabaParamStore
+ .getJabafromJwsArgs(parameters.getArguments()));
+ }
+ }
+ else if (arguments != null && arguments.size() > 0)
+ {
+ jobid = service.customAlign(seqs,
+ JabaParamStore.getJabafromJwsArgs(arguments));
+ }
+ else
+ {
+ jobid = service.align(seqs);
+ }
+
+ if (jobid == null)
+ {
+ return null;
+ }
+ return new JobId(our.getServiceType(), our.getName(), jobid);
+ }
+
+ @Override
+ public AlignmentI getAlignmentFor(JobId jobId)
+ throws InvalidArgumentException, ServerError, IOError
+ {
+ Alignment alignment = null;
+ try
+ {
+ alignment = service.getResult(jobId.getJobId());
+ } catch (ResultNotAvailableException rnotav)
+ {
+
+ // TODO - migrate JABA exception
+ // throw new ServerError("Couldn't get result for job",rnotav);
+ }
+ SequenceI[] alseqs;
+ int alseq_l = 0;
+ if (alignment.getSequences().size() == 0)
+ {
+ return null;
+ }
+
+ alseqs = new SequenceI[alignment.getSequences().size()];
+ for (compbio.data.sequence.FastaSequence seq : alignment.getSequences())
+ {
+ alseqs[alseq_l++] = new Sequence(seq.getId(), seq.getSequence());
+ }
+ AlignmentI jv_al = new jalview.datamodel.Alignment(alseqs);
+ jv_al.setGapCharacter(alignment.getMetadata().getGapchar());
+ return jv_al;
+
+ }
+
+ public JabawsMsaInstance(Jws2Instance handle)
+ {
+ super(handle);
+ }
+
+}
--- /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.jws2.jabaws2;
+
+import jalview.gui.AlignFrame;
+import jalview.ws.jws2.SeqAnnotationServiceCalcWorker;
+import jalview.ws.params.ArgumentI;
+import jalview.ws.params.WsParamSetI;
+
+import java.util.List;
+
+public abstract class JabawsMsaInterfaceAlignCalcWorker
+ extends SeqAnnotationServiceCalcWorker
+{
+
+ public JabawsMsaInterfaceAlignCalcWorker(Jws2Instance service,
+ AlignFrame alignFrame, WsParamSetI preset,
+ List<ArgumentI> paramset)
+ {
+ super(service, alignFrame, preset, paramset);
+ // TODO Auto-generated constructor stub
+ }
+
+ // TODO: REFACTOR if needed !
+ // may be able to get away with overriding run() only, but maybe not.
+ /***
+ * @SuppressWarnings("unchecked") protected MsaWS msaservice;
+ *
+ * protected Alignment msascoreset;
+ *
+ * public JabawsMsaInterfaceAlignCalcWorker(AlignViewportI alignViewport,
+ * AlignmentViewPanel alignPanel) { super(alignViewport, alignPanel); }
+ *
+ * public JabawsMsaInterfaceAlignCalcWorker(Jws2Instance service, AlignFrame
+ * alignFrame, WsParamSetI preset, List<ArgumentI> paramset) {
+ * this(alignFrame.getCurrentView(), alignFrame.alignPanel); this.guiProgress
+ * = alignFrame; this.preset = preset; this.arguments = paramset; this.service
+ * = service; msaservice = (MsaWS) service.service;
+ *
+ * }
+ *
+ * @Override ChunkHolder pullExecStatistics(String rslt, long rpos) { return
+ * msaservice.pullExecStatistics(rslt, rpos); }
+ *
+ * @Override boolean collectAnnotationResultsFor(String rslt) throws
+ * ResultNotAvailableException { msascoreset =
+ * msaservice.getResult(rslt); if (msascoreset != null) { return
+ * true; } return false; }
+ *
+ * @Override boolean cancelJob(String rslt) throws Exception { return
+ * msaservice.cancelJob(rslt); }
+ *
+ * @Override protected JobStatus getJobStatus(String rslt) throws Exception {
+ * return msaservice.getJobStatus(rslt); }
+ *
+ * @Override boolean hasService() { return msaservice != null; }
+ *
+ * @Override protected boolean isInteractiveUpdate() { return false; // this
+ * instanceof AAConClient; }
+ *
+ * @Override protected String submitToService(
+ * List<compbio.data.sequence.FastaSequence> seqs) throws
+ * JobSubmissionException { String rslt; if (preset == null &&
+ * arguments == null) { rslt = msaservice.align(seqs); } else { try
+ * { rslt = msaservice.customAlign(seqs, getJabaArguments()); }
+ * catch (WrongParameterException x) { throw new
+ * JobSubmissionException(MessageManager.getString(
+ * "exception.jobsubmission_invalid_params_set"), x); } } return
+ * rslt; }
+ *
+ * protected void createAnnotationRowsForScores(
+ * List<AlignmentAnnotation> ourAnnot, String calcId, int alWidth,
+ * Score scr) { // simple annotation row AlignmentAnnotation
+ * annotation = alignViewport.getAlignment()
+ * .findOrCreateAnnotation(scr.getMethod(), calcId, true, null,
+ * null); if (alWidth == gapMap.length) // scr.getScores().size()) {
+ * constructAnnotationFromScore(annotation, 0, alWidth, scr);
+ * ourAnnot.add(annotation); } }
+ *
+ * protected AlignmentAnnotation createAnnotationRowsForScores(
+ * List<AlignmentAnnotation> ourAnnot, String typeName, String
+ * calcId, SequenceI dseq, int base, Score scr) {
+ * System.out.println("Creating annotation on dseq:" +
+ * dseq.getStart() + " base is " + base + " and length=" +
+ * dseq.getLength() + " == " + scr.getScores().size()); //
+ * AlignmentAnnotation annotation = new AlignmentAnnotation( //
+ * scr.getMethod(), typeName, new Annotation[] // {}, 0, -1,
+ * AlignmentAnnotation.LINE_GRAPH); // annotation.setCalcId(calcId);
+ * AlignmentAnnotation annotation = alignViewport.getAlignment()
+ * .findOrCreateAnnotation(typeName, calcId, false, dseq, null);
+ * constructAnnotationFromScore(annotation, 0, dseq.getLength(),
+ * scr); annotation.createSequenceMapping(dseq, base, false);
+ * annotation.adjustForAlignment();
+ * dseq.addAlignmentAnnotation(annotation);
+ * ourAnnot.add(annotation); return annotation; }
+ *
+ * private void constructAnnotationFromScore(AlignmentAnnotation
+ * annotation, int base, int alWidth, Score scr) { Annotation[] elm
+ * = new Annotation[alWidth]; Iterator<Float> vals =
+ * scr.getScores().iterator(); float m = 0f, x = 0f; for (int i = 0;
+ * vals.hasNext(); i++) { float val = vals.next().floatValue(); if
+ * (i == 0) { m = val; x = val; } else { if (m > val) { m = val; } ;
+ * if (x < val) { x = val; } } // if we're at a gapped column then
+ * skip to next ungapped position if (gapMap != null &&
+ * gapMap.length > 0) { while (!gapMap[i]) { elm[i++] = new
+ * Annotation("", "", ' ', Float.NaN); } } elm[i] = new
+ * Annotation("", "" + val, ' ', val); }
+ *
+ * annotation.annotations = elm; annotation.belowAlignment = true;
+ * if (x < 0) { x = 0; } x += (x - m) * 0.1; annotation.graphMax =
+ * x; annotation.graphMin = m; annotation.validateRangeAndDisplay();
+ * }
+ ***/
+}
--- /dev/null
+package jalview.ws.jws2.jabaws2;
+
+import jalview.bin.Cache;
+import jalview.gui.WebserviceInfo;
+import jalview.util.MessageManager;
+import jalview.ws.gui.WsJob;
+import jalview.ws.gui.WsJob.JobState;
+import jalview.ws.jws2.JabaParamStore;
+import jalview.ws.jws2.JabaPreset;
+import jalview.ws.jws2.dm.JabaWsParamSet;
+import jalview.ws.params.WsParamSetI;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import compbio.metadata.Argument;
+import compbio.metadata.ChunkHolder;
+import compbio.metadata.JobStatus;
+import compbio.metadata.Preset;
+
+/**
+ * Base class for JABAWS service instances. Provides helper methods for
+ * interfacing with Jalview.
+ *
+ * @author jprocter
+ *
+ */
+public class JabawsServiceInstance<T extends compbio.data.msa.JManagement>
+ implements
+ jalview.ws.api.JalviewWebServiceI, jalview.ws.api.CancellableI
+{
+ /**
+ * our service instance handler generated by the discoverer
+ */
+ Jws2Instance our;
+ protected T service;
+ protected Map<JobStatus, JobState> jwsState = new HashMap<>();
+
+ @Override
+ public boolean cancel(WsJob job)
+ {
+ service.cancelJob(job.getJobId());
+ // if the Jaba server indicates the job can't be cancelled, its
+ // because its running on the server's local execution engine
+ // so we just close the window anyway.
+
+ return true;
+ }
+
+
+ public JabawsServiceInstance(Jws2Instance handle)
+ {
+ our = handle;
+ service = (T) handle.service;
+ }
+
+ @Override
+ public void updateStatus(WsJob job)
+ {
+ JobStatus jwsstatus = service.getJobStatus(job.getJobId());
+ job.setState(jwsState.get(jwsstatus));
+ }
+
+ @Override
+ public boolean updateJobProgress(WsJob job) throws Exception
+ {
+ StringBuilder response = new StringBuilder(job.getStatus());
+ long lastchunk = job.getNextChunk();
+ if (lastchunk == -1)
+ {
+ Cache.log.debug("No more status messages for job " + job.getJobId());
+ return false;
+ }
+ boolean changed = false;
+ do
+ {
+ ChunkHolder chunk = service.pullExecStatistics(job.getJobId(),
+ lastchunk);
+ if (chunk != null)
+ {
+ changed |= chunk.getChunk().length() > 0;
+ response.append(chunk.getChunk());
+ lastchunk = chunk.getNextPosition();
+ try
+ {
+ Thread.sleep(50);
+ } catch (InterruptedException x)
+ {
+ }
+ ;
+ }
+ ;
+ job.setnextChunk(lastchunk);
+ } while (lastchunk >= 0 && job.getNextChunk() != lastchunk);
+ if (job instanceof WsJob)
+ {
+ // TODO decide if WsJob will be the bean for all ng-webservices
+ job.setStatus(response.toString());
+ }
+ return changed;
+ }
+
+ {
+ jwsState.put(JobStatus.CANCELLED, JobState.CANCELLED);
+ jwsState.put(JobStatus.COLLECTED, JobState.FINISHED);
+ jwsState.put(JobStatus.FAILED, JobState.FAILED);
+ jwsState.put(JobStatus.FINISHED, JobState.FINISHED);
+ jwsState.put(JobStatus.PENDING, JobState.QUEUED);
+ jwsState.put(JobStatus.RUNNING, JobState.RUNNING);
+ jwsState.put(JobStatus.STARTED, JobState.RUNNING);
+ jwsState.put(JobStatus.SUBMITTED, JobState.SUBMITTED);
+ jwsState.put(JobStatus.UNDEFINED, JobState.UNKNOWN);
+ }
+
+ public boolean isPresetJob(WsJob job)
+ {
+ return job.getPreset() != null && job.getPreset() instanceof JabaPreset;
+ }
+
+ public Preset getServerPreset(WsJob job)
+ {
+ return (isPresetJob(job))
+ ? ((JabaPreset) job.getPreset()).getJabaPreset()
+ : null;
+ }
+
+ public List<Argument> getJabaArguments(WsParamSetI preset)
+ {
+ List<Argument> newargs = new ArrayList<>();
+ if (preset != null)
+ {
+ if (preset instanceof JabaWsParamSet)
+ {
+ newargs.addAll(((JabaWsParamSet) preset).getjabaArguments());
+ }
+ else
+ {
+ newargs.addAll(
+ JabaParamStore.getJabafromJwsArgs(preset.getArguments()));
+ }
+ }
+ return newargs;
+ }
+
+ @Override
+ public boolean handleSubmitError(Throwable _lex, WsJob j,
+ WebserviceInfo wsInfo) throws Exception, Error
+ {
+ if (_lex instanceof compbio.metadata.UnsupportedRuntimeException)
+ {
+ wsInfo.appendProgressText(MessageManager.formatMessage(
+ "info.job_couldnt_be_run_server_doesnt_support_program",
+ new String[]
+ { _lex.getMessage() }));
+ wsInfo.warnUser(_lex.getMessage(),
+ MessageManager.getString("warn.service_not_supported"));
+ wsInfo.setStatus(WebserviceInfo.STATE_STOPPED_SERVERERROR);
+ wsInfo.setStatus(j.getJobnum(),
+ WebserviceInfo.STATE_STOPPED_SERVERERROR);
+ return true;
+ }
+ if (_lex instanceof compbio.metadata.LimitExceededException)
+ {
+ wsInfo.appendProgressText(MessageManager.formatMessage(
+ "info.job_couldnt_be_run_exceeded_hard_limit", new String[]
+ { _lex.getMessage() }));
+ wsInfo.warnUser(_lex.getMessage(),
+ MessageManager.getString("warn.input_is_too_big"));
+ wsInfo.setStatus(WebserviceInfo.STATE_STOPPED_ERROR);
+ wsInfo.setStatus(j.getJobnum(), WebserviceInfo.STATE_STOPPED_ERROR);
+ return true;
+ }
+ if (_lex instanceof compbio.metadata.WrongParameterException)
+ {
+ wsInfo.warnUser(_lex.getMessage(),
+ MessageManager.getString("warn.invalid_job_param_set"));
+ wsInfo.appendProgressText(MessageManager.formatMessage(
+ "info.job_couldnt_be_run_incorrect_param_setting",
+ new String[]
+ { _lex.getMessage() }));
+ wsInfo.setStatus(WebserviceInfo.STATE_STOPPED_ERROR);
+ wsInfo.setStatus(j.getJobnum(), WebserviceInfo.STATE_STOPPED_ERROR);
+ return true;
+ }
+ // pass on to generic error handler
+ return false;
+ }
+
+ @Override
+ public boolean handleCollectionException(Exception ex, WsJob msjob,
+ WebserviceInfo wsInfo)
+ {
+ if (ex instanceof compbio.metadata.ResultNotAvailableException)
+ {
+ // job has failed for some reason - probably due to invalid
+ // parameters
+ Cache.log.debug(
+ "Results not available for finished job - marking as broken job.",
+ ex);
+ String status = msjob.getStatus();
+
+ msjob.setStatus(status
+ + "\nResult not available. Probably due to invalid input or parameter settings. Server error message below:\n\n"
+ + ex.getLocalizedMessage());
+ msjob.setState(WsJob.JobState.BROKEN);
+ return true;
+ }
+ return false;
+ }
+}
*/
package jalview.ws.jws2.jabaws2;
-import jalview.gui.AlignFrame;
import jalview.gui.Desktop;
import jalview.util.MessageManager;
+import jalview.ws.api.JalviewServiceEndpointProviderI;
+import jalview.ws.api.ServiceWithParameters;
import jalview.ws.jws2.JabaParamStore;
-import jalview.ws.jws2.MsaWSClient;
-import jalview.ws.jws2.SequenceAnnotationWSClient;
import jalview.ws.params.ParamDatastoreI;
+import jalview.ws.params.ParamManager;
import java.io.Closeable;
-
-import javax.swing.JMenu;
+import java.net.URL;
import compbio.data.msa.JABAService;
import compbio.data.msa.MsaWS;
import compbio.metadata.PresetManager;
import compbio.metadata.RunnerConfig;
-public class Jws2Instance implements AutoCloseable
+public class Jws2Instance extends ServiceWithParameters
+ implements JalviewServiceEndpointProviderI, AutoCloseable
{
- public String hosturl;
-
- public String serviceType;
-
- public String action;
public JABAService service;
- public String description;
-
- public String docUrl;
-
/**
*
* @param hosturl
public Jws2Instance(String hosturl, String serviceType, String action,
String description, JABAService service)
{
- super();
- this.hosturl = hosturl;
- this.serviceType = serviceType;
+ super(action, action, serviceType, description, hosturl);
this.service = service;
- this.action = action;
- this.description = description;
+ if (service instanceof MsaWS<?>)
+ {
+ style = ServiceClient.MSAWSCLIENT;
+ }
+ else if (service instanceof SequenceAnnotation<?>)
+ {
+ style = ServiceClient.SEQUENCEANNOTATIONWSCLIENT;
+ }
+
int p = description.indexOf("MORE INFORMATION:");
if (p > -1)
{
- docUrl = description.substring(description.indexOf("http", p)).trim();
+ String docUrl = description.substring(description.indexOf("http", p))
+ .trim();
if (docUrl.indexOf('\n') > -1)
{
docUrl = docUrl.substring(0, docUrl.indexOf("\n")).trim();
}
+ if (docUrl.length() > 0)
+ {
+ try
+ {
+ URL url = new URL(docUrl);
+ if (url != null)
+ {
+ setDocumentationUrl(docUrl);
+ }
+ } catch (Exception x)
+ {
+
+ }
+ }
}
}
} catch (Exception ex)
{
System.err.println("Exception when retrieving presets for service "
- + serviceType + " at " + hosturl);
+ + getServiceType() + " at " + getHostURL());
}
}
return presets;
}
- public String getHost()
- {
- return hosturl;
- /*
- * try { URL serviceurl = new URL(hosturl); if (serviceurl.getPort()!=80) {
- * return serviceurl.getHost()+":"+serviceurl.getPort(); } return
- * serviceurl.getHost(); } catch (Exception e) {
- * System.err.println("Failed to parse service URL '" + hosturl +
- * "' as a valid URL!"); } return null;
- */
- }
-
- /**
- * @return short description of what the service will do
- */
- public String getActionText()
- {
- return action + " with " + serviceType;
- }
-
/**
* non-thread safe - blocks whilst accessing service to get complete set of
* available options and parameters
throw new Error(MessageManager.formatMessage(
"error.implementation_error_runner_config_not_available",
new String[]
- { serviceType, service.getClass().toString() }));
+ { getServiceType(), service.getClass().toString() }));
}
@Override
// super.finalize();
}
+ @Override
public ParamDatastoreI getParamStore()
{
if (paramStore == null)
try
{
paramStore = new JabaParamStore(this,
- (Desktop.instance != null ? Desktop.getUserParameterStore()
+ (Desktop.getInstance() != null ? Desktop.getUserParameterStore()
: null));
} catch (Exception ex)
{
return paramStore;
}
- public String getUri()
- {
- // this is only valid for Jaba 1.0 - this formula might have to change!
- return hosturl
- + (hosturl.lastIndexOf("/") == (hosturl.length() - 1) ? ""
- : "/")
- + serviceType;
- }
-
private boolean hasParams = false, lookedForParams = false;
+ @Override
public boolean hasParameters()
{
if (!lookedForParams)
return hasParams;
}
- public void attachWSMenuEntry(JMenu atpoint, AlignFrame alignFrame)
+ /**
+ * initialise a parameter store for this service
+ *
+ * @param userParameterStore
+ * - the user ParamManager (e.g. Desktop.getUserParameterStore() )
+ */
+ @Override
+ public void initParamStore(ParamManager userParameterStore)
{
- if (service instanceof MsaWS<?>)
- {
- new MsaWSClient().attachWSMenuEntry(atpoint, this, alignFrame);
- }
- else if (service instanceof SequenceAnnotation<?>)
+ if (paramStore == null)
{
- new SequenceAnnotationWSClient().attachWSMenuEntry(atpoint, this,
- alignFrame);
+ paramStore = new JabaParamStore(this, userParameterStore);
}
}
- public String getServiceTypeURI()
+ /**
+ * an object that implements one or more interfaces in jalview.ws.api
+ *
+ * @return
+ */
+ @Override
+ public Object getEndpoint()
{
- return "java:" + serviceType;
- }
-
- jalview.ws.uimodel.AlignAnalysisUIText aaui;
+ if (service instanceof MsaWS<?>)
+ {
+ if (aaui != null)
+ {
+ throw new Error(
+ "JABAWS MsaWS based instant calculation not implemented.");
- public jalview.ws.uimodel.AlignAnalysisUIText getAlignAnalysisUI()
- {
- return aaui;
+ }
+ else
+ {
+ return new JabawsMsaInstance(this);
+ }
+ }
+ else
+ {
+ if (service instanceof compbio.data.msa.SequenceAnnotation)
+ {
+ if (aaui != null)
+ {
+ try
+ {
+ // probably a factory would be nicer but..
+ return aaui.getClient().getConstructor(getClass())
+ .newInstance(this);
+ } catch (Throwable t)
+ {
+ throw new Error("Implementation Error in web service framework",
+ t);
+ }
+ }
+ return new AADisorderClient(this);
+ }
+ return null;
+ }
}
}
*/
package jalview.ws.jws2.jabaws2;
-import jalview.ws.jws2.AAConClient;
-import jalview.ws.jws2.RNAalifoldClient;
+import jalview.bin.ApplicationSingletonProvider;
+import jalview.bin.ApplicationSingletonProvider.ApplicationSingletonI;
+
import jalview.ws.uimodel.AlignAnalysisUIText;
import java.util.HashMap;
import compbio.data.msa.JABAService;
-public class Jws2InstanceFactory
+public class Jws2InstanceFactory implements ApplicationSingletonI
{
- private static HashMap<String, AlignAnalysisUIText> aaConGUI;
- private static HashSet<String> ignoreGUI;
+ private Jws2InstanceFactory()
+ {
+ // private singleton
+ }
+
+ private static Jws2InstanceFactory getInstance()
+ {
+ return (Jws2InstanceFactory) ApplicationSingletonProvider
+ .getInstance(Jws2InstanceFactory.class);
+ }
+
+ private HashMap<String, AlignAnalysisUIText> aaConGUI;
+
+ private HashSet<String> ignoreGUI;
private static String category_rewrite(String cat_name)
{
: cat_name;
}
- private static void init()
+ private void init()
{
if (aaConGUI == null)
{
- aaConGUI = new HashMap<String, AlignAnalysisUIText>();
+ aaConGUI = new HashMap<>();
aaConGUI.put(compbio.ws.client.Services.AAConWS.toString(),
- AAConClient.getAlignAnalysisUITest());
+ AAConClient.getAlignAnalysisUIText());
aaConGUI.put(compbio.ws.client.Services.RNAalifoldWS.toString(),
- RNAalifoldClient.getAlignAnalysisUITest());
+ RNAalifoldClient.getAlignAnalysisUIText());
// ignore list for JABAWS services not supported in jalview ...
- ignoreGUI = new HashSet<String>();
+ ignoreGUI = new HashSet<>();
}
}
*/
public static boolean ignoreService(String serviceType)
{
- init();
- return (ignoreGUI.contains(serviceType.toString()));
+ getInstance().init();
+ return (getInstance().ignoreGUI.contains(serviceType.toString()));
}
/**
String serviceType, String name, String description,
JABAService service)
{
- init();
+ getInstance().init();
Jws2Instance svc = new Jws2Instance(jwsservers, serviceType,
category_rewrite(name), description, service);
- svc.aaui = aaConGUI.get(serviceType.toString());
+ svc.setAlignAnalysisUI(getInstance().aaConGUI.get(serviceType.toString()));
return svc;
}
* along with Jalview. If not, see <http://www.gnu.org/licenses/>.
* The Jalview Authors are detailed in the 'AUTHORS' file.
*/
-package jalview.ws.jws2;
+package jalview.ws.jws2.jabaws2;
+import jalview.api.FeatureColourI;
import jalview.datamodel.AlignmentAnnotation;
+import jalview.datamodel.AlignmentI;
import jalview.datamodel.Annotation;
-import jalview.gui.AlignFrame;
+import jalview.datamodel.features.FeatureMatcherSetI;
import jalview.util.MessageManager;
-import jalview.ws.jws2.jabaws2.Jws2Instance;
-import jalview.ws.params.WsParamSetI;
import jalview.ws.uimodel.AlignAnalysisUIText;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
+import java.util.Map;
import java.util.TreeSet;
import java.util.regex.Pattern;
-import compbio.data.sequence.FastaSequence;
import compbio.data.sequence.RNAStructReader.AlifoldResult;
import compbio.data.sequence.RNAStructScoreManager;
import compbio.data.sequence.Range;
import compbio.data.sequence.Score;
-import compbio.metadata.Argument;
/**
* Client for the JABA RNA Alifold Service
*
*/
-public class RNAalifoldClient extends JabawsCalcWorker
+public class RNAalifoldClient extends JabawsAnnotationInstance
{
- String methodName;
-
- AlignFrame af;
-
- // keeps track of whether the RNAalifold result includes base contact
- // probabilities
- boolean bpScores;
-
- public RNAalifoldClient(Jws2Instance sh, AlignFrame alignFrame,
- WsParamSetI preset, List<Argument> paramset)
- {
- super(sh, alignFrame, preset, paramset);
- af = alignFrame;
- methodName = sh.serviceType;
- alignedSeqs = true;
- submitGaps = true;
- nucleotidesAllowed = true;
- proteinAllowed = false;
- initViewportParams();
- }
+ // configuration
@Override
public String getCalcId()
private static String CALC_ID = "jalview.ws.jws2.RNAalifoldClient";
- public static AlignAnalysisUIText getAlignAnalysisUITest()
+ public static AlignAnalysisUIText getAlignAnalysisUIText()
{
return new AlignAnalysisUIText(
compbio.ws.client.Services.RNAalifoldWS.toString(),
- jalview.ws.jws2.RNAalifoldClient.class, CALC_ID, true, false,
- true, MessageManager.getString("label.rnalifold_calculations"),
+ jalview.ws.jws2.jabaws2.RNAalifoldClient.class, CALC_ID, true,
+ false, true, true, false, 2,
+ MessageManager.getString("label.rnalifold_calculations"),
MessageManager.getString("tooltip.rnalifold_calculations"),
MessageManager.getString("label.rnalifold_settings"),
MessageManager.getString("tooltip.rnalifold_settings"));
}
- @Override
- public String getServiceActionText()
+ public static String getServiceActionText()
{
return "Submitting RNA alignment for Secondary Structure prediction using "
+ "RNAalifold Service";
}
- @Override
- boolean checkValidInputSeqs(boolean dynamic, List<FastaSequence> seqs)
+ // instance
+
+ public RNAalifoldClient(Jws2Instance handle)
{
- return (seqs.size() > 1);
+ super(handle);
}
@Override
- public void updateResultAnnotation(boolean immediate)
+ List<AlignmentAnnotation> annotationFromScoreManager(AlignmentI seqs,
+ Map<String, FeatureColourI> featureColours,
+ Map<String, FeatureMatcherSetI> featureFilters)
{
-
- if (immediate || !calcMan.isWorking(this) && scoremanager != null)
+ List<AlignmentAnnotation> ourAnnot = new ArrayList<>();
+
+ // Unpack the ScoreManager
+ List<String> structs = ((RNAStructScoreManager) scoremanager)
+ .getStructs();
+ List<TreeSet<Score>> data = ((RNAStructScoreManager) scoremanager)
+ .getData();
+
+ // test to see if this data object contains base pair contacts
+ Score fscore = data.get(0).first();
+ boolean bpScores = (fscore.getMethod()
+ .equals(AlifoldResult.contactProbabilities.toString()));
+
+ // add annotation for the consensus sequence alignment
+ createAnnotationRowforScoreHolder(seqs, null,
+ ourAnnot,
+ getCalcId(), structs.get(0), null, null);
+
+ // Add annotations for the mfe Structure
+ createAnnotationRowforScoreHolder(seqs, null,
+ ourAnnot,
+ getCalcId(), structs.get(1), data.get(1), null);
+
+ // decide whether to add base pair contact probability histogram
+ int count = 2;
+ if (bpScores)
{
+ createAnnotationRowforScoreHolder(seqs, null,
+ ourAnnot,
+ getCalcId(), structs.get(2), data.get(0), data.get(2));
+ count++;
+ }
- List<AlignmentAnnotation> ourAnnot = new ArrayList<AlignmentAnnotation>();
-
- // Unpack the ScoreManager
- List<String> structs = ((RNAStructScoreManager) scoremanager)
- .getStructs();
- List<TreeSet<Score>> data = ((RNAStructScoreManager) scoremanager)
- .getData();
-
- // test to see if this data object contains base pair contacts
- Score fscore = data.get(0).first();
- this.bpScores = (fscore.getMethod()
- .equals(AlifoldResult.contactProbabilities.toString()));
-
- // add annotation for the consensus sequence alignment
- createAnnotationRowforScoreHolder(ourAnnot, getCalcId(),
- structs.get(0), null, null);
-
- // Add annotations for the mfe Structure
- createAnnotationRowforScoreHolder(ourAnnot, getCalcId(),
- structs.get(1), data.get(1), null);
-
- // decide whether to add base pair contact probability histogram
- int count = 2;
- if (bpScores)
- {
- createAnnotationRowforScoreHolder(ourAnnot, getCalcId(),
- structs.get(2), data.get(0), data.get(2));
- count++;
- }
-
- // Now loop for the rest of the Annotations (if there it isn't stochastic
- // output
- // only the centroid and MEA structures remain anyway)
- for (int i = count; i < structs.size(); i++)
- {
- // The ensemble values should be displayed in the description of the
- // first (or all?) Stochastic Backtrack Structures.
- if (!data.get(i).first().getMethod()
- .equals(AlifoldResult.ensembleValues.toString()))
- {
-
- createAnnotationRowforScoreHolder(ourAnnot, getCalcId(),
- structs.get(i), data.get(i), null);
- }
- }
-
- if (ourAnnot.size() > 0)
+ // Now loop for the rest of the Annotations (if there it isn't stochastic
+ // output
+ // only the centroid and MEA structures remain anyway)
+ for (int i = count; i < structs.size(); i++)
+ {
+ // The ensemble values should be displayed in the description of the
+ // first (or all?) Stochastic Backtrack Structures.
+ if (!data.get(i).first().getMethod()
+ .equals(AlifoldResult.ensembleValues.toString()))
{
- updateOurAnnots(ourAnnot);
- ap.adjustAnnotationHeight();
+ createAnnotationRowforScoreHolder(seqs, null, ourAnnot,
+ getCalcId(), structs.get(i), data.get(i), null);
}
}
+ return ourAnnot;
}
- protected void createAnnotationRowforScoreHolder(
+ private static void createAnnotationRowforScoreHolder(
+ AlignmentI alignment, boolean[] gapMap,
List<AlignmentAnnotation> ourAnnot, String calcId, String struct,
TreeSet<Score> data, TreeSet<Score> descriptionData)
{
String typename = typenameAndDescription[0];
String description = typenameAndDescription[1];
- AlignmentAnnotation annotation = alignViewport.getAlignment()
+ AlignmentAnnotation annotation = alignment
.findOrCreateAnnotation(typename, calcId, false, null, null);
- constructAnnotationFromScoreHolder(annotation, struct, data);
+ constructAnnotationFromScoreHolder(gapMap, annotation, struct, data);
/*
* update annotation description with the free Energy, frequency in ensemble
annotation.belowAlignment = false;
// annotation.showAllColLabels = true;
-
- alignViewport.getAlignment().validateAnnotation(annotation);
- af.setMenusForViewport();
-
+ annotation.validateRangeAndDisplay();
ourAnnot.add(annotation);
}
- private AlignmentAnnotation constructAnnotationFromScoreHolder(
- AlignmentAnnotation annotation, String struct,
+ private static AlignmentAnnotation constructAnnotationFromScoreHolder(
+ boolean[] gapMap, AlignmentAnnotation annotation, String struct,
TreeSet<Score> data)
{
Annotation[] anns = new Annotation[gapMap != null ? gapMap.length + 1
// The base pair probabilities are stored in a set in scoreholder. we want
// a map
- LinkedHashMap<Range, Float> basePairs = new LinkedHashMap<Range, Float>();
+ LinkedHashMap<Range, Float> basePairs = new LinkedHashMap<>();
for (Score score : data)
{
// The Score objects contain a set of size one containing the range and
return annotation;
}
- private String[] constructTypenameAndDescription(Score score)
+ private static String[] constructTypenameAndDescription(Score score)
{
String description = "";
String typename = "";
// Check whether, at position i there is a base contact and return all the
// contacts at this position. Should be in order of descending probability.
- private LinkedHashMap<Range, Float> isContact(
+ private static LinkedHashMap<Range, Float> isContact(
LinkedHashMap<Range, Float> basePairs, int i)
{
- LinkedHashMap<Range, Float> contacts = new LinkedHashMap<Range, Float>();
+ LinkedHashMap<Range, Float> contacts = new LinkedHashMap<>();
for (Range contact : basePairs.keySet())
{
return contacts;
}
- private char isSS(char chr)
+ private static char isSS(char chr)
{
String regex = "\\(|\\)|\\{|\\}|\\[|\\]";
char ss = (Pattern.matches(regex, Character.toString(chr))) ? 'S' : ' ';
return ss;
}
+
}
/**
*
+ * @return display name of this argument
+ */
+ default String getLabel()
+ {
+ return getName();
+ };
+
+ /**
+ *
* @return current value for the argument (may equal the name)
*/
String getValue();
*/
package jalview.ws.params;
+import jalview.util.MessageManager;
+import jalview.ws.api.ServiceWithParameters;
+
+import java.util.ArrayList;
import java.util.List;
-public abstract class AutoCalcSetting
+public class AutoCalcSetting
{
protected boolean autoUpdate;
protected List<ArgumentI> jobArgset;
- public AutoCalcSetting(WsParamSetI preset2, List<ArgumentI> jobArgset2,
+ protected ServiceWithParameters service;
+
+ public AutoCalcSetting(ServiceWithParameters service2,
+ WsParamSetI preset2, List<ArgumentI> jobArgset2,
boolean autoUpdate2)
{
+ service = service2;
autoUpdate = autoUpdate2;
preset = preset2;
jobArgset = jobArgset2;
}
/**
+ * TODO: refactor to ServiceWithParameters ?
*
* @return characteristic URI for this service. The URI should reflect the
* type and version of this service, enabling the service client code
* to recover the correct client for this calculation.
*/
- public abstract String getServiceURI();
+ public String getServiceURI()
+ {
+ return service.getNameURI();
+ }
/**
+ * TODO: refactor to ServiceWithParameters ?
+ *
* return any concrete service endpoints associated with this calculation.
* built in services should return a zero length array
*
* @return
*/
- public abstract String[] getServiceURLs();
+ public String[] getServiceURLs()
+ {
+ return new String[] { service.getUri() };
+ }
/**
+ * default WsParamFile generator method - clients with custom formats should
+ * override and implement their own
*
* @return stringified representation of the parameters for this setting
*/
- public abstract String getWsParamFile();
+ public String getWsParamFile()
+ {
+ List<ArgumentI> opts = null;
+ if (jobArgset != null)
+ {
+ opts = jobArgset;
+ }
+ else
+ {
+ if (preset != null)
+ {
+ opts = preset.getArguments();
+ }
+ }
+ if (opts == null || opts.size() == 0)
+ {
+ return "";
+ }
+ StringBuffer pset = new StringBuffer();
+ for (ArgumentI ps : opts)
+ {
+ pset.append(ps.getName() + "\t" + ps.getValue());
+ pset.append("\n");
+ }
+ return pset.toString();
+ }
+ public ServiceWithParameters getService()
+ {
+ return service;
+ }
+
+ public void setService(ServiceWithParameters service)
+ {
+ this.service = service;
+ if (preset != null)
+ {
+ // check if we need to migrate preset to a new service URL
+ for (String url : preset.getApplicableUrls())
+ {
+ if (url.equals(service.getUri()))
+ {
+ // preset already verified
+ return;
+ }
+ }
+ WsParamSetI pr = service.getParamStore().getPreset(preset.getName());
+
+ // TODO: decide of this distinction between preset and args are needed.
+ //
+ // if (pr instanceof JabaPreset && preset instanceof JabaPreset)
+ // {
+ // // easy - Presets are identical (we assume)
+ // preset = pr;
+ // return;
+ // }
+
+ // this verifies that all arguments in the existing preset are the same as
+ // the parameters for the preset provided by the service parameter store.
+ // ie the LastUsed settings or a predefined preset.
+
+ List<ArgumentI> oldargs = new ArrayList<>(),
+ newargs = new ArrayList<>();
+ oldargs.addAll(preset.getArguments());
+ // need to compare parameters
+ for (ArgumentI newparg : pr.getArguments())
+ {
+ if (!oldargs.remove(newparg))
+ {
+ newargs.add(newparg);
+ }
+ }
+ if (oldargs.size() == 0 && newargs.size() == 0)
+ {
+ // exact match.
+ preset = pr;
+ return;
+ }
+ // Try even harder to migrate arguments.
+ throw new Error(MessageManager
+ .getString("error.parameter_migration_not_implemented_yet"));
+ }
+ }
}
public interface OptionI extends ArgumentI
{
-
+ /**
+ * Answers a URL with further details for this option, or null if none is
+ * known
+ *
+ * @return
+ */
URL getFurtherDetails();
+ /**
+ * Answers true if the option is mandatory (a value must be chosen), false if
+ * it is optional
+ *
+ * @return
+ */
boolean isRequired();
+ /**
+ * Answers the description of the option
+ *
+ * @return
+ */
String getDescription();
+ /**
+ * Answers a list of possible values that may be chosen for the option (or
+ * null if not applicable)
+ *
+ * @return
+ */
List<String> getPossibleValues();
- OptionI copy();
+ /**
+ * Answers a list of display names corresponding to the possible values that
+ * may be chosen for the option (or null if not applicable)
+ *
+ * @return
+ */
+ List<String> getDisplayNames();
+ /**
+ * Answers a new Option with a copy of the settings of this one
+ *
+ * @return
+ */
+ OptionI copy();
}
public enum ValueType
{
- Integer, Float, String
+ Integer, Float, String, Double, File
};
ValueType getType();
*/
package jalview.ws.params.simple;
-import jalview.ws.params.OptionI;
-
import java.net.URL;
import java.util.Arrays;
-public class BooleanOption extends Option implements OptionI
+public class BooleanOption extends Option
{
public BooleanOption(String name, String descr, boolean required,
- boolean defVal, boolean val, URL link)
+ Boolean defVal, Boolean val, URL link)
{
+ super(name, descr, required, (defVal != null && defVal ? name : null),
+ (val != null && val ? name : null), Arrays.asList(name), link);
+ }
- super(name, descr, required, (defVal ? name : ""), (val ? name : ""),
- Arrays.asList(new String[]
- { name }), link);
+ public BooleanOption(String name, String description, String label,
+ boolean isrequired, Boolean defValue, String reprValue, URL link)
+ {
+ super(name, description, label, isrequired,
+ defValue != null && defValue ? reprValue : null,
+ defValue != null && defValue ? reprValue : null,
+ Arrays.asList(reprValue), link);
}
+ public BooleanOption(String name, String description, String label,
+ boolean isrequired, Boolean defValue, URL link)
+ {
+ this(name, description, label, isrequired, defValue, String.valueOf(true), link);
+ }
}
--- /dev/null
+package jalview.ws.params.simple;
+
+import jalview.ws.params.ParameterI;
+import jalview.ws.params.ValueConstrainI;
+
+/**
+ *
+ * @author TZVanaalten
+ *
+ */
+public class DoubleParameter extends Option implements ParameterI
+{
+ double defval;
+
+ double min;
+
+ double max;
+
+ @Override
+ public ValueConstrainI getValidValue()
+ {
+ return new ValueConstrainI()
+ {
+ @Override
+ public ValueType getType()
+ {
+ return ValueType.Double;
+ }
+
+ @Override
+ public Number getMin()
+ {
+ return min < max ? min : null;
+ }
+
+ @Override
+ public Number getMax()
+ {
+ return min < max ? max : null;
+ }
+ };
+ }
+
+ public DoubleParameter(DoubleParameter parm)
+ {
+ super(parm);
+ max = parm.max;
+ min = parm.min;
+ }
+
+ public DoubleParameter(String name, String description, boolean required,
+ Double defValue, double min, double max)
+ {
+ super(name, description, required, String.valueOf(defValue), null, null,
+ null);
+ defval = defValue;
+ this.min = min;
+ this.max = max;
+ }
+
+ public DoubleParameter(String name, String description, boolean required,
+ Double defValue, Double value, double min, double max)
+ {
+ super(name, description, required, String.valueOf(defValue),
+ String.valueOf(value), null, null);
+ defval = defValue;
+ this.min = min;
+ this.max = max;
+ }
+
+ @Override
+ public DoubleParameter copy()
+ {
+ return new DoubleParameter(this);
+ }
+}
--- /dev/null
+package jalview.ws.params.simple;
+
+import jalview.ws.params.ValueConstrainI;
+
+/**
+ * A class that represents a file parameter. User entry options should include
+ * direct input of a file path as text, or file selection using a file browser.
+ *
+ * @author gmcarstairs
+ *
+ */
+public class FileParameter extends StringParameter
+{
+
+ public FileParameter(String name, String description, boolean required,
+ String defValue, String value)
+ {
+ super(name, description, required, defValue, value);
+ }
+
+ @Override
+ public ValueConstrainI getValidValue()
+ {
+ return new ValueConstrainI()
+ {
+
+ @Override
+ public ValueType getType()
+ {
+ return ValueType.File;
+ }
+
+ @Override
+ public Number getMax()
+ {
+ return null;
+ }
+
+ @Override
+ public Number getMin()
+ {
+ return null;
+ }
+ };
+ }
+
+}
{
int defval;
- int min, max;
+ int min;
+ int max;
+
+ @Override
public ValueConstrainI getValidValue()
{
return new ValueConstrainI()
@Override
public Number getMin()
{
- if (min < max)
- {
- return min;
- }
- else
- {
- return null;
- }
+ return min < max ? min : null;
}
@Override
public Number getMax()
{
- if (min < max)
- {
- return max;
- }
- else
- {
- return null;
- }
+ return min < max ? max : null;
}
};
}
--- /dev/null
+package jalview.ws.params.simple;
+
+import jalview.ws.params.ParameterI;
+import jalview.ws.params.ValueConstrainI;
+
+/**
+ * A model for a numeric-valued parameter which should be displayed using a
+ * logarithmic scale
+ *
+ * @author TZVanaalten
+ */
+public class LogarithmicParameter extends Option implements ParameterI
+{
+ final double defval;
+
+ final double min;
+
+ final double max;
+
+ @Override
+ public ValueConstrainI getValidValue()
+ {
+ return new ValueConstrainI()
+ {
+
+ @Override
+ public ValueType getType()
+ {
+ return ValueType.Double;
+ }
+
+ @Override
+ public Number getMin()
+ {
+ return min < max ? min : null;
+ }
+
+ @Override
+ public Number getMax()
+ {
+ return min < max ? max : null;
+ }
+ };
+ }
+
+ public LogarithmicParameter(LogarithmicParameter parm)
+ {
+ super(parm);
+ max = parm.max;
+ min = parm.min;
+ defval = 0D;
+ }
+
+ public LogarithmicParameter(String name, String description,
+ boolean required, Double defValue, double min, double max)
+ {
+ super(name, description, required, String.valueOf(defValue), null, null,
+ null);
+ defval = defValue;
+ this.min = min;
+ this.max = max;
+ }
+
+ public LogarithmicParameter(String name, String description,
+ boolean required, Double defValue, double value, double min,
+ double max)
+ {
+ super(name, description, required, String.valueOf(defValue),
+ String.valueOf(value), null, null);
+ defval = defValue;
+ this.min = min;
+ this.max = max;
+ }
+
+ @Override
+ public LogarithmicParameter copy()
+ {
+ return new LogarithmicParameter(this);
+ }
+}
import java.net.URL;
import java.util.ArrayList;
-import java.util.Collection;
import java.util.List;
public class Option implements OptionI
{
+ String name;
- String name, value, defvalue, description;
+ String label;
- ArrayList<String> possibleVals = new ArrayList<String>();
+ /*
+ * current value in string format, or "null" if undefined
+ */
+ String value;
+
+ /*
+ * default value in string format, or "null" if undefined
+ */
+ String defvalue;
+
+ String description;
+
+ List<String> possibleVals;
+
+ /*
+ * optional display names corresponding to possibleVals
+ */
+ List<String> displayVals;
boolean required;
URL fdetails;
+ /**
+ * Copy constructor
+ *
+ * @param opt
+ */
+ public Option(Option opt)
+ {
+ name = opt.name;
+ label = opt.label;
+ value = opt.value;
+ defvalue = opt.defvalue;
+ description = opt.description;
+ if (opt.possibleVals != null)
+ {
+ possibleVals = new ArrayList<>(opt.possibleVals);
+ }
+ required = opt.required;
+ // URLs are singletons - so we copy by reference. nasty but true.
+ fdetails = opt.fdetails;
+ }
+
+ public Option()
+ {
+ }
+
+ public Option(String name, String description, String label, boolean isrequired,
+ String defValue, String val, List<String> possibleVals, URL fdetails)
+ {
+ this(name, description, isrequired, defValue, val, possibleVals, fdetails);
+ this.label = label;
+ }
+
+ /**
+ * Constructor including display names for possible values
+ *
+ * @param name2
+ * @param description2
+ * @param isrequired
+ * @param defValue
+ * @param val
+ * @param possibleVals
+ * @param fdetails
+ */
+ public Option(String name2, String description2, boolean isrequired,
+ String defValue, String val, List<String> possibleVals,
+ List<String> displayNames, URL fdetails)
+ {
+ name = name2;
+ description = description2;
+ this.value = val;
+ this.required = isrequired;
+ this.defvalue = defValue;
+ if (possibleVals != null)
+ {
+ this.possibleVals = new ArrayList<>(possibleVals);
+ }
+ if (displayNames != null)
+ {
+ this.displayVals = new ArrayList<>(displayNames);
+ }
+ this.fdetails = fdetails;
+ }
+
+ /**
+ * Constructor
+ *
+ * @param name2
+ * @param description2
+ * @param isrequired
+ * @param defValue
+ * @param val
+ * @param possibleVals
+ * @param fdetails
+ */
+ public Option(String name2, String description2, boolean isrequired,
+ String defValue, String val, List<String> possibleVals,
+ URL fdetails)
+ {
+ this(name2, description2, isrequired, defValue, val, possibleVals, null,
+ fdetails);
+ }
+
+ @Override
+ public OptionI copy()
+ {
+ Option opt = new Option(this);
+ return opt;
+ }
+
+ /**
+ * toString method to help identify options in the debugger only
+ */
+ @Override
+ public String toString()
+ {
+ return this.getClass().getName() + ":" + name;
+ }
+
@Override
public String getName()
{
}
@Override
+ public String getLabel()
+ {
+ return label != null ? label : name;
+ }
+
+ @Override
public String getValue()
{
return value == null ? defvalue : value;
return possibleVals;
}
- public Option(Option opt)
- {
- name = new String(opt.name);
- if (opt.value != null)
- value = new String(opt.value);
- if (opt.defvalue != null)
- defvalue = new String(opt.defvalue);
- if (opt.description != null)
- description = new String(opt.description);
- if (opt.possibleVals != null)
- {
- possibleVals = (ArrayList<String>) opt.possibleVals.clone();
- }
- required = opt.required;
- // URLs are singletons - so we copy by reference. nasty but true.
- fdetails = opt.fdetails;
- }
-
- public Option()
- {
- }
-
- public Option(String name2, String description2, boolean isrequired,
- String defValue, String value, Collection<String> possibleVals,
- URL fdetails)
- {
- name = name2;
- description = description2;
- this.value = value;
- this.required = isrequired;
- this.defvalue = defValue;
- if (possibleVals != null)
- {
- this.possibleVals = new ArrayList<String>();
- this.possibleVals.addAll(possibleVals);
- }
- this.fdetails = fdetails;
- }
-
@Override
- public OptionI copy()
+ public List<String> getDisplayNames()
{
- Option opt = new Option(this);
- return opt;
+ return displayVals;
}
}
+++ /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.params.simple;
-
-import jalview.ws.params.OptionI;
-import jalview.ws.params.ParameterI;
-import jalview.ws.params.ValueConstrainI;
-
-public abstract class Parameter extends Option
- implements OptionI, ParameterI
-{
- ValueConstrainI validator;
-
- @Override
- public ValueConstrainI getValidValue()
- {
- return validator;
- }
-
- public Parameter(Parameter parm)
- {
- super(parm);
- }
-
- public Parameter(ValueConstrainI validator)
- {
- super();
- this.validator = validator;
- }
-
- @Override
- public abstract Parameter copy();
-}
*/
package jalview.ws.params.simple;
-public class StringChoiceParameter extends Option
+import java.util.List;
+
+/**
+ * A parameter with a choice of possible options, preferred to be rendered as
+ * radio buttons if possible
+ */
+public class RadioChoiceParameter extends StringParameter
{
+ /**
+ * Constructor
+ *
+ * @param name
+ * @param description
+ * @param options
+ * @param def
+ */
+ public RadioChoiceParameter(String name, String description,
+ List<String> options, String def)
+ {
+ super(name, description, true, def, def, options, null);
+ }
}
--- /dev/null
+package jalview.ws.params.simple;
+
+import jalview.ws.params.ParameterI;
+import jalview.ws.params.ValueConstrainI;
+
+import java.util.List;
+
+public class StringParameter extends Option implements ParameterI
+{
+ @Override
+ public ValueConstrainI getValidValue()
+ {
+ return new StringValueConstrain();
+ }
+
+ @Override
+ public ParameterI copy()
+ {
+ return new StringParameter(this);
+ }
+
+ private class StringValueConstrain implements ValueConstrainI
+ {
+
+ @Override
+ public ValueType getType()
+ {
+ return ValueType.String;
+ }
+
+ @Override
+ public Number getMax()
+ {
+ return null;
+ }
+
+ @Override
+ public Number getMin()
+ {
+ return null;
+ }
+
+ }
+
+ public StringParameter(StringParameter parm)
+ {
+ this.name = parm.name;
+ this.defvalue = parm.defvalue;
+ this.possibleVals = parm.possibleVals;
+ this.displayVals = parm.displayVals;
+ }
+
+ public StringParameter(String name, String description, boolean required,
+ String defValue)
+ {
+ super(name, description, required, String.valueOf(defValue), null, null,
+ null);
+ this.defvalue = defValue;
+ }
+
+ public StringParameter(String name, String description, boolean required,
+ String defValue, String value)
+ {
+ super(name, description, required, String.valueOf(defValue),
+ String.valueOf(value), null, null);
+ this.defvalue = defValue;
+ }
+
+ /**
+ * Constructor for a parameter with a list of possible values and (optionally)
+ * corresponding display names
+ *
+ * @param name2
+ * @param description2
+ * @param isrequired
+ * @param defValue
+ * @param value
+ * @param possibleVals
+ * @param displayNames
+ */
+ public StringParameter(String name2, String description2,
+ boolean isrequired, String defValue, String value,
+ List<String> possibleVals, List<String> displayNames)
+ {
+ super(name2, description2, isrequired, defValue, value, possibleVals,
+ displayNames, null);
+ }
+}
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.entity.mime.MultipartEntity;
+import org.apache.http.util.EntityUtils;
import org.apache.james.mime4j.MimeException;
import org.apache.james.mime4j.parser.MimeStreamParser;
-
/**
* data source instantiated from the response of an httpclient request.
*
}
jalview.io.packed.JalviewDataset ds = restJob.newJalviewDataset();
// Decide how we deal with content.
- if (en instanceof MultipartEntity)
+ // TODO : verify we are detecting a multipart response correctly
+ if (en.getContentType().getValue().startsWith("multipart/form-data"))
{
// Multipart messages should be properly typed, so we parse them as we go.
- MultipartEntity mpe = (MultipartEntity) en;
- // multipart
JalviewMimeContentHandler handler = new JalviewMimeContentHandler(ds);
MimeStreamParser parser = new MimeStreamParser();
parser.setContentHandler(handler);
try
{
- parser.parse(mpe.getContent());
+ parser.parse(en.getContent());
} catch (MimeException me)
{
error = true;
errormessage = "Couldn't parse message from web service.";
Cache.log.warn("Failed to parse MIME multipart content", me);
- en.consumeContent();
+ EntityUtils.consume(en);
}
return new ParsePackedSet().getAlignment(ds,
handler.getJalviewDataProviders());
{
Cache.log.error("Can't handle encoding '" + enc
+ "' for response from webservice.", e);
- en.consumeContent();
+ EntityUtils.consume(en);
error = true;
errormessage = "Can't handle encoding for response from webservice";
return;
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import java.util.ArrayList;
-import java.util.Collection;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
{
NUC, PROT, MIX;
- public static Collection<String> toStringValues()
+ public static List<String> toStringValues()
{
- Collection<String> c = new ArrayList<String>();
+ List<String> c = new ArrayList<>();
for (molType type : values())
{
c.add(type.toString());
public int max = 0; // unbounded
- protected ArrayList<Class> inputData = new ArrayList<Class>();
+ protected List<Class> inputData = new ArrayList<>();
/**
* initialise the InputType with a list of jalview data classes that the
public boolean validFor(RestJob restJob)
{
if (!validFor(restJob.rsd))
+ {
return false;
+ }
for (Class cl : inputData)
{
if (!restJob.hasDataOfType(cl))
public boolean validFor(RestServiceDescription restServiceDescription)
{
if (!restServiceDescription.inputParams.values().contains(this))
+ {
return false;
+ }
return true;
}
public List<OptionI> getBaseOptions()
{
- ArrayList<OptionI> opts = new ArrayList<OptionI>();
+ ArrayList<OptionI> opts = new ArrayList<>();
opts.add(new IntegerParameter("min",
"Minimum number of data of this type", true, 1, min, 0, -1));
opts.add(new IntegerParameter("max",
public void configureFromArgumentI(List<ArgumentI> currentSettings)
throws InvalidArgumentException
{
- ArrayList<String> urltoks = new ArrayList<String>();
+ List<String> urltoks = new ArrayList<>();
String rg;
for (ArgumentI arg : currentSettings)
{
*/
package jalview.ws.rest;
+import jalview.bin.ApplicationSingletonProvider;
+import jalview.bin.ApplicationSingletonProvider.ApplicationSingletonI;
import jalview.bin.Cache;
import jalview.datamodel.AlignmentView;
import jalview.gui.AlignFrame;
import jalview.gui.Desktop;
import jalview.gui.JvOptionPane;
import jalview.gui.WebserviceInfo;
-import jalview.io.packed.DataProvider.JvDataType;
import jalview.util.MessageManager;
import jalview.ws.WSClient;
import jalview.ws.WSClientI;
import jalview.ws.WSMenuEntryProviderI;
+import jalview.ws.rest.clientdefs.ShmrRestClient;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
-import java.util.Hashtable;
import java.util.Vector;
import javax.swing.JMenu;
*
*/
public class RestClient extends WSClient
- implements WSClientI, WSMenuEntryProviderI
+implements WSClientI, WSMenuEntryProviderI, ApplicationSingletonI
{
+
+ @SuppressWarnings("unused")
+ private RestClient()
+ {
+ // accessed by ApplicationSingletonProvider
+ }
+
+
+private static RestClient getInstance()
+{
+return (RestClient) ApplicationSingletonProvider.getInstance(RestClient.class);
+}
+
+public static final String RSBS_SERVICES = "RSBS_SERVICES";
+
+
+ protected Vector<String> services = null;
+
+
RestServiceDescription service;
public RestClient(RestServiceDescription rsd)
{
WebServiceJobTitle = MessageManager
.formatMessage("label.webservice_job_title", new String[]
- { service.details.Action, service.details.Name });
- WebServiceName = service.details.Name;
+ { service.details.getAction(), service.details.getName() });
+ WebServiceName = service.details.getName();
WebServiceReference = "No reference - go to url for more info";
- if (service.details.description != null)
+ if (service.details.getDescription() != null)
{
- WebServiceReference = service.details.description;
+ WebServiceReference = service.details.getDescription();
}
if (!headless)
{
wsInfo = new WebserviceInfo(WebServiceJobTitle,
- WebServiceName + "\n" + WebServiceReference, true);
+ WebServiceName + "\n" + WebServiceReference, Desktop.FRAME_MAKE_VISIBLE);
wsInfo.setRenderAsHtml(true);
}
public void attachWSMenuEntry(final JMenu wsmenu,
final AlignFrame alignFrame)
{
- JMenuItem submit = new JMenuItem(service.details.Name);
+ JMenuItem submit = new JMenuItem(service.details.getName());
submit.setToolTipText(MessageManager
.formatMessage("label.rest_client_submit", new String[]
- { service.details.Action, service.details.Name }));
+ { service.details.getAction(), service.details.getName() }));
submit.addActionListener(new ActionListener()
{
else
{
// TODO: try to tell the user why the job couldn't be started.
- JvOptionPane.showMessageDialog(Desktop.desktop,
+ JvOptionPane.showMessageDialog(Desktop.getDesktopPane(),
(jobsthread.hasWarnings() ? jobsthread.getWarnings()
: MessageManager.getString(
"label.job_couldnt_be_started_check_input")),
}
}
- public static RestClient makeShmmrRestClient()
- {
- String action = "Analysis",
- description = "Sequence Harmony and Multi-Relief (Brandt et al. 2010)",
- name = MessageManager.getString("label.multiharmony");
- Hashtable<String, InputType> iparams = new Hashtable<String, InputType>();
- jalview.ws.rest.params.JobConstant toolp;
- // toolp = new jalview.ws.rest.JobConstant("tool","jalview");
- // iparams.put(toolp.token, toolp);
- // toolp = new jalview.ws.rest.params.JobConstant("mbjob[method]","shmr");
- // iparams.put(toolp.token, toolp);
- // toolp = new
- // jalview.ws.rest.params.JobConstant("mbjob[description]","step 1");
- // iparams.put(toolp.token, toolp);
- // toolp = new jalview.ws.rest.params.JobConstant("start_search","1");
- // iparams.put(toolp.token, toolp);
- // toolp = new jalview.ws.rest.params.JobConstant("blast","0");
- // iparams.put(toolp.token, toolp);
-
- jalview.ws.rest.params.Alignment aliinput = new jalview.ws.rest.params.Alignment();
- // SHMR server has a 65K limit for content pasted into the 'ali' parameter,
- // so we always upload our files.
- aliinput.token = "ali_file";
- aliinput.writeAsFile = true;
- iparams.put(aliinput.token, aliinput);
- jalview.ws.rest.params.SeqGroupIndexVector sgroups = new jalview.ws.rest.params.SeqGroupIndexVector();
- sgroups.setMinsize(2);
- sgroups.min = 2;// need at least two group defined to make a partition
- iparams.put("groups", sgroups);
- sgroups.token = "groups";
- sgroups.sep = " ";
- RestServiceDescription shmrService = new RestServiceDescription(action,
- description, name,
- "http://zeus.few.vu.nl/programs/shmrwww/index.php?tool=jalview", // ?tool=jalview&mbjob[method]=shmr&mbjob[description]=step1",
- "?tool=jalview", iparams, true, false, '-');
- // a priori knowledge of the data returned from the service
- shmrService.addResultDatatype(JvDataType.ANNOTATION);
- return new RestClient(shmrService);
- }
-
public AlignmentPanel recoverAlignPanelForView()
{
AlignmentPanel[] aps = Desktop
return true;
}
- protected static Vector<String> services = null;
-
- public static final String RSBS_SERVICES = "RSBS_SERVICES";
-
public static RestClient[] getRestClients()
{
+ return getInstance().getClients();
+ }
+
+ private RestClient[] getClients()
+ {
if (services == null)
{
- services = new Vector<String>();
+ services = new Vector<>();
try
{
for (RestServiceDescription descr : RestServiceDescription
- .parseDescriptions(
- jalview.bin.Cache.getDefault(RSBS_SERVICES,
- makeShmmrRestClient().service.toString())))
+ .parseDescriptions(jalview.bin.Cache.getDefault(
+ RSBS_SERVICES,
+ ShmrRestClient.makeShmmrRestClient().service.toString())))
{
services.add(descr.toString());
}
public String getAction()
{
- return service.details.Action;
+ return service.details.getAction();
}
public RestServiceDescription getRestDescription()
public static Vector<String> getRsbsDescriptions()
{
- Vector<String> rsbsDescrs = new Vector<String>();
+ Vector<String> rsbsDescrs = new Vector<>();
for (RestClient rsbs : getRestClients())
{
rsbsDescrs.add(rsbs.getRestDescription().toString());
{
if (rsbsUrls != null)
{
+
// TODO: consider validating services ?
- services = new Vector<String>(rsbsUrls);
+ getInstance().services = new Vector<String>(rsbsUrls);
StringBuffer sprop = new StringBuffer();
- for (String s : services)
+ for (String s : getInstance().services)
{
sprop.append(s);
}
import org.apache.http.entity.mime.HttpMultipartMode;
import org.apache.http.entity.mime.MultipartEntity;
import org.apache.http.impl.client.DefaultHttpClient;
-import org.apache.http.protocol.BasicHttpContext;
-import org.apache.http.protocol.HttpContext;
import org.apache.http.util.EntityUtils;
public class RestJobThread extends AWSThread
protected void doHttpReq(Stage stg, RestJob rj, String postUrl)
throws Exception
{
- StringBuffer respText = new StringBuffer();
- // con.setContentHandlerFactory(new
- // jalview.ws.io.mime.HttpContentHandler());
HttpRequestBase request = null;
String messages = "";
if (stg == Stage.SUBMIT)
{
DefaultHttpClient httpclient = new DefaultHttpClient();
- HttpContext localContext = new BasicHttpContext();
HttpResponse response = null;
try
{
Cache.log.debug("Processing result set.");
processResultSet(rj, response, request);
break;
+
case 202:
- rj.statMessage = "<br>Job submitted successfully. Results available at this URL:\n"
- + "<a href=" + rj.getJobId() + "\">" + rj.getJobId()
- + "</a><br>";
- rj.running = true;
+ markJobAsRunning(rj);
break;
+
+ case 201:
+ // Created - redirect may be present. Fallthrough to 302
case 302:
- Header[] loc;
- if (!rj.isSubmitted()
- && (loc = response
- .getHeaders(HTTPConstants.HEADER_LOCATION)) != null
- && loc.length > 0)
- {
- if (loc.length > 1)
- {
- Cache.log.warn("Ignoring additional " + (loc.length - 1)
- + " location(s) provided in response header ( next one is '"
- + loc[1].getValue() + "' )");
- }
- rj.setJobId(loc[0].getValue());
- rj.setSubmitted(true);
- }
+ extractJobId(rj, response);
completeStatus(rj, response);
break;
case 500:
- // Failed.
- rj.setSubmitted(true);
- rj.setAllowedServerExceptions(0);
- rj.setSubjobComplete(true);
- rj.error = true;
- rj.running = false;
- completeStatus(rj, response,
- "" + getStage(stg) + "failed. Reason below:\n");
+ markAsFailed(rj, response);
+ completeStatus(rj, response, "" + getStage(stg)
+ + "failed. Reason below:\n");
break;
default:
// Some other response. Probably need to pop up the content in a window.
}
}
+ private void markAsFailed(RestJob rj, HttpResponse response)
+ {
+ // Failed.
+ rj.setSubmitted(true);
+ rj.setAllowedServerExceptions(0);
+ rj.setSubjobComplete(true);
+ rj.error = true;
+ rj.running = false;
+ }
+
+ /**
+ * set the jobRunning flag and post a link to the physical result page encoded
+ * in rj.getJobId()
+ *
+ * @param rj
+ */
+ private void markJobAsRunning(RestJob rj)
+ {
+ rj.statMessage = "<br>Job submitted successfully. Results available at this URL:\n"
+ + "<a href="
+ + rj.getJobId()
+ + "\">"
+ + rj.getJobId()
+ + "</a><br>";
+ rj.running = true;
+ }
+
+ /**
+ * extract the job ID URL from the redirect page. Does nothing if job is
+ * already running.
+ *
+ * @param rj
+ * @param response
+ */
+ private void extractJobId(RestJob rj, HttpResponse response)
+ {
+ Header[] loc;
+ if (!rj.isSubmitted())
+ {
+
+ // redirect URL - typical for IBIVU type jobs.
+ if ((loc = response.getHeaders(HTTPConstants.HEADER_LOCATION)) != null
+ && loc.length > 0)
+ {
+ if (loc.length > 1)
+ {
+ Cache.log
+ .warn("Ignoring additional "
+ + (loc.length - 1)
+ + " location(s) provided in response header ( next one is '"
+ + loc[1].getValue() + "' )");
+ }
+ rj.setJobId(loc[0].getValue());
+ rj.setSubmitted(true);
+ }
+ }
+ }
+
/**
* job has completed. Something valid should be available from con
*
/**
* alignment panels derived from each alignment set returned by service.
*/
- ArrayList<jalview.gui.AlignmentPanel> destPanels = new ArrayList<jalview.gui.AlignmentPanel>();
+ ArrayList<jalview.gui.AlignmentPanel> destPanels = new ArrayList<>();
/**
* list of instructions for how to process each distinct alignment set
* returned by the job set
*/
- ArrayList<AddDataTo> resultDest = new ArrayList<AddDataTo>();
+ ArrayList<AddDataTo> resultDest = new ArrayList<>();
/**
* when false, zeroth pane is panel derived from input deta.
*/
boolean vsepjobs = restClient.service.isVseparable();
// total number of distinct alignment sets generated by job set.
int numAlSets = 0, als = 0;
- List<AlignmentI> destAls = new ArrayList<AlignmentI>();
- List<jalview.datamodel.HiddenColumns> destColsel = new ArrayList<jalview.datamodel.HiddenColumns>();
- List<List<NewickFile>> trees = new ArrayList<List<NewickFile>>();
+ List<AlignmentI> destAls = new ArrayList<>();
+ List<jalview.datamodel.HiddenColumns> destColsel = new ArrayList<>();
+ List<List<NewickFile>> trees = new ArrayList<>();
do
{
if (alset.trees != null)
{
- trees.add(new ArrayList<NewickFile>(alset.trees));
+ trees.add(new ArrayList<>(alset.trees));
}
else
{
*/
int vrestjob = 0;
// Destination alignments for all result data.
- ArrayList<SequenceGroup> visgrps = new ArrayList<SequenceGroup>();
- Hashtable<String, SequenceGroup> groupNames = new Hashtable<String, SequenceGroup>();
+ ArrayList<SequenceGroup> visgrps = new ArrayList<>();
+ Hashtable<String, SequenceGroup> groupNames = new Hashtable<>();
ArrayList<AlignmentAnnotation> visAlAn = null;
for (nvertsep = 0; nvertsep < nvertseps; nvertsep++)
{
}
if (visAlAn == null)
{
- visAlAn = new ArrayList<AlignmentAnnotation>();
+ visAlAn = new ArrayList<>();
}
AlignmentAnnotation visan = null;
for (AlignmentAnnotation v : visAlAn)
HiddenColumns destcs;
String alTitle = MessageManager
.formatMessage("label.webservice_job_title_on", new String[]
- { restClient.service.details.Action,
- restClient.service.details.Name, restClient.viewTitle });
+ { restClient.service.details.getAction(),
+ restClient.service.details.getName(),
+ restClient.viewTitle });
switch (action)
{
case newAlignment:
*/
public boolean isValid()
{
- ArrayList<String> _warnings = new ArrayList<String>();
+ ArrayList<String> _warnings = new ArrayList<>();
boolean validt = true;
if (jobs != null)
{
import jalview.datamodel.SequenceI;
import jalview.io.packed.DataProvider.JvDataType;
import jalview.util.StringUtils;
+import jalview.ws.api.UIinfo;
import jalview.ws.rest.params.Alignment;
import jalview.ws.rest.params.AnnotationFile;
import jalview.ws.rest.params.SeqGroupIndexVector;
boolean vseparable, char gapCharacter)
{
super();
- this.details = new UIinfo();
- details.Action = action == null ? "" : action;
- details.description = description == null ? "" : description;
- details.Name = name == null ? "" : name;
+ this.details = new UIinfo(action, action, name, description, postUrl);
this.postUrl = postUrl == null ? "" : postUrl;
this.urlSuffix = urlSuffix == null ? "" : urlSuffix;
if (inputParams != null)
// TODO - robust diff that includes constants and reordering of URL
// diff |= !(postUrl.equals(other.postUrl));
// diff |= !inputParams.equals(other.inputParams);
- diff |= !details.Name.equals(other.details.Name);
- diff |= !details.Action.equals(other.details.Action);
- diff |= !details.description.equals(other.details.description);
+ diff |= !details.equals(other.details);
return !diff;
}
- /**
- * Service UI Info { Action, Specific Name of Service, Brief Description }
- */
-
- public class UIinfo
- {
- public String getAction()
- {
- return Action;
- }
-
- public void setAction(String action)
- {
- Action = action;
- }
-
- public String getName()
- {
- return Name;
- }
-
- public void setName(String name)
- {
- Name = name;
- }
-
- public String getDescription()
- {
- return description;
- }
-
- public void setDescription(String description)
- {
- this.description = description;
- }
-
- String Action;
-
- String Name;
-
- String description;
- }
-
- public UIinfo details = new UIinfo();
+ public UIinfo details;
public String getAction()
{
/**
* input info given as key/value pairs - mapped to post arguments
*/
- Map<String, InputType> inputParams = new HashMap<String, InputType>();
+ Map<String, InputType> inputParams = new HashMap<>();
/**
* assigns the given inputType it to its corresponding input parameter token
}
StringTokenizer st = new StringTokenizer(outstring, ";");
String tok = "";
- resultData = new ArrayList<JvDataType>();
+ resultData = new ArrayList<>();
while (st.hasMoreTokens())
{
try
private String getServiceIOProperties()
{
- ArrayList<String> vls = new ArrayList<String>();
+ ArrayList<String> vls = new ArrayList<>();
if (isHseparable())
{
vls.add("hseparable");
",");
}
+ @Override
public String toString()
{
StringBuffer result = new StringBuffer();
result.append("|");
- result.append(details.Name);
+ result.append(details.getName());
result.append('|');
- result.append(details.Action);
+ result.append(details.getAction());
result.append('|');
- if (details.description != null)
+ if (details.getDescription() != null)
{
- result.append(details.description);
+ result.append(details.getDescription());
}
;
// list job input flags
{
p++;
}
- details.Name = list[p];
- details.Action = list[p + 1];
- details.description = list[p + 2];
+ String action = list[p + 1], name = list[p], descrip = list[p + 2];
+
invalid |= !configureFromServiceInputProperties(list[p + 3], warnings);
if (list.length - p > 5 && list[p + 5] != null
&& list[p + 5].trim().length() > 5)
p += 5;
}
}
+ details = new UIinfo(action, action, name, descrip, postUrl);
return invalid ? -1 : p;
}
int lastp = 0;
String url = new String();
Matcher prms = PARAM_ENCODED_URL_PATTERN.matcher(ipurl);
- Map<String, InputType> iparams = new Hashtable<String, InputType>();
+ Map<String, InputType> iparams = new Hashtable<>();
InputType jinput;
while (prms.find())
{
jinput = (InputType) (type.getConstructor().newInstance());
if (iprm.equalsIgnoreCase(jinput.getURLtokenPrefix()))
{
- ArrayList<String> al = new ArrayList<String>();
+ ArrayList<String> al = new ArrayList<>();
for (String prprm : StringUtils.separatorListToArray(iprmparams,
","))
{
return jobId + urlSuffix;
}
- private List<JvDataType> resultData = new ArrayList<JvDataType>();
+ private List<JvDataType> resultData = new ArrayList<>();
/**
*
{
if (resultData == null)
{
- resultData = new ArrayList<JvDataType>();
+ resultData = new ArrayList<>();
}
resultData.add(dt);
}
String services) throws Exception
{
String[] list = StringUtils.separatorListToArray(services, "|");
- List<RestServiceDescription> svcparsed = new ArrayList<RestServiceDescription>();
+ List<RestServiceDescription> svcparsed = new ArrayList<>();
int p = 0, lastp = 0;
StringBuffer warnings = new StringBuffer();
do
--- /dev/null
+package jalview.ws.rest.clientdefs;
+
+import jalview.io.packed.DataProvider.JvDataType;
+import jalview.util.MessageManager;
+import jalview.ws.rest.InputType;
+import jalview.ws.rest.RestClient;
+import jalview.ws.rest.RestServiceDescription;
+import java.util.Hashtable;
+
+public class ShmrRestClient
+{
+
+ public static RestClient makeShmmrRestClient()
+ {
+ String action = "Analysis", description = "Sequence Harmony and Multi-Relief (Brandt et al. 2010)", name = MessageManager
+ .getString("label.multiharmony");
+ Hashtable<String, InputType> iparams = new Hashtable<String, InputType>();
+ jalview.ws.rest.params.JobConstant toolp;
+ // toolp = new jalview.ws.rest.JobConstant("tool","jalview");
+ // iparams.put(toolp.token, toolp);
+ // toolp = new jalview.ws.rest.params.JobConstant("mbjob[method]","shmr");
+ // iparams.put(toolp.token, toolp);
+ // toolp = new
+ // jalview.ws.rest.params.JobConstant("mbjob[description]","step 1");
+ // iparams.put(toolp.token, toolp);
+ // toolp = new jalview.ws.rest.params.JobConstant("start_search","1");
+ // iparams.put(toolp.token, toolp);
+ // toolp = new jalview.ws.rest.params.JobConstant("blast","0");
+ // iparams.put(toolp.token, toolp);
+
+ jalview.ws.rest.params.Alignment aliinput = new jalview.ws.rest.params.Alignment();
+ // SHMR server has a 65K limit for content pasted into the 'ali' parameter,
+ // so we always upload our files.
+ aliinput.token = "ali_file";
+ aliinput.writeAsFile = true;
+ iparams.put(aliinput.token, aliinput);
+ jalview.ws.rest.params.SeqGroupIndexVector sgroups = new jalview.ws.rest.params.SeqGroupIndexVector();
+ sgroups.setMinsize(2);
+ sgroups.min = 2;// need at least two group defined to make a partition
+ iparams.put("groups", sgroups);
+ sgroups.token = "groups";
+ sgroups.sep = " ";
+ RestServiceDescription shmrService = new RestServiceDescription(
+ action,
+ description,
+ name,
+ "http://zeus.few.vu.nl/programs/shmrwww/index.php?tool=jalview",// ?tool=jalview&mbjob[method]=shmr&mbjob[description]=step1",
+ "?tool=jalview", iparams, true, false, '-');
+ // a priori knowledge of the data returned from the service
+ shmrService.addResultDatatype(JvDataType.ANNOTATION);
+ return new RestClient(shmrService);
+ }
+
+}
*/
package jalview.ws.sifts;
-import java.util.Locale;
-
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
+import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
private final static String NEWLINE = System.lineSeparator();
+ private static final boolean GET_STREAM = false;
+ private static final boolean CACHE_FILE = true;
private String curSourceDBRef;
private HashSet<String> curDBRefAccessionIdsString;
+ private boolean doCache = false;
private enum CoordinateSys
{
UNIPROT("UniProt"), PDB("PDBresnum"), PDBe("PDBe");
-
private String name;
private CoordinateSys(String name)
{
NAME_SEC_STRUCTURE("nameSecondaryStructure"),
CODE_SEC_STRUCTURE("codeSecondaryStructure"), ANNOTATION("Annotation");
-
private String code;
private ResidueDetailType(String code)
{
this.pdb = pdb;
this.pdbId = pdb.getId();
- File siftsFile = getSiftsFile(pdbId);
- siftsEntry = parseSIFTs(siftsFile);
+ if (doCache) {
+ File siftsFile = getSiftsFile(pdbId);
+ siftsEntry = parseSIFTs(siftsFile);
+ } else {
+ siftsEntry = parseSIFTSStreamFor(pdbId);
+ }
+ }
+
+ /**
+ * A more streamlined version of SIFT reading that allows for streaming of the data.
+ *
+ * @param pdbId
+ * @return
+ * @throws SiftsException
+ */
+ private static Entry parseSIFTSStreamFor(String pdbId) throws SiftsException
+ {
+ try
+ {
+ InputStream is = (InputStream) downloadSifts(pdbId, GET_STREAM);
+ return parseSIFTs(is);
+ } catch (Exception e)
+ {
+ throw new SiftsException(e.getMessage());
+ }
}
/**
*/
private Entry parseSIFTs(File siftFile) throws SiftsException
{
- try (InputStream in = new FileInputStream(siftFile);
- GZIPInputStream gzis = new GZIPInputStream(in);)
+ try (InputStream in = new FileInputStream(siftFile)) {
+ return parseSIFTs(in);
+ } catch (Exception e)
+ {
+ e.printStackTrace();
+ throw new SiftsException(e.getMessage());
+ }
+ }
+
+ private static Entry parseSIFTs(InputStream in) throws Exception {
+ try (GZIPInputStream gzis = new GZIPInputStream(in);)
{
// System.out.println("File : " + siftFile.getAbsolutePath());
JAXBContext jc = JAXBContext.newInstance("jalview.xml.binding.sifts");
Unmarshaller um = jc.createUnmarshaller();
JAXBElement<Entry> jbe = um.unmarshal(streamReader, Entry.class);
return jbe.getValue();
- } catch (Exception e)
- {
- e.printStackTrace();
- throw new SiftsException(e.getMessage());
}
}
}
/**
- * This method enables checking if a cached file has exceeded a certain
- * threshold(in days)
- *
- * @param file
- * the cached file
- * @param noOfDays
- * the threshold in days
- * @return
- */
- public static boolean isFileOlderThanThreshold(File file, int noOfDays)
- {
- Path filePath = file.toPath();
- BasicFileAttributes attr;
- int diffInDays = 0;
- try
- {
- attr = Files.readAttributes(filePath, BasicFileAttributes.class);
- diffInDays = (int) ((new Date().getTime()
- - attr.lastModifiedTime().toMillis())
- / (1000 * 60 * 60 * 24));
- // System.out.println("Diff in days : " + diffInDays);
- } catch (IOException e)
- {
- e.printStackTrace();
- }
- return noOfDays <= diffInDays;
- }
-
- /**
* Download a SIFTs XML file for a given PDB Id from an FTP repository
*
* @param pdbId
*/
public static File downloadSiftsFile(String pdbId)
throws SiftsException, IOException
+ {
+ return (File) downloadSifts(pdbId, CACHE_FILE);
+ }
+
+ /**
+ * Download SIFTs XML with the option to cache a file or to get a stream.
+ *
+ * @param pdbId
+ * @param asFile
+ * @return
+ * @throws IOException
+ */
+ private static Object downloadSifts(String pdbId, boolean asFile) throws IOException
{
+ pdbId = pdbId.toLowerCase(Locale.ROOT);
if (pdbId.contains(".cif"))
{
pdbId = pdbId.replace(".cif", "");
}
String siftFile = pdbId + ".xml.gz";
- String siftsFileFTPURL = SIFTS_FTP_BASE_URL + siftFile;
-
- /*
- * Download the file from URL to either
- * Java: directory of cached downloaded SIFTS files
- * Javascript: temporary 'file' (in-memory cache)
- */
File downloadTo = null;
- if (Platform.isJS())
- {
- downloadTo = File.createTempFile(siftFile, ".xml.gz");
- }
- else
+ if (asFile)
{
downloadTo = new File(
SiftsSettings.getSiftDownloadDirectory() + siftFile);
- File siftsDownloadDir = new File(
- SiftsSettings.getSiftDownloadDirectory());
+ File siftsDownloadDir = new File(SiftsSettings.getSiftDownloadDirectory());
if (!siftsDownloadDir.exists())
{
siftsDownloadDir.mkdirs();
}
}
- // System.out.println(">> Download ftp url : " + siftsFileFTPURL);
- // long now = System.currentTimeMillis();
+ String siftsFileFTPURL = SIFTS_FTP_BASE_URL + siftFile;
URL url = new URL(siftsFileFTPURL);
URLConnection conn = url.openConnection();
- InputStream inputStream = conn.getInputStream();
- FileOutputStream outputStream = new FileOutputStream(downloadTo);
- 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
- // + " took " + (System.currentTimeMillis() - now) + "ms");
+ InputStream is = conn.getInputStream();
+ if (!asFile)
+ return is;
+ // This is MUCH more efficent in JavaScript, as we already have the bytes
+ Platform.streamToFile(is, downloadTo);
+ is.close();
return downloadTo;
}
SequenceI seq, java.io.PrintStream os) throws SiftsException
{
List<Integer> omitNonObserved = new ArrayList<>();
- int nonObservedShiftIndex = 0, pdbeNonObserved = 0;
+ int nonObservedShiftIndex = 0,pdbeNonObserved=0;
// System.out.println("Generating mappings for : " + entityId);
Entity entity = null;
entity = getEntityById(entityId);
TreeMap<Integer, String> resNumMap = new TreeMap<Integer, String>();
List<Segment> segments = entity.getSegment();
SegmentHelperPojo shp = new SegmentHelperPojo(seq, mapping, resNumMap,
- omitNonObserved, nonObservedShiftIndex, pdbeNonObserved);
+ omitNonObserved, nonObservedShiftIndex,pdbeNonObserved);
processSegments(segments, shp);
try
{
{
throw new SiftsException("SIFTS mapping failed");
}
- // also construct a mapping object between the seq-coord sys and the PDB
- // seq's coord sys
+ // also construct a mapping object between the seq-coord sys and the PDB seq's coord sys
Integer[] keys = mapping.keySet().toArray(new Integer[0]);
Arrays.sort(keys);
seqStart = keys[0];
seqEnd = keys[keys.length - 1];
- List<int[]> from = new ArrayList<>(), to = new ArrayList<>();
- int[] _cfrom = null, _cto = null;
+ List<int[]> from=new ArrayList<>(),to=new ArrayList<>();
+ int[]_cfrom=null,_cto=null;
String matchedSeq = originalSeq;
- if (seqStart != UNASSIGNED) // fixme! seqStart can map to -1 for a pdb
- // sequence that starts <-1
+ if (seqStart != UNASSIGNED) // fixme! seqStart can map to -1 for a pdb sequence that starts <-1
{
- for (int seqps : keys)
+ for (int seqps:keys)
{
int pdbpos = mapping.get(seqps)[PDBE_POS];
if (pdbpos == UNASSIGNED)
// not correct - pdbpos might be -1, but leave it for now
continue;
}
- if (_cfrom == null || seqps != _cfrom[1] + 1)
+ if (_cfrom==null || seqps!=_cfrom[1]+1)
{
- _cfrom = new int[] { seqps, seqps };
+ _cfrom = new int[] { seqps,seqps};
from.add(_cfrom);
_cto = null; // discontinuity
+ } else {
+ _cfrom[1]= seqps;
}
- else
- {
- _cfrom[1] = seqps;
- }
- if (_cto == null || pdbpos != 1 + _cto[1])
+ if (_cto==null || pdbpos!=1+_cto[1])
{
- _cto = new int[] { pdbpos, pdbpos };
+ _cto = new int[] { pdbpos,pdbpos};
to.add(_cto);
- }
- else
- {
+ } else {
_cto[1] = pdbpos;
}
}
;
seqFromPdbMapping = new jalview.datamodel.Mapping(null, _cto, _cfrom,
- 1, 1);
+ 1,
+ 1);
pdbStart = mapping.get(seqStart)[PDB_RES_POS];
pdbEnd = mapping.get(seqEnd)[PDB_RES_POS];
int orignalSeqStart = seq.getStart();
for (Residue residue : residues)
{
boolean isObserved = isResidueObserved(residue);
- int pdbeIndex = getLeadingIntegerValue(residue.getDbResNum(),
+ int pdbeIndex = Platform.getLeadingIntegerValue(residue.getDbResNum(),
UNASSIGNED);
int currSeqIndex = UNASSIGNED;
List<CrossRefDb> cRefDbs = residue.getCrossRefDb();
pdbRefDb = cRefDb;
if (firstPDBResNum == UNASSIGNED)
{
- firstPDBResNum = getLeadingIntegerValue(cRefDb.getDbResNum(),
+ firstPDBResNum = Platform.getLeadingIntegerValue(cRefDb.getDbResNum(),
UNASSIGNED);
}
else
if (cRefDb.getDbCoordSys().equalsIgnoreCase(seqCoordSys.getName())
&& isAccessionMatched(cRefDb.getDbAccessionId()))
{
- currSeqIndex = getLeadingIntegerValue(cRefDb.getDbResNum(),
+ currSeqIndex = Platform.getLeadingIntegerValue(cRefDb.getDbResNum(),
UNASSIGNED);
if (pdbRefDb != null)
{
}
// if (currSeqIndex >= seq.getStart() && currSeqIndex <= seqlength) //
// true
- // numbering
- // is
- // not
- // up
- // to
- // seq.getEnd()
+ // numbering
+ // is
+ // not
+ // up
+ // to
+ // seq.getEnd()
{
int resNum = (pdbRefDb == null)
- ? getLeadingIntegerValue(residue.getDbResNum(),
+ ? Platform.getLeadingIntegerValue(residue.getDbResNum(),
UNASSIGNED)
- : getLeadingIntegerValue(pdbRefDb.getDbResNum(),
+ : Platform.getLeadingIntegerValue(pdbRefDb.getDbResNum(),
UNASSIGNED);
if (isObserved)
}
/**
- * Get the leading integer part of a string that begins with an integer.
- *
- * @param input
- * - the string input to process
- * @param failValue
- * - value returned if unsuccessful
- * @return
- */
- static int getLeadingIntegerValue(String input, int failValue)
- {
- if (input == null)
- {
- return failValue;
- }
- String[] parts = input.split("(?=\\D)(?<=\\d)");
- if (parts != null && parts.length > 0 && parts[0].matches("[0-9]+"))
- {
- return Integer.valueOf(parts[0]);
- }
- return failValue;
- }
-
- /**
*
* @param chainId
* Target chain to populate mapping of its atom positions.
{
return pdbeNonObserved;
}
-
public SequenceI getSeq()
{
return seq;
import java.util.Objects;
-public class SiftsSettings
+import jalview.bin.ApplicationSingletonProvider;
+import jalview.bin.ApplicationSingletonProvider.ApplicationSingletonI;
+
+public class SiftsSettings implements ApplicationSingletonI
{
- private static boolean mapWithSifts = false;
+ /**
+ * Constructor
+ *
+ * @return
+ */
+ private static SiftsSettings getInstance()
+ {
+ return (SiftsSettings) ApplicationSingletonProvider
+ .getInstance(SiftsSettings.class);
+ }
+
+ private SiftsSettings()
+ {
+ // singleton; use getInstance()
+ }
+
+ private boolean mapWithSifts = false;
- private static String siftDownloadDirectory;
+ private String siftDownloadDirectory;
- private static int cacheThresholdInDays;
+ private int cacheThresholdInDays;
- private static int failSafePIDThreshold;
+ private int failSafePIDThreshold;
public static boolean isMapWithSifts()
{
- return mapWithSifts;
+ return getInstance().mapWithSifts;
}
public static void setMapWithSifts(boolean mapWithSifts)
{
- SiftsSettings.mapWithSifts = mapWithSifts;
+ getInstance().mapWithSifts = mapWithSifts;
}
public static String getSiftDownloadDirectory()
{
- return siftDownloadDirectory;
+ return getInstance().siftDownloadDirectory;
}
public static void setSiftDownloadDirectory(String siftDownloadDirectory)
{
- SiftsSettings.siftDownloadDirectory = siftDownloadDirectory;
+ getInstance().siftDownloadDirectory = siftDownloadDirectory;
}
public static int getCacheThresholdInDays()
{
- return cacheThresholdInDays;
+ return getInstance().cacheThresholdInDays;
}
public static void setCacheThresholdInDays(String cacheThresholdInDays)
{
Objects.requireNonNull(cacheThresholdInDays);
- SiftsSettings.cacheThresholdInDays = Integer
+ getInstance().cacheThresholdInDays = Integer
.valueOf(cacheThresholdInDays);
}
public static int getFailSafePIDThreshold()
{
- return failSafePIDThreshold;
+ return getInstance().failSafePIDThreshold;
}
public static void setFailSafePIDThreshold(String failSafePIDThreshold)
{
Objects.requireNonNull(failSafePIDThreshold);
- SiftsSettings.failSafePIDThreshold = Integer
+ getInstance().failSafePIDThreshold = Integer
.valueOf(failSafePIDThreshold);
}
}
--- /dev/null
+package jalview.ws.slivkaws;
+
+import jalview.api.FeatureColourI;
+import jalview.bin.Cache;
+import jalview.datamodel.Alignment;
+import jalview.datamodel.AlignmentAnnotation;
+import jalview.datamodel.SequenceI;
+import jalview.datamodel.features.FeatureMatcherSetI;
+import jalview.io.AnnotationFile;
+import jalview.io.DataSourceType;
+import jalview.io.FeaturesFile;
+import jalview.util.MessageManager;
+import jalview.ws.api.JobId;
+import jalview.ws.api.SequenceAnnotationServiceI;
+import jalview.ws.params.ArgumentI;
+import jalview.ws.params.WsParamSetI;
+import jalview.ws.uimodel.AlignAnalysisUIText;
+
+import java.io.IOError;
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+
+import compbio.data.msa.Category;
+import uk.ac.dundee.compbio.slivkaclient.RemoteFile;
+import uk.ac.dundee.compbio.slivkaclient.SlivkaClient;
+import uk.ac.dundee.compbio.slivkaclient.SlivkaService;
+
+public class SlivkaAnnotationServiceInstance extends SlivkaWSInstance implements SequenceAnnotationServiceI
+{
+ public SlivkaAnnotationServiceInstance(SlivkaClient client,
+ SlivkaService service, String category)
+ {
+ super(client, service, category);
+ if (category == Category.CATEGORY_CONSERVATION)
+ {
+ /* FIXME: the category name is hardcoded for AACon, names other than
+ * "AAConWS" doesn't work. */
+ setAlignAnalysisUI(new AlignAnalysisUIText(getName(),
+ SlivkaAnnotationServiceInstance.class,
+ "Slivka.AACons", false, true, true, true, true, 2,
+ MessageManager.getString("label.aacon_calculations"),
+ MessageManager.getString("tooltip.aacon_calculations"),
+ MessageManager.getString("label.aacon_settings"),
+ MessageManager.getString("tooltip.aacon_settings")));
+ }
+ style = ServiceClient.SEQUENCEANNOTATIONWSCLIENT;
+ }
+
+ @Override
+ public JobId submitToService(List<SequenceI> seqs, WsParamSetI preset, List<ArgumentI> paramset) throws Throwable
+ {
+ return super.submit(seqs, preset, paramset);
+ }
+
+ @Override
+ public List<AlignmentAnnotation> getAnnotationResult(JobId job,
+ List<SequenceI> seqs, Map<String, FeatureColourI> featureColours,
+ Map<String, FeatureMatcherSetI> featureFilters) throws Throwable
+ {
+ RemoteFile annotFile = null;
+ RemoteFile featFile = null;
+ try
+ {
+ List<RemoteFile> files = client.getJobResults(job.getJobId());
+ for (RemoteFile f : files)
+ {
+ if (f.getMimeType().equals("application/jalview-annotations"))
+ {
+ annotFile = f;
+ }
+ else if (f.getMimeType().equals("application/jalview-features"))
+ {
+ featFile = f;
+ }
+ }
+ } catch (IOException e)
+ {
+ throw new IOError(e);
+ }
+ Alignment aln = new Alignment(seqs.toArray(new SequenceI[0]));
+ if (annotFile == null
+ || !new AnnotationFile().readAnnotationFile(aln, annotFile.getURL().toString(), DataSourceType.URL))
+ {
+ Cache.log.debug("No annotation from slivka job\n" + annotFile);
+ }
+ if (featFile == null
+ || !new FeaturesFile(featFile.getURL().toString(), DataSourceType.URL).parse(aln, featureColours, true))
+ {
+ Cache.log.debug("No features from slivka job\n" + featFile);
+ }
+ return Arrays.asList(aln.getAlignmentAnnotation());
+ }
+}
--- /dev/null
+package jalview.ws.slivkaws;
+
+import jalview.ws.params.ArgumentI;
+import jalview.ws.params.ParamDatastoreI;
+import jalview.ws.params.WsParamSetI;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import uk.ac.dundee.compbio.slivkaclient.SlivkaService;
+
+public class SlivkaDatastore implements ParamDatastoreI
+{
+ private SlivkaParamSet defaultPreset;
+ private List<WsParamSetI> presets = new ArrayList<>();
+
+ SlivkaDatastore(SlivkaService service) throws IOException {
+ defaultPreset = new SlivkaParamSet(service);
+ }
+
+ @Override
+ public List<WsParamSetI> getPresets()
+ {
+ return presets;
+ }
+
+ @Override
+ public WsParamSetI getPreset(String name)
+ {
+ for (WsParamSetI preset : presets)
+ {
+ if (preset.getName().equals(name))
+ {
+ return preset;
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public List<ArgumentI> getServiceParameters()
+ {
+ return new ArrayList<>(defaultPreset.getArguments());
+ }
+
+ @Override
+ public boolean presetExists(String name)
+ {
+ for (WsParamSetI preset : presets)
+ {
+ if (preset.getName().equals(name))
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public void deletePreset(String name)
+ {
+ }
+
+ @Override
+ public void storePreset(String presetName, String text, List<ArgumentI> jobParams)
+ {
+ }
+
+ @Override
+ public void updatePreset(String oldName, String presetName, String text, List<ArgumentI> jobParams)
+ {
+ }
+
+ @Override
+ public WsParamSetI parseServiceParameterFile(String name, String description, String[] serviceURL, String parameters)
+ throws IOException
+ {
+ return null;
+ }
+
+ @Override
+ public String generateServiceParameterFile(WsParamSetI pset) throws IOException
+ {
+ return null;
+ }
+
+}
--- /dev/null
+package jalview.ws.slivkaws;
+
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.SequenceI;
+import jalview.io.DataSourceType;
+import jalview.io.FileFormat;
+import jalview.io.FormatAdapter;
+import jalview.ws.api.JobId;
+import jalview.ws.api.MultipleSequenceAlignmentI;
+import jalview.ws.params.ArgumentI;
+import jalview.ws.params.InvalidArgumentException;
+import jalview.ws.params.WsParamSetI;
+
+import java.io.IOError;
+import java.io.IOException;
+import java.rmi.ServerError;
+import java.util.List;
+
+import compbio.data.msa.Category;
+import uk.ac.dundee.compbio.slivkaclient.RemoteFile;
+import uk.ac.dundee.compbio.slivkaclient.SlivkaClient;
+import uk.ac.dundee.compbio.slivkaclient.SlivkaService;
+
+public class SlivkaMsaServiceInstance extends SlivkaWSInstance implements MultipleSequenceAlignmentI
+{
+ SlivkaMsaServiceInstance(SlivkaClient client, SlivkaService service, String category) {
+ super(client, service, category);
+ style = ServiceClient.MSAWSCLIENT;
+ }
+
+ @Override
+ public JobId align(List<SequenceI> toalign, WsParamSetI parameters, List<ArgumentI> list) throws Throwable
+ {
+ return super.submit(toalign, parameters, list);
+ }
+
+ @Override
+ public AlignmentI getAlignmentFor(JobId jobId) throws InvalidArgumentException, ServerError, IOError
+ {
+ List<RemoteFile> files;
+ try
+ {
+ files = client.getJobResults(jobId.getJobId());
+ for (RemoteFile f : files)
+ {
+ if (f.getMimeType().equals("application/clustal"))
+ {
+ return new FormatAdapter().readFile(f.getURL().toString(), DataSourceType.URL, FileFormat.Clustal);
+ }
+ else if (f.getMimeType().equals("application/fasta"))
+ {
+ return new FormatAdapter().readFile(f.getURL().toString(), DataSourceType.URL, FileFormat.Fasta);
+ }
+ }
+ } catch (IOException e)
+ {
+ throw new IOError(e);
+ }
+ return null;
+ }
+}
--- /dev/null
+package jalview.ws.slivkaws;
+
+import jalview.ws.params.ArgumentI;
+import jalview.ws.params.WsParamSetI;
+import jalview.ws.params.simple.BooleanOption;
+import jalview.ws.params.simple.DoubleParameter;
+import jalview.ws.params.simple.IntegerParameter;
+import jalview.ws.params.simple.StringParameter;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import uk.ac.dundee.compbio.slivkaclient.BooleanField;
+import uk.ac.dundee.compbio.slivkaclient.ChoiceField;
+import uk.ac.dundee.compbio.slivkaclient.DecimalField;
+import uk.ac.dundee.compbio.slivkaclient.FormField;
+import uk.ac.dundee.compbio.slivkaclient.IntegerField;
+import uk.ac.dundee.compbio.slivkaclient.SlivkaForm;
+import uk.ac.dundee.compbio.slivkaclient.SlivkaService;
+import uk.ac.dundee.compbio.slivkaclient.TextField;
+
+
+
+public class SlivkaParamSet implements WsParamSetI
+{
+ private SlivkaService service;
+ private List<ArgumentI> args = new ArrayList<>();
+
+ SlivkaParamSet(SlivkaService service) throws IOException {
+ this.service = service;
+ SlivkaForm form = service.getForm();
+ for (FormField field : form.getFields())
+ {
+ switch (field.getType()) {
+ case BOOLEAN:
+ BooleanField boolField = (BooleanField) field;
+ args.add(new BooleanOption(
+ field.getName(), field.getDescription(), field.getLabel(),
+ field.isRequired(), boolField.getDefault(), null
+ ));
+ break;
+ case TEXT:
+ TextField textField = (TextField) field;
+ args.add(new StringParameter(
+ field.getName(), field.getDescription(), field.isRequired(),
+ textField.getDefault(), textField.getDefault()
+ ));
+ break;
+ case INTEGER:
+ IntegerField intField = (IntegerField) field;
+ args.add(new IntegerParameter(
+ field.getName(), field.getDescription(), field.isRequired(),
+ intField.getDefault(), intField.getMin(), intField.getMax()
+ ));
+ break;
+ case DECIMAL:
+ DecimalField doubleField = (DecimalField) field;
+ args.add(new DoubleParameter(
+ field.getName(), field.getDescription(), field.isRequired(),
+ doubleField.getDefault(), doubleField.getMin(),
+ doubleField.getMax()
+ ));
+ break;
+ case CHOICE:
+ ChoiceField choiceField = (ChoiceField) field;
+ List<String> choices = new ArrayList<>(choiceField.getChoices());
+ if (field.hasMultipleValues()) {
+ int counter = 0;
+ for (String choice : choices) {
+ args.add(new BooleanOption(
+ String.format("%s$%d", field.getName(), counter++),
+ field.getDescription(), choice, field.isRequired(),
+ choice.equals(choiceField.getDefault()), choice,
+ null
+ ));
+ }
+ }
+ else
+ {
+ args.add(new StringParameter(
+ field.getName(), field.getDescription(),
+ field.isRequired(), choiceField.getDefault(), choiceField.getDefault(),
+ choices, choices
+ ));
+ }
+ break;
+ case FILE:
+ default:
+ continue;
+ }
+ }
+ }
+
+ @Override
+ public String getName()
+ {
+ return "Default";
+ }
+
+ @Override
+ public String getDescription()
+ {
+ return "";
+ }
+
+ @Override
+ public String[] getApplicableUrls()
+ {
+ return new String[] { service.getURL().toString() };
+ }
+
+ @Override
+ public String getSourceFile()
+ {
+ return null;
+ }
+
+ @Override
+ public void setSourceFile(String newfile)
+ {
+ }
+
+ @Override
+ public boolean isModifiable()
+ {
+ return true;
+ }
+
+ @Override
+ public List<ArgumentI> getArguments()
+ {
+ return args;
+ }
+
+ @Override
+ public void setArguments(List<ArgumentI> args)
+ {
+ throw new RuntimeException();
+ }
+
+}
--- /dev/null
+package jalview.ws.slivkaws;
+
+import jalview.bin.Cache;
+import jalview.ws.ServiceChangeListener;
+import jalview.ws.WSDiscovererI;
+import jalview.ws.api.ServiceWithParameters;
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+import java.util.Vector;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.CopyOnWriteArraySet;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+
+import compbio.data.msa.Category;
+import uk.ac.dundee.compbio.slivkaclient.SlivkaClient;
+import uk.ac.dundee.compbio.slivkaclient.SlivkaService;
+
+public class SlivkaWSDiscoverer implements WSDiscovererI
+{
+ private static final String SLIVKA_HOST_URLS = "SLIVKAHOSTURLS";
+
+ private static final String COMPBIO_SLIVKA = "https://www.compbio.dundee.ac.uk/slivka/";
+
+ private static SlivkaWSDiscoverer instance = null;
+
+ private List<ServiceWithParameters> services = List.of();
+
+ private SlivkaWSDiscoverer()
+ {
+ }
+
+ public static SlivkaWSDiscoverer getInstance()
+ {
+ if (instance == null)
+ {
+ instance = new SlivkaWSDiscoverer();
+ }
+ return instance;
+ }
+
+ private Set<ServiceChangeListener> serviceListeners = new CopyOnWriteArraySet<>();
+
+ @Override
+ public void addServiceChangeListener(ServiceChangeListener l)
+ {
+ serviceListeners.add(l);
+ }
+
+ @Override
+ public void removeServiceChangeListener(ServiceChangeListener l)
+ {
+ serviceListeners.remove(l);
+ }
+
+ public void notifyServiceListeners(List<ServiceWithParameters> services)
+ {
+ for (var listener : serviceListeners)
+ {
+ listener.servicesChanged(this, services);
+ }
+ }
+
+ private final ExecutorService executor = Executors
+ .newSingleThreadExecutor();
+
+ private Vector<Future<?>> discoveryTasks = new Vector<>();
+
+ public CompletableFuture<WSDiscovererI> startDiscoverer()
+ {
+ CompletableFuture<WSDiscovererI> task = CompletableFuture
+ .supplyAsync(() -> {
+ reloadServices();
+ return SlivkaWSDiscoverer.this;
+ }, executor);
+ discoveryTasks.add(task);
+ return task;
+ }
+
+ private List<ServiceWithParameters> reloadServices()
+ {
+ Cache.log.info("Reloading Slivka services");
+ notifyServiceListeners(Collections.emptyList());
+ ArrayList<ServiceWithParameters> instances = new ArrayList<>();
+
+ for (String url : getServiceUrls())
+ {
+ SlivkaClient client = new SlivkaClient(url);
+
+ List<SlivkaService> services;
+ try
+ {
+ services = client.getServices();
+ } catch (IOException e)
+ {
+ e.printStackTrace();
+ continue;
+ }
+ for (SlivkaService service : services)
+ {
+ SlivkaWSInstance newInstance = null;
+ for (String classifier : service.classifiers)
+ {
+ String[] path = classifier.split("\\s*::\\s*");
+ if (path.length >= 3 && path[0].toLowerCase().equals("operation")
+ && path[1].toLowerCase().equals("analysis"))
+ {
+ switch (path[path.length - 1].toLowerCase())
+ {
+ case "sequence alignment analysis (conservation)":
+ newInstance = new SlivkaAnnotationServiceInstance(client,
+ service, Category.CATEGORY_CONSERVATION);
+ break;
+ case "protein sequence analysis":
+ newInstance = new SlivkaAnnotationServiceInstance(client,
+ service, Category.CATEGORY_DISORDER);
+ break;
+ case "protein secondary structure prediction":
+ newInstance = new SlivkaAnnotationServiceInstance(client,
+ service, "Secondary Structure Prediction");
+ break;
+ case "multiple sequence alignment":
+ newInstance = new SlivkaMsaServiceInstance(client, service,
+ Category.CATEGORY_ALIGNMENT);
+ break;
+ }
+ }
+ if (newInstance != null)
+ break;
+ }
+ if (newInstance != null)
+ instances.add(newInstance);
+ }
+ }
+
+ services = instances;
+ Cache.log.info("Slivka services reloading finished");
+ notifyServiceListeners(instances);
+ return instances;
+ }
+
+ @Override
+ public List<ServiceWithParameters> getServices()
+ {
+ return services;
+ }
+
+ @Override
+ public boolean hasServices()
+ {
+ return !isRunning() && services.size() > 0;
+ }
+
+ @Override
+ public boolean isRunning()
+ {
+ return !discoveryTasks.stream().allMatch(Future::isDone);
+ }
+
+ @Override
+ public void setServiceUrls(List<String> wsUrls)
+ {
+ if (wsUrls != null && !wsUrls.isEmpty())
+ {
+ Cache.setProperty(SLIVKA_HOST_URLS, String.join(",", wsUrls));
+ }
+ else
+ {
+ Cache.removeProperty(SLIVKA_HOST_URLS);
+ }
+ }
+
+ @Override
+ public List<String> getServiceUrls()
+ {
+ String surls = Cache.getDefault(SLIVKA_HOST_URLS, COMPBIO_SLIVKA);
+ String[] urls = surls.split(",");
+ ArrayList<String> valid = new ArrayList<>(urls.length);
+ for (String url : urls)
+ {
+ try
+ {
+ new URL(url);
+ valid.add(url);
+ } catch (MalformedURLException e)
+ {
+ Cache.log.warn("Problem whilst trying to make a URL from '"
+ + ((url != null) ? url : "<null>") + "'");
+ Cache.log.warn(
+ "This was probably due to a malformed comma separated list"
+ + " in the " + SLIVKA_HOST_URLS
+ + " entry of $(HOME)/.jalview_properties)");
+ Cache.log.debug("Exception was ", e);
+ }
+ }
+ return valid;
+ }
+
+ @Override
+ public boolean testServiceUrl(URL url)
+ {
+ return getServerStatusFor(url.toString()) == STATUS_OK;
+ }
+
+ @Override
+ public int getServerStatusFor(String url)
+ {
+ try
+ {
+ List<?> services = new SlivkaClient(url).getServices();
+ return services.isEmpty() ? STATUS_NO_SERVICES : STATUS_OK;
+ } catch (IOException e)
+ {
+ Cache.log.error("Slivka could not retrieve services list", e);
+ return STATUS_INVALID;
+ }
+ }
+
+ @Override
+ public String getErrorMessages()
+ {
+ // TODO Auto-generated method stub
+ return "";
+ }
+}
--- /dev/null
+package jalview.ws.slivkaws;
+
+import jalview.datamodel.SequenceI;
+import jalview.gui.WebserviceInfo;
+import jalview.io.FileFormat;
+import jalview.io.FormatAdapter;
+import jalview.ws.api.JalviewServiceEndpointProviderI;
+import jalview.ws.api.JalviewWebServiceI;
+import jalview.ws.api.JobId;
+import jalview.ws.api.ServiceWithParameters;
+import jalview.ws.gui.WsJob;
+import jalview.ws.params.ArgumentI;
+import jalview.ws.params.ParamDatastoreI;
+import jalview.ws.params.ParamManager;
+import jalview.ws.params.WsParamSetI;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOError;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Arrays;
+import java.util.EnumMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Optional;
+import java.util.Set;
+
+import uk.ac.dundee.compbio.slivkaclient.FieldType;
+import uk.ac.dundee.compbio.slivkaclient.FileField;
+import uk.ac.dundee.compbio.slivkaclient.FormField;
+import uk.ac.dundee.compbio.slivkaclient.FormValidationException;
+import uk.ac.dundee.compbio.slivkaclient.JobState;
+import uk.ac.dundee.compbio.slivkaclient.RemoteFile;
+import uk.ac.dundee.compbio.slivkaclient.SlivkaClient;
+import uk.ac.dundee.compbio.slivkaclient.SlivkaForm;
+import uk.ac.dundee.compbio.slivkaclient.SlivkaService;
+import uk.ac.dundee.compbio.slivkaclient.ValidationException;
+
+public abstract class SlivkaWSInstance extends ServiceWithParameters
+ implements JalviewServiceEndpointProviderI, JalviewWebServiceI
+{
+ protected final SlivkaClient client;
+
+ protected final SlivkaService service;
+
+ protected SlivkaDatastore store = null;
+
+ protected static final EnumMap<JobState, WsJob.JobState> stateMap = new EnumMap<>(JobState.class);
+ {
+ stateMap.put(JobState.PENDING, WsJob.JobState.QUEUED);
+ stateMap.put(JobState.REJECTED, WsJob.JobState.INVALID);
+ stateMap.put(JobState.ACCEPTED, WsJob.JobState.QUEUED);
+ stateMap.put(JobState.QUEUED, WsJob.JobState.QUEUED);
+ stateMap.put(JobState.RUNNING, WsJob.JobState.RUNNING);
+ stateMap.put(JobState.COMPLETED, WsJob.JobState.FINISHED);
+ stateMap.put(JobState.INTERRUPTED, WsJob.JobState.CANCELLED);
+ stateMap.put(JobState.DELETED, WsJob.JobState.CANCELLED);
+ stateMap.put(JobState.FAILED, WsJob.JobState.FAILED);
+ stateMap.put(JobState.ERROR, WsJob.JobState.SERVERERROR);
+ stateMap.put(JobState.UNKNOWN, WsJob.JobState.UNKNOWN);
+ }
+ protected final Set<WsJob.JobState> failedStates = new HashSet<>(Arrays.asList(
+ WsJob.JobState.INVALID, WsJob.JobState.BROKEN, WsJob.JobState.FAILED,
+ WsJob.JobState.SERVERERROR, WsJob.JobState.CANCELLED
+ ));
+
+ public SlivkaWSInstance(SlivkaClient client, SlivkaService service, String action)
+ {
+ super(action, action, service.getLabel(), "Slivka", client.getUrl().toString());
+ this.client = client;
+ this.service = service;
+ }
+
+ protected final JobId submit(List<SequenceI> sequences,
+ WsParamSetI preset, List<ArgumentI> args) throws Throwable
+ {
+ SlivkaForm form = service.getForm();
+ for (FormField field : form.getFields())
+ {
+ if (field.getType() == FieldType.FILE)
+ {
+ FormatAdapter fa = new FormatAdapter();
+ fa.setNewlineString("\r\n");
+ FileField fileField = (FileField) field;
+ FileFormat format;
+ switch (fileField.getMediaType())
+ {
+ case "application/pfam":
+ format = FileFormat.Pfam;
+ break;
+ case "application/stockholm":
+ format = FileFormat.Stockholm;
+ break;
+ default:
+ case "application/fasta":
+ format = FileFormat.Fasta;
+ break;
+ }
+ InputStream stream = new ByteArrayInputStream(
+ fa.formatSequences(format, sequences.toArray(new SequenceI[0]))
+ .getBytes());
+ RemoteFile rf = client.uploadFile(stream, "input",
+ fileField.getMediaType());
+ form.insert(field.getName(), rf);
+ }
+ }
+ if (args != null)
+ {
+ for (ArgumentI arg : args)
+ {
+ // multiple choice field names are name$number to avoid duplications
+ // the number is stripped here
+ String fieldName = arg.getName().split("\\$", 2)[0];
+ FormField field = form.getField(fieldName);
+ if (field.getType() == FieldType.BOOLEAN)
+ {
+ form.insert(fieldName,
+ (arg.getValue() != null && !arg.getValue().isBlank())
+ ? true
+ : false);
+ }
+ else
+ {
+ form.insert(fieldName, arg.getValue());
+ }
+ }
+ }
+ return new JobId(service.getName(), service.getName(), form.submit());
+ }
+
+ @Override
+ public final void updateStatus(WsJob job)
+ {
+ try
+ {
+ job.setState(stateMap.get(client.getJobState(job.getJobId())));
+ } catch (IOException e)
+ {
+ throw new IOError(e);
+ }
+ }
+
+ @Override
+ public final boolean updateJobProgress(WsJob job) throws IOException
+ {
+ List<RemoteFile> files = client.getJobResults(job.getJobId());
+ RemoteFile logFile=null;
+ for (RemoteFile f : files)
+ {
+ if (f.getLabel().equals("log"))
+ {
+ logFile = f; break;
+ }
+ }
+
+ boolean newContent = false;
+ if (logFile!=null)
+ {
+ ByteArrayOutputStream output = new ByteArrayOutputStream();
+ logFile.writeTo(output);
+ if (output.size() > job.getNextChunk())
+ {
+ newContent = true;
+ job.setStatus(output.toString("UTF-8"));
+ job.setnextChunk(output.size());
+ }
+ }
+ if (failedStates.contains(job.getJobState()))
+ {
+
+ RemoteFile errLogFile = null;
+ for (RemoteFile f : files)
+ {
+ if (f.getLabel().equals("error-log"))
+ {
+ errLogFile = f;
+ break;
+ }
+ }
+
+ if (errLogFile!=null)
+ {
+ ByteArrayOutputStream output = new ByteArrayOutputStream();
+ errLogFile.writeTo(output);
+ if (output.size() > 0)
+ {
+ newContent = true;
+ job.setStatus(job.getStatus() + "\n" + output.toString("UTF-8"));
+ }
+ }
+ }
+ return newContent;
+ }
+
+ @Override
+ public final boolean handleSubmitError(Throwable _lex, WsJob j, WebserviceInfo wsInfo)
+ {
+ if (_lex instanceof FormValidationException)
+ {
+ FormValidationException formError = (FormValidationException) _lex;
+ String[] messages = new String[formError.getErrors().size()];
+ int i = 0;
+ for (ValidationException e : formError.getErrors())
+ {
+ messages[i++] = String.format("%s: %s,", e.getField().getName(), e.getMessage());
+ }
+ j.setState(WsJob.JobState.INVALID);
+ j.setStatus(String.join(", ", messages));
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public final boolean handleCollectionException(Exception e, WsJob msjob, WebserviceInfo wsInfo)
+ {
+ // TODO
+ return false;
+ }
+
+ final SlivkaService getService()
+ {
+ return service;
+ }
+
+ @Override
+ public final Object getEndpoint()
+ {
+ return this;
+ }
+
+ @Override
+ public final void initParamStore(ParamManager userParameterStore)
+ {
+ if (store == null)
+ {
+ try
+ {
+ store = new SlivkaDatastore(service);
+ } catch (IOException e)
+ {
+ throw new IOError(e);
+ }
+ }
+ }
+
+ @Override
+ public boolean hasParameters()
+ {
+ return true;
+ }
+
+ @Override
+ public final ParamDatastoreI getParamStore()
+ {
+ if (store == null)
+ {
+ initParamStore(null);
+ }
+ return store;
+ }
+
+}
*/
package jalview.ws.uimodel;
+/**
+ * configures annotation worker style web service clients
+ *
+ * @author jprocter
+ *
+ */
public class AlignAnalysisUIText
{
return isPr;
}
+ /**
+ * @return true if service can accept sequences with gaps
+ */
public boolean isAA()
{
return isAA;
private boolean isAA;
+ private boolean filterSymbols;
+
+
+ private boolean needsAlignedSeqs;
+
+ private int min_valid_seqs;
+
+
public AlignAnalysisUIText(String serviceType, Class<?> client,
String calcId, boolean acceptNucl, boolean acceptProt,
- boolean acceptGaps, String toggle, String toggleTooltip,
+ boolean acceptGaps, boolean alignedSeq,
+ boolean filterNonStandardSymbols, int minSeq, String toggle,
+ String toggleTooltip,
String settings, String settingsTooltip)
{
this.serviceType = serviceType;
isNa = acceptNucl;
isPr = acceptProt;
isAA = acceptGaps;
+ this.needsAlignedSeqs = alignedSeq;
+ this.filterSymbols = filterNonStandardSymbols;
this.client = client;
this.AAconToggle = toggle;
this.AAconToggleTooltip = toggleTooltip;
this.AAeditSettings = settings;
this.AAeditSettingsTooltip = settingsTooltip;
+ this.min_valid_seqs = minSeq;
+ }
+
+ /**
+ *
+ * @return true if non-standard nucleotides and amino acids should be replaced
+ * or omitted
+ *
+ */
+ public boolean isFilterSymbols()
+ {
+ return filterSymbols;
+ }
+
+ /**
+ *
+ * @return true if service needs sequences all the same length (ie padded with
+ * gaps if necessary)
+ */
+ public boolean isNeedsAlignedSeqs()
+ {
+ return needsAlignedSeqs;
}
public Class getClient()
AAeditSettingsTooltip = aAeditSettingsTooltip;
}
+ public int getMinimumSequences()
+ {
+ return min_valid_seqs;
+ }
+
}
package jalview.ws.utils;
-import jalview.util.Platform;
-
import java.io.File;
-import java.io.FileOutputStream;
import java.io.IOException;
-import java.net.URL;
-import java.nio.channels.Channels;
-import java.nio.channels.ReadableByteChannel;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.nio.file.StandardCopyOption;
+
+import jalview.util.Platform;
public class UrlDownloadClient
{
public static void download(String urlstring, String outfile)
throws IOException
{
-
- FileOutputStream fos = null;
- ReadableByteChannel rbc = null;
- Path temp = null;
- try
- {
- temp = Files.createTempFile(".jalview_", ".tmp");
-
- URL url = new URL(urlstring);
- rbc = Channels.newChannel(url.openStream());
- fos = new FileOutputStream(temp.toString());
- fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);
-
- // copy tempfile to outfile once our download completes
- // incase something goes wrong
- Files.copy(temp, Paths.get(outfile),
- StandardCopyOption.REPLACE_EXISTING);
- } catch (IOException e)
- {
- throw e;
- } finally
- {
- try
- {
- if (fos != null)
- {
- fos.close();
- }
- } catch (IOException e)
- {
- System.out.println(
- "Exception while closing download file output stream: "
- + e.getMessage());
- }
- try
- {
- if (rbc != null)
- {
- rbc.close();
- }
- } catch (IOException e)
- {
- System.out.println("Exception while closing download channel: "
- + e.getMessage());
- }
- try
- {
- if (temp != null)
- {
- Files.deleteIfExists(temp);
- }
- } catch (IOException e)
- {
- System.out.println("Exception while deleting download temp file: "
- + e.getMessage());
- }
- }
-
+ Platform.download(urlstring, outfile);
}
public static void download(String urlstring, File tempFile) throws IOException
//
-// This file was generated by the Eclipse Implementation of JAXB, v2.3.3
-// See https://eclipse-ee4j.github.io/jaxb-ri
+// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802
+// See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a>
// Any modifications to this file will be lost upon recompilation of the source schema.
// Generated on: 2021.08.30 at 11:05:22 AM BST
//
/**
- * <p>Java class for DoubleVector complex type.
+ * <p>Java class for DoubleVector complex type.
*
- * <p>The following schema fragment specifies the expected content contained within this class.
+ * <p>The following schema fragment specifies the expected content contained within this class.
*
- * <pre>
- * &lt;complexType name="DoubleVector"&gt;
- * &lt;complexContent&gt;
- * &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType"&gt;
- * &lt;sequence&gt;
- * &lt;element name="v" type="{http://www.w3.org/2001/XMLSchema}double" maxOccurs="unbounded" minOccurs="0"/&gt;
- * &lt;/sequence&gt;
- * &lt;/restriction&gt;
- * &lt;/complexContent&gt;
- * &lt;/complexType&gt;
- * </pre>
+ * <pre>
+ * <complexType name="DoubleVector">
+ * <complexContent>
+ * <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ * <sequence>
+ * <element name="v" type="{http://www.w3.org/2001/XMLSchema}double" maxOccurs="unbounded" minOccurs="0"/>
+ * </sequence>
+ * </restriction>
+ * </complexContent>
+ * </complexType>
+ * </pre>
*
*
*/
/**
* Gets the value of the v property.
*
- * <p>
+ * <p>
* This accessor method returns a reference to the live list,
* not a snapshot. Therefore any modification you make to the
* returned list will be present inside the JAXB object.
- * This is why there is not a <CODE>set</CODE> method for the v property.
+ * This is why there is not a <CODE>set</CODE> method for the v property.
*
- * <p>
+ * <p>
* For example, to add a new item, do as follows:
- * <pre>
+ * <pre>
* getV().add(newItem);
- * </pre>
+ * </pre>
*
*
- * <p>
+ * <p>
* Objects of the following type(s) are allowed in the list
* {@link Double }
*
"features",
"pdbids",
"hiddenSequences",
- "rnaViewer"
+ "rnaViewer",
+ "hmmerProfile"
})
public static class JSeq {
protected List<Integer> hiddenSequences;
@XmlElement(namespace = "www.jalview.org")
protected List<JalviewModel.JSeq.RnaViewer> rnaViewer;
+ @XmlElement(namespace = "www.jalview.org")
+ protected String hmmerProfile;
@XmlAttribute(name = "colour")
protected Integer colour;
@XmlAttribute(name = "start", required = true)
}
/**
+ * Gets the value of the hmmerProfile property.
+ *
+ * @return
+ * possible object is
+ * {@link String }
+ *
+ */
+ public String getHmmerProfile() {
+ return hmmerProfile;
+ }
+
+ /**
+ * Sets the value of the hmmerProfile property.
+ *
+ * @param value
+ * allowed object is
+ * {@link String }
+ *
+ */
+ public void setHmmerProfile(String value) {
+ this.hmmerProfile = value;
+ }
+
+ /**
* Gets the value of the colour property.
*
* @return
--- /dev/null
+package javajs.async;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.MalformedURLException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipInputStream;
+
+import swingjs.api.JSUtilI;
+
+/**
+ * The Assets class allows assets such as images and property files to be
+ * combined into zip files rather than delivered individually. The Assets
+ * instance is a singleton served by a set of static methods. In particular, the
+ * three add(...) methods are used to create asset references, which include an
+ * arbitrary name, a path to a zip file asset, and one or more class paths that
+ * are covered by this zip file asset.
+ *
+ * For example:
+ *
+ * <code>
+ static {
+ try {
+ Assets.add(new Assets.Asset("osp", "osp-assets.zip", "org/opensourcephysics/resources"));
+ Assets.add(new Assets.Asset("tracker", "tracker-assets.zip",
+ "org/opensourcephysics/cabrillo/tracker/resources"));
+ Assets.add(new Assets.Asset("physlets", "physlet-assets.zip", new String[] { "opticsimages", "images" }));
+ // add the Info.assets last so that it can override these defaults
+ if (OSPRuntime.isJS) {
+ Assets.add(OSPRuntime.jsutil.getAppletInfo("assets"));
+ }
+ } catch (Exception e) {
+ OSPLog.warning("Error reading assets path. ");
+ }
+
+ }
+ * </code>
+ *
+ * It is not clear that Java is well-served by this zip-file loading, but
+ * certainly JavaScript is. What could be 100 downloads is just one, and SwingJS
+ * (but not Java) can cache individual ZipEntry instances in order to unzip them
+ * independently only when needed. This is potentially a huge savings.
+ *
+ * Several static methods can be used to retrieve assets. Principal among those
+ * are:
+ *
+ * <code>
+ * getAssetBytes(String fullPath)
+ * getAssetString(String fullPath)
+ * getAssetStream(String fullPath)
+ * </code>
+ *
+ * If an asset is not found in a zip file, then it will be loaded from its fullPath.
+ *
+ *
+ *
+ * @author hansonr
+ *
+ */
+
+public class Assets {
+
+ public static boolean isJS = /** @j2sNative true || */
+ false;
+
+ public static JSUtilI jsutil;
+
+ static {
+ try {
+ if (isJS) {
+ jsutil = ((JSUtilI) Class.forName("swingjs.JSUtil").newInstance());
+ }
+
+ } catch (Exception e) {
+ System.err.println("Assets could not create swinjs.JSUtil instance");
+ }
+ }
+
+ private Map<String, Map<String, ZipEntry>> htZipContents = new HashMap<>();
+
+ private static boolean doCacheZipContents = true;
+
+ private static Assets instance = new Assets();
+
+ private Assets() {
+ }
+
+ private Map<String, Asset> assetsByPath = new HashMap<>();
+
+ private String[] sortedList = new String[0];
+
+ /**
+ * If this object has been cached by SwingJS, add its bytes to the URL, URI, or
+ * File
+ *
+ * @param URLorURIorFile
+ * @return
+ */
+ public static byte[] addJSCachedBytes(Object URLorURIorFile) {
+ return (isJS ? jsutil.addJSCachedBytes(URLorURIorFile) : null);
+ }
+
+ public static class Asset {
+ String name;
+ URI uri;
+ String classPath;
+ String zipPath;
+ String[] classPaths;
+
+ public Asset(String name, String zipPath, String[] classPaths) {
+ this.name = name;
+ this.zipPath = zipPath;
+ this.classPaths = classPaths;
+ }
+
+ public Asset(String name, String zipPath, String classPath) {
+ this.name = name;
+ this.zipPath = zipPath;
+ uri = getAbsoluteURI(zipPath); // no spaces expected here.
+ this.classPath = classPath.endsWith("/") ? classPath : classPath + "/";
+ }
+
+ public URL getURL(String fullPath) throws MalformedURLException {
+ return (fullPath.indexOf(classPath) < 0 ? null
+ : new URL("jar", null, uri + "!/" + fullPath));//.replaceAll(" ", "%20")));
+ }
+
+ @Override
+ public String toString() {
+ return "{" + "\"name\":" + "\"" + name + "\"," + "\"zipPath\":" + "\"" + zipPath + "\"," + "\"classPath\":"
+ + "\"" + classPath + "\"" + "}";
+ }
+
+ }
+
+ public static Assets getInstance() {
+ return instance;
+ }
+
+ /**
+ * The difference here is that URL will not insert the %20 for space that URI will.
+ *
+ * @param path
+ * @return
+ */
+ @SuppressWarnings("deprecation")
+ public static URL getAbsoluteURL(String path) {
+ URL url = null;
+ try {
+ url = (path.indexOf(":/") < 0 ? new File(new File(path).getAbsolutePath()).toURL() : new URL(path));
+ if (path.indexOf("!/")>=0)
+ url = new URL("jar", null, url.toString());
+ } catch (MalformedURLException e) {
+ e.printStackTrace();
+ }
+ return url;
+ }
+
+ public static URI getAbsoluteURI(String path) {
+ URI uri = null;
+ try {
+ uri = (path.indexOf(":/") < 0 ? new File(new File(path).getAbsolutePath()).toURI() : new URI(path));
+ } catch (URISyntaxException e) {
+ e.printStackTrace();
+ }
+ return uri;
+ }
+
+ /**
+ * Allows passing a Java Asset or array of Assets or a JavaScript Object or
+ * Object array that contains name, zipPath, and classPath keys; in JavaScript,
+ * the keys can have multiple .
+ *
+ * @param o
+ */
+ public static void add(Object o) {
+ if (o == null)
+ return;
+ try {
+ if (o instanceof Object[]) {
+ Object[] a = (Object[]) o;
+ for (int i = 0; i < a.length; i++)
+ add(a[i]);
+ return;
+ }
+ // In JavaScript this may not actually be an Asset, only a proxy for that.
+ // Just testing for keys. Only one of classPath and classPaths is allowed.
+ Asset a = (Asset) o;
+ if (a.name == null || a.zipPath == null || a.classPath == null && a.classPaths == null
+ || a.classPath != null && a.classPaths != null) {
+ throw new NullPointerException("Assets could not parse " + o);
+ }
+ if (a.classPaths == null) {
+ // not possible in Java, but JavaScript may be passing an array of class paths
+ add(a.name, a.zipPath, a.classPath);
+ } else {
+ add(a.name, a.zipPath, a.classPaths);
+ }
+ } catch (Throwable t) {
+ throw new IllegalArgumentException(t.getMessage());
+ }
+ }
+
+ public static void add(String name, String zipFile, String path) {
+ add(name, zipFile, new String[] { path });
+ }
+
+ private static HashSet<String> loadedAssets = new HashSet<>();
+
+ public static boolean hasLoaded(String name) {
+ return loadedAssets.contains(name);
+ }
+
+ public static void reset() {
+ getInstance().htZipContents.clear();
+ getInstance().assetsByPath.clear();
+ getInstance().sortedList = new String[0];
+ }
+
+ public static void add(String name, String zipFile, String[] paths) {
+ getInstance()._add(name, zipFile, paths);
+ }
+
+ private void _add(String name, String zipFile, String[] paths) {
+ if (hasLoaded(name)) {
+ System.err.println("Assets warning: Asset " + name + " already exists");
+ }
+ loadedAssets.add(name);
+ for (int i = paths.length; --i >= 0;) {
+ assetsByPath.put(paths[i], new Asset(name, zipFile, paths[i]));
+ }
+ resort();
+ }
+
+
+ /**
+ * Gets the asset, preferably from a zip file asset, but not necessarily.
+ *
+ * @param assetPath
+ * @return
+ */
+ public static byte[] getAssetBytes(String assetPath) {
+ return getAssetBytes(assetPath, false);
+ }
+
+ /**
+ * Gets the asset, preferably from a zip file asset, but not necessarily.
+ *
+ * @param assetPath
+ * @return
+ */
+ public static String getAssetString(String assetPath) {
+ return getAssetString(assetPath, false);
+ }
+
+ /**
+ * Gets the asset, preferably from a zip file asset, but not necessarily.
+ *
+ * @param assetPath
+ * @return
+ */
+ public static InputStream getAssetStream(String assetPath) {
+ return getAssetStream(assetPath, false);
+ }
+
+ /**
+ * Gets the asset from a zip file.
+ *
+ * @param assetPath
+ * @return
+ */
+ public static byte[] getAssetBytesFromZip(String assetPath) {
+ return getAssetBytes(assetPath, true);
+ }
+
+ /**
+ * Gets the asset from a zip file.
+ *
+ * @param assetPath
+ * @return
+ */
+ public static String getAssetStringFromZip(String assetPath) {
+ return getAssetString(assetPath, true);
+ }
+
+ /**
+ * Gets the asset from a zip file.
+ *
+ * @param assetPath
+ * @return
+ */
+ public static InputStream getAssetStreamFromZip(String assetPath) {
+ return getAssetStream(assetPath, true);
+ }
+
+
+ /**
+ * Get the contents of a path from a zip file asset as byte[], optionally loading
+ * the resource directly using a class loader.
+ *
+ * @param path
+ * @param zipOnly
+ * @return
+ */
+ private static byte[] getAssetBytes(String path, boolean zipOnly) {
+ byte[] bytes = null;
+ try {
+ URL url = getInstance()._getURLFromPath(path, true);
+ if (url == null && !zipOnly) {
+ url = getAbsoluteURL(path);
+ //url = Assets.class.getResource(path);
+ }
+ if (url == null)
+ return null;
+ if (isJS) {
+ bytes = jsutil.getURLBytes(url);
+ if (bytes == null) {
+ url.openStream();
+ bytes = jsutil.getURLBytes(url);
+ }
+ } else {
+ bytes = getLimitedStreamBytes(url.openStream(), -1, null);
+ }
+ } catch (Throwable t) {
+ t.printStackTrace();
+ }
+ return bytes;
+ }
+
+ /**
+ * Get the contents of a path from a zip file asset as a String, optionally
+ * loading the resource directly using a class loader.
+ *
+ * @param path
+ * @param zipOnly
+ * @return
+ */
+ private static String getAssetString(String path, boolean zipOnly) {
+ byte[] bytes = getAssetBytes(path, zipOnly);
+ return (bytes == null ? null : new String(bytes));
+ }
+
+ /**
+ * Get the contents of a path from a zip file asset as an InputStream, optionally
+ * loading the resource directly using a class loader.
+ *
+ * @param path
+ * @param zipOnly
+ * @return
+ */
+ private static InputStream getAssetStream(String path, boolean zipOnly) {
+ try {
+ URL url = getInstance()._getURLFromPath(path, true);
+ if (url == null && !zipOnly) {
+ url = Assets.class.getClassLoader().getResource(path);
+ }
+ if (url != null)
+ return url.openStream();
+ } catch (Throwable t) {
+ }
+ return null;
+ }
+ /**
+ * Determine the path to an asset. If not found in a zip file asset, return the
+ * absolute path to this resource.
+ *
+ * @param fullPath
+ * @return
+ */
+ public static URL getURLFromPath(String fullPath) {
+ return getInstance()._getURLFromPath(fullPath, false);
+ }
+
+ /**
+ * Determine the path to an asset. If not found in a zip file asset, optionally
+ * return null or the absolute path to this resource.
+ *
+ * @param fullPath
+ * @param zipOnly
+ * @return the URL to this asset, or null if not found.
+ */
+ public static URL getURLFromPath(String fullPath, boolean zipOnly) {
+ return getInstance()._getURLFromPath(fullPath, zipOnly);
+ }
+
+ private URL _getURLFromPath(String fullPath, boolean zipOnly) {
+ URL url = null;
+ try {
+ if (fullPath.startsWith("/"))
+ fullPath = fullPath.substring(1);
+ for (int i = sortedList.length; --i >= 0;) {
+ if (fullPath.startsWith(sortedList[i])) {
+ url = assetsByPath.get(sortedList[i]).getURL(fullPath);
+ ZipEntry ze = findZipEntry(url);
+ if (ze == null)
+ break;
+ if (isJS) {
+ jsutil.setURLBytes(url, jsutil.getZipBytes(ze));
+ }
+ return url;
+ }
+ }
+ if (!zipOnly)
+ return getAbsoluteURL(fullPath);
+ } catch (MalformedURLException e) {
+ }
+ return null;
+ }
+
+ public static ZipEntry findZipEntry(URL url) {
+ String[] parts = getJarURLParts(url.toString());
+ if (parts == null || parts[0] == null || parts[1].length() == 0)
+ return null;
+ return findZipEntry(parts[0], parts[1]);
+ }
+
+ public static ZipEntry findZipEntry(String zipFile, String fileName) {
+ return getZipContents(zipFile).get(fileName);
+ }
+
+ /**
+ * Gets the contents of a zip file.
+ *
+ * @param zipPath the path to the zip file
+ * @return a set of file names in alphabetical order
+ */
+ public static Map<String, ZipEntry> getZipContents(String zipPath) {
+ return getInstance()._getZipContents(zipPath);
+ }
+
+ private Map<String, ZipEntry> _getZipContents(String zipPath) {
+ URL url = getURLWithCachedBytes(zipPath); // BH carry over bytes if we have them already
+ Map<String, ZipEntry> fileNames = htZipContents.get(url.toString());
+ if (fileNames != null)
+ return fileNames;
+ try {
+ // Scan URL zip stream for files.
+ return readZipContents(url.openStream(), url);
+ } catch (Exception ex) {
+ ex.printStackTrace();
+ return null;
+ }
+ }
+
+ /**
+ * Deconstruct a jar URL into two parts, before and after "!/".
+ *
+ * @param source
+ * @return
+ */
+ public static String[] getJarURLParts(String source) {
+ int n = source.indexOf("!/");
+ if (n < 0)
+ return null;
+ String jarfile = source.substring(0, n).replace("jar:", "");
+ while (jarfile.startsWith("//"))
+ jarfile = jarfile.substring(1);
+ return new String[] { jarfile, (n == source.length() - 2 ? null : source.substring(n + 2)) };
+ }
+
+ /**
+ * Get the contents of any URL as a byte array. This method does not do any asset check. It just gets the url data as a byte array.
+ *
+ * @param url
+ * @return byte[]
+ *
+ * @author hansonr
+ */
+ public static byte[] getURLContents(URL url) {
+ if (url == null)
+ return null;
+ try {
+ if (isJS) {
+ // Java 9! return new String(url.openStream().readAllBytes());
+ return jsutil.readAllBytes(url.openStream());
+ }
+ return getLimitedStreamBytes(url.openStream(), -1, null);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+ /**
+ *
+ * Convert a file path to a URL, retrieving any cached file data, as from DnD.
+ * Do not do any actual data transfer. This is a swingjs.JSUtil service.
+ *
+ * @param path
+ * @return
+ */
+ private static URL getURLWithCachedBytes(String path) {
+ URL url = getAbsoluteURL(path);
+ if (url != null)
+ addJSCachedBytes(url);
+ return url;
+ }
+
+ private Map<String, ZipEntry> readZipContents(InputStream is, URL url) throws IOException {
+ HashMap<String, ZipEntry> fileNames = new HashMap<String, ZipEntry>();
+ if (doCacheZipContents)
+ htZipContents.put(url.toString(), fileNames);
+ ZipInputStream input = new ZipInputStream(is);
+ ZipEntry zipEntry = null;
+ int n = 0;
+ while ((zipEntry = input.getNextEntry()) != null) {
+ if (zipEntry.isDirectory() || zipEntry.getSize() == 0)
+ continue;
+ n++;
+ String fileName = zipEntry.getName();
+ fileNames.put(fileName, zipEntry); // Java has no use for the ZipEntry, but JavaScript can read it.
+ }
+ input.close();
+ System.out.println("Assets: " + n + " zip entries found in " + url); //$NON-NLS-1$
+ return fileNames;
+ }
+
+ private void resort() {
+ sortedList = new String[assetsByPath.size()];
+ int i = 0;
+ for (String path : assetsByPath.keySet()) {
+ sortedList[i++] = path;
+ }
+ Arrays.sort(sortedList);
+ }
+
+
+ /**
+ * Only needed for Java
+ *
+ * @param is
+ * @param n
+ * @param out
+ * @return
+ * @throws IOException
+ */
+ private static byte[] getLimitedStreamBytes(InputStream is, long n, OutputStream out) throws IOException {
+
+ // Note: You cannot use InputStream.available() to reliably read
+ // zip data from the web.
+
+ boolean toOut = (out != null);
+ int buflen = (n > 0 && n < 1024 ? (int) n : 1024);
+ byte[] buf = new byte[buflen];
+ byte[] bytes = (out == null ? new byte[n < 0 ? 4096 : (int) n] : null);
+ int len = 0;
+ int totalLen = 0;
+ if (n < 0)
+ n = Integer.MAX_VALUE;
+ while (totalLen < n && (len = is.read(buf, 0, buflen)) > 0) {
+ totalLen += len;
+ if (toOut) {
+ out.write(buf, 0, len);
+ } else {
+ if (totalLen > bytes.length)
+ bytes = Arrays.copyOf(bytes, totalLen * 2);
+ System.arraycopy(buf, 0, bytes, totalLen - len, len);
+ if (n != Integer.MAX_VALUE && totalLen + buflen > bytes.length)
+ buflen = bytes.length - totalLen;
+ }
+ }
+ if (toOut)
+ return null;
+ if (totalLen == bytes.length)
+ return bytes;
+ buf = new byte[totalLen];
+ System.arraycopy(bytes, 0, buf, 0, totalLen);
+ return buf;
+ }
+
+ /**
+ * Return all assets in the form that is appropriate for the Info.assets value in SwingJS.
+ *
+ */
+ @Override
+ public String toString() {
+ String s = "[";
+ for (int i = 0; i < sortedList.length; i++) {
+ Asset a = assetsByPath.get(sortedList[i]);
+ s += (i == 0 ? "" : ",") + a;
+ }
+ return s + "]";
+ }
+
+}
--- /dev/null
+package javajs.async;
+
+/**
+ * A package to manage asynchronous aspects of SwingJS
+ *
+ * The javajs.async package simplifies the production of methods that can be
+ * used equally well in Java and in JavaScript for handling "pseudo-modal"
+ * blocking in JavaScript, meaning the user is locked out of other interactions,
+ * as in Java, but the code is not actually blocking the thread.
+ *
+ * Included in this package are
+ *
+ * Async
+ *
+ * Provides few simple generic static methods.
+ *
+ * Async.isJS() -- true if we are running this in JavaScript
+ *
+ * Async.javaSleep() -- bypassing Thread.sleep() for JavaScript; allowing it for
+ * Java
+ *
+ *
+ * AsyncDialog
+ *
+ * Provides several very useful methods that act as a replacement for direct
+ * JOptionPane or JDialog calls, including both a synchronous callback
+ * (manifested in Java) and an asynchronous callback (JavaScript), both
+ * resulting in the same effect, except for the fact that the JavaScript code
+ * has returned immediately from the call with an "ignore me" reference, while
+ * Java is waiting at that call to return a value from JOptionPane (which is
+ * saved by AsyncDialog and not delivered as a return value).
+ *
+ * AsyncDialog does not extend JOptionPane, but it mirrors that classes public
+ * methods. There are a LOT of public methods in JOPtionPane. I suppose we
+ * should implement them all. In practice, AsyncDialog calls standard
+ * JOptionPane static classes for the dialogs.
+ *
+ * Initially, the following methods are implemented:
+ *
+ * public void showConfirmDialog(Component frame, Object message, String title,
+ * ActionListener a)
+ *
+ * public void showConfirmDialog(Component frame, Object message, String title,
+ * int optionType, ActionListener a)
+ *
+ * public void showConfirmDialog(Component frame, Object message, String title,
+ * int optionType, int messageType, ActionListener a)
+ *
+ * public void showInputDialog(Component frame, Object message, ActionListener
+ * a)
+ *
+ * public void showInputDialog(Component frame, Object message, String title,
+ * int messageType, Icon icon, Object[] selectionValues, Object
+ * initialSelectionValue, ActionListener a)
+ *
+ * public void showMessageDialog(Component frame, Object message, ActionListener
+ * a)
+ *
+ * public void showOptionDialog(Component frame, Object message, String title,
+ * int optionType, int messageType, Icon icon, Object[] options, Object
+ * initialValue, ActionListener a)
+ *
+ *
+ * All nonstatic methods, requiring new AsyncDialog(), also require an
+ * ActionListener. This listener will get a call to actionPerformed(ActionEvent)
+ * where:
+ *
+ * event.getSource() is a reference to the originating AsyncDialog (super
+ * JOptionPane) for all information that a standard JOptionPane can provide,
+ * along with the two methods int getOption() and Object getChoice().
+ *
+ * event.getID() is a reference to the standard JOptionPane int return code.
+ *
+ * event.getActionCommand() also holds a value, but it may or may not be of
+ * value.
+ *
+ *
+ * A few especially useful methods are static, allowing just one or two expected
+ * callbacks of interest:
+ *
+ * AsyncDialog.showOKAsync(Component parent, Object message, String title,
+ * Runnable ok)
+ *
+ * AsyncDialog.showYesAsync (Component parent, Object message, String title,
+ * Runnable yes)
+ *
+ * AsyncDialog.showYesNoAsync (Component parent, Object message, String title,
+ * Runnable yes, Runnable no)
+ *
+ * These methods provide a fast way to adjust JOptionPane calls to be
+ * asynchronous.
+ *
+ *
+ *
+ * AsyncFileChooser extends javax.swing.JFileChooser
+ *
+ * Accepted constructors include:
+ *
+ * public AsyncFileChooser()
+ *
+ * public AsyncFileChooser(File file)
+ *
+ * public AsyncFileChooser(File file, FileSystemView view)
+ *
+ * (Note, however, that FileSystemView has no equivalent in JavaScript.)
+ *
+ * It's three public methods include:
+ *
+ * public void showDialog(Component frame, String btnLabel, Runnable ok,
+ * Runnable cancel)
+ *
+ * public void showOpenDialog(Component frame, Runnable ok, Runnable cancel)
+ *
+ * public void showSaveDialog(Component frame, Runnable ok, Runnable cancel)
+ *
+ *
+ * ActionListener is not needed here, as the instance of new AsyncFileChooser()
+ * already has direct access to all the JFileChooser public methods such as
+ * getSelectedFile() and getSelectedFiles().
+ *
+ * As a subclass of JFileChooser, it accepts all three public showXXXX methods
+ * of JFileChooser, namely:
+ *
+ * public void showDialog(Component frame, String btnLabel)
+ *
+ * public void showOpenDialog(Component frame)
+ *
+ * public void showSaveDialog(Component frame)
+ *
+ *
+ * None of these are recommended. AsyncFileChooser will indicate errors if the
+ * first of these two are called. (showSaveDialog is fine, as it is modal even
+ * in JavaScript. However it is not recommended that showSaveDialog(Component
+ * frame) be used, as in the future browsers may implement some sort of file
+ * saver in HTML5.
+ *
+ *
+ *
+ * AsyncColorChooser
+ *
+ *
+ * AsyncColorChooser accesses JColorChooser asynchronously, using a private
+ * SwingJS setting that tells JColorChooser to report back to it with property
+ * changes. It is constructed using new AsyncColorChooser() and implements just
+ * two methods:
+ *
+ * public void showDialog(Component component, String title, Color initialColor,
+ * ActionListener listener)
+ *
+ * public Color getSelectedColor()
+ *
+ *
+ * The listener will get an actionPerformed(ActionEvent) callback with
+ * event.getID() equal to the color value or 0 if canceled. The
+ * getSelectedColor() method may also be called from this callback to retrieve
+ * the associated java.awt.Color object, using
+ *
+ * ((AsyncColorChooser)e.getSource()).getSelectedColor()
+ *
+ * As in Java, a null value for the selected color indicates that the
+ * JColorChooser was closed.
+ *
+ * Bob Hanson 2019.11.07
+ *
+ *
+ * @author Bob Hanson hansonr_at_stolaf.edu
+ *
+ */
+public class Async {
+
+ public static boolean isJS() {
+ return (/** @j2sNative 1 ? true : */false);
+ }
+
+ /**
+ * No sleep in JavaScript
+ * @param ms
+ */
+ public static void javaSleep(int ms) {
+ if (!isJS()) {
+ try {
+ Thread.sleep(ms);
+ } catch (InterruptedException e) {
+ }
+ }
+
+ }
+
+}
--- /dev/null
+package javajs.async;
+
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+
+import javax.swing.JColorChooser;
+import javax.swing.plaf.UIResource;
+
+/**
+ * A simple Asynchronous file chooser for JavaScript; synchronous with Java.
+ *
+ * Allows two modes -- using an ActionListener (setAction(ActionListener) or constructor(ActionListener))
+ *
+ * @author Bob Hanson
+ */
+
+public class AsyncColorChooser implements PropertyChangeListener {
+
+ private ActionListener listener;
+ private Color selectedColor;
+
+ public void showDialog(Component component, String title, Color initialColor, ActionListener listener) {
+ setListener(listener);
+ process(JColorChooser.showDialog(component, title, initialColor));
+ unsetListener();
+ }
+
+ public Color getSelectedColor() {
+ return selectedColor;
+ }
+
+
+ @Override
+ public void propertyChange(PropertyChangeEvent evt) {
+ // JavaScript only
+ Color c = (Color) evt.getNewValue();
+
+ switch (evt.getPropertyName()) {
+ case "SelectedColor":
+ process(c);
+ break;
+ }
+ }
+
+ private void setListener(ActionListener a) {
+ listener = a;
+ /** @j2sNative Clazz.load("javax.swing.JColorChooser");javax.swing.JColorChooser.listener = this */
+ }
+
+ private void unsetListener() {
+ /** @j2sNative javax.swing.JColorChooser.listener = null */
+ }
+
+
+
+ private void process(Color c) {
+ if (c instanceof UIResource)
+ return;
+ selectedColor = c;
+ listener.actionPerformed(new ActionEvent(this, c == null ? 0 : c.getRGB(), c == null ? null : c.toString()));
+ }
+
+}
--- /dev/null
+package javajs.async;
+
+import java.awt.Component;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+
+import javax.swing.Icon;
+import javax.swing.JOptionPane;
+import javax.swing.plaf.UIResource;
+
+/**
+ * A class to manage asynchronous input, option, and confirmation dialogs.
+ *
+ * @author Bob Hanson hansonr_at_stolaf.edu
+ *
+ */
+public class AsyncDialog implements PropertyChangeListener {
+
+// see discussion in net.sf.j2s.core/doc/Differences.txt
+//
+// Confirmation dialog example. Note moving the parent component into the constructor.
+// Original:
+//
+// private void promptQuit() {
+// int sel = JOptionPane.showConfirmDialog(null, PROMPT_EXIT, NAME, JOptionPane.YES_NO_OPTION);
+// switch (sel) {
+// case JOptionPane.YES_OPTION:
+// resultsTab.clean();
+// seqs.dispose();
+// if (fromMain) {
+// System.exit(0);
+// }
+// break;
+// }
+// }
+//
+// revised:
+//
+// private void promptQuitAsync() {
+// new AsyncDialog().showConfirmDialog(null, PROMPT_EXIT, NAME, JOptionPane.YES_NO_OPTION, new ActionListener() {
+//
+// @Override
+// public void actionPerformed(ActionEvent e) {
+// int sel = ((AsyncDialog)e.getSource()).getOption();
+// switch (sel) {
+// case JOptionPane.YES_OPTION:
+// resultsTab.clean();
+// seqs.dispose();
+// if (fromMain) {
+// System.exit(0);
+// }
+// break;
+// }
+// }}));
+// }
+
+
+ public AsyncDialog() {
+ }
+
+ private ActionListener actionListener;
+ private Object choice;
+ private Object[] options;
+ private Object value;
+ private boolean wantsInput;
+
+ // These options can be supplemented as desired.
+
+
+ /**
+ * Synchronous call; OK in JavaScript as long as we are using a JavaScript prompt() call
+ *
+ * @param frame
+ * @param msg
+ * @return
+ */
+ @Deprecated
+ public static String showInputDialog(Component frame, String msg) {
+ return JOptionPane.showInputDialog(frame, msg);
+ }
+
+ public void showInputDialog(Component frame, Object message, ActionListener a) {
+ setListener(a);
+ wantsInput = true;
+ process(JOptionPane.showInputDialog(frame, message));
+ unsetListener();
+ }
+
+ public void showInputDialog(Component frame, Object message, String title, int messageType, Icon icon,
+ Object[] selectionValues, Object initialSelectionValue, ActionListener a) {
+ setListener(a);
+ wantsInput = true;
+ process(JOptionPane.showInputDialog(frame, message, title, messageType, icon, selectionValues,
+ initialSelectionValue));
+ unsetListener();
+ }
+
+ public void showMessageDialog(Component frame, Object message, ActionListener a) {
+ setListener(a);
+ JOptionPane.showMessageDialog(frame, message);
+ unsetListener();
+ if (/** @j2sNative false || */true)
+ process("" + message);
+ }
+
+ public void showOptionDialog(Component frame, Object message, String title, int optionType, int messageType,
+ Icon icon, Object[] options, Object initialValue, ActionListener a) {
+ actionListener = a;
+ this.options = options;
+ setListener(a);
+ process(JOptionPane.showOptionDialog(frame, message, title, optionType, messageType, icon, options,
+ initialValue));
+ unsetListener();
+ }
+
+ public void showConfirmDialog(Component frame, Object message, String title, ActionListener a) {
+ showConfirmDialog(frame, message, title, JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE, a);
+ }
+
+ public void showConfirmDialog(Component frame, Object message, String title, int optionType, ActionListener a) {
+ showConfirmDialog(frame, message, title, optionType, JOptionPane.QUESTION_MESSAGE, a);
+ }
+
+ public void showConfirmDialog(Component frame, Object message, String title, int optionType, int messageType,
+ ActionListener a) {
+ setListener(a);
+ process(JOptionPane.showConfirmDialog(frame, message, title, optionType, messageType));
+ unsetListener();
+ }
+
+ /**
+ * retrieve selection from the ActionEvent, for which "this" is getSource()
+ *
+ * @return
+ */
+ public Object getChoice() {
+ return choice;
+ }
+
+ public int getOption() {
+ if (!(choice instanceof Integer)) {
+ throw new java.lang.IllegalArgumentException("AsyncDialog.getOption called for non-Integer choice");
+ }
+ return ((Integer) choice).intValue();
+ }
+
+ /**
+ * A dialog option that allows for YES, NO, and CLOSE options via
+ * ActionListener. ActionEvent.getID() contains the reply.
+ *
+ * @param parent The parent component for the dialog
+ * @param message The text of the message to display
+ * @param title Optional title defaults to "Question"
+ * @param listener Handle options based on an ActionEvent
+ */
+ public static void showYesNoAsync(Component parent, Object message, String title, ActionListener listener) {
+ new AsyncDialog().showConfirmDialog(parent, message, (title == null ? "Question" : title),
+ JOptionPane.YES_NO_OPTION, listener);
+ }
+
+ /**
+ * A dialog option that involves just a YES follower.
+ * @param parent
+ * @param message
+ * @param title TODO
+ * @param yes
+ */
+ public static void showYesAsync(Component parent, Object message, String title, Runnable yes) {
+ AsyncDialog.showYesNoAsync(parent, message, title, new ActionListener() {
+
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ if (e.getID() == JOptionPane.YES_OPTION) {
+ yes.run();
+ }
+ }
+
+ });
+ }
+
+ /**
+ * A dialog option that involves just an OK follower.
+ * @param parent
+ * @param message
+ * @param title
+ * @param ok
+ */
+ public static void showOKAsync(Component parent, Object message, String title, Runnable ok) {
+ new AsyncDialog().showConfirmDialog(parent, message, title, JOptionPane.OK_CANCEL_OPTION, new ActionListener() {
+
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ if (e.getID() == JOptionPane.OK_OPTION) {
+ ok.run();
+ }
+ }
+
+ });
+ }
+
+
+ private void setListener(ActionListener a) {
+ actionListener = a;
+ @SuppressWarnings("unused")
+ Class c = JOptionPane.class; // loads the class
+ /** @j2sNative c.$clazz$.listener = this */
+ }
+
+ private void unsetListener() {
+ /** @j2sNative javax.swing.JOptionPane.listener = null */
+ }
+
+ /**
+ * Switch from property change to action.
+ *
+ */
+ @Override
+ public void propertyChange(PropertyChangeEvent evt) {
+ value = evt.getNewValue();
+ switch (evt.getPropertyName()) {
+ case "inputValue":
+ process(value);
+ break;
+ case "value":
+ if (value != null && options == null && !(value instanceof Integer)) {
+ process(getOptionIndex(((JOptionPane) evt.getSource()).getOptions(), value));
+ return;
+ }
+ if (options != null) {
+ int i = getOptionIndex(options, value);
+ value = Integer.valueOf(i >= 0 ? i : JOptionPane.CLOSED_OPTION);
+ }
+ process(value);
+ break;
+ }
+ }
+
+ private int getOptionIndex(Object[] options, Object val) {
+ if (options != null)
+ for (int i = 0; i < options.length; i++) {
+ if (options[i] == val)
+ return i;
+ }
+ return -1;
+ }
+
+ public Object getValue() {
+ if (wantsInput || options == null)
+ return value;
+ int val = ((Integer) value).intValue();
+ return (val < 0 ? null : options[val]);
+ }
+
+ private boolean processed;
+
+ /**
+ * Return for confirm dialog.
+ *
+ * @param ret may be JavaScript NaN, testable as ret != ret or ret != - -ret
+ */
+ private void process(int ret) {
+ if (ret != -(-ret) || processed)
+ return;
+ processed = true;
+ choice = ret;
+ actionListener.actionPerformed(new ActionEvent(this, ret, "SelectedOption"));
+ }
+
+ private void process(Object ret) {
+ if (ret instanceof UIResource || processed)
+ return;
+ processed = true;
+ choice = ret;
+ actionListener.actionPerformed(new ActionEvent(this,
+ ret == null ? JOptionPane.CANCEL_OPTION : JOptionPane.OK_OPTION,
+ (ret == null ? null : ret.toString())));
+ }
+
+
+}
--- /dev/null
+package javajs.async;
+
+
+import java.awt.Component;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import java.io.File;
+import java.util.function.Function;
+
+import javax.swing.JFileChooser;
+import javax.swing.JOptionPane;
+import javax.swing.filechooser.FileSystemView;
+
+/**
+ * A simple Asynchronous file chooser for JavaScript and Java.
+ *
+ * Requires an OK runnable; JavaScript can return notification of cancel for
+ * file reading only, not saving.
+ *
+ * @author Bob Hanson
+ */
+
+public class AsyncFileChooser extends JFileChooser implements PropertyChangeListener {
+
+ private int optionSelected;
+ private Runnable ok, cancel; // sorry, no CANCEL in JavaScript for file open
+ private boolean isAsyncSave = true;
+ private static boolean notified;
+
+ public AsyncFileChooser() {
+ super();
+ }
+
+ public AsyncFileChooser(File file) {
+ super(file);
+ }
+
+ public AsyncFileChooser(File file, FileSystemView view) {
+ super(file, view);
+ }
+
+ @Deprecated
+ @Override
+ public int showDialog(Component frame, String btnText) {
+ // This one can come from JFileChooser - default is OPEN
+ return super.showDialog(frame, btnText);
+ }
+
+ private int err() {
+ try {
+ throw new java.lang.IllegalAccessException("Warning! AsyncFileChooser interface bypassed!");
+ } catch (IllegalAccessException e) {
+ e.printStackTrace();
+ }
+ return JFileChooser.ERROR_OPTION;
+ }
+
+ @Deprecated
+ @Override
+ public int showOpenDialog(Component frame) {
+ return err();
+ }
+
+ @Override
+ public int showSaveDialog(Component frame) {
+ isAsyncSave = false;
+ return super.showSaveDialog(frame);
+ }
+
+ /**
+ *
+ * @param frame
+ * @param btnLabel "open" or "save"
+ * @param ok
+ * @param cancel must be null; JavaScript cannot capture a cancel from a file dialog
+ */
+ public void showDialog(Component frame, String btnLabel, Runnable ok, Runnable cancel) {
+ this.ok = ok;
+ if (getDialogType() != JFileChooser.SAVE_DIALOG && cancel != null)
+ notifyCancel();
+ process(super.showDialog(frame, btnLabel));
+ }
+
+ /**
+ *
+ * @param frame
+ * @param ok
+ * @param cancel must be null; JavaScript cannot capture a cancel from a file dialog
+ */
+ public void showOpenDialog(Component frame, Runnable ok, Runnable cancel) {
+ this.ok = ok;
+ if (cancel != null)
+ notifyCancel();
+ process(super.showOpenDialog(frame));
+ }
+
+ /**
+ *
+ * This just completes the set. It is not necessary for JavaScript, because JavaScript
+ * will just throw up a simple modal OK/Cancel message anyway.
+ *
+ * @param frame
+ * @param ok
+ * @param cancel must be null
+ */
+ public void showSaveDialog(Component frame, Runnable ok, Runnable cancel) {
+ this.ok = ok;
+ this.cancel = cancel;
+ process(super.showSaveDialog(frame));
+ }
+
+
+ /**
+ * Locate a file for input or output. Note that JavaScript will not return on cancel for OPEN_DIALOG.
+ *
+ * @param title The title for the dialog
+ * @param mode OPEN_DIALOG or SAVE_DIALOG
+ * @param processFile function to use when complete
+ */
+ public static void getFileAsync(Component parent, String title, int mode, Function<File, Void> processFile) {
+ // BH no references to this method. So changing its signature for asynchonous use
+ // And it didn't do as advertised - ran System.exit(0) if canceled
+ // create and display a file dialog
+ AsyncFileChooser fc = new AsyncFileChooser();
+ fc.setDialogTitle(title);
+ Runnable after = new Runnable() {
+
+ @Override
+ public void run() {
+ processFile.apply(fc.getSelectedFile());
+ }
+
+ };
+ if (mode == JFileChooser.OPEN_DIALOG) {
+ fc.showOpenDialog(parent, after, after);
+ } else {
+ fc.showSaveDialog(parent, after, after);
+ }
+
+ }
+
+ /**
+ * Run yes.run() if a file doesn't exist or if the user allows it, else run no.run()
+ * @param parent
+ * @param filename
+ * @param title
+ * @param yes (approved)
+ * @param no (optional)
+ */
+ public static void checkReplaceFileAsync(Component parent, File outfile, String title, Runnable yes, Runnable no) {
+ if (outfile.exists()) {
+ AsyncDialog.showYesNoAsync(parent,
+ outfile + " exists. Replace it?", null, new ActionListener() {
+
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ switch (e.getID()) {
+ case JOptionPane.YES_OPTION:
+ yes.run();
+ break;
+ default:
+ if (no != null)
+ no.run();
+ break;
+ }
+ }
+
+ });
+
+ } else {
+ yes.run();
+ }
+
+ }
+
+ private void notifyCancel() {
+ if (!notified) {
+ System.err.println("developer note: JavaScript cannot fire a FileChooser CANCEL action");
+ }
+ notified = true;
+ }
+
+ @Override
+ public void propertyChange(PropertyChangeEvent evt) {
+ switch (evt.getPropertyName()) {
+ case "SelectedFile":
+ case "SelectedFiles":
+ process(optionSelected = (evt.getNewValue() == null ? CANCEL_OPTION : APPROVE_OPTION));
+ break;
+ }
+ }
+
+ private void process(int ret) {
+ if (ret != -(-ret))
+ return; // initial JavaScript return is NaN
+ optionSelected = ret;
+ File f = getSelectedFile();
+ if (f == null) {
+ if (cancel != null)
+ cancel.run();
+ } else {
+ if (ok != null)
+ ok.run();
+ }
+ }
+
+ public int getSelectedOption() {
+ return optionSelected;
+ }
+
+ public static byte[] getFileBytes(File f) {
+ return /** @j2sNative f.秘bytes || */null;
+ }
+
+}
--- /dev/null
+package javajs.async;
+
+import java.awt.Component;
+
+import javax.swing.ProgressMonitor;
+import javax.swing.SwingUtilities;
+import javax.swing.SwingWorker;
+
+import javajs.async.SwingJSUtils.StateHelper;
+import javajs.async.SwingJSUtils.StateMachine;
+
+/**
+ * v. 2020.06.03
+ *
+ * Executes synchronous or asynchronous tasks using a SwingWorker in Java or
+ * JavaScript, equivalently.
+ *
+ * Unlike a standard SwingWorker, AsyncSwingWorker may itself be asynchronous.
+ * For example, it might load a file asynchronously, or carry out a background
+ * process in JavaScript much like one might be done in Java, but with only a
+ * single thread.
+ *
+ * Whereas a standard SwingWorker would execute done() long before the
+ * asynchronous task completed, this class will wait until progress has been
+ * asynchronously set greater or equal to its max value or the task is canceled
+ * before executing that method.
+ *
+ * Three methods must be supplied by the subclass:
+ *
+ * void initAsync()
+ *
+ * int doInBackgroundAsync(int progress)
+ *
+ * void doneAsync()
+ *
+ * Both initAsync() and doneAsync() are technically optional - they may be
+ * empty. doInBackgroundAsync(), however, is the key method where, like
+ * SwingWorker's doInBackground, the main work is done. The supplied progress
+ * parameter reminds the subclass of where it is at, and the return value allows
+ * the subclass to update the progress field in both the SwingWorker and the
+ * ProgressMonitor.
+ *
+ * If it is desired to run the AsyncSwingWorker synchronously, call the
+ * executeSynchronously() method rather than execute(). Never call
+ * SwingWorker.run().
+ *
+ * Note that doInBackgroundAsync runs on the Java AWT event queue. This means
+ * that, unlike a true SwingWorker, it will run in event-queue sequence, after
+ * anything that that method itself adds to the queue. This is what SwingWorker itself
+ * does with its done() signal.
+ *
+ * If doInBackgroundAsync has tasks that are time intensive, the thing to do is to
+ *
+ * (a) pause this worker by setting the value of progress for the NEXT step:
+ *
+ * setProgressAsync(n);
+ *
+ * (b) pause the timer so that when doInBackgroundAsync returns, the timer is not fired:
+ *
+ * setPaused(true);
+ *
+ * (c) start your process as new Thread, which bypasses the AWT EventQueue:
+ *
+ * new Thread(Runnable).start();
+ *
+ * (d) have your thread, when it is done, return control to this worker:
+ *
+ * setPaused(false);
+ *
+ * This final call restarts the worker with the currently specified progress value.
+ *
+ * @author hansonr
+ *
+ */
+public abstract class AsyncSwingWorker extends SwingWorker<Void, Void> implements StateMachine {
+
+
+ // PropertyChangeEvent getPropertyName()
+
+ private static final String PROPERTY_STATE = "state";
+ private static final String PROPERTY_PAUSE = "pause";
+
+ // PropertyChangeEvent getNewValue()
+
+ public static final String STARTED_ASYNC = "STARTED_ASYNC";
+ public static final String STARTED_SYNC = "STARTED_SYNC";
+
+ public static final String DONE_ASYNC = "DONE_ASYNC";
+ public static final String CANCELED_ASYNC = "CANCELED_ASYNC";
+
+ public static final String PAUSED = "PAUSED";
+ public static final String RESUMED = "RESUMED";
+
+ protected int progressAsync;
+
+ /**
+ * Override to provide initial tasks.
+ */
+ abstract public void initAsync();
+
+ /**
+ * Given the last progress, do some portion of the task that the SwingWorker
+ * would do in the background, and return the new progress. returning max or
+ * above will complete the task.
+ *
+ * @param progress
+ * @return new progress
+ */
+ abstract public int doInBackgroundAsync(int progress);
+
+ /**
+ * Do something when the task is finished or canceled.
+ *
+ */
+ abstract public void doneAsync();
+
+ protected ProgressMonitor progressMonitor;
+
+ protected int delayMillis;
+ protected String note;
+ protected int min;
+ protected int max;
+ protected int progressPercent;
+
+ protected boolean isAsync;
+ private Exception exception;
+
+ /**
+ * Construct an asynchronous SwingWorker task that optionally will display a
+ * ProgressMonitor. Progress also can be monitored by adding a
+ * PropertyChangeListener to the AsyncSwingWorker and looking for the "progress"
+ * event, just the same as for a standard SwingWorker.
+ *
+ * @param owner optional owner for the ProgressMonitor, typically a JFrame
+ * or JDialog.
+ *
+ * @param title A non-null title indicates we want to use a
+ * ProgressMonitor with that title line.
+ *
+ * @param delayMillis A positive number indicating the delay we want before
+ * executions, during which progress will be reported.
+ *
+ * @param min The first progress value. No range limit.
+ *
+ * @param max The last progress value. No range limit; may be greater
+ * than min.
+ *
+ */
+ public AsyncSwingWorker(Component owner, String title, int delayMillis, int min, int max) {
+ if (title != null && delayMillis > 0) {
+ progressMonitor = new ProgressMonitor(owner, title, "", Math.min(min, max), Math.max(min, max));
+ progressMonitor.setProgress(Math.min(min, max)); // displays monitor
+ }
+ this.delayMillis = Math.max(0, delayMillis);
+ this.isAsync = (delayMillis > 0);
+
+ this.min = min;
+ this.max = max;
+ }
+
+ public void executeAsync() {
+ firePropertyChange(PROPERTY_STATE, null, STARTED_ASYNC);
+ super.execute();
+ }
+
+ public void executeSynchronously() {
+ firePropertyChange(PROPERTY_STATE, null, STARTED_SYNC);
+ isAsync = false;
+ delayMillis = 0;
+ try {
+ doInBackground();
+ } catch (Exception e) {
+ exception = e;
+ e.printStackTrace();
+ cancelAsync();
+ }
+ }
+
+ public Exception getException() {
+ return exception;
+ }
+
+ public int getMinimum() {
+ return min;
+ }
+
+ public void setMinimum(int min) {
+ this.min = min;
+ if (progressMonitor != null) {
+ progressMonitor.setMinimum(min);
+ }
+ }
+
+ public int getMaximum() {
+ return max;
+ }
+
+ public void setMaximum(int max) {
+ if (progressMonitor != null) {
+ progressMonitor.setMaximum(max);
+ }
+ this.max = max;
+ }
+
+ public int getProgressPercent() {
+ return progressPercent;
+ }
+
+ public void setNote(String note) {
+ this.note = note;
+ if (progressMonitor != null) {
+ progressMonitor.setNote(note);
+ }
+ }
+
+ /**
+ * Cancel the asynchronous process.
+ *
+ */
+ public void cancelAsync() {
+ helper.interrupt();
+ }
+
+ /**
+ * Check to see if the asynchronous process has been canceled.
+ *
+ * @return true if StateHelper is not alive anymore
+ *
+ */
+ public boolean isCanceledAsync() {
+ return !helper.isAlive();
+ }
+
+ /**
+ * Check to see if the asynchronous process is completely done.
+ *
+ * @return true only if the StateMachine is at STATE_DONE
+ *
+ */
+ public boolean isDoneAsync() {
+ return helper.getState() == STATE_DONE;
+ }
+
+ /**
+ * Override to set a more informed note for the ProcessMonitor.
+ *
+ * @param progress
+ * @return
+ */
+ public String getNote(int progress) {
+ return String.format("Completed %d%%.\n", progress);
+ }
+
+ /**
+ * Retrieve the last note delivered by the ProcessMonitor.
+ *
+ * @return
+ */
+ public String getNote() {
+ return note;
+ }
+
+ public int getProgressAsync() {
+ return progressAsync;
+ }
+
+ /**
+ * Set the [min,max] progress safely.
+ *
+ * SwingWorker only allows progress between 0 and 100. This method safely
+ * translates [min,max] to [0,100].
+ *
+ * @param n
+ */
+ public void setProgressAsync(int n) {
+ n = (max > min ? Math.max(min, Math.min(n, max)) : Math.max(max, Math.min(n, min)));
+ progressAsync = n;
+ n = (n - min) * 100 / (max - min);
+ n = (n < 0 ? 0 : n > 100 ? 100 : n);
+ progressPercent = n;
+ }
+
+ ///// the StateMachine /////
+
+ private final static int STATE_INIT = 0;
+ private final static int STATE_LOOP = 1;
+ private final static int STATE_WAIT = 2;
+ private final static int STATE_DONE = 99;
+
+ private StateHelper helper;
+
+ protected StateHelper getHelper() {
+ return helper;
+ }
+
+ private boolean isPaused;
+
+ protected void setPaused(boolean tf) {
+ isPaused = tf;
+ firePropertyChange(PROPERTY_PAUSE, null, (tf ? PAUSED : RESUMED));
+ if (!tf)
+ stateLoop();
+ }
+
+ protected boolean isPaused() {
+ return isPaused;
+ }
+
+ /**
+ * The StateMachine's main loop.
+ *
+ * Note that a return from this method will exit doInBackground, trigger the
+ * isDone() state on the underying worker, and scheduling its done() for
+ * execution on the AWTEventQueue.
+ *
+ * Since this happens essentially immediately, it is unlikely that
+ * SwingWorker.isCancelled() will ever be true. Thus, the SwingWorker task
+ * itself won't be cancelable in Java or in JavaScript, since its
+ * doInBackground() method is officially complete, and isDone() is true well
+ * before we are "really" done. FutureTask will not set isCancelled() true once
+ * the task has run.
+ *
+ * We are using an asynchronous task specifically because we want to have the
+ * opportunity for the ProgressMonitor to report in JavaScript. We will have to
+ * cancel our task and report progress explicitly using our own methods.
+ *
+ */
+ @Override
+ public boolean stateLoop() {
+ while (helper.isAlive() && !isPaused) {
+ switch (helper.getState()) {
+ case STATE_INIT:
+ setProgressAsync(min);
+ initAsync();
+ helper.setState(STATE_WAIT);
+ continue;
+ case STATE_LOOP:
+ if (checkCanceled()) {
+ helper.setState(STATE_DONE);
+ firePropertyChange(PROPERTY_STATE, null, CANCELED_ASYNC);
+ } else {
+ int ret = doInBackgroundAsync(progressAsync);
+ if (!helper.isAlive() || isPaused) {
+ continue;
+ }
+ progressAsync = ret;
+ setProgressAsync(progressAsync);
+ setNote(getNote(progressAsync));
+ setProgress(progressPercent);
+ if (progressMonitor != null) {
+ progressMonitor.setProgress(max > min ? progressAsync : max + min - progressAsync);
+ }
+ helper.setState(progressAsync == max ? STATE_DONE : STATE_WAIT);
+ }
+ continue;
+ case STATE_WAIT:
+ // meaning "sleep" and then "loop"
+ helper.setState(STATE_LOOP);
+ helper.sleep(delayMillis);
+ return true;
+ default:
+ case STATE_DONE:
+ stopProgressMonitor();
+ // Put the doneAsync() method on the AWTEventQueue
+ // just as for SwingWorker.done().
+ if (isAsync) {
+ SwingUtilities.invokeLater(doneRunnable);
+ } else {
+ doneRunnable.run();
+ }
+
+ return false;
+ }
+ }
+ if (!helper.isAlive()) {
+ stopProgressMonitor();
+ }
+ return false;
+ }
+
+ private void stopProgressMonitor() {
+ if (progressMonitor != null) {
+ progressMonitor.close();
+ progressMonitor = null;
+ }
+ }
+
+ private Runnable doneRunnable = new Runnable() {
+ @Override
+ public void run() {
+ doneAsync();
+ firePropertyChange(PROPERTY_STATE, null, DONE_ASYNC);
+ }
+
+ };
+
+ private boolean checkCanceled() {
+ if (isMonitorCanceled() || isCancelled()) {
+ helper.interrupt();
+ return true;
+ }
+ return false;
+ }
+
+ //// final SwingWorker methods not to be used by subclasses ////
+
+ private boolean isMonitorCanceled() {
+ return (progressMonitor != null && progressMonitor.isCanceled());
+ }
+
+ /**
+ * see SwingWorker, made final here.
+ *
+ */
+ @Override
+ final protected Void doInBackground() throws Exception {
+ helper = new StateHelper(this);
+ setProgressAsync(min);
+ helper.next(STATE_INIT);
+ return null;
+ }
+
+ /**
+ * see SwingWorker, made final here. Nothing to do.
+ *
+ */
+ @Override
+ final public void done() {
+ }
+
+}
--- /dev/null
+package javajs.async;
+
+import java.awt.Component;
+import java.awt.Dimension;
+import java.awt.Graphics;
+import java.awt.Image;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.io.BufferedInputStream;
+import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.stream.Collectors;
+
+import javax.imageio.ImageIO;
+import javax.swing.Timer;
+
+/**
+ * A set of generally useful SwingJS-related methods. Includes:
+ *
+ * alternatives to using getCodeBase() for loading resources, due to issues in
+ * Eclipse setting that incorrectly (but no problem in JavaScript)
+ *
+ *
+ *
+ * @author hansonr
+ *
+ */
+public class SwingJSUtils {
+ /**
+ * Set the dimension for the applet prior to j2sApplet's call to
+ * run the applet. Must be used to create a static field:
+ *
+ * <code>
+ * private static Dimension dim =
+ * </code>
+ *
+ *
+ * Then, if it is desired also to have Java also set this, add
+ *
+ * if (dim != null) setSize(dim);
+ *
+ * to the applet's init() method.
+ *
+ * @param w
+ * @param h
+ * @return the Dimension
+ *
+ * @author hansonr
+ */
+ public static Dimension setDim(int w, int h) {
+ String baseURI = (/** @j2sNative document.body.baseURI || */
+ null);
+ boolean isTest = (baseURI == null || baseURI.indexOf("_applet.html") >= 0);
+ if (!isTest)
+ return null;
+ /**
+ * @j2sNative
+ *
+ * J2S.thisApplet.__Info.width = w; J2S.thisApplet.__Info.height = h;
+ */
+ return new Dimension(w, h);
+ }
+
+ /**
+ * Reliably load a resource of a specific type from the code directory
+ *
+ * adaptable - here we are returning an image or a string
+ *
+ * @param cl the classname of the object to return (Image.class,
+ * String.class) null for InputStream
+ * @param filename
+ * @return
+ *
+ * @author hansonr
+ */
+ public static Object getResource(Class<?> baseClass, String filename, Class<?> cl) {
+ System.out.println("mpUtils.SwingJSUtils.getResource " + baseClass.getCanonicalName() + " " + filename);
+ InputStream is = baseClass.getResourceAsStream(filename);
+ if (cl == Image.class) {
+ try {
+ return ImageIO.read(is);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ } else if (cl == String.class) {
+ return new BufferedReader(new InputStreamReader(is)).lines().collect(Collectors.joining("\n"));
+ }
+ return is;
+ }
+
+ /**
+ * Pre-fetch images during the static entry of the class. This should provide
+ * plenty of clock ticks, since the file transfer is synchronous, and all we are
+ * waiting for is the DOM image object to initialize.
+ *
+ * @param cl
+ * @param images
+ * @param root
+ * @param nImages
+ * @param ext
+ */
+ public static void loadImagesStatic(Class<?> cl, Image[] images, String root, String ext, int nImages) {
+ for (int i = nImages; --i >= 0;) {
+
+ // Bild laden und beim MediaTracker registrieren
+ // MediaTracker ladekontrolle = new MediaTracker(this);
+
+ // BH SwingJS -- adding generally useful method for loading data
+ // avoiding the use of getCodeBase(), which for some reason does not work in
+ // Eclipse.
+
+ images[i] = (Image) getResource(cl, root + i + "." + ext, Image.class);
+// /**
+// * @j2sNative
+// * $("body").append(images[i]._imgNode);
+// *
+// */
+// ladekontrolle.addImage(scharf[i],i);
+ // Warten , bis Bild ganz geladen ist
+
+// try {ladekontrolle.waitForID(i);}
+// catch (InterruptedException e)
+// {}
+ }
+ }
+
+ /**
+ * Fill an array with images based on a String[] listing
+ * @param cl reference class
+ * @param root optional root path, ending in "/"
+ * @param names source file names
+ * @param images array to fill
+ */
+ public static void loadImagesStatic(Class<?> cl, String root, String[] names, Image[] images) {
+ for (int i = names.length; --i >= 0;) {
+ images[i] = (Image) getResource(cl, root + names[i], Image.class);
+ }
+ }
+
+ /**
+ * Eclipse-friendly image getting
+ *
+ * @param c
+ * @param fileName
+ * @return
+ */
+ public static Image getImage(Component c, String fileName) {
+ return getImage(c.getClass(), fileName);
+ }
+
+ /**
+ * Eclipse-friendly image getting
+ *
+ * @param c
+ * @param fileName
+ * @return
+ */
+ public static Image getImage(Class<?> c, String fileName) {
+ return (Image) getResource(c, fileName, Image.class);
+ }
+
+ /**
+ * Clear the component graphic. BH added this for JavaScript because changing
+ * the browser zoom can change the size of the canvas for unknown reasons.
+ *
+ * @param c
+ */
+ public static void clearComponent(Component c) {
+ Graphics gc = c.getGraphics();
+ gc.clearRect(0, 0, c.getWidth(), c.getHeight());
+ gc.dispose();
+ }
+
+
+ /**
+ * A simple interface to the machine loop, generally of the form
+ * <code>
+ * public boolean stateLoop() {
+ * while (stateHepler.isAlive()) {
+ * switch (stateHelper.getState()) {
+ * case STATE_XXX:
+ * ...
+ * return stateHelper.delayState(100,STATE_YYY);
+ * case STATE_YYY:
+ * ...
+ * stateHelper.setState(STATE_ZZZ);
+ * continue;
+ * case STATE_ZZZ:
+ * ...
+ * return stateHelper.delayAction(100, MY_ID, "myCommand", myListener, STATE_XXX); *
+ * case STATE_DONE:
+ * ...
+ * stateHelper.interrupt();
+ * return false;
+ * }
+ * return true;
+ * }
+ * return false;
+ * }
+ * </code>
+ * @author hansonr
+ *
+ */
+ public interface StateMachine {
+
+ public boolean stateLoop();
+
+ }
+ /**
+ * StateHelper is a class that facilitates moving from an asychronous multithreaded model to a state-oriented model of programming
+ * for SwingJS animations and other asynchronous business.
+ *
+ * @author hansonr
+ *
+ */
+ public static class StateHelper {
+
+ public static final int UNCHANGED = Integer.MIN_VALUE;
+
+ private StateMachine machine;
+ private int state;
+ private int level;
+
+ private boolean interrupted;
+
+
+ public StateHelper(StateMachine machine) {
+ this.machine = machine;
+ }
+
+ public void interrupt() {
+ interrupted = true;
+ }
+
+ public boolean isInterrupted() {
+ return interrupted;
+ }
+
+ public boolean isAlive() {
+ return !interrupted;
+ }
+
+ public void restart() {
+ interrupted = false;
+ }
+
+ public void setState(int state) {
+ this.state = this.stateNext = state;
+ }
+
+ public int getState() {
+ return state;
+ }
+
+ public void setLevel(int level) {
+ this.level = this.levelNext = level;
+ }
+
+ public int getLevel() {
+ return level;
+ }
+
+ public void setNextState(int next) {
+ stateNext = next;
+ }
+
+ public int getNextState() {
+ return stateNext;
+ }
+
+ public int getNextLevel() {
+ return levelNext;
+ }
+
+ public void setNextLevel(int next) {
+ levelNext = next;
+ }
+
+ /**
+ *
+ * NOTE: this method must remain private; it is accessed via p$1
+ *
+ * @return
+ */
+ private boolean nextState() {
+ return next(stateNext, levelNext);
+ }
+ /**
+ * Set the state and run machine.stateLoop().
+ *
+ * @param state something meaningful to the machine
+ *
+ * @return not interrupted
+ *
+ * @author Bob Hanson hansonr@stolaf.edu
+ */
+ public boolean next(int state) {
+ return next(state, 0);
+ }
+
+ /**
+ * Set the state and level, and then run machine.stateLoop(). Driven directly or via delayedState or delayedAction
+ *
+ * @param state something meaningful to the machine
+ * @param level something meaningful to the machine
+ *
+ * @return not interrupted
+ *
+ * @author Bob Hanson hansonr@stolaf.edu
+ */
+ public boolean next(int state, int level) {
+ return nextStatePriv(this, state, level);
+ }
+
+ private static boolean nextStatePriv(Object oThis, int state, int level) {
+ StateHelper me = (StateHelper) oThis;
+ if (me.interrupted)
+ return false;
+ if (level != UNCHANGED)
+ me.level = level;
+ if (state != UNCHANGED)
+ me.state = state;
+ return me.machine.stateLoop();
+ }
+
+ /**
+ * After the given number of milliseseconds, set the new state and run the machines stateLoop with unchanged level
+ *
+ * @param ms the number of milliseconds to delay; 0 to execute synchronously *
+ * @param stateNext the next state to run
+ * @return not interrupted
+ *
+ * @author Bob Hanson hansonr@stolaf.edu
+ */
+ public boolean delayedState(int ms, int stateNext) {
+ return delayedState(ms, stateNext, level);
+ }
+
+ private Timer stateTimer;
+
+ private int stateNext;
+ private int levelNext;
+
+ /**
+ * After the given number of milliseseconds, set the new state and level, and
+ * run the machines stateLoop
+ *
+ * @param ms the number of milliseconds to delay; 0 to execute
+ * synchronously *
+ * @param stateNext the next state
+ * @param levelNext the next level
+ * @return not interrupted
+ *
+ * @author Bob Hanson hansonr@stolaf.edu
+ */
+
+ public boolean delayedState(int ms, int stateNext, int levelNext) {
+ if (interrupted)
+ return false;
+ if (ms == 0)
+ return next(stateNext, levelNext);
+ if (stateNext != UNCHANGED)
+ this.stateNext = stateNext;
+ if (levelNext != UNCHANGED)
+ this.levelNext = levelNext;
+
+ /**
+ * @j2sNative
+ * var me = this;
+ * setTimeout(function(){
+ * p$1.nextState.apply(me, []);
+ * },ms);
+ */
+ {
+ // Java only
+
+ if (stateTimer == null) {
+ stateTimer = new Timer(ms, new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ nextState();
+ }
+
+ });
+ stateTimer.setRepeats(false);
+ stateTimer.start();
+ } else {
+ stateTimer.restart();
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Fire an actionPerformed event after a given number of milliseconds
+ *
+ * @param ms delay milliseconds. if 0, then this action will be called
+ * synchronously
+ * @param id id for this event, possibly ACTION_PERFORMED (1001), but not
+ * necessarily
+ * @param command key for ActionEvent.getCommand()
+ * @param listener ActionListener to be called.
+ * @return not interrupted
+ *
+ * @author Bob Hanson hansonr@stolaf.edu
+ */
+ public boolean delayedAction(int ms, int id, String command, ActionListener listener) {
+ return delayedAction(ms, id, command, listener, UNCHANGED, UNCHANGED);
+ }
+
+ /**
+ * Fire an actionPerformed event after a given number of milliseconds
+ *
+ * @param ms delay milliseconds. if 0, then this action will be called
+ * synchronously
+ * @param id id for this event, possibly ACTION_PERFORMED (1001), but not
+ * necessarily
+ * @param command key for ActionEvent.getCommand()
+ * @param listener ActionListener to be called.
+ *
+ * @param state the next state to go to after this listener is called; UNCHANGED to let the listener take care of this.
+ *
+ * @return not interrupted
+ *
+ * @author Bob Hanson hansonr@stolaf.edu
+ */
+ public boolean delayedAction(int ms, int id, String command, ActionListener listener, int state) {
+ return delayedAction(ms, id, command, listener, state, UNCHANGED);
+ }
+
+ /**
+ * Fire an actionPerformed event after a given number of milliseconds. Setting BOTH stateNext and levelNext to UNCHANGED (Integer.MIN_VALUE)
+ * allows the listener to handle continuing the loop.
+ *
+ * @param ms delay milliseconds. if 0, then this action will be called
+ * synchronously
+ * @param id id for this event, possibly ACTION_PERFORMED (1001), but not
+ * necessarily
+ * @param command key for ActionEvent.getCommand()
+ * @param listener ActionListener to be called.
+ * @param stateNext state to run after the event is processed by the listener, or UNCHANGED (Integer.MIN_VALUE) to allow listener to handle this.
+ * @param levelNext level to run after the event is processed by the listener, or UNCHANGED (Integer.MIN_VALUE) to allow listener to handle this.
+ * @return not interrupted
+ *
+ * @author Bob Hanson hansonr@stolaf.edu
+ */
+ public boolean delayedAction(int ms, int id, String command, ActionListener listener, int stateNext, int levelNext) {
+ if (interrupted)
+ return false;
+ ActionEvent event = new ActionEvent(this, id, command);
+ if (ms == 0) {
+ listener.actionPerformed(event);
+ return (stateNext == UNCHANGED && levelNext == UNCHANGED || nextStatePriv(this, stateNext == UNCHANGED ? state : stateNext, levelNext == UNCHANGED ? level : levelNext));
+ }
+
+ StateHelper me = this;
+
+ Timer timer = new Timer(ms, id == ActionEvent.ACTION_PERFORMED ? listener : new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ if (!interrupted)
+ listener.actionPerformed(event);
+ if (!interrupted && (stateNext != UNCHANGED || levelNext != UNCHANGED))
+ nextStatePriv(me, stateNext == UNCHANGED ? state : stateNext, levelNext == UNCHANGED ? level : levelNext);
+ }
+
+ });
+ timer.setRepeats(false);
+ timer.start();
+ return true;
+ }
+
+ public static void delayedRun(int ms, Runnable runnable) {
+ new StateHelper(null).delayedRun(ms, runnable, UNCHANGED, UNCHANGED);
+ }
+
+
+ /**
+ * Fire an actionPerformed event after a given number of milliseconds. Setting
+ * BOTH stateNext and levelNext to UNCHANGED (Integer.MIN_VALUE) allows the
+ * listener to handle continuing the loop.
+ *
+ * @param ms delay milliseconds. if 0, then this action will be called
+ * synchronously
+ * @param id id for this event, possibly ACTION_PERFORMED (1001), but not
+ * necessarily
+ * @param command key for ActionEvent.getCommand()
+ * @param listener ActionListener to be called.
+ * @param stateNext state to run after the event is processed by the listener,
+ * or UNCHANGED (Integer.MIN_VALUE) to allow listener to handle
+ * this.
+ * @param levelNext level to run after the event is processed by the listener,
+ * or UNCHANGED (Integer.MIN_VALUE) to allow listener to handle
+ * this.
+ * @return not interrupted
+ *
+ * @author Bob Hanson hansonr@stolaf.edu
+ */
+ public boolean delayedRun(int ms, Runnable runnable, int stateNext, int levelNext) {
+ if (interrupted)
+ return false;
+ if (ms == 0) {
+ return (stateNext == UNCHANGED && levelNext == UNCHANGED || nextStateIfUnchanged(this, runnable,
+ stateNext == UNCHANGED ? state : stateNext, levelNext == UNCHANGED ? level : levelNext));
+ }
+ StateHelper me = this;
+ /**
+ * @j2sNative
+ *
+ * setTimeout(function() {
+ *
+ * me.nextStateIfUnchanged$O$O$I$I.apply(me, [me, runnable, stateNext, levelNext]);
+ *
+ * },ms);
+ */
+ {
+ Timer timer = new Timer(ms, new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ nextStateIfUnchanged(me, runnable, stateNext, levelNext);
+ }
+
+ });
+ timer.setRepeats(false);
+ timer.start();
+ }
+ return true;
+ }
+
+ protected boolean nextStateIfUnchanged(Object oThis, Object runnable, int stateNext, int levelNext) {
+ StateHelper me = (StateHelper)(oThis);
+ if (!me.interrupted)
+ ((Runnable) runnable).run();
+ if (!me.interrupted && (stateNext != UNCHANGED || levelNext != UNCHANGED))
+ nextStatePriv(oThis, stateNext == UNCHANGED ? me.state : stateNext,
+ levelNext == UNCHANGED ? me.level : levelNext);
+ return true;
+ }
+
+ /**
+ * sleep and then execute the next state
+ * @param ms
+ */
+ public void sleep(int ms) {
+ int next = stateNext;
+ delayedState(ms, next);
+ }
+ }
+
+ /**
+ * open a "url-like" input stream
+ * @param base
+ * @param fileName
+ * @return
+ */
+ public static BufferedInputStream openStream(Class<?> base, String fileName) {
+ String s = (String) getResource(base, fileName, String.class);
+ return new BufferedInputStream(new ByteArrayInputStream(s.getBytes()));
+ }
+
+
+ public static class Performance {
+
+ public final static int TIME_RESET = 0;
+
+ public final static int TIME_MARK = 1;
+
+ public static final int TIME_SET = 2;
+
+ public static final int TIME_GET = 3;
+
+ public static long time, mark, set, duration;
+
+ /**
+ * typical usage:
+ *
+ * Performance.timeCheck(null, Platform.TIME_MARK);
+ *
+ * ...
+ *
+ * Performance.timeCheck("some message", Platform.TIME_MARK);
+ *
+ * reset...[set/mark]n...get (total time) (time spent between set and mark)
+ *
+ * set...get (total time) (time spent between set and get)
+ *
+ * long t0 = now(0); ........ ; dt = now(t0); (time since t0)e
+ *
+ * @param msg
+ * @param mode
+ */
+ public static void timeCheck(String msg, int mode) {
+ msg = timeCheckStr(msg, mode);
+ if (msg != null)
+ System.err.println(msg);
+ }
+
+ public static long now(long t) {
+ return System.currentTimeMillis() - t;
+ }
+
+ public static String timeCheckStr(String msg, int mode) {
+ long t = System.currentTimeMillis();
+ switch (mode) {
+ case TIME_RESET:
+ time = mark = t;
+ duration = set = 0;
+ if (msg != null) {
+ return ("Platform: timer reset\t\t\t" + msg);
+ }
+ break;
+ case TIME_SET:
+ if (time == 0)
+ time = t;
+ set = t;
+ break;
+ case TIME_MARK:
+ if (set > 0) {
+ // total time between set/mark points
+ duration += (t - set);
+ } else {
+ if (time == 0) {
+ time = mark = t;
+ }
+ if (msg != null) {
+ long m0 = mark;
+ mark = t;
+ return ("Platform: timer mark\t" + ((t - time) / 1000f) + "\t" + ((t - m0) / 1000f) + "\t"
+ + msg);
+ }
+ mark = t;
+ }
+ break;
+ case TIME_GET:
+ if (msg != null) {
+ if (mark < set)
+ duration = t - set;
+ return ("Platform: timer get\t" + ((t - time) / 1000f) + "\t" + ((duration) / 1000f) + "\t" + msg);
+ }
+ set = 0;
+ break;
+ }
+ return null;
+ }
+
+ }
+
+}
\ No newline at end of file
import java.io.IOException;
import java.io.StringWriter;
import java.io.Writer;
-import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
--- /dev/null
+/* $RCSfile$
+ * $Author$
+ * $Date$
+ * $Revision$
+ *
+ * Some portions of this file have been modified by Robert Hanson hansonr.at.stolaf.edu 2012-2017
+ * for use in SwingJS via transpilation into JavaScript using Java2Script.
+ *
+ * Copyright (C) 2006 The Jmol Development Team
+ *
+ * Contact: jmol-developers@lists.sf.net
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+package swingjs.api;
+
+public class Interface {
+
+ private static String instances="";
+
+ public static Object getInstanceWithParams(String name, Class<?>[] classes, Object... params) {
+ try {
+ Class<?> cl = Class.forName(name);
+ return cl.getConstructor(classes).newInstance(params);
+ } catch (Exception e) {
+ return null;
+ }
+ }
+ public static Object getInstance(String name, boolean isQuiet) {
+ Object x = null;
+ /**
+ * @j2sNative
+ *
+ * Clazz._isQuietLoad = isQuiet;
+ */
+ {}
+ try {
+ if (!isQuiet && instances.indexOf(name + ";") <= 0) {
+ System.out.println("swingjs.api.Interface creating instance of " + name);
+ instances += name + ";";
+ }
+ Class<?> y = Class.forName(name);
+ if (y != null)
+ x = y.newInstance();
+ } catch (Throwable e) {
+ System.out.println("Swingjs.api.Interface Error creating instance for " + name + ": \n" + e);
+ /**
+ * @j2sNative
+ *
+ * if (e.stack)System.out.println(e.stack);
+ */
+ {}
+ } finally {
+ /**
+ * @j2sNative
+ *
+ * Clazz._isQuietLoad = false;
+ */
+ {}
+ }
+ return x;
+ }
+
+}
--- /dev/null
+package swingjs.api;
+
+public interface JSFileHandler {
+
+ void handleFileLoaded(Object data, String fileName);
+
+}
import java.awt.Component;
import java.io.File;
+import java.io.IOException;
import java.io.InputStream;
+import java.io.OutputStream;
import java.net.URL;
import java.util.HashMap;
+import java.util.Map;
import java.util.Properties;
+import java.util.function.Function;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipInputStream;
+
+import javax.swing.JComponent;
import swingjs.api.js.HTML5Applet;
public interface JSUtilI {
- /**
- * Indicate to SwingJS that the given file type is binary.
- *
- * @param ext
- */
- void addBinaryFileType(String ext);
-
- /**
- * Indicate to SwingJS that we can load files using AJAX from the given
- * domain, such as "www.stolaf.edu", because we know that CORS access has been
- * provided.
- *
- * @param domain
- */
- void addDirectDatabaseCall(String domain);
-
- /**
- * Cache or uncache data under the given path name.
- *
- * @param path
- * @param data
- * null to remove from the cache
- */
- void cachePathData(String path, Object data);
-
- /**
- * Get the HTML5 object corresponding to the specified Component, or the
- * current thread if null.
- *
- * @param c
- * the associated component, or null for the current thread
- * @return HTML5 applet object
- */
- HTML5Applet getAppletForComponent(Component c);
-
- /**
- * Get an attribute applet.foo for the applet found using getApplet(null).
- *
- * @param key
- * @return
- */
- Object getAppletAttribute(String key);
-
- /**
- * Get the code base (swingjs/j2s, probably) for the applet found using
- * getApplet(null).
- *
- * @return
- */
- URL getCodeBase();
-
- /**
- * Get the document base (wherever the page is) for the applet found using
- * getApplet(null).
- *
- * @return
- */
-
- URL getDocumentBase();
-
- /**
- * Get an attribute from the div on the page that is associated with this
- * frame, i.e. with id frame.getName() + "-div".
- *
- * @param frame
- * @param type
- * "node" or "dim"
- * @return
- */
- Object getEmbeddedAttribute(Component frame, String type);
-
- /**
- * Get a file synchronously.
- *
- * @param path
- * @param asString
- * true for String; false for byte[]
- * @return byte[] or String
- */
- Object getFile(String path, boolean asString);
-
- /**
- * Get the 秘bytes field associated with a file, but only if the File object
- * itself has them attached, not downloading them.
- *
- * @param f
- * @return
- */
- byte[] getBytes(File f);
-
- /**
- * Retrieve a HashMap consisting of whatever the application wants, but
- * guaranteed to be unique to this app context, that is, for the applet found
- * using getApplet(null).
- *
- * @param contextKey
- * @return
- */
- HashMap<?, ?> getJSContext(Object contextKey);
-
- /**
- * Load a resource -- probably a core file -- if and only if a particular
- * class has not been instantialized. We use a String here because if we used
- * a .class object, that reference itself would simply load the class, and we
- * want the core package to include that as well.
- *
- * @param resourcePath
- * @param className
- */
- void loadResourceIfClassUnknown(String resource, String className);
-
- /**
- * Read all applet.__Info properties for the applet found using
- * getApplet(null) that start with the given prefix, such as "jalview_". A
- * null prefix retrieves all properties. Note that non-string properties will
- * be stringified.
- *
- * @param prefix
- * an application prefix, or null for all properties
- * @param p
- * properties to be appended to
- */
- void readInfoProperties(String prefix, Properties p);
-
- /**
- * Set an attribute for the applet found using getApplet(null). That is,
- * applet[key] = val.
- *
- * @param key
- * @param val
- */
- void setAppletAttribute(String key, Object val);
-
- /**
- * Set an attribute of applet's Info map for the applet found using
- * getApplet(null). That is, applet.__Info[key] = val.
- *
- * @param infoKey
- * @param val
- */
- void setAppletInfo(String infoKey, Object val);
-
- /**
- * Set the given File object's 秘bytes field from an InputStream or a byte[]
- * array. If the file is a JSTempFile, then also cache those bytes.
- *
- * @param f
- * @param isOrBytes
- * BufferedInputStream, ByteArrayInputStream, FileInputStream, or
- * byte[]
- * @return
- */
- boolean setFileBytes(File f, Object isOrBytes);
-
- /**
- * Same as setFileBytes, but also caches the data if it is a JSTempFile.
- *
- * @param is
- * @param outFile
- * @return
- */
- boolean streamToFile(InputStream is, File outFile);
-
- /**
- * Switch the flag in SwingJS to use or not use the JavaScript Map object in
- * Hashtable, HashMap, and HashSet. Default is enabled.
- *
- */
-
- void setJavaScriptMapObjectEnabled(boolean enabled);
+ /**
+ * The HTML5 canvas delivers [r g b a r g b a ...] which is not a Java option.
+ * The closest Java option is TYPE_4BYTE_ABGR, but that is not quite what we
+ * need. SwingJS decodes TYPE_4BYTE_HTML5 as TYPE_4BYTE_RGBA"
+ *
+ * ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_sRGB);
+ *
+ * int[] nBits = { 8, 8, 8, 8 };
+ *
+ * int[] bOffs = { 0, 1, 2, 3 };
+ *
+ * colorModel = new ComponentColorModel(cs, nBits, true, false,
+ * Transparency.TRANSLUCENT, DataBuffer.TYPE_BYTE);
+ *
+ * raster = Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE, width, height,
+ * width * 4, 4, bOffs, null);
+ *
+ * Note, however, that this buffer type should only be used for direct buffer access
+ * using
+ *
+ *
+ *
+ */
+ public static final int TYPE_4BYTE_HTML5 = -6;
+
+ /**
+ * The HTML5 VIDEO element wrapped in a BufferedImage.
+ *
+ * To be extended to allow video capture?
+ */
+ public static final int TYPE_HTML5_VIDEO = Integer.MIN_VALUE;
+
+ /**
+ * Indicate to SwingJS that the given file type is binary.
+ *
+ * @param ext
+ */
+ void addBinaryFileType(String ext);
+
+ /**
+ * Indicate to SwingJS that we can load files using AJAX from the given domain,
+ * such as "www.stolaf.edu", because we know that CORS access has been provided.
+ *
+ * @param domain
+ */
+ void addDirectDatabaseCall(String domain);
+
+ /**
+ * Cache or uncache data under the given path name.
+ *
+ * @param path
+ * @param data null to remove from the cache
+ */
+ void cachePathData(String path, Object data);
+
+ /**
+ * Get the HTML5 object corresponding to the specified Component, or the current thread if null.
+ *
+ * @param c the associated component, or null for the current thread
+ * @return HTML5 applet object
+ */
+ HTML5Applet getAppletForComponent(Component c);
+
+ /**
+ * Get an attribute applet.foo for the applet found using getApplet(null).
+ *
+ * @param key
+ * @return
+ */
+ Object getAppletAttribute(String key);
+
+
+ /**
+ * Get the applet's __Info map or an attribute of that map for the applet found using
+ * getApplet(null). That is, applet.__Info or applet.__Info[InfoKey].
+ *
+ * @param infoKey if null, return the full __Info map
+ */
+ Object getAppletInfo(String infoKey);
+
+ /**
+ * Get the code base (swingjs/j2s, probably) for the applet found using
+ * getApplet(null).
+ *
+ * @return
+ */
+ URL getCodeBase();
+
+ /**
+ * Get the document base (wherever the page is) for the applet found using
+ * getApplet(null).
+ *
+ * @return
+ */
+
+ URL getDocumentBase();
+
+ /**
+ * Get an attribute from the div on the page that is associated with this frame,
+ * i.e. with id frame.getName() + "-div".
+ *
+ * @param frame
+ * @param type "node" or "dim"
+ * @return
+ */
+ Object getEmbeddedAttribute(Component frame, String type);
+
+ /**
+ * Get a file synchronously.
+ *
+ * @param path
+ * @param asString true for String; false for byte[]
+ * @return byte[] or String
+ */
+ Object getFile(String path, boolean asString);
+
+ /**
+ * Get the 秘bytes field associated with a file, but only if the File object itself has
+ * them attached, not downloading them.
+ *
+ * @param f
+ * @return
+ */
+ byte[] getBytes(File f);
+
+ /**
+ * Retrieve a HashMap consisting of whatever the application wants, but
+ * guaranteed to be unique to this app context, that is, for the applet found using
+ * getApplet(null).
+ *
+ * @param contextKey
+ * @return
+ */
+ HashMap<?, ?> getJSContext(Object contextKey);
+
+ /**
+ * Load a resource -- probably a core file -- if and only if a particular class
+ * has not been instantialized. We use a String here because if we used a .class
+ * object, that reference itself would simply load the class, and we want the
+ * core package to include that as well.
+ *
+ * @param resourcePath
+ * @param className
+ */
+ void loadResourceIfClassUnknown(String resource, String className);
+
+ /**
+ * Read all applet.__Info properties for the applet found using
+ * getApplet(null) that start with the given prefix, such as "jalview_".
+ * A null prefix retrieves all properties. Note that non-string properties will be
+ * stringified.
+ *
+ * @param prefix an application prefix, or null for all properties
+ * @param p properties to be appended to
+ */
+ void readInfoProperties(String prefix, Properties p);
+
+ /**
+ * Set an attribute for the applet found using
+ * getApplet(null). That is, applet[key] = val.
+ *
+ * @param key
+ * @param val
+ */
+ void setAppletAttribute(String key, Object val);
+
+ /**
+ * Set an attribute of applet's Info map for the applet found using
+ * getApplet(null). That is, applet.__Info[key] = val.
+ *
+ * @param infoKey
+ * @param val
+ */
+ void setAppletInfo(String infoKey, Object val);
+
+ /**
+ * Set the given File object's 秘bytes field from an InputStream or a byte[] array.
+ * If the file is a JSTempFile, then also cache those bytes.
+ *
+ * @param f
+ * @param isOrBytes BufferedInputStream, ByteArrayInputStream, FileInputStream, or byte[]
+ * @return
+ */
+ boolean setFileBytes(File f, Object isOrBytes);
+
+ /**
+ * Set the given URL object's _streamData field from an InputStream or a byte[] array.
+ *
+ * @param f
+ * @param isOrBytes BufferedInputStream, ByteArrayInputStream, FileInputStream, or byte[]
+ * @return
+ */
+ boolean setURLBytes(URL url, Object isOrBytes);
+
+ /**
+ * Same as setFileBytes.
+ *
+ * @param is
+ * @param outFile
+ * @return
+ */
+ boolean streamToFile(InputStream is, File outFile);
+
+ /**
+ * Switch the flag in SwingJS to use or not use the JavaScript Map object in
+ * Hashtable, HashMap, and HashSet. Default is enabled.
+ * *
+ */
+ void setJavaScriptMapObjectEnabled(boolean enabled);
+
+
+ /**
+ * Open a URL in a browser tab.
+ *
+ * @param url
+ * @param target null or specific tab, such as "_blank"
+ */
+ void displayURL(String url, String target);
+
+ /**
+ * Retrieve cached bytes for a path (with unnormalized name)
+ * from J2S._javaFileCache.
+ *
+ * @param path
+ *
+ * @return byte[] or null
+ */
+ byte[] getCachedBytes(String path);
+
+ /**
+ * Attach cached bytes to a file-like object, including URL,
+ * or anything having a 秘bytes field (File, URI, Path)
+ * from J2S._javaFileCache. That is, allow two such objects
+ * to share the same underlying byte[ ] array.
+ *
+ *
+ * @param URLorURIorFile
+ * @return byte[] or null
+ */
+ byte[] addJSCachedBytes(Object URLorURIorFile);
+
+ /**
+ * Seek an open ZipInputStream to the supplied ZipEntry, if possible.
+ *
+ * @param zis the ZipInputStream
+ * @param ze the ZipEntry
+ * @return the length of this entry, or -1 if, for whatever reason, this was not possible
+ */
+ long seekZipEntry(ZipInputStream zis, ZipEntry ze);
+
+ /**
+ * Retrieve the byte array associated with a ZipEntry.
+ *
+ * @param ze
+ * @return
+ */
+ byte[] getZipBytes(ZipEntry ze);
+
+ /**
+ * Java 9 method to read all (remaining) bytes from an InputStream. In SwingJS,
+ * this may just create a new reference to an underlying Int8Array without
+ * copying it.
+ *
+ * @param zis
+ * @return
+ * @throws IOException
+ */
+ byte[] readAllBytes(InputStream zis) throws IOException;
+
+ /**
+ * Java 9 method to transfer all (remaining) bytes from an InputStream to an OutputStream.
+ *
+ * @param is
+ * @param out
+ * @return
+ * @throws IOException
+ */
+ long transferTo(InputStream is, OutputStream out) throws IOException;
+
+ /**
+ * Retrieve any bytes already attached to this URL.
+ *
+ * @param url
+ * @return
+ */
+ byte[] getURLBytes(URL url);
+
+ /**
+ * Set a message in the lower-left-hand corner SwingJS status block.
+ *
+ * @param msg
+ * @param doFadeOut
+ */
+ void showStatus(String msg, boolean doFadeOut);
+
+ /**
+ * Asynchronously retrieve the byte[] for a URL.
+ *
+ * @param url
+ * @param whenDone
+ */
+ void getURLBytesAsync(URL url, Function<byte[], Void> whenDone);
+
+ /**
+ * Experimental method to completely disable a Swing Component's user interface.
+ *
+ * @param jc
+ * @param enabled
+ */
+ void setUIEnabled(JComponent jc, boolean enabled);
+
+
+ /**
+ * Play an audio
+ * @param buffer
+ * @param format a javax.sound.sampled.AudioFormat
+ * @throws Exception
+ */
+ void playAudio(byte[] buffer, Object format) throws Exception;
+
+ /**
+ * For either an applet or an application, get the ORIGINAL __Info as a Map that
+ * has a full set up lower-case keys along with whatever non-all-lower-case keys
+ * provided at start-up.
+ *
+ * @return
+ */
+ Map<String, Object> getAppletInfoAsMap();
+
+
+ void setAppClass(Object j);
}
--- /dev/null
+package swingjs.api.js;
+
+import java.awt.Dimension;
+import java.awt.Rectangle;
+
+/**
+ * A mix of direct DOM calls on DOM nodes and convenience methods to do that.
+ *
+ * NOTE: DO NOT OVERLOAD THESE METHODS, as this package will not be qualified.
+ *
+ * @author hansonr
+ *
+ */
+public interface DOMNode {
+
+ public static JQuery jQuery = /** @j2sNative jQuery.$ || (jQuery.$ = jQuery) || */null;
+
+ // "abstract" in the sense that these are the exact calls to JavaScript
+
+
+ public void addEventListener(String event, Object listener);
+ public void removeEventListener(String event);
+ public void removeEventListener(String event, Object listener);
+
+
+
+ public String[] getAttributeNames();
+
+ public String getAttribute(String name);
+
+ public void setAttribute(String attr, String val);
+
+ public void appendChild(DOMNode node);
+
+ public void prepend(DOMNode node);
+
+ public void insertBefore(DOMNode node, DOMNode refNode);
+
+ public DOMNode removeChild(DOMNode node);
+
+ public void focus();
+ public boolean hasFocus();
+ public void blur();
+
+ public DOMNode removeAttribute(String attr);
+
+ public void setSelectionRange(int start, int end, String direction);
+
+ public Rectangle getBoundingClientRect();
+
+ // static convenience methods
+
+ public static DOMNode createElement(String key, String id) {
+ DOMNode node = null;
+ /**
+ * @j2sNative
+ * node = document.createElement(key);
+ * id && (node.id = id);
+ */
+ return node;
+ }
+
+ public static DOMNode getElement(String id) {
+ return (/** @j2sNative document.getElementById(id) ||*/ null);
+ }
+
+ public static DOMNode createTextNode(String text) {
+ return (/** @j2sNative document.createTextNode(text) || */ null);
+ }
+
+ public static DOMNode getParent(DOMNode node) {
+ return (/** @j2sNative node.parentNode ||*/ null);
+ }
+
+ public static DOMNode getPreviousSibling(DOMNode node) {
+ return (/** @j2sNative node.previousSibling ||*/ null);
+ }
+
+ public static DOMNode firstChild(DOMNode node) {
+ return (/** @j2sNative node.firstChild ||*/ null);
+ }
+
+ public static DOMNode lastChild(DOMNode node) {
+ return (/** @j2sNative node.lastChild ||*/ null);
+ }
+
+ public static DOMNode setZ(DOMNode node, int z) {
+ return setStyles(node, "z-index", "" + z);
+ }
+
+ public static Object getAttr(Object node, String attr) {
+ /**
+ * @j2sNative
+ *
+ * if (!node)
+ * return null;
+ * var a = node[attr];
+ * return (typeof a == "undefined" ? null : a);
+ */
+ {
+ return null;
+ }
+ }
+
+ public static int getAttrInt(DOMNode node, String attr) {
+ return (/** @j2sNative node && node[attr] ||*/ 0);
+ }
+
+ public static String getStyle(DOMNode node, String style) {
+ return (/** @j2sNative node && node.style[style] ||*/ null);
+ }
+
+ public static void getCSSRectangle(DOMNode node, Rectangle r) {
+ /**
+ * @j2sNative
+ *
+ * r.x = parseInt(node.style.left.split("p")[0]);
+ * r.y = parseInt(node.style.top.split("p")[0]);
+ * r.width = parseInt(node.style.width.split("p")[0]);
+ * r.height = parseInt(node.style.height.split("p")[0]);
+ *
+ */
+ }
+
+ public static DOMNode setAttr(DOMNode node, String attr, Object val) {
+ /**
+ * @j2sNative
+ *
+ * attr && (node[attr] = (val == "秘TRUE" ? true : val == "秘FALSE" ? false : val));
+ *
+ */
+ return node;
+ }
+
+
+ public static void setAttrInt(DOMNode node, String attr, int val) {
+ /**
+ * @j2sNative
+ *
+ * node[attr] = val;
+ *
+ */
+ }
+
+
+ /**
+ * allows for null key to be skipped (used in audio)
+ *
+ * @param node
+ * @param attr
+ * @return
+ */
+ public static DOMNode setAttrs(DOMNode node, Object... attr) {
+ /**
+ * @j2sNative
+ *
+ * for (var i = 0; i < attr.length;) {
+ * C$.setAttr(node, attr[i++],attr[i++]);
+ * }
+ */
+ return node;
+ }
+
+ public static DOMNode setStyles(DOMNode node, String... attr) {
+ /**
+ * @j2sNative
+ *
+ * if (node) for (var i = 0; i < attr.length;) {
+ * node.style[attr[i++]] = attr[i++];
+ * }
+ *
+ */
+ return node;
+ }
+
+ public static DOMNode setSize(DOMNode node, int width, int height) {
+ return setStyles(node, "width", width + "px", "height", height + "px");
+ }
+
+ public static DOMNode setPositionAbsolute(DOMNode node) {
+ return DOMNode.setStyles(node, "position", "absolute");
+ }
+
+ public static void setVisible(DOMNode node, boolean visible) {
+ setStyles(node, "display", visible ? "block" : "none");
+ }
+
+ public static DOMNode setTopLeftAbsolute(DOMNode node, int top, int left) {
+ DOMNode.setStyles(node, "top", top + "px");
+ DOMNode.setStyles(node, "left", left + "px");
+ return DOMNode.setStyles(node, "position", "absolute");
+ }
+
+ public static void addHorizontalGap(DOMNode domNode, int gap) {
+ DOMNode label = DOMNode.setStyles(DOMNode.createElement("label", null),
+ "letter-spacing", gap + "px", "font-size", "0pt");
+ label.appendChild(DOMNode.createTextNode("."));
+ domNode.appendChild(label);
+ }
+
+ public static void appendChildSafely(DOMNode parent, DOMNode node) {
+ /**
+ * @j2sNative
+ * if (!parent || node.parentElement == parent)
+ * return;
+ */
+ parent.appendChild(node);
+ }
+
+ // static jQuery calls
+
+ /**
+ * jQuery height()
+ *
+ * @param node
+ * @return height
+ */
+ public static int getHeight(DOMNode node) {
+ return jQuery.$(node).height();
+ }
+
+ /**
+ * jQuery width()
+ *
+ * @param node
+ * @return width
+ */
+ public static int getWidth(DOMNode node) {
+ return jQuery.$(node).width();
+ }
+
+ /**
+ * jQuery remove()
+ *
+ * Remove this node and return its parent. Automatically removing all events
+ * attached to it.
+ *
+ * @param node
+ * @return parent or null
+ */
+ public static void dispose(DOMNode node) {
+ if (node != null)
+ jQuery.$(node).remove();
+ }
+
+ /**
+ * Just remove the node, keeping its events and data
+ * @param node
+ */
+ public static void remove(DOMNode node) {
+
+ // NOTE: IE does not have node.remove()
+
+ DOMNode p = getParent(node);
+ if (p != null)
+ p.removeChild(node);
+ }
+
+ /**
+ * just detaches all the nodes; doesn't remove their listeners
+ * @param node
+ */
+ public static void detachAll(DOMNode node) {
+ /**
+ * @j2sNative
+ * if(node)
+ * while(node.lastChild)
+ * node.removeChild(node.lastChild);
+ */
+ }
+
+ /**
+ * jQuery detach() + append()
+ *
+ * @param node
+ * @param container
+ * @return parent if container is null, or container if it is not null
+ */
+ public static DOMNode transferTo(DOMNode node, DOMNode container) {
+ if (node == null)
+ return null;
+ DOMNode p = getParent(node);
+ try {
+ if (p != null)
+ jQuery.$(node).detach();
+ } catch (Throwable e) {
+ // ignore
+ }
+ if (container == null)
+ return p;
+ jQuery.$(container).append(node);
+ return container;
+ }
+
+ public static Object getEmbedded(String name, String type) {
+ DOMNode node = DOMNode.getElement(name + "-div");
+ if (node == null)
+ return null;
+ switch (type) {
+ case "node":
+ return node;
+ case "dim":
+ return new Dimension(DOMNode.getWidth(node), DOMNode.getHeight(node));
+ default:
+ return DOMNode.getAttr(node, type);
+ }
+ }
+
+}
--- /dev/null
+package swingjs.api.js;
+
+public interface HTML5AudioContext {
+
+ // https://developer.mozilla.org/en-US/docs/Web/API/AudioContext
+ // https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API/Using_Web_Audio_API
+
+ void close();
+
+ float[] createBuffer(int nChannels, int frameCount, int sampleRate);
+
+ void createBufferSource();
+
+ void createMediaElementSource();
+
+ void createMediaStreamSource();
+
+ void createMediaStreamDestination();
+
+ void createScriptProcessor();
+
+ //void createStereoPanner();
+
+ void createAnalyser();
+
+ void createBiquadFilter();
+
+ void createChannelMerger();
+
+ void createChannelSplitter();
+
+ void createConvolver();
+
+ void createDelay();
+
+ void createDynamicsCompressor();
+
+ void createGain();
+
+ void createIIRFilter();
+
+ void createOscillator();
+
+ void createPanner();
+
+ void createPeriodicWave();
+
+ void createWaveShaper();
+
+ void createAudioWorker();
+
+ void decodeAudioData();
+
+ void resume();
+
+ void suspend();
+
+}
--- /dev/null
+package swingjs.api.js;
+
+import java.awt.image.BufferedImage;
+
+public interface HTML5Canvas extends DOMNode {
+
+ HTML5CanvasContext2D getContext(String str2d);
+
+ /*
+ * Retrieves the byte[] data buffer from an HTML5 CANVAS element, optionally
+ * first setting its contents to a source IMG, CANVAS, or VIDEO element.
+ *
+ */
+ static byte[] getDataBufferBytes(HTML5Canvas canvas, DOMNode sourceNode, int w, int h) {
+ if (sourceNode != null) {
+ DOMNode.setAttrInt(canvas, "width", w);
+ DOMNode.setAttrInt(canvas, "height", h);
+ }
+ HTML5CanvasContext2D ctx = canvas.getContext("2d");
+ if (sourceNode != null) {
+ ctx.drawImage(sourceNode, 0, 0, w, h);
+ }
+ // Coerse int[] to byte[]
+ return (byte[]) (Object) ctx.getImageData(0, 0, w, h).data;
+ }
+
+ /**
+ * Install a source image (img, video, or canvas) into a matching BufferedImage
+ *
+ * @param sourceNode
+ * @param image
+ */
+ static void setImageNode(DOMNode sourceNode, BufferedImage image) {
+ /**
+ * @j2sNative
+ *
+ * image._setImageNode$O$Z(sourceNode, false);
+ *
+ */ {
+ // image._setImageNode(sourceNode, false);
+ }
+ }
+
+
+
+ static HTML5Canvas createCanvas(int width, int height, String id) {
+ HTML5Canvas canvas = (HTML5Canvas) DOMNode.createElement("canvas", (id == null ? "img" + Math.random() : id + ""));
+ DOMNode.setStyles(canvas, "width", width + "px", "height", height + "px");
+ /**
+ * @j2sNative
+ *
+ * canvas.width = width;
+ * canvas.height = height;
+ *
+ */
+ return canvas;
+ }
+
+}
--- /dev/null
+package swingjs.api.js;
+
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Point2D.Float;
+
+public abstract class HTML5CanvasContext2D {
+
+ public class ImageData {
+ public int[] data;
+ }
+
+ public ImageData imageData;
+
+ public Object[][] _aSaved;
+
+ public double lineWidth;
+
+ public String font, fillStyle, strokeStyle;
+
+ public float globalAlpha;
+
+ public abstract void drawImage(DOMNode img, double sx,
+ double sy, double swidth, double sheight, double dx, double dy, double width, double height);
+
+ public abstract ImageData getImageData(int x, int y, int width, int height);
+
+ public abstract void beginPath();
+
+ public abstract void moveTo(double x0, double y0);
+
+ public abstract void lineTo(double x1, double y1);
+
+ public abstract void stroke();
+
+ public abstract void save();
+
+ public abstract void scale(double f, double g);
+
+ public abstract void arc(double centerX, double centerY, double radius, double startAngle, double endAngle, boolean counterclockwise);
+
+ public abstract void closePath();
+
+ public abstract void restore();
+
+ public abstract void translate(double x, double y);
+
+ public abstract void rotate(double radians);
+
+ public abstract void fill();
+
+
+ public abstract void fill(String winding);
+
+ public abstract void rect(double x, double y, double width, double height);
+
+ public abstract void fillText(String s, double x, double y);
+
+ public abstract void fillRect(double x, double y, double width, double height);
+
+ public abstract void clearRect(double i, double j, double windowWidth, double windowHeight);
+
+ public abstract void setLineDash(int[] dash);
+
+ public abstract void clip();
+
+ public abstract void quadraticCurveTo(double d, double e, double f, double g);
+
+ public abstract void bezierCurveTo(double d, double e, double f, double g, double h, double i);
+
+ public abstract void drawImage(DOMNode img, double x, double y, double width, double height);
+
+ public abstract void putImageData(Object imageData, double x, double y);
+
+ public abstract void transform(double d, double shx, double e, double shy, double f, double g);
+
+
+ /**
+ * pull one save structure onto the stack array ctx._aSaved
+ *
+ * @param ctx
+ * @return the length of the stack array after the push
+ */
+ public static int push(HTML5CanvasContext2D ctx, Object[] map) {
+ /**
+ * @j2sNative
+ *
+ * (ctx._aSaved || (ctx._aSaved = [])).push(map);
+ * return ctx._aSaved.length;
+ */
+ {
+ return 0;
+ }
+ }
+
+ /**
+ * pull one save structure off the stack array ctx._aSaved
+ *
+ * @param ctx
+ * @return
+ */
+ public static Object[] pop(HTML5CanvasContext2D ctx) {
+ /**
+ * @j2sNative
+ *
+ * return (ctx._aSaved && ctx._aSaved.length > 0 ? ctx._aSaved.pop() : null);
+ */
+ {
+ return null;
+ }
+ }
+
+ public static int getSavedLevel(HTML5CanvasContext2D ctx) {
+ /**
+ * @j2sNative
+ *
+ * return (ctx._aSaved ? ctx._aSaved.length : 0);
+ */
+ {
+ return 0;
+ }
+ }
+
+ public static Object[][] getSavedStack(HTML5CanvasContext2D ctx) {
+ /**
+ * @j2sNative
+ *
+ * return (ctx._aSaved || []);
+ */
+ {
+ return null;
+ }
+
+ }
+
+ public static double[] setMatrix(HTML5CanvasContext2D ctx, AffineTransform transform) {
+ double[] m = /** @j2sNative ctx._m || */ null;
+ if (transform == null) {
+ /** @j2sNative ctx._m = null; */
+ return null;
+ }
+ if (m == null) {
+ /**
+ * @j2sNative
+ * ctx._m = m = new Array(6);
+ */
+ transform.getMatrix(m);
+ }
+ return m;
+ }
+
+ public static void createLinearGradient(HTML5CanvasContext2D ctx, Float p1, Float p2, String css1, String css2) {
+ /**
+ * @j2sNative
+ *
+ * var grd = ctx.createLinearGradient(p1.x, p1.y, p2.x, p2.y);
+ * grd.addColorStop(0,css1);
+ * grd.addColorStop(1,css2);
+ * ctx.fillStyle = grd;
+ */
+ }
+
+ abstract public void drawImage(DOMNode domNode, int x, int y);
+
+}
--- /dev/null
+package swingjs.api.js;
+
+public interface HTML5DataTransfer {
+
+ Object getData(String type);
+
+}
--- /dev/null
+package swingjs.api.js;
+
+import java.awt.Container;
+import java.awt.Dimension;
+import java.awt.Frame;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.image.BufferedImage;
+import java.io.File;
+import java.net.URL;
+import java.nio.file.Files;
+import java.util.ArrayList;
+import java.util.function.Function;
+
+import javax.swing.BoxLayout;
+import javax.swing.ImageIcon;
+import javax.swing.JButton;
+import javax.swing.JDialog;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+
+import swingjs.api.JSUtilI;
+
+/**
+ * A full-service interface for HTML5 video element interaction. Allows setting
+ * and getting HTML5 video element properties. ActionListeners can be set to
+ * listen for JavaScript events associated with a video element.
+ *
+ * Video is added using a JavaScript-only two-parameter constructor for
+ * ImageIcon with "jsvideo" as the description, allowing for video construction
+ * from byte[], File, or URL.
+ *
+ * After adding the ImageIcon to a JLabel, calling
+ * jlabel.getClientProperty("jsvideo") returns an HTML5 object of type
+ * HTML5Video (the <video> tag), which has the full suite of HTML5 video
+ * element properties, methods, and events.
+ *
+ * Access to event listeners is via the method addActionListener, below, which
+ * return an ActionEvent that has as its source both the video element source as
+ * well as the original JavaScript event as an Object[] { jsvideo, event }. The
+ * id of this ActionEvent is 12345, and its command is the name of the event,
+ * for example, "canplay" or "canplaythrough".
+ *
+ * See https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement for
+ * details.
+ *
+ * @author hansonr
+ *
+ */
+public interface HTML5Video extends DOMNode {
+
+ public interface Promise {
+
+ }
+
+ final static String[] eventTypes = new String[] { "audioprocess", // The input buffer of a ScriptProcessorNode is
+ // ready to be processed.
+ "canplay", // The browser can play the media, but estimates that not enough data has been
+ // loaded to play the media up to its end without having to stop for further
+ // buffering of content.
+ "canplaythrough", // The browser estimates it can play the media up to its end without stopping
+ // for content buffering.
+ "complete", // The rendering of an OfflineAudioContext is terminated.
+ "durationchange", // The duration attribute has been updated.
+ "emptied", // The media has become empty; for example, this event is sent if the media has
+ // already been loaded (or partially loaded), and the load() method is called to
+ // reload it.
+ "ended", // Playback has stopped because the end of the media was reached.
+ "loadeddata", // The first frame of the media has finished loading.
+ "loadedmetadata", // The metadata has been loaded.
+ "pause", // Playback has been paused.
+ "play", // Playback has begun.
+ "playing", // Playback is ready to start after having been paused or delayed due to lack of
+ // data.
+ "progress", // Fired periodically as the browser loads a resource.
+ "ratechange", // The playback rate has changed.
+ "seeked", // A seek operation completed.
+ "seeking", // A seek operation began.
+ "stalled", // The user agent is trying to fetch media data, but data is unexpectedly not
+ // forthcoming.
+ "suspend", // Media data loading has been suspended.
+ "timeupdate", // The time indicated by the currentTimeattribute has been updated.
+ "volumechange", // The volume has changed.
+ "waiting", // Playback has stopped because of a temporary lack of data
+ };
+
+ // direct methods
+
+ public void addTextTrack() throws Throwable;
+
+ public Object captureStream() throws Throwable;
+
+ public String canPlayType(String mediaType) throws Throwable;
+
+ public void fastSeek(double time) throws Throwable;
+
+ public void load() throws Throwable;
+
+ public void mozCaptureStream() throws Throwable;
+
+ public void mozCaptureStreamUntilEnded() throws Throwable;
+
+ public void mozGetMetadata() throws Throwable;
+
+ public void pause() throws Throwable;
+
+ public Promise play() throws Throwable;
+
+ public Promise seekToNextFrame() throws Throwable;
+
+ public Promise setMediaKeys(Object mediaKeys) throws Throwable;
+
+ public Promise setSinkId(String id) throws Throwable;
+
+ // convenience methods
+
+ public static double getDuration(HTML5Video v) {
+ return /** @j2sNative v.duration || */
+ 0;
+ }
+
+ public static double setCurrentTime(HTML5Video v, double time) {
+ return /** @j2sNative v.currentTime = time|| */
+ 0;
+ }
+
+ public static double getCurrentTime(HTML5Video v) {
+ return /** @j2sNative v.currentTime|| */
+ 0;
+ }
+
+ public static Dimension getSize(HTML5Video v) {
+ return new Dimension(/** @j2sNative v.videoWidth || */
+ 0, /** @j2sNative v.videoHeight|| */
+ 0);
+ }
+
+ /**
+ *
+ * Create a BufferedIfmage from the current frame. The image will be of type
+ * swingjs.api.JSUtilI.TYPE_4BYTE_HTML5, matching the data buffer of HTML5
+ * images.
+ *
+ * @param v
+ * @param imageType if Integer.MIN_VALUE, swingjs.api.JSUtilI.TYPE_4BYTE_HTML5
+ * @return
+ */
+ public static BufferedImage getImage(HTML5Video v, int imageType) {
+ Dimension d = HTML5Video.getSize(v);
+ BufferedImage image = (BufferedImage) HTML5Video.getProperty(v, "_image");
+ if (image == null || image.getWidth() != d.width || image.getHeight() != d.height) {
+ image = new BufferedImage(d.width, d.height, imageType == Integer.MIN_VALUE ? JSUtilI.TYPE_4BYTE_HTML5 : imageType);
+ HTML5Video.setProperty(v, "_image", image);
+ }
+ HTML5Canvas.setImageNode(v, image);
+ return image;
+ }
+
+ // property setting and getting
+
+ /**
+ * Set a property of the the HTML5 video element using jsvideo[key] = value.
+ * Numbers and Booleans will be unboxed.
+ *
+ * @param jsvideo the HTML5 video element
+ * @param key
+ * @param value
+ */
+ public static void setProperty(HTML5Video jsvideo, String key, Object value) {
+ if (value instanceof Number) {
+ /** @j2sNative jsvideo[key] = +value; */
+ } else if (value instanceof Boolean) {
+ /** @j2sNative jsvideo[key] = !!+value */
+ } else {
+ /** @j2sNative jsvideo[key] = value; */
+ }
+ }
+
+ /**
+ * Get a property using jsvideo[key], boxing number as Double and boolean as
+ * Boolean.
+ *
+ * @param jsvideo the HTML5 video element
+ *
+ * @param key
+ * @return value or value boxed as Double or Boolean
+ */
+ @SuppressWarnings("unused")
+ public static Object getProperty(HTML5Video jsvideo, String key) {
+ Object val = (/** @j2sNative 1? jsvideo[key] : */
+ null);
+ if (val == null)
+ return null;
+ switch (/** @j2sNative typeof val || */
+ "") {
+ case "number":
+ return Double.valueOf(/** @j2sNative val || */
+ 0);
+ case "boolean":
+ return Boolean.valueOf(/** @j2sNative val || */
+ false);
+ default:
+ return val;
+ }
+ }
+
+ // event action
+
+ /**
+ * Add an ActionListener for the designated events. When an event is fired,
+ *
+ * @param jsvideo the HTML5 video element
+ * @param listener
+ * @param events array of events to listen to or null to listen on all video
+ * element event types
+ * @return an array of event/listener pairs that can be used for removal.
+ */
+ public static Object[] addActionListener(HTML5Video jsvideo, ActionListener listener, String... events) {
+ if (events == null || events.length == 0)
+ events = eventTypes;
+ @SuppressWarnings("unused")
+ Function<Object, Void> f = new Function<Object, Void>() {
+
+ @Override
+ public Void apply(Object jsevent) {
+ String name = (/** @j2sNative jsevent.type || */
+ "?");
+ System.out.println("HTML5Video " + name);
+ ActionEvent e = new ActionEvent(new Object[] { jsvideo, jsevent }, 12345, name,
+ System.currentTimeMillis(), 0);
+ listener.actionPerformed(e);
+ return null;
+ }
+ };
+ ArrayList<Object> listeners = new ArrayList<>();
+ for (int i = 0; i < events.length; i++) {
+ Object func = /**
+ * @j2sNative function(event){f.apply$O.apply(f, [event])} ||
+ */
+ null;
+ listeners.add(events[i]);
+ listeners.add(func);
+ if (jsvideo != null)
+ jsvideo.addEventListener(events[i], func);
+
+ }
+ return listeners.toArray(new Object[listeners.size()]);
+ }
+
+ /**
+ * Remove action listener
+ *
+ * @param jsvideo the HTML5 video element
+ * @param listeners an array of event/listener pairs created by
+ * addActionListener
+ */
+ public static void removeActionListener(HTML5Video jsvideo, Object[] listeners) {
+ if (listeners == null) {
+ for (int i = 0; i < eventTypes.length; i++) {
+ jsvideo.removeEventListener(eventTypes[i]);
+ }
+ }
+
+ for (int i = 0; i < listeners.length; i += 2) {
+ String event = (String) listeners[i];
+ Object listener = listeners[i + 1];
+ jsvideo.removeEventListener(event, listener);
+ }
+ }
+
+ /**
+ * Create an ImageIcon which, when placed in a JLabel, displays the video.
+ *
+ * @param source
+ * @return
+ */
+ public static ImageIcon createIcon(Object source) {
+ try {
+ if (source instanceof URL) {
+ return new ImageIcon((URL) source, "jsvideo");
+ } else if (source instanceof byte[]) {
+ return new ImageIcon((byte[]) source, "jsvideo");
+ } else if (source instanceof File) {
+ return new ImageIcon(Files.readAllBytes(((File) source).toPath()));
+ } else {
+ return new ImageIcon(Files.readAllBytes(new File(source.toString()).toPath()));
+ }
+ } catch (Throwable t) {
+ return null;
+ }
+ }
+
+ /**
+ * Create a label that, when shown, displays the video.
+ *
+ * @param source
+ * @return
+ */
+ public static JLabel createLabel(Object source) {
+ ImageIcon icon = (source instanceof ImageIcon ? (ImageIcon) source : createIcon(source));
+ return (icon == null ? null : new JLabel(icon));
+ }
+
+ /**
+ * Create a dialog that includes rudimentary controls. Optional maxWidth allows image downscaling by factors of two.
+ *
+ * @param parent
+ * @param source
+ * @param maxWidth
+ * @return
+ */
+ public static JDialog createDialog(Frame parent, Object source, int maxWidth, Function<HTML5Video, Void> whenReady) {
+ JDialog dialog = new JDialog(parent);
+ Container p = dialog.getContentPane();
+ p.setLayout(new BoxLayout(p, BoxLayout.Y_AXIS));
+ JLabel label = (source instanceof JLabel ? (JLabel) source : createLabel(source));
+ label.setAlignmentX(0.5f);
+ // not in Java! dialog.putClientProperty("jsvideo", label);
+ p.add(label);
+ label.setVisible(false);
+ p.add(getControls(label));
+ dialog.setModal(false);
+ dialog.pack();
+ dialog.setVisible(true);
+ dialog.setVisible(false);
+ HTML5Video jsvideo = (HTML5Video) label.getClientProperty("jsvideo");
+ HTML5Video.addActionListener(jsvideo, new ActionListener() {
+
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ if (label.getClientProperty("jsvideo.size") != null)
+ return;
+ Dimension dim = HTML5Video.getSize(jsvideo);
+ while (dim.width > maxWidth) {
+ dim.width /= 2;
+ dim.height /= 2;
+ }
+ label.putClientProperty("jsvideo.size", dim);
+ label.setPreferredSize(dim);
+ label.setVisible(true);
+// label.invalidate();
+ dialog.pack();
+// dialog.setVisible(false);
+ if (whenReady != null)
+ whenReady.apply(jsvideo);
+ }
+
+ }, "canplaythrough");
+ HTML5Video.setCurrentTime(jsvideo, 0);
+ return dialog;
+ }
+
+ static JPanel getControls(JLabel label) {
+
+ JPanel controls = new JPanel();
+ controls.setAlignmentX(0.5f);
+ JButton btn = new JButton("play");
+ btn.addActionListener(new ActionListener() {
+
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ try {
+ ((HTML5Video) label.getClientProperty("jsvideo")).play();
+ } catch (Throwable e1) {
+ e1.printStackTrace();
+ }
+ }
+
+ });
+ controls.add(btn);
+
+ btn = new JButton("pause");
+ btn.addActionListener(new ActionListener() {
+
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ try {
+ ((HTML5Video) label.getClientProperty("jsvideo")).pause();
+ } catch (Throwable e1) {
+ e1.printStackTrace();
+ }
+ }
+
+ });
+ controls.add(btn);
+
+ btn = new JButton("reset");
+ btn.addActionListener(new ActionListener() {
+
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ HTML5Video.setCurrentTime((HTML5Video) label.getClientProperty("jsvideo"), 0);
+ }
+
+ });
+ controls.add(btn);
+
+ return controls;
+ }
+
+ /**
+ * Advance to the next frame, using seekToNextFrame() if available, or using the time difference supplied.
+ *
+ * @param jsvideo
+ * @param dt seconds to advance if seekToNextFrame() is not available
+ * @return true if can use seekToNextFrame()
+ *
+ */
+ public static boolean nextFrame(HTML5Video jsvideo, double dt) {
+ Boolean canSeek = (Boolean) getProperty(jsvideo,"_canseek");
+ if (canSeek == null) {
+ setProperty(jsvideo, "_canseek", canSeek = Boolean.valueOf(getProperty(jsvideo, "seekToNextFrame") != null));
+ }
+ try {
+ if (canSeek) {
+ jsvideo.seekToNextFrame();
+ } else {
+ HTML5Video.setCurrentTime(jsvideo, HTML5Video.getCurrentTime(jsvideo) + dt);
+ }
+ } catch (Throwable e1) {
+ }
+ return canSeek.booleanValue();
+ }
+
+ public static int getFrameCount(HTML5Video jsvideo) {
+ return (int) (getDuration(jsvideo) / 0.033334);
+ }
+
+// HTMLMediaElement properties
+
+// audioTracks
+// autoplay
+// buffered Read only
+// controller
+// controls
+// controlsList Read only
+// crossOrigin
+// currentSrc Read only
+// currentTime
+// defaultMuted
+// defaultPlaybackRate
+// disableRemotePlayback
+// duration Read only
+// ended Read only
+// error Read only
+// loop
+// mediaGroup
+// mediaKeys Read only
+// mozAudioCaptured Read only
+// mozFragmentEnd
+// mozFrameBufferLength
+// mozSampleRate Read only
+// muted
+// networkState Read only
+// paused Read only
+// playbackRate
+// played Read only
+// preload
+// preservesPitch
+// readyState Read only
+// seekable Read only
+// seeking Read only
+// sinkId Read only
+// src
+// srcObject
+// textTracks Read only
+// videoTracks Read only
+// volume
+// initialTime Read only
+// mozChannels Read only
+
+}
--- /dev/null
+package swingjs.api.js;
+
+import java.awt.Component;
+import java.awt.Point;
+import java.util.Hashtable;
+
+
+/**
+ * An interface to J2S.xxx() functions.
+ *
+ * @author hansonr
+ *
+ */
+
+public interface J2SInterface {
+
+ void addBinaryFileType(String ext);
+
+ void addDirectDatabaseCall(String domain);
+
+ boolean debugClip();
+
+
+
+ HTML5Applet findApplet(String htmlName);
+
+ Object getCachedJavaFile(String key);
+
+ /**
+ *
+ * @param isAll true for check of navigator; otherwise just J2S._lang from j2sLang=xx_XX in URI
+ * @return
+ */
+ String getDefaultLanguage(boolean isAll);
+
+ Object getFileData(String fileName, Object fWhenDone, boolean doProcess, boolean isBinary);
+
+ void getFileFromDialog(Object fWhenDone, String type);
+
+ Object getJavaResource(String resourceName, boolean isJavaPath);
+
+ String getJavaVersion();
+
+ int getKeyModifiers(Object jQueryEvent);
+
+ Point getMousePosition(Point p);
+
+ String getResourcePath(String resourceName, boolean isJavaPath);
+
+ Hashtable<String, Object> getSetJavaFileCache(Object object);
+
+ Object getSwing(); // JSSwingMenu
+
+ int getZ(HTML5Applet applet, String frameType);
+
+ boolean isBinaryUrl(String filename);
+
+ boolean isResourceLoaded(String file, boolean done);
+
+ void readyCallback(String appId, String fullId, boolean isReady,
+ Object javaApplet, Object javaAppletPanel);
+
+ void saveFile(String fileName, Object data, String mimeType, String encoding);
+
+ void setDragDropTarget(Component target, DOMNode node, boolean adding);
+
+ void setDraggable(DOMNode tagNode, Object targetNodeOrFDown);
+
+ void setKeyListener(DOMNode node);
+
+ void setMouse(DOMNode frameNode, boolean isSwingJS);
+
+ int setWindowZIndex(DOMNode domNode, int pos);
+
+ void unsetMouse(DOMNode frameNode);
+
+ String fixCachePath(String uri);
+
+ void showStatus(String msg, boolean doFadeOut);
+
+
+}
+
--- /dev/null
+package swingjs.api.js;
+
+public interface JQuery {
+
+ JQueryObject $(Object selector);
+
+ DOMNode parseXML(String xmlData);
+
+ boolean contains(Object outer, Object inner);
+
+ Object parseJSON(String json);
+
+ Object data(Object node, String attr);
+
+}
--- /dev/null
+package swingjs.api.js;
+
+public interface JQueryObject {
+
+ public interface JQEvent {
+
+ }
+
+ public abstract void appendTo(Object obj);
+ public abstract JQueryObject append(Object span);
+
+ public abstract void bind(String actions, Object f);
+ public abstract void unbind(String actions);
+
+ public abstract void on(String eventName, Object f);
+
+ public abstract JQueryObject focus();
+ public abstract JQueryObject select();
+
+ public abstract int width();
+ public abstract int height();
+ public abstract Object offset();
+
+
+ public abstract void html(String html);
+
+ public abstract DOMNode get(int i);
+
+ public abstract String attr(String key);
+ public abstract JQueryObject attr(String key, String value);
+ public abstract JQueryObject css(String key, String value);
+
+ public abstract JQueryObject addClass(String name);
+ public abstract JQueryObject removeClass(String name);
+
+ public abstract JQueryObject show();
+ public abstract JQueryObject hide();
+
+ public abstract void resize(Object fHandleResize);
+
+
+ /**
+ * closest ancestor
+ *
+ * @param selector
+ * @return
+ */
+ public abstract JQueryObject closest(String selector);
+
+ /**
+ * find all descendants
+ *
+ * @param selector
+ * @return
+ */
+ public abstract JQueryObject find(String selector);
+
+ public abstract JQueryObject parent();
+ public abstract void before(Object obj);
+ public abstract void after(Object div);
+
+
+ /**
+ * remove from tree, but do not clear events
+ */
+ public abstract void detach(); // like remove(), but does not change event settings
+
+ /**
+ * remove from tree and clear all events -- for disposal only
+ */
+ public abstract void remove();
+
+ /**
+ * fully remove all children, clearing all events
+ */
+ public abstract void empty();
+
+ public abstract DOMNode getElement();
+
+ public static DOMNode getDOMNode(JQueryObject jnode) {
+ return (jnode == null ? null : ((DOMNode[]) (Object) jnode)[0]);
+ }
+
+
+}
--- /dev/null
+package swingjs.api.js;
+
+/**
+ * A flag that this object is really a JavaScript function that, for example,
+ * might be called from setTimeout().
+ *
+ * @author Bob Hanson
+ *
+ */
+public interface JSFunction {
+
+}
--- /dev/null
+package swingjs.api.js;
+
+/**
+ * called by SwingJS JavaScript methods
+ *
+ */
+public interface JSInterface {
+
+ int cacheFileByName(String fileName, boolean isAdd); // $S$Z
+
+ void cachePut(String key, Object data); // $S$O
+
+ void destroy();
+
+ String getFullName();
+
+ void openFileAsyncSpecial(String fileName, int flags); // $S$I
+
+ boolean processMouseEvent(int id, int x, int y, int modifiers, long time, Object jqevent, int scroll); // $I$I$I$I$J$O$I
+
+ void processTwoPointGesture(float[][][] touches); // AFFF
+
+ void setDisplay(HTML5Canvas canvas);
+
+ void setScreenDimension(int width, int height);
+
+ boolean setStatusDragDropped(int mode, int x, int y, String fileName);
+
+ void startHoverWatcher(boolean enable);
+
+ static void setCursor(String c) {
+ /**
+ * @j2sNative
+ *
+ * try {
+ *
+ * document.body.style.cursor = c;
+ *
+ * } catch (e) {}
+ */
+ }
+
+}
--- /dev/null
+package swingjs.api.js
+
+This package contains interfaces to HTML5 objects and JavaScript functions that
+are potentially useful to developers without use of @j2sNative.
+
+Caution should be used. Their persistence is not guaranteed.
\ No newline at end of file
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Hashtable;
-import java.util.PriorityQueue;
-import java.util.Random;
import java.util.TreeSet;
import javax.swing.event.TreeExpansionEvent;
private FragSeqNode _rootIDs = new FragSeqNode("IDs");
private FragSeqNode _rootFolders = new FragSeqNode("Folders");
- private TreeSet<String> _folders = new TreeSet<String>();
- private Hashtable<String,FragSeqNode> _folderPathToFolderNode = new Hashtable<String,FragSeqNode>();
+ private TreeSet<String> _folders = new TreeSet<>();
+ private Hashtable<String,FragSeqNode> _folderPathToFolderNode = new Hashtable<>();
- private Hashtable<String,FragSeqNode> _idsToNode = new Hashtable<String,FragSeqNode>();
- private Hashtable<String,ArrayList<FragSeqNode>> _pathToIDFileNodes = new Hashtable<String,ArrayList<FragSeqNode>>();
+ private Hashtable<String,FragSeqNode> _idsToNode = new Hashtable<>();
+ private Hashtable<String,ArrayList<FragSeqNode>> _pathToIDFileNodes = new Hashtable<>();
public enum SORT_MODE{
PATH,
if (parent.getChildCount()==0)
{
parent.removeFromParent();
- _folderPathToFolderNode.remove(parent);
+ // BH was just parent --
+ System.out.println("Varna FragSeqTreeModel removing " + parent + " "
+ + parent.toString());
+ _folderPathToFolderNode.remove(parent.toString());
if (parent.getUserObject() instanceof String)
{
String path = parent.getUserObject().toString();
public void removeFolder(String path)
{
- ArrayList<FragSeqNode> toBeRemoved = new ArrayList<FragSeqNode>();
+ ArrayList<FragSeqNode> toBeRemoved = new ArrayList<>();
Enumeration en = _folderPathToFolderNode.get(path).children();
while(en.hasMoreElements())
{
insertFileNode(_folderPathToFolderNode.get(folder), m);
}
+ @Override
public FragSeqNode getRoot()
{
return (FragSeqNode) super.getRoot();
public ArrayList<String> getFolders()
{
- ArrayList<String> result = new ArrayList<String>(_folders);
+ ArrayList<String> result = new ArrayList<>(_folders);
return result;
}
FilenameFilter _f = new FilenameFilter(){
- public boolean accept(File dir, String name) {
+ @Override
+ public boolean accept(File dir, String name) {
return name.toLowerCase().endsWith(".dbn")
|| name.toLowerCase().endsWith(".ct")
|| name.toLowerCase().endsWith(".bpseq")
}
-private Hashtable<FragSeqNode,Boolean> _isExpanded = new Hashtable<FragSeqNode,Boolean>();
+private Hashtable<FragSeqNode,Boolean> _isExpanded = new Hashtable<>();
public boolean isExpanded(FragSeqNode n)
{
return _isExpanded.get(n);
}
else
- return false;
+ {
+ return false;
+ }
}
+@Override
public void treeWillExpand(TreeExpansionEvent event) throws ExpandVetoException {
if (event.getSource() instanceof FragSeqTree)
{
}
}
+@Override
public void treeWillCollapse(TreeExpansionEvent event)
throws ExpandVetoException {
// TODO Auto-generated method stub
--- /dev/null
+@BobHanson The SwingJS-site.zip file is in ./swingjs as you'll expect.
+It gets unzipped to a transfer location (and not to the actual site location
+to avoid the unzip happening again unecessarily when something changes in that location,
+e.g. an Eclipse IDE on-the-fly transpile) which is ./build/jalviewjs/tmp/site_swingjs/.
+
+In the meantime, if you're using Eclipse as IDE, it should be transpiling directly
+into the actual site location, which is ./build/jalviewjs/site, and if you run the task
+jalviewjsIDE_PrepareSite (under the Gradle Tasks tab) it will sync the files
+from ./build/jalviewjs/tmp/site_swingjs/ to ./build/jalviewjs/site/ (along with other unzipped
+files such as those in ./utils/jalviewjs/libjs/*.zip and files from ./utils/jalviewjs/site-resources/).
+
+If you run the task jalviewjsIDE_AssembleSite it will (/should) also build cores
+into ./build/jalviewjs/tmp/site_core/ and then sync them to ./build/jalviewjs/site/.
+
+The _j2sclasslist.txt that gets used to build core_jalview.js is ./utils/jalviewjs/_j2sclasslist.txt,
+whereas other lists are that are used to build cores are all the files found in ./utils/jalviewjs/classlists/.
+Basically all the stuff that gradle uses to build jalviewjs is found in ./utils/jalviewjs with
+the exception of ./swingjs, which I know you wanted as-is in the top-level.
+
+
+
+
+
-java2script/SwingJS Notes
-=========================
-
-updated 12/31/2020 -- full support for 64-bit long
-updated 12/6/2020 -- note about restrictions on long, including BitSet and Scanner
-updated 3/21/2020 -- adds note about HashMap, Hashtable, and HashSet iterator ordering
-updated 3/20/2020 -- adds note about interning, new String("xxx"), and "xxx"
-updated 2/26/2020 -- adds Graphics.setClip issue
-updated 12/22/19 -- additional issues
-updated 11/03/19 -- adds information about File.exists() and points to src/javajs/async
-updated 10/26/19 -- adds information about File.createTempFile()
-updated 8/16/19 -- minor typos and added summary paragraph
-updated 7/19/19 -- clarification that AWT and Swing classes are supported directly
-updated 5/13/19 -- Mandarin U+79D8 reserved character; Missing Math methods; int and long
-updated 5/10/19 -- adds a section on static issues in multi-(duplicate)-applet pages
-updated 1/4/19 -- nio
-updated 9/15/18 -- adds integer 1/0 == Infinity
-updated 7/24/18 -- most classes replaced with https://github.com/frohoff/jdk8u-jdk
-updated 6/5/17 -- reserved package name "window"
-updated 3/11/17 -- myClass.getField
-updated 3/7/17 -- overloading of JSplitPane.setDividerLocation
-updated 3/2/17 -- more indication of classes not implemented (KeyListener)
+Notes
+=====
---IMPORTANT CHARACTER SET NOTE---
-It is critical that all development work in Java2Script be done in UTF-8. This means:
+It is critical that all development work in Java2Script
+be done in UTF-8. This means:
- making sure your Eclipse project is set up for UTF-8 (not the Eclipse default?)
- making sure your server can serve up UTF-8 by default for any browser-loaded files
Note that the DOCTYPE tag is critical for some browsers to switch into HTML5 mode. (MSIE?)
+
+
In particular, the Mandarin character 秘 (mi; "secret") is used extensively throughout
the SwingJS class files to distinguish j2s-specific fields and methods that must not
ever be shadowed or overridden by subclasses. For example, we see in java.lang.Thread.java:
----------------------------------
+updated 12/6/2020 -- note about restrictions on long, including BitSet and Scanner
+updated 3/21/2020 -- adds note about HashMap, Hashtable, and HashSet iterator ordering
+updated 3/20/2020 -- adds note about interning, new String("xxx"), and "xxx"
+updated 2/26/2020 -- adds Graphics.setClip issue
+updated 12/22/19 -- additional issues
+updated 11/03/19 -- adds information about File.exists() and points to src/javajs/async
+updated 10/26/19 -- adds information about File.createTempFile()
+updated 8/16/19 -- minor typos and added summary paragraph
+updated 7/19/19 -- clarification that AWT and Swing classes are supported directly
+updated 5/13/19 -- Mandarin U+79D8 reserved character; Missing Math methods; int and long
+updated 5/10/19 -- adds a section on static issues in multi-(duplicate)-applet pages
+updated 1/4/19 -- nio
+updated 9/15/18 -- adds integer 1/0 == Infinity
+updated 7/24/18 -- most classes replaced with https://github.com/frohoff/jdk8u-jdk
+updated 6/5/17 -- reserved package name "window"
+updated 3/11/17 -- myClass.getField
+updated 3/7/17 -- overloading of JSplitPane.setDividerLocation
+updated 3/2/17 -- more indication of classes not implemented (KeyListener)
=============================================================================
SwingJS and OpenJDK 8+
and for all practical purposes it will appear that Java is running.
-The goal of java2script/SwingJS is NOT to reproduce Java byte code processing in a
-browser. We leave that task and its own issues to others. Here, instead, we have a
-working JavaScript version of the Java classes along with runtime assistance in the
-j2sClazz.js library. This design has several advantages:
-
- 1) It leads to much smaller downloads, since the class loader can dynamically load
- code at the class level.
-
- 2) It allow the browser to use its own optimizations and features, not to ignore those.
- This leads to huge performance gains and in many cases much simpler coding.
-
- 3) It allows for in-browser debugging and analysis.
-
- 4) It allows for code switching between Java and JavaScript. Working Java code
- can be annotated (@j2sNative, @j2sAlias, @j2sIgnore) in a fashion that
- allows the code to run slightly differently in a Java than a JavaScript environment.
- For example:
-
- int delayMS = /** @j2sNative 10 ||*/2;
-
- will read "var delayMS = 10 || 2;" (i.e. 10) in JavaScript but read by the Java
- compiler as "int delayMS = 2".
-
- 5) Just generally, it allows for a much more integrated environment. JavaScript on
- the page can call into any SwingJS program, and, likewise, any SwingJS code can
- access anything on the page.
-
Method and Field Disambiguation
-------------------------------
-This is no problem. SwingJS has no problem with the overloading of methods, for example:
+SwingJS has no problem with the overloading of methods, for example:
public void print(int b);
public void print(float b);
Clazz.newMeth(C$, 'c$$S', function (text) {...});
-Field disambiguation involves prepending.
-
-In Java, a class and its subclass can both have the same field name, such as
+Field disambiguation involves prepending. In Java, a class and its subclass
+can both have the same field name, such as
boolean visible;
since JavaScript does not have the "super" keyword.
+
+
Parameterless methods such as toString() are appended with "$" to become toString$().
The one exception to this rule is private methods, which are saved in (truly) private
array in the class (and are not accessible by reflection). Private parameterless
This renaming of methods has a few consequences, which are discussed more fully below.
See particularly the section on "qualified field and method names", where it is described
how you can use packages or classes or interfaces with ".api.js" in them to represent JavaScript
-objects for which all method names are to be left unqualified, and how individual methods
-can have more than one name using @j2sAlias.
+objects for which all method names are to be left unqualified. Note that it is not
+possible to cherry-pick methods to be unqualified; only full packages, classes or
+interfaces can hold this status.
The swingjs.api.js package in particular contains a number of useful interfaces that
you can import into your project for JavaScript-specific capabilities.
some refactoring of the Java to make it more efficient in both Java and JavaScript.
"for" loops need to be more carefully crafted; use of "new" and "instanceof" need to be
minimized in critical areas. Note that method overloading -- that is, the same method name
-with different parameters, such as read(int) and read(byte) -- is no longer any problem.
+with different parameters, such as read(int) and read(byte) -- is no longer any problem.
+
Threads
-------
The key is to create a state-based run() that can be exited and re-entered in JavaScript.
-The javajs.async package can be added to any Java program to provide Java+JavaScript asynchronous
-classes, including AsyncColorChooser, AsyncDialog, AsyncFileChooser, and AsyncSwingWorker. All
-of these classes work just as well in Java as in JavaScript. There is no need to run them
-only when in JavaScript.
Static fields
-------------
The SwingJS library is the swingjs/ package. There are interfaces that may be of assistance
in swingjs/api, but other than that, it is not recommended that developers access classes in
-this package. The "public" nature of their methods is really an internal necessity. Most access
-to this package in working Java should be via the swingjs.api.JSUtilI interface.
+this package. The "public" nature of their methods is really an internal necessity.
In addition to swingjs/, though, there are several useful classes in the javajs/ package
that could be very useful. This package is a stand-alone package that can be
Fortunately, they are not common, and those that are present in Java (for example, in calculating
checksums in ZIP file creation) are at a low enough level that most developers do not utilize them
or do not even have access to them. All native calls in Java classes have been replaced by
-Java or JavaScript equivalents.
+Java equivalents.
Swing GUI Peers and UIClasses
-----------------------------
One of the biggest adaptations introduced in SwingJS is in the area of the graphical
-user interface. Basically, what we have is a Java Swing "LookAndFeel" customized for HTML.
-
-The issue here is complex but workable. In Java there are two background concepts -- the
-Component "peer" (one per "heavy-weight" component, such as a Frame) and the
-component "uiClass" (one per component, such as BasicButtonUI or BasicTextFieldUI).
+user interface. The issue here is complex but workable. In Java there are two background
+concepts -- the Component "peer" (one per "heavy-weight" component, such as a Frame) and the
+component "uiClass" (one per component, such as JButton or JTextField).
Peers are native objects of the operating system. These are the virtual buttons and text areas
-that the user is interacting with at a very base level. They are chunks of low-level code that
-paint the screen to give the illusion that you really are pressing a button or typing text
-ot the screen. Their events are being passed on to Java or the browser by the operating system.
-
-UI classes provide a consistent "look and feel" for these native objects, rendering them onto
-the native window canvas and handling all user-generated events. They paint the borders,
-the backgrounds, the highlights, of every control you see in Java. There is one-to-one
-correspondence of Swing classes and UI classes. Setting the Look and Feel for a project amounts
-to selecting the directory from which to draw these UI classes. Java's UI class interfaces can
-be found in the javax.swing.plaf ("platform look and feel") package. Individual look and feel
-implementations are found in sun.plaf.basic, sun.plaf.metal, and other such specialized packages.
+that the user is interacting with at a very base level. Their events are being passed on to
+Java or the browser by the operating system. UI classes provide a consistent "look and feel"
+for these native objects, rendering them onto the native window canvas and handling all
+user-generated events. They paint the borders, the backgrounds, the highlights, of every
+control you see in Java. There is one-to-one correspondence of Swing classes and UI classes.
+Setting the Look and Feel for a project amounts to selecting the directory from which to draw
+these UI classes. The UI classes can be found in the javax.swing.plaf ("platform look and feel")
+package.
Early on in the development of SwingJS, we decided not to fully reproduce the painfully detailed
bit-by-bit painting of controls as is done in Java. Instead, we felt it was wiser to utilize the standard
design choice posed a huge headache for Swing class developers.
For SwingJS, we decided from the beginning NOT to allow this mixed-mode programming and
-instead to require that all components be Swing components. However, this is not really an
-issue. We have reconfigured the class relationships a bit. In SwingJS, all AWT components
-are now subclasses of javax.swing.JComponent. While this might seem error prone, so far we have
-found no problem with this arrangement. It's a little surprising to me that the original developers
-of Swing did not think of this.
+instead to require that all components be Swing components.
+
+However, this is no longer an issue. All AWT components in SwingJS are now subclasses of
+javax.swing.JComponent. So far, we have found no problem with this.
The a2s Adapter Package
The solution turned out to be simple: Write a package (a2s) that recreates the interface for
non-Swing components as subclasses of Swing components. Thus, a2s.Button subclasses javax.swing.JButton
but also accepts all of the methods of java.awt.Button. This works amazingly well, with a few
-special adaptations to the core javax.swing to be "AWT-aware."
-
-Then, to tie it all togeter, all AWT components such as java.awt.Button now subclass their respective
+special adaptations to the core javax.swing to be "AWT-aware." All AWT components now subclass
a2s components, which in turn subclass JComponents. So no changes in code are necessary. We have
-successfully transpiled over 500 applets using this strategy.
+successfully transpiled over 500 applets using this strategy. (Kind of surprising, actually, that
+the original Java developers did not see that option. But we have a hindsight advantage here.)
+
Working with Files
==================
Simple String file names are not optimal for passing information about
-files read by SwingJS applications. That is because just peeking at a file
-in SwingJS will load its entire byte[] data.
+read files within SwingJS applications.
-Optimally, all work with files should either use Path or File objects exclusively.
+All work with files should either use Path or File objects exclusively.
These objects, after a file is read or checked for existence, will already
-contain the file byte[] data. The string name can be used alone, since SwingJS will
-cache the files itself and not reload them -- just as the browser normally does.
+contain the file byte[] data. Doing something like this:
+
+File f = File("./test.dat");
+boolean isOK = f.exists();
+
+will load f with its byte[] data, if the file exists.
+
+But if after that, we use:
+
+File f2 = new File(f.getAbsolutePath());
+
+f2 will not contain that data. Such copying should be done as:
+
+File f2 = new File(f);
+
+in which case, the byte[] data will be transferred.
+
SwingJS uses the following criteria to determine if File.exists() returns true:
Temporary files can be created in SwingJS. SwingJS will maintain a pseudo-filesystem for files
created with File.createTempFile(). This is useful in that closure of writing to a temporary file
-does not generate a pseudo-download to the user's machine. Temporary files will be placed in the
-"/TEMP/" directory, as seen from the running Java program. Any file written to this directory will
-simply be stored in memory; files written to any other directory, when closed, will appear to the
-user as a download, often involving a "What do you want to do with this file" dialog.
-
-
-See below for details relating to each of the subjects below:
+does not generate a pseudo-download to the user's machine.
UNIMPLEMENTED CLASSES BY DESIGN
TODO LIST FOR UNIMPLEMENTED CLASSES
===================================
-none as of 2020.12.31. Source code for classes and methods missing
-from Java 8 or from Java 9+ can be inserted by any developer along
-with their running code source, and they should run.
+JEditorPane (minimal implementation) - DONE 12/2018; some issues still
+JSplitPane - DONE 8/2018
+JTabbedPane - DONE 10/2018
+JTree - done 12/2019
MINOR ISSUES--required some rewriting/refactoring by Bob and Udo
See below for a full discussion.
-primitive type restrictions - int, long, and float
+Restrictions on long
+Restriction on BitSet and Scanner
HashMap, Hashtable, and HashSet iterator ordering
interning, new String("xxx") vs "xxx"
Names with "$" and "_"
+positive integers do not add to give negative numbers
ArrayIndexOutOfBounds
java.awt.Color
native methods
"window" and other reserved JavaScript names
reserved field and method names
qualified field and method names
+missing Math methods
Component.getGraphics(), Graphics.dispose()
Graphics.setClip()
threads
modal dialogs
image loading
+BigDecimal not fully implemented
no format internationalization
-Graphics2D: missing winding rules
+no winding rules
text-related field implementation
Formatter/Regex limitations
+integer 1/0 == Infinity
========================================================================
Table row/col sorter needs checking after removal of java.text.Collator references
+I had to move all of SunHints class to RenderingHints, or the
+two classes could not be loaded. Shouldn't be a problem, I think. The sun classes are
+not accessible to developers in Java anyway, since they are generally package private.
+
==========================================================================
//////////////////////////////////////////////////////////////////////////////
MINOR ISSUES--requiring some rewriting/refactoring outside of SwingJS
=====================================================================
-primitive restrictions - int, long, and float
----------------------------------------------
-
-int
-
-For performance reasons, int addition and multiplication do not by default overflow to
-negative values. Instead, they just get bigger. Java code that relies on overflow to
-negative values should be surrounded by ()|0 -- an OR with integer 0:
-
-
-int bigI, bigJ;
-...
-
-bigI = (bigI + bigJ)|0;
-
-bigI = (bigI + 1)|0; //instead of bigI++
-
-
-Thus, in Java, the following is true:
-
- 2000000000 + 2000000000 == -294967296
-
-But in SwingJS, that will be 4000000000. So, for example, the following
-strategy will fail in SwingJS:
+restrictions on long
+--------------------
- int newLength = lineBuf.length * 2;
- if (newLength < 0) {
- newLength = Integer.MAX_VALUE;
- }
+Java's 64-bit long type is not supported in JavaScript. There is no Int64Array in JavaScript,
+and 0x20000000000000 + 1 evaluates to 0x20000000000000, not 0x20000000000001.
+(Likewise, -0x20000000000000 - 1 is left unchanged.)
-This is because, generally, "-1" in JavaScript is not 0xFFFFFFFF. The simple ()|0 takes
-caes of this:
+The largest "integer" value in JavaScript is 9007199254740991 (9.007199254740991E13, or 0x1FFFFFFFFFFFFFF).
+Effectively, you get to use only 53 bits of the long, not 64. Trying to set a long larger than
+0x1FFFFFFFFFFFFFF or smaller than -0x1FFFFFFFFFFFFFF will result in a NumberFormatException.
- int newLength = (lineBuf.length * 2)|0;
- if (newLength < 0) {
- newLength = Integer.MAX_VALUE;
- }
-
-JavaScript does process bitwise operators & | ^ ~ properly for int values. There is no issue using
-these operations.
-
-Note that int 1/0 in Java throws "java.lang.ArithmeticException: / by zero", but in JavaScript is just Infinity.
+The transpiler handles conversion to long the same as Java for all cases other than from double.
-Importantly, the JavaScript Int32Array does behave properly. From the Firefox developer console:
+For small double values, there is no problem, and, in fact, this is a known trick used to round
+doubles and floats toward zero:
->> x = new Int32Array(1)
-<- Int32Array(1) [ 0 ]
->> x[0] = 4000000000
-<- 4000000000
->> x[0]
-<- -294967296
+double d;
+d = (long) 3.8;
+assert(d == 3);
+d = (long) -3.8;
+assert(d == -3);
-Notice that, perhaps unexpectedly, the following two constructs produce
-different results in JavaScript:
+SwingJS will evaluate (long) d as 0 for d > 9007199254740991
+or d < -9007199254740991, same as Java returns for Double.NaN.
+So, in Java we have:
-x = new Int32Array(1);
-b = x[0] = 4000000000;
+ assert(((long) Double.NaN) == 0);
+ assert(((int) Double.NaN) == 0);
+ assert(((long) Float.NaN) == 0);
+ assert(((int) Float.NaN) == 0);
-(b will be 4000000000)
+and also, in JavaScript only, we also have:
-and
+ double d = 0x2000000000000L;
+ assert(((long) d) == 0);
-x = new Int32Array(1);
-x[0] = 4000000000;
-b = x[0];
-(b will be -294967296)
-
-
-SwingJS leverages array typing to handle all byte and short arithmetic so as
-to ensure that any byte or short operation in JavaScript does give the same
-result in Java.
-
-long
+restrictions on BitSet and Scanner
+----------------------------------
-Java's 64-bit long type is fully supported, starting with java2script 3.3.1 (2020.12.31)
-The transpiler handles all conversions to and from long appropriately. See the discussion
-at https://github.com/BobHanson/java2script/issues/202 for how this is done.
+Because of the issue of long being only 53 bits, any time a method returns a long value, considerations must
+be made as to whether this will work in JavaScript. In particular, BitSet and Scanner have issues.
-float
+In SwingJS, java.util.BitSet has been implemented as a 32-bit integer-based bitset. This was no problem in
+Java 6, but starting with Java 7, a method was added to BitSet that allows for the extraction of the
+underlying long[] word data. This is not work in JavaScript. Instead, SwingJS java.util.Bitset.toLongArray() will deliver
+32-bit int[] data.
-SwingJS does not distinguish between float and double. Everything is double.
+SwingJS Scanner has hasNextLong() and nextLong(), and although it will scan through long numbers,
+Scanner will choke on long numbers greater than the JavaScript 53-bit limit. hasNextLong() will
+return false, and nextLong() will throw an InputMismatchException triggered by the NumberFormatException
+thrown by Long.parseLong().
HashMap, Hashtable, and HashSet iterator ordering
whenever all keys are strictly of JavaScript typeof "string". If any key is introduced that is not a string, the
implementation falls back to using hash codes, the same as Java.
+Note strings created using new String("xxxx") are NOT typeof "string"; they are typeof "object".
+
The result is significantly faster performance (3-12 x faster) than originally, and up to 3 x faster
-performance in JavaScript than in Java itself. That is not a misprint. Faster than Java.
+performance in JavaScript than in Java itself. Right. Faster than Java.
The JavaScript Map implementation is implemented UNLESS the constructor used is the one that
specifies both initial capacity and load factor in their constructor. Thus,
methods that return new String(), and those classes that do that would cause a JavaScript error
if implicitly stringified if new String() returned a JavaScript String object.
-This is fine in JavaScript:
+This is fine in JavaScript
test1 = function() { return { toString:function(){ return "OK" } } }
"testing" + new test1()
assert(new String("xxx") != "xxx");
assert(new String("xxx") != new String("xxx"));
-But the following two fail to assert true in SwingJS:
+But the following two fail to assert true:
assert("xxx" != "xx" + a);
assert("xxx" != "xx" + a.toString());
-because, in JavaScript, both of these right-side expressions evaluate to a simple "interned" string.
+because in JavaScript, both of these right-side expressions evaluate to a simple "interned" string.
In Java, however, these assertions are true because Java implicitly "boxes" String
concatentaion as a String object, not a literal.
My recommendation, if you need to use IdentityHashMap with strings is to always use an explicit String.intern()
for any keys -- unless you really want to keep every string as separate keys even if they are the same sequence,
-in which case, use new String(). This will work in Java and in JavaScript.
+in which case, use new String(). This will work in Java and in JavaScript.
Be aware when working with strings that come from SwingJS and are being used by other JavaScript modules
that those that are String objects will return "object" for the JavaScript typeof operator, not "string".
unless you are certain that the string is being returned is a raw JavaScript string.
-
Names with "$" and "_"
----------------------
creating the fully qualified JavaScript name.
+positive integers do not add to give negative numbers
+-----------------------------------------------------
+
+In Java, the following is true:
+
+ 2000000000 + 2000000000 == -294967296
+
+But in SwingJS, that will be 4000000000. So, for example, the following
+strategy will fail in SwingJS:
+
+ int newLength = lineBuf.length * 2;
+ if (newLength < 0) {
+ newLength = Integer.MAX_VALUE;
+ }
+
+"-1" in JavaScript is not 0xFFFFFFFF.
+
+And one must take care to not compare a negative number with a 32-bit mask. So
+
+(b & 0xFF000000) == 0xFF000000
+
+is true in Java for (int) b = -1, but is false in JavaScript, because 0xFF000000 is 4278190080,
+while (-1 & 0xFF000000) is, strangely enough, -16777216, and, in fact,
+
+(0xFF000000 & 0xFF000000) != 0xFF000000
+
+because -16777216 is not 4278190080.
+
+The fix is that one must compare similar operations:
+
+if ((b & 0xFF000000) == (0xFF000000 & 0xFF000000)) .....
+
+Importantly, the JavaScript Int32Array does behave properly. From
+the Firefox developer console:
+
+>> x = new Int32Array(1)
+<- Int32Array(1) [ 0 ]
+>> x[0] = 4000000000
+<- 4000000000
+>> x[0]
+<- -294967296
+
+Notice that, perhaps unexpectedly, the following two constructs produce
+different results in JavaScript:
+
+x = new Int32Array(1);
+b = x[0] = 4000000000;
+
+(b will be 4000000000)
+
+and
+
+x = new Int32Array(1);
+x[0] = 4000000000;
+b = x[0];
+
+(b will be -294967296)
+
+
+SwingJS leverages array typing to handle all byte and short arithmetic so as
+to ensure that any byte or short operation in JavaScript does give the same
+result in Java. The design decision to not also do this with integer math was
+a trade-off between performance and handling edge cases.
+
+
ArrayIndexOutOfBounds
---------------------
will work in Java but not in JavaScript. Code should not depend upon this sort
of trap anyway, if you ask me.
-
Throwable vs Error vs Exception
-------------------------------
Error and Exception as well. So if you want to be sure to catch any JavaScript
error, use try{}catch (Throwable t){}, not try{}catch (Exception e){}.
-java.awt.Color
+j
+ava.awt.Color
--------------
ColorSpace: only "support" CS_sRGB.
javax.swing.JOptionPane dialogs
-------------------------------
-For a full discussion of modal dialogs, see the javajs.asyc.AsyncDialog.java discussion.
-
-For this action to work, the parent component must implement
+For this action to work, the parentComponent must implement
propertyChangeListener, and any call to JOptionPanel should allow for
an asynchronous response, meaning that there is no actionable code following the
call to the dialog opening.
-For full compatibility, The calling method must not continue beyond this call.
+For full compatibility, The calling method must not continue beyond this
+call.
-All of the standard Java events associated with Components are also available.
+All of the standard Java events associated with Components are also
+available.
Certain fall back mechanisms are possible, where onReturn does not exist, but
only for the following cases:
*/
Note that if you follow that directly with a {...} block, then
- only the javadoc code will run in JavaScript, and only the {...} code will run in Java.
+ the javadoc code will run in JavaScript, and the {...} code will run in Java.
key Focus
No reserved top-level JavaScript name is allowed for a package name. So, for example,
one must rename packages such as "window" or "document" to names such as "win" or "doc".
-
reserved field and method names
-------------------------------
would be if you use that character followed by certain English words in certain classes. For example
\u79D8canvas for JComponents (in java.awt.JSComponent) and \u79D8byte (in java.io.File).
-
qualified field and method names
--------------------------------
parameters, such as write(int) and write(double), must not have the same name in JavaScript. (In this
case, we will have write$I and write$D.) However, in certain cases it may be desirable to leave the
method names unqualified. In particular, when an interface actually represents a JavaScript object,
-the transpiler can leave a method name unqualified.
-
-You can implement a simple name for a method using the @j2sAlias annoation in the javadoc for the
-method involved. For example:
-
-
-/**
- * @j2sAlias read
- *
- */
-public void read(byte[] buf, int pos, int len) {...}
-
-will allow the method to be accesible either as "read" or "read$BA$I$I" in JavaScript.
-
-
-The default situation for this is a class name includes ".api.js" (case-sensitive).
-This means that any method in any class in a package js within a package api, or any private interface js
-that has an outer interface api, will have all-unqualified methods. An example of this is
-swingjs.plaf.JSComboPopupList, which needs to communicate with a jQuery
+the transpiler can leave a method name unqualified. The default situation for this is a class name
+includes ".api.js" (case-sensitive). This means that any method in any class in a package js within
+a package api, or any private interface js that has an outer interface api, will have all-unqualified
+methods. An example of this is swingjs.plaf.JSComboPopupList, which needs to communicate with a jQuery
object directly using the following interface:
private interface api {
Notice that all these variants of j2sCB() will call the same method in JavaScript by design.
+missing Math methods
+--------------------
+
+java.lang.Math is worked out, but some methods are missing, either because they
+involve long integer value that are inaccessible in JavaScript, or because I just
+didn't implement them. This is a result of continued Java development.
+It is easy enough to add these methods if you have the source. They go into j2sClazz.js,
+which is combined with other initial libraries into swingjs2.js by build_site.xml
+
+
Component.getGraphics(), Graphics.dispose()
-------------------------------------------
Use of component.getGraphics() is discouraged in Java and in SwingJS.
Specifically in SwingJS, any call to component.getGraphics() or
BufferedImage.createGraphics() or Graphics.create(...) should be matched with graphics.dispose(),
-particularly when it is called outside the context of a paint(Graphics) call from the system.
+particularly when it is called outside the context of a paint(Graphics)
+call from the system.
If you see your graphics scrolling down the page with each repaint,
look for where you have used Component.getGraphics() and not Graphics.dispose().
...
Graphics.setClip(oldClip);
-If you need to do something like this, you must schedule the paints to not have overlapping clip needs.
+If you need to do something like this, you must schedule the paints
+to not have overlapping clip needs.
MAJOR ISSUES--for Bob and Udo within SwingJS
java.awt.Toolkit
java.awt.GraphicsEnvironment
-
+
+
which are created using Class.forName are implemented using classes in the swingjs package.
-sun.awt.AWTAccessor is not implemented.
+AWTAccessor is not implemented.
AWT component peers and component "ui" user interfaces
References to such objects have been removed, but clearly there must be
some connection to similar DOM objects, even for "light-weight" components.
+
MAJOR ISSUES--to be resolved by implementers
============================================
}
}
-
image loading
-------------
- All image loading in SwingJS is synchronous. A MediaTracker call will immediately return "complete".
BigInteger and BigDecimal
-------------------------
-java.math.BigInteger and java.math.BigDecimal are fully supported.
+java.math.BigInteger is fully supported; java.math.BigDecimal is roughed
+in and not fully tested (07/2019).
+Both classes present significant issues for JavaScript, as they are based in
+Java's 64-bit long for all their operations. Here is the JavaDoc note I added
+to BigInteger:
+
+ * SwingJS note: Because of the limitations of JavaScript with regard
+ * to long-integer bit storage as a double, this implementation drops
+ * the integer storage bit length to 24, giving 48 for long and leaving
+ * the last 16 bits clear for the exponent of the double number. This should
+ * not affect performance significantly. It does increase the storage
+ * size by about 33%. By bringing an "int" to 3 bytes, we can easily construct
+ * and use byte[] data intended for the original BitSet.
+
+"Easily" may be a bit strong there. This was a serious challenge.
+
+BigDecimal seems to run normally, but in order to do that, my hack involves
+reducing the size of an integer that is allowed to be stored as such and not
+in byte[] as a BigInteger. I'm sure there is a performance hit, but it does work.
no format internationalization
------------------------------
-For now, just "en" for number and date formatters
+For now, just en for number and date formatters
+no winding rules
+----------------
-missing winding rules
----------------------
-
-When filling a graphic, only nonzero winding rule is implemented in HTML5 Canvas2D.
+ When filling a graphic, only nonzero winding rule is implemented in HTML5 Canvas2D.
key value even after SwingUtilities.invokeLater() is called. Thus, key pressed actions may need
to be recorded after a key released event instead.
-
Formatter/Regex limitations
---------------------------
java.util.Formatter will function correctly for all standard %... patterns.
-In addition, JavaScript does not implement some of the more arcane POSIX {...} formats.
-From java.util.regex.Pattern.java, we find the listing of conversions SwingJS does use:
-
- "\\p{javaWhitespace}","\\s",
- "\\p{javaDigit}","\\d",
- "\\p{Lower}", "[a-z]",
- "\\p{Upper}", "[A-Z]",
- "\\p{ASCII}", "[\u0000-\u007F]",
- "\\p{Alpha}", "[A-Za-z]",
- "\\p{Digit}", "[0-9]",
- "\\p{Alnum}", "[A-Za-z0-9]",
- "\\p{Punct}", "[!\"#$%&'\\(\\)\\*\\+,-./:;<=>?@\\[\\\\\\]^_`{\\|}~]",
- "\\p{Graph}", "[A-Za-z0-9]!\"#$%&'\\(\\)\\*\\+,-./:;<=>?@\\[\\\\\\]^_`{\\|}~]",
- "\\p{Print}", "[A-Za-z0-9]!\"#$%&'\\(\\)\\*\\+,-./:;<=>?@\\[\\\\\\]^_`{\\|}~]",
- "\\p{Blank}", "[ \t]",
- "\\p{Cntrl}", "[\u0000-\u001F\u007F]",
- "\\p{XDigit}", "[0-9a-fA-F]",
- "\\p{Space}", "[ \t\n\u000B\f\r]",
- "\\p{javaLowerCase}", "[a-z]",
- "\\p{javaUpperCase}", "[A-Z]",
- "\\p{Sc}", "[\u0024\u00A2\u00A3\u00A4\u00A5\u058F\u060B\u07FE\u07FF\u09F2\u09F3\u09FB\u0AF1\u0BF9\u0E3F\u20A0\u20A1\u20A2\u20A3\u20A4\u20A5\u20A6\u20A7\u20A8\u20A9\u20AA\u20AB\u20AC\u20AD\u20AE\u20AF\u20B0\u20B1\u20B2\u20B3\u20B4\u20B5\u20B6\u20B7\u20B8\u20B9\u20BA\u20BB\u20BC\u20BD\u20BE\u20BF\uA838\uFDFC\uFE69\uFF04\uFFE0\uFFE1\uFFE5\uFFE6]"
-
-Java's \Q \E quoting is handled appropriately.
-
-Additional Issues
------------------
-
-Method reflection is limited. Fields and methods do not retain public or default characteristics.
-(This could be easily adapted, though.) Interfaces do not expose their methods, as the transpiler does not
-actually transpile the interfaces themselves unless they contain default methods.
-And method reflection only includes annotated methods.
-
-java.util.concurrent is not fully elaborated. This package is rewritten to not actually use the
-memory handling capabilities of concurrency, which JavaScript does not have access to.
+integer 1/0 == Infinity
+-----------------------
-System.getProperties() just returns a minimal set of properties.
+1/0 in Java throws "java.lang.ArithmeticException: / by zero", but in JavaScript is just Infinity.
+
Summary
may or may not be present with the JAR or class files. Use class files at your own risk.
Bob Hanson
+2019.08.16
+
+
+Additional Issues
+-----------------
+
+Annotation is working for classes, methods, and fields (12/22/19). Method reflection, however,
+is limited. Interfaces do not expose their methods, as the transpiler does not actually transpile
+the interfaces themselves. And method reflection only includes annotated methods.
+
+java.util.concurrent is not fully elaborated. This package is rewritten to not actually use the
+memory handling capabilities of concurrency, which JavaScript does not have access to.
+
+System.getProperties() just returns a minimal set of properties.
-20210728172208
+20201222130550
--- /dev/null
+<!DOCTYPE html>
+<html>
+<head>
+<title>SwingJS test _NAME_</title><meta charset="utf-8" />
+<script src="swingjs/swingjs2.js"></script>
+<script>
+if (!self.SwingJS)alert('swingjs2.js was not found. It needs to be in swingjs folder in the same directory as ' + document.location.href)
+Info = {
+ code: _CODE_,
+ main: _MAIN_,
+ core: "NONE",
+ width: 850,
+ height: 550,
+ readyFunction: null,
+ serverURL: 'https://chemapps.stolaf.edu/jmol/jsmol/php/jsmol.php',
+ j2sPath: 'swingjs/j2s',
+ console:'sysoutdiv',
+ allowjavascript: true
+}
+</script>
+</head>
+<body>
+<script>
+SwingJS.getApplet('testApplet', Info)
+getClassList = function(){J2S._saveFile('_j2sclasslist.txt', Clazz.ClassFilesLoaded.sort().join('\n'))}
+</script>
+<div style="position:absolute;left:900px;top:30px;width:600px;height:300px;">
+<div id="sysoutdiv" contentEditable="true" style="border:1px solid green;width:100%;height:95%;overflow:auto"></div>
+This is System.out. <a href="javascript:testApplet._clearConsole()">clear it</a> <a href='javascript:J2S.getProfile()'>start/stop profiling</a><br>see <a href=___j2sflags.htm>___j2sflags.htm</a> for SwingJS URL command-line options<br><a href="javascript:getClassList()">get _j2sClassList.txt</a>
+</div>
+</body>
+</html>
import jalview.datamodel.AlignmentAnnotation;
import jalview.datamodel.Annotation;
+import jalview.datamodel.HiddenMarkovModel;
import jalview.datamodel.Profile;
import jalview.datamodel.ProfileI;
+import jalview.datamodel.Profiles;
import jalview.datamodel.ProfilesI;
import jalview.datamodel.ResidueCount;
import jalview.datamodel.Sequence;
import jalview.datamodel.SequenceI;
import jalview.gui.JvOptionPane;
+import jalview.io.DataSourceType;
+import jalview.io.FileParse;
+import jalview.io.HMMFile;
+
+import java.io.IOException;
+import java.net.MalformedURLException;
import java.util.Hashtable;
public class AAFrequencyTest
{
+ HiddenMarkovModel hmm;
@BeforeClass(alwaysRun = true)
public void setUpJvOptionPane()
JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
}
+ @BeforeClass(alwaysRun = true)
+ public void setUp() throws IOException, MalformedURLException
+ {
+ /*
+ * load a dna (ACGT) HMM file to a HiddenMarkovModel
+ */
+ HMMFile hmmFile = new HMMFile(new FileParse(
+ "test/jalview/io/test_MADE1_hmm.txt", DataSourceType.FILE));
+ hmm = hmmFile.getHMM();
+ }
+
@Test(groups = { "Functional" })
public void testCalculate_noProfile()
{
encoded2, 58, encoded1, 25, encoded3, 7 };
org.testng.Assert.assertEquals(extracted, expected);
}
+
+ @Test(groups = { "Functional" })
+ public void testExtractHMMProfile()
+ throws MalformedURLException, IOException
+ {
+ int[] expected = { 0, 4, 100, 'T', 71, 'C', 12, 'G', 9, 'A', 9 };
+ int[] actual = AAFrequency.extractHMMProfile(hmm, 17, false, false);
+ for (int i = 0; i < actual.length; i++)
+ {
+ if (i == 2)
+ {
+ assertEquals(actual[i], expected[i]);
+ }
+ else
+ {
+ assertEquals(actual[i], expected[i]);
+ }
+ }
+
+ int[] expected2 = { 0, 4, 100, 'A', 85, 'C', 0, 'G', 0, 'T', 0 };
+ int[] actual2 = AAFrequency.extractHMMProfile(hmm, 2, true, false);
+ for (int i = 0; i < actual2.length; i++)
+ {
+ if (i == 2)
+ {
+ assertEquals(actual[i], expected[i]);
+ }
+ else
+ {
+ assertEquals(actual[i], expected[i]);
+ }
+ }
+
+ assertNull(AAFrequency.extractHMMProfile(null, 98978867, true, false));
+ }
+
+ @Test(groups = { "Functional" })
+ public void testGetAnalogueCount()
+ {
+ /*
+ * 'T' in column 0 has emission probability 0.7859, scales to 7859
+ */
+ int count = AAFrequency.getAnalogueCount(hmm, 0, 'T', false, false);
+ assertEquals(7859, count);
+
+ /*
+ * same with 'use info height': value is multiplied by log ratio
+ * log(value / background) / log(2) = log(0.7859/0.25)/0.693
+ * = log(3.1)/0.693 = 1.145/0.693 = 1.66
+ * so value becomes 1.2987 and scales up to 12987
+ */
+ count = AAFrequency.getAnalogueCount(hmm, 0, 'T', false, true);
+ assertEquals(12987, count);
+
+ /*
+ * 'G' in column 20 has emission probability 0.75457, scales to 7546
+ */
+ count = AAFrequency.getAnalogueCount(hmm, 20, 'G', false, false);
+ assertEquals(7546, count);
+
+ /*
+ * 'G' in column 1077 has emission probability 0.0533, here
+ * ignored (set to 0) since below background of 0.25
+ */
+ count = AAFrequency.getAnalogueCount(hmm, 1077, 'G', true, false);
+ assertEquals(0, count);
+ }
+
+ @Test(groups = { "Functional" })
+ public void testCompleteInformation()
+ {
+ ProfileI prof1 = new Profile(1, 0, 100, "A");
+ ProfileI prof2 = new Profile(1, 0, 100, "-");
+
+ ProfilesI profs = new Profiles(new ProfileI[] { prof1, prof2 });
+ Annotation ann1 = new Annotation(6.5f);
+ Annotation ann2 = new Annotation(0f);
+ Annotation[] annots = new Annotation[] { ann1, ann2 };
+ SequenceI seq = new Sequence("", "AA", 0, 0);
+ seq.setHMM(hmm);
+ AlignmentAnnotation annot = new AlignmentAnnotation("", "", annots);
+ annot.setSequenceRef(seq);
+ AAFrequency.completeInformation(annot, profs, 0, 1);
+ float ic = annot.annotations[0].value;
+ assertEquals(0.91532f, ic, 0.0001f);
+ ic = annot.annotations[1].value;
+ assertEquals(0f, ic, 0.0001f);
+ int i = 0;
+ }
}
import java.util.Locale;
-import jalview.datamodel.Alignment;
-import jalview.datamodel.AlignmentI;
-import jalview.datamodel.Sequence;
-import jalview.datamodel.SequenceI;
-import jalview.gui.JvOptionPane;
-import jalview.io.FastaFile;
-
import java.io.File;
import java.io.FileNotFoundException;
import java.io.PrintStream;
import java.util.Arrays;
import java.util.Random;
-import org.testng.annotations.BeforeClass;
+import jalview.datamodel.Alignment;
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.Sequence;
+import jalview.datamodel.SequenceI;
+import jalview.io.FastaFile;
/**
* Generates, and outputs in Fasta format, a random peptide or nucleotide alignment for given
/*
* sort with no score features does nothing
*/
- PA.setValue(AlignmentSorter.class, "sortByFeatureCriteria", null);
+ PA.setValue(AlignmentSorter.getInstance(), "sortByFeatureCriteria", null);
AlignmentSorter.sortByFeature(null, null, 0, al.getWidth(), al,
AlignmentSorter.FEATURE_SCORE);
* sort by ascending score, no filter on feature type or group
* NB sort order for the same feature set (none) gets toggled, so descending
*/
- PA.setValue(AlignmentSorter.class, "sortByFeatureAscending", true);
+ PA.setValue(AlignmentSorter.getInstance(), "sortByFeatureAscending", true);
AlignmentSorter.sortByFeature(null, null, 0, al.getWidth(), al,
AlignmentSorter.FEATURE_SCORE);
assertSame(al.getSequenceAt(3), seq3); // -0.5
import static org.testng.AssertJUnit.assertSame;
import static org.testng.AssertJUnit.assertTrue;
-import jalview.analysis.AlignmentUtils.DnaVariant;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
+
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
import jalview.datamodel.AlignedCodonFrame;
import jalview.datamodel.Alignment;
import jalview.datamodel.AlignmentAnnotation;
import jalview.datamodel.Sequence;
import jalview.datamodel.SequenceFeature;
import jalview.datamodel.SequenceI;
-import jalview.datamodel.features.SequenceFeatures;
import jalview.gui.JvOptionPane;
import jalview.io.AppletFormatAdapter;
import jalview.io.DataSourceType;
import jalview.io.gff.SequenceOntologyI;
import jalview.util.MapList;
import jalview.util.MappingUtils;
-import jalview.ws.params.InvalidArgumentException;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.TreeMap;
-
-import org.testng.annotations.BeforeClass;
-import org.testng.annotations.Test;
public class AlignmentUtilsTests
{
import static org.testng.AssertJUnit.assertSame;
import static org.testng.AssertJUnit.assertTrue;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
import jalview.datamodel.AlignedCodonFrame;
import jalview.datamodel.AlignedCodonFrame.SequenceToSequenceMapping;
import jalview.datamodel.Alignment;
import jalview.util.DBRefUtils;
import jalview.util.MapList;
import jalview.ws.SequenceFetcher;
-import jalview.ws.SequenceFetcherFactory;
-import jalview.ws.params.InvalidArgumentException;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-import org.testng.annotations.AfterClass;
-import org.testng.annotations.BeforeClass;
-import org.testng.annotations.Test;
public class CrossRefTest
{
return new SequenceI[] { pep1, pep2 };
}
};
- SequenceFetcherFactory.setSequenceFetcher(mockFetcher);
+ SequenceFetcher.setMockFetcher(mockFetcher);
/*
* find UNIPROT xrefs for nucleotide sequence
@AfterClass(alwaysRun = true)
public void tearDown()
{
- SequenceFetcherFactory.setSequenceFetcher(null);
+ SequenceFetcher.setMockFetcher(null);
}
/**
return new SequenceI[] { pep1, pep2 };
}
};
- SequenceFetcherFactory.setSequenceFetcher(mockFetcher);
+ SequenceFetcher.setMockFetcher(mockFetcher);
/*
* find UNIPROT xrefs for gene and transcripts
}
}
};
- SequenceFetcherFactory.setSequenceFetcher(mockFetcher);
+ SequenceFetcher.setMockFetcher(mockFetcher);
/*
* find EMBL xrefs for Uniprot seqs and verify that
public void setUp()
{
Cache.loadProperties("test/jalview/io/testProps.jvprops");
- Cache.applicationProperties.setProperty("PAD_GAPS",
+ Cache.setPropertyNoSave("PAD_GAPS",
Boolean.FALSE.toString());
//@formatter:off
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertTrue;
+import jalview.api.AlignViewportI;
import jalview.api.analysis.ScoreModelI;
import jalview.api.analysis.SimilarityParamsI;
import jalview.datamodel.Alignment;
import jalview.datamodel.SequenceFeature;
import jalview.datamodel.SequenceI;
import jalview.gui.AlignFrame;
-import jalview.gui.AlignViewport;
import jalview.gui.JvOptionPane;
import jalview.io.DataSourceType;
import jalview.io.FileLoader;
public void testFindDistances_withParams()
{
AlignFrame af = setupAlignmentView();
- AlignViewport viewport = af.getViewport();
+ AlignViewportI viewport = af.getViewport();
AlignmentView view = viewport.getAlignmentView(false);
ScoreModelI sm = new FeatureDistanceModel();
*/
package jalview.bin;
+import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.assertTrue;
import jalview.gui.JvOptionPane;
+import jalview.io.DataSourceType;
+import jalview.io.FileFormat;
+import jalview.io.FileFormatException;
+import jalview.io.FileFormatI;
+import jalview.io.FileFormats;
+import jalview.io.IdentifyFile;
import java.io.BufferedReader;
import java.io.File;
dataProvider = "headlessModeOutputOperationsData")
public void testHeadlessModeOutputOperations(String harg, String type,
String fileName, boolean withAWT, int expectedMinFileSize,
- int timeout)
+ int timeout, String fileFormatType)
{
String cmd = harg + type + " " + fileName;
// System.out.println(">>>>>>>>>>>>>>>> Command : " + cmd);
assertTrue(file.exists(), msg);
FileAssert.assertFile(file, msg);
FileAssert.assertMinLength(file, expectedMinFileSize);
+ if (fileFormatType!=null && fileFormatType.length()>0)
+ {
+ FileFormatI format = FileFormats.getInstance()
+ .forName(fileFormatType);
+ if (format!=null)
+ {
+ try
+ {
+ FileFormatI exportedType = new IdentifyFile()
+ .identify(file.getAbsolutePath(), DataSourceType.FILE);
+ assertEquals(exportedType, format,
+ "Exported file type was wrong");
+ } catch (FileFormatException e)
+ {
+ Assert.fail("Couldn't identify file " + file
+ + " as an alignment format", e);
+ }
+ }
+ }
if (worker != null && worker.exit == null)
{
worker.interrupt();
String workingDir = "test/jalview/bin/";
return new Object[][] { { "nodisplay -open examples/uniref50.fa",
" -eps", workingDir + "test_uniref50_out.eps", true,
- MINFILESIZE_BIG, TEST_TIMEOUT },
+ MINFILESIZE_BIG, TEST_TIMEOUT, null },
{ "nodisplay -open examples/uniref50.fa", " -eps",
workingDir + "test_uniref50_out.eps", false,
- MINFILESIZE_BIG, TEST_TIMEOUT },
+ MINFILESIZE_BIG, TEST_TIMEOUT, null },
{ "nogui -open examples/uniref50.fa", " -eps",
workingDir + "test_uniref50_out.eps", true, MINFILESIZE_BIG,
- TEST_TIMEOUT },
+ TEST_TIMEOUT, null },
{ "nogui -open examples/uniref50.fa", " -eps",
workingDir + "test_uniref50_out.eps", false,
- MINFILESIZE_BIG, TEST_TIMEOUT },
+ MINFILESIZE_BIG, TEST_TIMEOUT, null },
{ "headless -open examples/uniref50.fa", " -eps",
workingDir + "test_uniref50_out.eps", true, MINFILESIZE_BIG,
- TEST_TIMEOUT },
+ TEST_TIMEOUT, null },
{ "headless -open examples/uniref50.fa", " -svg",
workingDir + "test_uniref50_out.svg", false,
- MINFILESIZE_BIG, TEST_TIMEOUT },
+ MINFILESIZE_BIG, TEST_TIMEOUT, null },
{ "headless -open examples/uniref50.fa", " -png",
workingDir + "test_uniref50_out.png", true, MINFILESIZE_BIG,
- TEST_TIMEOUT },
+ TEST_TIMEOUT, null },
{ "headless -open examples/uniref50.fa", " -html",
workingDir + "test_uniref50_out.html", true,
- MINFILESIZE_BIG, TEST_TIMEOUT },
+ MINFILESIZE_BIG, TEST_TIMEOUT, null },
{ "headless -open examples/uniref50.fa", " -fasta",
workingDir + "test_uniref50_out.mfa", true, MINFILESIZE_SMALL,
- TEST_TIMEOUT },
+ TEST_TIMEOUT, FileFormat.Fasta.toString() },
{ "headless -open examples/uniref50.fa", " -clustal",
workingDir + "test_uniref50_out.aln", true, MINFILESIZE_SMALL,
- TEST_TIMEOUT },
+ TEST_TIMEOUT, FileFormat.Clustal.toString() },
{ "headless -open examples/uniref50.fa", " -msf",
workingDir + "test_uniref50_out.msf", true, MINFILESIZE_SMALL,
- TEST_TIMEOUT },
+ TEST_TIMEOUT, FileFormat.MSF.toString() },
{ "headless -open examples/uniref50.fa", " -pileup",
workingDir + "test_uniref50_out.aln", true, MINFILESIZE_SMALL,
- TEST_TIMEOUT },
+ TEST_TIMEOUT, FileFormat.Pileup.toString() },
{ "headless -open examples/uniref50.fa", " -pir",
workingDir + "test_uniref50_out.pir", true, MINFILESIZE_SMALL,
- TEST_TIMEOUT },
+ TEST_TIMEOUT, FileFormat.PIR.toString() },
{ "headless -open examples/uniref50.fa", " -pfam",
workingDir + "test_uniref50_out.pfam", true, MINFILESIZE_SMALL,
- TEST_TIMEOUT },
+ TEST_TIMEOUT, FileFormat.Pfam.toString() },
{ "headless -open examples/uniref50.fa", " -blc",
workingDir + "test_uniref50_out.blc", true, MINFILESIZE_SMALL,
- TEST_TIMEOUT },
+ TEST_TIMEOUT, FileFormat.BLC.toString() },
{ "headless -open examples/uniref50.fa", " -jalview",
workingDir + "test_uniref50_out.jvp", true, MINFILESIZE_SMALL,
- TEST_TIMEOUT }, };
+ TEST_TIMEOUT, FileFormat.Jalview.toString() }, };
}
}
createAnnotation(sq);
AlignmentAnnotation alc, alo = sq.getAnnotation()[0];
alc = new AlignmentAnnotation(alo);
+
+ // TODO: this only tests string equals (which is unreliable), should use
+ // refactored tests from StockholmFileTest
+ Assert.assertEquals(alc.toString(), alo.toString());
+
for (String key : alo.getProperties())
{
assertEquals("Property mismatch", alo.getProperty(key),
"Temperature Factor", null, false, seq, null);
assertNotNull(ala);
assertEquals(seq, ala.sequenceRef);
- assertEquals("", ala.calcId);
+ assertEquals("", ala.getCalcId());
+ }
+
+ @Test(groups = {"Functional"})
+ public void testUpdateFromOrAddAnnotation()
+ {
+ SequenceI seq = new Sequence("seq1", "FRMLPSRT-A--L-");
+ AlignmentI alignment = new Alignment(new SequenceI[] { seq });
+
+ AlignmentAnnotation ala = alignment.findOrCreateAnnotation(
+ "Temperature Factor", null, false, seq, null);
+
+ assertNotNull(ala);
+ assertEquals(seq, ala.sequenceRef);
+ assertEquals("", ala.getCalcId());
+
+ // Assuming findOrCreateForNullCalcId passed then this should work
+
+ assertTrue(ala == alignment.updateFromOrCopyAnnotation(ala));
+ AlignmentAnnotation updatedAla = new AlignmentAnnotation(ala);
+ updatedAla.description = "updated Description";
+ Assert.assertTrue(
+ ala == alignment.updateFromOrCopyAnnotation(updatedAla));
+ Assert.assertEquals(ala.toString(), updatedAla.toString());
+ updatedAla.calcId = "newCalcId";
+ AlignmentAnnotation newUpdatedAla = alignment
+ .updateFromOrCopyAnnotation(updatedAla);
+ Assert.assertTrue(updatedAla != newUpdatedAla);
+ Assert.assertEquals(updatedAla.toString(), newUpdatedAla.toString());
}
@Test(groups = "Functional")
import static org.testng.Assert.assertEquals;
import jalview.gui.AlignFrame;
-import jalview.gui.AlignViewport;
import jalview.gui.JvOptionPane;
import jalview.io.DataSourceType;
import jalview.io.FileLoader;
+import jalview.viewmodel.AlignmentViewport;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
{
AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
">s1\n0123456789\n", DataSourceType.PASTE);
- AlignViewport av = af.getViewport();
+ AlignmentViewport av = af.getViewport();
AlignmentView view = av.getAlignmentView(true);
/*
--- /dev/null
+package jalview.datamodel;
+
+import static org.testng.Assert.assertEquals;
+
+import jalview.io.DataSourceType;
+import jalview.io.FileParse;
+import jalview.io.HMMFile;
+
+import java.io.IOException;
+import java.net.MalformedURLException;
+
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+public class HMMNodeTest
+{
+ private HiddenMarkovModel hmm;
+
+ @BeforeClass(alwaysRun = true)
+ public void setUp() throws MalformedURLException, IOException
+ {
+ /*
+ * load hmm model of a Kinase domain to a HiddenMarkovModel
+ */
+ HMMFile file = new HMMFile(new FileParse(
+ "test/jalview/io/test_PKinase_hmm.txt", DataSourceType.FILE));
+ hmm = file.getHMM();
+ }
+
+ @Test(groups="Functional")
+ public void testGetMaxMatchEmissionIdex()
+ {
+ assertEquals(hmm.getAlphabetType(), "amino");
+ String symbols = hmm.getSymbols();
+
+ assertEquals(hmm.getNode(1).getMaxMatchEmissionIndex(),
+ symbols.indexOf('Y'));
+
+ assertEquals(hmm.getNode(17).getMaxMatchEmissionIndex(),
+ symbols.indexOf('K'));
+ }
+}
--- /dev/null
+package jalview.datamodel;
+
+import static org.testng.Assert.assertEquals;
+
+import jalview.io.DataSourceType;
+import jalview.io.FileParse;
+import jalview.io.HMMFile;
+import jalview.schemes.ResidueProperties;
+
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.util.Map;
+
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+public class HiddenMarkovModelTest {
+
+ HiddenMarkovModel hmm;
+
+ HiddenMarkovModel alignmentHmm;
+
+ @BeforeClass(alwaysRun = true)
+ public void setUp() throws MalformedURLException, IOException
+ {
+ /*
+ * load hmm model of a Kinase domain to a HiddenMarkovModel
+ */
+ HMMFile file = new HMMFile(new FileParse(
+ "test/jalview/io/test_PKinase_hmm.txt", DataSourceType.FILE));
+ hmm = file.getHMM();
+
+ // used to check if consensus sequence is automatically aligned with alignment
+ HMMFile alignmentTest = new HMMFile(
+ new FileParse("test/jalview/io/HMMAlignmentTestHMM.hmm",
+ DataSourceType.FILE));
+ alignmentHmm = alignmentTest.getHMM();
+ }
+
+ @Test(groups = "Functional")
+ public void testGetMatchEmissionProbabilities()
+ throws MalformedURLException, IOException
+ {
+ /*
+ * raw value in file is 3.67403
+ * saved as probability e^-X = 0.05259
+ */
+ double mep = hmm.getMatchEmissionProbability(0, 'R');
+ assertEquals(mep, 0.02537400637, 0.0001d);
+ assertEquals(mep, Math.pow(Math.E, -3.67403), 0.0001d);
+
+ mep = hmm.getMatchEmissionProbability(19, 'W');
+ assertEquals(mep, 0.00588228492, 0.0001d);
+ assertEquals(mep, Math.pow(Math.E, -5.13581), 0.0001d);
+
+ // column 160 is a gapped region of the model
+ mep = hmm.getMatchEmissionProbability(160, 'G');
+ assertEquals(mep, 0D, 0.0001d);
+
+ mep = hmm.getMatchEmissionProbability(475, 'A');
+ assertEquals(mep, 0.04995163708, 0.0001d);
+ assertEquals(mep, Math.pow(Math.E, -2.99670), 0.0001d);
+ }
+
+ @Test(groups = "Functional")
+ public void testGetInsertEmissionProbabilities()
+ {
+ double iep = hmm.getInsertEmissionProbability(2, 'A');
+ assertEquals(iep, Math.pow(Math.E, -2.68618), 0.0001d);
+ // symbol is not case-sensitive
+ assertEquals(iep, hmm.getInsertEmissionProbability(2, 'a'));
+
+ iep = hmm.getInsertEmissionProbability(5, 'T');
+ assertEquals(iep, Math.pow(Math.E, -2.77519), 0.0001d);
+
+ // column 161 is gapped in the hmm
+ iep = hmm.getInsertEmissionProbability(161, 'K');
+ assertEquals(iep, 0D, 0.0001d);
+
+ iep = hmm.getInsertEmissionProbability(472, 'L');
+ assertEquals(iep, Math.pow(Math.E, -2.69355), 0.0001d);
+ }
+
+ @Test(groups = "Functional")
+ public void testGetStateTransitionProbabilities()
+ {
+ // * in model file treated as negative infinity
+ double stp = hmm.getStateTransitionProbability(475,
+ HiddenMarkovModel.MATCHTODELETE);
+ assertEquals(stp, Double.NEGATIVE_INFINITY);
+
+ // file value is 5.01631, saved as e^-5.01631
+ stp = hmm.getStateTransitionProbability(8,
+ HiddenMarkovModel.MATCHTOINSERT);
+ assertEquals(stp, Math.pow(Math.E, -5.01631), 0.0001D);
+
+ stp = hmm.getStateTransitionProbability(36,
+ HiddenMarkovModel.MATCHTODELETE);
+ assertEquals(stp, Math.pow(Math.E, -5.73865), 0.0001D);
+
+ stp = hmm.getStateTransitionProbability(22,
+ HiddenMarkovModel.INSERTTOMATCH);
+ assertEquals(stp, Math.pow(Math.E, -0.61958), 0.0001D);
+
+ stp = hmm.getStateTransitionProbability(80,
+ HiddenMarkovModel.INSERTTOINSERT);
+ assertEquals(stp, Math.pow(Math.E, -0.77255), 0.0001D);
+
+ stp = hmm.getStateTransitionProbability(475,
+ HiddenMarkovModel.DELETETOMATCH);
+ assertEquals(stp, 1D, 0.0001D);
+
+ stp = hmm.getStateTransitionProbability(218,
+ HiddenMarkovModel.DELETETODELETE);
+ assertEquals(stp, Math.pow(Math.E, -0.95510), 0.0001D);
+ }
+
+ @Test(groups = "Functional")
+ public void testGetConsensusSequence()
+ {
+ SequenceI seq = hmm.getConsensusSequence();
+ String subStr = seq.getSequenceAsString().substring(0, 10);
+ assertEquals(subStr, "yelleklGsG");
+ subStr = seq.getSequenceAsString().substring(150, 161);
+ assertEquals(subStr, "-dllk------");
+
+ // test to see if consensus sequence maps to alignment correctly
+ // see HMMAlignmentTest.sto for corresponding alignment file
+ SequenceI seq2 = alignmentHmm.getConsensusSequence();
+ assertEquals(seq2.getCharAt(0), '-');
+ assertEquals(seq2.getCharAt(7), '-');
+ assertEquals(seq2.getCharAt(8), 's');
+
+ }
+
+ /**
+ * A rather pointless test that reproduces the code implemented and asserts
+ * the result is the same...
+ */
+ @Test(groups = "Functional")
+ public void testGetInformationContent()
+ {
+ /*
+ * information measure is sum over all symbols of
+ * emissionProb * log(emissionProb / background) / log(2)
+ */
+ Map<Character, Float> uniprotFreqs = ResidueProperties.backgroundFrequencies
+ .get("amino");
+ int col = 4;
+ float expected = 0f;
+ for (char aa : hmm.getSymbols().toCharArray())
+ {
+ double mep = hmm.getMatchEmissionProbability(col, aa);
+ float background = uniprotFreqs.get(aa);
+ expected += mep * Math.log(mep / background);
+ }
+ expected /= Math.log(2D);
+
+ float actual = hmm.getInformationContent(col);
+ assertEquals(actual, expected, 0.0001d);
+ }
+}
import jalview.gui.AlignViewport;
import jalview.gui.JvOptionPane;
+import jalview.viewmodel.AlignmentViewport;
import java.util.List;
* represent seqs 2-4 with seq3
* this hides seq2 and seq4 but not seq3
*/
- AlignViewport av = new AlignViewport(al);
+ AlignmentViewport av = new AlignViewport(al);
SequenceGroup sg = new SequenceGroup();
sg.addSequence(seqs[1], false);
sg.addSequence(seqs[2], false);
import jalview.datamodel.ResidueCount.SymbolCounts;
import jalview.gui.JvOptionPane;
+import java.util.Arrays;
+
import org.junit.Assert;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
assertEquals(rc.getCount('N'), 1);
assertEquals(rc.getCount('?'), 0);
assertEquals(rc.getCount('-'), 0);
+ assertEquals(rc.getTotalResidueCount(), 11);
assertFalse(rc.isCountingInts());
assertFalse(rc.isUsingOtherData());
assertEquals(rc.getCount(' '), 4);
assertEquals(rc.getCount('-'), 4);
assertEquals(rc.getCount('.'), 4);
+ assertEquals(rc.getTotalResidueCount(), 0);
assertFalse(rc.isUsingOtherData());
assertFalse(rc.isCountingInts());
assertEquals(rc.getCount('m'), 13);
assertEquals(rc.getCount('G'), 0);
assertEquals(rc.getCount('-'), 0);
+ assertEquals(rc.getTotalResidueCount(), 27);
assertFalse(rc.isCountingInts());
assertFalse(rc.isUsingOtherData());
assertEquals(rc.getCount('?'), 6);
assertEquals(rc.getCount('!'), 7);
}
+
+ @Test(groups = "Functional")
+ public void testConstructor_forSequences()
+ {
+ SequenceI seq1 = new Sequence("seq1", "abcde--. FCD");
+ SequenceI seq2 = new Sequence("seq2", "ab.kKqBd-.");
+ ResidueCount rc = new ResidueCount(Arrays.asList(seq1, seq2));
+
+ assertEquals(rc.getGapCount(), 7);
+ assertEquals(rc.getTotalResidueCount(), 15); // excludes gaps
+ assertEquals(rc.getCount('a'), 2);
+ assertEquals(rc.getCount('A'), 2);
+ assertEquals(rc.getCount('B'), 3);
+ assertEquals(rc.getCount('c'), 2);
+ assertEquals(rc.getCount('D'), 3);
+ assertEquals(rc.getCount('f'), 1);
+ assertEquals(rc.getCount('K'), 2);
+ assertEquals(rc.getCount('Q'), 1);
+ }
}
sg.setDisplayBoxes(false);
sg.setDisplayText(false);
sg.setColourText(true);
- sg.isDefined = true;
+ PA.setValue(sg, "isDefined", true);
sg.setShowNonconserved(true);
sg.setOutlineColour(Color.red);
sg.setIdColour(Color.blue);
{
SequenceI s1 = new Sequence("abcde", "fg");
SequenceI s2 = new Sequence("foo", "bar");
- List<SequenceI> seqs = new ArrayList<SequenceI>();
+ List<SequenceI> seqs = new ArrayList<>();
seqs.add(s1);
seqs.add(s2);
SequenceGroup sg = new SequenceGroup(seqs);
import static org.testng.AssertJUnit.assertSame;
import static org.testng.AssertJUnit.assertTrue;
-import jalview.analysis.AlignmentGenerator;
-import jalview.commands.EditCommand;
-import jalview.commands.EditCommand.Action;
-import jalview.datamodel.PDBEntry.Type;
-import jalview.gui.JvOptionPane;
-import jalview.util.MapList;
-import jalview.ws.params.InvalidArgumentException;
-
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
+import jalview.analysis.AlignmentGenerator;
+import jalview.commands.EditCommand;
+import jalview.commands.EditCommand.Action;
+import jalview.datamodel.PDBEntry.Type;
+import jalview.gui.JvOptionPane;
+import jalview.util.MapList;
+
import junit.extensions.PA;
public class SequenceTest
* invalid inputs
*/
assertNull(sq.findPositions(6, 5));
- assertNull(sq.findPositions(0, 5));
- assertNull(sq.findPositions(-1, 5));
/*
* all gapped ranges
assertEquals(new Range(11, 12), sq.findPositions(5, 10)); // DE
assertEquals(new Range(8, 13), sq.findPositions(1, 13)); // the lot
assertEquals(new Range(8, 13), sq.findPositions(1, 99));
+
+ /**
+ * now try on a sequence with no gaps
+ */
+ sq.createDatasetSequence();
+ assertEquals(new Range(8, 13),
+ sq.getDatasetSequence().findPositions(1, 99));
+ assertEquals(new Range(8, 13),
+ sq.getDatasetSequence().findPositions(0, 99));
+
}
/**
* Test the method that keeps attribute names in non-case-sensitive order,
* including handling of 'compound' names
*/
- @Test(groups="Functional")
+ @Test(groups = "Functional")
public void testAttributeNameComparator()
{
FeatureAttributes fa = FeatureAttributes.getInstance();
"comparator");
assertEquals(
- comp.compare(new String[] { "CSQ" }, new String[] { "csq" }), 0);
+ comp.compare(new String[]
+ { "CSQ" }, new String[] { "csq" }), 0);
- assertTrue(comp.compare(new String[] { "CSQ", "a" },
- new String[] { "csq" }) > 0);
+ assertTrue(
+ comp.compare(new String[]
+ { "CSQ", "a" }, new String[] { "csq" }) > 0);
- assertTrue(comp.compare(new String[] { "CSQ" }, new String[] { "csq",
- "b" }) < 0);
+ assertTrue(
+ comp.compare(new String[]
+ { "CSQ" }, new String[] { "csq", "b" }) < 0);
- assertTrue(comp.compare(new String[] { "CSQ", "AF" }, new String[] {
- "csq", "ac" }) > 0);
+ assertTrue(
+ comp.compare(new String[]
+ { "CSQ", "AF" }, new String[] { "csq", "ac" }) > 0);
- assertTrue(comp.compare(new String[] { "CSQ", "ac" }, new String[] {
- "csq", "AF" }) < 0);
+ assertTrue(
+ comp.compare(new String[]
+ { "CSQ", "ac" }, new String[] { "csq", "AF" }) < 0);
}
@Test(groups = "Functional")
"group");
sf.setValue("kd", "-1");
sf.setValue("domain", "Metal");
+ sf.setValue("foo", " ");
sf.setValue("phase", "1");
- sf.setValue("phase", "reverse");
+ sf.setValue("phase", "1reverse");
assertEquals(fa.getDatatype("Pfam", "kd"), Datatype.Number);
assertEquals(fa.getDatatype("Pfam", "domain"), Datatype.Character);
assertEquals(fa.getDatatype("Pfam", "phase"), Datatype.Mixed);
+ assertNull(fa.getDatatype("Pfam", "unobserved"));
+ assertNull(fa.getDatatype("Pfam", "foo"));// empty values are ignored
}
}
@BeforeClass(alwaysRun = true)
public void setUp()
{
- SequenceOntologyFactory.setInstance(new SequenceOntologyLite());
+ SequenceOntologyFactory.setSequenceOntology(new SequenceOntologyLite());
}
@AfterClass(alwaysRun = true)
public void tearDown()
{
- SequenceOntologyFactory.setInstance(null);
+ SequenceOntologyFactory.setSequenceOntology(null);
}
/**
@BeforeClass(alwaysRun = true)
public void setUp()
{
- SequenceOntologyFactory.setInstance(new SequenceOntologyLite());
+ SequenceOntologyFactory.setSequenceOntology(new SequenceOntologyLite());
}
@AfterClass(alwaysRun = true)
public void tearDown()
{
- SequenceOntologyFactory.setInstance(null);
+ SequenceOntologyFactory.setSequenceOntology(null);
}
/**
public void setUp()
{
Cache.loadProperties("test/jalview/io/testProps.jvprops");
- SequenceOntologyFactory.setInstance(new SequenceOntologyLite());
+ SequenceOntologyFactory.setSequenceOntology(new SequenceOntologyLite());
}
@AfterClass(alwaysRun = true)
public void tearDown()
{
- SequenceOntologyFactory.setInstance(null);
+ SequenceOntologyFactory.setSequenceOntology(null);
}
/**
@BeforeClass(alwaysRun = true)
public void setUp()
{
- SequenceOntologyFactory.setInstance(new SequenceOntologyLite());
+ SequenceOntologyFactory.setSequenceOntology(new SequenceOntologyLite());
}
@AfterClass(alwaysRun = true)
public void tearDown()
{
- SequenceOntologyFactory.setInstance(null);
+ SequenceOntologyFactory.setSequenceOntology(null);
}
/**
@BeforeClass(alwaysRun = true)
public void setUp()
{
- SequenceOntologyFactory.setInstance(new SequenceOntologyLite());
+ SequenceOntologyFactory.setSequenceOntology(new SequenceOntologyLite());
}
@AfterClass(alwaysRun = true)
public void tearDown()
{
- SequenceOntologyFactory.setInstance(null);
+ SequenceOntologyFactory.setSequenceOntology(null);
}
@DataProvider(name = "ens_seqs")
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
-
import jalview.datamodel.Alignment;
import jalview.datamodel.AlignmentI;
import jalview.datamodel.ColumnSelection;
import jalview.structure.StructureMapping;
import jalview.structure.StructureSelectionManager;
+
public class JmolCommandsTest
{
private JmolCommands testee;
SequenceI[][] seqs = new SequenceI[][] { { seq1 }, { seq2 } };
String[] files = new String[] { "seq1.pdb", "seq2.pdb" };
StructureSelectionManager ssm = new StructureSelectionManager();
-
/*
* map residues 1-10 to residues 21-30 (atoms 105-150) in structures
*/
StructureMapping sm2 = new StructureMapping(seq2, "seq2.pdb", "pdb2",
"B", map, null);
ssm.addStructureMapping(sm2);
-
String[] commands = testee.colourBySequence(ssm,
files,
seqs, sr, af.alignPanel);
assertEquals(commands.length, 2);
+ assertEquals(commands[0].commands.length, 1); // from 2.12 merge from 2.11.2
String chainACommand = commands[0];
// M colour is #82827d == (130, 130, 125) (see strand.html help page)
public void setUp()
{
Cache.loadProperties("test/jalview/io/testProps.jvprops");
- Cache.applicationProperties.setProperty("STRUCT_FROM_PDB",
+ Cache.setPropertyNoSave("STRUCT_FROM_PDB",
Boolean.TRUE.toString());
- Cache.applicationProperties.setProperty("ADD_TEMPFACT_ANN",
+ Cache.setPropertyNoSave("ADD_TEMPFACT_ANN",
Boolean.FALSE.toString());
- Cache.applicationProperties.setProperty("ADD_SS_ANN",
+ Cache.setPropertyNoSave("ADD_SS_ANN",
Boolean.TRUE.toString());
StructureImportSettings.setDefaultStructureFileFormat("PDB");
StructureImportSettings
@AfterClass(alwaysRun = true)
public static void tearDownAfterClass() throws Exception
{
- jalview.gui.Desktop.instance.closeAll_actionPerformed(null);
+ jalview.gui.Desktop.getInstance().closeAll_actionPerformed(null);
}
@Test(groups = { "Functional" })
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertTrue;
+
import java.awt.Color;
import java.util.HashMap;
import java.util.LinkedHashMap;
import jalview.structure.AtomSpecModel;
import jalview.structure.StructureCommand;
import jalview.structure.StructureCommandI;
-
public class ChimeraCommandsTest
{
private ChimeraCommands testee;
*/
Map<String, Map<Object, AtomSpecModel>> featuresMap = new LinkedHashMap<>();
Map<Object, AtomSpecModel> featureValues = new HashMap<>();
-
/*
* start with just one feature/value...
*/
model.addRange("5", 25, 35, " ");
assertEquals(testee.getAtomSpec(model, false),
"#0:1-4.B,3-10.C|#1:2-5.A,8.A,5-10.B|#5:25-35.");
-
}
@Test(groups = { "Functional" })
@AfterClass(alwaysRun = true)
public static void tearDownAfterClass() throws Exception
{
- Desktop.instance.closeAll_actionPerformed(null);
+ Desktop.getInstance().closeAll_actionPerformed(null);
}
@AfterMethod(alwaysRun = true)
import static org.testng.AssertJUnit.assertEquals;
import static org.testng.AssertJUnit.assertTrue;
-import jalview.gui.JvOptionPane;
-
-import javax.swing.JComboBox;
import javax.swing.JInternalFrame;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
+import jalview.gui.JvOptionPane;
import junit.extensions.PA;
public class PDBFTSPanelTest
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
+import jalview.api.AlignViewportI;
import jalview.api.FeatureColourI;
import jalview.bin.Cache;
import jalview.bin.Jalview;
import jalview.schemes.StrandColourScheme;
import jalview.schemes.TurnColourScheme;
import jalview.util.MessageManager;
+import jalview.viewmodel.AlignmentViewport;
public class AlignFrameTest
{
@AfterMethod(alwaysRun = true)
public void tearDown()
{
- Desktop.instance.closeAll_actionPerformed(null);
+ Desktop.getInstance().closeAll_actionPerformed(null);
}
/**
public void setUp()
{
Cache.loadProperties("test/jalview/io/testProps.jvprops");
- Cache.applicationProperties.setProperty("SHOW_IDENTITY",
+ Cache.setPropertyNoSave("SHOW_IDENTITY",
Boolean.TRUE.toString());
af = new FileLoader().LoadFileWaitTillLoaded("examples/uniref50.fa",
DataSourceType.FILE);
@Test(groups = "Functional")
public void testChangeColour_background_groupsAndThresholds()
{
- AlignViewport av = af.getViewport();
+ AlignViewportI av = af.getViewport();
AlignmentI al = av.getAlignment();
/*
@Test(groups = "Functional")
public void testColourThresholdActions()
{
- AlignViewport av = af.getViewport();
+ AlignViewportI av = af.getViewport();
AlignmentI al = av.getAlignment();
/*
@Test(groups = "Functional")
public void testNewView_colourThresholds()
{
- AlignViewport av = af.getViewport();
+ AlignViewportI av = af.getViewport();
AlignmentI al = av.getAlignment();
/*
*/
af.newView_actionPerformed(null);
assertEquals(af.alignPanel.getViewName(), "View 1");
- AlignViewport av2 = af.getViewport();
+ AlignmentViewport av2 = af.getViewport();
assertNotSame(av, av2);
assertSame(av2, af.alignPanel.av);
rs = av2.getResidueShading();
import static org.testng.AssertJUnit.assertSame;
import static org.testng.AssertJUnit.assertTrue;
+import jalview.api.AlignViewportI;
import java.util.ArrayList;
import java.util.List;
import jalview.schemes.PIDColourScheme;
import jalview.structure.StructureSelectionManager;
import jalview.util.MapList;
+import jalview.viewmodel.AlignmentViewport;
import jalview.viewmodel.ViewportRanges;
+import jalview.workers.AlignCalcManager;
public class AlignViewportTest
{
AlignmentI al;
- AlignViewport testee;
+ AlignmentViewport testee;
@BeforeClass(alwaysRun = true)
public static void setUpBeforeClass() throws Exception
{
- Jalview.main(new String[] { "-nonews", "-props",
+ Jalview.main(new String[] {
+ //"-jabaws", "none",
+ "-nonews", "-props",
"test/jalview/testProps.jvprops" });
/*
* remove any sequence mappings left lying around by other tests
*/
StructureSelectionManager ssm = StructureSelectionManager
- .getStructureSelectionManager(Desktop.instance);
+ .getStructureSelectionManager(Desktop.getInstance());
ssm.resetAll();
}
* mappings
*/
StructureSelectionManager ssm = StructureSelectionManager
- .getStructureSelectionManager(Desktop.instance);
+ .getStructureSelectionManager(Desktop.getInstance());
List<AlignedCodonFrame> sequenceMappings = ssm.getSequenceMappings();
assertEquals(2, sequenceMappings.size());
assertTrue(sequenceMappings.contains(acf1));
@Test(groups = { "Functional" })
public void testDeregisterMapping_withNoReference()
{
- Desktop d = Desktop.instance;
+ Desktop d = Desktop.getInstance();
assertNotNull(d);
StructureSelectionManager ssm = StructureSelectionManager
- .getStructureSelectionManager(Desktop.instance);
+ .getStructureSelectionManager(Desktop.getInstance());
ssm.resetAll();
AlignFrame af1 = new FileLoader().LoadFileWaitTillLoaded(
@Test(groups = { "Functional" })
public void testDeregisterMapping_withReference()
{
- Desktop d = Desktop.instance;
+ Desktop d = Desktop.getInstance();
assertNotNull(d);
StructureSelectionManager ssm = StructureSelectionManager
- .getStructureSelectionManager(Desktop.instance);
+ .getStructureSelectionManager(Desktop.getInstance());
ssm.resetAll();
AlignFrame af1 = new FileLoader().LoadFileWaitTillLoaded(
@Test(groups = { "Functional" }, timeOut=2000)
public void testUpdateConservation_qualityOnly()
{
- Cache.applicationProperties.setProperty("SHOW_ANNOTATIONS",
+ Cache.setPropertyNoSave("SHOW_ANNOTATIONS",
Boolean.TRUE.toString());
- Cache.applicationProperties.setProperty("SHOW_QUALITY",
+ Cache.setPropertyNoSave("SHOW_QUALITY",
Boolean.TRUE.toString());
- Cache.applicationProperties.setProperty("SHOW_CONSERVATION",
+ Cache.setPropertyNoSave("SHOW_CONSERVATION",
Boolean.FALSE.toString());
- Cache.applicationProperties.setProperty("SHOW_OCCUPANCY",
+ Cache.setPropertyNoSave("SHOW_OCCUPANCY",
Boolean.FALSE.toString());
- Cache.applicationProperties.setProperty("SHOW_IDENTITY",
+ Cache.setPropertyNoSave("SHOW_IDENTITY",
Boolean.FALSE.toString());
AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
"examples/uniref50.fa", DataSourceType.FILE);
{
synchronized (this)
{
- while (viewport.getCalcManager().isWorking())
+ System.out.print("waiting...");
+ int n = 3;
+ while (--n >= 0 || viewport.getCalcManager().isWorking())
{
try
{
+ System.out.print(((AlignCalcManager) viewport.getCalcManager()).getQueueLength());
wait(50);
} catch (InterruptedException e)
{
}
}
+ System.out.println("...done");
}
}
/*
* test for JAL-2283: don't inadvertently turn on colour by conservation
*/
- Cache.applicationProperties.setProperty("DEFAULT_COLOUR_PROT", "None");
- Cache.applicationProperties.setProperty("SHOW_CONSERVATION",
+ Cache.setPropertyNoSave("DEFAULT_COLOUR_PROT", "None");
+ Cache.setPropertyNoSave("SHOW_CONSERVATION",
Boolean.TRUE.toString());
AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
"examples/uniref50.fa", DataSourceType.FILE);
{
AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
"examples/uniref50.fa", DataSourceType.FILE);
- AlignViewport av = af.getViewport();
+ AlignViewportI av = af.getViewport();
SequenceGroup sg1 = new SequenceGroup();
SequenceGroup sg2 = new SequenceGroup();
SequenceGroup sg3 = new SequenceGroup();
jalview.bin.Cache.setProperty("SHOW_OCCUPANCY", Boolean.FALSE.toString());
AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
"examples/uniref50.fa", DataSourceType.FILE);
- AlignViewport av = af.getViewport();
- Assert.assertNull(av.getAlignmentGapAnnotation(), "Preference did not disable occupancy row.");
+ AlignViewportI av = af.getViewport();
+ Assert.assertNull(av.getAlignmentGapAnnotation(),
+ "Preference did not disable occupancy row.");
int c = 0;
for (AlignmentAnnotation aa : av.getAlignment().findAnnotations(null,
null, "Occupancy"))
af = new FileLoader().LoadFileWaitTillLoaded(
"examples/uniref50.fa", DataSourceType.FILE);
av = af.getViewport();
- Assert.assertNotNull(av.getAlignmentGapAnnotation(), "Preference did not enable occupancy row.");
+ Assert.assertNotNull(av.getAlignmentGapAnnotation(),
+ "Preference did not enable occupancy row.");
c = 0;
for (AlignmentAnnotation aa : av.getAlignment().findAnnotations(null,
null, av.getAlignmentGapAnnotation().label))
AlignViewport testme = af.getViewport();
waitForCalculations(testme);
SequenceI cons = testme.getConsensusSeq();
- assertEquals("A-C", cons.getSequenceAsString());
+ String s = cons.getSequenceAsString();
+ System.out.println("s is " + s);
+
+ assertEquals("A-C", s);
}
@Test(groups = { "Functional" })
import jalview.datamodel.SequenceI;
import jalview.io.DataSourceType;
import jalview.io.FileLoader;
+import jalview.util.Platform;
import jalview.viewmodel.ViewportRanges;
public class AlignmentPanelTest
@BeforeMethod(alwaysRun = true)
public void setUp() throws InvocationTargetException, InterruptedException
{
- Jalview.main(new String[] { "-nonews", "-props",
- "test/jalview/testProps.jvprops" });
+ Jalview.main(new String[] { "-nonews",
+ "-props", "test/jalview/testProps.jvprops",
+ "-jabaws", "none"});
- Cache.applicationProperties.setProperty("SHOW_IDENTITY",
+ Cache.setPropertyNoSave("SHOW_IDENTITY",
Boolean.TRUE.toString());
af = new FileLoader().LoadFileWaitTillLoaded("examples/uniref50.fa",
DataSourceType.FILE);
af.alignPanel.setScrollValues(-1, 5);
// setting -ve x value does not change residue
+ // no update necessary now
assertEquals(ranges.getEndRes(), oldres);
af.alignPanel.setScrollValues(0, 5);
-
+ // no update necessary now
// setting 0 as x value does not change residue
+ // no update necessary now
assertEquals(ranges.getEndRes(), oldres);
af.alignPanel.setScrollValues(5, 5);
// setting x value to 5 extends endRes by 5 residues
+ System.out.println(ranges);
+ // no update necessary now
assertEquals(ranges.getEndRes(), oldres + 5);
// scroll to position after hidden columns sets endres to oldres (width) +
// position
- int scrollpos = 60;
+
+ int scrollpos = 53; // was 60, but this is too high to allow full scrolling
+ // in Windows
af.getViewport().hideColumns(30, 50);
af.alignPanel.setScrollValues(scrollpos, 5);
+ // no update necessary now
assertEquals(ranges.getEndRes(), oldres + scrollpos);
// scroll to position within hidden columns, still sets endres to oldres +
af.getViewport().showAllHiddenColumns();
af.getViewport().hideColumns(30, 50);
af.alignPanel.setScrollValues(scrollpos, 5);
+ // no update necessary now
assertEquals(ranges.getEndRes(), oldres + scrollpos);
// scroll to position within <width> distance of the end of the alignment
scrollpos = 130;
af.getViewport().showAllHiddenColumns();
af.alignPanel.setScrollValues(scrollpos, 5);
- assertEquals(ranges.getEndRes(), af.getViewport()
- .getAlignment().getWidth() - 1);
+ // no update necessary now
+ assertEquals(ranges.getEndRes(),
+ af.getViewport().getAlignment().getWidth() - 1);
// now hide some columns, and scroll to position within <width>
// distance of the end of the alignment
// columns
af.getViewport().hideColumns(30, 50);
af.alignPanel.setScrollValues(scrollpos, 5);
- assertEquals(ranges.getEndRes(), af.getViewport()
- .getAlignment().getWidth() - 1 - 21); // 21 is the number of hidden
- // columns
+ // no update necessary now
+ assertEquals(ranges.getEndRes(),
+ af.getViewport().getAlignment().getWidth() - 1 - 21); // 21 is the
+ // number of
+ // hidden
+ // columns
}
/**
* note 4 pixels padding are added to the longest sequence name width
*/
av.setIdWidth(-1); // force recalculation
+
d = af.alignPanel.calculateIdWidth();
- assertEquals(d.width, 166); // 4 + pixel width of "Q93Z60_ARATH/1-118"
+ assertEquals(d.width, Platform.isWin() ? 172 : 166); // 4 + pixel width of "Q93Z60_ARATH/1-118"
assertEquals(d.height, 12);
assertEquals(d.width, av.getIdWidth());
}
* note 4 pixels 'padding' are added to the longest seq name/annotation label
*/
Dimension d = af.alignPanel.calculateIdWidth(2000);
- assertEquals(d.width, 166); // 4 + pixel width of "Q93Z60_ARATH/1-118"
+ assertEquals(d.width, Platform.isWin() ? 172 : 166); // 4 + pixel width of "Q93Z60_ARATH/1-118"
assertEquals(d.height, 12); // fixed value (not used?)
assertEquals(av.getIdWidth(), 18); // not changed by this method
*/
SequenceI seq = af.viewport.getAlignment()
.findSequenceMatch("Q93Z60_ARATH")[0];
- seq.setName(seq.getName() + "MMMMM");
+ String orig = seq.getName();
+ seq.setName(orig + "MMMMM");
d = af.alignPanel.calculateIdWidth(2000);
- assertEquals(d.width, 211); // 4 + pixel width of "Q93Z60_ARATHMMMMM/1-118"
+ assertEquals(d.width, Platform.isWin() ? 219 : 211); // 4 + pixel width of "Q93Z60_ARATHMMMMM/1-118"
assertEquals(d.height, 12);
assertEquals(av.getIdWidth(), 18); // unchanged
+ // for next test:
+ seq.setName(orig);
/*
* make the longest annotation name even longer
FontMetrics fmfor = af.alignPanel
.getFontMetrics(af.alignPanel.getAlabels().getFont());
// Assumption ID_WIDTH_PADDING == 4
+ // AH! But with those added MMMM above, this was NOT the longest label!
int expwidth = 4 + fmfor.stringWidth(aa.label);
d = af.alignPanel.calculateIdWidth(2000);
- assertEquals(d.width, expwidth); // 228 == ID_WIDTH_PADDING + pixel width of "THIS IS A VERY LONG LABEL INDEED"
+ assertEquals(d.width, expwidth); // 191 == ID_WIDTH_PADDING + pixel width of "THIS IS A VERY LONG LABEL INDEED"
assertEquals(d.height, 12);
/*
* override with maxwidth
* note the 4 pixels padding is added to this value
*/
- d = af.alignPanel.calculateIdWidth(213);
- assertEquals(d.width, 217);
+ // BH but we have to be under the max width
+ d = af.alignPanel.calculateIdWidth(180);
+ assertEquals(d.width, 184);
assertEquals(d.height, 12);
}
*/
int w = af.alignPanel.getVisibleIdWidth(true);
assertEquals(w, af.alignPanel.getIdPanel().getWidth());
- assertEquals(w, 115);
+ assertEquals(w, Platform.isWin() ? 112 : 115);
/*
* width for offscreen rendering is the same
* preference for auto id width overrides fixed width
*/
Cache.setProperty("FIGURE_AUTOIDWIDTH", Boolean.TRUE.toString());
- assertEquals(115, af.alignPanel.getVisibleIdWidth(false));
+ assertEquals(Platform.isWin() ? 106 : 115, af.alignPanel.getVisibleIdWidth(false));
}
}
{
Cache.loadProperties("test/jalview/io/testProps.jvprops");
// pin down annotation sort order for test
- Cache.applicationProperties.setProperty(Preferences.SORT_ANNOTATIONS,
+ Cache.setPropertyNoSave(Preferences.SORT_ANNOTATIONS,
SequenceAnnotationOrder.NONE.name());
final String TRUE = Boolean.TRUE.toString();
- Cache.applicationProperties.setProperty(
+ Cache.setPropertyNoSave(
Preferences.SHOW_AUTOCALC_ABOVE, TRUE);
- Cache.applicationProperties.setProperty("SHOW_QUALITY", TRUE);
- Cache.applicationProperties.setProperty("SHOW_CONSERVATION", TRUE);
- Cache.applicationProperties.setProperty("SHOW_IDENTITY", TRUE);
+ Cache.setPropertyNoSave("SHOW_QUALITY", TRUE);
+ Cache.setPropertyNoSave("SHOW_CONSERVATION", TRUE);
+ Cache.setPropertyNoSave("SHOW_IDENTITY", TRUE);
AlignmentI al = new FormatAdapter().readFile(TEST_DATA,
DataSourceType.PASTE, FileFormat.Fasta);
{
Cache.loadProperties("test/jalview/io/testProps.jvprops");
// pin down annotation sort order for test
- Cache.applicationProperties.setProperty(Preferences.SORT_ANNOTATIONS,
+ Cache.setPropertyNoSave(Preferences.SORT_ANNOTATIONS,
SequenceAnnotationOrder.NONE.name());
final String TRUE = Boolean.TRUE.toString();
- Cache.applicationProperties.setProperty(Preferences.SHOW_AUTOCALC_ABOVE,
+ Cache.setPropertyNoSave(Preferences.SHOW_AUTOCALC_ABOVE,
TRUE);
- Cache.applicationProperties.setProperty("SHOW_QUALITY", TRUE);
- Cache.applicationProperties.setProperty("SHOW_CONSERVATION", TRUE);
- Cache.applicationProperties.setProperty("SHOW_IDENTITY", TRUE);
+ Cache.setPropertyNoSave("SHOW_QUALITY", TRUE);
+ Cache.setPropertyNoSave("SHOW_CONSERVATION", TRUE);
+ Cache.setPropertyNoSave("SHOW_IDENTITY", TRUE);
AlignmentI al = new FormatAdapter().readFile(TEST_DATA,
DataSourceType.PASTE, FileFormat.Fasta);
public void setUp()
{
Cache.loadProperties("test/jalview/io/testProps.jvprops");
- Cache.applicationProperties.setProperty("SHOW_ANNOTATIONS",
+ Cache.setPropertyNoSave("SHOW_ANNOTATIONS",
Boolean.TRUE.toString());
- Cache.applicationProperties.setProperty(
+ Cache.setPropertyNoSave(
Preferences.SHOW_AUTOCALC_ABOVE, Boolean.TRUE.toString());
af = new FileLoader().LoadFileWaitTillLoaded("examples/uniref50.fa",
DataSourceType.FILE);
{
// read-only Jalview properties
Cache.loadProperties("test/jalview/io/testProps.jvprops");
- Cache.applicationProperties.setProperty("BLOSUM62_PCA_FOR_NUCLEOTIDE",
+ Cache.setPropertyNoSave("BLOSUM62_PCA_FOR_NUCLEOTIDE",
Boolean.FALSE.toString());
}
/*
* enable inclusion of BLOSUM62 for nucleotide PCA (JAL-2962)
*/
- Cache.applicationProperties.setProperty("BLOSUM62_PCA_FOR_NUCLEOTIDE",
+ Cache.setPropertyNoSave("BLOSUM62_PCA_FOR_NUCLEOTIDE",
Boolean.TRUE.toString());
/*
import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.assertTrue;
+
import java.awt.event.MouseEvent;
import java.io.File;
import java.io.IOException;
* maximum retained heap usage (in MB) for a passing test
*/
private static int MAX_RESIDUAL_HEAP = 45;
-
/**
* Configure (read-only) Jalview property settings for test
*/
new String[]
{ "-nonews", "-props", "test/jalview/testProps.jvprops" });
String True = Boolean.TRUE.toString();
- Cache.applicationProperties.setProperty("SHOW_ANNOTATIONS", True);
- Cache.applicationProperties.setProperty("SHOW_QUALITY", True);
- Cache.applicationProperties.setProperty("SHOW_CONSERVATION", True);
- Cache.applicationProperties.setProperty("SHOW_OCCUPANCY", True);
- Cache.applicationProperties.setProperty("SHOW_IDENTITY", True);
+ Cache.setPropertyNoSave("SHOW_ANNOTATIONS", True);
+ Cache.setPropertyNoSave("SHOW_QUALITY", True);
+ Cache.setPropertyNoSave("SHOW_CONSERVATION", True);
+ Cache.setPropertyNoSave("SHOW_OCCUPANCY", True);
+ Cache.setPropertyNoSave("SHOW_IDENTITY", True);
}
+ /**
+ * A simple test that memory is released when all windows are closed.
+ * <ul>
+ * <li>generates a reasonably large alignment and loads it</li>
+ * <li>performs various operations on the alignment</li>
+ * <li>closes all windows</li>
+ * <li>requests garbage collection</li>
+ * <li>asserts that the remaining memory footprint (heap usage) is 'not large'
+ * </li>
+ * </ul>
+ * If the test fails, this suggests that a reference to some large object
+ * (perhaps the alignment data, or some annotation / Tree / PCA data) has
+ * failed to be garbage collected. If this is the case, the heap will need to
+ * be inspected manually (suggest using jvisualvm) in order to track down
+ * where large objects are still referenced. The code (for example
+ * AlignmentViewport.dispose()) should then be updated to ensure references to
+ * large objects are set to null when they are no longer required.
+ *
+ * @throws IOException
+ */
@Test(groups = "Memory")
public void testFreeMemoryOnClose() throws IOException
{
File f = generateAlignment();
f.deleteOnExit();
+ long expectedMin = MAX_RESIDUAL_HEAP;
+ long usedMemoryAtStart=getUsedMemory();
+ if (usedMemoryAtStart>expectedMin)
+ {
+ System.err.println("used memory before test is "+usedMemoryAtStart+" > "+expectedMin+"MB .. adjusting minimum.");
+ expectedMin = usedMemoryAtStart;
+ }
doStuffInJalview(f);
- Desktop.instance.closeAll_actionPerformed(null);
+ Desktop.getInstance().closeAll_actionPerformed(null);
- checkUsedMemory(MAX_RESIDUAL_HEAP);
+ checkUsedMemory(expectedMin);
}
/**
long availableMemory = Runtime.getRuntime().totalMemory();
long freeMemory = Runtime.getRuntime().freeMemory();
long usedMemory = availableMemory - freeMemory;
-
return (int) (usedMemory / ONE_MB);
}
-
/**
* Requests garbage collection and then checks whether remaining memory in use
* is less than the expected value (in Megabytes)
JvSwingUtils.wrapTooltip(true, tip));
tip = "0123456789012345678901234567890123456789012345678901234567890"; // 61
- assertFalse(tip.equals(JvSwingUtils.wrapTooltip(false, tip)));
+
+ // n/a -- message is too long for "false"
+//
+// assertFalse(tip.equals(JvSwingUtils.wrapTooltip(false, tip)));
+//
+
assertFalse(("<html>" + tip + "</html>").equals(JvSwingUtils
.wrapTooltip(true, tip)));
}
public void testWrapTooltip_multilineShortText()
{
String tip = "Now is the winter of our discontent<br>Made glorious summer by this sun of York";
- assertEquals(tip, JvSwingUtils.wrapTooltip(false, tip));
- assertEquals("<html>" + tip + "</html>",
- JvSwingUtils.wrapTooltip(true, tip));
+ String tip2 = "Now is the winter of our discontent<br/>Made glorious summer by this sun of York";
+
+// BH not applicable in Jalview; "false" is only for when no <br> and only for short j2s2Discover messages
+//
+// String s = JvSwingUtils.wrapTooltip(false, tip);
+// System.out.println("<html>" + tip + "</html>");
+// assertEquals(tip, s);
+
+ String s;
+ s = JvSwingUtils.wrapTooltip(true, tip);
+ System.out.println(s);
+ assertEquals("<html>" + tip + "</html>", s);
+ s = JvSwingUtils.wrapTooltip(true, tip2);
+ System.out.println(s);
+ assertEquals("<html>" + tip + "</html>", s);
}
/**
@Test(groups = { "Functional" })
public void testWrapTooltip_longText()
{
+ // BH should work in Java and JavaScript
String tip = "Now is the winter of our discontent made glorious summer by this sun of York";
- String expected = "<style> div.ttip {width:350px;white-space:pre-wrap;padding:2px;overflow-wrap:break-word;}</style>"
- + "<div class=\"ttip\">" + tip + " </div>";
- assertEquals("<html>" + expected + "</html>",
- JvSwingUtils.wrapTooltip(true, tip));
- assertEquals(expected, JvSwingUtils.wrapTooltip(false, tip));
+ String expected = JvSwingUtils.HTML_PREFIX + tip + "</div></html>";
+ String s = JvSwingUtils.wrapTooltip(true, tip);
+ assertEquals(expected, s);
+ // BH not applicable in Jalview; "false" is only for when no <br> and only for short j2s2Discover messages
+// s = JvSwingUtils.wrapTooltip(false, tip);
+// assertEquals(expected, s);
}
}
import static org.testng.Assert.assertEquals;
+import jalview.api.AlignViewportI;
import jalview.datamodel.AlignmentI;
import jalview.datamodel.SequenceGroup;
import jalview.io.DataSourceType;
import jalview.io.FileLoader;
-
import javax.swing.JTextArea;
-import junit.extensions.PA;
-
import org.testng.annotations.Test;
+import junit.extensions.PA;
+
public class PairwiseAlignmentPanelTest
{
@Test(groups = "Functional")
{
AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
"examples/uniref50.fa", DataSourceType.FILE);
- AlignViewport viewport = af.getViewport();
+ AlignViewportI viewport = af.getViewport();
AlignmentI al = viewport.getAlignment();
/*
PairwiseAlignPanel testee = new PairwiseAlignPanel(viewport);
- String text = ((JTextArea) PA.getValue(testee, "textarea")).getText();
+ String text = ((JTextArea) PA.getValue(testee, "textarea")).getText().replace("\r\n", "\n");
String expected = "Score = 80.0\n" + "Length of alignment = 4\n"
+ "Sequence FER1_PEA/29-32 (Sequence length = 7)\n"
+ "Sequence Q93XJ9_SOLTU/23-26 (Sequence length = 7)\n\n"
String seqs = ">Q93XJ9_SOLTU/23-29\nL-KAISNV\n>FER1_PEA/26-32\nV-TTTKAF\n";
AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(seqs,
DataSourceType.PASTE);
- AlignViewport viewport = af.getViewport();
+ AlignViewportI viewport = af.getViewport();
PairwiseAlignPanel testee = new PairwiseAlignPanel(viewport);
- String text = ((JTextArea) PA.getValue(testee, "textarea")).getText();
+ String text = ((JTextArea) PA.getValue(testee, "textarea")).getText().replace("\r\n", "\n");
String expected = "Score = 80.0\n" + "Length of alignment = 4\n"
+ "Sequence FER1_PEA/29-32 (Sequence length = 7)\n"
+ "Sequence Q93XJ9_SOLTU/23-26 (Sequence length = 7)\n\n"
testee.configureReferenceAnnotationsMenu(menu, seqs);
assertTrue(menu.isEnabled());
String s = MessageManager.getString("label.add_annotations_for");
- String expected = "<html><style> div.ttip {width:350px;white-space:pre-wrap;padding:2px;overflow-wrap:break-word;}</style>"
- + "<div class=\"ttip\">" + s
- + "<br/>Jmol/secondary structure<br/>PDB/Temp </div></html>";
+// String expected = "<html><style> div.ttip {width:350px;white-space:pre-wrap;padding:2px;overflow-wrap:break-word;}</style>"
+// + "<div class=\"ttip\">" + s
+// + "<br/>Jmol/secondary structure<br/>PDB/Temp </div></html>";
+ String expected = "<html>" + s + "<br>Jmol/secondary structure<br>PDB/Temp</html>";
assertEquals(expected, menu.getToolTipText());
}
testee.configureReferenceAnnotationsMenu(menu, seqs);
assertTrue(menu.isEnabled());
String s = MessageManager.getString("label.add_annotations_for");
- String expected = "<html><style> div.ttip {width:350px;white-space:pre-wrap;padding:2px;overflow-wrap:break-word;}</style>"
- + "<div class=\"ttip\">" + s
- + "<br/>Jmol/secondary structure<br/>PDB/Temp </div></html>";
- assertEquals(expected, menu.getToolTipText());
+// String expected = "<html><style> div.ttip {width:350px;white-space:pre-wrap;padding:2px;overflow-wrap:break-word;}</style>"
+// + "<div class=\"ttip\">" + s
+// + "<br/>Jmol/secondary structure<br/>PDB/Temp</html>";
+ String expected = "<html>" + s
+ + "<br>Jmol/secondary structure<br>PDB/Temp</html>";
+ s = menu.getToolTipText();
+ assertEquals(expected, s);
}
/**
// PDB.secondary structure on Sequence0
AlignmentAnnotation annotation = new AlignmentAnnotation(
"secondary structure", "", 0);
+ annotation.annotations = new Annotation[] { new Annotation(2f) };
annotation.setCalcId("PDB");
seqs.get(0).getDatasetSequence().addAlignmentAnnotation(annotation);
if (addToSequence)
// PDB.Temp on Sequence1
annotation = new AlignmentAnnotation("Temp", "", 0);
annotation.setCalcId("PDB");
+ annotation.annotations = new Annotation[] { new Annotation(2f) };
seqs.get(1).getDatasetSequence().addAlignmentAnnotation(annotation);
if (addToSequence)
{
// JMOL.secondary structure on Sequence0
annotation = new AlignmentAnnotation("secondary structure", "", 0);
annotation.setCalcId("Jmol");
+ annotation.annotations = new Annotation[] { new Annotation(2f) };
seqs.get(0).getDatasetSequence().addAlignmentAnnotation(annotation);
if (addToSequence)
{
*/
package jalview.gui;
-import java.awt.Font;
-import java.awt.FontMetrics;
-
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.assertNull;
import static org.testng.Assert.assertTrue;
+import java.awt.Font;
+import java.awt.FontMetrics;
+
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
import jalview.bin.Cache;
import jalview.datamodel.AlignmentI;
import jalview.datamodel.SearchResults;
import jalview.datamodel.SearchResultsI;
import jalview.io.DataSourceType;
-import jalview.io.DataSourceType;
import jalview.io.FileLoader;
-
+import jalview.util.Platform;
+import jalview.viewmodel.ViewportRanges;
import junit.extensions.PA;
public class SeqCanvasTest
{
- private AlignFrame af;
+ @BeforeClass(alwaysRun = true)
+ public void setUp()
+ {
+ Cache.loadProperties(null);
+ Cache.initLogger();
+ Desktop.getInstance().setVisible(false);
+ }
/**
* Test the method that computes wrapped width in residues, height of wrapped
av.setFont(new Font("SansSerif", Font.PLAIN, 14), true);
int charHeight = av.getCharHeight();
int charWidth = av.getCharWidth();
- assertEquals(charHeight, 17);
- assertEquals(charWidth, 12);
+ assertEquals(charHeight, !Platform.isWin() ? 17 : 19);
+ assertEquals(charWidth, !Platform.isWin() ? 12 : 11);
/*
* first with scales above, left, right
av.setScaleRightWrapped(true);
FontMetrics fm = testee.getFontMetrics(av.getFont());
int labelWidth = fm.stringWidth("000") + charWidth;
- assertEquals(labelWidth, 39); // 3 x 9 + charWidth
+ assertEquals(labelWidth,
+ !Platform.isWin() ? 3 * 9 + charWidth : 3 * 8 + charWidth);
/*
* width 400 pixels leaves (400 - 2*labelWidth) for residue columns
canvasWidth += 2;
wrappedWidth = testee.calculateWrappedGeometry(canvasWidth,
canvasHeight);
- assertEquals(wrappedWidth, 24); // 2px not enough
+ assertEquals(wrappedWidth, !Platform.isWin() ? 24 : 25); // 2px not enough
canvasWidth += 1;
wrappedWidth = testee.calculateWrappedGeometry(canvasWidth,
canvasHeight);
av.setFont(new Font("SansSerif", Font.PLAIN, 14), true);
int charHeight = av.getCharHeight();
int charWidth = av.getCharWidth();
- assertEquals(charHeight, 17);
- assertEquals(charWidth, 12);
-
+ assertEquals(charHeight, !Platform.isWin() ? 17 : 19);
+ assertEquals(charWidth, !Platform.isWin() ? 12 : 11);
SeqCanvas testee = af.alignPanel.getSeqPanel().seqCanvas;
/*
av.setScaleRightWrapped(true);
FontMetrics fm = testee.getFontMetrics(av.getFont());
int labelWidth = fm.stringWidth("000") + charWidth;
- assertEquals(labelWidth, 39); // 3 x 9 + charWidth
+ assertEquals(labelWidth,
+ !Platform.isWin() ? 3 * 9 + charWidth : 3 * 8 + charWidth);
int annotationHeight = testee.getAnnotationHeight();
/*
@Test(groups = "Functional")
public void testClear_HighlightAndSelection()
{
+ AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
+ "examples/uniref50.fa", DataSourceType.FILE);
AlignViewport av = af.getViewport();
SearchResultsI highlight = new SearchResults();
highlight.addResult(
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
-
import jalview.api.AlignViewportI;
import jalview.bin.Cache;
import jalview.bin.Jalview;
import jalview.io.FileLoader;
import jalview.util.MessageManager;
import jalview.viewmodel.ViewportRanges;
+
+
import junit.extensions.PA;
public class SeqPanelTest
import static org.testng.Assert.assertEquals;
+import jalview.api.AlignViewportI;
import jalview.bin.Jalview;
import jalview.datamodel.Alignment;
import jalview.datamodel.AlignmentI;
public class SequenceRendererTest
{
AlignmentI al;
- AlignViewport av;
+ AlignViewportI av;
SequenceI seq1;
import static org.testng.AssertJUnit.assertNotNull;
import static org.testng.AssertJUnit.assertTrue;
+
import java.util.Collection;
import java.util.Vector;
upSeq_nocanonical.createDatasetSequence();
// not a canonical reference
upSeq_nocanonical.addDBRef(new DBRefEntry("UNIPROT","0","P38398",null,false));
-
}
@AfterMethod(alwaysRun = true)
}
}
-
-
@Test(groups = { "Functional" })
public void sanitizeSeqNameTest()
{
--- /dev/null
+package jalview.hmmer;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.fail;
+
+import jalview.bin.Jalview;
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.HiddenMarkovModel;
+import jalview.datamodel.SequenceI;
+import jalview.gui.AlignFrame;
+import jalview.gui.Desktop;
+import jalview.io.HMMFile;
+import jalview.util.MessageManager;
+import jalview.ws.params.ArgumentI;
+import jalview.ws.params.simple.Option;
+
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+public class HMMERTest {
+
+ AlignFrame frame;
+
+ @BeforeClass(alwaysRun = true)
+ public void setUpBeforeClass() throws Exception
+ {
+ /*
+ * NB: check HMMER_PATH in testProps.jvprops is valid for
+ * the machine on which this runs
+ */
+ Jalview.main(
+ new String[]
+ { "-noquestionnaire", "-nonews", "-props",
+ "test/jalview/hmmer/testProps.jvprops", "-open",
+ "examples/uniref50.fa" });
+ frame = Desktop.getAlignFrames()[0];
+ }
+
+ @AfterClass(alwaysRun = true)
+ public static void tearDownAfterClass() throws Exception
+ {
+ Desktop.getInstance().closeAll_actionPerformed(null);
+ }
+
+ /**
+ * Test with a dependency on locally installed hmmbuild binaries
+ *
+ * @throws MalformedURLException
+ * @throws IOException
+ */
+ @Test(groups = "External")
+ public void testHMMBuildThenHMMAlign()
+ throws MalformedURLException, IOException
+ {
+ /*
+ * run hmmbuild
+ */
+ testHMMBuild();
+ List<SequenceI> hmms = frame.getViewport().getAlignment()
+ .getHmmSequences();
+ assertFalse(hmms.isEmpty());
+
+ /*
+ * now run hmmalign - by default with respect to the added HMM profile
+ */
+ testHMMAlign();
+ }
+
+ public void testHMMBuild()
+ {
+ /*
+ * set up argument to run hmmbuild for the alignment
+ */
+ ArrayList<ArgumentI> params = new ArrayList<>();
+ String argName = MessageManager.getString("label.hmmbuild_for");
+ String argValue = MessageManager.getString("label.alignment");
+ params.add(
+ new Option(argName, null, false, null, argValue, null, null));
+
+ HMMBuild builder = new HMMBuild(frame, params);
+ builder.run();
+
+ SequenceI seq = frame.getViewport().getAlignment().getSequenceAt(0);
+ HiddenMarkovModel hmm = seq.getHMM();
+ assertNotNull(hmm);
+
+ assertEquals(hmm.getLength(), 148);
+ assertEquals(hmm.getAlphabetType(), "amino");
+ assertEquals(hmm.getName(), "Alignment_HMM");
+ assertEquals(hmm.getProperty(HMMFile.EFF_NUMBER_OF_SEQUENCES),
+ "0.648193");
+ }
+
+ public void testHMMAlign()
+ {
+ HmmerCommand thread = new HMMAlign(frame,
+ new ArrayList<ArgumentI>());
+ thread.run();
+
+ AlignFrame[] alignFrames = Desktop.getAlignFrames();
+ if (alignFrames == null)
+ {
+ fail("No align frame loaded");
+ }
+
+ /*
+ * now have the original align frame, and another for realigned sequences
+ */
+ assertEquals(alignFrames.length, 2);
+ AlignmentI original = alignFrames[0].getViewport().getAlignment();
+ assertNotNull(original);
+ AlignmentI realigned = alignFrames[1].getViewport().getAlignment();
+ assertNotNull(realigned);
+ assertFalse(original.getHmmSequences().isEmpty());
+ assertFalse(realigned.getHmmSequences().isEmpty());
+
+ SequenceI ferCapan = original.findName("FER_CAPAN");
+ assertTrue(ferCapan.getSequenceAsString().startsWith("MA------SVSAT"));
+
+ SequenceI ferCapanRealigned = realigned.findName("FER_CAPAN");
+ assertTrue(ferCapanRealigned.getSequenceAsString()
+ .startsWith("-------m-A----SVSAT"));
+ }
+}
+
--- /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_OCCUPANCY=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
+DAS_LOCAL_SOURCE=
+SCREEN_HEIGHT=650
+ANNOTATIONCOLOUR_MAX=ff0000
+AUTO_CALC_CONSENSUS=true
+FASTA_JVSUFFIX=true
+DAS_ACTIVE_SOURCE=uniprot\t
+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.dasregistry.org/das/ # retired 01/05/2015
+DAS_REGISTRY_URL=http\://www.ebi.ac.uk/das-srv/registry/das/
+logs.Jalview.level=DEBUG
+HMMER_PATH=/Users/gmcarstairs/software/hmmer-3.1b2-macosx-intel/binaries
@BeforeMethod(alwaysRun = true)
public void setup() throws Exception
{
- Cache.applicationProperties.setProperty("STRUCT_FROM_PDB",
+ Cache.setPropertyNoSave("STRUCT_FROM_PDB",
Boolean.TRUE.toString());
- Cache.applicationProperties.setProperty("ADD_SS_ANN",
+ Cache.setPropertyNoSave("ADD_SS_ANN",
Boolean.TRUE.toString());
FileLoader loader = new FileLoader(false);
AlignFrame af = loader.LoadFileWaitTillLoaded("examples/1gaq.txt",
@AfterClass(alwaysRun = true)
public static void tearDownAfterClass() throws Exception
{
- jalview.gui.Desktop.instance.closeAll_actionPerformed(null);
+ jalview.gui.Desktop.getInstance().closeAll_actionPerformed(null);
}
--- /dev/null
+package jalview.io;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+
+import jalview.datamodel.SequenceFeature;
+import jalview.datamodel.SequenceI;
+import jalview.datamodel.features.SequenceFeaturesI;
+
+import java.io.IOException;
+import java.util.List;
+
+import org.testng.annotations.Test;
+
+public class BSMLFileTest
+{
+ @Test(groups="Functional")
+ public void testParse_BSML() throws IOException
+ {
+ //@formatter:off
+ String data = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n" +
+ "<Bsml>\r\n" +
+ " <Definitions>\r\n" +
+ " <Sequences>\r\n" +
+ " <Sequence\r\n" +
+ " comment=\"Sequence Data Contained in 'Multiple-alignment' section\"\r\n" +
+ " id=\"SEQ-ID:181170\" length=\"30\" molecule=\"dna\" title=\"EP1\">\r\n" +
+ " <Feature-tables>\r\n" +
+ " <Feature-table title=\"GENE\">\r\n" +
+ " <Feature class=\"GENE\" title=\"TEST-001\">\r\n" +
+ " <Interval-loc complement=\"0\" endpos=\"20\" startpos=\"10\"/>\r\n" +
+ " <Resource id=\"GENE-ID:181171\"/>\r\n" +
+ " </Feature>\r\n" +
+ " </Feature-table>\r\n" +
+ " </Feature-tables>\r\n" +
+ " </Sequence>\r\n" +
+ " </Sequences>\r\n" +
+ " <Tables>\r\n" +
+ " <Multiple-alignment-table molecule-type=\"nucleotide\">\r\n" +
+ " <Sequence-alignment sequences=\"1\">\r\n" +
+ " <Sequence-data seq-name=\"EP1\">--AATTTT-ATTTAGTGTCT-----------</Sequence-data>\r\n" +
+ " <Alignment-consensus/>\r\n" +
+ " </Sequence-alignment>\r\n" +
+ " </Multiple-alignment-table>\r\n" +
+ " </Tables>\r\n" +
+ " <Notebook notebook=\"\"/>\r\n" +
+ " </Definitions>\r\n" +
+ "</Bsml>\r\n" +
+ "";
+ BSMLFile cf = new BSMLFile(data, DataSourceType.PASTE);
+// why twice? cf.parse();
+ SequenceI[] seqs = cf.getSeqsAsArray();
+ assertEquals(seqs.length, 1);
+ SequenceI seq = seqs[0];
+ assertEquals(seq.getName(), "EP1");
+ assertEquals(seq.getStart(), 1);
+ assertEquals(seq.getEnd(), 31);
+ assertTrue(seq.getSequenceAsString().equals("--AATTTT-ATTTAGTGTCT-----------"));
+ SequenceFeaturesI features = seq.getFeatures();
+ List<SequenceFeature> genes = features.getAllFeatures("GENE");
+ assertEquals(genes.size(), 1);
+ SequenceFeature sf = genes.get(0);
+ assertEquals(sf.getDescription(), "TEST-001");
+ assertEquals(sf.begin + "," + sf.end, "10,20");
+
+ }
+
+}
{
Cache.loadProperties(propsFile);
- Cache.applicationProperties.setProperty(BackupFiles.ENABLED,
+ Cache.setPropertyNoSave(BackupFiles.ENABLED,
Boolean.toString(enabled));
- Cache.applicationProperties.setProperty(
+ Cache.setPropertyNoSave(
BackupFilesPresetEntry.SAVEDCONFIG, bfpe.toString());
/*
- Cache.applicationProperties.setProperty(BackupFiles.ENABLED,
+ Cache.setPropertyNoSave(BackupFiles.ENABLED,
Boolean.toString(enabled));
- Cache.applicationProperties.setProperty(BackupFiles.SUFFIX, suffix);
- Cache.applicationProperties.setProperty(BackupFiles.SUFFIX_DIGITS,
+ Cache.setPropertyNoSave(BackupFiles.SUFFIX, suffix);
+ Cache.setPropertyNoSave(BackupFiles.SUFFIX_DIGITS,
Integer.toString(digits));
- Cache.applicationProperties.setProperty(BackupFiles.REVERSE_ORDER,
+ Cache.setPropertyNoSave(BackupFiles.REVERSE_ORDER,
Boolean.toString(reverse));
- Cache.applicationProperties.setProperty(BackupFiles.NO_MAX,
+ Cache.setPropertyNoSave(BackupFiles.NO_MAX,
Boolean.toString(noMax));
- Cache.applicationProperties.setProperty(BackupFiles.ROLL_MAX,
+ Cache.setPropertyNoSave(BackupFiles.ROLL_MAX,
Integer.toString(rollMax));
- Cache.applicationProperties.setProperty(BackupFiles.CONFIRM_DELETE_OLD,
+ Cache.setPropertyNoSave(BackupFiles.CONFIRM_DELETE_OLD,
"false");
*/
}
{
// retrieve dbref
- SequenceFetcher sf = new SequenceFetcher(Desktop.instance,
+ SequenceFetcher sf = new SequenceFetcher(Desktop.getInstance(),
forSource, forAccession);
sf.run();
AlignFrame[] afs = Desktop.getAlignFrames();
}
else
{
- Desktop.instance.closeAll_actionPerformed(null);
+ Desktop.getInstance().closeAll_actionPerformed(null);
// recover stored project
af = new FileLoader(false).LoadFileWaitTillLoaded(
savedProjects.get(first).toString(), DataSourceType.FILE);
}
else
{
- Desktop.instance.closeAll_actionPerformed(null);
+ Desktop.getInstance().closeAll_actionPerformed(null);
pass3 = 0;
// recover stored project
File storedProject = savedProjects.get(nextxref);
}
else
{
- Desktop.instance.closeAll_actionPerformed(null);
+ Desktop.getInstance().closeAll_actionPerformed(null);
// recover stored project
File storedProject = savedProjects.get(nextnextxref);
if (storedProject == null)
* remove any sequence mappings created so they don't pollute other tests
*/
StructureSelectionManager ssm = StructureSelectionManager
- .getStructureSelectionManager(Desktop.instance);
+ .getStructureSelectionManager(Desktop.getInstance());
ssm.resetAll();
}
package jalview.io;
-import java.util.Locale;
-
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertNotEquals;
public void testIsIdentifiable()
{
FileFormats formats = FileFormats.getInstance();
- assertTrue(formats
- .isIdentifiable(formats.forName(FileFormat.Fasta.getName())));
- assertTrue(formats
- .isIdentifiable(formats.forName(FileFormat.MMCif.getName())));
- assertTrue(formats
- .isIdentifiable(formats.forName(FileFormat.Jnet.getName())));
- assertTrue(formats
- .isIdentifiable(formats.forName(FileFormat.Jalview.getName())));
- // GenBank/ENA
+ assertTrue(formats.isIdentifiable(formats.forName(FileFormat.Fasta
+ .getName())));
+ assertTrue(formats.isIdentifiable(formats.forName(FileFormat.MMCif
+ .getName())));
+ assertTrue(formats.isIdentifiable(formats.forName(FileFormat.Jnet
+ .getName())));
+ assertTrue(formats.isIdentifiable(formats.forName(FileFormat.Jalview
+ .getName())));
assertFalse(formats.isIdentifiable(null));
/*
@Test(groups = "Functional")
public void testGetWritableFormats()
{
- String expected = "[Fasta, PFAM, Stockholm, PIR, BLC, AMSA, JSON, PileUp, MSF, Clustal, PHYLIP]";
+ String expected = "[Fasta, PFAM, Stockholm, PIR, BLC, AMSA, JSON, PileUp, MSF, Clustal, PHYLIP, HMMER3]";
FileFormats formats = FileFormats.getInstance();
assertEquals(formats.getWritableFormats(true).toString(), expected);
- expected = "[Fasta, PFAM, Stockholm, PIR, BLC, AMSA, JSON, PileUp, MSF, Clustal, PHYLIP, Jalview]";
+ expected = "[Fasta, PFAM, Stockholm, PIR, BLC, AMSA, JSON, PileUp, MSF, Clustal, PHYLIP, Jalview, HMMER3]";
assertEquals(formats.getWritableFormats(false).toString(), expected);
}
@Test(groups = "Functional")
public void testDeregisterFileFormat()
{
- String writable = "[Fasta, PFAM, Stockholm, PIR, BLC, AMSA, JSON, PileUp, MSF, Clustal, PHYLIP]";
- String readable = "[Fasta, PFAM, Stockholm, PIR, BLC, AMSA, HTML, RNAML, JSON, PileUp, MSF, Clustal, PHYLIP, GenBank Flatfile, ENA Flatfile, GFF or Jalview features, PDB, mmCIF, Jalview]";
+ String writable = "[Fasta, PFAM, Stockholm, PIR, BLC, AMSA, JSON, PileUp, MSF, Clustal, PHYLIP, HMMER3]";
+ String readable = "[Fasta, PFAM, Stockholm, PIR, BLC, AMSA, HTML, RNAML, JSON, PileUp, MSF, Clustal, PHYLIP, GenBank Flatfile, ENA Flatfile, GFF or Jalview features, PDB, mmCIF, Jalview, HMMER3, BSML]";
FileFormats formats = FileFormats.getInstance();
+ System.out.println(formats.getReadableFormats().toString());
assertEquals(formats.getWritableFormats(true).toString(), writable);
assertEquals(formats.getReadableFormats().toString(), readable);
formats.deregisterFileFormat(FileFormat.Fasta.getName());
- writable = "[PFAM, Stockholm, PIR, BLC, AMSA, JSON, PileUp, MSF, Clustal, PHYLIP]";
- readable = "[PFAM, Stockholm, PIR, BLC, AMSA, HTML, RNAML, JSON, PileUp, MSF, Clustal, PHYLIP, GenBank Flatfile, ENA Flatfile, GFF or Jalview features, PDB, mmCIF, Jalview]";
+ writable = "[PFAM, Stockholm, PIR, BLC, AMSA, JSON, PileUp, MSF, Clustal, PHYLIP, HMMER3]";
+ readable = "[PFAM, Stockholm, PIR, BLC, AMSA, HTML, RNAML, JSON, PileUp, MSF, Clustal, PHYLIP, GenBank Flatfile, ENA Flatfile, GFF or Jalview features, PDB, mmCIF, Jalview, HMMER3, BSML]";
assertEquals(formats.getWritableFormats(true).toString(), writable);
assertEquals(formats.getReadableFormats().toString(), readable);
* re-register the format: it gets added to the end of the list
*/
formats.registerFileFormat(FileFormat.Fasta);
- writable = "[PFAM, Stockholm, PIR, BLC, AMSA, JSON, PileUp, MSF, Clustal, PHYLIP, Fasta]";
- readable = "[PFAM, Stockholm, PIR, BLC, AMSA, HTML, RNAML, JSON, PileUp, MSF, Clustal, PHYLIP, GenBank Flatfile, ENA Flatfile, GFF or Jalview features, PDB, mmCIF, Jalview, Fasta]";
+ writable = "[PFAM, Stockholm, PIR, BLC, AMSA, JSON, PileUp, MSF, Clustal, PHYLIP, HMMER3, Fasta]";
+ readable = "[PFAM, Stockholm, PIR, BLC, AMSA, HTML, RNAML, JSON, PileUp, MSF, Clustal, PHYLIP, GenBank Flatfile, ENA Flatfile, GFF or Jalview features, PDB, mmCIF, Jalview, HMMER3, BSML, Fasta]";
assertEquals(formats.getWritableFormats(true).toString(), writable);
assertEquals(formats.getReadableFormats().toString(), readable);
}
* verify the list of file formats registered matches the enum values
*/
FileFormats instance = FileFormats.getInstance();
- Iterator<FileFormatI> formats = instance.getFormats().iterator();
+ Iterator<FileFormatI> formats = instance.getFormats()
+ .iterator();
FileFormatI[] builtIn = FileFormat.values();
for (FileFormatI ff : builtIn)
package jalview.io;
+import static org.testng.Assert.assertEquals;
+
+import jalview.bin.Cache;
+
import org.junit.Assert;
import org.testng.annotations.Test;
// Data source type expected to be DataSourceType.URL
Assert.assertEquals(DataSourceType.URL, fileLoader.protocol);
}
+
+ @Test(groups = "Functional")
+ public void testUpdateRecentlyOpened()
+ {
+ // ensure properties file is read-only
+ Cache.loadProperties("test/jalview/io/testProps.jvprops");
+
+ String recent = "RECENT_FILE";
+ Cache.removeProperty(recent);
+
+ String prop = FileLoader.updateRecentlyOpened("a/b/c",
+ DataSourceType.FILE);
+ assertEquals(prop, "a/b/c");
+
+ prop = FileLoader.updateRecentlyOpened("d/e/f", DataSourceType.FILE);
+ assertEquals(prop, "d/e/f\ta/b/c");
+
+ // revisiting a file moves it to the top of the list
+ prop = FileLoader.updateRecentlyOpened("a/b/c", DataSourceType.FILE);
+ assertEquals(prop, "a/b/c\td/e/f");
+
+ // history list is limited to the most recent 11 items
+ for (int i = 0; i < 20; i++)
+ {
+ prop = FileLoader.updateRecentlyOpened(String.format("%d.fa", i),
+ DataSourceType.FILE);
+ }
+ assertEquals(prop,
+ "19.fa\t18.fa\t17.fa\t16.fa\t15.fa\t14.fa\t13.fa\t12.fa\t11.fa\t10.fa\t9.fa");
+ }
}
{
try
{
- AlignmentI al = new FormatAdapter().readFile("examples/uniref50.fa",
+ AlignmentI al;
+ if (format == FileFormat.HMMER3)
+ {
+ al = new FormatAdapter().readFile("examples/uniref50.hmm",
+ DataSourceType.FILE, FileFormat.HMMER3);
+ }
+ else
+ {
+ al = new FormatAdapter().readFile("examples/uniref50.fa",
DataSourceType.FILE, FileFormat.Fasta);
+ }
/*
* 'gap' is the gap character used in the alignment data file here,
AlignmentI reloaded = new FormatAdapter().readFile(formatted,
DataSourceType.PASTE, format);
List<SequenceI> reread = reloaded.getSequences();
- assertEquals("Wrong number of reloaded sequences", seqs.length,
- reread.size());
+ assertEquals("Wrong number of reloaded sequences", seqs.length,
+ reread.size());
+
int i = 0;
for (SequenceI seq : reread)
@DataProvider(name = "formats")
static Object[][] getFormats()
{
- List<FileFormatI> both = new ArrayList<FileFormatI>();
+ List<FileFormatI> both = new ArrayList<>();
for (FileFormatI format : FileFormats.getInstance().getFormats())
{
if (format.isReadable() && format.isWritable()
--- /dev/null
+# STOCKHOLM 1.0
+#=GS Q7XA98_TRIPR/1-152 DR UNIPROT ; Q7XA98
+#=GS FER1_PEA/1-149 DR UNIPROT ; P09911
+#=GS Q93XJ9_SOLTU/1-144 DR UNIPROT ; Q93XJ9
+#=GS FER_CAPAN/1-144 DR UNIPROT ; Q9ZTS2
+#=GS FER1_SOLLC/1-144 DR UNIPROT ; Q43517
+#=GS FER_CAPAA/1-97 DR UNIPROT ; P83527
+FER_CAPAA/1-97 ------------------------------------------------------------------------ASYKVKLITPDGPIEFDCPDDVYILDQAEEAGHDLPYSCRAGSCSSCAGKIAGGAVDQTDGNFLDDDQLEEGWVLTCVAYPQSDVTIETHKEAELVG-
+FER_CAPAN/1-144 MA------SVSATMISTSFMPRKPAVTSL-KPIPNVGE--ALFGLKS-A--NGGKVTCMASYKVKLITPDGPIEFDCPDNVYILDQAEEAGHDLPYSCRAGSCSSCAGKIAGGAVDQTDGNFLDDDQLEEGWVLTCVAYPQSDVTIETHKEAELVG-
+FER1_SOLLC/1-144 -------------MA------SISGTMISTSFLPRKPAVTSL-KAISNVGE--ALFGLKS-G--RNGRITCMASYKVKLITPEGPIEFECPDDVYILDQAEEEGHDLPYSCRAGSCSSCAGKVTAGSVDQSDGNFLDEDQEAAGFVLTCVAYPKGDVTIETHKEEELTA-
+Q93XJ9_SOLTU/1-144 --------MA------SISGTMISTSFLPRKPVVTSL-KAISNVGE--ALFGLKS-G--RNGRITCMASYKVKLITPDGPIEFECPDDVYILDQAEEEGHDLPYSCRAGSCSSCAGKVTAGTVDQSDGKFLDDDQEAAGFVLTCVAYPKCDVTIETHKEEELTA-
+FER1_PEA/1-149 -------------MATT---PALYGTAVSTSFLRTQPMPMSV-TTTKAFSN--GFLGLKT-SLKRGDLAVAMASYKVKLVTPDGTQEFECPSDVYILDHAEEVGIDLPYSCRAGSCSSCAGKVVGGEVDQSDGSFLDDEQIEAGFVLTCVAYPTSDVVIETHKEEDLTA-
+Q7XA98_TRIPR/1-152 -------------MATT---PALYGTAVSTSFMRRQPVPMSV-ATTTTTKAFPSGFGLKSVSTKRGDLAVAMATYKVKLITPEGPQEFDCPDDVYILDHAEEVGIELPYSCRAGSCSSCAGKVVNGNVNQEDGSFLDDEQIEGGWVLTCVAFPTSDVTIETHKEEELTA-
+#=GC SS_cons EEE EEEEEEEE HHHHH e e e EE EE HHHH E e EE EEEEE
+#=GC Iron_Sulphur_Contacts -------------------------------------------------------------------------------------------------e----e--e-----------------------------e---------------------
+//
--- /dev/null
+HMMER3/f [3.2 | June 2018]
+NAME Alignment_HMM
+LENG 152
+ALPH amino
+RF no
+MM no
+CONS yes
+CS no
+MAP yes
+DATE Fri Jun 7 14:44:10 2019
+NSEQ 6
+EFFN 2.071289
+CKSUM 2312940853
+STATS LOCAL MSV -10.2278 0.70920
+STATS LOCAL VITERBI -10.8843 0.70920
+STATS LOCAL FORWARD -4.3996 0.70920
+HMM A C D E F G H I K L M N P Q R S T V W Y
+ m->m m->i m->d i->m i->i d->m d->d
+ COMPO 2.41432 3.67931 2.75921 2.60121 3.50018 2.76530 3.83614 2.93106 2.71371 2.66765 3.66760 3.24838 3.26026 3.17831 3.19279 2.51076 2.65615 2.59873 5.09464 3.62512
+ 2.68544 4.42237 2.77531 2.73135 3.46365 2.40524 3.72506 3.29365 2.67752 2.69366 4.24294 2.90358 2.73751 3.18158 2.89812 2.37898 2.77531 2.98530 4.58488 3.61515
+ 0.78057 1.55851 1.10441 0.67815 0.70837 0.00000 *
+ 1 2.59800 4.39329 3.63625 3.18787 3.71456 3.43841 4.11392 3.03068 3.09157 2.71409 1.85445 3.48425 4.00395 3.44434 3.39575 1.59145 2.94832 2.79270 5.21434 3.95539 9 s - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.02133 4.25401 4.97636 0.61958 0.77255 0.98598 0.46693
+ 2 1.50579 4.32755 4.18645 3.78216 3.88559 3.56425 4.59767 2.41074 3.70275 2.69336 3.78707 3.89382 4.19613 3.99133 3.94010 2.99086 3.05698 1.28977 5.52248 4.31320 10 v - - -
+ 2.68550 4.42242 2.77537 2.73141 3.46371 2.40530 3.72512 3.29371 2.67758 2.69372 4.24707 2.90364 2.73757 3.18164 2.89818 2.37841 2.77443 2.98536 4.58494 3.61520
+ 0.90209 1.16285 1.26696 1.01535 0.44985 0.39057 1.12909
+ 3 3.42707 4.91214 4.61207 4.26925 3.52422 4.22326 4.89422 2.75377 4.00666 2.06722 0.68834 4.47974 4.70831 4.36739 4.15005 3.81331 3.75358 2.81142 5.41119 4.20659 14 M - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01938 4.34894 5.07129 0.61958 0.77255 0.90177 0.52062
+ 4 1.43643 4.42503 4.31312 3.86585 3.75424 3.86050 4.64018 1.40277 3.76673 2.49922 3.64972 4.05060 4.39156 4.05997 3.99981 3.25891 3.19718 2.11006 5.45161 4.24039 15 i - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.14665 4.34894 2.09167 0.61958 0.77255 0.90177 0.52062
+ 5 2.37098 4.31475 3.56770 3.24979 4.37798 3.10030 4.31086 3.75066 3.26247 3.47251 4.31621 3.42494 3.83407 3.57718 3.57680 1.30947 1.53387 3.24501 5.72919 4.50336 16 s - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.02198 4.22428 4.94663 0.61958 0.77255 0.54114 0.87248
+ 6 2.50652 4.44141 3.83949 3.54853 4.61304 3.23185 4.57545 3.99871 3.56049 3.72110 4.55726 3.64948 3.99392 3.85973 3.84879 1.49216 1.01986 3.44946 5.96659 4.76085 17 t - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.24086 4.47354 1.59630 0.61958 0.77255 0.76398 0.62700
+ 7 2.65517 4.36127 3.81549 3.38335 3.69064 3.54500 4.25486 1.58799 3.30272 2.65201 3.68407 3.64162 4.10535 3.63002 3.58335 1.61226 3.00284 2.44965 5.24306 3.98781 18 i - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.02133 4.25401 4.97636 0.61958 0.77255 0.98598 0.46693
+ 8 2.74723 4.45808 3.83003 3.43336 1.55716 3.57739 4.01030 3.12129 3.39844 2.75883 3.78862 3.64312 4.13759 3.66183 3.66464 1.60155 3.09781 2.89427 4.64509 3.10366 19 f - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.02133 4.25401 4.97636 0.61958 0.77255 0.98598 0.46693
+ 9 2.65532 4.43699 3.65638 3.26130 3.78761 1.68622 4.19753 3.09268 3.18548 2.76736 1.66329 3.54773 4.04431 3.53861 3.47551 2.87376 3.01742 2.85730 5.28180 4.04464 20 m - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.02133 4.25401 4.97636 0.61958 0.77255 0.55834 0.84900
+ 10 2.62413 4.55150 3.73217 3.46502 4.58891 3.32606 4.53947 3.93771 3.48022 3.66044 4.54532 3.64966 1.08714 3.81713 3.77509 2.80225 1.57704 3.45878 5.93284 4.72852 21 p - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01709 4.47354 5.19589 0.61958 0.77255 0.51701 0.90709
+ 11 1.99709 4.68552 3.40260 2.84388 3.94615 3.60689 3.90388 3.32023 2.73340 2.98773 2.29384 3.29447 4.03205 3.12399 2.03393 2.35985 2.99523 3.04365 5.29921 4.03061 22 a - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01548 4.57201 5.29435 0.61958 0.77255 0.62415 0.76726
+ 12 3.03612 4.58206 4.17469 3.58665 3.60032 4.09338 4.33760 1.51772 1.94651 1.71212 3.50362 3.91731 4.43832 3.70785 3.50867 3.39096 3.26453 2.43051 5.23091 4.03724 23 i - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01548 4.57201 5.29435 0.61958 0.77255 0.62415 0.76726
+ 13 2.76197 4.70799 3.41034 2.96484 3.84310 3.56022 4.02290 3.51807 2.97071 3.16868 4.04204 3.37800 2.07618 3.30589 3.36146 1.59778 3.07503 3.20545 5.27554 2.20871 24 s - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01548 4.57201 5.29435 0.61958 0.77255 0.62415 0.76726
+ 14 1.42932 4.46589 4.02364 3.69643 4.72988 1.43294 4.68906 4.13282 3.71549 3.83309 4.64260 3.74322 4.03851 3.97444 4.00639 2.72003 1.63454 3.53847 6.07503 4.89460 25 a - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01548 4.57201 5.29435 0.61958 0.77255 0.62415 0.76726
+ 15 2.63382 4.43500 3.98903 3.52691 4.05377 3.47381 4.41118 3.21360 3.46955 3.09630 4.00516 3.71495 4.11115 3.75748 3.76367 1.74048 1.56254 1.69711 5.50933 4.30015 26 t - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01548 4.57201 5.29435 0.61958 0.77255 0.62415 0.76726
+ 16 1.97870 4.28154 4.12278 3.55312 2.14335 3.81420 4.17500 2.68382 3.44988 2.41995 2.61784 3.79310 4.21338 3.68984 3.66833 3.11084 1.96434 2.49922 4.91664 3.71472 27 t - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01548 4.57201 5.29435 0.61958 0.77255 0.62415 0.76726
+ 17 2.91846 4.34842 4.48199 3.90988 3.46317 4.07572 4.44144 1.98330 3.78456 1.67828 3.41359 4.10010 4.43748 4.00384 3.95399 2.01206 3.16092 1.64497 5.07625 3.88829 28 v - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01548 4.57201 5.29435 0.61958 0.77255 0.62415 0.76726
+ 18 2.70635 4.56892 3.60528 3.14080 3.96671 3.53723 4.15403 3.33644 3.10057 1.82443 3.93202 3.49380 2.11690 3.43662 3.45226 1.62468 3.04334 3.04998 5.39218 4.13558 29 s - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.26457 4.57201 1.50451 0.61958 0.77255 0.62415 0.76726
+ 19 2.81401 4.82005 3.48128 2.94818 4.34473 3.53963 3.92028 3.69738 2.45527 3.31575 4.19707 3.33652 4.04563 3.10077 1.62480 2.90920 1.49986 3.36258 5.52959 4.29493 30 t - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01981 4.32725 5.04960 0.61958 0.77255 0.42245 1.06549
+ 20 2.99742 5.17558 3.29695 2.86766 4.77169 3.64255 3.98284 4.20460 1.15211 3.71930 4.54717 3.31939 4.14896 3.12831 2.80934 1.59962 3.28379 3.79417 5.81941 4.54197 31 k - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01548 4.57201 5.29435 0.61958 0.77255 0.62415 0.76726
+ 21 3.28763 4.90910 4.31235 3.99239 1.36983 4.02580 4.37777 3.48169 3.95787 2.96396 4.13543 4.15449 1.08518 4.20039 4.16663 3.51751 3.64052 3.33099 4.84797 3.27396 32 p - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01548 4.57201 5.29435 0.61958 0.77255 0.62415 0.76726
+ 22 3.45018 4.70771 5.41218 4.85806 3.55317 4.84496 5.27184 1.41698 4.72877 1.42021 2.43827 4.98314 5.05481 4.81112 4.77841 4.21177 3.68367 1.42720 5.55642 4.46185 33 i - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01548 4.57201 5.29435 0.61958 0.77255 0.62415 0.76726
+ 23 2.82485 4.73326 3.55705 3.00955 4.05482 3.65786 4.00613 3.34731 2.73677 3.06317 3.96177 3.42018 1.80573 3.23126 2.02314 2.96454 3.09977 1.95730 5.39957 4.14889 34 p - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01548 4.57201 5.29435 0.61958 0.77255 0.62415 0.76726
+ 24 2.86127 5.09016 3.19616 2.69781 4.52201 3.59071 3.86031 3.94606 2.49967 3.49458 4.30305 1.96704 4.04133 2.99863 1.96172 2.88186 1.74316 3.56959 5.66035 4.34483 35 t - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01548 4.57201 5.29435 0.61958 0.77255 0.62415 0.76726
+ 25 2.78170 4.95829 3.16704 2.62944 4.23097 3.58469 3.79757 3.63325 2.16991 3.23781 4.05928 3.13605 3.98936 2.12578 2.95429 2.00470 3.01690 2.13727 5.47298 4.15357 36 s - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01548 4.57201 5.29435 0.61958 0.77255 0.62415 0.76726
+ 26 2.74867 4.60831 3.61740 3.20842 4.05654 1.87017 4.23901 3.42440 3.19407 1.83184 4.02720 3.54846 1.75260 3.52860 3.53526 2.92904 3.10347 3.12934 5.47730 4.23070 37 p - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.24245 4.57201 1.58496 0.61958 0.77255 0.62415 0.76726
+ 27 2.23893 4.60373 3.28448 1.87774 3.79882 3.57859 3.83870 3.03021 2.72644 2.79800 2.80144 3.21864 3.97823 3.06477 3.13889 2.82027 2.92566 2.31720 5.19891 3.92417 38 e - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.34327 4.34894 1.28144 0.61958 0.77255 0.43345 1.04488
+ 28 2.73943 4.82202 3.20350 2.68202 4.15055 3.52581 3.79474 3.47895 1.71004 3.13955 3.99838 3.15504 2.24076 2.96517 2.84990 2.80694 2.99350 2.43471 5.40910 4.11885 39 k - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01981 4.32725 5.04960 0.61958 0.77255 0.92238 0.50679
+ 29 1.67523 4.32939 3.80070 3.28713 3.65556 3.52435 4.14641 2.82922 3.20444 2.62909 2.04920 3.56786 4.04881 3.50886 3.50296 2.86733 2.23962 2.60434 5.15734 3.94638 40 a - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01981 4.32725 5.04960 0.61958 0.77255 0.42245 1.06549
+ 30 1.66814 4.43166 3.95026 3.47077 3.91143 3.54985 4.34218 1.84764 3.41576 2.94090 3.86903 3.70285 4.13774 3.70337 3.71262 1.58997 3.04021 2.78308 5.38688 4.17260 41 s - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01548 4.57201 5.29435 0.61958 0.77255 0.62415 0.76726
+ 31 2.86839 4.40063 4.28613 3.75197 3.53211 3.91378 4.39907 2.56140 3.63254 1.42290 3.49235 3.96842 4.35205 3.89101 3.84593 1.98860 3.14663 1.72465 5.13588 3.93489 42 l - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.33933 4.57201 1.28224 0.61958 0.77255 0.62415 0.76726
+ 32 2.99338 4.73521 3.52318 3.19423 1.49578 3.74751 3.84834 3.30385 3.23971 2.88691 3.93859 1.69947 4.23548 3.52506 3.56009 3.13754 3.28417 3.09751 4.46980 2.84938 43 f - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.02133 4.25401 4.97636 0.61958 0.77255 0.39057 1.12909
+ 33 2.26113 4.65266 3.39149 2.85535 3.96561 2.14052 3.94035 3.32256 2.32255 3.01451 3.87297 3.29920 4.01793 3.16391 3.22857 2.83216 2.44156 2.03814 5.33010 4.05751 44 v - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01548 4.57201 5.29435 0.61958 0.77255 0.62415 0.76726
+ 34 2.14527 4.45044 3.76875 3.26603 3.85788 2.04177 4.18979 3.17104 3.21967 1.81090 3.81461 3.56903 4.08500 3.51989 3.54833 2.88152 1.96723 2.89522 5.29995 4.07724 45 l - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01548 4.57201 5.29435 0.61958 0.77255 0.62415 0.76726
+ 35 2.77531 5.06924 3.07796 1.89721 4.35250 3.56090 3.75513 2.86917 1.82937 3.33902 4.13804 3.06897 3.95918 2.88565 2.93068 2.78088 2.17797 3.41042 5.54533 4.19589 46 k - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.24245 4.57201 1.58496 0.61958 0.77255 0.62415 0.76726
+ 36 2.66334 4.78591 3.14690 2.69736 4.34791 3.40164 3.87711 3.75678 2.10710 3.36111 4.18006 3.15163 3.92504 3.04074 3.00575 1.44108 2.29363 3.36678 5.57460 4.27063 47 s - - -
+ 2.68590 4.42232 2.77527 2.73130 3.46361 2.40520 3.72502 3.29361 2.67748 2.69362 4.24697 2.90308 2.73747 3.18154 2.89808 2.37894 2.77488 2.98526 4.58484 3.61510
+ 0.44576 1.04019 5.07129 0.13971 2.03720 0.43345 1.04488
+ 37 1.35032 4.33598 4.11743 3.57274 2.66462 3.74950 4.26894 2.70612 3.48547 2.58049 3.54278 3.80339 4.21776 3.73820 3.72893 3.07578 2.40333 2.07300 5.08335 3.87699 49 a - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.26457 4.57201 1.50451 0.61958 0.77255 0.62415 0.76726
+ 38 2.67849 4.67202 3.20606 2.69337 3.93262 2.63512 3.80028 3.31587 2.17250 1.96311 3.82914 3.16211 3.94141 3.00575 3.00084 2.28900 2.93113 3.03056 5.26473 3.98290 50 l - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01981 4.32725 5.04960 0.61958 0.77255 0.92238 0.50679
+ 39 2.23745 4.71916 3.05672 2.16980 2.23785 3.50580 3.78395 3.31902 2.66523 2.97723 3.83443 2.49003 3.93379 2.99259 3.10154 2.77864 2.93862 3.03813 5.25364 3.93663 51 e - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.29014 4.32725 1.43280 0.61958 0.77255 0.42245 1.06549
+ 40 2.71194 4.71147 3.14073 2.76488 2.63325 1.94411 3.91859 3.50545 2.86219 3.15174 4.02297 1.82298 3.98451 3.17614 3.28134 2.81220 3.01803 3.18804 5.26894 3.87083 52 n - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01895 4.37135 5.09369 0.61958 0.77255 0.87955 0.53609
+ 41 2.64945 4.49564 3.49208 3.06414 3.88051 1.81354 4.08661 3.23766 3.04151 1.74255 3.84911 3.42067 2.61702 3.37781 3.38586 2.83194 2.98495 2.96040 5.30850 4.06003 53 l - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01895 4.37135 5.09369 0.61958 0.77255 0.44572 1.02266
+ 42 2.20625 4.93221 3.17339 2.72120 4.55189 1.72555 3.94981 3.99413 1.81667 3.55820 4.34814 3.19358 3.98997 3.09380 3.14134 2.24894 3.05082 3.55894 5.74349 4.41072 54 g - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01548 4.57201 5.29435 0.61958 0.77255 0.62415 0.76726
+ 43 2.73118 4.74977 3.26283 2.70881 2.98752 2.82347 3.82752 3.34686 1.92589 2.48911 3.84846 3.19660 3.99345 3.02672 3.10018 2.03919 2.96671 3.06691 5.29037 3.99373 55 k - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.24245 4.57201 1.58496 0.61958 0.77255 0.62415 0.76726
+ 44 3.21892 4.54748 4.94678 4.39384 1.84065 4.45647 4.69231 2.23828 4.25181 1.55834 3.19076 4.52046 4.72563 4.36468 4.33750 3.79737 3.45238 1.39236 5.03910 3.75691 56 v - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01938 4.34894 5.07129 0.61958 0.77255 0.43345 1.04488
+ 45 2.63358 4.56206 3.94281 3.76669 4.90587 0.86987 4.83032 4.31802 3.87414 4.03413 4.86498 3.81723 4.11786 4.13859 4.13012 2.82336 1.52160 3.69008 6.22345 5.06760 57 g - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.24245 4.57201 1.58496 0.61958 0.77255 0.62415 0.76726
+ 46 3.01864 1.79566 4.69259 4.19257 3.41038 4.04365 4.66782 2.43586 3.98238 1.14404 3.36027 4.28885 4.50409 4.22027 4.10902 3.45690 3.32610 2.36331 5.19668 3.99182 58 l - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01938 4.34894 5.07129 0.61958 0.77255 0.90177 0.52062
+ 47 2.96377 4.89266 3.53249 2.95386 4.04795 3.74350 3.88142 3.34726 1.40052 2.91530 1.93101 3.37640 4.14009 3.07637 2.67530 3.06693 3.18523 3.14375 5.36699 4.12971 59 k - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01938 4.34894 5.07129 0.61958 0.77255 0.43345 1.04488
+ 48 1.77870 4.80105 3.33239 2.80291 4.36522 3.47131 3.95619 3.78270 2.73318 3.38875 4.19761 3.24889 3.98437 3.11824 1.99740 1.90727 2.40269 3.38967 5.61455 4.31002 60 a - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.21961 4.57201 1.67756 0.61958 0.77255 0.62415 0.76726
+ 49 2.60823 4.64033 3.22015 2.80894 4.20933 3.36458 3.98710 3.59284 2.85357 3.27469 4.11620 1.86137 3.93152 3.18866 3.26591 1.65119 2.95563 2.38198 5.53276 4.23147 61 s - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01895 4.37135 5.09369 0.61958 0.77255 0.44572 1.02266
+ 50 2.74410 4.67335 3.45404 3.06703 3.90844 1.64792 4.12669 3.60477 3.11681 3.26108 4.13393 3.44191 4.09025 3.43093 3.49590 1.86622 3.09650 3.26485 5.35022 1.97056 62 g - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.11556 4.57201 2.31473 0.61958 0.77255 0.62415 0.76726
+ 51 2.95370 5.14232 3.38998 2.75626 4.47479 3.70680 3.76608 3.85318 1.57496 2.58800 4.21663 3.22595 4.07617 2.90174 1.75899 2.96747 2.46355 3.52788 5.54040 4.28024 63 k - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01709 4.47354 5.19589 0.61958 0.77255 0.76398 0.62700
+ 52 2.97237 4.48471 4.17487 3.61038 3.68717 4.08286 4.40175 1.59509 2.09243 2.51779 3.58882 3.93788 4.44245 3.78487 3.66371 3.38387 3.21319 1.46639 5.29622 4.08064 64 v - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01709 4.47354 5.19589 0.61958 0.77255 0.51701 0.90709
+ 53 3.16272 5.37499 3.59177 2.92070 4.82565 3.84597 3.83774 4.18579 1.50049 3.63868 4.47141 3.36065 4.21246 2.96157 1.48253 3.15294 1.98320 3.83770 5.70684 4.49260 65 r - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01548 4.57201 5.29435 0.61958 0.77255 0.62415 0.76726
+ 54 2.69126 2.25915 3.80687 3.28606 3.66656 2.21575 4.13449 3.01259 3.21697 1.80809 3.65267 2.64888 4.11014 3.51421 3.51970 2.94231 2.98955 2.76835 5.12838 3.90654 66 l - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01548 4.57201 5.29435 0.61958 0.77255 0.62415 0.76726
+ 55 2.75976 4.54905 2.30455 2.95518 3.70676 2.79648 3.96957 2.00953 2.95066 2.74085 2.27446 3.39166 4.08996 3.25986 3.33214 2.95036 2.99901 2.76002 5.14787 3.89753 67 i - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01548 4.57201 5.29435 0.61958 0.77255 0.62415 0.76726
+ 56 1.92745 4.55633 3.54968 2.99110 3.77370 3.65270 3.97236 3.10509 2.88439 2.02402 3.71145 3.40529 4.07525 3.24934 2.56281 2.91984 1.98149 2.86151 5.18773 3.94368 68 a - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01548 4.57201 5.29435 0.61958 0.77255 0.62415 0.76726
+ 57 1.83228 4.53823 3.61230 3.10354 4.02012 3.49038 4.12836 2.50681 3.07752 3.08124 3.94943 3.45725 2.07017 3.39222 3.45240 1.83561 2.99081 3.04929 5.41506 4.16867 69 a - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01548 4.57201 5.29435 0.61958 0.77255 0.62415 0.76726
+ 58 2.75895 4.66749 2.12963 2.81059 3.81488 3.63897 3.90096 3.17855 2.82626 2.89854 3.77788 3.28020 4.04584 3.14685 3.24113 2.89220 2.45960 2.10817 5.21741 2.34581 70 v - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01548 4.57201 5.29435 0.61958 0.77255 0.62415 0.76726
+ 59 1.87134 2.92490 3.41990 2.89562 4.22753 2.00930 4.00910 3.62340 1.87199 3.26968 4.10116 3.31508 4.00325 3.20209 3.23675 2.78496 2.99855 3.26410 5.53516 4.25405 71 a - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01548 4.57201 5.29435 0.61958 0.77255 0.62415 0.76726
+ 60 2.89677 4.42989 4.26135 3.71893 3.52156 3.94729 4.39343 2.57065 3.59726 2.35872 1.80824 3.96209 2.13460 3.86316 3.82140 3.27132 3.16554 1.68431 5.14387 3.95469 72 v - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01548 4.57201 5.29435 0.61958 0.77255 0.40804 1.09349
+ 61 1.57565 4.67644 3.61371 3.07202 3.92167 3.75428 4.06548 1.97069 1.96866 2.90804 3.83592 3.49072 4.17868 3.32201 3.23603 3.03786 3.11158 2.81687 5.33764 4.09102 73 a - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01431 4.64966 5.37201 0.61958 0.77255 0.48576 0.95510
+ 62 2.78306 4.91407 3.16080 1.90266 4.17861 3.59010 3.85833 3.57055 2.67830 2.17323 4.03601 3.16932 4.01281 3.02684 3.12616 1.86668 2.50737 3.25963 5.47226 4.15166 74 s - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01431 4.64966 5.37201 0.61958 0.77255 0.48576 0.95510
+ 63 3.70553 4.96355 5.18038 4.77967 1.51175 4.68042 4.04025 1.78081 4.59062 2.70856 3.92100 4.53151 4.97996 4.54894 4.56550 4.02683 3.92721 3.14972 4.19952 1.17802 75 y - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01431 4.64966 5.37201 0.61958 0.77255 0.48576 0.95510
+ 64 2.92406 5.37226 1.90980 2.50543 4.72545 3.56703 3.85582 4.19183 1.50834 3.69445 4.47134 3.05483 4.03152 2.97675 3.09023 2.88240 2.07165 3.77594 5.84089 4.43845 76 k - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01431 4.64966 5.37201 0.61958 0.77255 0.48576 0.95510
+ 65 2.78562 2.01948 4.55150 4.07045 3.82424 3.73349 4.63777 2.73929 3.93362 2.80343 3.79417 4.09169 2.08695 4.16452 4.09382 3.13564 3.15495 1.28567 5.38169 4.19434 77 v - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01431 4.64966 5.37201 0.61958 0.77255 0.48576 0.95510
+ 66 3.00177 5.48795 1.87629 2.49660 4.83835 3.57687 3.90289 4.32338 1.47116 3.80689 4.58836 3.05453 2.14999 3.02804 3.16908 2.94349 3.25201 3.89612 5.94044 4.52232 78 k - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01431 4.64966 5.37201 0.61958 0.77255 0.48576 0.95510
+ 67 2.97021 5.07355 1.83355 2.70799 4.34142 2.06896 4.05903 3.73788 2.99051 1.56224 4.26678 3.22685 4.13776 3.25977 3.46241 3.01746 3.25070 3.43787 5.68476 4.34458 79 l - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01431 4.64966 5.37201 0.61958 0.77255 0.48576 0.95510
+ 68 2.80435 4.51738 3.70485 3.17345 3.71222 3.76651 4.10838 1.80977 3.12705 2.73704 3.66708 2.15696 2.34690 3.43898 3.47179 3.04517 3.05888 2.24183 5.18327 3.94621 80 i - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01431 4.64966 5.37201 0.61958 0.77255 0.48576 0.95510
+ 69 3.21770 4.57086 4.97188 4.44662 3.86947 4.49942 5.05720 1.47430 4.33664 2.56546 3.72458 4.61110 4.86186 4.58040 4.51238 3.86070 1.54232 1.34555 5.64266 4.43926 81 v - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01431 4.64966 5.37201 0.61958 0.77255 0.48576 0.95510
+ 70 2.95708 5.14521 2.99403 1.83121 4.19063 3.63668 3.92702 3.82818 2.78051 3.41772 4.26662 3.17833 1.74182 3.12106 3.22848 2.97355 3.20630 3.50738 5.52563 2.17177 82 p - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01431 4.64966 5.37201 0.61958 0.77255 0.48576 0.95510
+ 71 2.81050 4.79261 2.28753 2.03040 2.37706 3.65659 3.90550 2.14897 2.80356 2.99311 3.87365 3.24848 4.06373 3.12317 3.23928 2.91155 3.04567 3.04162 5.32210 4.01594 83 e - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01431 4.64966 5.37201 0.61958 0.77255 0.48576 0.95510
+ 72 2.93437 5.03828 3.04311 1.83946 4.30552 1.65755 3.99888 3.68879 2.85177 1.98910 4.20097 3.22855 4.11576 3.18781 3.28771 2.98470 3.19963 3.39021 5.62197 4.29753 84 g - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01431 4.64966 5.37201 0.61958 0.77255 0.48576 0.95510
+ 73 2.73902 2.32080 1.99570 2.81784 4.32430 3.51217 4.01811 3.72234 2.87487 3.36392 4.18957 3.27606 1.98571 3.19798 3.31847 2.82453 2.44358 3.35784 5.62280 4.31413 85 p - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01431 4.64966 5.37201 0.61958 0.77255 0.48576 0.95510
+ 74 2.87088 4.85397 3.36105 2.86591 4.06081 3.69200 3.97062 2.23427 2.75935 3.04437 3.96579 3.33519 2.30215 1.57203 3.13528 2.97368 3.12105 3.13247 5.42664 4.13968 86 q - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01431 4.64966 5.37201 0.61958 0.77255 0.48576 0.95510
+ 75 1.84740 5.71599 1.70450 1.29585 5.04192 3.56048 4.02374 4.54881 2.96239 4.03556 4.84247 3.02480 4.13163 3.16811 3.53263 3.05937 3.42628 4.10758 6.18823 4.70375 87 e - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01431 4.64966 5.37201 0.61958 0.77255 0.48576 0.95510
+ 76 3.06953 5.41519 1.80939 1.67828 1.68690 3.60061 3.98096 4.10134 2.91401 3.66294 4.51080 3.08865 4.12438 3.15808 3.43938 3.03000 3.32748 3.75306 5.79034 4.33444 88 e - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01431 4.64966 5.37201 0.61958 0.77255 0.48576 0.95510
+ 77 3.03870 5.47436 1.90526 1.29548 4.76783 3.57223 3.95900 4.16399 2.84250 3.75797 4.57501 3.05039 4.09259 3.10162 3.37273 2.98560 3.29722 2.13649 5.96102 4.53077 89 e - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01431 4.64966 5.37201 0.61958 0.77255 0.48576 0.95510
+ 78 1.74787 1.64658 4.29549 3.78786 3.51816 3.70291 4.33651 2.97775 3.65907 2.75066 3.68827 3.90525 4.24339 3.90389 3.85120 3.07083 3.08999 2.74475 5.04806 2.07593 90 c - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01431 4.64966 5.37201 0.61958 0.77255 0.48576 0.95510
+ 79 2.75948 4.56996 3.79425 3.38335 4.06237 1.91193 4.35624 1.91599 3.36983 3.10692 4.02732 3.67147 1.55829 3.68001 3.68915 2.97218 3.12763 3.01951 5.50730 4.27905 91 p - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01431 4.64966 5.37201 0.61958 0.77255 0.48576 0.95510
+ 80 2.84361 5.11662 1.88614 2.55687 4.33854 3.57668 2.26268 3.81219 2.65486 2.21008 4.20214 3.09171 4.01205 2.98715 3.13133 2.39282 3.08430 3.46799 5.59000 4.21533 92 d - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01431 4.64966 5.37201 0.61958 0.77255 0.48576 0.95510
+ 81 4.05062 6.09585 0.25016 3.16592 5.63180 4.01455 4.88658 5.44743 4.14657 4.91966 5.97362 3.74150 4.71639 4.16606 4.71915 3.96503 4.42100 5.01815 6.60717 5.45534 93 D - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01431 4.64966 5.37201 0.61958 0.77255 0.48576 0.95510
+ 82 3.04959 4.58334 4.21832 3.66721 3.55820 4.11355 4.41299 2.59646 3.48731 1.61108 3.47616 3.98523 4.47164 2.16526 3.73518 3.41507 3.28754 1.39698 5.22079 4.02388 94 v - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01431 4.64966 5.37201 0.61958 0.77255 0.48576 0.95510
+ 83 1.82715 4.61744 3.67020 3.22382 3.72690 3.63976 4.15441 3.35282 3.20066 3.04408 3.94999 3.56979 2.08621 3.51946 3.54139 2.98757 3.12307 3.07635 5.20580 1.61753 95 y - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01431 4.64966 5.37201 0.61958 0.77255 0.48576 0.95510
+ 84 2.90062 4.56201 3.71550 2.09080 3.49327 3.86304 4.08810 1.59101 3.18089 2.67620 3.64335 3.61449 4.25289 3.49651 3.50065 3.15073 3.13529 2.70012 5.01515 2.15048 96 i - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01431 4.64966 5.37201 0.61958 0.77255 0.48576 0.95510
+ 85 2.86216 4.89215 3.16897 1.91855 4.11409 3.63867 3.95829 3.48538 2.81326 1.65439 4.02074 3.25472 4.09032 3.16123 3.23386 1.94184 3.11683 3.21094 5.46706 4.16201 97 l - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01431 4.64966 5.37201 0.61958 0.77255 0.48576 0.95510
+ 86 3.02911 2.20051 1.43610 1.72118 4.75550 3.57025 3.97871 4.20820 2.86443 3.76403 4.57605 3.07440 4.09745 3.12563 3.38808 2.98631 3.29630 3.81727 5.95041 4.53316 98 d - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01431 4.64966 5.37201 0.61958 0.77255 0.48576 0.95510
+ 87 2.95229 5.31841 3.20763 2.65443 4.67641 2.24293 2.35827 4.11573 2.37176 3.59677 4.38392 3.16553 4.07082 2.08202 1.87641 2.92797 3.16779 3.72847 5.70861 4.38173 99 r - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01431 4.64966 5.37201 0.61958 0.77255 0.48576 0.95510
+ 88 0.89304 4.83593 3.52252 3.21237 4.28827 3.57365 1.98662 3.92815 3.18973 3.57384 4.45958 3.56834 4.20309 3.58992 3.52232 3.01049 3.26669 3.54231 5.67260 4.31414 100 a - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01431 4.64966 5.37201 0.61958 0.77255 0.48576 0.95510
+ 89 3.32897 5.98995 1.59036 1.21041 5.29223 1.85016 4.13193 4.84216 3.17456 4.29824 5.13981 3.02434 4.20540 3.29334 3.80439 3.19395 3.62119 4.37723 6.44195 4.89720 101 e - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01431 4.64966 5.37201 0.61958 0.77255 0.48576 0.95510
+ 90 2.86612 5.04422 3.04967 1.53080 4.31043 3.59969 3.90678 3.70979 2.72310 2.13413 4.17356 3.16516 4.05445 3.07158 3.17171 1.93423 3.11943 3.39271 5.59276 4.25151 102 e - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01431 4.64966 5.37201 0.61958 0.77255 0.48576 0.95510
+ 91 2.33839 2.33319 3.66936 2.51274 3.71047 3.68123 4.05819 3.02481 3.07985 2.77576 3.67017 3.50531 2.35114 3.38402 3.43065 2.95965 3.00527 2.02342 5.15389 3.92054 103 v - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01431 4.64966 5.37201 0.61958 0.77255 0.48576 0.95510
+ 92 2.77841 4.71648 3.50561 3.12657 4.00129 1.51312 4.19518 3.69627 3.18257 3.34991 4.21891 3.49374 4.13113 3.49456 3.56191 1.76331 3.14172 3.34204 5.43765 2.07352 104 g - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01431 4.64966 5.37201 0.61958 0.77255 0.48576 0.95510
+ 93 2.80900 4.65790 3.51214 3.01139 3.79431 3.68037 2.38933 2.16836 2.94391 2.94776 3.84277 3.43128 4.12697 3.30452 3.30672 1.48154 3.07555 2.99103 5.22365 3.91367 105 s - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01431 4.64966 5.37201 0.61958 0.77255 0.48576 0.95510
+ 94 3.04847 1.50371 1.61592 2.10236 4.66715 3.58851 4.05112 4.08665 2.97076 3.69723 4.53735 3.13921 4.13665 3.22062 3.48126 3.03480 3.33057 3.72643 5.91738 4.53055 106 c - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01431 4.64966 5.37201 0.61958 0.77255 0.48576 0.95510
+ 95 1.88410 4.65574 3.78265 3.20892 3.82389 3.79819 4.09423 3.12221 2.89200 1.51545 3.75540 3.58503 4.21920 3.38078 2.03442 3.09778 3.14791 2.92061 5.27033 4.04785 107 l - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01431 4.64966 5.37201 0.61958 0.77255 0.48576 0.95510
+ 96 1.54090 4.57715 3.92273 3.65745 4.90631 1.66510 4.74228 4.35275 3.75572 4.01671 4.81278 3.76174 1.32436 4.00941 4.06725 2.79701 3.13028 3.70679 6.22047 5.03095 108 p - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01431 4.64966 5.37201 0.61958 0.77255 0.48576 0.95510
+ 97 2.97420 5.05368 3.30132 2.83355 4.07677 2.15834 3.92294 3.75113 1.76958 3.34315 4.20275 3.31006 4.15184 3.13365 2.98906 3.02497 3.21508 3.44631 5.40486 1.71904 109 y - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01431 4.64966 5.37201 0.61958 0.77255 0.48576 0.95510
+ 98 2.82535 4.57572 4.10028 3.71301 4.03925 3.66632 4.58086 1.72884 3.64091 3.01747 4.04865 3.90026 4.29816 3.95980 3.90549 0.98108 3.22247 2.79320 5.58742 4.33006 110 s - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01431 4.64966 5.37201 0.61958 0.77255 0.48576 0.95510
+ 99 1.43514 0.82892 4.80681 4.58666 4.69417 3.39195 5.16406 3.80758 4.43086 3.75239 4.68183 4.17266 4.21161 4.63066 4.50594 2.88757 3.18548 3.35323 6.15457 5.03517 111 c - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01431 4.64966 5.37201 0.61958 0.77255 0.48576 0.95510
+ 100 2.82498 4.95715 3.40974 2.94255 4.70228 1.94565 4.08107 4.14251 2.73685 3.69574 4.49749 3.36420 4.09658 3.23391 1.46522 1.83152 3.16614 3.68558 5.84898 4.56169 112 r - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01431 4.64966 5.37201 0.61958 0.77255 0.48576 0.95510
+ 101 1.10475 4.52228 4.11576 3.83581 4.96435 1.64082 4.84380 4.42439 3.89199 4.08943 4.86937 3.83086 4.09259 4.12724 4.17193 1.57246 3.10246 3.72147 6.28518 5.11952 113 a - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01431 4.64966 5.37201 0.61958 0.77255 0.48576 0.95510
+ 102 1.43394 1.83402 4.58768 4.30129 4.75045 1.21055 5.01466 4.12708 4.21833 3.87731 4.70556 4.01744 4.11929 4.41365 4.36995 2.77887 3.09436 3.53695 6.15056 5.02931 114 g - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01431 4.64966 5.37201 0.61958 0.77255 0.48576 0.95510
+ 103 1.63449 4.47604 4.14466 3.71946 4.28385 3.44523 4.59529 3.45965 3.67241 3.33633 4.23051 3.81973 4.14313 3.94095 3.94969 1.28973 3.08609 1.71945 5.72686 4.53067 115 s - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01431 4.64966 5.37201 0.61958 0.77255 0.48576 0.95510
+ 104 2.83251 1.48569 1.76496 3.05212 4.63546 1.87091 4.34311 4.05699 3.30285 3.71503 4.55202 3.45874 4.14769 3.56082 3.73402 2.94445 3.23212 3.61792 5.93755 4.65533 116 c - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01431 4.64966 5.37201 0.61958 0.77255 0.48576 0.95510
+ 105 2.96957 5.32904 3.14366 2.65593 4.72494 3.66151 3.84186 4.16441 1.75186 3.64779 4.43821 3.16888 4.08411 1.93241 2.79580 1.59020 3.19856 3.76805 5.76348 4.43156 117 s - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01431 4.64966 5.37201 0.61958 0.77255 0.48576 0.95510
+ 106 2.66373 4.49207 4.03296 3.57936 4.18285 3.48606 4.48323 3.36835 3.52695 3.23079 4.12951 3.75581 4.14350 3.81520 3.82610 1.34147 1.75798 1.80637 5.62511 4.41600 118 s - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01431 4.64966 5.37201 0.61958 0.77255 0.48576 0.95510
+ 107 2.74792 1.62573 1.91234 3.05734 4.31516 3.50848 4.22275 3.63214 3.15497 3.36887 4.23026 3.44805 4.10111 3.45245 3.56167 2.88548 1.89159 3.28014 5.67623 4.40213 119 c - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01431 4.64966 5.37201 0.61958 0.77255 0.48576 0.95510
+ 108 0.68941 4.56331 4.20169 4.04692 5.05279 1.58716 5.03141 4.47978 4.15844 4.19817 5.00681 3.95737 4.16246 4.36890 4.37009 2.84226 3.19149 3.77919 6.37750 5.25838 120 A - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01431 4.64966 5.37201 0.61958 0.77255 0.48576 0.95510
+ 109 3.02964 5.08328 3.17150 3.12104 5.13170 0.81179 4.59407 4.73207 3.60754 4.31434 5.15959 1.65030 4.27627 3.83105 4.02354 3.11995 3.49284 4.12591 6.35429 5.05698 121 g - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01431 4.64966 5.37201 0.61958 0.77255 0.48576 0.95510
+ 110 2.85780 4.78493 3.46807 2.92281 2.21689 3.71308 3.94679 3.34785 1.56806 3.01008 3.90816 3.37147 4.12450 3.18495 3.10090 2.97945 2.06570 3.09328 5.28703 3.97445 122 k - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01431 4.64966 5.37201 0.61958 0.77255 0.48576 0.95510
+ 111 3.56792 4.79047 5.56843 5.05882 3.83185 5.08010 5.63680 1.72792 4.96256 1.47356 3.59353 5.21772 5.28003 5.11439 5.06846 4.48190 3.81459 0.88361 5.91262 4.77603 123 v - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01431 4.64966 5.37201 0.61958 0.77255 0.48576 0.95510
+ 112 2.34885 4.88546 1.50680 2.76582 4.28202 3.57605 3.99821 3.49749 2.86169 3.28542 4.14261 3.25275 4.06485 3.17747 3.31619 2.88335 2.45367 2.13395 5.60583 4.28774 124 d - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01431 4.64966 5.37201 0.61958 0.77255 0.48576 0.95510
+ 113 2.37560 5.43186 1.88002 2.44821 4.76975 2.31003 3.85108 4.26118 2.66530 3.74586 4.51061 2.44214 4.01416 2.00579 3.18288 2.86422 3.16817 3.82620 5.88838 4.45514 125 d - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01431 4.64966 5.37201 0.61958 0.77255 0.48576 0.95510
+ 114 3.02825 5.34001 1.64973 2.62556 5.04958 1.43770 4.18261 4.55907 3.15840 4.08500 4.89492 3.15845 4.14205 3.34808 3.70413 1.79379 3.38532 4.04813 6.24427 4.81118 126 g - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01431 4.64966 5.37201 0.61958 0.77255 0.48576 0.95510
+ 115 2.43421 5.39468 1.99800 2.11130 4.72686 3.53375 3.80066 4.21905 2.58750 3.69532 4.44801 2.47018 3.98139 1.98470 3.09824 2.34600 3.10833 3.78019 5.82949 4.40030 127 q - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01431 4.64966 5.37201 0.61958 0.77255 0.48576 0.95510
+ 116 2.94597 4.44901 4.44561 3.93108 3.62623 2.15331 4.54520 2.49864 3.80946 1.67061 3.57798 4.11336 4.45736 4.06092 4.00094 3.35990 3.23101 1.30872 5.24560 4.04661 128 v - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01431 4.64966 5.37201 0.61958 0.77255 0.48576 0.95510
+ 117 3.07108 5.65983 1.61666 1.64591 4.97722 3.55644 3.94110 4.49006 1.85258 3.95163 4.73218 2.37323 4.08443 3.06951 3.35115 2.98315 3.32751 4.04015 6.08373 4.61352 129 d - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01431 4.64966 5.37201 0.61958 0.77255 0.48576 0.95510
+ 118 2.90641 5.14851 3.03065 1.82407 2.34336 3.62785 3.86089 3.81266 2.66227 3.36932 4.21751 3.14311 4.06155 1.65090 3.10716 2.91351 3.14323 3.49036 5.52105 4.11540 130 q - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01431 4.64966 5.37201 0.61958 0.77255 0.48576 0.95510
+ 119 2.76255 4.86202 3.19852 2.29238 4.13565 2.23517 3.86729 3.53680 2.70242 2.16346 4.00273 3.18654 4.00924 3.04372 3.14909 2.07641 2.54383 3.22686 5.44173 4.12929 131 s - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01431 4.64966 5.37201 0.61958 0.77255 0.48576 0.95510
+ 120 3.57941 5.58171 0.75523 3.12318 4.02169 3.96847 4.37908 4.42174 3.52990 3.92216 4.91170 3.63855 4.53554 3.76654 3.97529 3.57745 3.86789 4.12842 1.75169 3.95153 132 d - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01431 4.64966 5.37201 0.61958 0.77255 0.48576 0.95510
+ 121 2.91174 5.02616 1.86612 2.75649 4.50983 1.54341 4.12514 3.82111 3.05693 3.54399 4.40141 3.25444 4.12333 3.31620 3.53368 2.97056 3.23532 1.93277 5.82328 4.48241 133 g - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01431 4.64966 5.37201 0.61958 0.77255 0.48576 0.95510
+ 122 2.86459 5.20437 2.00723 2.52234 4.49985 3.55603 3.85351 3.95142 2.67319 2.15274 4.30753 2.15442 4.01247 2.99055 3.16622 2.05025 3.11283 3.57971 5.70819 4.32388 134 d - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01431 4.64966 5.37201 0.61958 0.77255 0.48576 0.95510
+ 123 2.86858 4.64306 3.62963 3.12613 1.70785 3.76769 4.03967 3.15671 3.04812 2.80119 3.75818 3.52490 4.19369 2.11823 3.38968 3.05795 1.97932 2.94141 5.07338 3.71197 135 f - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01431 4.64966 5.37201 0.61958 0.77255 0.48576 0.95510
+ 124 2.87729 2.25286 3.84987 2.10126 3.62200 3.85343 4.19223 2.84299 3.24572 1.47166 3.58556 3.69315 4.26287 3.56918 3.54313 3.15439 3.12814 2.66630 5.14969 3.92844 136 l - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01431 4.64966 5.37201 0.61958 0.77255 0.48576 0.95510
+ 125 1.87554 4.89400 1.55330 2.83635 4.32557 3.59793 4.10822 3.41524 3.01358 3.31001 4.20357 3.31594 4.12580 3.30435 3.46699 2.95750 3.16753 1.90970 5.68921 4.37289 137 d - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01431 4.64966 5.37201 0.61958 0.77255 0.48576 0.95510
+ 126 1.31978 5.65673 1.53971 2.00100 5.00455 3.56144 4.04702 4.49528 2.99731 4.00710 4.82437 3.04396 4.14090 3.19815 3.56394 3.06909 3.43192 4.06642 6.17533 4.70374 138 a - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01431 4.64966 5.37201 0.61958 0.77255 0.48576 0.95510
+ 127 2.99154 5.46776 1.93424 1.79632 4.74629 2.13218 3.90636 4.24433 2.76518 3.75551 4.54564 3.02592 4.05721 3.04023 3.29236 2.93391 3.24309 3.83702 5.91396 2.21504 139 e - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01431 4.64966 5.37201 0.61958 0.77255 0.48576 0.95510
+ 128 2.90782 4.87069 3.38284 2.90818 2.18962 3.72084 3.95729 3.47130 2.86207 3.05902 3.98760 3.36869 2.19368 1.63399 3.25068 3.00729 3.16046 3.21829 5.19587 3.77282 140 q - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01431 4.64966 5.37201 0.61958 0.77255 0.48576 0.95510
+ 129 2.80387 4.50973 3.68288 2.53916 3.64508 3.79101 4.04638 2.09044 3.05762 2.30112 3.59386 3.52646 4.16714 2.16471 3.40576 3.04110 3.03585 1.93346 5.11678 3.88419 141 v - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01431 4.64966 5.37201 0.61958 0.77255 0.48576 0.95510
+ 130 2.33816 4.92974 3.14216 1.79211 4.20735 3.58332 3.86460 3.60039 2.68643 2.17242 4.06142 3.16489 4.01325 3.03072 3.13839 1.97098 3.03629 3.28400 5.49619 4.17164 142 e - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01431 4.64966 5.37201 0.61958 0.77255 0.48576 0.95510
+ 131 2.04954 5.30098 1.94774 2.15701 4.64724 2.73655 3.83132 4.12007 2.63294 3.63223 4.40230 3.02948 3.99372 2.95114 3.13793 2.82654 2.09314 3.70436 5.79378 4.38447 143 d - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01431 4.64966 5.37201 0.61958 0.77255 0.48576 0.95510
+ 132 2.67461 1.98295 4.54536 4.13152 4.08175 1.38240 4.74089 3.14924 4.01069 3.12077 4.06082 4.04085 4.22311 4.23030 4.16807 2.96147 3.11654 1.64169 5.59063 4.41633 144 g - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01431 4.64966 5.37201 0.61958 0.77255 0.48576 0.95510
+ 133 2.83984 4.25742 4.52040 3.93471 2.15049 3.96796 4.23092 2.63475 3.77248 2.37225 3.34682 4.03138 4.33444 3.94714 3.87337 3.27306 1.99292 1.78236 2.52955 3.47977 145 v - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01431 4.64966 5.37201 0.61958 0.77255 0.48576 0.95510
+ 134 1.94019 4.61061 5.17838 4.67117 3.96915 4.65508 5.28276 1.37973 4.57265 2.60668 3.79310 4.80809 5.00205 4.81289 4.73487 4.03650 3.57041 1.05280 5.80976 4.59927 146 v - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01431 4.64966 5.37201 0.61958 0.77255 0.48576 0.95510
+ 135 2.95269 4.69517 3.60665 1.97843 3.45446 3.85775 4.03090 3.11104 3.08550 1.51175 3.71657 3.54821 4.25024 3.42171 3.42726 3.14413 3.18521 2.92923 4.99169 2.16477 147 l - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01431 4.64966 5.37201 0.61958 0.77255 0.48576 0.95510
+ 136 2.73695 4.65605 3.95869 3.70106 4.76353 3.44035 4.74373 4.12362 3.71195 3.84701 4.72350 3.83266 1.83108 4.03586 3.98938 2.92296 0.79061 3.61700 6.10688 4.92055 148 t - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01431 4.64966 5.37201 0.61958 0.77255 0.48576 0.95510
+ 137 2.98616 1.77306 3.54257 2.96917 4.20397 3.77066 2.12431 3.65954 1.76469 3.27311 4.13902 3.40552 4.18321 3.14102 2.82770 3.07008 3.21991 3.37163 5.45841 4.17830 149 k - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01431 4.64966 5.37201 0.61958 0.77255 0.48576 0.95510
+ 138 2.87318 2.27487 4.08101 3.51686 3.73262 3.86520 4.28384 2.71684 1.98443 2.72135 3.68760 3.80830 4.30540 3.67099 3.52284 3.18558 3.14569 1.41553 5.23503 4.02368 150 v - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01431 4.64966 5.37201 0.61958 0.77255 0.48576 0.95510
+ 139 1.47784 5.66115 1.72234 1.61325 4.99518 3.55917 4.01510 4.49306 2.94403 3.99053 4.79675 3.03102 4.12373 3.15930 3.50625 3.04342 3.40107 4.05871 6.14898 4.67614 151 a - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01431 4.64966 5.37201 0.61958 0.77255 0.48576 0.95510
+ 140 1.90208 4.30196 4.42388 3.85048 2.53064 3.96808 4.20458 2.66664 3.71202 2.43952 3.40720 3.98922 4.33968 3.90366 3.85104 3.27006 3.09799 1.78444 4.75310 1.94066 152 v - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01431 4.64966 5.37201 0.61958 0.77255 0.48576 0.95510
+ 141 2.90716 5.18104 2.93680 1.74324 4.63204 3.55056 3.97551 4.06458 2.79684 3.63682 4.44671 3.14754 1.69442 3.12392 3.26513 2.91368 2.00011 3.66927 5.83669 4.46781 153 p - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01431 4.64966 5.37201 0.61958 0.77255 0.48576 0.95510
+ 142 2.78359 4.49365 3.67376 3.10170 3.62714 3.76072 4.00455 2.07844 2.47123 1.90888 3.58652 3.50028 4.13823 2.73193 3.32251 3.01272 2.16843 2.73906 5.07658 3.84773 154 l - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01431 4.64966 5.37201 0.61958 0.77255 0.48576 0.95510
+ 143 2.78538 4.94129 3.12446 1.90128 4.30138 2.71211 3.90968 3.70356 2.74123 3.32793 4.14951 3.17742 4.01886 3.07350 3.19942 1.81320 3.05695 2.10287 5.57786 4.24807 155 s - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01431 4.64966 5.37201 0.61958 0.77255 0.48576 0.95510
+ 144 3.00331 5.31213 1.34717 2.61563 4.93207 1.88993 4.12688 4.41067 3.06726 3.95757 4.76779 3.14959 4.12417 3.28737 3.59771 2.99405 1.91587 3.94167 6.13257 4.71628 156 d - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.24219 4.64967 1.58216 0.61958 0.77255 0.48576 0.95510
+ 145 2.90502 4.57765 3.77724 3.34069 3.46532 3.78667 1.98962 2.88032 3.15748 2.73793 3.75784 3.66796 4.25545 3.57022 3.42567 3.15372 3.18669 1.26808 5.01387 3.61579 157 v - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01794 4.42541 5.14776 0.61958 0.77255 0.82155 0.57937
+ 146 2.75147 4.74628 3.34357 2.80400 4.07335 3.57581 3.87957 3.30949 1.78780 3.06148 3.94193 3.25653 4.01680 3.07201 2.96883 2.85636 1.75071 2.41258 5.38823 4.11449 158 t - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01794 4.42541 5.14776 0.61958 0.77255 0.82155 0.57937
+ 147 3.00773 4.73948 3.43003 1.82450 3.89452 3.85717 4.23450 1.28531 3.14323 2.70935 3.80542 3.55715 4.30487 3.50591 3.49765 3.23918 3.26469 2.47035 5.46041 4.19035 159 i - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01794 4.42541 5.14776 0.61958 0.77255 0.82155 0.57937
+ 148 3.57591 5.69104 2.89034 0.43897 5.13067 3.74172 4.42582 4.71128 3.39211 4.24880 5.23832 3.41868 4.38352 3.65470 3.83330 3.52091 3.89687 4.34990 6.18698 4.96489 160 E - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01794 4.42541 5.14776 0.61958 0.77255 0.82155 0.57937
+ 149 2.88350 5.07456 2.83549 1.62789 4.53394 3.47506 3.97205 3.88890 2.80700 3.53770 4.39728 3.11273 4.03065 3.14364 3.24643 2.90638 1.35985 3.52987 5.77718 4.42810 161 t - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01794 4.42541 5.14776 0.61958 0.77255 0.82155 0.57937
+ 150 3.16212 4.85727 3.80335 3.36209 3.16774 3.96001 1.35846 3.22944 3.06257 1.59155 3.82989 3.70773 4.37953 3.54897 3.31681 3.33732 3.40874 3.10705 4.77246 3.24032 162 h - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01794 4.42541 5.14776 0.61958 0.77255 0.82155 0.57937
+ 151 2.94073 5.06198 3.33349 2.84187 4.57011 3.62118 3.89060 3.90975 1.20057 3.49273 4.35032 3.28330 4.09402 3.04189 2.67455 2.98263 1.83732 3.56058 5.65563 4.40287 163 k - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01794 4.42541 5.14776 0.61958 0.77255 0.82155 0.57937
+ 152 1.71060 5.15430 2.74244 1.20101 4.65798 3.45089 3.98759 4.03463 2.85903 3.66257 4.51252 3.07555 4.02822 3.15387 3.33026 2.91028 3.22047 3.64649 5.88103 4.50506 164 e - - -
+ 2.68526 4.42272 2.77529 2.72949 3.46401 2.40536 3.72542 3.29401 2.67788 2.69262 4.24737 2.90394 2.73787 3.18194 2.89848 2.37934 2.77449 2.98523 4.58524 3.61550
+ 0.55049 0.85960 * 1.51709 0.24763 0.00000 *
+//
--- /dev/null
+package jalview.io;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertNull;
+import static org.testng.Assert.assertTrue;
+
+import jalview.datamodel.HMMNode;
+import jalview.datamodel.HiddenMarkovModel;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Scanner;
+
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+import junit.extensions.PA;
+
+public class HMMFileTest {
+
+ HMMFile fn3;
+
+ HMMFile pKinase;
+
+ HMMFile made1;
+
+ @BeforeClass(alwaysRun = true)
+ public void setUp() throws IOException
+ {
+ fn3 = new HMMFile("test/jalview/io/test_fn3_hmm.txt",
+ DataSourceType.FILE);
+
+ pKinase = new HMMFile("test/jalview/io/test_PKinase_hmm.txt",
+ DataSourceType.FILE);
+
+ made1 = new HMMFile("test/jalview/io/test_MADE1_hmm.txt",
+ DataSourceType.FILE);
+ }
+
+ @Test(groups = "Functional")
+ public void testParse() throws IOException
+ {
+ HiddenMarkovModel hmm = pKinase.getHMM();
+ assertEquals(hmm.getName(), "Pkinase");
+ assertEquals(hmm.getProperty(HMMFile.ACCESSION_NUMBER), "PF00069.17");
+ assertEquals(hmm.getProperty(HMMFile.DESCRIPTION),
+ "Protein kinase domain");
+ assertEquals(hmm.getLength(), 260);
+ assertNull(hmm.getProperty(HMMFile.MAX_LENGTH));
+ assertEquals(hmm.getAlphabetType(), "amino");
+ assertFalse(hmm.getBooleanProperty(HMMFile.REFERENCE_ANNOTATION));
+ assertFalse(hmm.getBooleanProperty(HMMFile.MASKED_VALUE));
+ assertTrue(hmm.getBooleanProperty(HMMFile.CONSENSUS_RESIDUE));
+ assertTrue(hmm.getBooleanProperty(HMMFile.CONSENSUS_STRUCTURE));
+ assertTrue(hmm.getBooleanProperty(HMMFile.MAP));
+ assertEquals(hmm.getProperty(HMMFile.DATE), "Thu Jun 16 11:44:06 2011");
+ assertNull(hmm.getProperty(HMMFile.COMMAND_LOG));
+ assertEquals(hmm.getProperty(HMMFile.NUMBER_OF_SEQUENCES), "54");
+ assertEquals(hmm.getProperty(HMMFile.EFF_NUMBER_OF_SEQUENCES),
+ "3.358521");
+ assertEquals(hmm.getProperty(HMMFile.CHECK_SUM), "3106786190");
+ assertEquals(hmm.getProperty(HMMFile.GATHERING_THRESHOLD),
+ "70.30 70.30");
+ assertEquals(hmm.getProperty(HMMFile.TRUSTED_CUTOFF), "70.30 70.30");
+ assertEquals(hmm.getProperty(HMMFile.NOISE_CUTOFF), "70.20 70.20");
+
+ assertEquals(hmm.getSymbols(), "ACDEFGHIKLMNPQRSTVWY");
+
+ assertEquals(hmm.getMatchEmissionProbability(0, 'Y'), 0.16102, 0.001d);
+ assertEquals(hmm.getMatchEmissionProbability(11, 'P'), 0.0130, 0.001d);
+ assertEquals(hmm.getMatchEmissionProbability(24, 'I'), 0.02583, 0.001d);
+ assertEquals(hmm.getMatchEmissionProbability(83, 'C'), 0.008549,
+ 0.001d);
+ assertEquals(hmm.getMatchEmissionProbability(332, 'E'), 0.07998,
+ 0.001d);
+ assertEquals(hmm.getMatchEmissionProbability(381, 'D'), 0.014465,
+ 0.001d);
+ assertEquals(hmm.getMatchEmissionProbability(475, 'Y'), 0.02213,
+ 0.001d);
+
+ assertEquals(hmm.getInsertEmissionProbability(1, 'C'), 0.012, 0.001d);
+ assertEquals(hmm.getInsertEmissionProbability(14, 'H'), 0.02411,
+ 0.001d);
+ assertEquals(hmm.getInsertEmissionProbability(23, 'L'), 0.06764,
+ 0.001d);
+ assertEquals(hmm.getInsertEmissionProbability(90, 'D'), 0.0623, 0.001d);
+ assertEquals(hmm.getInsertEmissionProbability(374, 'T'), 0.0623,
+ 0.001d);
+ assertEquals(hmm.getInsertEmissionProbability(470, 'P'), 0.0647,
+ 0.001d);
+
+ assertEquals(hmm.getStateTransitionProbability(2, 6), 0.3848, 0.001d);
+ assertEquals(hmm.getStateTransitionProbability(38, 3), 0.5382, 0.001d);
+ assertEquals(hmm.getStateTransitionProbability(305, 3), 0.2916, 0.001d);
+ assertEquals(hmm.getStateTransitionProbability(380, 0), 0.99, 0.001d);
+ assertEquals(hmm.getStateTransitionProbability(453, 1), 0.0066, 0.001d);
+
+ assertEquals(hmm.getNodeMapPosition(3), 3);
+ assertEquals(hmm.getReferenceAnnotation(7), '-');
+ assertEquals(hmm.getConsensusResidue(23), 't');
+ assertEquals(hmm.getMaskedValue(30), '-');
+ assertEquals(hmm.getConsensusStructure(56), 'S');
+
+ assertEquals(hmm.getNodeMapPosition(78), 136);
+ assertEquals(hmm.getReferenceAnnotation(93), '-');
+ assertEquals(hmm.getConsensusResidue(145), 'a');
+ assertEquals(hmm.getMaskedValue(183), '-');
+ assertEquals(hmm.getConsensusStructure(240), 'H');
+ }
+
+ /**
+ * Test that Jalview can parse an HMM file even with a bunch of 'mandatory'
+ * fields missing (including no MAP annotation or // terminator line)
+ *
+ * @throws IOException
+ */
+ @Test(groups = "Functional")
+ public void testParse_minimalFile() throws IOException
+ {
+ /*
+ * ALPH is absent, alphabet inferred from HMM header line
+ * Optional COMPO line is absent
+ * first line after HMM is a guide line for readability
+ * next line is BEGIN node insert emissions
+ * next line is BEGIN node transitions
+ * next line is first sequence node match emissions 1.1 1.2 1.3
+ * next line is first sequence node insert emissions 1.4 1.5 1.6
+ * last line is first sequence node transitions
+ */
+ //@formatter:off
+ String hmmData =
+ "HMMER3\n" +
+ "HMM P M J\n" +
+ // both spec and parser require a line after the HMM line
+ " m->m m->i m->d i->m i->i d->m d->d\n" +
+ " 0.1 0.2 0.3\n" +
+ " 0.4 0.5 0.6 0.7 0.8 0.9 0.95\n" +
+ " 1 1.1 1.2 1.3 - - - - -\n" +
+ " 1.4 1.5 1.6\n" +
+ " 1.7 1.8 1.9 2.0 2.1 2.2 2.3\n" +
+ " 2 1.01 1.02 1.03 - - - - -\n" +
+ " 1.04 1.05 1.06\n" +
+ " 1.7 1.8 1.9 2.0 2.1 2.2 2.3\n";
+ //@formatter:on
+ HMMFile parser = new HMMFile(hmmData, DataSourceType.PASTE);
+ HiddenMarkovModel hmm = parser.getHMM();
+ assertNotNull(hmm);
+ assertEquals(hmm.getSymbols(), "PMJ");
+ // no LENG property: this should return node count excluding BEGIN node
+ assertEquals(hmm.getLength(), 2);
+
+ // node 1 (implicitly mapped to column 0)
+ double prob = hmm.getMatchEmissionProbability(0, 'p');
+ assertEquals(prob, Math.pow(Math.E, -1.1));
+ prob = hmm.getInsertEmissionProbability(0, 'J');
+ assertEquals(prob, Math.pow(Math.E, -1.6));
+
+ // node 2 (implicitly mapped to column 1)
+ prob = hmm.getMatchEmissionProbability(1, 'M');
+ assertEquals(prob, Math.pow(Math.E, -1.02));
+ prob = hmm.getInsertEmissionProbability(1, 'm');
+ assertEquals(prob, Math.pow(Math.E, -1.05));
+ }
+
+ @Test(groups = "Functional")
+ public void testParseHeaderLines_amino() throws IOException
+ {
+ FileReader fr = new FileReader(
+ new File("test/jalview/io/test_fn3_hmm.txt"));
+ BufferedReader br = new BufferedReader(fr);
+ HiddenMarkovModel hmm = new HiddenMarkovModel();
+ HMMFile testee = new HMMFile();
+ PA.setValue(testee, "hmm", hmm);
+ testee.parseHeaderLines(br);
+ br.close();
+ fr.close();
+
+ assertEquals(hmm.getName(), "fn3");
+ assertEquals(hmm.getProperty(HMMFile.ACCESSION_NUMBER), "PF00041.13");
+ assertEquals(hmm.getProperty(HMMFile.DESCRIPTION),
+ "Fibronectin type III domain");
+ assertEquals(hmm.getProperty(HMMFile.LENGTH), "86");
+ assertNull(hmm.getProperty(HMMFile.MAX_LENGTH));
+ assertEquals(hmm.getAlphabetType(), "amino");
+ assertFalse(hmm.getBooleanProperty(HMMFile.REFERENCE_ANNOTATION));
+ assertFalse(hmm.getBooleanProperty(HMMFile.MASKED_VALUE));
+ assertTrue(hmm.getBooleanProperty(HMMFile.CONSENSUS_RESIDUE));
+ assertTrue(hmm.getBooleanProperty(HMMFile.CONSENSUS_STRUCTURE));
+
+ assertTrue(hmm.getBooleanProperty(HMMFile.MAP));
+ assertEquals(hmm.getProperty(HMMFile.DATE), "Fri Jun 20 08:22:31 2014");
+ assertNull(hmm.getProperty(HMMFile.COMMAND_LOG));
+ assertEquals(hmm.getProperty(HMMFile.NUMBER_OF_SEQUENCES), "106");
+ assertEquals(hmm.getProperty(HMMFile.EFF_NUMBER_OF_SEQUENCES),
+ "11.415833");
+ assertEquals(hmm.getProperty(HMMFile.CHECK_SUM), "3564431818");
+ assertEquals(hmm.getProperty(HMMFile.GATHERING_THRESHOLD), "8.00 7.20");
+ assertEquals(hmm.getProperty(HMMFile.TRUSTED_CUTOFF), "8.00 7.20");
+ assertEquals(hmm.getProperty(HMMFile.NOISE_CUTOFF), "7.90 7.90");
+ assertEquals(hmm.getViterbi(), "-9.7737 0.71847");
+ assertEquals(hmm.getMSV(), "-9.4043 0.71847");
+ assertEquals(hmm.getForward(), "-3.8341 0.71847");
+ }
+
+ @Test(groups = "Functional")
+ public void testParseHeaderLines_dna() throws IOException
+ {
+ FileReader fr = new FileReader(
+ new File("test/jalview/io/test_MADE1_hmm.txt"));
+ BufferedReader br = new BufferedReader(fr);
+ HiddenMarkovModel hmm = new HiddenMarkovModel();
+ HMMFile testee = new HMMFile();
+ PA.setValue(testee, "hmm", hmm);
+ testee.parseHeaderLines(br);
+ br.close();
+ fr.close();
+
+ assertEquals(hmm.getName(), "MADE1");
+ assertEquals(hmm.getProperty(HMMFile.ACCESSION_NUMBER),
+ "DF0000629.2");
+ assertEquals(hmm.getProperty(HMMFile.DESCRIPTION),
+ "MADE1 (MAriner Derived Element 1), a TcMar-Mariner DNA transposon");
+ assertEquals(hmm.getProperty(HMMFile.LENGTH), "80");
+ assertEquals(hmm.getProperty(HMMFile.MAX_LENGTH), "426");
+ assertEquals(hmm.getAlphabetType(), "DNA");
+ assertTrue(hmm.getBooleanProperty(HMMFile.REFERENCE_ANNOTATION));
+ assertFalse(hmm.getBooleanProperty(HMMFile.MASKED_VALUE));
+ assertTrue(hmm.getBooleanProperty(HMMFile.CONSENSUS_RESIDUE));
+ assertFalse(hmm.getBooleanProperty(HMMFile.CONSENSUS_STRUCTURE));
+ assertTrue(hmm.getBooleanProperty(HMMFile.MAP));
+ assertEquals(hmm.getProperty(HMMFile.DATE), "Tue Feb 19 20:33:41 2013");
+ assertNull(hmm.getProperty(HMMFile.COMMAND_LOG));
+ assertEquals(hmm.getProperty(HMMFile.NUMBER_OF_SEQUENCES), "1997");
+ assertEquals(hmm.getProperty(HMMFile.EFF_NUMBER_OF_SEQUENCES), "3.911818");
+ assertEquals(hmm.getProperty(HMMFile.CHECK_SUM), "3015610723");
+ assertEquals(hmm.getProperty(HMMFile.GATHERING_THRESHOLD),
+ "2.324 4.234");
+ assertEquals(hmm.getProperty(HMMFile.TRUSTED_CUTOFF), "2.343 1.212");
+ assertEquals(hmm.getProperty(HMMFile.NOISE_CUTOFF), "2.354 5.456");
+ assertEquals(hmm.getViterbi(), "-9.3632 0.71858");
+ assertEquals(hmm.getMSV(), "-8.5786 0.71858");
+ assertEquals(hmm.getForward(), "-3.4823 0.71858");
+ }
+
+ @Test(groups = "Functional")
+ public void testFillList() throws IOException
+ {
+ Scanner scanner1 = new Scanner("1.3 2.4 5.3 3.9 9.8 4.7 4.3 2.3 6.9");
+ ArrayList<Double> filledArray = new ArrayList<>();
+
+ filledArray.add(0.27253);
+ filledArray.add(0.0907);
+ filledArray.add(0.00499);
+ filledArray.add(0.02024);
+ filledArray.add(0.00005);
+ filledArray.add(0.00909);
+ filledArray.add(0.01357);
+ filledArray.add(0.10026);
+ filledArray.add(0.001);
+
+ double[] testList = HMMFile.parseDoubles(scanner1, 9);
+
+ for (int i = 0; i < 9; i++)
+ {
+ assertEquals(testList[i], filledArray.get(i), 0.001d);
+ }
+
+ filledArray.clear();
+ scanner1.close();
+
+ Scanner scanner2 = new Scanner(
+ "1.346 5.554 35.345 5.64 1.4");
+ filledArray.add(0.2603);
+ filledArray.add(0.00387);
+ filledArray.add(0d);
+ filledArray.add(0.00355);
+ filledArray.add(0.2466);
+
+ testList = HMMFile.parseDoubles(scanner2, 5);
+
+ for (int i = 0; i < 5; i++)
+ {
+ assertEquals(testList[i], filledArray.get(i), 0.001d);
+ }
+ }
+
+ @Test(groups = "Functional")
+ public void testParseModel() throws IOException
+ {
+ FileReader fr = new FileReader(
+ new File("test/jalview/io/test_MADE1_hmm.txt"));
+ BufferedReader br = new BufferedReader(fr);
+ HiddenMarkovModel testHMM = new HiddenMarkovModel();
+ String line = null;
+ do
+ {
+ line = br.readLine(); // skip header lines up to HMM plus one
+ } while (!line.startsWith("HMM "));
+ br.readLine();
+
+ made1.parseModel(br);
+ testHMM = made1.getHMM();
+
+ br.close();
+ fr.close();
+
+ assertEquals(testHMM.getMatchEmissionProbability(1, 'C'), 0.09267,
+ 0.001d);
+ assertEquals(testHMM.getMatchEmissionProbability(25, 'G'), 0.07327,
+ 0.001d);
+ assertEquals(testHMM.getMatchEmissionProbability(1092, 'C'), 0.04184,
+ 0.001d);
+ assertEquals(testHMM.getMatchEmissionProbability(1107, 'G'), 0.07,
+ 0.001d);
+
+ assertEquals(testHMM.getInsertEmissionProbability(0, 'G'), 0.25,
+ 0.001d);
+ assertEquals(testHMM.getInsertEmissionProbability(247, 'T'), 0.2776,
+ 0.001d);
+ assertEquals(testHMM.getInsertEmissionProbability(1096, 'T'), 0.25,
+ 0.001d);
+ assertEquals(testHMM.getInsertEmissionProbability(1111, 'T'), 0.25,
+ 0.001d);
+
+ assertEquals(testHMM.getStateTransitionProbability(1, 0), 0.9634,
+ 0.001d);
+ assertEquals(testHMM.getStateTransitionProbability(5, 1), 0.0203,
+ 0.001d);
+ assertEquals(testHMM.getStateTransitionProbability(14, 3), 0.2515,
+ 0.001d);
+ assertEquals(testHMM.getStateTransitionProbability(65, 4), 0.78808,
+ 0.001d);
+ assertEquals(testHMM.getStateTransitionProbability(1080, 2), 0.01845,
+ 0.001d);
+ assertEquals(testHMM.getStateTransitionProbability(1111, 6),
+ Double.NEGATIVE_INFINITY);
+ }
+
+ @Test(groups = "Functional")
+ public void testParseAnnotations()
+ {
+ HMMFile testFile = new HMMFile();
+ HiddenMarkovModel hmm = new HiddenMarkovModel();
+ PA.setValue(testFile, "hmm", hmm);
+
+ List<HMMNode> nodes = new ArrayList<>();
+ nodes.add(new HMMNode()); // BEGIN node
+
+ hmm.setProperty(HMMFile.CONSENSUS_RESIDUE, "yes");
+ hmm.setProperty(HMMFile.MAP, "yes");
+ hmm.setProperty(HMMFile.REFERENCE_ANNOTATION, "yes");
+ hmm.setProperty(HMMFile.CONSENSUS_STRUCTURE, "yes");
+ hmm.setProperty(HMMFile.MASKED_VALUE, "yes");
+ Scanner scanner = new Scanner("1345 t t t t");
+ HMMNode node = new HMMNode();
+ nodes.add(node);
+ testFile.parseAnnotations(scanner, node);
+
+ hmm.setProperty(HMMFile.CONSENSUS_RESIDUE, "yes");
+ hmm.setProperty(HMMFile.MAP, "no");
+ hmm.setProperty(HMMFile.REFERENCE_ANNOTATION, "yes");
+ hmm.setProperty(HMMFile.CONSENSUS_STRUCTURE, "no");
+ hmm.setProperty(HMMFile.MASKED_VALUE, "no");
+ Scanner scanner2 = new Scanner("- y x - -");
+ node = new HMMNode();
+ nodes.add(node);
+ testFile.parseAnnotations(scanner2, node);
+
+ hmm.setNodes(nodes);
+
+ assertEquals(hmm.getNodeMapPosition(1), 1345);
+ assertEquals(hmm.getConsensusResidue(1), 't');
+ assertEquals(hmm.getReferenceAnnotation(1), 't');
+ assertEquals(hmm.getMaskedValue(1), 't');
+ assertEquals(hmm.getConsensusStructure(1), 't');
+
+ scanner.close();
+ }
+
+ /**
+ * tests to see if file produced by the output matches the file from the input
+ *
+ * @throws IOException
+ */
+ @Test(groups = "Functional")
+ public void testPrint_roundTrip() throws IOException
+ {
+ String output = pKinase.print();
+ HMMFile pKinaseClone = new HMMFile(
+ new FileParse(output, DataSourceType.PASTE));
+ HiddenMarkovModel pKinaseHMM = pKinase.getHMM();
+ HiddenMarkovModel pKinaseCloneHMM = pKinaseClone.getHMM();
+
+ checkModelsMatch(pKinaseHMM, pKinaseCloneHMM);
+ }
+
+ /**
+ * A helper method to check two HMM models have the same values
+ *
+ * @param model1
+ * @param model2
+ */
+ protected void checkModelsMatch(HiddenMarkovModel model1,
+ HiddenMarkovModel model2)
+ {
+ assertEquals(model1.getLength(), model2.getLength());
+
+ for (int i = 0; i < model1.getLength(); i++)
+ {
+ String msg = "For Node" + i;
+ assertEquals(model1.getNode(i).getMatchEmissions(),
+ model2.getNode(i).getMatchEmissions(), msg);
+ assertEquals(model1.getNode(i).getInsertEmissions(),
+ model2.getNode(i).getInsertEmissions(), msg);
+ assertEquals(model1.getNode(i).getStateTransitions(),
+ model2.getNode(i).getStateTransitions(), msg);
+
+ if (i > 0)
+ {
+ assertEquals(model1.getNodeMapPosition(i),
+ model2.getNodeMapPosition(i), msg);
+ assertEquals(model1.getReferenceAnnotation(i),
+ model2.getReferenceAnnotation(i), msg);
+ assertEquals(model1.getConsensusResidue(i),
+ model2.getConsensusResidue(i), msg);
+ }
+ }
+ }
+
+ @Test(groups = "Functional")
+ public void testAppendProperties() throws FileNotFoundException
+ {
+ StringBuilder sb = new StringBuilder();
+ fn3.appendProperties(sb);
+
+ Scanner testScanner = new Scanner(sb.toString());
+
+ String[] expected = new String[] { "HMMER3/f [3.1b1 | May 2013]",
+ "NAME fn3", "ACC PF00041.13",
+ "DESC Fibronectin type III domain", "LENG 86", "ALPH amino",
+ "RF no", "MM no", "CONS yes", "CS yes", "MAP yes",
+ "DATE Fri Jun 20 08:22:31 2014", "NSEQ 106", "EFFN 11.415833",
+ "CKSUM 3564431818", "GA 8.00 7.20", "TC 8.00 7.20",
+ "NC 7.90 7.90", "STATS LOCAL MSV -9.4043 0.71847",
+ "STATS LOCAL VITERBI -9.7737 0.71847",
+ "STATS LOCAL FORWARD -3.8341 0.71847" };
+
+ for (String value : expected)
+ {
+ assertEquals(testScanner.nextLine(), value);
+ }
+
+ testScanner.close();
+ }
+
+ @Test(groups = "Functional")
+ public void testAppendModelAsString() throws FileNotFoundException
+ {
+ StringBuilder sb = new StringBuilder();
+ fn3.appendModelAsString(sb);
+ String string = sb.toString();
+
+ assertEquals(findValue(2, 2, 2, string), "4.42225");
+ assertEquals(findValue(12, 14, 1, string), "2.79307");
+ assertEquals(findValue(6, 24, 3, string), "0.48576");
+ assertEquals(findValue(19, 33, 2, string), "4.58477");
+ assertEquals(findValue(20, 64, 2, string), "3.61505");
+ assertEquals(findValue(3, 72, 3, string), "6.81068");
+ assertEquals(findValue(10, 80, 2, string), "2.69355");
+ assertEquals(findValue(16, 65, 1, string), "2.81003");
+ assertEquals(findValue(14, 3, 1, string), "2.69012");
+ assertEquals(findValue(11, 32, 1, string), "4.34805");
+ }
+
+ /**
+ * A helper method to find a token in the model string
+ *
+ * @param symbolIndex
+ * index of symbol being searched. First symbol has index 1.
+ * @param nodeIndex
+ * index of node being searched. Begin node has index 0. First node
+ * has index 1.
+ * @param line
+ * index of line being searched in node. First line has index 1.
+ * @param model
+ * string model being searched
+ * @return value at specified position
+ */
+ private String findValue(int symbolIndex, int nodeIndex, int line,
+ String model)
+ {
+ String value = "";
+ Scanner scanner = new Scanner(model);
+ scanner.nextLine();
+ scanner.nextLine();
+
+ for (int lineIndex = 0; lineIndex < line - 1; lineIndex++)
+ {
+ scanner.nextLine();
+ }
+ for (int node = 0; node < nodeIndex; node++)
+ {
+ scanner.nextLine();
+ scanner.nextLine();
+ scanner.nextLine();
+ }
+
+ for (int symbol = 0; symbol < symbolIndex; symbol++)
+ {
+ value = scanner.next();
+ if ("COMPO".equals(value))
+ {
+ scanner.next();
+ }
+ else if (value.length() < 7)
+ {
+ scanner.next();
+ }
+ }
+ scanner.close();
+ return value;
+ }
+}
+
@AfterClass(alwaysRun = true)
public static void tearDownAfterClass() throws Exception
{
- jalview.gui.Desktop.instance.closeAll_actionPerformed(null);
+ jalview.gui.Desktop.getInstance().closeAll_actionPerformed(null);
}
@BeforeTest(alwaysRun = true)
public static void clearDesktop()
{
- if (Desktop.instance != null && Desktop.getFrames() != null
+ if (Desktop.getInstance() != null && Desktop.getFrames() != null
&& Desktop.getFrames().length > 0)
{
- Desktop.instance.closeAll_actionPerformed(null);
+ Desktop.getInstance().closeAll_actionPerformed(null);
}
}
@AfterClass(alwaysRun = true)
public static void tearDownAfterClass() throws Exception
{
- jalview.gui.Desktop.instance.closeAll_actionPerformed(null);
+ jalview.gui.Desktop.getInstance().closeAll_actionPerformed(null);
}
sar.appendFeature(sb, 2, null, sf, null, 0);
assertEquals("123456", sb.toString());
- // residuePos == 1 matches start of feature, text appended (but no <br/>)
+ // residuePos == 1 matches start of feature, text appended (but no <br>)
// feature score is not included
sar.appendFeature(sb, 1, null, sf, null, 0);
assertEquals("123456disulfide bond 1:3", sb.toString());
// residuePos == 3 matches end of feature, text appended
- // <br/> is prefixed once sb.length() > 6
+ // <br> is prefixed once sb.length() > 6
sar.appendFeature(sb, 3, null, sf, null, 0);
- assertEquals("123456disulfide bond 1:3<br/>disulfide bond 1:3",
+ assertEquals("123456disulfide bond 1:3<br>disulfide bond 1:3",
sb.toString());
}
*/
minmax.put("METAL", new float[][] { { 0f, 1f }, null });
sar.appendFeature(sb, 1, fr, sf, null, 0);
- // <br/> is appended to a buffer > 6 in length
- assertEquals("METAL 1 3; Fe2-S<br/>METAL 1 3; Fe2-S Score=1.3",
+ // <br> is appended to a buffer > 6 in length
+ assertEquals("METAL 1 3; Fe2-S<br>METAL 1 3; Fe2-S Score=1.3",
sb.toString());
/*
null));
sb.setLength(0);
sar.createSequenceAnnotationReport(sb, seq, true, true, null);
- String expected = "<i>SeqDesc<br/>Type1 ; Nonpos Score=1.0</i>";
+ String expected = "<i>SeqDesc<br>Type1 ; Nonpos Score=1.0</i>";
assertEquals(expected, sb.toString());
/*
sb.setLength(0);
sar.createSequenceAnnotationReport(sb, seq, true, true, fr);
- expected = "<i>SeqDesc<br/>Metal ; Desc<br/>Type1 ; Nonpos</i>";
+ expected = "<i>SeqDesc<br>Metal ; Desc<br>Type1 ; Nonpos</i>";
assertEquals(expected, sb.toString());
/*
seq.addSequenceFeature(sf2);
sb.setLength(0);
sar.createSequenceAnnotationReport(sb, seq, true, true, fr);
- expected = "<i>SeqDesc<br/>Metal ; Desc<br/>Type1 ; Nonpos<br/>Variant ; Havana</i>";
+ expected = "<i>SeqDesc<br>Metal ; Desc<br>Type1 ; Nonpos<br>Variant ; Havana</i>";
assertEquals(expected, sb.toString());
/*
fc.setAttributeName("clinical_significance");
fr.setColour("Variant", fc);
sar.createSequenceAnnotationReport(sb, seq, true, true, fr);
- expected = "<i>SeqDesc<br/>UNIPROT P30419<br/>PDB 3iu1<br/>Metal ; Desc<br/>"
- + "Type1 ; Nonpos<br/>Variant ; Havana; clinical_significance=benign</i>";
+ expected = "<i>SeqDesc<br>UNIPROT P30419<br>PDB 3iu1<br>Metal ; Desc<br>"
+ + "Type1 ; Nonpos<br>Variant ; Havana; clinical_significance=benign</i>";
assertEquals(expected, sb.toString());
// with showNonPositionalFeatures = false
sb.setLength(0);
sar.createSequenceAnnotationReport(sb, seq, true, false, fr);
- expected = "<i>SeqDesc<br/>UNIPROT P30419<br/>PDB 3iu1</i>";
+ expected = "<i>SeqDesc<br>UNIPROT P30419<br>PDB 3iu1</i>";
assertEquals(expected, sb.toString());
/*
sf2.setDescription(
"This is a very long description which should be truncated");
sar.createSequenceAnnotationReport(sb, seq, false, true, fr);
- expected = "<i>SeqDesc<br/>Metal ; Desc<br/>Type1 ; Nonpos<br/>Variant ; This is a very long description which sh...; clinical_significance=benign</i>";
+ expected = "<i>SeqDesc<br>Metal ; Desc<br>Type1 ; Nonpos<br>Variant ; This is a very long description which sh...; clinical_significance=benign</i>";
assertEquals(expected, sb.toString());
// see other tests for treatment of status and html
String report = sb.toString();
assertTrue(report
.startsWith(
- "<i><br/>UNIPROT P30410, P30411, P30412, P30413,...<br/>PDB0 3iu1"));
+ "<i><br>UNIPROT P30410, P30411, P30412, P30413,...<br>PDB0 3iu1"));
assertTrue(report
.endsWith(
- "<br/>PDB7 3iu1<br/>PDB8,...<br/>(Output Sequence Details to list all database references)</i>"));
+ "<br>PDB7 3iu1<br>PDB8,...<br>(Output Sequence Details to list all database references)</i>"));
}
/**
|| (seq_original[i].getSequenceFeatures() != null && seq_new[in]
.getSequenceFeatures() != null));
// compare sequence features
- if (seq_original[i].getSequenceFeatures() != null
+ if (!ignoreFeatures
+ && seq_original[i].getSequenceFeatures() != null
&& seq_new[in].getSequenceFeatures() != null)
{
- System.out.println("There are feature!!!");
+ System.out.println("Checking feature equivalence.");
sequenceFeatures_original = seq_original[i]
.getSequenceFeatures();
sequenceFeatures_new = seq_new[in].getSequenceFeatures();
--- /dev/null
+HMMER3/f [3.1 | February 2013]
+NAME MADE1
+ACC DF0000629.2
+DESC MADE1 (MAriner Derived Element 1), a TcMar-Mariner DNA transposon
+LENG 80
+MAXL 426
+ALPH DNA
+RF yes
+MM no
+CONS yes
+CS no
+MAP yes
+DATE Tue Feb 19 20:33:41 2013
+NSEQ 1997
+EFFN 3.911818
+CKSUM 3015610723
+GA 2.324 4.234
+TC 2.343 1.212
+NC 2.354 5.456
+STATS LOCAL MSV -8.5786 0.71858
+STATS LOCAL VITERBI -9.3632 0.71858
+STATS LOCAL FORWARD -3.4823 0.71858
+HMM A C G T
+ m->m m->i m->d i->m i->i d->m d->d
+ COMPO 1.24257 1.59430 1.62906 1.16413
+ 1.38629 1.38629 1.38629 1.38629
+ 0.03960 3.94183 3.94183 1.46634 0.26236 0.00000 *
+ 1 2.69765 2.44396 2.81521 0.24089 1 t x - -
+ 1.38629 1.38629 1.38629 1.38629
+ 0.03960 3.94183 3.94183 1.46634 0.26236 1.09861 0.40547
+ 2 2.72939 2.37873 2.85832 0.24244 2 t x - -
+ 1.38629 1.38629 1.38629 1.38629
+ 0.03725 4.00179 4.00179 1.46634 0.26236 1.09861 0.40547
+ 3 0.16099 3.16370 2.87328 2.99734 3 a x - -
+ 1.38629 1.38629 1.38629 1.38629
+ 0.03604 4.03416 4.03416 1.46634 0.26236 1.09861 0.40547
+ 4 1.98862 2.42132 0.42649 2.10770 4 g x - -
+ 1.38629 1.38629 1.38629 1.38629
+ 0.03539 4.05203 4.05203 1.46634 0.26236 1.09861 0.40547
+ 5 1.96369 2.69532 0.36534 2.32099 5 g x - -
+ 1.38629 1.38629 1.38629 1.38629
+ 0.03764 4.06427 3.92372 1.46634 0.26236 1.09861 0.40547
+ 6 2.56994 2.11239 2.71946 0.30571 6 t x - -
+ 1.37159 1.41129 1.39124 1.37159
+ 0.03806 3.89715 4.07214 1.50442 0.25122 1.00714 0.45454
+ 7 2.58388 2.10353 2.64646 0.31253 12 t x - -
+ 1.38764 1.38524 1.38764 1.38465
+ 0.03494 4.03864 4.09125 1.40070 0.28293 1.09237 0.40860
+ 8 2.18552 2.70201 0.28821 2.64645 14 g x - -
+ 1.38629 1.38629 1.38629 1.38629
+ 0.03628 4.09157 3.96779 1.46634 0.26236 1.09861 0.40547
+ 9 2.16916 2.82142 0.28427 2.60854 15 g x - -
+ 1.38091 1.39033 1.38365 1.39033
+ 0.03566 4.00237 4.08886 1.38021 0.28972 1.01958 0.44745
+ 10 2.45517 2.15232 2.42886 0.34277 18 t x - -
+ 1.39065 1.39065 1.39065 1.37335
+ 0.03536 4.01212 4.09576 1.39554 0.28462 1.09775 0.40589
+ 11 2.10260 2.95484 0.28160 2.64222 21 g x - -
+ 1.36740 1.40555 1.40555 1.36740
+ 0.03843 3.92069 4.02468 1.44733 0.26814 1.09856 0.40549
+ 12 2.54740 0.30185 2.61355 2.21647 26 c x - -
+ 1.38748 1.38276 1.38748 1.38748
+ 0.03457 4.05446 4.09623 1.40847 0.28040 1.05496 0.42803
+ 13 0.28443 2.72003 2.32214 2.48149 28 a x - -
+ 1.38740 1.38740 1.38298 1.38740
+ 0.03441 4.05976 4.10001 1.41198 0.27926 1.09780 0.40587
+ 14 0.29412 2.55413 2.49679 2.35701 30 a x - -
+ 1.38194 1.39067 1.38194 1.39067
+ 0.03505 4.02482 4.10005 1.39522 0.28473 1.09929 0.40512
+ 15 0.18837 2.99710 2.82270 2.77556 33 a x - -
+ 1.39015 1.39472 1.37503 1.38539
+ 0.03725 3.97815 4.02618 1.37955 0.28994 1.10102 0.40426
+ 16 0.50816 2.05151 2.22111 1.82407 37 a x - -
+ 1.36727 1.38730 1.39683 1.39405
+ 0.04830 3.89881 3.61610 1.29026 0.32186 1.05306 0.42905
+ 17 2.11260 2.73141 0.29747 2.64152 41 g x - -
+ 1.36913 1.40376 1.40376 1.36913
+ 0.03705 3.93681 4.08299 1.44872 0.26771 1.07479 0.41759
+ 18 2.24459 1.90539 2.34054 0.43234 46 t x - -
+ 1.33632 1.42493 1.39937 1.38665
+ 0.04427 3.64574 4.06297 1.70501 0.20061 1.21309 0.35279
+ 19 0.44322 2.17202 2.18055 2.03175 57 a x - -
+ 1.41047 1.41471 1.36338 1.35797
+ 0.03970 3.81957 4.07540 1.65588 0.21186 1.22788 0.34660
+ 20 0.33340 2.42691 2.40824 2.25160 66 a x - -
+ 1.29389 1.44615 1.37917 1.43324
+ 0.04223 3.70146 4.09459 1.55158 0.23815 1.05880 0.42598
+ 21 2.50563 1.98543 2.69601 0.33746 74 t x - -
+ 1.39462 1.39462 1.42862 1.32990
+ 0.04184 3.80216 3.98177 1.80466 0.17976 1.00279 0.45705
+ 22 2.54484 1.97505 2.66483 0.33806 84 t x - -
+ 1.39134 1.39489 1.38662 1.37246
+ 0.03877 3.97504 3.95038 1.37620 0.29107 1.13932 0.38572
+ 23 2.10159 2.83856 0.29282 2.61635 88 g x - -
+ 1.39682 1.39682 1.35536 1.39682
+ 0.05046 3.75402 3.65808 1.08330 0.41321 1.13019 0.39004
+ 24 2.25298 0.61854 2.50691 1.29221 90 c x - -
+ 1.35803 1.49605 1.46737 1.24379
+ 0.06091 3.28322 3.83564 1.89752 0.16245 1.28788 0.32276
+ 25 1.27819 2.23285 0.76242 1.91259 106 g x - -
+ 1.29024 1.67349 1.68279 1.04597
+ 0.05752 3.44263 3.73311 2.58671 0.07825 1.26818 0.33037
+ 26 1.86925 2.58352 0.39466 2.33986 131 g x - -
+ 1.31084 1.49412 1.46666 1.29002
+ 0.04698 3.54257 4.07715 2.25245 0.11109 0.86163 0.54900
+ 27 2.38297 1.93394 2.39162 0.39800 151 t x - -
+ 1.33582 1.47359 1.44163 1.30411
+ 0.04951 3.48445 4.03783 2.15951 0.12260 1.21681 0.35122
+ 28 2.41717 2.17810 2.62774 0.32113 170 t x - -
+ 1.36805 1.48060 1.37439 1.32840
+ 0.04849 3.50958 4.05014 2.58370 0.07850 1.22399 0.34822
+ 29 2.57764 2.35132 2.56552 0.28512 194 t x - -
+ 1.43829 1.43458 1.24787 1.43829
+ 0.04667 3.56670 4.05428 2.49706 0.08591 1.23744 0.34267
+ 30 2.47248 2.07688 2.62257 0.33172 215 t x - -
+ 1.25120 1.52623 1.70635 1.15531
+ 0.08932 3.31524 3.01336 2.81842 0.06156 1.22909 0.34610
+ 31 2.25937 2.13157 2.02027 0.43957 248 t x - -
+ 1.18172 1.43522 1.72841 1.28150
+ 0.07936 2.93117 3.77395 2.46269 0.08906 0.60457 0.79034
+ 32 2.04508 2.84981 0.30490 2.58263 280 g x - -
+ 1.17665 1.66785 1.66218 1.16056
+ 0.05998 3.23615 3.96853 2.83684 0.06040 1.01952 0.44749
+ 33 2.45103 0.38098 2.56776 1.87147 317 c x - -
+ 1.24153 1.52524 1.60663 1.22783
+ 0.05538 3.39046 3.90294 2.73920 0.06680 1.18729 0.36391
+ 34 2.22082 0.36258 2.75077 2.02704 347 c x - -
+ 1.15008 1.62014 1.86511 1.10673
+ 0.06086 3.18178 4.04341 2.94504 0.05403 1.25991 0.33363
+ 35 0.27033 2.66664 2.52541 2.43767 388 a x - -
+ 1.24951 1.47565 1.41392 1.42074
+ 0.07123 3.00373 3.95552 3.13655 0.04440 1.28173 0.32512
+ 36 2.83107 2.41670 2.97197 0.22235 439 t x - -
+ 1.37071 1.57683 1.38637 1.23972
+ 0.05293 3.45216 3.91807 2.54402 0.08181 1.14651 0.38235
+ 37 2.52322 2.25084 2.45909 0.31611 465 t x - -
+ 1.26335 1.55077 1.59008 1.19965
+ 0.07504 3.13329 3.55006 3.08962 0.04659 1.13108 0.38962
+ 38 0.45807 2.30687 1.98940 2.03143 512 a x - -
+ 1.15472 1.67511 1.53797 1.26320
+ 0.09820 3.13076 2.99876 2.79197 0.06326 1.39915 0.28343
+ 39 2.37471 0.42180 2.44763 1.80427 550 c x - -
+ 1.23785 1.49058 1.48364 1.35502
+ 0.06081 3.19472 4.01643 2.41851 0.09327 0.94671 0.49105
+ 40 2.32826 1.95481 2.36781 0.40458 578 t x - -
+ 1.36586 1.46001 1.43000 1.29720
+ 0.05257 3.39673 4.03256 1.84862 0.17133 1.40979 0.27997
+ 41 2.68669 2.13935 2.81520 0.28200 592 t x - -
+ 1.34965 1.42793 1.45781 1.31633
+ 0.04735 3.57826 3.99988 2.09424 0.13144 1.22129 0.34934
+ 42 2.55904 2.16444 2.70859 0.29952 609 t x - -
+ 1.12072 1.61936 1.63578 1.26895
+ 0.07346 3.25910 3.42962 2.85641 0.05919 1.38363 0.28857
+ 43 1.99923 1.61027 2.26343 0.57851 646 t x - -
+ 1.32290 1.58747 1.61095 1.11018
+ 0.06656 3.08568 3.97944 2.44774 0.09046 0.75593 0.63407
+ 44 0.23887 2.79899 2.55209 2.60783 675 a x - -
+ 1.18557 1.50323 1.59070 1.31590
+ 0.05597 3.38637 3.88222 2.46900 0.08847 1.27945 0.32599
+ 45 0.29593 2.53488 2.53903 2.32335 701 a x - -
+ 1.08710 1.54222 1.59276 1.40430
+ 0.07539 2.94521 3.91062 1.91623 0.15918 1.22327 0.34852
+ 46 2.58352 2.40524 2.76700 0.25955 725 t x - -
+ 1.19685 1.58503 1.74852 1.14293
+ 0.06124 3.18279 4.02089 2.82961 0.06085 1.05474 0.42814
+ 47 2.13251 2.88788 0.29508 2.50964 764 g x - -
+ 1.20891 1.55463 1.68206 1.19000
+ 0.06526 3.12574 3.94910 2.41448 0.09367 1.10396 0.40280
+ 48 2.23841 2.99164 0.25118 2.72900 792 g x - -
+ 1.26330 1.55339 1.52606 1.24355
+ 0.05464 3.34968 4.01313 2.78872 0.06347 1.15133 0.38012
+ 49 2.57533 0.32900 2.64632 2.01501 824 c x - -
+ 1.35118 1.39828 1.40141 1.39516
+ 0.04340 3.79297 3.91506 1.59549 0.22666 1.20075 0.35806
+ 50 0.46433 2.04127 2.23437 2.00605 833 a x - -
+ 1.23062 1.36903 1.62282 1.36182
+ 0.05764 3.31530 3.92762 2.28791 0.10700 1.07910 0.41536
+ 51 0.27513 2.77017 2.28518 2.57549 853 a x - -
+ 1.27958 1.58726 1.46109 1.25394
+ 0.05750 3.30072 3.96214 2.60776 0.07656 1.25708 0.33475
+ 52 0.20149 2.86434 2.84551 2.69770 883 a x - -
+ 1.23645 1.62259 1.71174 1.10368
+ 0.05756 3.26729 4.02702 2.54508 0.08172 1.27391 0.32814
+ 53 0.26982 2.65833 2.50477 2.46835 911 a x - -
+ 1.36005 1.50358 1.48100 1.22550
+ 0.06921 3.37553 3.42118 2.36646 0.09851 1.27560 0.32748
+ 54 0.40022 2.19284 2.22687 2.20396 934 a x - -
+ 1.12070 1.60472 1.53213 1.35895
+ 0.05523 3.36752 3.94966 2.42917 0.09224 0.84774 0.55928
+ 55 2.11356 0.46400 2.46442 1.79955 960 c x - -
+ 1.23932 1.35913 1.50478 1.46331
+ 0.05187 3.47055 3.94022 2.35854 0.09933 1.12102 0.39445
+ 56 1.85868 0.79440 2.22069 1.25971 983 c x - -
+ 1.21951 1.50212 1.51138 1.34185
+ 0.06404 3.29054 3.69705 1.75742 0.18933 1.18410 0.36532
+ 57 1.33272 2.32720 0.71452 1.90215 999 g x - -
+ 1.12229 1.49343 1.56653 1.42255
+ 0.04920 3.46654 4.08749 2.17995 0.11996 1.31769 0.31164
+ 58 2.48337 0.43652 2.46331 1.68683 1017 c x - -
+ 1.34704 1.55461 1.38112 1.28222
+ 0.04823 3.61532 3.90311 2.20911 0.11631 1.00864 0.45368
+ 59 0.41659 2.44509 1.93972 2.20507 1034 a x - -
+ 1.38198 1.38198 1.39194 1.38932
+ 0.03641 3.98130 4.06929 1.35873 0.29704 1.31330 0.31325
+ 60 0.41612 2.39160 1.97116 2.21075 1037 a x - -
+ 1.03649 1.46430 1.57421 1.57557
+ 0.04769 3.52580 4.06641 2.32461 0.10294 0.84329 0.56263
+ 61 2.66264 2.12302 2.82746 0.28581 1056 t x - -
+ 1.36925 1.39635 1.38930 1.39048
+ 0.04097 3.97400 3.84718 1.39433 0.28502 1.12205 0.39395
+ 62 2.26510 2.13196 2.42551 0.37231 1060 t x - -
+ 1.37965 1.39147 1.39147 1.38264
+ 0.04082 3.91610 3.90805 1.24613 0.33914 0.95192 0.48776
+ 63 0.41244 2.25761 2.16787 2.12907 1062 a x - -
+ 1.34515 1.41203 1.41203 1.37753
+ 0.04054 3.77835 4.08203 1.30483 0.31638 1.11819 0.39582
+ 64 2.51464 0.37905 2.62296 1.82008 1068 c x - -
+ 1.39543 1.38753 1.39233 1.37008
+ 0.03854 3.90584 4.03535 1.36573 0.29463 1.13682 0.38689
+ 65 2.16380 2.11332 2.18714 0.42765 1073 t x - -
+ 1.38764 1.38471 1.38519 1.38764
+ 0.03575 4.05376 4.03073 1.40080 0.28289 1.03825 0.43707
+ 66 2.79349 2.39141 2.87271 0.23478 1075 t x - -
+ 1.37227 1.39101 1.39101 1.39101
+ 0.03597 4.01447 4.05827 1.39017 0.28639 1.06429 0.42308
+ 67 2.82488 2.47749 2.93179 0.21887 1078 t x - -
+ 1.38141 1.39112 1.38915 1.38353
+ 0.03661 3.99477 4.04370 1.35958 0.29675 1.13439 0.38804
+ 68 2.77679 2.30433 2.90694 0.24425 1081 t x - -
+ 1.37593 1.38989 1.45520 1.32825
+ 0.04447 3.68736 3.99242 1.76176 0.18843 0.98580 0.46703
+ 69 2.47698 3.17398 0.19595 2.95437 1093 g x - -
+ 1.38264 1.38264 1.39734 1.38264
+ 0.05358 3.96553 3.40487 1.40348 0.28202 1.03112 0.44100
+ 70 2.84327 0.27906 2.97336 2.00890 1097 c x - -
+ 1.38629 1.38629 1.38629 1.38629
+ 0.03412 4.08811 4.08811 1.46634 0.26236 0.69006 0.69625
+ 71 0.21870 2.83638 2.69251 2.65798 1098 a x - -
+ 1.37446 1.37942 1.39640 1.39509
+ 0.03670 3.93983 4.09935 1.41905 0.27700 1.10002 0.40476
+ 72 2.35233 0.46085 2.23804 1.78715 1103 c x - -
+ 1.38536 1.38781 1.38781 1.38421
+ 0.03493 4.03822 4.09272 1.39310 0.28542 1.09638 0.40658
+ 73 2.57111 0.32543 2.74124 1.98892 1105 c x - -
+ 1.38629 1.38629 1.38629 1.38629
+ 0.03381 4.09688 4.09688 1.46634 0.26236 1.09626 0.40664
+ 74 0.27014 2.61416 2.53262 2.47636 1106 a x - -
+ 1.38629 1.38629 1.38629 1.38629
+ 0.03461 4.09267 4.05587 1.46634 0.26236 1.09748 0.40603
+ 75 0.52873 2.16549 1.91736 1.90409 1107 a x - -
+ 1.38629 1.38629 1.38629 1.38629
+ 0.03426 4.08396 4.08396 1.46634 0.26236 1.07423 0.41788
+ 76 2.33134 0.38082 2.65861 1.90055 1108 c x - -
+ 1.38629 1.38629 1.38629 1.38629
+ 0.03466 4.07266 4.07266 1.46634 0.26236 1.09861 0.40547
+ 77 2.20588 0.45134 2.35553 1.84373 1109 c x - -
+ 1.38629 1.38629 1.38629 1.38629
+ 0.03550 4.04912 4.04912 1.46634 0.26236 1.09861 0.40547
+ 78 2.69018 2.22054 2.82311 0.26898 1110 t x - -
+ 1.38629 1.38629 1.38629 1.38629
+ 0.03711 4.00561 4.00561 1.46634 0.26236 1.09861 0.40547
+ 79 0.16248 3.15867 2.86159 2.98963 1111 a x - -
+ 1.38629 1.38629 1.38629 1.38629
+ 0.04048 3.92018 3.92018 1.46634 0.26236 1.09861 0.40547
+ 80 0.17484 3.04770 2.86638 2.88183 1112 a x - -
+ 1.38629 1.38629 1.38629 1.38629
+ 0.02045 3.90014 * 1.46634 0.26236 0.00000 *
+//
--- /dev/null
+HMMER3/e [3.0 | March 2010]
+NAME Pkinase
+ACC PF00069.17
+DESC Protein kinase domain
+LENG 260
+ALPH amino
+RF no
+CONS yes
+CS yes
+MAP yes
+DATE Thu Jun 16 11:44:06 2011
+NSEQ 54
+EFFN 3.358521
+CKSUM 3106786190
+GA 70.30 70.30
+TC 70.30 70.30
+NC 70.20 70.20
+STATS LOCAL MSV -10.7215 0.70254
+STATS LOCAL VITERBI -11.6541 0.70254
+STATS LOCAL FORWARD -5.2305 0.70254
+HMM A C D E F G H I K L M N P Q R S T V W Y
+ m->m m->i m->d i->m i->i d->m d->d
+ COMPO 2.60017 4.19886 2.94089 2.63789 3.35087 2.89119 3.48337 2.79435 2.60265 2.43454 3.62613 3.06133 3.41286 3.09693 2.94507 2.65650 2.87761 2.67871 4.54052 3.43274
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.00000 *
+ 1 2.91704 4.31028 4.76351 3.63148 2.10912 3.47710 4.39734 2.27639 3.96619 1.99282 3.42844 4.19567 4.43771 4.11903 3.67403 3.22736 3.14918 2.35905 3.32515 1.82622 1 y - - E
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 2 2.77204 4.20708 3.06476 1.97968 4.66603 3.66509 3.19858 3.37903 2.25347 3.34018 4.38833 2.97180 4.05804 2.36838 2.43173 2.67542 2.50268 2.83403 5.78758 4.38976 2 e - - E
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 3 2.90076 4.04294 3.31590 2.80413 3.08157 3.87481 4.12616 2.18958 2.49735 1.97194 3.73714 3.32717 3.98753 3.23115 3.12315 2.99137 2.62008 2.29426 5.21478 3.75979 3 l - - E
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 4 2.89383 4.85429 3.10311 2.63174 3.71383 2.56808 3.47232 2.82076 2.61844 1.98342 3.72320 3.05498 4.17347 3.05527 3.32194 2.85608 2.93671 2.18878 5.40057 3.87183 4 l - - E
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 5 2.68261 5.39185 2.80437 1.87471 4.73638 2.79887 3.69591 4.22191 2.19487 3.69685 4.08896 3.12413 3.70490 2.48424 2.08916 2.53260 3.02309 3.43812 5.82480 4.41426 5 e - - E
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 6 2.77253 4.06085 3.07881 2.53373 4.10647 3.71564 3.68370 2.64290 2.00036 2.72968 4.17370 3.24239 3.08607 2.77632 2.72820 2.69921 2.54335 2.71931 5.60386 4.26496 6 k - - E
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 7 3.42930 4.74416 5.34765 4.76823 3.71832 4.71430 5.09461 1.33015 3.54417 1.12594 3.33523 4.84641 5.00427 4.73010 4.64986 4.05097 3.66327 1.83083 5.51142 4.37013 7 l - - E
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 8 2.57460 4.94286 4.00732 3.93216 5.40516 0.41612 5.15134 4.86315 4.18766 4.52736 5.33508 4.05990 4.45245 3.74651 4.46171 3.15888 3.14590 4.15180 6.71159 5.52767 8 G - - E
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 9 2.30218 5.38172 3.03799 2.02026 4.18991 3.65799 3.84554 3.67215 2.28945 3.68495 4.42365 2.84227 3.73039 2.44555 2.39428 2.00278 2.95859 3.63127 5.81726 4.40923 9 s - - E
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 10 4.54226 6.07621 5.39207 5.44513 6.34643 0.07137 6.34600 6.33790 5.73770 5.76452 6.83374 5.56171 5.46536 5.98137 5.73783 4.76037 5.08470 5.67502 7.03864 6.52156 10 G - - E
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 11 2.06444 5.37337 2.91595 2.40063 4.70969 2.61181 3.84889 4.18948 2.46835 3.67503 4.41668 2.62917 4.05392 2.88235 2.66711 2.00495 2.47288 3.39649 5.81159 4.40596 11 s - - T
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 12 2.90920 4.46494 4.12493 3.14570 1.52027 3.22992 4.24969 2.92840 3.46467 2.66529 3.12827 3.55640 4.33979 3.72214 3.72236 2.53517 2.98442 2.55125 5.06498 2.30159 12 f - - T
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 13 2.21104 4.80722 4.64199 4.55509 5.54982 0.52550 5.49025 5.04875 4.70671 4.72740 5.47955 4.30215 4.43233 4.84666 4.86038 1.95116 3.45005 4.17507 6.87595 5.79039 13 G - - E
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 14 2.71551 3.46186 3.01248 2.27453 4.55840 3.55853 3.50842 3.55064 2.03335 3.34882 4.31847 3.17065 4.07218 2.83960 2.83653 2.25762 2.26864 2.61469 5.72841 4.35037 14 k - - E
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 15 3.17885 3.97005 5.63014 5.16553 4.35293 4.89782 5.77682 2.09398 5.06494 2.94083 4.14496 5.20428 5.30924 5.30763 5.20260 4.32158 3.61414 0.44769 6.26043 5.04118 15 V - - E
+ 2.68625 4.42232 2.77526 2.73102 3.46361 2.40519 3.72501 3.29361 2.67747 2.69306 4.24696 2.90353 2.73746 3.18153 2.89807 2.37893 2.77526 2.98499 4.58484 3.61510
+ 0.09563 2.43065 5.73865 0.67073 0.71608 0.48576 0.95510
+ 16 2.91101 3.31342 4.36759 3.41772 2.45121 4.01227 4.31421 2.75922 2.81772 2.31733 3.50420 3.69862 4.38187 3.88257 3.14725 3.02772 3.14303 2.46483 3.37889 1.69905 18 y - - E
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 17 2.88484 5.28431 3.03179 2.31849 4.58595 3.47769 3.54625 2.98124 1.69233 2.43413 4.04064 3.16353 4.06907 2.72555 2.58277 2.55274 3.04512 3.20501 5.74377 4.36100 19 k - - E
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 18 1.57125 2.56460 3.38436 3.39201 3.66458 2.34190 4.20526 2.93932 3.32823 2.44127 3.26099 3.74334 4.30466 3.60817 3.63469 3.01628 2.92537 2.55308 5.13581 3.91882 20 a - - E
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 19 2.89298 4.40558 3.44708 2.63051 3.77015 3.77747 2.87940 2.57515 2.33949 2.85128 3.20054 3.37379 4.16367 2.65910 2.52913 2.67954 2.59930 2.46709 5.42679 3.74337 21 k - - E
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 20 2.88350 5.37811 2.42858 2.28192 4.71668 3.65945 2.35349 4.19788 2.20596 2.91798 4.42054 2.38258 4.05280 2.81490 2.60119 2.77457 3.11461 3.76528 3.43428 3.80493 22 k - - E
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 21 2.59359 5.30144 3.00667 2.46268 4.60954 3.67285 3.22394 2.91749 2.13087 2.60378 4.35201 3.05590 3.51881 2.48537 2.35096 2.62551 3.00998 2.84793 5.75687 4.36947 23 k - - T
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 22 2.64500 5.38003 2.46961 2.36386 4.71962 2.36153 3.71093 3.77963 2.19342 3.27291 4.42213 2.49968 3.44456 2.94396 2.94770 2.23767 2.90215 3.58800 5.81601 3.79868 24 k - - T
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 23 2.71410 5.35453 2.26257 2.17828 4.68327 3.06138 3.85215 3.65600 2.51871 3.65284 4.39957 2.64619 4.05631 2.95399 2.98284 2.41102 1.94961 3.19379 5.79713 3.78693 25 t - - T
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.03260 5.01631 3.67114 0.61958 0.77255 0.48576 0.95510
+ 24 2.77509 4.50579 3.06414 2.40741 4.68877 2.10468 3.84020 4.16638 2.52713 3.65577 4.39945 2.31826 2.82304 2.55347 2.45557 2.51717 3.10489 3.55245 5.79545 3.68618 26 g - - T
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.13496 4.99383 2.12471 0.61958 0.77255 0.54753 0.86365
+ 25 2.82390 4.23357 2.59579 2.09029 4.65095 3.47120 3.53571 3.50264 1.93281 3.24335 4.10745 2.98984 3.99409 2.41262 2.43858 2.60001 2.84781 3.57090 5.75206 3.98239 27 k - - E
+ 2.68634 4.42166 2.77510 2.73101 3.46370 2.40521 3.72473 3.29370 2.67713 2.69347 4.24706 2.90350 2.73742 3.18145 2.89817 2.37895 2.77536 2.98516 4.58493 3.61485
+ 0.21086 2.33296 2.37401 1.37928 0.29003 0.81455 0.58490
+ 26 2.79249 4.86773 3.27912 2.48247 3.81836 3.65430 3.86742 2.36980 2.31612 2.40000 3.66176 2.98804 3.52938 2.45192 2.80383 2.80149 2.71760 2.93241 5.39419 3.83742 36 k - - E
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01259 4.77670 5.49905 0.61958 0.77255 0.27298 1.43175
+ 27 2.94684 4.40681 4.93000 4.33270 2.14562 4.19543 4.43742 2.60780 4.12995 2.51432 3.32273 4.32339 4.55150 4.25562 4.15094 3.50804 3.26683 1.12964 4.39266 2.23526 37 v - - E
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 28 0.67405 4.13502 4.78133 4.26234 4.00859 4.13420 4.88775 2.58668 4.14876 2.87877 3.59530 4.37511 4.66004 4.38446 4.34251 3.50924 3.44597 2.20111 5.62436 4.43519 38 A - - E
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 29 2.77559 4.05359 4.82280 4.21814 3.45081 3.88127 4.46447 1.69887 3.29990 2.06046 2.92956 4.25618 4.49083 4.18293 4.07725 3.28739 3.19210 1.31639 4.98894 3.80930 39 v - - E
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 30 4.13385 6.06880 4.58555 3.84767 5.73274 4.53840 4.41573 5.06650 0.32256 4.37802 5.30885 4.14872 4.92009 3.55775 2.54913 4.11741 4.25754 4.75872 6.25921 5.22828 40 K - - E
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 31 2.53136 3.93442 3.55191 2.54113 3.59001 3.81267 3.67691 2.09853 2.22431 2.85063 3.63116 3.45300 4.19661 2.87681 2.71089 2.96116 2.67441 2.46338 5.34241 3.76111 41 i - - E
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 32 2.80227 4.30542 4.81704 3.71619 2.31247 3.45194 4.41496 1.85614 4.00698 1.68898 3.06826 4.22398 4.44809 4.15126 4.03957 3.11345 3.01936 1.82478 4.92889 3.75130 42 l - - E
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 33 2.72320 4.19698 2.89173 2.30854 4.21536 3.66470 3.63903 3.54937 1.81020 3.33297 4.38970 2.50126 3.12497 2.85129 2.61476 2.47307 2.93549 3.43057 4.63863 3.86554 43 k - - E
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 34 2.73748 5.16363 3.24304 2.62749 4.42406 3.39882 3.64889 3.08793 1.75481 2.64054 4.22767 2.81684 3.49630 2.92572 2.69253 2.71691 2.78362 2.91622 5.65055 3.09244 44 k - - H
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 35 2.82342 4.21564 2.57688 2.18304 4.09635 3.66104 3.29269 4.17416 2.24176 3.24419 4.40775 3.13331 3.02670 2.66210 2.30119 2.38622 2.91913 2.84969 5.80393 4.13733 45 e - - H
+ 2.68618 4.42225 2.77520 2.73124 3.46354 2.40513 3.72495 3.29354 2.67741 2.69355 4.24690 2.90347 2.73731 3.18147 2.89801 2.37887 2.77520 2.98519 4.58477 3.61503
+ 0.02362 3.90596 5.73865 0.48782 0.95182 0.48576 0.95510
+ 36 2.81479 5.38805 2.34307 2.08229 3.84722 3.00939 3.24618 4.21561 2.24819 3.24444 4.42924 2.80965 3.63231 2.74299 2.65208 2.41080 2.72103 3.26063 5.82196 4.16400 47 e - - H
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 37 2.42659 5.32934 2.94543 1.98753 4.27035 3.66735 3.85733 2.97282 2.27697 3.20526 3.75542 2.69174 3.50027 2.79550 2.45131 2.66535 2.70832 3.28701 5.77800 4.07668 48 e - - C
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 38 2.82479 5.36482 2.46403 2.36491 4.23121 3.19666 3.53460 3.47934 2.01766 2.87145 4.06028 2.53791 3.88358 2.73438 2.79605 2.39315 2.94316 3.30320 5.80464 3.67777 49 k - - C
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 39 2.81259 3.82036 2.58997 2.16257 3.93187 3.50795 3.44913 3.32347 2.23760 3.42042 3.43188 3.03914 3.18139 2.98833 2.90722 1.97318 3.04237 3.44327 4.85883 4.01646 50 s - - C
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.04017 5.01631 3.41907 0.61958 0.77255 0.48576 0.95510
+ 40 2.75150 4.68420 2.78864 2.20581 3.96394 3.14028 3.85474 3.62649 2.17804 2.84544 3.93254 2.66146 3.79370 2.72658 2.87564 2.43841 2.71937 3.23202 3.36778 4.34996 51 k - - C
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01020 4.98634 5.70869 0.61958 0.77255 0.56699 0.83755
+ 41 2.52028 4.29421 2.93844 2.26593 3.28616 3.42961 3.89113 3.40312 1.92589 2.89626 3.59280 3.04537 4.08209 2.42956 3.02333 2.89065 2.87512 2.78376 5.62895 3.97726 52 k - - C
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.06456 4.98634 2.88790 0.61958 0.77255 0.56699 0.83755
+ 42 2.52102 4.66200 2.60886 2.12080 3.90563 3.43164 3.41299 3.76759 2.19798 2.95231 4.37667 2.71584 3.31098 2.66775 2.46389 2.65499 2.89357 3.57073 4.74853 4.36793 53 e - - C
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.06881 4.93254 2.82535 0.61958 0.77255 0.69302 0.69327
+ 43 2.65676 5.27743 2.81592 2.16715 4.59834 3.44096 3.79920 2.82354 2.10889 3.57233 3.78816 2.93522 4.00237 2.20078 2.58862 2.72374 2.99283 3.18643 5.72482 3.30249 54 k - - H
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.04191 4.87514 3.39892 0.61958 0.77255 0.80592 0.59181
+ 44 2.46416 5.14935 3.14274 2.35064 4.42785 3.46788 3.62138 3.06885 2.39724 2.90472 4.00413 2.77252 4.01153 2.56699 2.69346 2.37713 2.33258 3.34725 5.62407 3.30627 55 t - - H
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.15381 4.84499 2.00472 0.61958 0.77255 0.85820 0.55151
+ 45 2.15178 5.11690 2.80767 2.47016 4.06926 3.56450 3.25874 3.42510 2.38373 2.72748 4.17388 2.58132 3.95629 2.68997 2.59104 2.52019 2.89357 3.10461 5.58730 3.84420 56 a - - H
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.06869 4.70471 2.85898 0.61958 0.77255 1.05523 0.42788
+ 46 2.33893 4.38200 3.78128 3.08857 2.87706 3.76539 4.03303 2.50172 2.82237 2.26545 3.48958 3.56901 4.14175 3.13269 2.43377 3.02211 2.55318 2.18677 4.40164 3.75633 57 v - - H
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.07407 4.65033 2.78326 0.61958 0.77255 1.03937 0.43646
+ 47 2.66580 4.77769 3.25859 2.69691 3.69577 3.61140 3.56963 3.36841 2.45062 2.28390 3.86113 2.83101 3.99793 3.01640 2.00932 2.40384 2.97180 2.98514 3.81809 4.01106 58 r - - H
+ 2.68588 4.42292 2.77574 2.73101 3.46421 2.40561 3.72562 3.29362 2.67747 2.69305 4.24679 2.90348 2.73776 3.18179 2.89693 2.37874 2.77432 2.98554 4.58544 3.61510
+ 0.56084 0.85690 5.33966 1.67148 0.20822 0.22069 1.61932
+ 48 3.87852 6.35819 2.88185 0.33512 5.75300 3.98086 4.66680 5.41085 3.73193 4.87592 5.81368 3.19190 4.67406 3.86930 4.28895 3.74624 4.21685 4.94226 6.88673 5.40485 78 E - - H
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 49 2.34469 4.06185 4.67394 3.74635 3.19070 3.72385 4.38165 1.69529 3.89930 1.68521 3.30505 3.88179 4.42519 3.50953 3.71087 3.12279 3.14596 1.99339 4.94125 3.41486 79 l - - H
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 50 2.41611 3.92039 3.06862 2.24055 4.69692 3.38839 3.50460 4.17440 2.17094 3.43336 4.01855 2.84870 4.05421 2.22409 2.42800 2.49697 2.93959 3.48161 5.80403 3.10747 80 k - - H
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 51 2.65097 4.31309 4.79937 4.19096 3.25102 4.08746 4.41763 1.57396 3.99634 1.77576 3.18772 3.58572 4.45127 4.14513 4.03729 2.91921 3.15786 1.73265 4.93848 3.33785 81 i - - H
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 52 2.71474 4.35776 4.49839 3.90546 3.26558 3.60358 3.11363 2.58541 3.76519 1.24138 2.56017 3.78382 4.40165 3.77674 3.90460 2.91080 2.88501 2.43218 4.97232 3.44306 82 l - - H
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 53 2.21717 5.37509 3.13954 2.36108 4.71254 3.44569 3.50643 4.19289 1.90576 2.89362 4.41783 2.84264 3.50886 2.51670 2.27883 2.73413 2.79427 3.37900 5.81221 4.40629 83 k - - H
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 54 2.88332 4.76187 3.15794 2.34306 4.64959 3.18467 2.98724 4.11774 2.20976 2.84622 3.53657 2.69640 4.06011 2.81953 2.22587 2.26090 2.67755 3.39248 5.77872 3.89328 84 k - - H
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 55 2.92075 3.71086 4.82119 4.21031 2.91851 4.08375 4.41406 2.48059 4.00923 1.14255 2.77088 4.22517 4.44739 4.15194 3.51737 2.79440 3.04088 2.14784 4.92583 3.58797 85 l - - H
+ 2.68619 4.42231 2.77526 2.73130 3.46360 2.40505 3.72501 3.29360 2.67737 2.69361 4.24696 2.90322 2.73746 3.18153 2.89797 2.37878 2.77526 2.98514 4.58483 3.61509
+ 0.21093 1.81438 3.60337 0.15203 1.95873 0.48576 0.95510
+ 56 2.87228 4.32697 2.43695 2.52023 4.72535 3.09966 3.42727 4.21076 2.24746 3.68599 4.14994 2.21640 3.70120 2.45856 2.42604 2.20075 2.84715 3.77128 5.81417 4.40372 87 s - - S
+ 2.68626 4.42233 2.77498 2.73131 3.46362 2.40515 3.72479 3.29362 2.67733 2.69363 4.24698 2.90355 2.73719 3.18141 2.89809 2.37895 2.77498 2.98527 4.58485 3.61511
+ 0.08622 2.53438 5.71435 0.90816 0.51628 0.44628 1.02166
+ 57 2.95437 4.05540 4.02453 3.66262 4.73022 3.00582 0.63840 4.27369 3.61156 3.92435 4.76053 3.90244 4.38221 3.97389 3.93213 2.36608 3.39859 3.79517 6.08861 4.80370 91 H - - S
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 58 2.74925 4.59154 2.64384 2.02057 4.69046 3.19970 3.85151 4.16644 2.39568 3.65893 3.99620 3.06676 1.73396 2.95270 2.98758 2.52836 2.96698 3.57815 5.80119 4.39902 92 p - - S
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 59 2.77600 3.63123 3.60742 3.04389 2.88763 3.83093 3.22852 3.27052 2.82124 2.96220 3.83761 1.44485 4.21384 3.33393 3.26463 3.06163 2.84916 2.86372 5.30436 2.85576 93 n - - S
+ 2.68619 4.42226 2.77521 2.73125 3.46355 2.40506 3.72496 3.29355 2.67742 2.69356 4.24691 2.90348 2.73741 3.18148 2.89802 2.37880 2.77521 2.98520 4.58478 3.61504
+ 0.02736 3.73933 5.73865 0.64347 0.74542 0.48576 0.95510
+ 60 3.43736 4.73250 5.40681 4.85032 3.21534 3.89737 5.21348 0.72821 4.70181 2.29095 3.77438 4.92025 5.08011 4.86610 4.77171 4.12622 3.68020 1.72131 5.65218 4.46593 96 i - - B
+ 2.68620 4.42119 2.77522 2.73126 3.46356 2.40515 3.72497 3.29356 2.67743 2.69357 4.24692 2.90349 2.73742 3.18149 2.89780 2.37889 2.77522 2.98521 4.58479 3.61505
+ 0.04171 3.27988 5.73865 0.65380 0.73410 0.48576 0.95510
+ 61 3.22247 3.52386 5.20134 4.62057 3.74032 4.49428 4.89197 1.38422 4.44333 2.03444 3.40884 4.64781 4.83078 4.60265 4.48778 3.55308 3.01459 1.16992 5.37248 4.18666 99 v - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 62 2.72238 4.59459 3.13585 2.30027 4.72566 3.17722 3.67251 4.20868 2.00822 3.53187 4.42604 2.97500 3.44674 2.41134 2.06447 2.53711 2.32763 3.77297 5.81907 4.41084 100 k - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 63 2.75790 4.02501 4.89076 4.27684 2.25991 4.10991 4.44304 2.31340 4.06541 1.38378 2.56521 4.26823 4.47075 4.19670 4.07763 3.42134 2.72551 2.21249 4.93572 3.01728 101 l - - E
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 64 2.79378 4.36122 4.48297 3.70404 2.84684 4.03133 3.55103 1.94759 2.82835 1.82248 3.32801 4.05424 4.39941 3.70850 3.13439 3.15759 3.14407 2.41334 4.25902 2.30786 102 l - - E
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 65 2.47264 4.33075 2.07830 2.03157 4.71750 2.27093 3.18950 4.19892 2.58523 3.68152 4.42156 3.04070 4.05295 2.84140 2.67254 2.59104 3.11515 3.76615 5.81569 3.60292 103 e - - E
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 66 2.10377 4.03530 4.82986 4.21790 2.76136 4.07923 4.41023 2.08081 4.01359 2.30827 2.78821 4.22543 4.44340 4.15406 4.03913 2.38166 2.60707 1.97272 3.19782 3.33258 104 v - - E
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 67 2.82605 3.67894 3.38070 3.01266 1.82001 3.97118 3.82789 2.76491 3.48734 2.34143 3.24926 3.10725 3.78017 3.42990 3.73647 2.98277 3.13977 2.32864 3.87637 2.72935 105 f - - E
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.04987 5.01631 3.16967 0.61958 0.77255 0.48576 0.95510
+ 68 2.55964 4.21441 3.10666 1.94329 4.49707 3.21758 3.46239 3.37098 2.39709 3.00488 3.51821 3.06808 4.06187 2.54621 2.66989 2.75991 2.68522 3.13970 5.68635 3.14043 106 e - - E
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.02094 4.97674 4.28127 0.61958 0.77255 0.42506 1.06054
+ 69 2.80310 5.38415 2.22807 2.18295 4.72718 3.65266 3.36574 4.21171 2.46641 3.56699 4.42536 2.57848 3.46451 2.86899 2.36310 2.58224 2.17995 3.52075 5.81804 3.65548 107 t - - E
+ 2.68640 4.42162 2.77535 2.73147 3.46354 2.40551 3.72458 3.29233 2.67716 2.69348 4.24762 2.90375 2.73699 3.18187 2.89837 2.37858 2.77480 2.98522 4.58549 3.61548
+ 0.36809 1.18844 5.72853 1.68950 0.20409 0.46837 0.98355
+ 70 2.88244 5.39287 2.47300 2.29715 3.79460 2.82884 3.28660 4.22374 2.09832 3.69810 4.43357 2.45444 3.07035 2.85151 2.47539 2.34133 3.01376 3.78345 5.82560 4.10620 126 k - - T
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 71 2.57798 5.39101 2.06614 2.42374 4.73510 2.82383 3.84381 4.22040 2.28304 3.69587 4.43195 2.62257 3.38372 2.71683 2.73886 2.29050 2.66881 3.34289 5.82427 4.18691 127 d - - T
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 72 2.58231 5.35788 2.77781 2.22432 4.08337 3.66211 2.49021 4.16401 2.37240 3.16748 4.40241 2.52484 4.05523 2.76334 2.63486 2.49164 2.89823 3.30761 4.95167 3.05734 128 e - - E
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 73 2.78575 3.74303 4.78141 4.17260 2.95491 4.07322 4.40160 1.89067 3.97854 1.60353 2.95383 3.71592 3.11906 4.12798 3.50390 3.07790 2.85145 2.24111 4.92509 2.91282 129 l - - E
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 74 2.58399 2.76389 4.59675 3.99881 3.19843 4.04871 3.62339 2.65148 3.84111 2.12752 3.45456 3.62454 3.46238 4.02369 3.94739 2.79096 3.14543 2.42948 3.13888 1.74690 130 y - - E
+ 2.68624 4.42096 2.77500 2.73129 3.46360 2.40508 3.72501 3.29360 2.67747 2.69353 4.24696 2.90343 2.73746 3.18153 2.89807 2.37893 2.77510 2.98525 4.58483 3.61509
+ 0.10354 2.49668 4.13492 0.66960 0.71726 0.48576 0.95510
+ 75 3.07392 4.44555 4.97084 3.81418 2.87255 4.25097 4.57886 1.74564 4.16653 1.31678 2.12605 4.39109 4.59167 3.71495 4.19337 3.56380 3.30386 2.29390 5.05348 3.89648 133 l - - E
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01003 5.00344 5.72579 0.61958 0.77255 0.52175 0.90012
+ 76 2.86449 3.41378 5.01300 4.41506 3.07458 4.28568 4.64425 1.49634 4.22335 2.27773 3.54368 4.43380 4.63588 3.70581 4.25773 3.60458 3.30826 1.19505 5.13861 3.95920 134 v - - E
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01003 5.00344 5.72579 0.61958 0.77255 0.46390 0.99109
+ 77 2.91733 4.35063 4.55668 3.96112 2.40516 4.04680 4.36140 2.56068 3.81048 1.70108 1.79340 3.59899 4.41359 3.09405 3.93172 3.15547 2.48177 2.59902 4.96582 3.78095 135 l - - E
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 78 2.76564 5.57030 2.50020 1.03018 4.90220 3.70297 3.44513 4.39514 2.75995 3.87044 4.62325 3.16505 3.19754 2.75935 3.27129 2.65802 3.28146 3.95557 6.00401 4.57374 136 e - - E
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 79 2.81579 3.90369 4.68991 4.08721 2.27644 4.06399 3.63829 2.69790 3.58050 1.84024 3.31248 4.16081 4.42953 4.07816 3.60709 3.36667 3.01039 2.57256 4.40465 1.54393 137 y - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 80 2.45920 2.17262 4.69646 4.09287 3.22405 3.32199 3.21264 2.59887 3.91610 2.06244 2.25581 4.16309 3.61702 4.08102 3.98811 3.14866 3.14614 2.03766 4.93767 3.46778 138 v - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.04171 5.01631 3.37486 0.61958 0.77255 0.48576 0.95510
+ 81 2.70314 5.37371 2.37994 1.91497 4.71601 2.93053 3.83161 4.20005 2.46492 3.55263 3.57885 2.58870 2.59223 2.74552 2.71928 2.69862 3.03649 3.29150 5.80804 4.39872 139 e - - T
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01022 4.98481 5.70716 0.61958 0.77255 0.57090 0.83245
+ 82 2.41993 3.72287 3.12898 2.52046 4.44831 1.89639 3.49536 3.62837 2.38762 3.31281 3.53904 2.44913 3.42379 3.00780 3.12891 2.87912 2.75467 3.52812 5.65946 3.81984 140 g - - S
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.10979 4.98481 2.33166 0.61958 0.77255 0.57090 0.83245
+ 83 2.77350 5.21303 2.43943 2.62703 4.54309 1.39496 3.89257 3.99092 2.60267 3.54085 4.32260 3.04209 4.06226 3.01831 3.03242 2.64588 2.77651 3.04353 5.73236 4.35922 141 g - - -
+ 2.68631 4.42210 2.77537 2.73126 3.46359 2.40522 3.72475 3.29338 2.67758 2.69250 4.24657 2.90377 2.73770 3.18148 2.89796 2.37902 2.77541 2.98478 4.58507 3.61496
+ 0.21230 1.67338 5.60865 1.39945 0.28334 0.33567 1.25476
+ 84 2.88583 5.39491 1.79381 2.06461 4.73890 3.24821 3.51210 4.22442 2.47141 3.51906 4.43601 2.95989 3.57031 2.79057 2.82788 2.02605 2.91163 3.62254 5.82805 4.41723 147 d - - B
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 85 2.90986 4.42406 3.70533 3.66371 3.02577 3.99009 3.90749 2.78363 3.56278 1.02082 3.24022 3.34355 4.36146 3.52102 3.78389 3.13807 2.95820 2.60948 5.03043 3.48016 148 l - - H
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 86 2.57337 4.10245 3.03950 2.95233 2.09915 3.53742 3.15959 3.37138 2.66519 2.44003 3.54971 3.10382 3.71714 3.06888 3.13958 2.44794 3.05039 3.11306 4.61969 3.07664 149 f - - H
+ 2.68621 4.42228 2.77522 2.73126 3.46357 2.40516 3.72497 3.29357 2.67744 2.69358 4.24693 2.90350 2.73735 3.18149 2.89804 2.37890 2.77502 2.98521 4.58480 3.61458
+ 0.24291 3.02648 1.78874 0.58545 0.81386 0.48576 0.95510
+ 87 2.29362 5.30873 1.92419 2.32474 4.26868 3.43187 3.46788 4.12970 2.37357 3.61146 4.35100 2.92576 3.98105 2.69850 2.60197 2.47206 2.54407 3.69618 5.74493 3.96335 152 d - - H
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01185 4.83724 5.55959 0.61958 0.77255 0.87096 0.54223
+ 88 2.24696 4.24235 4.56569 3.96478 2.41045 3.97137 3.29432 2.27668 3.43922 2.04964 3.19406 4.05576 4.33743 3.97000 3.38896 3.27217 3.06100 2.23241 4.18296 2.20711 153 l - - H
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01185 4.83724 5.55959 0.61958 0.77255 0.87096 0.54223
+ 89 3.80243 5.01974 5.81731 5.27268 3.70245 5.26548 5.70409 1.30084 5.15744 0.98923 3.04180 5.42350 5.39649 5.16571 5.17462 4.65797 4.03105 1.75151 5.84473 4.80632 154 l - - H
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01185 4.83724 5.55959 0.61958 0.77255 0.62617 0.76494
+ 90 2.48275 5.13868 3.18520 2.44727 3.97540 3.65122 3.65677 3.36126 2.16734 3.30486 3.19390 3.06911 4.04233 2.41632 2.75033 2.25069 2.41675 3.09873 5.62108 3.69504 155 k - - H
+ 2.68595 4.42186 2.77509 2.73103 3.46377 2.40517 3.72421 3.29387 2.67761 2.69368 4.24695 2.90368 2.73754 3.18175 2.89730 2.37895 2.77536 2.98514 4.58473 3.61505
+ 0.63487 1.25520 1.68753 1.39580 0.28453 0.74756 0.64154
+ 91 2.43987 5.24839 2.75312 2.20207 4.11839 3.54175 3.72993 4.06095 2.07671 3.34429 3.98666 2.75679 3.72576 2.60349 2.28520 2.46158 2.79062 3.43756 5.68761 3.81452 172 k - - H
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01352 4.70589 5.42824 0.61958 0.77255 0.34096 1.24163
+ 92 2.56414 5.37054 2.84426 2.11401 4.71382 2.70860 2.88683 4.19851 2.19051 3.14492 4.41168 2.55924 4.03189 2.79129 2.63798 2.35762 3.09530 3.76022 5.80426 3.44686 173 e - - H
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01035 4.97167 5.69402 0.61958 0.77255 0.60365 0.79145
+ 93 2.86527 4.78061 2.95620 2.59670 4.27271 1.99448 3.84571 3.48713 2.08881 3.39073 4.33266 2.46895 3.64059 2.84730 2.63768 2.84659 2.50396 3.24160 5.73764 4.35043 174 g - - H
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01035 4.97167 5.69402 0.61958 0.77255 0.46145 0.99524
+ 94 2.57883 3.45102 3.31966 2.70191 4.02973 3.16828 3.76144 3.12068 2.26544 3.06289 4.10647 2.81108 2.70638 2.99156 2.57108 2.49596 2.68439 2.78596 4.48656 4.03099 175 k - - S
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01001 5.00539 5.72774 0.61958 0.77255 0.51640 0.90799
+ 95 3.00846 4.37852 4.95050 4.33851 2.03946 4.18408 4.51243 2.07907 4.13124 1.32746 2.71567 3.86888 4.53472 4.25457 4.14405 3.49709 3.23945 2.15194 4.98866 3.35208 176 l - - T
+ 2.68632 4.42239 2.77534 2.73137 3.46298 2.40515 3.72509 3.29351 2.67755 2.69332 4.24641 2.90361 2.73734 3.18136 2.89815 2.37881 2.77519 2.98532 4.58491 3.61446
+ 0.13280 2.11108 5.72774 1.00017 0.45858 0.46707 0.98573
+ 96 2.55096 5.39506 2.51329 2.14467 4.73966 3.20813 3.84532 4.22553 2.37049 3.70015 4.43599 2.79265 3.16832 2.74582 2.82569 1.88822 2.42672 3.78548 5.82793 4.41687 180 s - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 97 2.55253 5.00371 2.91674 1.56530 3.77486 3.74196 3.71669 3.18678 2.77868 2.90828 3.00031 3.29724 3.28640 3.12328 3.07027 2.76413 2.89289 3.32236 3.74938 3.48354 181 e - - H
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 98 2.59075 4.32000 2.44335 2.15201 3.95693 3.12347 3.34011 3.83572 2.30797 3.16698 3.93315 2.75363 3.60071 2.81660 2.61665 2.70578 2.85000 3.34465 3.67935 4.00275 182 e - - H
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 99 2.65092 5.35978 2.44414 1.82235 4.69093 3.44711 3.03513 3.63938 2.46445 2.69072 4.40412 3.13476 3.87902 2.43027 2.99516 2.67955 2.75495 3.20344 5.80088 4.03299 183 e - - H
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 100 1.86496 3.02665 4.71869 4.11439 3.41506 3.78632 4.39467 1.72869 3.93413 2.03606 3.25110 4.17623 4.43415 4.09606 3.42450 3.02051 2.94480 2.04904 4.94015 3.76003 184 i - - H
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 101 2.66380 3.60669 3.09016 2.70629 3.97052 3.12773 3.91117 3.25572 1.80561 2.74214 4.19581 3.23071 4.10037 2.51557 2.19861 2.73033 3.11863 2.97558 5.62300 4.27841 185 k - - H
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 102 2.65525 3.61780 2.73206 2.59880 2.91626 3.69337 3.17740 3.91061 2.06495 2.87551 3.62080 2.65252 4.08468 3.01717 2.55140 2.50072 2.84956 3.37543 5.67937 3.86408 186 k - - H
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 103 2.78549 3.75825 4.89230 4.27707 2.37628 4.09576 4.42870 1.58181 4.06146 2.16353 2.83229 4.25917 4.45832 4.19107 4.06819 3.40747 3.15724 2.08428 3.94244 2.32199 187 i - - H
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 104 1.91854 4.04767 4.83572 4.22341 2.21465 3.82491 4.41156 2.18264 4.01792 2.17430 2.43077 4.22827 4.44431 4.15736 4.04152 2.82624 2.88622 2.07903 4.25105 3.74133 188 a - - H
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 105 2.59846 4.94560 3.39451 2.56515 3.67443 3.44440 3.79808 3.54150 2.22767 2.11264 4.02778 3.19297 4.14629 3.16161 2.51054 2.63727 2.68778 3.11215 4.13689 2.62651 189 l - - H
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 106 2.71202 4.65478 2.93025 2.07602 4.70407 3.24619 3.70431 4.18261 2.58938 3.67040 4.10390 3.00747 4.05496 1.41184 3.00214 2.55548 2.74962 3.75459 5.80879 4.40428 190 q - - H
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 107 3.40758 4.70636 5.39472 4.82751 3.82844 4.73217 5.15283 1.33187 4.66862 1.85779 2.55181 4.88258 5.03394 4.81634 4.72035 4.07618 2.46891 1.37416 5.58393 4.41648 191 i - - H
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 108 2.29107 3.23763 4.81578 4.20571 3.00975 3.26830 4.41487 2.37700 4.00619 1.39060 3.28560 4.22330 4.44775 4.15070 4.03923 2.94875 3.15303 1.86969 4.92930 3.75166 192 l - - H
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 109 2.62933 4.07203 2.95927 2.08969 4.71415 3.53463 3.84677 3.97436 2.17805 2.82549 4.41873 2.79932 4.05232 2.53645 2.16719 2.25459 2.86145 3.76301 5.81311 4.40656 193 e - - H
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 110 1.17650 4.82606 4.24050 3.83461 4.98724 1.08848 4.85992 4.42183 3.81285 4.07900 4.88120 3.97861 4.34888 4.10941 3.49121 2.50205 3.18154 3.58125 6.30917 5.10145 194 g - - H
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 111 3.90271 5.14012 5.90469 5.33230 3.41122 5.28833 5.65529 2.02087 5.19062 0.88043 2.65524 5.45552 5.42442 5.15469 5.16815 4.66249 4.12260 1.40813 5.79888 4.77647 195 l - - H
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 112 2.18892 5.38966 2.64044 1.97751 4.73333 3.65659 3.60437 3.92129 2.10090 3.35469 4.43069 2.33847 4.05005 2.60616 2.77179 2.58383 3.11351 3.51057 5.82316 3.92131 196 e - - H
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 113 2.81051 5.07767 4.77644 4.29954 2.03535 4.57845 2.23184 3.59557 4.18346 3.18325 4.21755 4.37554 4.93163 4.33627 4.35340 3.88728 3.48134 3.41897 4.49144 0.85916 197 y - - H
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 114 3.22459 2.61128 5.38969 4.79509 3.58979 4.68737 5.03975 1.79213 4.61293 0.89179 2.61919 4.84389 4.96801 4.69100 4.62327 4.02095 3.66625 2.57847 5.40913 4.29402 198 l - - H
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 115 4.50357 5.94639 4.67261 4.49457 2.97674 4.90740 0.35314 4.75553 4.20979 3.98991 5.25041 4.60971 5.36272 4.62490 4.36557 4.47961 4.76464 4.60938 4.62703 2.51319 199 H - - H
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 116 2.59851 4.33805 2.68311 2.05797 4.71676 3.15802 3.59362 3.65569 2.43439 3.32473 4.42034 2.78736 4.05190 2.70193 2.69422 1.73897 3.11362 3.60918 5.81450 4.40740 200 s - - H
+ 2.68619 4.42226 2.77521 2.73118 3.46355 2.40514 3.72496 3.29355 2.67742 2.69356 4.24691 2.90348 2.73741 3.18131 2.89802 2.37888 2.77521 2.98510 4.58478 3.61505
+ 0.04979 3.09322 5.73865 0.35009 1.21950 0.48576 0.95510
+ 117 2.54785 4.42029 2.89622 2.25922 4.34868 3.66610 3.21799 3.71995 2.27125 3.07920 3.10189 2.25867 4.05899 2.34775 2.56766 2.85682 3.11428 3.36249 5.78309 3.93739 202 n - - T
+ 2.68634 4.42198 2.77524 2.73138 3.46344 2.40486 3.72467 3.29300 2.67713 2.69352 4.24714 2.90371 2.73709 3.18145 2.89825 2.37911 2.77527 2.98532 4.58501 3.61528
+ 0.09842 2.40225 5.73865 1.69597 0.20263 0.48576 0.95510
+ 118 2.53322 5.34393 2.95935 2.59629 3.94657 1.84501 3.63806 4.14023 2.18335 3.64044 4.39013 2.55576 3.77395 2.95784 2.71428 2.21077 3.11477 3.72355 4.68564 4.39095 213 g - - T
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 119 3.55513 4.24694 5.60079 5.05662 2.60993 4.96071 5.43324 0.97900 4.91818 2.09234 3.80321 5.12225 5.23216 5.06726 4.97588 4.32549 3.79818 1.34455 5.81250 4.64107 214 i - - E
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 120 2.50668 3.55624 4.84676 4.23404 3.24346 4.08398 4.41611 1.66920 4.02684 2.01982 2.79518 4.23489 4.44784 4.16480 3.83668 2.91482 2.83994 1.71230 4.92013 3.32611 215 i - - E
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 121 4.62495 5.94818 4.90176 4.71687 2.80207 5.05504 0.41821 4.71670 4.43975 3.92227 5.21366 4.70109 5.45885 4.74110 4.56151 4.57303 4.86606 4.59605 4.46431 2.05738 216 H - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 122 3.04282 4.16968 3.83274 3.22981 4.12386 3.92565 4.16387 3.45658 2.89535 2.79946 3.52962 3.63885 4.33284 3.40809 0.88367 3.03173 2.91452 3.20781 5.47983 4.24517 217 r - - S
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 123 4.66549 6.56867 0.13049 3.73947 6.20930 4.51726 5.46620 6.15252 4.80154 5.54790 6.65359 4.31602 5.22661 4.77980 5.35908 4.57977 5.04873 5.69924 7.06132 6.05090 218 D - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 124 4.11594 5.30633 6.13178 5.57769 3.73657 5.59693 5.98457 1.50133 5.46568 0.67788 3.07617 5.76705 5.63423 5.36401 5.43088 5.00606 4.33175 2.14525 5.97972 5.01356 219 L - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 125 4.55719 6.24846 4.80697 4.34215 5.94023 4.73956 5.02576 5.52333 0.17090 4.86848 5.87217 4.66859 5.24422 4.23030 3.41495 4.59394 4.77093 5.20290 6.57866 5.65826 220 K - - S
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 126 2.73388 4.87911 3.10327 2.90832 4.07991 3.41413 4.01646 3.20246 2.89177 2.38683 3.78561 3.39051 1.51394 3.22647 3.32105 2.31617 2.81372 3.19214 5.43675 4.15025 221 p - - G
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 127 2.30763 5.39894 2.49711 1.50775 4.74209 3.53358 3.60730 4.22742 2.31483 3.70337 3.89187 2.94609 4.05547 2.65035 3.08133 2.29509 3.12215 3.78862 5.83238 4.42137 222 e - - G
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 128 4.24075 6.04161 4.10323 4.13804 5.66046 4.44992 5.52992 5.77835 4.64675 5.26705 6.30900 0.15130 5.17553 4.91694 4.94682 4.32646 4.70552 5.25421 6.75952 5.61338 223 N - - G
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 129 3.55135 3.88080 5.58388 5.03211 3.05772 4.93598 5.38843 0.81084 4.88763 1.84199 3.74557 5.09695 5.20522 5.02095 4.93631 4.29650 3.79207 1.75582 5.75938 4.60163 224 i - - E
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 130 4.26500 5.46000 6.21355 5.61602 2.31085 5.64571 5.88455 2.68862 5.47780 0.52109 2.36789 5.81754 5.61663 5.25881 5.37169 5.03996 4.45544 2.72136 5.81387 4.88779 225 L - - E
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 131 3.14725 3.80930 5.11896 4.51210 2.75868 4.35237 4.69393 1.48763 4.30885 1.32733 3.15909 4.51494 4.68518 4.42027 4.31553 3.67228 3.37834 1.91515 5.14039 3.60311 226 l - - E
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 132 2.83132 4.28838 2.02200 2.41335 4.70055 3.12743 3.31546 4.17875 2.06503 3.46693 4.09733 2.49326 4.05387 2.94892 3.07895 2.27711 2.89161 2.90947 5.80603 4.40188 227 d - - E
+ 2.68620 4.42227 2.77521 2.73125 3.46356 2.40515 3.72496 3.29356 2.67743 2.69346 4.24692 2.90348 2.73741 3.18137 2.89794 2.37889 2.77521 2.98513 4.58479 3.61505
+ 0.19179 2.92011 2.11536 0.31959 1.29625 0.48576 0.95510
+ 133 2.77846 5.34345 2.73873 2.12504 4.68884 3.31622 3.10327 4.17503 2.07146 3.64885 4.14408 2.35495 3.55373 2.53396 2.68259 2.30312 2.80970 3.73426 5.77591 4.07717 229 k - - T
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01122 4.89146 5.61380 0.61958 0.77255 0.46383 0.99121
+ 134 2.76231 5.37627 2.40965 2.30431 4.72103 3.48860 3.46007 4.20680 2.15285 3.68141 4.41704 2.22463 3.54282 2.67483 2.66394 2.48608 2.48229 3.08661 5.80911 4.39830 230 k - - T
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01030 4.97674 5.69908 0.61958 0.77255 0.42506 1.06054
+ 135 2.88621 4.31580 2.58861 2.52891 4.00821 1.80604 3.64216 3.70404 2.55848 3.01103 3.82083 2.93142 3.28125 2.96153 3.15140 2.63196 2.92652 3.07947 5.65563 3.39061 231 g - - T
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 136 2.74326 5.32913 2.62872 2.23118 4.20190 3.27586 3.01088 3.39612 2.54602 3.28443 3.99578 2.66732 4.06020 2.45230 2.82728 2.54748 2.65672 2.69485 5.77785 3.49295 232 e - - E
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 137 2.61635 3.28525 4.16732 3.71739 2.98202 4.03403 4.34546 2.03775 3.50788 1.92540 3.47356 3.38535 3.11745 3.96570 3.52677 3.32696 2.46663 1.86856 4.97202 3.78516 233 v - - E
+ 2.68644 4.42087 2.77438 2.73125 3.46306 2.40580 3.72561 3.29182 2.67742 2.69394 4.24637 2.90298 2.73752 3.18209 2.89809 2.37898 2.77573 2.98487 4.58490 3.61464
+ 0.36530 1.19470 5.73865 2.01193 0.14356 0.48576 0.95510
+ 138 2.92386 3.12674 3.30583 2.50241 4.41812 3.73989 3.57074 3.83865 1.16713 3.42239 3.64701 3.25964 4.12762 3.06518 2.74407 2.94589 3.15200 3.22587 5.64420 3.71460 253 k - - E
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 139 3.61791 5.07369 5.93139 5.42030 4.01697 5.40165 5.95563 1.06228 5.32659 1.08905 3.76387 5.56598 5.56723 5.42106 5.39317 4.81179 4.11011 1.74432 6.14737 5.05160 254 i - - E
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 140 1.74479 2.79152 4.35686 3.77898 3.55350 2.78668 4.34505 2.08763 3.66685 2.55990 3.56128 3.98833 4.38080 3.89329 3.86150 2.46831 2.34811 2.41028 5.05799 3.86488 255 a - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 141 4.66549 6.56867 0.13049 3.73947 6.20930 4.51726 5.46620 6.15252 4.80154 5.54790 6.65359 4.31602 5.22661 4.77980 5.35908 4.57977 5.04873 5.69924 7.06132 6.05090 256 D - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 142 4.66482 5.73614 5.86239 5.64956 0.40883 5.43325 4.33355 3.86711 5.42110 2.16428 4.36705 5.11239 5.65371 5.16689 5.27011 4.83252 4.86624 3.98432 3.74189 2.69037 257 F - - G
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 143 3.93699 5.85566 3.02816 3.87037 6.00993 0.21285 5.44927 5.75466 4.70121 5.27717 6.21696 4.31536 4.99427 4.76567 5.12629 4.02226 4.42780 5.10478 6.99282 5.96830 258 G - - T
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 144 2.54355 3.67295 4.73868 4.13265 2.71576 4.06852 3.76754 2.37455 3.94756 1.20416 3.31174 3.74431 4.43365 4.10500 4.00521 2.64259 3.14725 2.29206 4.93223 3.75278 259 l - - T
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.03189 5.01631 3.69859 0.61958 0.77255 0.48576 0.95510
+ 145 0.77520 2.86695 4.81978 4.47036 4.95592 3.15951 5.20700 4.36343 4.38394 4.08078 4.90451 4.25075 4.38058 4.58838 4.56864 1.45304 3.34905 3.34992 6.35477 5.22001 260 a - - .
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.07711 4.99453 2.69658 0.61958 0.77255 0.54567 0.86620
+ 146 2.54977 3.79925 3.16699 2.32606 4.48674 3.31547 3.84408 3.47518 1.75582 3.12339 4.25869 2.84258 4.04145 2.96441 2.18943 2.71334 2.91887 2.95414 5.67187 4.30075 261 k - - E
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.13472 4.92824 2.13029 0.61958 0.77255 0.70219 0.68419
+ 147 2.64685 3.78445 3.06669 2.61534 3.32325 3.67596 3.69246 3.14713 2.01231 2.43193 3.43451 3.16113 4.06301 2.47274 3.08778 2.74475 2.84906 2.65428 5.37440 4.07606 262 k - - .
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.29473 4.80574 1.39802 0.61958 0.77255 0.92027 0.50818
+ 148 2.40579 4.15423 4.25399 3.66267 2.39272 3.57693 3.44550 2.33935 3.03827 1.86796 2.97007 3.83355 4.18573 3.73297 3.67827 3.10851 2.93289 2.21754 4.76738 2.96352 263 l - - .
+ 2.68635 4.42219 2.77489 2.73146 3.46367 2.40530 3.72500 3.29419 2.67720 2.69370 4.24630 2.90362 2.73727 3.18122 2.89818 2.37860 2.77478 2.98583 4.58472 3.61420
+ 0.77167 0.63015 5.24955 1.50734 0.25038 0.20147 1.70117
+ 149 2.68930 5.13793 2.99383 2.28756 4.12167 3.02811 3.40047 2.83046 2.53990 2.67433 3.91490 2.66806 3.85841 2.95123 3.08518 2.54554 2.43488 3.14237 4.83794 3.11842 281 e - - E
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 150 2.67960 3.59834 3.08049 2.32634 4.00400 2.85568 3.65072 3.26198 2.22635 2.80014 3.89773 3.03566 3.90780 2.84131 2.77630 2.59674 2.54121 2.94346 4.66327 3.60288 282 k - - E
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 151 2.78407 5.36932 2.80723 2.38070 3.95652 3.28210 3.31902 3.80407 2.38757 3.23090 4.41260 2.26860 2.87333 2.94776 2.55475 2.11230 2.82314 3.31603 5.80800 4.40313 283 s - - C
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 152 2.55066 5.37311 2.42428 2.58328 4.70981 2.65546 3.66067 3.46611 2.34139 3.39818 4.41598 2.44705 3.58966 2.48003 2.87086 2.30355 2.92043 3.58081 5.81084 3.32103 284 s - - S
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 153 2.61131 5.36709 3.05324 2.00706 4.70125 2.53001 3.45141 4.17959 2.46541 3.54879 4.41063 3.13225 3.27183 2.67970 2.77280 2.14590 2.62504 2.97295 5.80635 3.79465 285 e - - S
+ 2.68619 4.42226 2.77520 2.73124 3.46320 2.40514 3.72495 3.29355 2.67742 2.69356 4.24691 2.90348 2.73740 3.18147 2.89802 2.37888 2.77520 2.98519 4.58478 3.61504
+ 0.03620 3.43177 5.73865 0.40966 1.09027 0.48576 0.95510
+ 154 2.80870 4.76397 2.82688 2.35901 3.53520 3.31737 3.24083 3.53679 2.31494 2.98485 3.52265 2.69923 3.15465 2.90046 2.56489 2.40361 2.83318 3.04461 5.74293 3.76697 287 k - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 155 2.38638 3.55872 3.84850 3.27925 3.07902 3.89951 3.49984 3.07191 2.87600 2.13071 2.79826 2.94436 3.28103 3.24012 3.30127 2.77627 2.52689 2.66914 5.17020 2.84075 288 l - - C
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 156 2.88266 4.79637 2.63708 2.49106 4.69372 3.27452 3.02757 4.17056 2.31920 3.54781 3.84892 2.54158 3.83133 2.71114 2.83815 2.34796 2.07167 3.53868 4.84477 3.26548 289 t - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 157 2.55115 5.22307 2.81541 2.42597 3.84088 2.72211 3.45978 3.70939 2.65113 3.50012 4.03956 3.00145 3.26637 2.92366 3.12986 2.10982 2.09681 2.95270 4.42058 4.32902 290 t - - S
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 158 2.79383 4.53543 3.94528 3.00256 2.28876 3.25886 4.19260 2.53698 3.31063 2.13485 3.51266 3.25465 3.61933 3.02975 2.60672 3.04108 3.13630 2.22820 5.12884 3.03437 291 l - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 159 2.54133 2.27249 3.62507 3.14565 3.48798 3.47382 4.20805 2.87324 3.24770 2.61629 3.62417 3.76153 4.31084 3.45605 3.15192 3.19594 2.77273 1.44309 5.11140 3.89714 292 v - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 160 2.50560 4.02210 4.21483 3.69251 4.03927 0.87585 4.50859 3.18042 3.62456 3.12203 4.01557 3.91946 4.34666 3.89680 3.91281 2.66630 3.23503 2.52015 5.49804 3.97346 293 g - - S
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 161 2.98792 5.00679 3.18026 3.47531 5.09253 3.65988 4.75357 4.53531 3.72802 4.18133 4.99276 3.79669 4.37930 3.97717 4.12874 1.60941 0.74054 3.97784 6.39182 5.11951 294 t - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 162 2.69840 5.26022 3.00961 2.31122 4.20998 3.68086 3.63617 3.20701 2.41779 2.58849 4.31499 2.98486 2.62271 2.99075 2.13729 2.36313 3.11573 3.42385 5.72545 3.54571 295 r - - G
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 163 2.71301 5.29924 2.59488 2.14743 3.52695 3.04037 3.28275 4.06670 2.61594 3.34508 4.35002 2.84026 3.31113 2.97459 2.36266 2.86533 2.70674 3.41928 3.03699 3.23042 296 e - - G
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 164 4.65993 5.73598 5.69662 5.49898 1.97465 5.32012 3.31709 4.36240 5.29326 3.66395 4.92323 4.93743 5.59573 5.06816 5.17473 4.69695 3.41633 4.25844 2.61302 0.51590 297 Y - - G
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 165 2.46851 3.63596 4.34730 3.76113 3.49978 4.00900 4.30977 2.55613 3.41377 2.11254 1.89168 3.40620 4.37893 3.86942 2.23584 3.08926 3.14320 2.13937 5.00600 3.81292 298 m - - S
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 166 0.54633 4.79516 4.59072 4.34047 5.33605 3.22550 5.27451 4.80651 4.37656 4.47607 5.24769 4.21379 3.02084 4.58677 4.60871 1.81435 3.40538 4.05386 6.66459 5.53199 299 A - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 167 3.08666 5.02380 4.02349 3.92167 5.10908 3.73669 5.07487 4.62556 4.04836 4.33998 5.22795 3.34786 0.41351 4.38870 4.30726 3.26072 3.60085 3.40472 6.47905 5.20179 300 P - - H
+ 2.68622 4.42144 2.77523 2.73111 3.46358 2.40517 3.72498 3.29358 2.67745 2.69359 4.24694 2.90351 2.73743 3.18126 2.89786 2.37891 2.77523 2.98522 4.58481 3.61507
+ 0.03484 3.47295 5.73865 0.99675 0.46057 0.48576 0.95510
+ 168 3.66837 6.19086 2.84947 0.45189 5.55161 3.90523 4.43200 5.09782 3.30487 4.55035 5.42336 3.03786 4.53514 3.60153 3.37398 3.54999 3.95969 4.65772 6.64024 5.17650 305 E - - H
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 169 2.79774 4.32598 4.68241 3.67608 3.42171 4.06471 4.38713 2.01470 3.90321 1.87174 3.44282 4.15860 4.43014 3.77035 3.25202 3.36713 2.95239 1.31877 3.77234 3.76466 306 v - - H
+ 2.68603 4.42242 2.77519 2.73104 3.46342 2.40506 3.72511 3.29371 2.67728 2.69322 4.24707 2.90364 2.73756 3.18163 2.89801 2.37893 2.77519 2.98535 4.58494 3.61520
+ 0.12919 2.22240 4.35495 1.23224 0.34480 0.48576 0.95510
+ 170 2.91184 3.76308 4.76588 4.15799 3.39752 4.06920 3.82796 1.60071 3.96642 1.39613 3.17824 3.65225 4.43387 4.11848 4.01348 2.94594 3.14403 2.21737 4.92444 3.43929 311 l - - H
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00999 5.00664 5.72898 0.61958 0.77255 0.51297 0.91308
+ 171 2.62785 5.06480 3.29796 2.67561 3.73804 3.41086 3.92577 3.21358 2.32640 2.15096 3.31180 2.55443 4.11004 2.47045 2.33927 2.70318 3.11578 3.12852 5.57146 4.24107 312 l - - C
+ 2.68631 4.42245 2.77511 2.73076 3.46350 2.40522 3.72547 3.29356 2.67765 2.69366 4.24573 2.90389 2.73738 3.18142 2.89826 2.37846 2.77520 2.98520 4.58530 3.61473
+ 0.62427 1.87899 1.16602 1.98855 0.14722 0.46912 0.98231
+ 172 2.60166 5.18307 2.62016 2.19793 3.35206 2.39740 3.57105 3.96340 2.18128 3.47543 4.23188 3.01161 3.92489 2.82990 2.86326 2.33987 2.67701 3.55746 5.63416 3.78538 327 k - - C
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01428 4.65191 5.37425 0.61958 0.77255 0.24611 1.52250
+ 173 2.37600 3.94341 2.81761 2.45806 4.08381 2.38833 3.32666 4.15213 2.47322 3.64753 4.39446 2.71786 3.74359 2.39493 2.76163 2.38666 3.00597 3.01776 5.79219 3.82026 328 a - - S
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00998 5.00778 5.73012 0.61958 0.77255 0.47101 0.97916
+ 174 2.81816 4.87774 2.88922 2.34131 3.91699 3.47934 3.84840 3.76601 2.22767 3.10881 4.41163 2.46519 2.75598 2.51039 2.43545 2.43680 2.76354 3.54179 5.80719 3.84984 329 k - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 175 2.74169 5.33416 2.58184 2.32653 3.61666 2.33545 3.50275 4.12419 2.36762 3.50261 3.56274 2.91332 3.07814 2.74477 2.96926 2.79421 2.92848 3.32496 5.78164 2.72284 330 e - - C
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 176 2.48397 4.72191 2.72922 2.94719 3.45604 3.83733 2.73484 2.72590 3.03376 2.94128 3.81928 3.51045 4.21965 3.13222 3.31573 2.84267 3.12967 2.71705 3.94971 1.76193 331 y - - T
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 177 2.88858 5.15756 2.48812 2.69267 3.68939 2.20273 3.90720 3.84889 2.69072 3.17648 4.22648 3.21985 3.19313 3.04303 3.16266 2.07644 2.02474 3.50391 5.64990 3.69862 332 t - - H
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 178 2.44412 5.27089 3.18567 2.52594 4.01181 3.49400 3.20300 3.68711 2.26882 2.99802 4.32458 3.16791 2.73532 2.67304 2.47574 2.35896 2.41445 3.31659 5.73361 3.79657 333 k - - H
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 179 2.27957 5.36842 3.14470 2.24142 4.70283 3.35867 3.70433 4.18054 1.84880 3.00297 4.41216 3.13478 2.50109 2.87247 2.49374 2.50485 2.88881 3.75338 5.80713 4.40386 334 k - - H
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 180 2.25487 3.19836 3.67383 3.53894 3.58335 3.60706 4.24810 2.30247 3.45618 2.57768 3.58074 3.40343 4.33674 3.48890 3.71724 2.25302 2.94661 1.56396 5.07167 3.86608 335 v - - H
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 181 3.32488 6.23611 0.30142 2.99559 5.85936 3.97225 4.81661 5.46625 4.07634 5.00781 5.98660 3.57219 4.70996 4.04099 4.76451 3.76774 4.26196 4.95940 7.04785 5.56474 336 D - - H
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 182 2.97530 4.34655 4.92112 4.31006 3.42469 4.15298 4.48903 1.67409 4.10270 2.14170 2.44181 4.30839 4.51041 4.23558 4.11915 3.46567 2.80277 1.45020 3.28394 3.56694 337 v - - H
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 183 4.60767 5.71652 5.61554 3.89031 2.18526 5.28181 4.15190 4.32304 5.18037 3.62888 4.88484 4.90634 5.56392 5.01906 5.10312 4.65700 4.81381 4.22147 0.60655 1.74323 338 W - - H
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 184 1.30551 4.78823 4.65738 4.37945 5.36630 2.58206 5.28849 4.84019 4.38318 4.50739 5.27020 4.22569 4.39579 4.59600 4.61395 0.79404 2.89139 4.06528 6.68751 5.56026 339 s - - H
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 185 2.44153 3.17932 4.87400 4.25972 2.53121 4.09082 4.42403 2.33144 4.04748 1.34403 2.92510 4.24940 4.45392 4.18053 4.05982 3.14600 3.15398 2.13810 4.92017 3.14864 340 l - - H
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 186 2.22507 4.96728 4.63623 4.63233 5.66307 0.33314 5.62287 5.16416 4.86793 4.86816 5.66661 4.43512 4.57282 5.01497 4.99264 3.26151 3.63533 4.32703 6.92990 5.89905 341 G - - H
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 187 2.93009 2.13614 4.95885 4.35253 3.48038 4.19799 4.54424 1.68794 4.14925 1.93394 3.18432 4.35359 4.55452 4.28834 4.17024 3.34008 3.23972 1.60527 5.03746 3.47367 342 v - - H
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 188 3.21831 4.55127 5.17022 4.58630 3.70338 4.47717 4.86313 1.30610 4.40976 1.92114 2.79907 4.62299 4.81179 4.56490 4.45688 3.52794 2.67243 1.42404 5.34369 4.16408 343 i - - H
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 189 2.77853 3.56970 4.91220 4.29933 2.66878 4.13468 4.46922 2.12981 4.08926 1.13811 3.14072 4.29275 4.49323 4.21981 4.10205 3.44689 2.88537 2.20246 4.95897 3.46211 344 l - - H
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 190 2.08301 4.31008 4.80905 4.20025 2.66597 4.08391 3.54227 2.07553 4.00182 2.35024 3.19529 4.21899 4.44796 4.14611 4.03654 3.39206 3.15615 2.32332 2.91148 1.86433 345 y - - H
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 191 2.65126 3.79080 3.03118 1.37895 4.54227 3.68257 3.87660 3.27048 2.56225 3.53374 4.30787 2.88399 4.07460 2.72714 3.11894 2.49943 2.86114 3.20681 5.71940 3.61825 346 e - - H
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 192 2.75949 4.33120 4.86063 4.24972 2.93412 4.11800 4.44873 2.58063 4.04775 1.34098 1.86205 4.26240 4.47769 4.18564 4.07448 3.30982 2.87183 2.17494 4.95131 3.25026 347 l - - H
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 193 2.13730 3.34433 4.84746 4.23449 2.67079 4.08305 4.41495 2.45417 4.02682 1.45586 2.95446 4.23448 4.44687 4.16424 3.65241 3.39295 2.78239 2.10310 4.91833 3.10946 348 l - - H
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 194 2.61714 3.04119 3.51958 2.50105 3.16562 3.44068 4.02999 3.26384 2.78703 2.46125 3.90521 2.94061 4.18669 3.26384 2.94427 2.45451 1.92365 2.96026 5.36672 3.77569 349 t - - H
+ 2.68592 4.42131 2.77530 2.73134 3.46364 2.40523 3.72505 3.29364 2.67751 2.69365 4.24624 2.90357 2.73750 3.18157 2.89769 2.37886 2.77510 2.98507 4.58487 3.61513
+ 0.08274 2.77459 4.07273 1.24373 0.34011 0.48576 0.95510
+ 195 2.74009 5.38236 2.60734 2.58658 4.30151 1.49346 3.57775 4.19577 2.06867 3.68256 4.42710 2.84258 4.06100 2.86136 2.79826 2.78642 3.12785 3.76776 5.82019 4.41533 355 g - - S
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.02515 5.00240 4.01100 0.61958 0.77255 0.52459 0.89600
+ 196 2.87057 4.15783 2.81932 2.15097 3.67482 3.00161 3.44561 3.53712 2.01194 3.52030 4.39830 2.84675 4.04172 2.62971 2.18111 2.65254 2.90372 3.46034 5.79407 3.92999 356 k - - S
+ 2.68632 4.42239 2.77496 2.73101 3.46368 2.40527 3.72508 3.29339 2.67739 2.69369 4.24616 2.90361 2.73734 3.18160 2.89815 2.37901 2.77533 2.98486 4.58491 3.61430
+ 0.06990 2.74572 5.70978 1.46974 0.26135 0.43968 1.03351
+ 197 2.53761 4.57755 3.85895 3.05555 3.06219 3.90225 3.89097 2.90555 3.23603 1.98376 3.43681 3.14844 2.18635 3.28921 3.56902 2.76101 2.38583 2.48063 5.16546 3.65117 363 l - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 198 2.94035 4.49377 4.16973 3.59341 3.59928 3.99457 4.28692 2.57573 3.48228 2.11382 3.59630 3.88641 1.19333 3.75706 3.46613 3.08341 3.17527 2.51467 5.10025 3.66586 364 p - - T
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 199 2.95410 3.97958 4.76382 4.16399 1.23466 4.10162 4.38107 2.78567 3.65586 2.19089 3.46719 4.20671 3.78920 4.13156 4.03525 3.25126 3.18603 2.50296 2.73984 2.86766 365 f - - T
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 200 2.72297 4.82530 2.62940 2.35446 3.83755 3.31971 3.71413 4.17131 2.26174 3.54363 4.14174 3.02369 2.60946 2.49179 2.66057 2.21727 2.99115 3.74587 4.55596 3.10965 366 s - - S
+ 2.68620 4.42227 2.77522 2.73112 3.46340 2.40515 3.72496 3.29334 2.67743 2.69357 4.24692 2.90349 2.73742 3.18148 2.89803 2.37889 2.77522 2.98520 4.58479 3.61505
+ 0.07731 2.84051 4.13492 0.30572 1.33404 0.48576 0.95510
+ 201 2.63880 5.38435 2.63657 2.22720 4.72697 1.94780 3.15235 3.87964 2.57669 3.68860 4.42577 2.57921 3.16991 2.74291 2.86900 2.50219 2.85278 3.77370 5.81843 4.40865 368 g - - S
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01003 5.00344 5.72579 0.61958 0.77255 0.52175 0.90012
+ 202 2.40102 4.71375 2.46996 2.13243 4.71840 3.11745 3.05416 3.48265 2.25142 3.16134 4.41932 2.93828 3.25177 2.60824 2.79040 2.58260 2.90071 3.38079 5.81277 4.40438 369 e - - S
+ 2.68658 4.42180 2.77453 2.73123 3.46394 2.40505 3.72421 3.29333 2.67765 2.69382 4.24730 2.90354 2.73686 3.18110 2.89829 2.37906 2.77522 2.98525 4.58428 3.61543
+ 0.55463 1.48984 1.60791 1.39890 0.28351 0.52175 0.90012
+ 203 2.69338 5.29005 2.51143 2.25105 4.62988 2.84270 3.49832 3.48405 2.27737 3.31427 4.33211 2.56706 3.20350 2.85310 2.67590 2.21378 2.73620 3.67787 5.72586 4.31806 375 s - - H
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01250 4.78398 5.50633 0.61958 0.77255 0.95212 0.48763
+ 204 2.65942 5.19894 2.69156 2.28179 3.77027 3.19251 3.77484 3.06173 2.43464 2.99400 3.94013 2.58274 3.44930 2.63512 2.62020 2.46578 2.71730 3.35179 5.65696 3.80565 376 e - - H
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01250 4.78398 5.50633 0.61958 0.77255 0.77169 0.62033
+ 205 2.38920 5.21254 2.73488 2.26876 4.51445 3.29559 3.03245 3.05648 2.42252 2.83088 3.97624 2.72691 3.66747 2.74292 2.65924 2.79642 2.87825 3.04317 5.67196 3.47007 377 e - - C
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01186 4.83615 5.55849 0.61958 0.77255 0.33713 1.25111
+ 206 2.65422 4.48489 1.88534 2.29942 4.71042 3.12833 3.84224 3.67843 2.58000 3.67468 4.41498 2.22848 4.04754 2.86157 2.64414 2.33478 2.73698 3.75923 5.80928 4.40246 378 d - - C
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01003 5.00344 5.72579 0.61958 0.77255 0.52175 0.90012
+ 207 2.52228 5.35256 2.79874 2.27245 4.68298 3.15080 3.25420 3.81263 2.42135 3.03021 2.98061 3.02733 3.41549 2.09266 2.89624 2.43800 3.03420 3.22791 5.79412 4.39217 379 q - - T
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01003 5.00344 5.72579 0.61958 0.77255 0.52175 0.90012
+ 208 2.88352 5.03264 3.01718 2.64158 3.36791 3.41419 3.67586 2.82361 2.46533 2.06980 3.25199 2.87105 3.91016 2.67457 2.54739 2.67076 3.11488 3.35644 5.54543 3.24074 380 l - - H
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01003 5.00344 5.72579 0.61958 0.77255 0.52175 0.90012
+ 209 2.31106 5.21929 3.20358 2.11286 3.58411 3.54755 3.12693 3.74178 2.35878 3.37262 4.27754 3.18132 3.64073 2.21825 2.83044 2.63943 3.03559 2.71879 4.50670 3.34948 381 e - - H
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01003 5.00344 5.72579 0.61958 0.77255 0.46390 0.99109
+ 210 2.74907 4.02445 4.23598 3.43708 3.16042 3.98772 3.66116 2.29352 2.78065 1.91975 2.65717 3.64306 4.00461 3.79624 2.62994 3.12682 2.72367 2.05105 5.03295 3.83444 382 l - - H
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 211 2.79706 4.32223 4.14412 4.07508 2.44930 4.05985 3.54709 1.67401 3.90204 2.17979 2.94629 3.31750 4.42562 4.07034 3.98057 2.91878 2.88141 2.01026 4.94063 2.95520 383 i - - H
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 212 2.43063 3.51667 2.84063 2.33381 3.23751 3.53757 3.64461 3.61354 2.52297 3.04234 3.80037 3.02528 3.31294 2.77439 2.36706 2.71893 3.04140 2.71650 5.64517 3.47973 384 e - - S
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 213 2.54995 5.35768 3.14585 2.23433 4.68798 3.33616 3.38625 3.80986 2.09254 2.85705 3.68757 2.56176 4.05535 2.40160 2.38927 2.57618 3.04385 3.36418 5.79929 3.79887 385 k - - S
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 214 2.66499 5.02053 2.80345 2.59207 4.23983 3.19081 3.94632 1.95336 2.43621 2.96229 3.77095 2.92719 4.12615 3.11304 2.86357 2.94448 2.42822 2.54184 5.53679 4.21766 386 i - - H
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 215 2.79062 4.84420 3.48859 2.83007 4.02200 3.06268 4.01637 2.98055 2.36084 1.68419 3.06982 3.40535 3.56488 2.89781 2.78978 2.64270 2.97298 2.81255 5.39215 4.11258 387 l - - H
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 216 2.78422 4.40067 2.87114 2.38957 4.66317 2.42774 3.11725 3.68493 2.29738 3.11118 3.80555 3.07548 3.38861 2.66839 2.52841 2.36297 2.74889 3.71883 4.85618 3.72852 388 k - - H
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.04975 5.01631 3.17248 0.61958 0.77255 0.48576 0.95510
+ 217 2.55009 3.88585 3.08502 2.47179 4.52328 2.60499 3.86026 3.74333 2.31088 3.21633 3.94275 3.03087 2.50945 2.97834 2.41589 2.69163 2.38722 3.38360 5.70135 4.11095 389 k - - .
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01030 4.97686 5.69921 0.61958 0.77255 0.59090 0.80705
+ 218 2.71816 5.35510 2.47492 2.28903 4.69101 3.44039 3.67059 2.92462 2.15295 3.03900 4.39818 2.98975 2.40750 2.74839 2.76016 2.49540 2.85213 3.74081 5.79327 4.38792 390 k - - .
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.02103 4.97686 4.27462 0.61958 0.77255 0.59090 0.80705
+ 219 2.59242 4.56547 3.37418 3.24570 3.28039 3.87349 3.78552 2.80260 2.91515 1.85640 3.67045 2.94464 3.03710 3.48913 3.31352 2.93163 2.57101 2.12270 4.60315 3.29903 391 l - - .
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01041 4.96623 5.68858 0.61958 0.77255 0.61678 0.77584
+ 220 2.76552 5.35116 2.75065 2.09233 4.26840 3.39661 3.23930 3.45666 2.13782 2.93921 3.69074 2.78256 2.85112 2.85423 2.61182 2.41762 3.01864 3.73701 5.78920 4.16743 392 e - - .
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01041 4.96623 5.68858 0.61958 0.77255 0.61678 0.77584
+ 221 2.56616 4.88573 3.26662 2.33696 2.41520 3.27403 3.41068 2.92250 2.70761 2.68623 3.97070 3.19787 3.38122 3.16656 2.79903 2.47364 2.99470 2.86843 4.82552 3.32054 393 e - - .
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01041 4.96623 5.68858 0.61958 0.77255 0.61678 0.77584
+ 222 2.62567 5.35084 2.04845 2.35215 4.39252 3.47212 3.16243 3.98892 2.45186 3.65226 3.66396 2.66846 2.63580 2.82810 3.05661 2.22708 2.99549 3.54011 5.78899 3.92777 394 d - - .
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.03667 4.96623 3.53930 0.61958 0.77255 0.61678 0.77584
+ 223 2.86103 4.03193 3.18635 2.38909 3.31435 3.61153 3.49109 2.70908 2.69769 2.69388 3.88535 3.22191 3.67076 3.11276 2.73635 2.49324 3.00545 2.72730 2.94731 2.96802 395 e - - T
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01875 4.94025 4.47244 0.61958 0.77255 0.67631 0.71028
+ 224 2.62521 5.12447 2.77972 2.44738 3.31605 3.53418 3.86652 3.33309 2.47319 3.03557 4.18886 3.10134 2.42408 2.60018 2.70100 2.64509 2.92363 3.22521 3.41935 3.46519 396 p - - T
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.05901 4.93227 2.99396 0.61958 0.77255 0.69360 0.69269
+ 225 2.68343 5.20702 2.88582 2.22963 3.55567 3.45903 3.65367 3.49248 2.11994 2.97314 4.26172 2.80968 3.57686 2.44336 3.06162 2.53581 2.67303 3.18308 3.73101 3.66292 397 k - - S
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01130 4.88456 5.60691 0.61958 0.77255 0.78866 0.60597
+ 226 2.68707 4.98468 2.82158 2.38405 3.75917 3.36024 3.65392 3.18317 2.38508 2.73942 3.76303 3.22111 3.36652 3.04584 2.96704 2.31757 2.64759 2.95752 3.21600 3.40268 398 s - - .
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.11345 4.88456 2.30573 0.61958 0.77255 0.78866 0.60597
+ 227 2.79298 3.84213 2.48108 2.52210 3.99851 3.60747 3.12972 3.13545 2.48018 3.05991 4.13768 2.83211 3.54520 2.93964 2.41588 2.35619 2.76810 2.97839 5.56015 3.44494 399 s - - .
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.02807 4.78362 3.94704 0.61958 0.77255 0.95264 0.48731
+ 228 2.58191 4.56682 2.77742 2.37170 4.46635 3.58143 3.77449 3.50815 2.36445 2.67587 4.22448 2.86502 2.73607 2.80387 2.79297 2.07848 2.75446 3.53442 5.63386 3.74575 400 s - - .
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.14447 4.76826 2.07130 0.61958 0.77255 0.97412 0.47405
+ 229 2.74120 5.02625 2.90214 2.38037 3.96892 2.81361 3.75340 3.09744 2.29181 2.85276 3.79351 2.85134 3.31773 2.88600 2.57247 2.48932 2.74923 2.81409 5.51153 4.15648 401 k - - .
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.02950 4.63827 3.94280 0.61958 0.77255 1.12880 0.39071
+ 230 2.65814 5.03703 2.72915 2.44094 4.30481 3.19996 3.74471 3.73960 2.51991 2.72378 3.12113 3.05398 2.98987 2.79382 2.49179 2.12708 2.96796 3.38544 5.51898 3.52938 402 s - - .
+ 2.68724 4.42293 2.77612 2.73159 3.46162 2.40699 3.72369 3.29398 2.67731 2.69321 4.24701 2.90285 2.73662 3.18257 2.89624 2.37860 2.77511 2.98573 4.58252 3.61251
+ 0.60323 0.80254 5.34581 2.99471 0.05135 0.22221 1.61320
+ 231 2.51767 5.38833 2.69504 1.91983 4.73145 3.65677 3.84405 3.51135 2.26714 3.33248 4.42951 2.74739 2.83044 2.63263 2.69535 2.26534 2.89575 3.77792 5.82218 4.12814 442 e - - H
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 232 2.61324 5.33087 2.55247 1.71577 3.78905 3.51981 3.85697 4.11872 2.53837 3.37618 3.68276 2.71899 3.50504 2.96215 2.76975 2.43182 2.62759 3.19721 4.83386 4.08215 443 e - - H
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 233 1.85315 2.66076 4.74963 4.14369 2.72361 2.76389 4.40211 2.66580 3.95769 1.60680 3.08425 4.19191 4.43908 4.11400 4.01342 3.37949 2.94810 2.35782 4.93743 3.75833 444 l - - H
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 234 2.54113 3.93957 3.31567 2.58263 3.59686 3.36801 3.93655 2.84244 1.77469 2.55244 4.12290 3.02474 4.11900 2.54032 2.70090 2.93506 2.79964 3.23719 5.55956 3.97978 445 k - - H
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 235 2.66035 5.38903 1.80529 2.16718 4.22724 3.25823 3.17680 4.00903 2.28647 3.50730 4.43018 2.97613 4.05032 2.48614 2.98498 2.31241 3.11375 3.77870 5.82277 3.97909 446 d - - H
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 236 3.21254 4.56529 5.14365 4.53738 1.97526 4.40976 4.73239 2.19759 4.34073 1.04052 3.41232 4.55986 4.72994 4.44093 4.35221 3.72900 3.00622 2.20314 5.16040 3.53582 447 l - - H
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 237 2.97518 4.05135 5.35921 4.78478 3.77817 4.66169 5.06989 1.35059 4.61468 1.50253 2.60400 4.82061 4.97178 4.75525 4.65269 4.00168 3.59517 1.52175 5.50364 4.33590 448 i - - H
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 238 2.63113 4.16111 2.70523 2.01221 4.32546 2.89528 3.69801 3.91463 1.97992 3.37990 4.41866 2.72468 4.05215 2.88390 2.65380 2.44936 2.78930 3.52828 5.81309 3.68713 449 k - - H
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 239 2.79532 4.56741 2.59886 2.26653 4.72524 2.97326 3.84498 4.20852 1.87988 3.68761 4.42563 2.67816 4.05093 2.72680 2.26697 2.39445 3.11354 3.44147 4.06926 3.70096 450 k - - H
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 240 2.76031 1.91137 4.93344 4.32897 3.47342 4.21043 4.55379 2.12811 4.13437 1.60981 2.11111 4.35327 4.56463 4.27495 4.16872 3.52442 2.73881 2.49904 5.05160 3.88034 451 l - - H
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 241 3.00579 3.43594 4.91160 4.30236 2.88535 4.17356 4.48924 2.41412 3.62991 0.97514 3.41700 4.31537 4.52645 4.23058 4.12367 3.48482 3.23680 2.59853 2.70167 3.78558 452 l - - T
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 242 2.51291 3.86266 2.42773 2.26878 4.71076 3.65927 3.14908 3.51790 2.32370 3.67561 4.41657 2.44903 4.05255 2.58104 2.64695 2.72413 2.48024 3.27065 5.81133 3.77060 453 e - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 243 2.89024 4.99098 3.22187 2.69841 3.16242 3.74556 3.43367 3.45008 2.12873 2.47972 3.65551 3.30484 3.00902 2.69329 2.47140 2.87653 2.77051 2.80352 4.74384 3.09104 454 k - - S
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 244 2.75442 4.59220 1.48443 2.55169 4.69407 3.66624 3.85987 4.16899 2.26580 3.66358 4.41104 2.16093 4.06270 2.96232 2.94350 2.69711 3.00639 3.21953 5.80766 4.40610 455 d - - S
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 245 2.53666 4.51809 3.31495 2.50094 3.81458 3.47863 3.66745 3.68842 2.74796 3.30408 3.76297 2.90283 1.45947 2.98944 2.97069 2.84711 3.12065 2.90248 5.56105 4.23506 456 p - - G
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 246 2.18867 5.36299 2.90524 2.21328 4.32931 3.53924 3.49382 3.97251 2.24621 3.14962 3.99253 2.78034 3.78478 2.54072 2.85251 2.30318 2.70173 3.25844 5.80328 3.47734 457 a - - G
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 247 2.48590 4.36945 2.67418 2.22639 4.72760 3.65776 3.84501 4.21118 1.68322 3.11616 4.42723 3.02530 4.05117 2.52411 2.40832 2.54354 2.78662 3.77464 5.82017 4.41136 458 k - - G
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 248 3.97870 5.88109 4.77637 3.79584 5.10245 4.51923 4.26030 4.68907 2.25479 4.07008 4.99673 4.06985 4.83329 3.42182 0.45649 3.98836 4.07883 4.42272 3.45519 4.78623 459 R - - S
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 249 2.59820 4.04607 4.60274 4.00452 3.26886 3.61184 4.36773 2.06089 3.84570 1.56372 3.45362 4.11687 2.06890 4.02734 3.95003 2.68390 3.14561 2.58630 4.40258 3.38622 460 l - - T
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.04987 5.01631 3.16967 0.61958 0.77255 0.48576 0.95510
+ 250 2.79362 5.19179 3.01710 2.75300 4.64905 2.77281 4.01085 4.10036 2.79939 3.46822 4.43166 2.61914 4.12461 3.14023 3.27668 1.68833 1.53351 3.69065 5.84113 4.47617 461 t - - T
+ 2.68631 4.42192 2.77519 2.73130 3.46353 2.40482 3.72508 3.29367 2.67738 2.69360 4.24703 2.90360 2.73753 3.18148 2.89804 2.37867 2.77518 2.98532 4.58490 3.61498
+ 0.12278 2.37863 3.77824 1.17468 0.36950 0.42506 1.06054
+ 251 1.47902 3.78300 4.72209 4.11644 2.74562 3.65840 4.38345 2.02614 3.93274 2.07959 3.21794 4.17061 3.49702 4.09137 3.99270 2.98272 3.05871 2.38788 4.48487 3.74373 467 a - - H
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01009 4.99737 5.71972 0.61958 0.77255 0.53813 0.87669
+ 252 2.38222 4.71734 2.84513 2.05232 4.42547 3.25385 3.43556 4.19285 2.14440 3.09056 3.51596 2.80436 3.18490 2.67888 2.63294 2.69832 2.67125 3.58577 5.80764 4.40015 468 e - - H
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01009 4.99737 5.71972 0.61958 0.77255 0.45436 1.00747
+ 253 2.65797 4.06542 2.63237 1.57032 4.71890 3.65831 3.45654 4.20087 2.52289 3.68238 4.00276 3.00654 3.59507 2.12286 2.86428 2.58695 3.11362 3.45316 5.81563 3.91003 469 e - - H
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 254 1.93383 3.77543 4.87213 4.26567 3.27005 3.35948 4.48352 1.60295 4.06924 1.71770 3.29328 4.28554 4.50523 4.21524 4.10410 3.45599 3.20183 2.00553 4.99383 3.81574 470 i - - H
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 255 2.91099 3.35807 4.39311 3.80506 3.12662 3.41984 4.32058 2.74098 2.62412 1.35983 2.89439 3.70896 4.38574 3.55146 3.43970 3.02120 3.14303 2.30767 4.99433 3.18557 471 l - - H
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 256 2.62697 4.23577 2.94369 2.01671 4.73311 3.52212 3.12192 4.21804 1.98366 3.41966 4.43054 2.33684 4.05005 2.29561 2.80226 2.65814 2.90658 3.41449 5.82302 4.41298 472 k - - T
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 5.01631 5.73865 0.61958 0.77255 0.48576 0.95510
+ 257 2.67425 5.24257 2.69003 2.64384 4.09422 3.68496 1.59772 3.97575 2.52719 3.06621 3.97630 3.17995 4.07682 2.88982 2.86815 2.31165 2.78826 3.60139 5.71188 4.10399 473 h - - S
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.18941 5.01631 1.79622 0.61958 0.77255 0.48576 0.95510
+ 258 2.81850 5.23743 2.76502 2.35780 4.54654 3.39495 3.79640 3.57339 2.36240 3.35446 4.28834 3.08690 1.61434 2.83455 2.79066 2.56844 3.04975 3.37601 5.69198 4.30446 474 p - - G
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01183 4.83873 5.56107 0.61958 0.77255 0.86853 0.54398
+ 259 3.22678 4.58175 4.94227 4.40609 1.73776 4.31983 4.20406 3.01156 4.21650 2.23279 3.33965 4.33985 4.66520 3.80636 4.24184 3.63704 3.45535 2.61441 1.69956 1.91736 475 w - - G
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01183 4.83873 5.56107 0.61958 0.77255 0.30436 1.33787
+ 260 2.99670 4.36610 4.95290 4.33956 1.72799 3.71830 4.50360 1.92619 4.12878 1.69258 2.79907 4.33234 4.52551 4.25179 4.13733 3.48573 3.22794 1.98896 4.25850 3.81122 476 l - - G
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00667 5.01308 * 0.61958 0.77255 0.00000 *
+//
--- /dev/null
+HMMER3/f [3.1b1 | May 2013]
+NAME fn3
+ACC PF00041.13
+DESC Fibronectin type III domain
+LENG 86
+ALPH amino
+RF no
+MM no
+CONS yes
+CS yes
+MAP yes
+DATE Fri Jun 20 08:22:31 2014
+NSEQ 106
+EFFN 11.415833
+CKSUM 3564431818
+GA 8.00 7.20
+TC 8.00 7.20
+NC 7.90 7.90
+STATS LOCAL MSV -9.4043 0.71847
+STATS LOCAL VITERBI -9.7737 0.71847
+STATS LOCAL FORWARD -3.8341 0.71847
+HMM A C D E F G H I K L M N P Q R S T V W Y
+ m->m m->i m->d i->m i->i d->m d->d
+ COMPO 2.70330 4.91262 3.03272 2.64079 3.60307 2.84344 3.74204 3.07942 2.79841 2.65364 4.14864 2.95826 2.87120 3.02176 2.96125 2.44783 2.59757 2.57680 4.02726 3.21526
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00338 6.08833 6.81068 0.61958 0.77255 0.00000 *
+ 1 3.16986 5.21447 4.52134 3.29953 4.34285 4.18764 4.30886 3.35801 3.70246 2.11675 4.32057 4.32984 0.76706 3.91880 4.22437 3.23552 3.21670 2.88223 5.80355 3.93889 1 p - - -
+ 2.68629 4.42236 2.77530 2.73088 3.46365 2.40512 3.72505 3.29365 2.67737 2.69316 4.24701 2.90358 2.73734 3.18157 2.89812 2.37898 2.77517 2.98515 4.58488 3.61514
+ 0.09796 2.38361 6.81068 0.10064 2.34607 0.48576 0.95510
+ 2 2.70230 5.97353 2.24744 2.62947 5.31433 2.60356 4.43584 4.79731 3.17221 2.95090 5.01531 3.26630 2.09873 3.30219 3.34190 1.45782 3.14099 3.57507 6.40877 4.25623 3 s - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00338 6.08833 6.81068 0.61958 0.77255 0.48576 0.95510
+ 3 1.38116 5.98285 3.50784 2.54546 5.32790 3.48945 4.43311 4.81385 2.38773 3.98773 5.02352 3.27895 1.92260 2.69012 2.96119 2.64228 3.29228 3.29618 6.41555 4.20553 4 a - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00338 6.08833 6.81068 0.61958 0.77255 0.48576 0.95510
+ 4 3.32856 5.10403 4.47046 4.60386 4.23079 4.75438 5.09647 2.69918 4.46632 2.97102 4.23502 4.77984 0.63388 4.68581 3.76781 4.05413 3.46306 2.04533 5.75329 4.56372 5 P - - -
+ 2.68616 4.42236 2.77530 2.73134 3.46365 2.40523 3.72505 3.29295 2.67751 2.69303 4.24634 2.90357 2.73739 3.18157 2.89783 2.37897 2.77530 2.98529 4.58488 3.61514
+ 0.09682 2.39494 6.81068 0.10162 2.33687 0.48576 0.95510
+ 5 2.95325 4.65976 3.57762 2.20709 3.14816 2.51487 3.41109 4.78902 2.65862 3.19599 4.41042 3.45032 3.44719 2.43205 2.26492 2.25400 2.23196 3.66828 4.80003 4.52485 7 e - - C
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01246 6.08833 4.59386 0.61958 0.77255 0.48576 0.95510
+ 6 2.74215 5.97618 2.19482 2.69150 4.58171 2.33553 3.83525 3.28222 2.95080 3.32698 5.01691 1.45822 3.52462 2.79670 2.90942 3.13467 3.27956 4.36668 6.40902 3.92307 8 n - - E
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00341 6.07928 6.80162 0.61958 0.77255 0.44282 1.02784
+ 7 3.32507 4.98102 3.78072 3.31043 2.85257 4.76439 5.09585 2.50332 4.69760 1.03851 3.36125 4.91001 2.73206 4.83820 4.72389 4.07376 3.83146 1.59790 5.60385 4.42704 9 l - - E
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.03752 6.08833 3.36505 0.61958 0.77255 0.48576 0.95510
+ 8 3.15997 4.90658 3.35204 2.72775 4.53493 3.60960 2.65074 3.69535 2.11078 4.01384 4.99896 3.14668 4.61695 2.40643 2.34723 1.92358 2.03982 3.05153 6.39127 4.98082 10 s - - E
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00349 6.05430 6.77664 0.61958 0.77255 0.35749 1.20207
+ 9 1.76295 3.98252 5.55061 4.93551 2.13202 3.39992 5.09294 2.14638 4.23898 2.23988 3.42109 4.92079 4.39252 3.70640 3.99349 3.50811 3.63432 1.47830 4.51148 4.41177 11 v - - E
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00338 6.08833 6.81068 0.61958 0.77255 0.48576 0.95510
+ 10 3.01387 4.98892 2.91217 2.42744 5.22342 4.00576 3.74074 2.67275 2.47618 2.92529 3.89570 3.36720 4.15809 3.26810 2.80854 1.81572 2.02040 2.77133 4.92415 4.31555 12 s - - E
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00338 6.08833 6.81068 0.61958 0.77255 0.48576 0.95510
+ 11 2.41247 5.98374 2.24093 2.04842 3.41543 2.59695 4.10033 4.81544 3.05501 4.28918 5.02429 2.22829 2.90635 3.12939 3.01921 2.37278 3.01194 3.02522 6.41619 3.66635 13 e - - E
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.06784 6.08833 2.75947 0.61958 0.77255 0.48576 0.95510
+ 12 2.77725 4.36386 3.23435 2.92496 4.75140 4.31852 4.53101 1.91389 3.01135 2.51491 3.47932 2.97934 3.54432 2.88257 2.68923 3.07794 2.71169 1.80880 6.06849 4.75973 14 v - - E
+ 2.68623 4.42259 2.77533 2.73059 3.46323 2.40500 3.72529 3.29333 2.67757 2.69369 4.24724 2.90364 2.73744 3.18108 2.89835 2.37891 2.77531 2.98493 4.58511 3.61510
+ 0.22113 1.62346 6.74643 0.44471 1.02446 0.29166 1.37446
+ 13 3.17575 5.97994 3.10322 2.84738 5.32369 2.00173 4.43389 4.80873 3.01150 3.75019 4.42663 2.23751 4.64014 2.74467 2.85546 1.99984 1.67133 4.36987 5.08444 3.58488 18 t - - C
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00338 6.08833 6.81068 0.61958 0.77255 0.48576 0.95510
+ 14 2.14203 5.98483 2.53686 2.20884 5.33077 2.76253 3.61799 4.81737 2.91636 3.96256 5.02525 2.79307 2.44932 3.35978 3.34773 1.76758 2.51815 4.12754 4.53404 4.35768 19 s - - T
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.02274 6.08833 3.90154 0.61958 0.77255 0.48576 0.95510
+ 15 3.45984 5.96297 2.32904 2.98671 5.30486 3.14893 3.59992 3.68067 2.95954 4.26690 5.00447 2.01875 4.62814 3.51950 2.89162 1.97303 1.47565 3.87160 6.39755 3.59993 20 t - - T
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00344 6.06904 6.79138 0.61958 0.77255 0.40302 1.10352
+ 16 2.82603 5.98256 2.96292 2.53617 4.39559 3.14388 4.09532 4.81336 2.59005 4.28779 5.02326 3.12547 4.63955 2.76620 3.03618 1.28432 2.14874 3.55065 4.82032 3.29405 21 s - - E
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00338 6.08833 6.81068 0.61958 0.77255 0.48576 0.95510
+ 17 2.29842 4.96481 5.56794 4.95172 2.45211 3.33868 4.31545 1.97312 4.73378 1.34355 2.88087 4.92903 5.12608 4.86259 4.73754 4.07438 3.55674 1.71344 5.58685 3.78328 22 l - - E
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00338 6.08833 6.81068 0.61958 0.77255 0.48576 0.95510
+ 18 2.99930 4.68496 3.44656 2.53427 3.92510 4.04338 3.13178 3.10095 3.07007 2.68343 3.58599 3.17010 4.15335 2.63450 2.71950 2.30083 2.03779 2.23518 4.92400 3.84991 23 t - - E
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00338 6.08833 6.81068 0.61958 0.77255 0.48576 0.95510
+ 19 3.61302 4.50726 5.99163 5.39935 2.74200 5.23506 5.61087 1.85210 5.20622 1.10188 3.56291 5.40353 5.56305 5.33364 5.22134 4.56441 3.85751 1.20867 6.05610 4.88933 24 l - - E
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00338 6.08833 6.81068 0.61958 0.77255 0.48576 0.95510
+ 20 2.90508 5.98486 3.37356 2.37027 5.33083 3.46854 3.40789 4.81743 2.65230 3.22177 4.17825 2.67373 4.63906 2.52648 2.39431 1.50547 2.16764 4.37598 5.01440 5.00552 25 s - - E
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00338 6.08833 6.81068 0.61958 0.77255 0.48576 0.95510
+ 21 5.54218 6.63564 6.83891 6.61797 2.57168 6.35073 5.30532 3.96643 6.37377 3.18917 5.26281 6.07009 4.35269 6.11992 6.21105 5.74680 5.75143 4.86346 0.24436 3.66807 26 W - - E
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00338 6.08833 6.81068 0.61958 0.77255 0.48576 0.95510
+ 22 3.10862 5.98423 2.61761 2.10221 4.46995 3.93009 3.84182 3.79843 2.19229 3.09373 4.47555 2.66452 4.06864 2.59255 2.99987 1.99073 2.05618 3.67318 6.41655 4.47364 27 s - - E
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00338 6.08833 6.81068 0.61958 0.77255 0.48576 0.95510
+ 23 2.05280 5.87614 3.77610 2.63103 5.17655 3.25143 3.55897 3.09279 2.68152 3.35866 4.92882 3.43937 1.44938 3.29932 2.98336 2.85751 2.78420 3.02863 4.43359 4.47040 28 p - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00338 6.08833 6.81068 0.61958 0.77255 0.48576 0.95510
+ 24 2.65644 5.88726 3.37601 2.96202 5.19190 3.53629 4.46143 4.20046 2.87295 2.91429 4.93884 3.27084 1.07653 3.39095 3.69926 2.07705 3.29723 2.92337 6.34501 4.95985 29 p - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.32165 6.08833 1.29911 0.61958 0.77255 0.48576 0.95510
+ 25 2.44244 5.77880 2.64467 2.21733 3.20572 3.66340 3.27861 4.60939 2.17717 2.95495 4.81953 3.17778 2.62084 2.96028 2.64039 2.55818 2.51134 3.52175 6.21164 4.20060 30 k - - S
+ 2.68557 4.42278 2.77404 2.73101 3.46370 2.40555 3.72548 3.29364 2.67779 2.69337 4.24743 2.90378 2.73741 3.18051 2.89835 2.37928 2.77557 2.98526 4.58530 3.61392
+ 1.12909 0.74203 1.60680 0.24883 1.51281 1.67198 0.20810
+ 26 2.76497 5.64634 2.06362 2.44254 4.06108 3.91520 3.28362 3.73992 2.46695 3.95074 4.68755 2.93859 2.87257 2.71813 3.08100 2.16767 2.28242 3.00778 6.08028 4.00221 33 d - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00580 5.54941 6.27176 0.61958 0.77255 1.23854 0.34222
+ 27 2.94904 4.81418 2.88265 2.99332 4.83563 1.49306 3.87927 3.68299 2.59086 2.53757 4.07313 2.89409 2.92833 3.04624 2.88166 2.82744 3.22994 3.21444 4.18838 4.04981 34 g - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00508 5.68074 6.40309 0.61958 0.77255 0.20085 1.70396
+ 28 2.96588 5.95917 2.45759 2.65943 5.30490 1.91234 3.11781 3.44164 2.78003 4.01788 4.99965 2.12379 3.26764 2.84040 2.87160 2.26272 3.15721 3.84740 4.86821 3.64128 35 g - - S
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00351 6.05095 6.77330 0.61958 0.77255 0.34864 1.22298
+ 29 2.45969 5.96445 2.88574 2.61716 5.30131 1.53630 4.43818 3.46883 2.98393 3.60366 4.33332 3.25719 4.28257 3.08417 2.40821 2.08539 3.20111 2.81105 6.40207 4.25093 36 g - - S
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00338 6.08833 6.81068 0.61958 0.77255 0.48576 0.95510
+ 30 2.71563 5.98438 2.50720 1.96228 5.33013 3.47246 3.38617 3.68065 2.34086 4.03521 4.36775 3.08029 1.87041 2.90329 3.33287 2.70645 2.77558 2.97286 6.41666 4.17777 37 p - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00338 6.08833 6.81068 0.61958 0.77255 0.48576 0.95510
+ 31 3.04837 4.96747 2.67316 4.92527 2.42064 4.14655 5.09097 1.34551 4.71334 2.18068 3.34829 4.91585 3.31178 4.15082 4.72663 3.69906 3.53551 1.88881 3.93067 3.04034 38 i - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00338 6.08833 6.81068 0.61958 0.77255 0.48576 0.95510
+ 32 2.89418 4.58676 2.12720 2.65970 3.99748 4.30700 4.50689 3.12934 2.75241 2.32504 4.34805 3.25317 4.69765 2.93544 2.97945 2.48570 1.85268 2.60501 5.05387 4.40931 39 t - - S
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00338 6.08833 6.81068 0.61958 0.77255 0.48576 0.95510
+ 33 3.05045 5.96458 3.15002 2.79713 4.16491 1.56242 3.20986 4.07540 2.34002 3.77648 3.66616 2.65073 4.64351 3.21500 2.62101 2.34442 2.98761 3.25677 5.04578 3.36446 40 g - - E
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00338 6.08833 6.81068 0.61958 0.77255 0.48576 0.95510
+ 34 4.72855 5.99332 6.32397 5.91516 1.75259 5.71064 3.47111 3.64093 3.68669 3.44300 5.13564 5.60513 6.03397 5.64902 5.63703 5.05114 4.95149 3.46344 3.97019 0.49348 41 Y - - E
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00338 6.08833 6.81068 0.61958 0.77255 0.48576 0.95510
+ 35 3.03913 5.98101 2.74983 1.95825 3.75604 3.98121 3.78677 3.48894 2.41418 2.89991 5.02189 2.66693 4.63989 2.65222 2.20113 2.26435 2.64729 3.16844 6.41420 3.93691 42 e - - E
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00338 6.08833 6.81068 0.61958 0.77255 0.48576 0.95510
+ 36 3.75576 5.90373 6.92143 6.48083 5.27028 6.48043 7.33031 1.16190 6.46559 1.72148 4.18143 6.65320 6.63807 6.70678 6.63399 5.94811 5.00240 0.82398 7.51298 6.31097 43 v - - E
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.04904 6.08833 3.08806 0.61958 0.77255 0.48576 0.95510
+ 37 2.63429 4.71789 2.89387 2.04081 4.17861 4.22097 3.38514 2.92734 2.36124 3.26230 4.97143 3.69265 4.61418 2.27063 2.38238 2.70982 2.11937 3.37005 6.36711 3.73375 44 e - - E
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00353 6.04282 6.76517 0.61958 0.77255 0.32899 1.27173
+ 38 3.00800 2.48193 5.53105 4.91728 2.98458 4.75707 4.15268 2.83469 3.12355 2.32451 4.08737 4.91198 5.12099 4.84273 3.46182 3.58557 3.26283 2.28912 2.64554 1.29971 45 y - - E
+ 2.68641 4.42053 2.77543 2.73091 3.46377 2.40536 3.72420 3.29377 2.67764 2.69378 4.24582 2.90336 2.73763 3.18113 2.89660 2.37910 2.77543 2.98542 4.58500 3.61526
+ 0.12278 2.16768 6.81068 0.54422 0.86820 0.48576 0.95510
+ 39 2.52553 4.02469 3.60093 2.65311 4.18239 3.63052 4.17989 3.44209 2.14970 3.12319 4.96260 3.43770 4.02454 2.12722 2.15391 2.32250 3.25888 3.40611 2.73453 3.57446 49 q - - E
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.02932 6.08833 3.62591 0.61958 0.77255 0.48576 0.95510
+ 40 2.85303 5.96779 2.74660 1.91867 5.31393 3.60453 3.59476 4.33679 2.36399 3.57280 3.62613 2.83996 2.06170 2.51716 3.24767 2.43993 2.61505 3.39964 6.39984 4.98824 50 e - - E
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00347 6.06248 6.78482 0.61958 0.77255 0.67944 0.70705
+ 41 2.55267 3.11480 2.72137 2.31006 5.21613 3.67111 4.08491 3.18721 2.11932 2.73126 3.73119 3.72342 3.44703 2.78931 3.31632 2.60923 2.50487 2.33623 6.34948 4.95631 51 k - - T
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.09789 6.06248 2.39773 0.61958 0.77255 0.38130 1.14877
+ 42 3.41114 5.92195 2.00739 2.51445 4.35946 1.85149 4.04885 4.75310 3.02073 3.41727 4.96259 1.88803 4.57836 2.81891 2.77402 2.53317 2.79169 3.60394 6.35459 4.48731 52 g - - T
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00370 5.99676 6.71911 0.61958 0.77255 0.25112 1.50474
+ 43 2.89692 5.98568 2.39354 2.04021 5.33202 2.12548 3.27810 4.81889 2.36649 3.39071 4.58505 2.82477 4.63888 2.99231 3.02264 2.04514 2.45319 3.82791 6.41761 5.00590 53 e - - T
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00338 6.08833 6.81068 0.61958 0.77255 0.48576 0.95510
+ 44 3.10206 5.95088 3.50928 2.19657 4.70794 1.83640 4.44201 3.85177 2.81849 3.20653 3.64542 2.17673 2.82486 2.50236 3.67274 2.64718 2.71954 3.18909 6.39210 3.73228 54 g - - C
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.08059 6.08833 2.58819 0.61958 0.77255 0.48576 0.95510
+ 45 2.83017 5.93388 2.31048 1.94273 5.28007 2.46456 3.60606 4.35357 2.35448 2.95362 4.97424 3.06816 3.41033 2.69285 2.84649 2.21743 2.98206 3.67978 4.23187 4.95426 55 e - - C
+ 2.68733 4.40831 2.77609 2.73043 3.46444 2.40393 3.72592 3.29278 2.67833 2.69426 4.24827 2.90407 2.73626 3.18024 2.89744 2.37952 2.77650 2.98614 4.58019 3.61570
+ 1.45631 0.90375 1.01651 1.51529 0.24813 0.96821 0.47765
+ 46 2.32839 5.42660 2.93163 2.28220 4.02543 3.04571 3.03894 3.22247 2.82753 3.21315 3.89864 3.49093 2.50859 3.14260 2.89921 2.69284 3.05772 2.38519 4.38264 3.20345 66 e - - G
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00571 5.56406 6.28641 0.61958 0.77255 0.18459 1.78051
+ 47 2.69465 3.91083 2.42967 2.34662 4.43247 3.13708 3.62175 3.49809 2.56727 2.84127 4.03266 3.52527 3.00745 3.22895 3.52756 2.46523 2.69768 3.11906 2.19019 4.92515 67 w - - C
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00353 6.04443 6.76678 0.61958 0.77255 0.33269 1.26228
+ 48 2.67627 5.86490 3.17099 3.22595 3.40616 4.27494 3.15476 3.07365 2.21494 2.78239 4.39426 2.30764 3.56160 2.19351 2.71433 2.94392 2.62330 2.55032 5.16850 4.37026 68 q - - E
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00338 6.08833 6.81068 0.61958 0.77255 0.48576 0.95510
+ 49 3.05871 5.98132 3.36643 1.71285 5.32569 3.90513 2.27648 4.25125 2.92072 4.28630 4.28595 2.90579 3.33969 2.79371 2.63337 2.42582 2.46361 2.81009 3.46671 3.72048 69 e - - E
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00338 6.08833 6.81068 0.61958 0.77255 0.48576 0.95510
+ 50 2.88323 4.65127 3.40086 2.73607 2.41972 3.62669 3.91044 2.52424 2.75640 2.37424 3.94274 3.64921 4.76561 2.38668 2.64750 3.03028 3.09193 2.27100 6.08057 3.03402 70 v - - E
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00338 6.08833 6.81068 0.61958 0.77255 0.48576 0.95510
+ 51 3.36533 5.95840 2.65995 2.86095 3.44584 4.25167 3.55888 2.90987 2.78397 3.33346 3.90493 2.03375 3.68901 2.80089 2.78508 2.11531 1.97302 3.15541 6.39763 4.99330 71 t - - E
+ 2.68571 4.42246 2.77540 2.73144 3.46375 2.40497 3.72515 3.29375 2.67742 2.69376 4.24711 2.90367 2.73710 3.18135 2.89822 2.37876 2.77540 2.98457 4.58498 3.61524
+ 0.06628 2.76409 6.81068 0.97562 0.47314 0.48576 0.95510
+ 52 2.38926 5.49703 3.09615 2.80044 4.68202 3.76562 4.62096 2.19958 3.33274 2.03099 4.11871 2.97731 4.26404 3.83080 2.89542 3.19964 2.84193 1.56133 6.03936 4.75239 75 v - - E
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00338 6.08833 6.81068 0.61958 0.77255 0.48576 0.95510
+ 53 2.79501 4.92737 2.35659 2.60299 4.06511 2.98090 3.88301 4.80087 2.44593 3.57653 5.01701 3.37711 1.76863 3.53250 3.23955 1.94419 2.68524 2.95506 6.41016 5.00121 76 p - - E
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00338 6.08833 6.81068 0.61958 0.77255 0.48576 0.95510
+ 54 2.44542 5.98316 3.18675 2.55065 5.32835 2.12386 4.43300 4.38419 2.38413 2.93654 5.02378 2.50193 2.49139 3.27226 2.05133 2.36069 3.70337 4.12664 4.32391 4.48343 77 r - - T
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00338 6.08833 6.81068 0.61958 0.77255 0.48576 0.95510
+ 55 2.77179 5.98329 2.50848 2.76644 5.32854 3.30269 3.08416 4.38434 3.16759 4.28865 5.02390 2.27915 2.67265 2.61285 3.32102 2.18277 1.82444 2.83013 6.41587 4.35727 78 t - - T
+ 2.68621 4.42251 2.77546 2.73149 3.46380 2.40468 3.72521 3.29380 2.67767 2.69252 4.24716 2.90344 2.73766 3.18134 2.89827 2.37913 2.77442 2.98545 4.58503 3.61529
+ 0.07130 2.69245 6.81068 1.11635 0.39671 0.48576 0.95510
+ 56 2.32530 5.97446 3.57954 1.89562 5.31575 4.24796 3.32554 3.73278 2.42253 2.98562 5.01611 3.71687 3.10116 2.71107 2.91871 2.60336 1.70360 3.15915 6.40941 5.00074 83 t - - T
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.35248 6.08833 1.22151 0.61958 0.77255 0.48576 0.95510
+ 57 2.95924 5.72336 2.75932 2.63159 3.96190 3.29462 3.22449 3.40062 2.77057 3.18108 3.56769 2.46117 2.98702 3.05715 2.72729 2.56520 1.96589 3.52719 6.16591 2.96938 84 t - - S
+ 2.68622 4.42162 2.77539 2.73088 3.46349 2.40510 3.72514 3.29311 2.67761 2.69358 4.24710 2.90367 2.73759 3.18166 2.89753 2.37894 2.77488 2.98538 4.58497 3.61523
+ 0.23969 1.55321 6.46298 0.15973 1.91309 0.51157 0.91517
+ 58 2.78411 5.86726 3.65151 2.46190 3.55121 3.32277 3.71415 3.82816 2.87545 3.69015 4.27003 2.90512 3.60994 2.68731 2.37548 1.72361 1.95655 3.42914 6.30822 3.85760 87 s - - E
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00384 5.96109 6.68344 0.61958 0.77255 0.21363 1.64843
+ 59 2.13080 3.38910 5.56698 4.95075 2.41578 4.20194 3.39215 2.83299 4.73282 2.14660 3.19234 4.92810 5.12527 4.86169 4.18461 4.07348 3.03808 1.63705 4.66089 1.78369 88 v - - E
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00338 6.08833 6.81068 0.61958 0.77255 0.48576 0.95510
+ 60 3.12543 5.93769 2.99354 2.53954 5.26303 4.25659 3.21054 2.85212 2.62935 2.82513 3.45830 2.90110 4.19559 2.80624 3.10357 2.88568 1.50190 2.67316 6.38237 3.93622 89 t - - E
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00338 6.08833 6.81068 0.61958 0.77255 0.48576 0.95510
+ 61 3.61965 4.99402 3.63828 4.95783 2.26826 4.79135 5.12555 1.86647 4.74679 1.34194 3.74460 4.94944 5.15281 3.10559 4.75989 3.74420 3.85186 1.42486 5.61987 4.44474 90 l - - E
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00338 6.08833 6.81068 0.61958 0.77255 0.48576 0.95510
+ 62 3.10387 5.98366 3.06368 2.31445 4.05906 3.57903 3.48488 4.81531 2.43543 4.01680 3.91148 2.67498 2.99920 2.70828 2.56621 2.14984 1.90367 3.06274 4.55677 4.37671 91 t - - E
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00338 6.08833 6.81068 0.61958 0.77255 0.48576 0.95510
+ 63 3.34220 5.98744 1.86090 2.69096 5.33359 1.40608 3.63608 4.82043 2.48624 4.29318 4.45099 1.96888 4.06897 3.19339 3.48838 2.73868 3.70514 4.37867 6.41942 4.25681 92 g - - S
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00338 6.08833 6.81068 0.61958 0.77255 0.48576 0.95510
+ 64 5.18530 6.36522 4.58586 6.57578 3.53131 6.59442 6.84537 2.81242 6.44067 0.21363 3.54046 6.78308 6.53953 6.19263 6.31583 5.99910 5.37457 3.39834 6.73440 5.83217 93 L - - -
+ 2.68590 4.42227 2.77521 2.73125 3.46356 2.40515 3.72496 3.29356 2.67743 2.69357 4.24692 2.90349 2.73741 3.18148 2.89803 2.37889 2.77521 2.98520 4.58479 3.61505
+ 0.02033 3.96193 6.81068 0.31431 1.31041 0.48576 0.95510
+ 65 2.93361 5.98253 3.16620 2.07447 5.32745 3.84017 3.84639 3.52003 2.07989 2.71701 4.56317 3.05465 3.94228 2.39023 2.13660 2.81003 2.42767 2.98359 6.41531 3.87097 95 e - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00338 6.08833 6.81068 0.61958 0.77255 0.48576 0.95510
+ 66 2.17452 5.85112 3.79178 2.44872 5.14174 4.27993 4.47388 4.59086 3.04069 4.13287 4.42378 3.36057 0.82761 3.31072 3.71538 3.13243 3.15654 3.97958 4.90439 4.38214 96 p - - T
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00338 6.08833 6.81068 0.61958 0.77255 0.48576 0.95510
+ 67 2.72531 5.97666 2.50761 2.79752 4.22378 1.29966 2.70734 4.80294 2.85170 4.02964 5.01805 2.59981 4.64085 3.32835 3.25617 2.51345 3.59137 3.91820 4.88800 2.97800 97 g - - T
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00338 6.08833 6.81068 0.61958 0.77255 0.48576 0.95510
+ 68 2.39925 4.86641 3.79312 2.74568 5.13568 4.27988 3.97435 3.95098 2.69562 3.65359 3.00813 3.38952 4.67180 3.12070 2.33490 2.43668 1.27713 2.90106 6.31421 4.93977 98 t - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00338 6.08833 6.81068 0.61958 0.77255 0.48576 0.95510
+ 69 2.87821 5.98261 2.71299 2.05681 3.93787 3.36966 3.57296 3.81023 2.25993 3.03102 3.49917 2.39917 3.09415 2.62154 2.82818 2.67359 2.51409 3.67730 4.58228 5.00448 99 e - - E
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00338 6.08833 6.81068 0.61958 0.77255 0.48576 0.95510
+ 70 6.32206 7.09639 6.95855 7.01624 2.70399 6.62558 5.12529 5.84365 6.77161 4.03604 6.32463 4.32154 6.86163 6.30239 6.48747 6.05185 6.49899 5.81871 5.18730 0.14189 100 Y - - E
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00338 6.08833 6.81068 0.61958 0.77255 0.48576 0.95510
+ 71 3.06725 5.97020 3.56838 1.93769 4.23056 3.77167 3.39655 3.53252 2.56448 3.45405 4.47893 2.47898 4.64226 2.55695 2.74362 2.36648 2.01401 2.66399 6.40629 3.70776 101 e - - E
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00338 6.08833 6.81068 0.61958 0.77255 0.48576 0.95510
+ 72 3.19486 4.19171 5.58508 4.96942 1.44027 4.15574 5.11433 1.81297 4.75161 2.09873 3.37140 4.94615 5.14143 4.88008 4.75485 4.09123 3.83769 1.47173 5.60267 3.09551 102 f - - E
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00338 6.08833 6.81068 0.61958 0.77255 0.48576 0.95510
+ 73 3.18039 4.06436 3.15201 2.27681 5.32468 3.77041 3.95744 3.70705 2.23538 4.28548 4.11883 2.88564 4.63997 2.58030 1.70576 2.27707 2.39981 3.62914 4.03739 3.61343 103 r - - E
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00338 6.08833 6.81068 0.61958 0.77255 0.48576 0.95510
+ 74 3.76685 5.84337 6.79391 6.31497 3.84743 6.27452 6.95358 1.59565 6.25134 2.11498 4.30213 6.44619 6.46746 6.44080 6.36566 5.70153 4.90672 0.53161 7.20703 6.03175 104 V - - E
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00338 6.08833 6.81068 0.61958 0.77255 0.48576 0.95510
+ 75 2.31005 4.88319 3.40675 2.63903 3.58848 4.26911 3.49342 3.09105 2.39543 3.00463 4.93879 3.41670 4.66153 1.98639 2.22144 3.11070 2.61129 2.78609 6.34491 2.92043 105 q - - E
+ 2.68621 4.42228 2.77522 2.73126 3.46357 2.40516 3.72497 3.29357 2.67744 2.69312 4.24693 2.90350 2.73743 3.18149 2.89804 2.37890 2.77522 2.98521 4.58480 3.61506
+ 0.03738 3.58894 4.70319 0.25135 1.50394 0.48576 0.95510
+ 76 0.79499 5.17226 4.80437 3.93376 4.33120 3.17569 4.96596 3.30029 4.15773 2.86829 4.32533 4.52823 5.01384 4.41886 4.42465 2.28661 2.19420 2.76335 5.81537 4.60940 107 a - - E
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00340 6.08033 6.80268 0.61958 0.77255 0.44741 1.01966
+ 77 2.84306 4.15407 4.98296 3.19564 3.23517 4.66606 3.67524 2.49603 3.23224 2.21212 3.84796 4.62630 5.03633 2.88555 2.43211 3.49088 3.22704 1.33993 5.67363 2.88123 108 v - - E
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00338 6.08833 6.81068 0.61958 0.77255 0.48576 0.95510
+ 78 3.27061 4.75060 2.81965 3.10410 5.31934 3.95942 3.99367 3.88107 2.62205 4.02823 5.01830 1.35628 3.08534 3.32913 3.08546 1.88067 2.21938 4.02145 6.41122 3.76470 109 n - - E
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00992 6.08833 4.87890 0.61958 0.77255 0.48576 0.95510
+ 79 2.39836 4.69624 2.57939 2.56364 4.72011 1.55094 3.74815 4.26504 2.61409 4.28517 5.02018 2.82673 4.26340 2.69971 2.87382 2.73983 2.53993 3.07568 6.41202 5.00074 110 g - - T
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00340 6.08180 6.80415 0.61958 0.77255 0.45398 1.00812
+ 80 2.22211 4.94595 2.69424 2.44928 4.84552 2.32005 3.06335 2.95704 2.33976 3.55821 4.09648 2.87488 4.09930 2.85656 2.97877 3.08279 3.07714 2.39346 6.40553 4.01548 111 a - - T
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.38398 6.08833 1.15015 0.61958 0.77255 0.48576 0.95510
+ 81 2.96920 5.43248 3.46409 2.76236 3.93019 1.02513 4.29951 4.07917 3.10833 3.39330 4.50784 3.40559 4.48149 3.45547 3.56956 2.50552 2.39680 3.76237 5.94228 3.01765 112 g - - E
+ 2.68652 4.42259 2.77488 2.73144 3.46170 2.40466 3.72529 3.29388 2.67703 2.69373 4.24724 2.90335 2.73774 3.18162 2.89801 2.37895 2.77529 2.98552 4.58511 3.61537
+ 0.29928 1.35852 6.43163 0.48724 0.95274 1.77816 0.18506
+ 82 2.84273 4.18992 3.05053 2.12883 3.36284 2.75189 4.25559 3.03507 2.66396 2.65563 4.59024 2.63081 3.84786 2.76844 3.19058 2.84597 2.82776 2.89016 3.06821 3.41272 117 e - - E
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00494 5.70928 6.43163 0.61958 0.77255 1.56406 0.23482
+ 83 3.37920 5.61493 3.74277 3.20384 4.92800 1.01625 3.96683 4.35082 2.94708 2.91738 4.72998 3.71516 3.70329 3.52945 3.00683 1.61777 3.61882 4.00263 6.13360 4.80162 118 g - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00481 5.73459 6.45693 0.61958 0.77255 0.30535 1.33510
+ 84 2.58463 5.93784 3.04102 2.09605 4.57465 2.51630 3.24109 4.26208 2.60545 3.44607 3.62705 3.20484 1.89678 2.68661 2.74662 2.97880 3.02092 3.23569 6.37074 4.50367 119 p - - E
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00361 6.02233 6.74467 0.61958 0.77255 0.28862 1.38348
+ 85 2.48488 5.72055 3.87501 1.97538 3.04853 3.48010 4.51877 3.51898 2.88839 2.73568 4.42660 3.64380 2.08811 3.48814 2.70856 2.40769 2.92982 4.05679 2.77386 3.43366 120 e - - B
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00338 6.08833 6.81068 0.61958 0.77255 0.48576 0.95510
+ 86 3.03720 5.94099 3.75455 2.96917 5.26587 2.91682 3.66571 4.11840 2.98472 4.23738 4.98891 3.74380 4.66031 3.40955 3.12788 0.72443 2.46104 4.32115 6.38683 4.99111 121 s - - E
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00227 6.08723 * 0.61958 0.77255 0.00000 *
+//
import org.testng.Assert;
import org.testng.AssertJUnit;
+import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import jalview.datamodel.AlignmentI;
import jalview.datamodel.DBRefEntry;
import jalview.datamodel.GeneLocus;
+import jalview.datamodel.HiddenMarkovModel;
import jalview.datamodel.HiddenSequences;
import jalview.datamodel.Mapping;
import jalview.datamodel.PDBEntry;
import jalview.datamodel.features.FeatureMatcherSet;
import jalview.datamodel.features.FeatureMatcherSetI;
import jalview.gui.AlignFrame;
-import jalview.gui.AlignViewport;
import jalview.gui.AlignmentPanel;
import jalview.gui.Desktop;
import jalview.gui.JvOptionPane;
import jalview.viewmodel.AlignmentViewport;
import jalview.viewmodel.seqfeatures.FeatureRendererModel;
+import junit.extensions.PA;
+
@Test(singleThreaded = true)
public class Jalview2xmlTests extends Jalview2xmlBase
{
+ @AfterMethod(alwaysRun = true)
+ public void tearDown()
+ {
+ Desktop.getInstance().closeAll_actionPerformed(null);
+ }
@Override
@BeforeClass(alwaysRun = true)
DataSourceType.FILE);
assertNotNull(af, "Didn't read input file " + inFile);
af.loadJalviewDataFile(inAnnot, DataSourceType.FILE, null, null);
- AlignViewport viewport = af.getViewport();
+ AlignViewportI viewport = af.getViewport();
assertSame(viewport.getGlobalColourScheme().getClass(),
TCoffeeColourScheme.class, "Didn't set T-coffee colourscheme");
assertNotNull(
AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
"examples/exampleFile_2_7.jar", DataSourceType.FILE);
assertNotNull(af, "Didn't read in the example file correctly.");
- assertTrue(Desktop.getAlignFrames().length == 1 + origCount,
+ assertEquals(Desktop.getAlignFrames().length,
+ 1 + origCount,
"Didn't gather the views in the example file.");
-
}
/**
@Test(groups = { "Functional" }, enabled = true)
public void testStoreAndRecoverExpandedviews() throws Exception
{
- Desktop.instance.closeAll_actionPerformed(null);
+ Desktop.getInstance().closeAll_actionPerformed(null);
AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
"examples/exampleFile_2_7.jar", DataSourceType.FILE);
{
Assert.fail("Didn't save the expanded view state", e);
}
- Desktop.instance.closeAll_actionPerformed(null);
+ Desktop.getInstance().closeAll_actionPerformed(null);
if (Desktop.getAlignFrames() != null)
{
Assert.assertEquals(Desktop.getAlignFrames().length, 0);
@Test(groups = { "Functional" })
public void testStoreAndRecoverReferenceSeqSettings() throws Exception
{
- Desktop.instance.closeAll_actionPerformed(null);
+ Desktop.getInstance().closeAll_actionPerformed(null);
AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
"examples/exampleFile_2_7.jar", DataSourceType.FILE);
assertNotNull(af, "Didn't read in the example file correctly.");
{
Assert.fail("Didn't save the expanded view state", e);
}
- Desktop.instance.closeAll_actionPerformed(null);
+ Desktop.getInstance().closeAll_actionPerformed(null);
if (Desktop.getAlignFrames() != null)
{
Assert.assertEquals(Desktop.getAlignFrames().length, 0);
@Test(groups = { "Functional" })
public void testStoreAndRecoverGroupRepSeqs() throws Exception
{
- Desktop.instance.closeAll_actionPerformed(null);
+ Desktop.getInstance().closeAll_actionPerformed(null);
AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
"examples/uniref50.fa", DataSourceType.FILE);
assertNotNull(af, "Didn't read in the example file correctly.");
{
Assert.fail("Didn't save the expanded view state", e);
}
- Desktop.instance.closeAll_actionPerformed(null);
+ Desktop.getInstance().closeAll_actionPerformed(null);
if (Desktop.getAlignFrames() != null)
{
Assert.assertEquals(Desktop.getAlignFrames().length, 0);
@Test(groups = { "Functional" })
public void testStoreAndRecoverPDBEntry() throws Exception
{
- Desktop.instance.closeAll_actionPerformed(null);
+ Desktop.getInstance().closeAll_actionPerformed(null);
String exampleFile = "examples/3W5V.pdb";
AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(exampleFile,
DataSourceType.FILE);
{
Assert.fail("Didn't save the state", e);
}
- Desktop.instance.closeAll_actionPerformed(null);
+ Desktop.getInstance().closeAll_actionPerformed(null);
if (Desktop.getAlignFrames() != null)
{
Assert.assertEquals(Desktop.getAlignFrames().length, 0);
@Test(groups = { "Functional" })
public void testStoreAndRecoverColourThresholds() throws IOException
{
- Desktop.instance.closeAll_actionPerformed(null);
+ Desktop.getInstance().closeAll_actionPerformed(null);
AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
"examples/uniref50.fa", DataSourceType.FILE);
- AlignViewport av = af.getViewport();
+ AlignViewportI av = af.getViewport();
AlignmentI al = av.getAlignment();
/*
".jvp");
tfile.deleteOnExit();
new Jalview2XML(false).saveState(tfile);
- Desktop.instance.closeAll_actionPerformed(null);
+ Desktop.getInstance().closeAll_actionPerformed(null);
af = new FileLoader().LoadFileWaitTillLoaded(tfile.getAbsolutePath(),
DataSourceType.FILE);
Assert.assertNotNull(af, "Failed to reload project");
}
/**
+ * Load an HMM profile to an alignment, and confirm it is correctly restored
+ * when reloaded from project
+ *
+ * @throws IOException
+ */
+ @Test(groups = { "Functional" })
+ public void testStoreAndRecoverHmmProfile() throws IOException
+ {
+ Desktop.getInstance().closeAll_actionPerformed(null);
+ AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
+ "examples/uniref50.fa", DataSourceType.FILE);
+
+ AlignViewportI av = af.getViewport();
+ AlignmentI al = av.getAlignment();
+
+ /*
+ * mimic drag and drop of hmm file on to alignment
+ */
+ AlignFrame af2 = new FileLoader().LoadFileWaitTillLoaded(
+ "examples/uniref50.hmm", DataSourceType.FILE);
+ al.insertSequenceAt(0,
+ af2.getViewport().getAlignment().getSequenceAt(0));
+
+ /*
+ * check it loaded in
+ */
+ SequenceI hmmSeq = al.getSequenceAt(0);
+ assertTrue(hmmSeq.hasHMMProfile());
+ HiddenMarkovModel hmm = hmmSeq.getHMM();
+ assertSame(hmm.getConsensusSequence(), hmmSeq);
+
+ /*
+ * save project, close windows, reload project, verify
+ */
+ File tfile = File.createTempFile("testStoreAndRecoverHmmProfile",
+ ".jvp");
+ tfile.deleteOnExit();
+ new Jalview2XML(false).saveState(tfile);
+ Desktop.getInstance().closeAll_actionPerformed(null);
+ af = new FileLoader().LoadFileWaitTillLoaded(tfile.getAbsolutePath(),
+ DataSourceType.FILE);
+ Assert.assertNotNull(af, "Failed to reload project");
+
+ hmmSeq = al.getSequenceAt(0);
+ assertTrue(hmmSeq.hasHMMProfile());
+ assertSame(hmm.getConsensusSequence(), hmmSeq);
+ Mapping mapToHmmConsensus = (Mapping) PA.getValue(hmm,
+ "mapToHmmConsensus");
+ assertNotNull(mapToHmmConsensus);
+ assertSame(mapToHmmConsensus.getTo(), hmmSeq.getDatasetSequence());
+ }
+
+ /**
* pre 2.11 - jalview 2.10 erroneously created new dataset entries for each
* view (JAL-3171) this test ensures we can import and merge those views
*/
@Test(groups = { "Functional" })
public void testMergeDatasetsforManyViews() throws IOException
{
- Desktop.instance.closeAll_actionPerformed(null);
+ Desktop.getInstance().closeAll_actionPerformed(null);
// complex project - one dataset, several views on several alignments
AlignFrame af = new FileLoader(false).LoadFileWaitTillLoaded(
@Test(groups = "Functional")
public void testPcaViewAssociation() throws IOException
{
- Desktop.instance.closeAll_actionPerformed(null);
+ Desktop.getInstance().closeAll_actionPerformed(null);
final String PCAVIEWNAME = "With PCA";
// create a new tempfile
File tempfile = File.createTempFile("jvPCAviewAssoc", "jvp");
}
// load again.
- Desktop.instance.closeAll_actionPerformed(null);
+ Desktop.getInstance().closeAll_actionPerformed(null);
AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
tempfile.getCanonicalPath(), DataSourceType.FILE);
- JInternalFrame[] frames = Desktop.instance.getAllFrames();
+ JInternalFrame[] frames = Desktop.getInstance().getAllFrames();
// PCA and the tabbed alignment view should be the only two windows on the
// desktop
assertEquals(frames.length, 2,
@Test(groups = { "Functional" })
public void testStoreAndRecoverGeneLocus() throws Exception
{
- Desktop.instance.closeAll_actionPerformed(null);
+ Desktop.getInstance().closeAll_actionPerformed(null);
String seqData = ">P30419\nACDE\n>X1235\nGCCTGTGACGAA";
AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(seqData,
DataSourceType.PASTE);
{
Assert.fail("Didn't save the state", e);
}
- Desktop.instance.closeAll_actionPerformed(null);
+ Desktop.getInstance().closeAll_actionPerformed(null);
new FileLoader().LoadFileWaitTillLoaded(tfile.getAbsolutePath(),
DataSourceType.FILE);
import static org.testng.AssertJUnit.assertEquals;
+import jalview.api.AlignViewportI;
import jalview.bin.Cache;
import jalview.datamodel.Alignment;
import jalview.datamodel.AlignmentI;
import jalview.schemes.ColourSchemeI;
import jalview.schemes.UserColourScheme;
import jalview.schemes.ZappoColourScheme;
-
import java.awt.Color;
import java.util.ArrayList;
{
SequenceI seq = new Sequence("name", "MA--TVLGSPRAPAFF");
AlignmentI al = new Alignment(new SequenceI[] { seq });
- final AlignViewport av = new AlignViewport(al);
+ final AlignViewportI av = new AlignViewport(al);
ResidueColourFinder rcf = new OverviewResColourFinder();
// gaps are grey, residues white
SequenceI seq = new Sequence("name", "MAT--GSPRAPAFF"); // FER1_MAIZE... + a
// gap
AlignmentI al = new Alignment(new SequenceI[] { seq });
- final AlignViewport av = new AlignViewport(al);
+ final AlignViewportI av = new AlignViewport(al);
ResidueColourFinder rcf = new OverviewResColourFinder();
av.setGlobalColourScheme(new ZappoColourScheme());
SequenceI seq = new Sequence("name", "MAT--GSPRAPAFF"); // FER1_MAIZE... + a
// gap
AlignmentI al = new Alignment(new SequenceI[] { seq });
- final AlignViewport av = new AlignViewport(al);
+ final AlignViewportI av = new AlignViewport(al);
ResidueColourFinder rcf = new OverviewResColourFinder();
Color[] newColours = new Color[24];
SequenceGroup[] groups = new SequenceGroup[1];
groups[0] = sg;
- final AlignViewport av = new AlignViewport(al);
+ final AlignViewportI av = new AlignViewport(al);
ResidueColourFinder rcf = new OverviewResColourFinder();
// G in group specified as magenta in Zappo
{
SequenceI seq = new Sequence("name", "MAT--GSPRAPAFF"); // FER1_MAIZE... + a
// gap
- AlignmentI al = new Alignment(new SequenceI[] { seq });
- final AlignViewport av = new AlignViewport(al);
// non-legacy colouring
ResidueColourFinder rcf = new OverviewResColourFinder();
// gaps gap colour
c = rcf.getBoxColour(shader, seq, 3);
- assertEquals(
- jalview.renderer.OverviewResColourFinder.OVERVIEW_DEFAULT_GAP,
- c);
+ assertEquals(OverviewResColourFinder.OVERVIEW_DEFAULT_GAP, c);
// non legacy colouring with colour scheme
rcf = new OverviewResColourFinder(false, Color.blue, Color.red);
import static org.testng.AssertJUnit.assertEquals;
+import jalview.api.AlignViewportI;
import jalview.datamodel.Alignment;
import jalview.datamodel.AlignmentI;
import jalview.datamodel.Sequence;
import jalview.gui.JvOptionPane;
import jalview.schemes.UserColourScheme;
import jalview.schemes.ZappoColourScheme;
-
import java.awt.Color;
import org.testng.annotations.BeforeClass;
{
SequenceI seq = new Sequence("name", "MATVLGSPRAPAFF"); // FER1_MAIZE...
AlignmentI al = new Alignment(new SequenceI[] { seq });
- final AlignViewport av = new AlignViewport(al);
+ final AlignViewportI av = new AlignViewport(al);
ResidueColourFinder rcf = new ResidueColourFinder();
av.setGlobalColourScheme(new ZappoColourScheme());
{
SequenceI seq = new Sequence("name", "MA--TVLGSPRAPAFF");
AlignmentI al = new Alignment(new SequenceI[] { seq });
- final AlignViewport av = new AlignViewport(al);
+ final AlignViewportI av = new AlignViewport(al);
ResidueColourFinder rcf = new ResidueColourFinder();
assertEquals(Color.white,
SequenceI seq = new Sequence("name", "MAT--GSPRAPAFF"); // FER1_MAIZE... + a
// gap
AlignmentI al = new Alignment(new SequenceI[] { seq });
- final AlignViewport av = new AlignViewport(al);
+ final AlignViewportI av = new AlignViewport(al);
ResidueColourFinder rcf = new ResidueColourFinder();
Color[] newColours = new Color[24];
import static org.testng.Assert.assertTrue;
import jalview.gui.AlignFrame;
-import jalview.gui.AlignViewport;
import jalview.io.DataSourceType;
import jalview.io.FileLoader;
import jalview.renderer.ScaleRenderer.ScaleMark;
+import jalview.viewmodel.AlignmentViewport;
import java.util.List;
String data = ">Seq/20-45\nABCDEFGHIJKLMNOPQRSTUVWXYS\n";
AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(data,
DataSourceType.PASTE);
- AlignViewport av = af.getViewport();
+ AlignmentViewport av = af.getViewport();
/*
* scale has minor ticks at 5, 15, 25, major at 10 and 20
import static org.testng.Assert.assertNull;
import static org.testng.Assert.assertTrue;
+import java.awt.Color;
+import java.util.List;
+
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
import jalview.api.FeatureColourI;
import jalview.datamodel.SequenceFeature;
import jalview.datamodel.SequenceI;
import jalview.gui.AlignFrame;
-import jalview.gui.AlignViewport;
+import jalview.api.AlignViewportI;
import jalview.io.DataSourceType;
import jalview.io.FileLoader;
import jalview.schemes.FeatureColour;
import jalview.viewmodel.seqfeatures.FeatureRendererModel;
import jalview.viewmodel.seqfeatures.FeatureRendererModel.FeatureSettingsBean;
-import java.awt.Color;
-import java.util.List;
-
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.BeforeTest;
-import org.testng.annotations.Test;
-
/**
* Unit tests for feature colour determination, including but not limited to
* <ul>
*/
public class FeatureColourFinderTest
{
- private AlignViewport av;
+ private AlignViewportI av;
private SequenceI seq;
private FeatureRendererModel fr;
- @BeforeTest(alwaysRun = true)
+ @BeforeClass(alwaysRun = true)
public void setUp()
{
// aligned column 8 is sequence position 6
import static org.testng.Assert.assertSame;
import static org.testng.Assert.assertTrue;
+import java.awt.Color;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.Test;
+
import jalview.analysis.GeneticCodes;
import jalview.api.AlignViewportI;
import jalview.api.FeatureColourI;
import jalview.util.matcher.Condition;
import jalview.viewmodel.seqfeatures.FeatureRendererModel.FeatureSettingsBean;
-import java.awt.Color;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.testng.annotations.Test;
-
public class FeatureRendererTest
{
+ @AfterMethod(alwaysRun = true)
+ public void tearDown()
+ {
+ Desktop.getInstance().closeAll_actionPerformed(null);
+ }
@Test(groups = "Functional")
public void testFindAllFeatures()
// TODO more test cases; check if help documentation matches implementation
}
-
- // @formatter:on
/**
* Test for colour calculation when the consensus percentage ignores gapped
@AfterClass(alwaysRun = true)
public static void tearDownAfterClass() throws Exception
{
- Desktop.instance.closeAll_actionPerformed(null);
+ Desktop.getInstance().closeAll_actionPerformed(null);
}
@Test(groups = "Functional")
--- /dev/null
+package jalview.schemes;
+
+import static org.testng.Assert.assertEquals;
+
+import jalview.datamodel.Alignment;
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.SequenceI;
+import jalview.io.DataSourceType;
+import jalview.io.HMMFile;
+
+import java.awt.Color;
+import java.io.IOException;
+import java.net.MalformedURLException;
+
+import org.testng.annotations.Test;
+
+public class HmmerGlobalBackgroundTest {
+
+ @Test(groups = "Functional")
+ public void testFindColour() throws MalformedURLException, IOException
+ {
+ HMMFile file = new HMMFile("test/jalview/io/test_PKinase_hmm.txt",
+ DataSourceType.FILE);
+
+ SequenceI hmmSeq = file.getSeqsAsArray()[0];
+ AlignmentI al = new Alignment(new SequenceI[] { hmmSeq });
+ ColourSchemeI scheme = new HmmerGlobalBackground(al);
+
+ /*
+ * 'A' in column 1, node 2, match emission 2.77204
+ * e-2.77204 = 0.0625
+ * background frequency is 0.0826
+ * ratio is 0.757, log is negative, colour is Orange
+ */
+ Color actual = scheme.findColour('A', 1, null, null, 0);
+ assertEquals(actual, Color.ORANGE);
+
+ // gap is white
+ actual = scheme.findColour('-', 2, null, null, 0);
+ assertEquals(actual, Color.WHITE);
+ actual = scheme.findColour(' ', 2, null, null, 0);
+ assertEquals(actual, Color.WHITE);
+ actual = scheme.findColour('.', 2, null, null, 0);
+ assertEquals(actual, Color.WHITE);
+
+ /*
+ * 'Y' in column 4, node 5, match emission 4.41426
+ * e-4.41426 = 0.0121
+ * background frequency is 0.0292
+ * ratio is 0.414, log is negative, colour is Orange
+ */
+ actual = scheme.findColour('Y', 4, null, null, 0);
+ assertEquals(actual, Color.ORANGE);
+
+ /*
+ * 'M' in column 109, no matching node, colour is reddish
+ */
+ actual = scheme.findColour('M', 109, null, null, 0);
+ assertEquals(actual, new Color(230, 0, 0));
+
+ /*
+ * 'I' in column 6, node 7, match emission 1.33015
+ * e-1.33015 = 0.2644
+ * background frequency is 0.0593
+ * ratio is 4.459, log is 1.495
+ * colour is graduated 1.495/4.52 or 84/255 of the way from
+ * white(255, 255, 255) to blue(0, 0, 255)
+ */
+ actual = scheme.findColour('I', 6, null, null, 0);
+ assertEquals(actual, new Color(171, 171, 255));
+
+ /*
+ * 'V' in column 14, node 15, match emission 0.44769
+ * e-0.44769 = 0.6391
+ * background frequency is 0.0686
+ * ratio is 9.316, log is 2.232
+ * colour is graduated 2.232/4.52 or 126/255 of the way from
+ * white(255, 255, 255) to blue(0, 0, 255)
+ */
+ actual = scheme.findColour('V', 14, null, null, 0);
+ assertEquals(actual, new Color(129, 129, 255));
+
+ /*
+ * invalid symbol is White
+ */
+ actual = scheme.findColour('X', 2, null, null, 0);
+ assertEquals(actual, Color.WHITE);
+ }
+
+}
--- /dev/null
+package jalview.schemes;
+
+import static org.testng.Assert.assertEquals;
+
+import jalview.datamodel.Alignment;
+import jalview.datamodel.AnnotatedCollectionI;
+import jalview.datamodel.Sequence;
+import jalview.datamodel.SequenceI;
+import jalview.io.DataSourceType;
+import jalview.io.HMMFile;
+
+import java.awt.Color;
+import java.io.IOException;
+import java.net.MalformedURLException;
+
+import org.testng.annotations.Test;
+
+public class HmmerLocalBackgroundTest {
+
+ @Test(groups = "Functional")
+ public void testFindColour() throws MalformedURLException, IOException
+ {
+ HMMFile file = new HMMFile("test/jalview/io/test_PKinase_hmm.txt",
+ DataSourceType.FILE);
+
+ /*
+ * alignment with 20 residues and background frequencies:
+ * A/a, S 3/20 = 0.15
+ * M, K 4/20 = 0.2
+ * V 2/20 = 0.1
+ * Q, R, L 1/20 = 0.05
+ * log(totalCount) = log(20) = 2.996
+ */
+ SequenceI seq1 = new Sequence("seq1", "AAMMMKKKVV");
+ SequenceI seq2 = new Sequence("seq2", "aAM-QKRSSSL");
+ SequenceI hmmSeq = file.getSeqsAsArray()[0];
+ AnnotatedCollectionI ac = new Alignment(
+ new SequenceI[]
+ { hmmSeq, seq1, seq2 });
+ ColourSchemeI scheme = new HmmerLocalBackground(ac);
+
+ /*
+ * 'A' in column 1, node 2, match emission 2.77204
+ * e-2.77204 = 0.0625
+ * background frequency is 0.15
+ * ratio is < 1, log is negative, colour is Orange
+ */
+ Color actual = scheme.findColour('A', 1, null, null, 0);
+ assertEquals(actual, Color.ORANGE);
+
+ // gap is white
+ actual = scheme.findColour('-', 2, null, null, 0);
+ assertEquals(actual, Color.WHITE);
+ actual = scheme.findColour(' ', 2, null, null, 0);
+ assertEquals(actual, Color.WHITE);
+ actual = scheme.findColour('.', 2, null, null, 0);
+ assertEquals(actual, Color.WHITE);
+
+ /*
+ * 'L' in column 3, node 4, match emission 1.98342
+ * e-1.98342 = 0.1376
+ * background frequency is 0.05
+ * ratio is 2.752, log is 1.012
+ * colour is graduated 1.012/2.996 or 86/255 of the way from
+ * white(255, 255, 255) to blue(0, 0, 255)
+ */
+ actual = scheme.findColour('L', 3, null, null, 0);
+ assertEquals(actual, new Color(169, 169, 255));
+
+ /*
+ * invalid symbol is White
+ */
+ actual = scheme.findColour('X', 2, null, null, 0);
+ assertEquals(actual, Color.WHITE);
+ }
+
+}
import jalview.datamodel.SequenceI;
import jalview.gui.AlignFrame;
-import jalview.gui.AlignViewport;
import jalview.io.DataSourceType;
import jalview.io.FileLoader;
+import jalview.viewmodel.AlignmentViewport;
public class PIDColourSchemeTest
{
*/
AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(seqs,
DataSourceType.PASTE);
- AlignViewport viewport = af.getViewport();
+ AlignmentViewport viewport = af.getViewport();
viewport.setIgnoreGapsConsensus(false, af.alignPanel);
do
{
int coils[] = { 266, 275, 278, 287, 289, 298, 302, 316 }, helices[] = new int[]
{ 303, 315 }, sheets[] = new int[] { 267, 268, 269, 270 };
- StructureSelectionManager ssm = new jalview.structure.StructureSelectionManager();
+ StructureSelectionManager ssm = StructureSelectionManager
+ .getStructureSelectionManager(null);
StructureFile pmap = ssm.setMapping(true, new SequenceI[] { uprot },
new String[] { "A" }, "test/jalview/ext/jmol/1QCF.pdb",
DataSourceType.FILE);
"EIVKGVCSNFLCDLQPGDNVQITGPVGKEMLMPKDPNATIIMLATGTGIAPFRSFLWKMFFEKHDDYKFNGLGWLFLGVPTSSSLLYKEEFGKM");
Sequence sq1 = new Sequence(sq);
String inFile;
- StructureSelectionManager ssm = new jalview.structure.StructureSelectionManager();
+ StructureSelectionManager ssm = StructureSelectionManager
+ .getStructureSelectionManager(null);
// Associate the 1GAQ pdb file with the subsequence 'imported' from another
// source
StructureFile pde = ssm.setMapping(true, new SequenceI[] { sq },
">FER1_MAIZE/1-150 Ferredoxin-1, chloroplast precursor\nMATVLGSPRAPAFFFSSSSLRAAPAPTAVALPAAKVGIMGRSASSRRRLRAQATYNVKLITPEGEVELQVPD\nDVYILDQAEEDGIDLPYSCRAGSCSSCAGKVVSGSVDQSDQSYLDDGQIADGWVLTCHAYPTSDVVIETHKE\nEELTGA",
DataSourceType.PASTE, FileFormat.Fasta);
SequenceI newseq = seqf.getViewport().getAlignment().getSequenceAt(0);
- StructureSelectionManager ssm = new jalview.structure.StructureSelectionManager();
+ StructureSelectionManager ssm = StructureSelectionManager
+ .getStructureSelectionManager(null);
StructureFile pmap = ssm.setMapping(true, new SequenceI[] { newseq },
new String[] { null }, "examples/3W5V.pdb",
DataSourceType.FILE);
// make it harder by shifting the copy vs the reference
newseq.setStart(refseq.getStart() + 25);
newseq.setEnd(refseq.getLength() + 25 + refseq.getStart());
- StructureSelectionManager ssm = new jalview.structure.StructureSelectionManager();
+ StructureSelectionManager ssm = StructureSelectionManager
+ .getStructureSelectionManager(null);
ssm.setProcessSecondaryStructure(true);
ssm.setAddTempFacAnnot(true);
StructureFile pmap = ssm.setMapping(true, new SequenceI[] { newseq },
public void setUp()
{
StructureImportSettings.setShowSeqFeatures(true);
- ssm = new StructureSelectionManager();
+ ssm = StructureSelectionManager.getStructureSelectionManager(null);
+ ssm.resetAll();
}
@Test(groups = { "Functional" })
ssm.registerMappings(set2);
ssm.registerMappings(set2);
- assertEquals(3, ssm.getSequenceMappings().size());
- assertTrue(ssm.getSequenceMappings().contains(acf1));
- assertTrue(ssm.getSequenceMappings().contains(acf2));
- assertTrue(ssm.getSequenceMappings().contains(acf3));
+ List<AlignedCodonFrame> mappings = ssm.getSequenceMappings();
+ assertEquals(3, mappings.size());
+ assertTrue(mappings.contains(acf1));
+ assertTrue(mappings.contains(acf2));
+ assertTrue(mappings.contains(acf3));
}
/**
SequenceI seq = new Sequence(
"1GAQ|B",
"ATYNVKLITPEGEVELQVPDDVYILDQAEEDGIDLPYSCRAGSCSSCAGKVVSGSVDQSDQSYLDDGQIADGWVLTCHAYPTSDVVIETHKEEELTGA");
- StructureSelectionManager sm = new StructureSelectionManager();
+ StructureSelectionManager sm = StructureSelectionManager.getStructureSelectionManager(null);
sm.setProcessSecondaryStructure(true);
sm.setAddTempFacAnnot(true);
StructureFile pmap = sm.setMapping(true, new SequenceI[] { seq },
{
// for some reason 'BeforeMethod' (which should be inherited from
// Jalview2XmlBase isn't always called)...
- Desktop.instance.closeAll_actionPerformed(null);
+ Desktop.getInstance().closeAll_actionPerformed(null);
try {
Thread.sleep(200);
} catch (Exception foo) {};
SequenceI seq = new Sequence("4IM2|A",
"LDFCIRNIEKTVMGEISDIHTKLLRLSSSQGTIE");
String P4IM2_MISSING = "examples/testdata/4IM2_missing.pdb";
- StructureSelectionManager sm = new StructureSelectionManager();
+ StructureSelectionManager sm = StructureSelectionManager.getStructureSelectionManager(null);
sm.setProcessSecondaryStructure(true);
sm.setAddTempFacAnnot(true);
StructureFile pmap = sm.setMapping(true, new SequenceI[] { seq },
PDBEntry importedPDB = new PDBEntry("3A6S", "", Type.PDB,
"Paste");
AAStructureBindingModel binder = new AAStructureBindingModel(
- new StructureSelectionManager(), new PDBEntry[]
+ StructureSelectionManager.getStructureSelectionManager(null), new PDBEntry[]
{ importedPDB },
new SequenceI[][]
{ importedAl.getSequencesArray() }, null)
seqs[0] = new SequenceI[] { seq1a, seq1b };
seqs[1] = new SequenceI[] { seq2 };
seqs[2] = new SequenceI[] { seq3 };
- StructureSelectionManager ssm = new StructureSelectionManager();
+ StructureSelectionManager ssm = StructureSelectionManager.getStructureSelectionManager(null);
ssm.setMapping(new SequenceI[] { seq1a, seq1b }, null, PDB_1,
DataSourceType.PASTE, null);
--- /dev/null
+1.8, 4.53
+3.4, 2.65
+0, 5.4
+6.4, 10.8
\ No newline at end of file
import static org.testng.AssertJUnit.assertNull;
import static org.testng.AssertJUnit.assertSame;
-import jalview.gui.JvOptionPane;
-
import java.awt.Color;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
+import jalview.gui.JvOptionPane;
+
public class ColorUtilsTest
{
*/
assertNull(ColorUtils.parseColourString(null));
assertNull(ColorUtils.parseColourString("rubbish"));
- assertEquals(Color.WHITE, ColorUtils.parseColourString("-1"));
+ assertNull(ColorUtils.parseColourString("-1"));
assertNull(ColorUtils.parseColourString(String
.valueOf(Integer.MAX_VALUE)));
assertNull(ColorUtils.parseColourString("100,200,300")); // out of range
--- /dev/null
+package jalview.util;
+
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertTrue;
+
+import java.io.IOException;
+import java.nio.file.Paths;
+import java.util.List;
+
+import org.testng.annotations.Test;
+
+public class FileUtilsTest
+{
+ @Test(groups = "Functional")
+ public void testFindMatchingPaths() throws IOException
+ {
+ String expect1 = Paths.get("..", "jalview", "examples", "plantfdx.fa")
+ .toString();
+ String expect2 = Paths.get("../jalview/examples/plantfdx.features")
+ .toString();
+ String expect3 = Paths
+ .get("../jalview/examples/testdata/plantfdx.features")
+ .toString();
+
+ List<String> matches = FileUtils
+ .findMatchingPaths(Paths.get(".."),
+ ".*[\\\\/]plant.*\\.f.*");
+ System.out.println(matches);
+ assertTrue(matches.contains(expect1));
+ assertTrue(matches.contains(expect2));
+ assertTrue(matches.contains(expect3));
+ }
+
+ @Test(groups = "External")
+ public void testWindowsPath() throws IOException
+ {
+ if (System.getProperty("os.name").startsWith("Windows"))
+ {
+ /*
+ * should pass provided Eclipse is installed
+ */
+ List<String> matches = FileUtils.findMatches("C:\\",
+ "Program Files*/eclips*/eclips?.exe");
+ assertFalse(matches.isEmpty());
+
+ /*
+ * should pass provided Chimera is installed
+ */
+ matches = FileUtils.findMatches("C:\\",
+ "Program Files*/Chimera*/bin/{chimera,chimera.exe}");
+ assertFalse(matches.isEmpty());
+ }
+ }
+
+ @Test(groups = "Functional")
+ public void testFindMatches() throws IOException
+ {
+ String expect1 = Paths.get("..", "jalview", "examples", "plantfdx.fa")
+ .toString();
+ String expect2 = Paths.get("../jalview/examples/plantfdx.features")
+ .toString();
+ String expect3 = Paths
+ .get("../jalview/examples/testdata/plantfdx.features")
+ .toString();
+
+ List<String> matches = FileUtils
+ .findMatches("..", "jalview/ex*/plant*.f*");
+ System.out.println(matches);
+ assertTrue(matches.contains(expect1));
+ assertTrue(matches.contains(expect2));
+ assertFalse(matches.contains(expect3));
+ }
+}
--- /dev/null
+package jalview.util;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNull;
+
+import jalview.datamodel.HMMNode;
+import jalview.datamodel.HiddenMarkovModel;
+import jalview.datamodel.Sequence;
+import jalview.datamodel.SequenceI;
+
+import java.io.BufferedReader;
+import java.io.FileReader;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Vector;
+
+import org.testng.annotations.Test;
+
+import junit.extensions.PA;
+
+public class HMMProbabilityDistributionAnalyserTest {
+
+ HMMProbabilityDistributionAnalyser analyser = new HMMProbabilityDistributionAnalyser();
+
+ @Test
+ public void testMoveToFile() throws IOException
+ {
+
+ BufferedReader br = new BufferedReader(new FileReader(
+ "test/jalview/util/test_Fams_for_probability_analysis"));
+ analyser.moveLocationBy(1, br);
+
+ String line = br.readLine();
+ assertEquals(line, "# STOCKHOLM 1.0");
+ line = br.readLine();
+ assertEquals(line, "seq1 ATW");
+ line = br.readLine();
+ assertEquals(line, "seq2 ATI");
+
+ }
+
+ @Test
+ public void testCountValidResidues()
+ {
+ analyser.sequences = new Vector<>();
+ analyser.hmm = new HiddenMarkovModel();
+ analyser.hmm.setProperty("LENG", "8");
+
+ List<HMMNode> nodes = new ArrayList<>();
+ nodes.add(new HMMNode());
+ for (int i = 1; i < 9; i++)
+ {
+ HMMNode node = new HMMNode();
+ node.setResidueNumber(i - 1);
+ nodes.add(node);
+
+ }
+ PA.setValue(analyser.hmm, "nodes", nodes);
+
+ SequenceI[] sequence = new Sequence[] {
+ new Sequence("seq1", "ATGWWSCF"), new Sequence("seq2", "GGMKI"),
+ new Sequence("seq3", "--.ATccGc") };
+ analyser.sequences.add(sequence[0]);
+ analyser.sequences.add(sequence[1]);
+ analyser.sequences.add(sequence[2]);
+
+ int count = analyser.countValidResidues();
+ assertEquals(count, 16);
+ }
+
+ @Test(priority = 0)
+ public void testReadBinned() throws IOException
+ {
+ analyser.readBinned("test/jalview/util/");
+ Map<String, Double> map = analyser.binned;
+ assertEquals(map.get("1.8"), 4.53);
+ assertEquals(map.get("3.4"), 2.65);
+ assertEquals(map.get("6.4"), 10.8);
+ assertEquals(map.get("0"), 5.4);
+ }
+
+ @Test
+ public void testReadRaw() throws IOException
+ {
+ analyser.readRaw("test/jalview/util/");
+ List<ArrayList<Double>> list = analyser.raw;
+
+ assertEquals(list.get(0).get(0), 1.43);
+ assertNull(list.get(0).get(2));
+ assertEquals(list.get(1).get(1), 1.2);
+ assertEquals(list.get(2).get(0), 5.6);
+ assertEquals(list.get(2).get(2), 6.8);
+
+ }
+
+ @Test(priority = 1)
+ public void testProcessData() throws IOException
+ {
+ analyser.keepRaw = true;
+ BufferedReader brFam = new BufferedReader(new FileReader(
+ "test/jalview/util/test_Fams_for_probability_analysis"));
+ BufferedReader brHMM = new BufferedReader(new FileReader(
+ "test/jalview/util/test_HMMs_for_probability_analysis"));
+ analyser.readStockholm(brFam);
+ analyser.readHMM(brHMM);
+ analyser.processData(6);
+ Map<String, Double> map = analyser.binned;
+ List<ArrayList<Double>> list = analyser.raw;
+ assertEquals(map.get("1.8"), 4.863, 0.001d);
+ assertEquals(map.get("3.4"), 2.65);
+ assertEquals(map.get("0"), 5.4);
+ assertEquals(map.get("6.4"), 10.8);
+ assertEquals(map.get("1.4"), 0.166667, 0.00001d);
+ assertEquals(map.get("4.4"), 0.5);
+
+ }
+}
assertEquals("[ [11, 16] ] 1:3 to [ [72, 53] ]", ml.toString());
}
- @Test(groups = "Functional")
- public void testAddRange()
- {
- int[] range = { 1, 5 };
- List<int[]> ranges = new ArrayList<>();
-
- // add to empty list:
- MapList.addRange(range, ranges);
- assertEquals(1, ranges.size());
- assertSame(range, ranges.get(0));
-
- // extend contiguous (same position):
- MapList.addRange(new int[] { 5, 10 }, ranges);
- assertEquals(1, ranges.size());
- assertEquals(1, ranges.get(0)[0]);
- assertEquals(10, ranges.get(0)[1]);
-
- // extend contiguous (next position):
- MapList.addRange(new int[] { 11, 15 }, ranges);
- assertEquals(1, ranges.size());
- assertEquals(1, ranges.get(0)[0]);
- assertEquals(15, ranges.get(0)[1]);
-
- // change direction: range is not merged:
- MapList.addRange(new int[] { 16, 10 }, ranges);
- assertEquals(2, ranges.size());
- assertEquals(16, ranges.get(1)[0]);
- assertEquals(10, ranges.get(1)[1]);
-
- // extend reverse contiguous (same position):
- MapList.addRange(new int[] { 10, 8 }, ranges);
- assertEquals(2, ranges.size());
- assertEquals(16, ranges.get(1)[0]);
- assertEquals(8, ranges.get(1)[1]);
-
- // extend reverse contiguous (next position):
- MapList.addRange(new int[] { 7, 6 }, ranges);
- assertEquals(2, ranges.size());
- assertEquals(16, ranges.get(1)[0]);
- assertEquals(6, ranges.get(1)[1]);
-
- // change direction: range is not merged:
- MapList.addRange(new int[] { 6, 9 }, ranges);
- assertEquals(3, ranges.size());
- assertEquals(6, ranges.get(2)[0]);
- assertEquals(9, ranges.get(2)[1]);
-
- // not contiguous: not merged
- MapList.addRange(new int[] { 11, 12 }, ranges);
- assertEquals(4, ranges.size());
- assertEquals(11, ranges.get(3)[0]);
- assertEquals(12, ranges.get(3)[1]);
- }
-
/**
* Check state after construction
*/
import jalview.io.FileFormatI;
import jalview.io.FormatAdapter;
+
public class MappingUtilsTest
{
@BeforeClass(alwaysRun = true)
// expected
}
}
+
+ // new for 2.12
+ @Test(groups = "Functional")
+ public void testAddRange()
+ {
+ int[] range = { 1, 5 };
+ List<int[]> ranges = new ArrayList<>();
+
+ // add to empty list:
+ MappingUtils.addRange(range, ranges);
+ assertEquals(1, ranges.size());
+ assertSame(range, ranges.get(0));
+
+ // extend contiguous (same position):
+ MappingUtils.addRange(new int[] { 5, 10 }, ranges);
+ assertEquals(1, ranges.size());
+ assertEquals(1, ranges.get(0)[0]);
+ assertEquals(10, ranges.get(0)[1]);
+
+ // extend contiguous (next position):
+ MappingUtils.addRange(new int[] { 11, 15 }, ranges);
+ assertEquals(1, ranges.size());
+ assertEquals(1, ranges.get(0)[0]);
+ assertEquals(15, ranges.get(0)[1]);
+
+ // change direction: range is not merged:
+ MappingUtils.addRange(new int[] { 16, 10 }, ranges);
+ assertEquals(2, ranges.size());
+ assertEquals(16, ranges.get(1)[0]);
+ assertEquals(10, ranges.get(1)[1]);
+
+ // extend reverse contiguous (same position):
+ MappingUtils.addRange(new int[] { 10, 8 }, ranges);
+ assertEquals(2, ranges.size());
+ assertEquals(16, ranges.get(1)[0]);
+ assertEquals(8, ranges.get(1)[1]);
+
+ // extend reverse contiguous (next position):
+ MappingUtils.addRange(new int[] { 7, 6 }, ranges);
+ assertEquals(2, ranges.size());
+ assertEquals(16, ranges.get(1)[0]);
+ assertEquals(6, ranges.get(1)[1]);
+
+ // change direction: range is not merged:
+ MappingUtils.addRange(new int[] { 6, 9 }, ranges);
+ assertEquals(3, ranges.size());
+ assertEquals(6, ranges.get(2)[0]);
+ assertEquals(9, ranges.get(2)[1]);
+
+ // not contiguous: not merged
+ MappingUtils.addRange(new int[] { 11, 12 }, ranges);
+ assertEquals(4, ranges.size());
+ assertEquals(11, ranges.get(3)[0]);
+ assertEquals(12, ranges.get(3)[1]);
+ }
}
import java.awt.event.InputEvent;
import java.awt.event.MouseEvent;
+import org.testng.Assert;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
assertEquals(Platform.escapeBackslashes("hello world"), "hello world");
assertEquals(Platform.escapeBackslashes("hello\\world"), "hello\\\\world");
}
+
+ @Test(groups = { "Functional" })
+ public void getLeadingIntegerFromString()
+ {
+ Assert.assertEquals(Platform.getLeadingIntegerValue("1234abcd", -1),
+ 1234);
+ Assert.assertEquals(Platform.getLeadingIntegerValue("1234", -1), 1234);
+ Assert.assertEquals(Platform.getLeadingIntegerValue("abcd", -1), -1);
+ Assert.assertEquals(Platform.getLeadingIntegerValue("abcd1234", -1),
+ -1);
+ Assert.assertEquals(Platform.getLeadingIntegerValue("None", -1), -1);
+ Assert.assertEquals(Platform.getLeadingIntegerValue("Null", -1), -1);
+ }
}
--- /dev/null
+Seq1, Seq2, Seq3
+1.43, 2.34, 5.6,
+EMPTY, 1.2, 0.05,
+EMPTY, 5.4, 6.8,
\ No newline at end of file
}
@Test(groups = { "Functional" })
- public void testGetLastToken()
- {
- assertNull(StringUtils.getLastToken(null, null));
- assertNull(StringUtils.getLastToken(null, "/"));
- assertEquals("a", StringUtils.getLastToken("a", null));
-
- assertEquals("abc", StringUtils.getLastToken("abc", "/"));
- assertEquals("c", StringUtils.getLastToken("abc", "b"));
- assertEquals("file1.dat", StringUtils.getLastToken(
- "file://localhost:8080/data/examples/file1.dat", "/"));
- }
-
- @Test(groups = { "Functional" })
public void testSeparatorListToArray()
{
String[] result = StringUtils.separatorListToArray(
--- /dev/null
+# STOCKHOLM 1.0
+seq1 AW
+seq2 GW
+seq3 AW
+//
+# STOCKHOLM 1.0
+seq1 ATW
+seq2 ATI
+//
+# STOCKHOLM 1.0
+seq1 R-WW
+seq2 RAWW
+//
\ No newline at end of file
--- /dev/null
+HMMER3/f [3.1b2 | February 2015]
+NAME test1
+LENG 4
+ALPH amino
+RF no
+MM no
+CONS yes
+CS no
+MAP yes
+DATE Fri Jul 21 06:35:06 2017
+NSEQ 3
+EFFN 3.000000
+CKSUM 657102310
+STATS LOCAL MSV -5.0223 0.82341
+STATS LOCAL VITERBI -4.9569 0.82341
+STATS LOCAL FORWARD -2.0282 0.82341
+HMM A C D E F G H I K L M N P Q R S T V W Y
+ m->m m->i m->d i->m i->i d->m d->d
+ COMPO 1.94296 5.20658 4.78882 4.52987 4.66525 2.54188 5.19553 2.25221 4.08549 3.87133 5.00250 4.55734 4.73106 4.65220 2.77287 3.67799 1.53923 3.75384 1.48526 4.84023
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01083 4.92694 5.64929 0.61958 0.77255 0.00000 *
+ 1 0.67027 4.79120 4.60974 4.51892 5.43734 1.28080 5.43621 4.90028 4.64310 4.61059 5.39837 4.28688 4.41468 4.80804 4.79047 3.08135 3.44468 4.10506 6.74908 5.67939 1 A - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01083 4.92694 5.64929 0.61958 0.77255 0.48576 0.95510
+ 2 5.43405 6.34487 5.85697 5.84679 4.39288 5.10370 5.65594 5.70664 5.69821 4.87848 6.25251 5.89664 5.70261 6.00722 5.60902 5.64576 5.80049 5.59366 0.08910 4.36301 2 W - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01083 4.92694 5.64929 0.61958 0.77255 0.48576 0.95510
+ 3 3.42384 5.23617 4.84601 4.77568 5.39247 4.01365 5.64153 4.72950 4.75585 4.52264 5.55782 4.69647 4.81267 5.08969 4.87301 3.64217 0.20934 4.25217 6.65833 5.63018 3 T - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01083 4.92694 5.64929 0.61958 0.77255 0.48576 0.95510
+ 4 3.53954 5.09963 4.71395 4.06038 4.20429 4.44020 4.65482 0.90152 3.16536 2.96072 4.13056 4.31689 4.83725 3.95143 1.46549 3.86829 3.78084 2.85654 5.74911 4.54685 4 i - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00730 4.92341 * 0.61958 0.77255 0.00000 *
+//
+HMMER3/f [3.1b2 | February 2015]
+NAME test2
+LENG 3
+ALPH amino
+RF no
+MM no
+CONS yes
+CS no
+MAP yes
+DATE Fri Jul 21 06:36:50 2017
+NSEQ 2
+EFFN 2.000000
+CKSUM 777554360
+STATS LOCAL MSV -5.2452 0.95763
+STATS LOCAL VITERBI -5.2886 0.95763
+STATS LOCAL FORWARD -1.5134 0.95763
+HMM A C D E F G H I K L M N P Q R S T V W Y
+ m->m m->i m->d i->m i->i d->m d->d
+ COMPO 1.33364 4.79082 4.44132 4.24796 3.91456 3.75718 4.85762 2.23342 4.16821 3.09137 4.29744 4.25088 4.41741 4.46803 4.31080 3.33397 1.39376 3.21010 2.54819 4.14914
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01467 4.62483 5.34718 0.61958 0.77255 0.00000 *
+ 1 0.32372 4.76536 4.42980 4.32857 5.00499 3.55951 5.22620 4.27004 4.37081 4.10495 5.08789 4.22499 4.36948 4.63911 4.51684 3.12947 3.46009 3.76842 6.33337 5.25783 1 A - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01467 4.62483 5.34718 0.61958 0.77255 0.48576 0.95510
+ 2 3.04414 4.87155 4.35068 4.21532 4.89213 3.66881 5.13994 4.14202 4.17893 3.96810 5.00600 4.23490 4.44590 4.53729 4.35178 3.25814 0.35496 3.73038 6.23308 5.12388 2 T - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01467 4.62483 5.34718 0.61958 0.77255 0.48576 0.95510
+ 3 3.41901 4.77187 4.98694 4.49106 3.10447 4.49364 4.52024 1.21391 4.22709 2.30875 3.57865 4.53952 4.83367 4.43564 4.31127 3.88439 3.66452 2.61326 1.44329 3.34125 3 i - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 4.62006 * 0.61958 0.77255 0.00000 *
+//
+HMMER3/f [3.1b2 | February 2015]
+NAME test3
+LENG 4
+ALPH amino
+RF no
+MM no
+CONS yes
+CS no
+MAP yes
+DATE Fri Jul 21 06:37:01 2017
+NSEQ 2
+EFFN 2.000000
+CKSUM 986955970
+STATS LOCAL MSV -5.4578 0.80004
+STATS LOCAL VITERBI -5.2499 0.80004
+STATS LOCAL FORWARD -2.1856 0.80004
+HMM A C D E F G H I K L M N P Q R S T V W Y
+ m->m m->i m->d i->m i->i d->m d->d
+ COMPO 2.16700 5.33023 4.57707 4.32329 4.15728 4.03215 4.83242 4.49728 3.73978 4.00181 5.18156 4.45520 4.63709 4.41734 1.53081 3.84281 4.10073 4.20172 0.82417 4.15750
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01467 4.62483 5.34718 0.61958 0.77255 0.00000 *
+ 1 4.09153 5.75008 4.67229 4.09411 5.31638 4.34678 4.67762 4.97541 2.93879 4.35023 5.37643 4.37234 4.85576 3.90366 0.27042 4.17197 4.33362 4.67489 6.11461 5.14175 1 R - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.39762 4.62483 1.14482 0.61958 0.77255 0.48576 0.95510
+ 2 0.58385 4.42717 3.89187 3.72118 4.47383 3.23815 4.69159 3.65968 3.74862 3.52210 4.52478 3.76053 4.01438 4.05655 3.96007 2.78076 3.08518 3.24526 5.86063 4.71068 2 A - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.02145 4.24866 4.97100 0.61958 0.77255 0.27360 1.42978
+ 3 4.82318 5.87391 5.36844 5.28961 3.81117 4.70308 5.10523 4.98084 5.06729 4.21822 5.56037 5.33222 5.28501 5.40387 5.04111 5.02415 5.17266 4.88017 0.16601 3.78547 3 W - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.01467 4.62483 5.34718 0.61958 0.77255 0.48576 0.95510
+ 4 4.82318 5.87391 5.36844 5.28961 3.81117 4.70308 5.10523 4.98084 5.06729 4.21822 5.56037 5.33222 5.28501 5.40387 5.04111 5.02415 5.17266 4.88017 0.16601 3.78547 4 W - - -
+ 2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
+ 0.00990 4.62006 * 0.61958 0.77255 0.00000 *
+//
\ No newline at end of file
--- /dev/null
+package jalview.workers;
+
+import static org.testng.Assert.*;
+
+import java.util.ArrayList;
+import java.util.concurrent.CancellationException;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import jalview.api.AlignCalcManagerI2;
+import jalview.api.AlignCalcWorkerI;
+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 jalview.gui.JvOptionPane;
+
+@Test(singleThreaded = true)
+public class AlignCaclManager2Test
+{
+ AlignFrame alignFrame;
+
+ AlignCalcManagerI2 calcManager;
+
+ @BeforeClass(alwaysRun = true)
+ public void setUpClass()
+ {
+ JvOptionPane.setInteractiveMode(false);
+ JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+ }
+
+ @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);
+ calcManager = alignFrame.getViewport().getCalcManager();
+ }
+
+ @AfterMethod(alwaysRun = true)
+ public void tearDown()
+ {
+ calcManager.shutdown();
+ }
+
+ // Running workers
+
+ @Test(groups = "Functional")
+ public void testStartRegisteredWorker() throws InterruptedException
+ {
+ var sentinel = new Object();
+ var job = CompletableFuture.completedFuture(sentinel);
+ var worker = new AlignCalcWorkerMock(job);
+ calcManager.registerWorker(worker);
+ Thread.sleep(10);
+ assertSame(worker.getLastResult(), sentinel);
+ }
+
+ @Test(groups = "Functional")
+ public void testIsWorking() throws InterruptedException
+ {
+ var job = new CompletableFuture<Object>();
+ var worker = new AlignCalcWorkerMock(job);
+ calcManager.registerWorker(worker);
+ assertTrue(calcManager.isWorking(worker));
+ assertTrue(calcManager.isWorking());
+ job.complete(null);
+ Thread.sleep(10);
+ assertFalse(calcManager.isWorking(worker));
+ assertFalse(calcManager.isWorking());
+ }
+
+ @Test(groups = "Functional")
+ public void testIsWorkingWithAnnotation() throws InterruptedException
+ {
+ var job = new CompletableFuture<Void>();
+ var worker1 = new AlignCalcWorkerMock(job);
+ var annot = worker1.annotation = newAlignmentAnnotation();
+ var otherAnnot = newAlignmentAnnotation();
+ calcManager.registerWorker(worker1);
+ assertTrue(calcManager.isWorkingWithAnnotation(annot));
+ assertFalse(calcManager.isWorkingWithAnnotation(otherAnnot));
+ job.complete(null);
+ Thread.sleep(10);
+ assertFalse(calcManager.isWorkingWithAnnotation(annot));
+ }
+
+ @Test(groups = "Functional")
+ public void testRestartCompletedWorkers() throws Throwable
+ {
+ var sentinel1 = new Object();
+ var sentinel2 = new Object();
+ var job = CompletableFuture.completedFuture(sentinel1);
+ var worker = new AlignCalcWorkerMock(job);
+ calcManager.registerWorker(worker);
+ Thread.sleep(10);
+ assertSame(worker.getLastResult(), sentinel1);
+ job.obtrudeValue(sentinel2);
+ calcManager.restartWorkers();
+ Thread.sleep(10);
+ assertSame(worker.getLastResult(), sentinel2);
+ }
+
+ @Test(groups = "Functional")
+ public void testRestartCancelsWorkers() throws Throwable
+ {
+ var job = new CompletableFuture<Object>();
+ var worker = new AlignCalcWorkerMock(job);
+ var sentinel = new Object();
+ calcManager.registerWorker(worker);
+ Thread.sleep(10);
+ calcManager.restartWorkers();
+ Thread.sleep(10);
+ assertTrue(worker.wasCancelled());
+ job.obtrudeValue(sentinel);
+ Thread.sleep(10);
+ assertSame(worker.getLastResult(), sentinel);
+ }
+
+ // Disabling workers
+
+ @Test(groups = "Functional")
+ public void testDisableWorker()
+ {
+ var worker = new AlignCalcWorkerMock(null);
+ calcManager.registerWorker(worker);
+ calcManager.disableWorker(worker);
+ assertTrue(calcManager.isDisabled(worker));
+ calcManager.enableWorker(worker);
+ assertFalse(calcManager.isDisabled(worker));
+ }
+
+ @Test(groups = "Functional")
+ public void testRestartDisabledWorker() throws InterruptedException
+ {
+ var worker = new AlignCalcWorkerMock(null);
+ calcManager.registerWorker(worker);
+ Thread.sleep(10);
+ assertEquals(worker.getCallCount(), 1);
+ calcManager.disableWorker(worker);
+ calcManager.restartWorkers();
+ Thread.sleep(10);
+ assertEquals(worker.getCallCount(), 1);
+ calcManager.enableWorker(worker);
+ calcManager.restartWorkers();
+ Thread.sleep(10);
+ assertEquals(worker.getCallCount(), 2);
+ }
+
+ // Canceling workers
+
+ @Test(groups = "Functional")
+ public void testCancelWorker() throws InterruptedException
+ {
+ var worker = new AlignCalcWorkerMock(new CompletableFuture<>());
+ calcManager.registerWorker(worker);
+ Thread.sleep(10);
+ calcManager.cancelWorker(worker);
+ Thread.sleep(10);
+ assertTrue(worker.wasCancelled());
+ }
+
+ // One-shot workers
+
+ @Test(groups = "Functional")
+ public void testStartOneShotWorker() throws InterruptedException
+ {
+ var job = CompletableFuture.completedFuture("result");
+ var worker = new AlignCalcWorkerMock(job);
+ calcManager.startWorker(worker);
+ Thread.sleep(10);
+ assertEquals(worker.getLastResult(), "result");
+ }
+
+ @Test(groups = "Functional")
+ public void testCancelOneShotWorker() throws InterruptedException
+ {
+ var worker = new AlignCalcWorkerMock(new CompletableFuture<>());
+ calcManager.startWorker(worker);
+ Thread.sleep(10);
+ calcManager.cancelWorker(worker);
+ Thread.sleep(10);
+ assertTrue(worker.wasCancelled());
+ }
+
+ @Test(groups = "Functional")
+ public void restartOneShotWorker() throws InterruptedException
+ {
+ var job = CompletableFuture.completedFuture("result1");
+ var worker = new AlignCalcWorkerMock(job);
+ calcManager.startWorker(worker);
+ Thread.sleep(10);
+ job.obtrudeValue("result2");
+ calcManager.restartWorkers();
+ Thread.sleep(10);
+
+ }
+
+
+ // Retrieving workers
+
+ @Test(groups = "Functional")
+ public void testGetWorkersOfClass() throws InterruptedException
+ {
+ var worker1 = new AlignCalcWorkerMock(null);
+ var worker2 = new AlignCalcWorkerMock(null);
+ var worker3 = new AlignCalcWorkerMock(null) {};
+ calcManager.registerWorker(worker1);
+ calcManager.registerWorker(worker2);
+ calcManager.registerWorker(worker3);
+ final var workers = calcManager
+ .getWorkersOfClass(AlignCalcWorkerMock.class);
+ assertTrue(workers.contains(worker1) && workers.contains(worker2));
+ assertFalse(workers.contains(worker3));
+ }
+
+ // Removing workers
+
+ @Test(groups = "Functional")
+ public void testRemoveWorker()
+ {
+ var worker = new AlignCalcWorkerMock(null);
+ calcManager.registerWorker(worker);
+ calcManager.removeWorker(worker);
+ assertFalse(calcManager.getWorkers().contains(worker));
+ }
+
+ @Test(groups = "Functional")
+ public void testRemoveWorkersOfClass()
+ {
+ var worker1 = new AlignCalcWorkerMock(null);
+ var worker2 = new AlignCalcWorkerMock(null);
+ var worker3 = new AlignCalcWorkerMock(null) {};
+ calcManager.registerWorker(worker1);
+ calcManager.registerWorker(worker2);
+ calcManager.registerWorker(worker3);
+ calcManager.removeWorkersOfClass(worker1.getClass());
+ assertFalse(calcManager.getWorkers().contains(worker1)
+ || calcManager.getWorkers().contains(worker2));
+ assertTrue(calcManager.getWorkers().contains(worker3));
+ }
+
+ @Test(groups = "Functional")
+ public void testRemoveWorkersForAnnotation()
+ {
+ var worker1 = new AlignCalcWorkerMock(null);
+ var worker2 = new AlignCalcWorkerMock(null);
+ var annot = worker1.annotation = newAlignmentAnnotation();
+ calcManager.registerWorker(worker1);
+ calcManager.registerWorker(worker2);
+ calcManager.removeWorkerForAnnotation(annot);
+ var workers = calcManager.getWorkers();
+ assertFalse(workers.contains(worker1));
+ assertTrue(workers.contains(worker2));
+ }
+
+ @Test(groups = "Functional")
+ public void testRemoveNonRemovableWorker()
+ {
+ var worker = new AlignCalcWorkerMock(null);
+ worker.deletable = false;
+ calcManager.registerWorker(worker);
+ calcManager.removeWorker(worker);
+ assertTrue(calcManager.getWorkers().contains(worker));
+ }
+
+ @Test(groups = "Functional")
+ public void testRemoveNonRemovableWorkersOfClass()
+ {
+ var worker1 = new AlignCalcWorkerMock(null);
+ var worker2 = new AlignCalcWorkerMock(null);
+ worker2.deletable = false;
+ calcManager.registerWorker(worker1);
+ calcManager.registerWorker(worker2);
+ calcManager.removeWorkersOfClass(worker1.getClass());
+ var workers = calcManager.getWorkers();
+ assertFalse(workers.contains(worker1));
+ assertTrue(workers.contains(worker2));
+ }
+
+ private int annotationCount = 0;
+
+ private AlignmentAnnotation newAlignmentAnnotation()
+ {
+ return new AlignmentAnnotation("Ann" + annotationCount++, "description",
+ new Annotation[] {});
+ }
+}
+
+class AlignCalcWorkerMock implements AlignCalcWorkerI
+{
+ AlignmentAnnotation annotation = null;
+ Future<?> job;
+ ArrayList<Object> values = new ArrayList<>();
+ int callCount = 0;
+ boolean deletable = true;
+
+ AlignCalcWorkerMock(Future<?> job)
+ {
+ this.job = job;
+ }
+
+ public Object getLastResult()
+ {
+ return values.isEmpty() ? null : values.get(values.size() - 1);
+ }
+
+ public Throwable getException()
+ {
+ var result = getLastResult();
+ return (result instanceof Throwable) ? (Throwable) result : null;
+ }
+
+ public int getCallCount() {
+ return callCount;
+ }
+
+ public boolean wasCancelled()
+ {
+ return getException() instanceof InterruptedException;
+ }
+
+ @Override
+ public boolean involves(AlignmentAnnotation annot)
+ {
+ if (annotation == null)
+ return false;
+ else
+ return annot == annotation;
+ }
+
+ @Override
+ public void updateAnnotation()
+ {
+ }
+
+ @Override
+ public void removeAnnotation()
+ {
+ }
+
+ @Override
+ public void run() throws Throwable
+ {
+ callCount++;
+ if (job != null)
+ {
+ try
+ {
+ values.add(job.get());
+ }
+ catch (InterruptedException e) { values.add(e); }
+ catch (CancellationException e) {
+ values.add(new InterruptedException());
+ } catch (ExecutionException e)
+ {
+ values.add(e.getCause());
+ }
+ }
+ }
+
+ @Override
+ public boolean isDeletable()
+ {
+ return deletable;
+ }
+}
import static org.testng.AssertJUnit.assertTrue;
import jalview.api.AlignCalcManagerI;
+import jalview.api.AlignCalcManagerI2;
import jalview.api.AlignCalcWorkerI;
import jalview.api.FeatureRenderer;
import jalview.datamodel.Alignment;
@Test(groups = "Functional")
public void testRemoveWorkerForAnnotation()
{
- AlignCalcManagerI acm = alignFrame.getViewport().getCalcManager();
+ AlignCalcManagerI2 acm = alignFrame.getViewport().getCalcManager();
final AlignmentAnnotation ann1 = new AlignmentAnnotation("Ann1",
"desc", new Annotation[] {});
final AlignmentAnnotation ann2 = new AlignmentAnnotation("Ann2",
}
}
- List<AlignCalcWorkerI> workers = acm
- .getRegisteredWorkersOfClass(worker1.getClass());
+ List<AlignCalcWorkerI> workers = acm.getWorkersOfClass(worker1.getClass());
assertEquals(2, workers.size());
assertTrue(workers.contains(worker1));
assertTrue(workers.contains(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));
+ assertTrue(acm.getWorkersOfClass(worker1.getClass()).contains(worker1));
+ assertTrue(acm.getWorkersOfClass(worker1.getClass()).contains(worker2));
assertFalse(acm.isDisabled(worker1));
assertFalse(acm.isDisabled(worker2));
* - should delete worker1 but not worker2
*/
acm.removeWorkerForAnnotation(ann1);
- assertEquals(1, acm.getRegisteredWorkersOfClass(worker1.getClass())
- .size());
- assertTrue(acm.getRegisteredWorkersOfClass(worker1.getClass())
- .contains(worker2));
+ assertEquals(1, acm.getWorkersOfClass(worker1.getClass()).size());
+ assertTrue(acm.getWorkersOfClass(worker1.getClass()).contains(worker2));
assertFalse(acm.isDisabled(worker1));
assertFalse(acm.isDisabled(worker2));
}
{
Cache.loadProperties("test/jalview/io/testProps.jvprops");
// ensure 'add annotation from structure' is selected
- Cache.applicationProperties.setProperty("STRUCT_FROM_PDB",
+ Cache.setPropertyNoSave("STRUCT_FROM_PDB",
Boolean.TRUE.toString());
- Cache.applicationProperties.setProperty("ADD_SS_ANN",
+ Cache.setPropertyNoSave("ADD_SS_ANN",
Boolean.TRUE.toString());
sf = new SequenceFetcher();
@Test(groups = { "Network" }, enabled = true)
public void testRnaSeqRetrieve() throws Exception
{
- Cache.applicationProperties.setProperty("PDB_DOWNLOAD_FORMAT", "PDB");
+ Cache.setPropertyNoSave("PDB_DOWNLOAD_FORMAT", "PDB");
List<DbSourceProxy> sps = sf.getSourceProxy("PDB");
AlignmentI response = sps.get(0).getSequenceRecords("2GIS");
assertTrue(response != null);
// chains in structure have a mapping to data in the structure
List<SequenceFeature> prev = null;
int lastp = -1;
- for (int col = 1; col <= sq.getLength(); col++)
+ for (int col = 1, ns = sq.getLength(); col <= ns; col++)
{
List<SequenceFeature> sf = sq.findFeatures(col, col, "RESNUM");
if (sf.size() != 1)
{
Cache.loadProperties("test/jalview/io/testProps.jvprops");
// ensure 'add annotation from structure' is selected
- Cache.applicationProperties.setProperty("STRUCT_FROM_PDB",
+ Cache.setPropertyNoSave("STRUCT_FROM_PDB",
Boolean.TRUE.toString());
- Cache.applicationProperties.setProperty("ADD_SS_ANN",
+ Cache.setPropertyNoSave("ADD_SS_ANN",
Boolean.TRUE.toString());
sf = new SequenceFetcher();
--- /dev/null
+package jalview.ws.ebi;
+
+import jalview.datamodel.AlignmentAnnotation;
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.SequenceI;
+import jalview.io.DataSourceType;
+import jalview.io.FileFormat;
+import jalview.io.FileParse;
+import jalview.io.FormatAdapter;
+
+import java.io.File;
+
+import org.json.simple.JSONObject;
+import org.json.simple.parser.JSONParser;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+public class HmmerJSONProcessTest {
+ public static File alignmentFragFile = new File(
+ "examples/testdata/hmmer3/alignment_frag.fa.gz");
+
+ private AlignmentI getSearchResultFragmentAlignment() throws Exception
+ {
+ AlignmentI alf = new FormatAdapter().readFile(
+ alignmentFragFile.getAbsolutePath(), DataSourceType.FILE,
+ FileFormat.Fasta);
+
+ return alf;
+ }
+
+ public static File alignmentResultFile = new File(
+ "examples/testdata/hmmer3/alignment_res.fa.gz");
+
+ private AlignmentI getSearchResultAlignment() throws Exception
+ {
+ AlignmentI alf = new FormatAdapter().readFile(
+ alignmentResultFile.getAbsolutePath(), DataSourceType.FILE,
+ FileFormat.Fasta);
+
+ return alf;
+ }
+
+ public static String hitTestFile = "examples/testdata/hmmer3/hit_fragment.json.gz",
+ hmmerResultFile = "examples/testdata/hmmer3/hmmeresult.json.gz";
+
+
+ @Test(groups = { "Functional" })
+ public void parseHitTest() throws Exception
+ {
+
+ Assert.assertTrue(new File(hitTestFile).exists(),
+ "Can't find test data.\n"
+ + hitTestFile);
+ JSONParser jp = new JSONParser();
+ // read JSON in same way - via fileparse
+ Object hitfragment = jp.parse(new FileParse(hitTestFile,
+ DataSourceType.FILE).getReader());
+ Assert.assertTrue((hitfragment instanceof JSONObject),
+ "Didn't find a JSON object map in " + hitTestFile);
+ AlignmentI searchResult = getSearchResultFragmentAlignment();
+
+ Assert.assertTrue(searchResult != null && searchResult.getHeight() > 0,
+ "Didn't read search result alignment from " + alignmentFragFile);
+
+ HmmerJSONProcessor hjsp = new HmmerJSONProcessor(searchResult);
+ hjsp.addHit((JSONObject) hitfragment, 1);
+ // check that
+ // scores, posterior probabilities and stuff exist.
+ }
+
+ @Test(groups = { "Functional" })
+ public void parseJsonResultTest() throws Exception
+ {
+
+ Assert.assertTrue(new File(hmmerResultFile).exists(),
+ "Can't find test data.\n" + hmmerResultFile);
+
+ AlignmentI searchResult = getSearchResultAlignment();
+
+ Assert.assertTrue(searchResult != null && searchResult.getHeight() > 0,
+ "Didn't read search result alignment from " + alignmentFragFile);
+
+ HmmerJSONProcessor hjsp = new HmmerJSONProcessor(searchResult);
+ hjsp.parseFrom(new FileParse(hmmerResultFile, DataSourceType.FILE));
+ AlignmentAnnotation[] aa = searchResult.getSequenceAt(5)
+ .getAnnotation();
+ Assert.assertNotNull(aa);
+ Assert.assertEquals(aa.length, 3,
+ "didn't get expected set of annotation.\n");
+ // DPTSERWFHGHLSGKEAEKLLTeKGKHGSFLVRESQSHPGDFVLSVRTgddkgesndgKSKVTHVMIR-CQELKYDVGGGERFDSLTDLVEHYKKNPmvet
+ // LGTVLQLKQP
+ // 5789*****************9799***********************999998888888********.99**************************9999
+ // 899999*999
+ // AlignmentAnnotation
+ // 101 == 8
+ String seq = "tLGT";
+ SequenceI s5 = searchResult.getSequenceAt(5);
+ Assert.assertEquals(
+ s5.getSubSequence(s5.findIndex(225), s5.findIndex(229))
+ .getSequenceAsString(),
+ seq);
+ int pos = s5.findIndex(226);
+ for (AlignmentAnnotation an : aa)
+ {
+ if (an.label.startsWith("Posterior"))
+ {
+ Assert.assertEquals(an.annotations[pos].value, 8f);
+
+ }
+ }
+ ;
+ // check that
+ // scores, posterior probabilities and stuff exist.
+ }
+ // Groovy test
+ // def al = Jalview.getAlignFrames()[0].getViewport().getAlignment()
+ // def jproc = new jalview.ws.ebi.HmmerJSONProcessor(al)
+ // jproc.parseFrom(new
+ // jalview.io.FileParse("examples/testdata/hmmer3/hmmeresult.json.gz","File"))
+ // jproc.updateView(Jalview.getAlignFrames()[0].getViewport())
+
+}
package jalview.ws.gui;
import java.util.Locale;
-
import jalview.bin.Cache;
import jalview.gui.JvOptionPane;
import jalview.gui.WsJobParameters;
import jalview.util.MessageManager;
+import jalview.ws.api.ServiceWithParameters;
import jalview.ws.jabaws.JalviewJabawsTestUtils;
import jalview.ws.jws2.JabaPreset;
import jalview.ws.jws2.Jws2Discoverer;
import jalview.ws.jws2.jabaws2.Jws2Instance;
+import jalview.ws.params.ArgumentI;
+import jalview.ws.params.ParamDatastoreI;
import java.awt.BorderLayout;
import java.awt.event.WindowAdapter;
/**
* which services to test
*/
- public static List<String> serviceTests = new ArrayList<String>();
+ public static List<String> serviceTests = new ArrayList<>();
/**
* which presets to test for services
*/
- public static List<String> presetTests = new ArrayList<String>();
+ public static List<String> presetTests = new ArrayList<>();
static
{
serviceTests.add("AAConWS".toLowerCase(Locale.ROOT));
public void testJws2Gui()
{
Iterator<String> presetEnum = presetTests.iterator();
- for (Jws2Instance service : disc.getServices())
+ for (ServiceWithParameters _service : disc.getServices())
{
+ // This will fail for non-jabaws services
+ Jws2Instance service = (Jws2Instance) _service;
if (serviceTests.size() == 0
|| serviceTests.contains(service.serviceType.toLowerCase(Locale.ROOT)))
{
}
pr = en.next();
}
- WsJobParameters pgui = new WsJobParameters(service,
- new JabaPreset(service, pr));
- JFrame jf = new JFrame(MessageManager.formatMessage(
- "label.ws_parameters_for",
- new String[] { service.getActionText() }));
+ WsJobParameters pgui = new WsJobParameters((ParamDatastoreI) null,
+ service, new JabaPreset(service, pr),
+ (List<ArgumentI>) null);
+ JFrame jf = new JFrame(MessageManager
+ .formatMessage("label.ws_parameters_for", new String[]
+ { service.getActionText() }));
jf.setSize(700, 800);
JPanel cont = new JPanel(new BorderLayout());
pgui.validate();
--- /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.jabaws;
+
+import static org.testng.AssertJUnit.assertNotNull;
+import static org.testng.AssertJUnit.assertTrue;
+
+import jalview.bin.Cache;
+import jalview.datamodel.AlignmentAnnotation;
+import jalview.datamodel.AlignmentI;
+import jalview.gui.AlignFrame;
+import jalview.gui.JvOptionPane;
+import jalview.ws.api.ServiceWithParameters;
+import jalview.ws.jws2.Jws2Discoverer;
+import jalview.ws.jws2.SeqAnnotationServiceCalcWorker;
+import jalview.ws.slivkaws.SlivkaWSDiscoverer;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+/*
+ * All methods in this class are set to the Network group because setUpBeforeClass will fail
+ * if there is no network.
+ */
+@Test(singleThreaded = true)
+public class AAConAnnotAndSettingsIO
+{
+
+ @BeforeClass(alwaysRun = true)
+ public void setUpJvOptionPane()
+ {
+ JvOptionPane.setInteractiveMode(false);
+ JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+ }
+
+ public static String testseqs = "examples/uniref50.fa";
+
+ public static Jws2Discoverer disc;
+
+ public static List<ServiceWithParameters[]> aacon;
+
+ jalview.ws.jws2.SeqAnnotationServiceCalcWorker aaconClient;
+
+ public static jalview.gui.AlignFrame af = null;
+
+ @BeforeClass(alwaysRun = true)
+ public static void setUpBeforeClass() throws Exception
+ {
+ Cache.loadProperties("test/jalview/io/testProps.jvprops");
+ Cache.initLogger();
+ disc = JalviewJabawsTestUtils.getJabawsDiscoverer();
+
+ while (disc.isRunning())
+ {
+ // don't get services until discoverer has finished
+ Thread.sleep(100);
+ }
+
+
+ aacon = new ArrayList<>();
+ for (ServiceWithParameters svc : disc.getServices())
+ {
+ if (svc.getNameURI().toLowerCase().contains("aacon"))
+ {
+ aacon.add(new ServiceWithParameters[] { svc });
+ }
+ }
+
+ for (ServiceWithParameters svc : SlivkaWSDiscoverer.getInstance()
+ .getServices())
+ {
+ if (svc.getNameURI().toLowerCase().contains("aacon"))
+ {
+ aacon.add(new ServiceWithParameters[] { svc });
+ }
+ }
+ assertTrue("Couldn't discover any AACon services to use to test.",
+ aacon.size() > 0);
+ }
+
+ @AfterClass(alwaysRun = true)
+ public static void tearDownAfterClass() throws Exception
+ {
+ if (af != null)
+ {
+ af.setVisible(false);
+ af.dispose();
+ af = null;
+ }
+ }
+
+ @DataProvider(name = "aacons")
+ public Object[][] getAaconArray()
+ {
+
+ Object[][] rtn = new Object[aacon.size()][1];
+ int i = 0;
+ for (ServiceWithParameters[] aa : aacon)
+ {
+ rtn[i++] = aa;
+ }
+ return rtn;
+ }
+ /**
+ * Run AACon on an alignment with defaults and verify Just Shenkin annotation
+ * appears
+ */
+ @Test(groups = { "External", "Network" }, dataProvider = "aacons")
+ public void testAAConAnnotAndRecovery(ServiceWithParameters service)
+ {
+ jalview.io.FileLoader fl = new jalview.io.FileLoader(false);
+ AlignFrame _af = fl.LoadFileWaitTillLoaded(testseqs,
+ jalview.io.DataSourceType.FILE);
+ assertNotNull("Couldn't load test data ('" + testseqs + "')", _af);
+ af = _af;
+ try
+ {
+ testAAConClient(_af, service);
+ } finally
+ {
+ af = null;
+ _af.setVisible(false);
+ _af.dispose();
+ _af = null;
+
+ }
+ }
+
+ /**
+ * triggers the given aacon worker on the alignment, waits for 5s and gives up
+ * or verifies SHENKIN annotation is produced.
+ *
+ * @param af
+ * - test data in an alignment frame
+ * @param aacon
+ * - the service to test
+ */
+ static void testAAConClient(AlignFrame af, ServiceWithParameters aacon)
+ {
+ SeqAnnotationServiceCalcWorker aaconClient = new SeqAnnotationServiceCalcWorker(
+ aacon, af, null,
+ null);
+ long current = System.currentTimeMillis(), limit = 15;
+ af.getViewport().getCalcManager().startWorker(aaconClient);
+ do
+ {
+ try
+ {
+ Thread.sleep(50);
+ } catch (InterruptedException x)
+ {
+ }
+ ;
+ assertTrue(
+ "Waited " + limit + "s for " + aacon.getHostURL()
+ + " - giving up.",
+ (System.currentTimeMillis() - current) < limit * 1000);
+ } while (af.getViewport().getCalcManager().isWorking());
+ AlignmentI orig_alig = af.getViewport().getAlignment();
+ boolean foundShenkin = false;
+ Iterable<AlignmentAnnotation> _aa=orig_alig
+ .findAnnotation(aacon.getAlignAnalysisUI().getCalcId());
+ assertTrue("No annotation from service",
+ _aa != null && _aa.iterator().hasNext());
+
+ for (AlignmentAnnotation aa : _aa)
+ {
+ assertTrue("AACon annotation not marked as autocalculated!",
+ aa.autoCalculated);
+ if ("shenkin".equals(aa.label.toLowerCase()))
+ {
+ foundShenkin = true;
+ break;
+ }
+ }
+ assertTrue("Failed to locate 'SHENKIN' annotation row.", foundShenkin);
+ }
+}
package jalview.ws.jabaws;
import java.util.Locale;
-
import static org.testng.AssertJUnit.assertNotNull;
import static org.testng.AssertJUnit.assertTrue;
import jalview.io.FileFormat;
import jalview.io.FormatAdapter;
import jalview.io.StockholmFileTest;
-import jalview.ws.jws2.AADisorderClient;
+import jalview.ws.api.ServiceWithParameters;
import jalview.ws.jws2.Jws2Discoverer;
-import jalview.ws.jws2.jabaws2.Jws2Instance;
+import jalview.ws.jws2.SeqAnnotationServiceCalcWorker;
+import jalview.ws.slivkaws.SlivkaWSDiscoverer;
import java.util.ArrayList;
import java.util.List;
public static Jws2Discoverer disc;
- public static List<Jws2Instance> iupreds;
+ public static List<ServiceWithParameters> iupreds;
- jalview.ws.jws2.AADisorderClient disorderClient;
+ jalview.ws.jws2.SeqAnnotationServiceCalcWorker disorderClient;
public static jalview.gui.AlignFrame af = null;
Thread.sleep(100);
}
- iupreds = new ArrayList<Jws2Instance>();
- for (Jws2Instance svc : disc.getServices())
+ SlivkaWSDiscoverer disc2 = SlivkaWSDiscoverer.getInstance();
+ disc2.startDiscoverer();
+ while (disc2.isRunning())
{
if (svc.getServiceTypeURI().toLowerCase(Locale.ROOT).contains("iupredws"))
{
@Test(groups = { "External", "Network" })
public void testDisorderAnnotExport()
{
- disorderClient = new AADisorderClient(iupreds.get(0), af, null, null);
+ disorderClient = new SeqAnnotationServiceCalcWorker(iupreds.get(0), af, null,
+ null);
af.getViewport().getCalcManager().startWorker(disorderClient);
do
{
AlignmentI orig_alig = af.getViewport().getAlignment();
// NOTE: Consensus annotation row cannot be exported and reimported
// faithfully - so we remove them
- List<AlignmentAnnotation> toremove = new ArrayList<AlignmentAnnotation>();
+ List<AlignmentAnnotation> toremove = new ArrayList<>();
for (AlignmentAnnotation aa : orig_alig.getAlignmentAnnotation())
{
if (aa.autoCalculated)
public static Jws2Discoverer getJabawsDiscoverer(boolean localhost)
{
jalview.ws.jws2.Jws2Discoverer disc = jalview.ws.jws2.Jws2Discoverer
- .getDiscoverer();
+ .getInstance();
String svcurls = "";
if (localhost)
{
services.add(url);
}
;
- Jws2Discoverer.getDiscoverer().setServiceUrls(services);
+ Jws2Discoverer.getInstance().setServiceUrls(services);
}
try
{
package jalview.ws.jabaws;
import java.util.Locale;
-
import static org.testng.AssertJUnit.assertNotNull;
import static org.testng.AssertJUnit.assertTrue;
import jalview.io.FormatAdapter;
import jalview.io.StockholmFileTest;
import jalview.project.Jalview2XML;
+import jalview.ws.api.ServiceWithParameters;
+import jalview.ws.jws2.JabaParamStore;
import jalview.ws.jws2.Jws2Discoverer;
-import jalview.ws.jws2.RNAalifoldClient;
+import jalview.ws.jws2.SeqAnnotationServiceCalcWorker;
import jalview.ws.jws2.SequenceAnnotationWSClient;
import jalview.ws.jws2.jabaws2.Jws2Instance;
import jalview.ws.params.AutoCalcSetting;
public static Jws2Instance rnaalifoldws;
- jalview.ws.jws2.RNAalifoldClient alifoldClient;
+ SeqAnnotationServiceCalcWorker alifoldClient;
public static jalview.gui.AlignFrame af = null;
Thread.sleep(100);
}
- for (Jws2Instance svc : disc.getServices())
+ for (ServiceWithParameters svc : disc.getServices())
{
if (svc.getServiceTypeURI().toLowerCase(Locale.ROOT).contains("rnaalifoldws"))
{
- rnaalifoldws = svc;
+ rnaalifoldws = (Jws2Instance) svc;
}
}
public void testRNAAliFoldValidStructure()
{
- alifoldClient = new RNAalifoldClient(rnaalifoldws, af, null, null);
+ alifoldClient = new SeqAnnotationServiceCalcWorker(rnaalifoldws, af, null,
+ null);
af.getViewport().getCalcManager().startWorker(alifoldClient);
public void testRNAStructExport()
{
- alifoldClient = new RNAalifoldClient(rnaalifoldws, af, null, null);
+ alifoldClient = new SeqAnnotationServiceCalcWorker(rnaalifoldws, af, null,
+ null);
af.getViewport().getCalcManager().startWorker(alifoldClient);
AlignmentI orig_alig = af.getViewport().getAlignment();
// JBPNote: this assert fails (2.10.2) because the 'Reference Positions'
// annotation is mistakenly recognised as an RNA annotation row when read in
- // as an annotation file.
+ // as an annotation file. bug is JAL-3122
verifyAnnotationFileIO("Testing RNAalifold Annotation IO", orig_alig);
}
opts.add(rg);
}
}
- alifoldClient = new RNAalifoldClient(rnaalifoldws, af, null, opts);
+ alifoldClient = new SeqAnnotationServiceCalcWorker(rnaalifoldws, af, null,
+ JabaParamStore.getJwsArgsfromJaba(opts));
af.getViewport().getCalcManager().startWorker(alifoldClient);
package jalview.ws.jws2;
import java.util.Locale;
-
import static org.testng.AssertJUnit.assertEquals;
import static org.testng.AssertJUnit.assertFalse;
import static org.testng.AssertJUnit.assertTrue;
import jalview.bin.Cache;
import jalview.gui.JvOptionPane;
+import jalview.ws.api.ServiceWithParameters;
+import jalview.ws.api.UIinfo;
import jalview.ws.jabaws.JalviewJabawsTestUtils;
import jalview.ws.jws2.jabaws2.Jws2Instance;
* To limit tests to specify services, add them to this list; leave list empty
* to test all
*/
- private static List<String> serviceTests = new ArrayList<String>();
+ private static List<String> serviceTests = new ArrayList<>();
private static Jws2Discoverer disc = null;
@Test(groups = { "Network" })
public void testWriteParameterSet() throws WrongParameterException
{
- for (Jws2Instance service : disc.getServices())
+ for (ServiceWithParameters _service : disc.getServices())
{
- if (isForTesting(service))
+ if (isForTesting(_service))
{
+ Jws2Instance service = (Jws2Instance) _service;
List<Preset> prl = null;
PresetManager prman = service.getPresets();
* @param service
* @return
*/
- public boolean isForTesting(Jws2Instance service)
+ public boolean isForTesting(UIinfo service)
{
return serviceTests.size() == 0
|| serviceTests.contains(service.serviceType.toLowerCase(Locale.ROOT));
@Test(groups = { "Network" })
public void testCopyOption()
{
- for (Jws2Instance service : disc.getServices())
+ for (ServiceWithParameters _service : disc.getServices())
{
- if (isForTesting(service))
+ if (isForTesting(_service))
{
+ Jws2Instance service = (Jws2Instance) _service;
List<Option<?>> options = service.getRunnerConfig().getOptions();
for (Option<?> o : options)
{
@Test(groups = { "Network" })
public void testCopyParameter()
{
- for (Jws2Instance service : disc.getServices())
+ for (ServiceWithParameters _service : disc.getServices())
{
- if (isForTesting(service))
+ if (isForTesting(_service))
{
+ Jws2Instance service = (Jws2Instance) _service;
List<Parameter> parameters = service.getRunnerConfig()
.getParameters();
for (Parameter o : parameters)
import jalview.gui.AlignFrame;
import jalview.gui.JvOptionPane;
+import jalview.ws.rest.clientdefs.ShmrRestClient;
import java.util.Map;
assertTrue(
"Test Rsd Exchange using using default Shmmr service failed.",
testRsdExchange("Test using default Shmmr service",
- RestClient.makeShmmrRestClient().service));
+ ShmrRestClient.makeShmmrRestClient().service));
}
@Test(groups = { "Functional" })
public void testShmmrServiceDataprep() throws Exception
{
- RestClient _rc = RestClient.makeShmmrRestClient();
+ RestClient _rc = ShmrRestClient.makeShmmrRestClient();
assertNotNull(_rc);
AlignFrame alf = new jalview.io.FileLoader(false)
.LoadFileWaitTillLoaded("examples/testdata/smad.fa",
if (!service.equals(newService))
{
System.err.println("Failed for service (" + desc + ").");
+ if (fromservicetostring.equals(newService.toString()))
+ {
+ System.err.println(
+ "Description strings are equivalent: fault during RestServiceDescription.equals()");
+ return false;
+ }
System.err.println("Original service and parsed service differ.");
System.err.println("Original: " + fromservicetostring);
System.err.println("Parsed : " + newService.toString());
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertTrue;
-import jalview.api.DBRefEntryI;
-import jalview.bin.Cache;
-import jalview.datamodel.DBRefEntry;
-import jalview.datamodel.DBRefSource;
-import jalview.datamodel.Sequence;
-import jalview.datamodel.SequenceI;
-import jalview.gui.JvOptionPane;
-import jalview.io.DataSourceType;
-import jalview.structure.StructureMapping;
-import jalview.xml.binding.sifts.Entry.Entity;
-
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;
+import jalview.api.DBRefEntryI;
+import jalview.bin.Cache;
+import jalview.datamodel.DBRefEntry;
+import jalview.datamodel.DBRefSource;
+import jalview.datamodel.Sequence;
+import jalview.datamodel.SequenceI;
+import jalview.gui.JvOptionPane;
+import jalview.io.DataSourceType;
+import jalview.structure.StructureMapping;
+import jalview.xml.binding.sifts.Entry.Entity;
import mc_view.Atom;
import mc_view.PDBfile;
Cache.loadProperties("test/jalview/io/testProps.jvprops");
// SIFTs entries are updated weekly - so use saved SIFTs file to enforce
// test reproducibility
- new SiftsSettings();
SiftsSettings.setSiftDownloadDirectory(jalview.bin.Cache.getDefault(
"sifts_download_dir", DEFAULT_SIFTS_DOWNLOAD_DIR));
SiftsSettings.setMapWithSifts(true);
atom.atomIndex = 7;
atoms.add(atom);
int actualAtomIndex = siftsClient.getAtomIndex(1, atoms);
- Assert.assertEquals(actualAtomIndex, siftsClient.UNASSIGNED);
+ Assert.assertEquals(actualAtomIndex, SiftsClient.UNASSIGNED);
actualAtomIndex = siftsClient.getAtomIndex(43, atoms);
Assert.assertEquals(actualAtomIndex, 7);
}
Assert.assertNull(entityP);
}
-
- @Test(groups = { "Network" })
- public void getLeadingIntegerFromString()
- {
- Assert.assertEquals(
- SiftsClient.getLeadingIntegerValue("1234abcd", -1), 1234);
- Assert.assertEquals(
- SiftsClient.getLeadingIntegerValue("1234", -1),
- 1234);
- Assert.assertEquals(
- SiftsClient.getLeadingIntegerValue("abcd", -1), -1);
- Assert.assertEquals(
- SiftsClient.getLeadingIntegerValue("abcd1234", -1), -1);
- Assert.assertEquals(
- SiftsClient.getLeadingIntegerValue("None", -1), -1);
- Assert.assertEquals(
- SiftsClient.getLeadingIntegerValue("Null", -1), -1);
- }
}
public void UrlDownloadTest()
{
UrlDownloadClient client = new UrlDownloadClient();
- String urlstring = "http://identifiers.org/rest/collections/";
+ String urlstring = "http://www.jalview.org/services/identifiers";
+ // was "http://identifiers.org/rest/collections/";
String outfile = "testfile.tmp";
try
// download file has a believable size
// identifiers.org file typically at least 250K
- Assert.assertTrue(f.length() > 250000);
-
+ long n = f.length();
if (f.exists())
{
f.delete();
}
+ // 74589
+ Assert.assertTrue(n > 70000);
+
}
public void setUp()
{
Cache.loadProperties("test/jalview/io/testProps.jvprops");
- Cache.applicationProperties.setProperty("STRUCT_FROM_PDB",
+ Cache.setPropertyNoSave("STRUCT_FROM_PDB",
Boolean.TRUE.toString());
- Cache.applicationProperties.setProperty("ADD_TEMPFACT_ANN",
+ Cache.setPropertyNoSave("ADD_TEMPFACT_ANN",
Boolean.TRUE.toString());
- Cache.applicationProperties.setProperty("ADD_SS_ANN",
+ Cache.setPropertyNoSave("ADD_SS_ANN",
Boolean.TRUE.toString());
StructureImportSettings.setDefaultStructureFileFormat("PDB");
}
--- /dev/null
+package jalview.bin;
+
+import java.io.File;
+import java.net.URISyntaxException;
+
+import jalview.gui.AlignFrame;
+import jalview.io.BioJsHTMLOutput;
+import jalview.io.FileFormatI;
+import jalview.io.HtmlSvgOutput;
+import jalview.util.Platform;
+
+/**
+ * Abandoned -- see JalviewApp
+ *
+ * A class to load parameters for either JalviewLite or Jalview
+ *
+ * @author hansonr
+ *
+ */
+public class JalviewAppLoader
+{
+
+ public JalviewAppLoader()
+ {
+ }
+
+}
\ No newline at end of file
--- /dev/null
+package jalview.bin;
+
+import java.util.List;
+
+import jalview.appletgui.js.JSFunctionExec;
+
+public interface JalviewJSApp
+{
+
+
+
+}
<param name="file2" value="${file2}" />
</antcall>
<echo message=" "/>
- <echo message="Missing message labels in Messages.properties compare to ${file2}"/>
+ <echo message="Missing message labels in Messages.properties compared to ${file2}"/>
<antcall target="compareProperties">
<param name="file2" value="resources/lang/Messages.properties"/>
<param name="file1" value="${file2}" />
+++ /dev/null
-java/applet/Applet.js
-java/applet/AppletContext.js
-java/applet/AppletStub.js
-java/applet/JSApplet.js
-java/awt/ActiveEvent.js
-java/awt/Adjustable.js
-java/awt/AWTEvent.js
-java/awt/AWTEventMulticaster.js
-java/awt/AWTKeyStroke.js
-java/awt/BasicStroke.js
-java/awt/BorderLayout.js
-java/awt/Button.js
-java/awt/Color.js
-java/awt/color/ColorSpace.js
-java/awt/Component.js
-java/awt/ComponentOrientation.js
-java/awt/ContainerOrderFocusTraversalPolicy.js
-java/awt/Container.js
-java/awt/Cursor.js
-java/awt/DefaultFocusTraversalPolicy.js
-java/awt/DefaultKeyboardFocusManager.js
-java/awt/Dialog.js
-java/awt/Dimension.js
-java/awt/dnd/peer/DropTargetPeer.js
-java/awt/event/ActionListener.js
-java/awt/event/AdjustmentEvent.js
-java/awt/event/AdjustmentListener.js
-java/awt/event/AWTEventListener.js
-java/awt/event/ComponentAdapter.js
-java/awt/event/ComponentEvent.js
-java/awt/event/ComponentListener.js
-java/awt/event/ContainerListener.js
-java/awt/event/FocusEvent.js
-java/awt/event/FocusListener.js
-java/awt/event/HierarchyBoundsListener.js
-java/awt/event/HierarchyListener.js
-java/awt/event/InputEvent.js
-java/awt/event/InputMethodListener.js
-java/awt/event/InvocationEvent.js
-java/awt/event/ItemEvent.js
-java/awt/event/ItemListener.js
-java/awt/event/KeyListener.js
-java/awt/event/MouseEvent.js
-java/awt/event/MouseListener.js
-java/awt/event/MouseMotionListener.js
-java/awt/event/MouseWheelListener.js
-java/awt/event/TextListener.js
-java/awt/event/WindowAdapter.js
-java/awt/event/WindowEvent.js
-java/awt/event/WindowFocusListener.js
-java/awt/event/WindowListener.js
-java/awt/event/WindowStateListener.js
-java/awt/EventDispatchThread.js
-java/awt/EventFilter.js
-java/awt/EventQueue.js
-java/awt/EventQueueItem.js
-java/awt/FlowLayout.js
-java/awt/FocusTraversalPolicy.js
-java/awt/Font.js
-java/awt/font/FontRenderContext.js
-java/awt/FontMetrics.js
-java/awt/Frame.js
-java/awt/geom/AffineTransform.js
-java/awt/geom/Dimension2D.js
-java/awt/geom/Path2D.js
-java/awt/geom/PathIterator.js
-java/awt/geom/Point2D.js
-java/awt/geom/Rectangle2D.js
-java/awt/geom/RectangularShape.js
-java/awt/geom/RectIterator.js
-java/awt/GraphicsCallback.js
-java/awt/GraphicsConfiguration.js
-java/awt/GraphicsDevice.js
-java/awt/GraphicsEnvironment.js
-java/awt/image/ImageObserver.js
-java/awt/Insets.js
-java/awt/ItemSelectable.js
-java/awt/JSComponent.js
-java/awt/JSDialog.js
-java/awt/JSFrame.js
-java/awt/JSPanel.js
-java/awt/KeyboardFocusManager.js
-java/awt/KeyEventDispatcher.js
-java/awt/KeyEventPostProcessor.js
-java/awt/Label.js
-java/awt/LayoutManager.js
-java/awt/LayoutManager2.js
-java/awt/LightweightDispatcher.js
-java/awt/Paint.js
-java/awt/Panel.js
-java/awt/peer/ComponentPeer.js
-java/awt/peer/ContainerPeer.js
-java/awt/peer/FramePeer.js
-java/awt/peer/KeyboardFocusManagerPeer.js
-java/awt/peer/LightweightPeer.js
-java/awt/peer/WindowPeer.js
-java/awt/Point.js
-java/awt/Queue.js
-java/awt/Rectangle.js
-java/awt/RenderingHints.js
-java/awt/Scrollbar.js
-java/awt/ScrollPane.js
-java/awt/Shape.js
-java/awt/Stroke.js
-java/awt/TextArea.js
-java/awt/TextComponent.js
-java/awt/TextField.js
-java/awt/Toolkit.js
-java/awt/Transparency.js
-java/awt/Window.js
-java/beans/ChangeListenerMap.js
-java/beans/PropertyChangeEvent.js
-java/beans/PropertyChangeListener.js
-java/beans/PropertyChangeSupport.js
-java/lang/AbstractStringBuilder.js
-java/lang/Class.js
-java/lang/Enum.js
-java/lang/Iterable.js
-java/lang/reflect/Constructor.js
-java/lang/reflect/Method.js
-java/lang/StringBuffer.js
-java/lang/StringBuilder.js
-java/lang/Thread.js
-java/lang/ThreadGroup.js
-java/math/RoundingMode.js
-java/net/URL.js
-java/net/URLStreamHandlerFactory.js
-java/text/CharacterIterator.js
-java/text/DecimalFormat.js
-java/text/DecimalFormatSymbols.js
-java/text/DigitList.js
-java/text/FieldPosition.js
-java/text/Format.js
-java/text/NumberFormat.js
-java/util/AbstractCollection.js
-java/util/AbstractList.js
-java/util/AbstractMap.js
-java/util/AbstractSequentialList.js
-java/util/AbstractSet.js
-java/util/ArrayList.js
-java/util/Arrays.js
-java/util/Collection.js
-java/util/Collections.js
-java/util/Comparator.js
-java/util/Deque.js
-java/util/Dictionary.js
-java/util/Enumeration.js
-java/util/EventListener.js
-java/util/EventObject.js
-java/util/HashMap.js
-java/util/HashSet.js
-java/util/Hashtable.js
-java/util/IdentityHashMap.js
-java/util/Iterator.js
-java/util/LinkedHashMap.js
-java/util/LinkedList.js
-java/util/List.js
-java/util/ListResourceBundle.js
-java/util/Locale.js
-java/util/Map.js
-java/util/Objects.js
-java/util/Queue.js
-java/util/Random.js
-java/util/RandomAccess.js
-java/util/ResourceBundle.js
-java/util/Set.js
-java/util/TimSort.js
-java/util/Vector.js
-javajs/api/JSFunction.js
-javajs/util/AjaxURLConnection.js
-javajs/util/AjaxURLStreamHandlerFactory.js
-javajs/util/AU.js
-javajs/util/JSThread.js
-javajs/util/Lst.js
-javajs/util/PT.js
-javajs/util/SB.js
-javax/net/ssl/HttpsUrlConnection.js
-javax/swing/AbstractAction.js
-javax/swing/AbstractButton.js
-javax/swing/AbstractListModel.js
-javax/swing/Action.js
-javax/swing/ActionMap.js
-javax/swing/AncestorNotifier.js
-javax/swing/ArrayTable.js
-javax/swing/border/AbstractBorder.js
-javax/swing/border/BevelBorder.js
-javax/swing/border/Border.js
-javax/swing/border/CompoundBorder.js
-javax/swing/border/EmptyBorder.js
-javax/swing/border/EtchedBorder.js
-javax/swing/border/LineBorder.js
-javax/swing/BorderFactory.js
-javax/swing/BoundedRangeModel.js
-javax/swing/BoxLayout.js
-javax/swing/ButtonGroup.js
-javax/swing/ButtonModel.js
-javax/swing/ClientPropertyKey.js
-javax/swing/ComboBoxModel.js
-javax/swing/DefaultBoundedRangeModel.js
-javax/swing/DefaultButtonModel.js
-javax/swing/DefaultComboBoxModel.js
-javax/swing/DefaultSingleSelectionModel.js
-javax/swing/DropMode.js
-javax/swing/event/AncestorEvent.js
-javax/swing/event/AncestorListener.js
-javax/swing/event/CaretEvent.js
-javax/swing/event/CaretListener.js
-javax/swing/event/ChangeEvent.js
-javax/swing/event/ChangeListener.js
-javax/swing/event/DocumentEvent.js
-javax/swing/event/DocumentListener.js
-javax/swing/event/EventListenerList.js
-javax/swing/event/ListDataEvent.js
-javax/swing/event/ListDataListener.js
-javax/swing/event/UndoableEditEvent.js
-javax/swing/event/UndoableEditListener.js
-javax/swing/FocusManager.js
-javax/swing/InternalFrameFocusTraversalPolicy.js
-javax/swing/LayoutComparator.js
-javax/swing/LayoutFocusTraversalPolicy.js
-javax/swing/SortingFocusTraversalPolicy.js
-javax/swing/SwingContainerOrderFocusTraversalPolicy.js
-javax/swing/SwingDefaultFocusTraversalPolicy.js
-javax/swing/InputMap.js
-javax/swing/JApplet.js
-javax/swing/JButton.js
-javax/swing/JCheckBox.js
-javax/swing/JCheckBoxMenuItem.js
-javax/swing/JComboBox.js
-javax/swing/JComponent.js
-javax/swing/JFrame.js
-javax/swing/JLabel.js
-javax/swing/JLayeredPane.js
-javax/swing/JMenu.js
-javax/swing/JMenuBar.js
-javax/swing/JMenuItem.js
-javax/swing/JPanel.js
-javax/swing/JPopupMenu.js
-javax/swing/JRadioButtonMenuItem.js
-javax/swing/JRootPane.js
-javax/swing/JScrollBar.js
-javax/swing/JScrollPane.js
-javax/swing/JSeparator.js
-javax/swing/JTextArea.js
-javax/swing/JTextField.js
-javax/swing/JToggleButton.js
-javax/swing/JViewport.js
-javax/swing/KeyboardManager.js
-javax/swing/KeyStroke.js
-javax/swing/ListModel.js
-javax/swing/LookAndFeel.js
-javax/swing/MenuElement.js
-javax/swing/MutableComboBoxModel.js
-javax/swing/plaf/ActionMapUIResource.js
-javax/swing/plaf/basic/BasicBorders.js
-javax/swing/plaf/BorderUIResource.js
-javax/swing/plaf/ColorUIResource.js
-javax/swing/plaf/ComponentUI.js
-javax/swing/plaf/DimensionUIResource.js
-javax/swing/plaf/FontUIResource.js
-javax/swing/plaf/InputMapUIResource.js
-javax/swing/plaf/InsetsUIResource.js
-javax/swing/plaf/UIResource.js
-javax/swing/RepaintManager.js
-javax/swing/RootPaneContainer.js
-javax/swing/Scrollable.js
-javax/swing/ScrollPaneConstants.js
-javax/swing/ScrollPaneLayout.js
-javax/swing/SingleSelectionModel.js
-javax/swing/SizeRequirements.js
-javax/swing/SwingConstants.js
-javax/swing/SwingPaintEventDispatcher.js
-javax/swing/SwingUtilities.js
-javax/swing/text/AbstractDocument.js
-javax/swing/text/AttributeSet.js
-javax/swing/text/Caret.js
-javax/swing/text/DefaultCaret.js
-javax/swing/text/DefaultEditorKit.js
-javax/swing/text/Document.js
-javax/swing/text/EditorKit.js
-javax/swing/text/Element.js
-javax/swing/text/GapContent.js
-javax/swing/text/GapVector.js
-javax/swing/text/JTextComponent.js
-javax/swing/text/MutableAttributeSet.js
-javax/swing/text/PlainDocument.js
-javax/swing/text/PlainView.js
-javax/swing/text/Position.js
-javax/swing/text/Segment.js
-javax/swing/text/SegmentCache.js
-javax/swing/text/SimpleAttributeSet.js
-javax/swing/text/Style.js
-javax/swing/text/StyleConstants.js
-javax/swing/text/StyleContext.js
-javax/swing/text/TabExpander.js
-javax/swing/text/TextAction.js
-javax/swing/text/Utilities.js
-javax/swing/text/View.js
-javax/swing/tree/TreeNode.js
-javax/swing/UIDefaults.js
-javax/swing/UIManager.js
-javax/swing/undo/AbstractUndoableEdit.js
-javax/swing/undo/CompoundEdit.js
-javax/swing/undo/UndoableEdit.js
-javax/swing/ViewportLayout.js
-javax/swing/WindowConstants.js
-sun/awt/AppContext.js
-sun/awt/AWTAutoShutdown.js
-sun/awt/CausedFocusEvent.js
-sun/awt/ComponentFactory.js
-sun/awt/KeyboardFocusManagerPeerProvider.js
-sun/awt/MostRecentKeyValue.js
-sun/awt/MostRecentThreadAppContext.js
-sun/awt/PaintEventDispatcher.js
-sun/awt/PostEventQueue.js
-sun/awt/RequestFocusController.js
-sun/awt/SunToolkit.js
-sun/awt/WindowClosingListener.js
-sun/awt/WindowClosingSupport.js
-sun/font/FontDesignMetrics.js
-sun/swing/DefaultLookup.js
-sun/swing/SwingLazyValue.js
-sun/text/resources/FormatData.js
-sun/text/resources/FormatData_en.js
-sun/util/resources/LocaleData.js
-swingjs/a2s/A2SContainer.js
-swingjs/a2s/A2SEvent.js
-swingjs/a2s/A2SListener.js
-swingjs/a2s/Applet.js
-swingjs/a2s/Button.js
-swingjs/a2s/Label.js
-swingjs/a2s/Panel.js
-swingjs/a2s/Scrollbar.js
-swingjs/a2s/ScrollPane.js
-swingjs/a2s/TextArea.js
-swingjs/a2s/TextField.js
-swingjs/api/Interface.js
-swingjs/api/js/DOMNode.js
-swingjs/api/js/HTML5CanvasContext2D.js
-swingjs/api/js/JSInterface.js
-swingjs/jquery/JQueryUI.js
-swingjs/JSApp.js
-swingjs/JSAppletThread.js
-swingjs/JSAppletViewer.js
-swingjs/JSFocusPeer.js
-swingjs/JSFontMetrics.js
-swingjs/JSFrameViewer.js
-swingjs/JSGraphics2D.js
-swingjs/JSGraphicsConfiguration.js
-swingjs/JSGraphicsEnvironment.js
-swingjs/JSMouse.js
-swingjs/JSNullComponentPeer.js
-swingjs/JSScreenDevice.js
-swingjs/JSThreadGroup.js
-swingjs/JSToolkit.js
-swingjs/JSUtil.js
-swingjs/plaf/ButtonListener.js
-swingjs/plaf/DefaultMenuLayout.js
-swingjs/plaf/HTML5LookAndFeel.js
-swingjs/plaf/JSAppletUI.js
-swingjs/plaf/JSButtonUI.js
-swingjs/plaf/JSCheckBoxMenuItemUI.js
-swingjs/plaf/JSCheckBoxUI.js
-swingjs/plaf/JSComboBoxUI.js
-swingjs/plaf/JSComponentUI.js
-swingjs/plaf/JSEventHandler.js
-swingjs/plaf/JSFrameUI.js
-swingjs/plaf/JSGraphicsUtils.js
-swingjs/plaf/JSLabelUI.js
-swingjs/plaf/JSLayeredPaneUI.js
-swingjs/plaf/JSLightweightUI.js
-swingjs/plaf/JSMenuBarUI.js
-swingjs/plaf/JSMenuItemUI.js
-swingjs/plaf/JSMenuUI.js
-swingjs/plaf/JSPanelUI.js
-swingjs/plaf/JSPopupMenuSeparatorUI.js
-swingjs/plaf/JSPopupMenuUI.js
-swingjs/plaf/JSRadioButtonMenuItemUI.js
-swingjs/plaf/JSRadioButtonUI.js
-swingjs/plaf/JSRootPaneUI.js
-swingjs/plaf/JSScrollBarUI.js
-swingjs/plaf/JSScrollPaneUI.js
-swingjs/plaf/JSSeparatorUI.js
-swingjs/plaf/JSSliderUI.js
-swingjs/plaf/JSTextAreaUI.js
-swingjs/plaf/JSTextFieldUI.js
-swingjs/plaf/JSTextUI.js
-swingjs/plaf/JSTextViewUI.js
-swingjs/plaf/JSViewportUI.js
-swingjs/plaf/JSWindowUI.js
-swingjs/plaf/LazyActionMap.js
-swingjs/plaf/Resizer.js
-swingjs/plaf/TextListener.js
-
-
-jalview/analysis/AAFrequency.js
-jalview/analysis/AlignSeq.js
-jalview/analysis/AlignmentAnnotationUtils.js
-jalview/analysis/AlignmentUtils.js
-jalview/analysis/AnnotationSorter.js
-jalview/analysis/Conservation.js
-jalview/analysis/CrossRef.js
-jalview/analysis/NJTree.js
-jalview/analysis/SeqsetUtils.js
-jalview/analysis/TreeBuilder.js
-jalview/analysis/TreeModel.js
-jalview/analysis/scoremodels/DistanceScoreModel.js
-jalview/analysis/scoremodels/FeatureDistanceModel.js
-jalview/analysis/scoremodels/PIDModel.js
-jalview/analysis/scoremodels/ScoreMatrix.js
-jalview/analysis/scoremodels/ScoreModels.js
-jalview/analysis/scoremodels/SimilarityParams.js
-jalview/analysis/scoremodels/SimilarityScoreModel.js
-jalview/api/AlignCalcManagerI.js
-jalview/api/AlignCalcWorkerI.js
-jalview/api/AlignViewControllerGuiI.js
-jalview/api/AlignViewControllerI.js
-jalview/api/AlignViewportI.js
-jalview/api/AlignmentViewPanel.js
-jalview/api/BuildDetailsI.js
-jalview/api/FeatureColourI.js
-jalview/api/FeatureRenderer.js
-jalview/api/FeaturesDisplayedI.js
-jalview/api/OOMHandlerI.js
-jalview/api/SequenceRenderer.js
-jalview/api/StructureSelectionManagerProvider.js
-jalview/api/ViewStyleI.js
-jalview/api/analysis/PairwiseScoreModelI.js
-jalview/api/analysis/ScoreModelI.js
-jalview/api/analysis/SimilarityParamsI.js
-jalview/bin/ArgsParser.js
-jalview/bin/BuildDetails.js
-jalview/bin/Cache.js
-jalview/bin/Jalview.js
-jalview/bin/JalviewJS2.js
-jalview/controller/AlignViewController.js
-jalview/datamodel/ASequence.js
-jalview/datamodel/ASequenceI.js
-jalview/datamodel/Alignment.js
-jalview/datamodel/AlignmentAnnotation.js
-jalview/datamodel/AlignmentI.js
-jalview/datamodel/AlignmentView.js
-jalview/datamodel/AnnotatedCollectionI.js
-jalview/datamodel/Annotation.js
-jalview/datamodel/BinaryNode.js
-jalview/datamodel/CigarArray.js
-jalview/datamodel/CigarBase.js
-jalview/datamodel/CigarSimple.js
-jalview/datamodel/ColumnSelection.js
-jalview/datamodel/ContiguousI.js
-jalview/datamodel/DBRefSource.js
-jalview/datamodel/HiddenColumns.js
-jalview/datamodel/HiddenColumnsCursor.js
-jalview/datamodel/HiddenCursorPosition.js
-jalview/datamodel/HiddenSequences.js
-jalview/datamodel/PDBEntry.js
-jalview/datamodel/Profile.js
-jalview/datamodel/ProfileI.js
-jalview/datamodel/Profiles.js
-jalview/datamodel/ProfilesI.js
-jalview/datamodel/Range.js
-jalview/datamodel/RangeIterator.js
-jalview/datamodel/ResidueCount.js
-jalview/datamodel/SearchResults.js
-jalview/datamodel/SearchResultsI.js
-jalview/datamodel/SeqCigar.js
-jalview/datamodel/Sequence.js
-jalview/datamodel/SequenceCollectionI.js
-jalview/datamodel/SequenceCursor.js
-jalview/datamodel/SequenceFeature.js
-jalview/datamodel/SequenceGroup.js
-jalview/datamodel/SequenceI.js
-jalview/datamodel/SequenceNode.js
-jalview/datamodel/features/FeatureLocationI.js
-jalview/datamodel/features/FeatureMatcher.js
-jalview/datamodel/features/FeatureMatcherI.js
-jalview/datamodel/features/FeatureMatcherSet.js
-jalview/datamodel/features/FeatureMatcherSetI.js
-jalview/datamodel/features/FeatureStore.js
-jalview/datamodel/features/RangeComparator.js
-jalview/datamodel/features/SequenceFeatures.js
-jalview/datamodel/features/SequenceFeaturesI.js
-jalview/gui/AlignFrame.js
-jalview/gui/AlignViewport.js
-jalview/gui/AlignmentPanel.js
-jalview/gui/AnnotationLabels.js
-jalview/gui/AnnotationPanel.js
-jalview/gui/CalculationChooser.js
-jalview/gui/ColourMenuHelper.js
-jalview/gui/ComboBoxTooltipRenderer.js
-jalview/gui/Desktop.js
-jalview/gui/FeatureRenderer.js
-jalview/gui/IProgressIndicator.js
-jalview/gui/IdCanvas.js
-jalview/gui/IdPanel.js
-jalview/gui/IdwidthAdjuster.js
-jalview/gui/JalviewChangeSupport.js
-jalview/gui/JvSwingUtils.js
-jalview/gui/PaintRefresher.js
-jalview/gui/PopupMenu.js
-jalview/gui/Preferences.js
-jalview/gui/ProgressBar.js
-jalview/gui/ScalePanel.js
-jalview/gui/SeqCanvas.js
-jalview/gui/SeqPanel.js
-jalview/gui/SequenceRenderer.js
-jalview/gui/TreeCanvas.js
-jalview/gui/TreePanel.js
-jalview/gui/ViewSelectionMenu.js
-jalview/io/AlignFile.js
-jalview/io/AlignmentFileReaderI.js
-jalview/io/AlignmentFileWriterI.js
-jalview/io/AppletFormatAdapter.js
-jalview/io/DataSourceType.js
-jalview/io/FileFormat.js
-jalview/io/FileFormatI.js
-jalview/io/FileFormats.js
-jalview/io/FileLoader.js
-jalview/io/FileParse.js
-jalview/io/IdentifyFile.js
-jalview/io/PIRFile.js
-jalview/io/ScoreMatrixFile.js
-jalview/io/SequenceAnnotationReport.js
-jalview/javascript/log4j/ConsoleAppender.js
-jalview/javascript/log4j/Layout.js
-jalview/javascript/log4j/Level.js
-jalview/javascript/log4j/Logger.js
-jalview/javascript/log4j/Priority.js
-jalview/javascript/log4j/SimpleLayout.js
-jalview/javascript/log4j/spi/OptionHandler.js
-jalview/jbgui/GAlignFrame.js
-jalview/jbgui/GAlignmentPanel.js
-jalview/jbgui/GDesktop.js
-jalview/jbgui/GPreferences.js
-jalview/jbgui/GTreePanel.js
-jalview/math/Matrix.js
-jalview/math/MatrixI.js
-jalview/project/Jalview2XML.js
-jalview/renderer/AnnotationRenderer.js
-jalview/renderer/AwtRenderPanelI.js
-jalview/renderer/ResidueColourFinder.js
-jalview/renderer/ResidueShader.js
-jalview/renderer/ResidueShaderI.js
-jalview/renderer/ScaleRenderer.js
-jalview/renderer/seqfeatures/FeatureRenderer.js
-jalview/schemes/Blosum62ColourScheme.js
-jalview/schemes/BuriedColourScheme.js
-jalview/schemes/ClustalxColourScheme.js
-jalview/schemes/ColourSchemeI.js
-jalview/schemes/ColourSchemeProperty.js
-jalview/schemes/ColourSchemes.js
-jalview/schemes/Consensus.js
-jalview/schemes/FeatureColour.js
-jalview/schemes/HelixColourScheme.js
-jalview/schemes/HydrophobicColourScheme.js
-jalview/schemes/JalviewColourScheme.js
-jalview/schemes/NucleotideColourScheme.js
-jalview/schemes/PIDColourScheme.js
-jalview/schemes/PurinePyrimidineColourScheme.js
-jalview/schemes/RNAHelicesColour.js
-jalview/schemes/ResidueColourScheme.js
-jalview/schemes/ResidueProperties.js
-jalview/schemes/ScoreColourScheme.js
-jalview/schemes/StrandColourScheme.js
-jalview/schemes/TCoffeeColourScheme.js
-jalview/schemes/TaylorColourScheme.js
-jalview/schemes/TurnColourScheme.js
-jalview/schemes/ZappoColourScheme.js
-jalview/structure/CommandListener.js
-jalview/structure/SelectionListener.js
-jalview/structure/SelectionSource.js
-jalview/structure/SequenceListener.js
-jalview/structure/StructureImportSettings.js
-jalview/structure/StructureSelectionManager.js
-jalview/structure/VamsasSource.js
-jalview/urls/CustomUrlProvider.js
-jalview/urls/IdOrgSettings.js
-jalview/urls/IdentifiersUrlProvider.js
-jalview/urls/UrlLinkDisplay.js
-jalview/urls/UrlLinkTableModel.js
-jalview/urls/UrlProvider.js
-jalview/urls/UrlProviderImpl.js
-jalview/urls/api/UrlProviderFactoryI.js
-jalview/urls/api/UrlProviderI.js
-jalview/urls/desktop/DesktopUrlProviderFactory.js
-jalview/util/ColorUtils.js
-jalview/util/Comparison.js
-jalview/util/DBRefUtils.js
-jalview/util/Format.js
-jalview/util/MessageManager.js
-jalview/util/Platform.js
-jalview/util/QuickSort.js
-jalview/util/StringUtils.js
-jalview/util/UrlLink.js
-jalview/util/jarInputStreamProvider.js
-jalview/util/matcher/Condition.js
-jalview/util/matcher/Matcher.js
-jalview/util/matcher/MatcherI.js
-jalview/viewmodel/AlignmentViewport.js
-jalview/viewmodel/ViewportListenerI.js
-jalview/viewmodel/ViewportProperties.js
-jalview/viewmodel/ViewportRanges.js
-jalview/viewmodel/seqfeatures/FeatureRendererModel.js
-jalview/viewmodel/seqfeatures/FeatureRendererSettings.js
-jalview/viewmodel/seqfeatures/FeaturesDisplayed.js
-jalview/viewmodel/styles/ViewStyle.js
-jalview/workers/AlignCalcManager.js
-jalview/workers/AlignCalcWorker.js
-jalview/workers/ConsensusThread.js
-jalview/workers/ConservationThread.js
-jalview/ws/sifts/SiftsSettings.js
-jalview/xml/binding/jalview/Annotation.js
-jalview/xml/binding/jalview/AnnotationElement.js
-jalview/xml/binding/jalview/Feature.js
-jalview/xml/binding/jalview/FeatureMatcher.js
-jalview/xml/binding/jalview/FeatureMatcherSet.js
-jalview/xml/binding/jalview/FilterBy.js
-jalview/xml/binding/jalview/JalviewModel.js
-jalview/xml/binding/jalview/NoValueColour.js
-jalview/xml/binding/jalview/Pdbentry.js
-jalview/xml/binding/jalview/Sequence.js
-jalview/xml/binding/jalview/SequenceSet.js
-jalview/xml/binding/jalview/SequenceType.js
-jalview/xml/binding/jalview/VAMSAS.js
-jalview/xml/binding/jalview/WebServiceParameterSet.js
+java/applet/Applet.js
java/applet/AppletContext.js
java/applet/AppletStub.js
java/applet/JSApplet.js
+java/awt/ActiveEvent.js
+java/awt/Adjustable.js
java/awt/AWTEvent.js
java/awt/AWTEventMulticaster.js
java/awt/AWTKeyStroke.js
-java/awt/ActiveEvent.js
-java/awt/Adjustable.js
-java/awt/AlphaComposite.js
java/awt/BasicStroke.js
java/awt/BorderLayout.js
+java/awt/Button.js
java/awt/Color.js
+java/awt/color/ColorSpace.js
java/awt/Component.js
java/awt/ComponentOrientation.js
-java/awt/Composite.js
-java/awt/Container.js
java/awt/ContainerOrderFocusTraversalPolicy.js
+java/awt/Container.js
java/awt/Cursor.js
java/awt/DefaultFocusTraversalPolicy.js
java/awt/DefaultKeyboardFocusManager.js
java/awt/Dialog.js
java/awt/Dimension.js
-java/awt/EventDispatchThread.js
-java/awt/EventFilter.js
-java/awt/EventQueue.js
-java/awt/EventQueueItem.js
-java/awt/FlowLayout.js
-java/awt/FocusTraversalPolicy.js
-java/awt/Font.js
-java/awt/FontMetrics.js
-java/awt/GraphicsCallback.js
-java/awt/GraphicsConfiguration.js
-java/awt/GraphicsDevice.js
-java/awt/GraphicsEnvironment.js
-java/awt/GridLayout.js
-java/awt/Image.js
-java/awt/Insets.js
-java/awt/ItemSelectable.js
-java/awt/JSComponent.js
-java/awt/JSDialog.js
-java/awt/JSFrame.js
-java/awt/JSPanel.js
-java/awt/KeyEventDispatcher.js
-java/awt/KeyEventPostProcessor.js
-java/awt/KeyboardFocusManager.js
-java/awt/LayoutManager.js
-java/awt/LayoutManager2.js
-java/awt/LightweightDispatcher.js
-java/awt/Paint.js
-java/awt/Point.js
-java/awt/Queue.js
-java/awt/Rectangle.js
-java/awt/RenderingHints.js
-java/awt/SentEvent.js
-java/awt/Shape.js
-java/awt/Stroke.js
-java/awt/Toolkit.js
-java/awt/Transparency.js
-java/awt/VKCollection.js
-java/awt/Window.js
-java/awt/color/ColorSpace.js
-java/awt/datatransfer/ClipboardOwner.js
-java/awt/datatransfer/FlavorMap.js
-java/awt/datatransfer/FlavorTable.js
-java/awt/datatransfer/SystemFlavorMap.js
-java/awt/dnd/DropTarget.js
-java/awt/dnd/DropTargetContext.js
-java/awt/dnd/DropTargetListener.js
java/awt/dnd/peer/DropTargetPeer.js
-java/awt/event/AWTEventListener.js
-java/awt/event/ActionEvent.js
java/awt/event/ActionListener.js
java/awt/event/AdjustmentEvent.js
java/awt/event/AdjustmentListener.js
+java/awt/event/AWTEventListener.js
java/awt/event/ComponentAdapter.js
java/awt/event/ComponentEvent.js
java/awt/event/ComponentListener.js
-java/awt/event/ContainerEvent.js
java/awt/event/ContainerListener.js
-java/awt/event/FocusAdapter.js
java/awt/event/FocusEvent.js
java/awt/event/FocusListener.js
java/awt/event/HierarchyBoundsListener.js
java/awt/event/InvocationEvent.js
java/awt/event/ItemEvent.js
java/awt/event/ItemListener.js
-java/awt/event/KeyAdapter.js
-java/awt/event/KeyEvent.js
java/awt/event/KeyListener.js
-java/awt/event/MouseAdapter.js
java/awt/event/MouseEvent.js
java/awt/event/MouseListener.js
-java/awt/event/MouseMotionAdapter.js
java/awt/event/MouseMotionListener.js
java/awt/event/MouseWheelListener.js
java/awt/event/TextListener.js
java/awt/event/WindowFocusListener.js
java/awt/event/WindowListener.js
java/awt/event/WindowStateListener.js
+java/awt/EventDispatchThread.js
+java/awt/EventFilter.js
+java/awt/EventQueue.js
+java/awt/EventQueueItem.js
+java/awt/FlowLayout.js
+java/awt/FocusTraversalPolicy.js
+java/awt/Font.js
java/awt/font/FontRenderContext.js
+java/awt/FontMetrics.js
+java/awt/Frame.js
java/awt/geom/AffineTransform.js
java/awt/geom/Dimension2D.js
java/awt/geom/Path2D.js
java/awt/geom/PathIterator.js
java/awt/geom/Point2D.js
-java/awt/geom/RectIterator.js
java/awt/geom/Rectangle2D.js
java/awt/geom/RectangularShape.js
-java/awt/image/BufferedImage.js
-java/awt/image/ColorModel.js
-java/awt/image/DataBuffer.js
-java/awt/image/DataBufferInt.js
-java/awt/image/DirectColorModel.js
+java/awt/geom/RectIterator.js
+java/awt/GraphicsCallback.js
+java/awt/GraphicsConfiguration.js
+java/awt/GraphicsDevice.js
+java/awt/GraphicsEnvironment.js
java/awt/image/ImageObserver.js
-java/awt/image/PackedColorModel.js
-java/awt/image/Raster.js
-java/awt/image/RenderedImage.js
-java/awt/image/SampleModel.js
-java/awt/image/SinglePixelPackedSampleModel.js
-java/awt/image/WritableRaster.js
+java/awt/Insets.js
+java/awt/ItemSelectable.js
+java/awt/JSComponent.js
+java/awt/JSDialog.js
+java/awt/JSFrame.js
+java/awt/JSPanel.js
+java/awt/KeyboardFocusManager.js
+java/awt/KeyEventDispatcher.js
+java/awt/KeyEventPostProcessor.js
+java/awt/Label.js
+java/awt/LayoutManager.js
+java/awt/LayoutManager2.js
+java/awt/LightweightDispatcher.js
+java/awt/Paint.js
+java/awt/Panel.js
java/awt/peer/ComponentPeer.js
java/awt/peer/ContainerPeer.js
java/awt/peer/FramePeer.js
java/awt/peer/KeyboardFocusManagerPeer.js
java/awt/peer/LightweightPeer.js
java/awt/peer/WindowPeer.js
-java/awt/print/Printable.js
+java/awt/Point.js
+java/awt/Queue.js
+java/awt/Rectangle.js
+java/awt/RenderingHints.js
+java/awt/Scrollbar.js
+java/awt/ScrollPane.js
+java/awt/Shape.js
+java/awt/Stroke.js
+java/awt/TextArea.js
+java/awt/TextComponent.js
+java/awt/TextField.js
+java/awt/Toolkit.js
+java/awt/Transparency.js
+java/awt/Window.js
java/beans/ChangeListenerMap.js
java/beans/PropertyChangeEvent.js
java/beans/PropertyChangeListener.js
java/beans/PropertyChangeSupport.js
-java/io/BufferedInputStream.js
-java/io/BufferedReader.js
-java/io/ByteArrayInputStream.js
-java/io/Closeable.js
-java/io/File.js
-java/io/FileDescriptor.js
-java/io/FileInputStream.js
-java/io/FileReader.js
-java/io/FileSystem.js
-java/io/FilterInputStream.js
-java/io/InputStream.js
-java/io/InputStreamReader.js
-java/io/PushbackInputStream.js
-java/io/Reader.js
java/lang/AbstractStringBuilder.js
-java/lang/AutoCloseable.js
java/lang/Class.js
java/lang/Enum.js
java/lang/Iterable.js
-java/lang/Readable.js
-java/lang/Runtime.js
+java/lang/reflect/Constructor.js
+java/lang/reflect/Method.js
java/lang/StringBuffer.js
java/lang/StringBuilder.js
java/lang/Thread.js
java/lang/ThreadGroup.js
-java/lang/reflect/Constructor.js
-java/lang/reflect/Method.js
-java/math/BigDecimal.js
-java/math/BigInteger.js
-java/math/MathContext.js
java/math/RoundingMode.js
-java/net/HttpURLConnection.js
-java/net/MalformedURLException.js
java/net/URL.js
-java/net/URLConnection.js
-java/net/URLDecoder.js
-java/net/URLStreamHandler.js
java/net/URLStreamHandlerFactory.js
-java/nio/Bits.js
-java/nio/Buffer.js
-java/nio/ByteBuffer.js
-java/nio/ByteOrder.js
-java/nio/CharBuffer.js
-java/nio/HeapByteBuffer.js
-java/nio/HeapCharBuffer.js
-java/nio/charset/Charset.js
-java/nio/charset/CharsetDecoder.js
-java/nio/charset/CoderResult.js
-java/nio/charset/CodingErrorAction.js
-java/security/AccessControlContext.js
-java/security/AccessController.js
-java/security/PrivilegedAction.js
-java/security/PrivilegedExceptionAction.js
-java/text/AttributedCharacterIterator.js
java/text/CharacterIterator.js
-java/text/DateFormat.js
-java/text/DateFormatSymbols.js
java/text/DecimalFormat.js
java/text/DecimalFormatSymbols.js
java/text/DigitList.js
java/text/FieldPosition.js
java/text/Format.js
-java/text/MessageFormat.js
java/text/NumberFormat.js
-java/text/SimpleDateFormat.js
java/util/AbstractCollection.js
java/util/AbstractList.js
java/util/AbstractMap.js
-java/util/AbstractQueue.js
java/util/AbstractSequentialList.js
java/util/AbstractSet.js
-java/util/ArrayDeque.js
java/util/ArrayList.js
java/util/Arrays.js
-java/util/BitSet.js
-java/util/Calendar.js
java/util/Collection.js
java/util/Collections.js
java/util/Comparator.js
java/util/Deque.js
java/util/Dictionary.js
-java/util/DualPivotQuicksort.js
java/util/Enumeration.js
java/util/EventListener.js
java/util/EventObject.js
-java/util/GregorianCalendar.js
java/util/HashMap.js
java/util/HashSet.js
java/util/Hashtable.js
java/util/LinkedHashMap.js
java/util/LinkedList.js
java/util/List.js
-java/util/ListIterator.js
java/util/ListResourceBundle.js
java/util/Locale.js
java/util/Map.js
-java/util/NavigableMap.js
-java/util/NavigableSet.js
java/util/Objects.js
-java/util/Properties.js
-java/util/PropertyResourceBundle.js
java/util/Queue.js
+java/util/Random.js
java/util/RandomAccess.js
java/util/ResourceBundle.js
java/util/Set.js
-java/util/SortedMap.js
-java/util/SortedSet.js
-java/util/StringTokenizer.js
java/util/TimSort.js
-java/util/TimeZone.js
-java/util/TreeMap.js
-java/util/TreeSet.js
java/util/Vector.js
-java/util/concurrent/AbstractExecutorService.js
-java/util/concurrent/BlockingQueue.js
-java/util/concurrent/ConcurrentHashMap.js
-java/util/concurrent/ConcurrentMap.js
-java/util/concurrent/Executor.js
-java/util/concurrent/ExecutorService.js
-java/util/concurrent/Executors.js
-java/util/concurrent/LinkedBlockingQueue.js
-java/util/concurrent/RejectedExecutionHandler.js
-java/util/concurrent/Semaphore.js
-java/util/concurrent/ThreadFactory.js
-java/util/concurrent/ThreadPoolExecutor.js
-java/util/concurrent/TimeUnit.js
-java/util/concurrent/atomic/AtomicBoolean.js
-java/util/concurrent/atomic/AtomicInteger.js
-java/util/concurrent/locks/AbstractOwnableSynchronizer.js
-java/util/concurrent/locks/AbstractQueuedSynchronizer.js
-java/util/concurrent/locks/Condition.js
-java/util/concurrent/locks/Lock.js
-java/util/concurrent/locks/ReadWriteLock.js
-java/util/concurrent/locks/ReentrantLock.js
-java/util/concurrent/locks/ReentrantReadWriteLock.js
-java/util/jar/JarEntry.js
-java/util/jar/JarInputStream.js
-java/util/logging/Level.js
-java/util/logging/Logger.js
-java/util/regex/MatchResult.js
-java/util/regex/Matcher.js
-java/util/regex/Pattern.js
-java/util/zip/CRC32.js
-java/util/zip/Inflater.js
-java/util/zip/InflaterInputStream.js
-java/util/zip/ZipConstants.js
-java/util/zip/ZipEntry.js
-java/util/zip/ZipInputStream.js
-javajs/api/GenericLineReader.js
javajs/api/JSFunction.js
-javajs/api/JSONEncodable.js
-javajs/util/AU.js
javajs/util/AjaxURLConnection.js
-javajs/util/AjaxURLStreamHandler.js
javajs/util/AjaxURLStreamHandlerFactory.js
-javajs/util/Encoding.js
+javajs/util/AU.js
javajs/util/JSThread.js
javajs/util/Lst.js
javajs/util/PT.js
-javajs/util/Rdr.js
javajs/util/SB.js
+javax/net/ssl/HttpsUrlConnection.js
javax/swing/AbstractAction.js
javax/swing/AbstractButton.js
javax/swing/AbstractListModel.js
javax/swing/ActionMap.js
javax/swing/AncestorNotifier.js
javax/swing/ArrayTable.js
+javax/swing/border/AbstractBorder.js
+javax/swing/border/BevelBorder.js
+javax/swing/border/Border.js
+javax/swing/border/CompoundBorder.js
+javax/swing/border/EmptyBorder.js
+javax/swing/border/EtchedBorder.js
+javax/swing/border/LineBorder.js
javax/swing/BorderFactory.js
javax/swing/BoundedRangeModel.js
javax/swing/BoxLayout.js
javax/swing/ButtonModel.js
javax/swing/ClientPropertyKey.js
javax/swing/ComboBoxModel.js
-javax/swing/ComponentInputMap.js
javax/swing/DefaultBoundedRangeModel.js
javax/swing/DefaultButtonModel.js
javax/swing/DefaultComboBoxModel.js
-javax/swing/DefaultDesktopManager.js
-javax/swing/DefaultListCellRenderer.js
javax/swing/DefaultSingleSelectionModel.js
-javax/swing/DesktopManager.js
+javax/swing/DropMode.js
+javax/swing/event/AncestorEvent.js
+javax/swing/event/AncestorListener.js
+javax/swing/event/CaretEvent.js
+javax/swing/event/CaretListener.js
+javax/swing/event/ChangeEvent.js
+javax/swing/event/ChangeListener.js
+javax/swing/event/DocumentEvent.js
+javax/swing/event/DocumentListener.js
+javax/swing/event/EventListenerList.js
+javax/swing/event/ListDataEvent.js
+javax/swing/event/ListDataListener.js
+javax/swing/event/UndoableEditEvent.js
+javax/swing/event/UndoableEditListener.js
+javax/swing/FocusManager.js
+javax/swing/InternalFrameFocusTraversalPolicy.js
+javax/swing/LayoutComparator.js
+javax/swing/LayoutFocusTraversalPolicy.js
+javax/swing/SortingFocusTraversalPolicy.js
+javax/swing/SwingContainerOrderFocusTraversalPolicy.js
+javax/swing/SwingDefaultFocusTraversalPolicy.js
javax/swing/InputMap.js
javax/swing/JApplet.js
javax/swing/JButton.js
javax/swing/JCheckBoxMenuItem.js
javax/swing/JComboBox.js
javax/swing/JComponent.js
-javax/swing/JDesktopPane.js
-javax/swing/JDialog.js
javax/swing/JFrame.js
-javax/swing/JInternalFrame.js
javax/swing/JLabel.js
javax/swing/JLayeredPane.js
javax/swing/JMenu.js
javax/swing/JMenuItem.js
javax/swing/JPanel.js
javax/swing/JPopupMenu.js
-javax/swing/JProgressBar.js
-javax/swing/JRadioButton.js
javax/swing/JRadioButtonMenuItem.js
javax/swing/JRootPane.js
javax/swing/JScrollBar.js
javax/swing/JScrollPane.js
javax/swing/JSeparator.js
-javax/swing/JTabbedPane.js
+javax/swing/JTextArea.js
+javax/swing/JTextField.js
javax/swing/JToggleButton.js
-javax/swing/JToolTip.js
javax/swing/JViewport.js
-javax/swing/JWindow.js
-javax/swing/KeyStroke.js
javax/swing/KeyboardManager.js
-javax/swing/ListCellRenderer.js
+javax/swing/KeyStroke.js
javax/swing/ListModel.js
javax/swing/LookAndFeel.js
javax/swing/MenuElement.js
-javax/swing/MenuSelectionManager.js
javax/swing/MutableComboBoxModel.js
-javax/swing/Popup.js
-javax/swing/PopupFactory.js
+javax/swing/plaf/ActionMapUIResource.js
+javax/swing/plaf/basic/BasicBorders.js
+javax/swing/plaf/BorderUIResource.js
+javax/swing/plaf/ColorUIResource.js
+javax/swing/plaf/ComponentUI.js
+javax/swing/plaf/DimensionUIResource.js
+javax/swing/plaf/FontUIResource.js
+javax/swing/plaf/InputMapUIResource.js
+javax/swing/plaf/InsetsUIResource.js
+javax/swing/plaf/UIResource.js
javax/swing/RepaintManager.js
javax/swing/RootPaneContainer.js
+javax/swing/Scrollable.js
javax/swing/ScrollPaneConstants.js
javax/swing/ScrollPaneLayout.js
-javax/swing/Scrollable.js
javax/swing/SingleSelectionModel.js
javax/swing/SizeRequirements.js
javax/swing/SwingConstants.js
javax/swing/SwingPaintEventDispatcher.js
javax/swing/SwingUtilities.js
-javax/swing/Timer.js
-javax/swing/ToolTipManager.js
+javax/swing/text/AbstractDocument.js
+javax/swing/text/AttributeSet.js
+javax/swing/text/Caret.js
+javax/swing/text/DefaultCaret.js
+javax/swing/text/DefaultEditorKit.js
+javax/swing/text/Document.js
+javax/swing/text/EditorKit.js
+javax/swing/text/Element.js
+javax/swing/text/GapContent.js
+javax/swing/text/GapVector.js
+javax/swing/text/JTextComponent.js
+javax/swing/text/MutableAttributeSet.js
+javax/swing/text/PlainDocument.js
+javax/swing/text/PlainView.js
+javax/swing/text/Position.js
+javax/swing/text/Segment.js
+javax/swing/text/SegmentCache.js
+javax/swing/text/SimpleAttributeSet.js
+javax/swing/text/Style.js
+javax/swing/text/StyleConstants.js
+javax/swing/text/StyleContext.js
+javax/swing/text/TabExpander.js
+javax/swing/text/TextAction.js
+javax/swing/text/Utilities.js
+javax/swing/text/View.js
+javax/swing/tree/TreeNode.js
javax/swing/UIDefaults.js
javax/swing/UIManager.js
+javax/swing/undo/AbstractUndoableEdit.js
+javax/swing/undo/CompoundEdit.js
+javax/swing/undo/UndoableEdit.js
javax/swing/ViewportLayout.js
javax/swing/WindowConstants.js
-javax/swing/border/AbstractBorder.js
-javax/swing/border/BevelBorder.js
-javax/swing/border/Border.js
-javax/swing/border/EmptyBorder.js
-javax/swing/border/EtchedBorder.js
-javax/swing/border/LineBorder.js
-javax/swing/border/TitledBorder.js
-javax/swing/event/AncestorEvent.js
-javax/swing/event/AncestorListener.js
-javax/swing/event/ChangeEvent.js
-javax/swing/event/ChangeListener.js
-javax/swing/event/EventListenerList.js
-javax/swing/event/InternalFrameAdapter.js
-javax/swing/event/InternalFrameEvent.js
-javax/swing/event/InternalFrameListener.js
-javax/swing/event/ListDataListener.js
-javax/swing/event/MenuKeyListener.js
-javax/swing/event/MenuListener.js
-javax/swing/event/TableModelListener.js
-javax/swing/plaf/ActionMapUIResource.js
-javax/swing/plaf/BorderUIResource.js
-javax/swing/plaf/ColorUIResource.js
-javax/swing/plaf/ComponentInputMapUIResource.js
-javax/swing/plaf/ComponentUI.js
-javax/swing/plaf/DimensionUIResource.js
-javax/swing/plaf/FontUIResource.js
-javax/swing/plaf/InsetsUIResource.js
-javax/swing/plaf/UIResource.js
-javax/swing/plaf/basic/BasicBorders.js
-javax/swing/table/AbstractTableModel.js
-javax/swing/table/TableModel.js
-javax/xml/bind/ContextFinder.js
-javax/xml/bind/GetPropertyAction.js
-javax/xml/bind/JAXBContext.js
-javax/xml/bind/JAXBContextFactory.js
-javax/xml/bind/JAXBElement.js
-javax/xml/bind/ModuleUtil.js
-javax/xml/bind/ServiceLoaderUtil.js
-javax/xml/bind/Unmarshaller.js
-javax/xml/bind/ValidationEventHandler.js
-javax/xml/bind/annotation/adapters/CollapsedStringAdapter.js
-javax/xml/bind/annotation/adapters/XmlAdapter.js
-javax/xml/bind/helpers/AbstractUnmarshallerImpl.js
-javax/xml/bind/helpers/DefaultValidationEventHandler.js
-javax/xml/datatype/XMLGregorianCalendar.js
-javax/xml/namespace/QName.js
-javax/xml/stream/XMLInputFactory.js
-javax/xml/stream/XMLStreamReader.js
-org/apache/xerces/jaxp/datatype/XMLGregorianCalendarImpl.js
-org/json/simple/parser/JSONParser.js
-org/json/simple/parser/ParseException.js
-org/json/simple/parser/Yylex.js
-org/xml/sax/AttributeList.js
-org/xml/sax/Attributes.js
-org/xml/sax/ContentHandler.js
-org/xml/sax/InputSource.js
-org/xml/sax/Parser.js
-org/xml/sax/XMLReader.js
-org/xml/sax/ext/Attributes2.js
-sun/awt/AWTAccessor.js
-sun/awt/AWTAutoShutdown.js
sun/awt/AppContext.js
+sun/awt/AWTAutoShutdown.js
sun/awt/CausedFocusEvent.js
sun/awt/ComponentFactory.js
-sun/awt/EventQueueItem.js
sun/awt/KeyboardFocusManagerPeerProvider.js
sun/awt/MostRecentKeyValue.js
sun/awt/MostRecentThreadAppContext.js
sun/awt/PaintEventDispatcher.js
sun/awt/PostEventQueue.js
sun/awt/RequestFocusController.js
-sun/awt/SunGraphicsCallback.js
sun/awt/SunToolkit.js
sun/awt/WindowClosingListener.js
sun/awt/WindowClosingSupport.js
-sun/awt/image/DataStealer.js
-sun/awt/image/IntegerComponentRaster.js
-sun/awt/image/IntegerInterleavedRaster.js
-sun/awt/image/SunWritableRaster.js
sun/font/FontDesignMetrics.js
-sun/java2d/StateTrackable.js
-sun/java2d/StateTrackableDelegate.js
-sun/nio/cs/ArrayDecoder.js
-sun/nio/cs/HistoricallyNamedCharset.js
-sun/nio/cs/StandardCharsets.js
-sun/nio/cs/ThreadLocalCoders.js
-sun/nio/cs/UTF_8.js
-sun/nio/cs/Unicode.js
sun/swing/DefaultLookup.js
sun/swing/SwingLazyValue.js
-sun/swing/UIAction.js
sun/text/resources/FormatData.js
-sun/text/resources/FormatData_en.js
-sun/util/calendar/AbstractCalendar.js
-sun/util/calendar/BaseCalendar.js
-sun/util/calendar/CalendarDate.js
-sun/util/calendar/CalendarSystem.js
-sun/util/calendar/CalendarUtils.js
-sun/util/calendar/Gregorian.js
-sun/util/calendar/ZoneInfo.js
+sun/text/resources/en/FormatData_en.js
sun/util/resources/LocaleData.js
+swingjs/a2s/A2SContainer.js
+swingjs/a2s/A2SEvent.js
+swingjs/a2s/A2SListener.js
+swingjs/a2s/Applet.js
+swingjs/a2s/Button.js
+swingjs/a2s/Label.js
+swingjs/a2s/Panel.js
+swingjs/a2s/Scrollbar.js
+swingjs/a2s/ScrollPane.js
+swingjs/a2s/TextArea.js
+swingjs/a2s/TextField.js
+swingjs/api/Interface.js
+swingjs/api/js/DOMNode.js
+swingjs/api/js/HTML5CanvasContext2D.js
+swingjs/api/js/JSInterface.js
+swingjs/jquery/JQueryUI.js
swingjs/JSApp.js
-swingjs/JSApplet.js
swingjs/JSAppletThread.js
swingjs/JSAppletViewer.js
-swingjs/JSCharSet.js
swingjs/JSFocusPeer.js
swingjs/JSFontMetrics.js
swingjs/JSFrameViewer.js
swingjs/JSGraphics2D.js
swingjs/JSGraphicsConfiguration.js
swingjs/JSGraphicsEnvironment.js
-swingjs/JSKeyEvent.js
-swingjs/JSMenuManager.js
swingjs/JSMouse.js
+swingjs/JSNullComponentPeer.js
swingjs/JSScreenDevice.js
swingjs/JSThreadGroup.js
swingjs/JSToolkit.js
swingjs/JSUtil.js
-swingjs/a2s/Dialog.js
-swingjs/api/Interface.js
-swingjs/api/js/DOMNode.js
-swingjs/api/js/HTML5CanvasContext2D.js
-swingjs/api/js/JSInterface.js
-swingjs/jquery/JQueryUI.js
-swingjs/jzlib/Adler32.js
-swingjs/jzlib/CRC32.js
-swingjs/jzlib/Checksum.js
-swingjs/jzlib/InfBlocks.js
-swingjs/jzlib/InfCodes.js
-swingjs/jzlib/InfTree.js
-swingjs/jzlib/Inflate.js
-swingjs/jzlib/Inflater.js
-swingjs/jzlib/InflaterInputStream.js
-swingjs/jzlib/ZStream.js
swingjs/plaf/ButtonListener.js
swingjs/plaf/DefaultMenuLayout.js
swingjs/plaf/HTML5LookAndFeel.js
swingjs/plaf/JSCheckBoxUI.js
swingjs/plaf/JSComboBoxUI.js
swingjs/plaf/JSComponentUI.js
-swingjs/plaf/JSDesktopIconUI.js
-swingjs/plaf/JSDesktopPaneUI.js
swingjs/plaf/JSEventHandler.js
swingjs/plaf/JSFrameUI.js
swingjs/plaf/JSGraphicsUtils.js
-swingjs/plaf/JSInternalFrameUI.js
swingjs/plaf/JSLabelUI.js
swingjs/plaf/JSLayeredPaneUI.js
swingjs/plaf/JSLightweightUI.js
swingjs/plaf/JSPanelUI.js
swingjs/plaf/JSPopupMenuSeparatorUI.js
swingjs/plaf/JSPopupMenuUI.js
-swingjs/plaf/JSPopupUI.js
-swingjs/plaf/JSProgressBarUI.js
swingjs/plaf/JSRadioButtonMenuItemUI.js
swingjs/plaf/JSRadioButtonUI.js
swingjs/plaf/JSRootPaneUI.js
swingjs/plaf/JSScrollPaneUI.js
swingjs/plaf/JSSeparatorUI.js
swingjs/plaf/JSSliderUI.js
-swingjs/plaf/JSTabbedPaneUI.js
-swingjs/plaf/JSToolTipUI.js
+swingjs/plaf/JSTextAreaUI.js
+swingjs/plaf/JSTextFieldUI.js
+swingjs/plaf/JSTextUI.js
+swingjs/plaf/JSTextViewUI.js
swingjs/plaf/JSViewportUI.js
swingjs/plaf/JSWindowUI.js
swingjs/plaf/LazyActionMap.js
swingjs/plaf/Resizer.js
-swingjs/xml/JSJAXBClass.js
-swingjs/xml/JSJAXBContext.js
-swingjs/xml/JSJAXBContextFactory.js
-swingjs/xml/JSJAXBField.js
-swingjs/xml/JSJAXBUnmarshaller.js
-swingjs/xml/JSSAXAttributes.js
-swingjs/xml/JSSAXParser.js
-swingjs/xml/JSXMLGregorianCalendarImpl.js
-swingjs/xml/JSXMLInputFactory.js
-swingjs/xml/JSXMLStreamReader.js
+swingjs/plaf/TextListener.js
+
+
--- /dev/null
+jalview/ext/jmol/JalviewJmolBinding.js
+jalview/ext/jmol/JmolCommands.js
+jalview/ext/jmol/JmolParser.js
+jalview/gui/AppJmol.js
+jalview/gui/AppJmolBinding.js
+jalview/gui/StructureViewerBase.js
+jalview/io/StructureFile.js
+jalview/jbgui/GStructureViewer.js
+jalview/renderer/seqfeatures/FeatureColourFinder.js
+jalview/structure/StructureListener.js
+jalview/structure/StructureMapping.js
+jalview/structure/StructureMappingcommandSet.js
+jalview/structures/models/AAStructureBindingModel.js
+jalview/structures/models/SequenceStructureBindingModel.js
+jalview/util/CaseInsensitiveString.js
+jalview/util/HttpUtils.js
+jalview/util/MapList.js
+jalview/ws/dbsources/EbiFileRetrievedProxy.js
+jalview/ws/dbsources/Pdb.js
+jalview/ws/seqfetcher/DbSourceProxy.js
+jalview/ws/seqfetcher/DbSourceProxyImpl.js
+java/awt/font/TextAttribute.js
+java/awt/image/ImageProducer.js
+java/awt/image/PixelGrabber.js
+java/io/BufferedWriter.js
+java/io/FilterOutputStream.js
+java/io/OutputStream.js
+java/io/OutputStreamWriter.js
+java/io/PrintStream.js
+java/io/StringWriter.js
+java/io/Writer.js
+javajs/api/BytePoster.js
+javajs/api/GenericOutputChannel.js
+javajs/util/A4.js
+javajs/util/BS.js
+javajs/util/CU.js
+javajs/util/DF.js
+javajs/util/LimitedLineReader.js
+javajs/util/M3.js
+javajs/util/M34.js
+javajs/util/M4.js
+javajs/util/Measure.js
+javajs/util/OC.js
+javajs/util/P3.js
+javajs/util/P3i.js
+javajs/util/P4.js
+javajs/util/T3.js
+javajs/util/T3i.js
+javajs/util/T4.js
+javajs/util/V3.js
+mc_view/Atom.js
+mc_view/Bond.js
+mc_view/PDBChain.js
+mc_view/Residue.js
+org/jmol/adapter/readers/pdb/PdbReader.js
+org/jmol/adapter/smarter/Atom.js
+org/jmol/adapter/smarter/AtomIterator.js
+org/jmol/adapter/smarter/AtomSetCollection.js
+org/jmol/adapter/smarter/AtomSetCollectionReader.js
+org/jmol/adapter/smarter/AtomSetObject.js
+org/jmol/adapter/smarter/Bond.js
+org/jmol/adapter/smarter/BondIterator.js
+org/jmol/adapter/smarter/Resolver.js
+org/jmol/adapter/smarter/SmarterJmolAdapter.js
+org/jmol/adapter/smarter/Structure.js
+org/jmol/api/AtomIndexIterator.js
+org/jmol/api/EventManager.js
+org/jmol/api/GenericFileInterface.js
+org/jmol/api/GenericMouseInterface.js
+org/jmol/api/GenericPlatform.js
+org/jmol/api/Interface.js
+org/jmol/api/JmolAdapter.js
+org/jmol/api/JmolAdapterAtomIterator.js
+org/jmol/api/JmolAdapterBondIterator.js
+org/jmol/api/JmolCallbackListener.js
+org/jmol/api/JmolGraphicsInterface.js
+org/jmol/api/JmolPropertyManager.js
+org/jmol/api/JmolRendererInterface.js
+org/jmol/api/JmolRepaintManager.js
+org/jmol/api/JmolScriptEvaluator.js
+org/jmol/api/JmolScriptFunction.js
+org/jmol/api/JmolScriptManager.js
+org/jmol/api/JmolSelectionListener.js
+org/jmol/api/JmolStatusListener.js
+org/jmol/api/JmolViewer.js
+org/jmol/api/PlatformViewer.js
+org/jmol/api/Translator.js
+org/jmol/atomdata/AtomDataServer.js
+org/jmol/atomdata/RadiusData.js
+org/jmol/awt/AwtFile.js
+org/jmol/awt/AwtFont.js
+org/jmol/awt/Display.js
+org/jmol/awt/Image.js
+org/jmol/awt/Mouse.js
+org/jmol/awt/Platform.js
+org/jmol/bspt/Bspf.js
+org/jmol/bspt/Bspt.js
+org/jmol/bspt/CubeIterator.js
+org/jmol/bspt/Element.js
+org/jmol/bspt/Leaf.js
+org/jmol/bspt/Node.js
+org/jmol/c/CBK.js
+org/jmol/c/FIL.js
+org/jmol/c/PAL.js
+org/jmol/c/STER.js
+org/jmol/c/STR.js
+org/jmol/c/VDW.js
+org/jmol/g3d/CylinderRenderer.js
+org/jmol/g3d/G3DRenderer.js
+org/jmol/g3d/Graphics3D.js
+org/jmol/g3d/HermiteRenderer.js
+org/jmol/g3d/LineRenderer.js
+org/jmol/g3d/Pixelator.js
+org/jmol/g3d/Platform3D.js
+org/jmol/g3d/PrecisionRenderer.js
+org/jmol/g3d/SphereRenderer.js
+org/jmol/g3d/TextRenderer.js
+org/jmol/g3d/TextString.js
+org/jmol/g3d/TriangleRenderer.js
+org/jmol/i18n/GT.js
+org/jmol/i18n/Language.js
+org/jmol/i18n/Resource.js
+org/jmol/io/FileReader.js
+org/jmol/modelset/Atom.js
+org/jmol/modelset/AtomCollection.js
+org/jmol/modelset/AtomIteratorWithinModel.js
+org/jmol/modelset/Bond.js
+org/jmol/modelset/BondCollection.js
+org/jmol/modelset/BondIterator.js
+org/jmol/modelset/BondIteratorSelected.js
+org/jmol/modelset/Chain.js
+org/jmol/modelset/Group.js
+org/jmol/modelset/Model.js
+org/jmol/modelset/ModelLoader.js
+org/jmol/modelset/ModelSet.js
+org/jmol/modelset/Orientation.js
+org/jmol/modelset/Structure.js
+org/jmol/modelsetbio/AlphaMonomer.js
+org/jmol/modelsetbio/AlphaPolymer.js
+org/jmol/modelsetbio/BioModel.js
+org/jmol/modelsetbio/BioModelSet.js
+org/jmol/modelsetbio/BioPolymer.js
+org/jmol/modelsetbio/BioResolver.js
+org/jmol/modelsetbio/Helix.js
+org/jmol/modelsetbio/Monomer.js
+org/jmol/modelsetbio/ProteinStructure.js
+org/jmol/render/BallsRenderer.js
+org/jmol/render/FontLineShapeRenderer.js
+org/jmol/render/FrankRenderer.js
+org/jmol/render/RepaintManager.js
+org/jmol/render/ShapeRenderer.js
+org/jmol/render/SticksRenderer.js
+org/jmol/renderbio/BackboneRenderer.js
+org/jmol/renderbio/BioShapeRenderer.js
+org/jmol/renderbio/CartoonRenderer.js
+org/jmol/renderbio/RocketsRenderer.js
+org/jmol/renderbio/StrandsRenderer.js
+org/jmol/script/ContextToken.js
+org/jmol/script/SV.js
+org/jmol/script/ScriptCompiler.js
+org/jmol/script/ScriptContext.js
+org/jmol/script/ScriptError.js
+org/jmol/script/ScriptEval.js
+org/jmol/script/ScriptExpr.js
+org/jmol/script/ScriptFlowContext.js
+org/jmol/script/ScriptFunction.js
+org/jmol/script/ScriptManager.js
+org/jmol/script/ScriptMathProcessor.js
+org/jmol/script/ScriptParam.js
+org/jmol/script/ScriptTokenParser.js
+org/jmol/script/T.js
+org/jmol/scriptext/MathExt.js
+org/jmol/shape/AtomShape.js
+org/jmol/shape/Balls.js
+org/jmol/shape/Frank.js
+org/jmol/shape/Mesh.js
+org/jmol/shape/Shape.js
+org/jmol/shape/Sticks.js
+org/jmol/shapebio/Backbone.js
+org/jmol/shapebio/BioShape.js
+org/jmol/shapebio/BioShapeCollection.js
+org/jmol/shapebio/Cartoon.js
+org/jmol/shapebio/Rockets.js
+org/jmol/thread/HoverWatcherThread.js
+org/jmol/thread/JmolThread.js
+org/jmol/util/BSUtil.js
+org/jmol/util/BoxInfo.js
+org/jmol/util/C.js
+org/jmol/util/ColorEncoder.js
+org/jmol/util/CommandHistory.js
+org/jmol/util/DefaultLogger.js
+org/jmol/util/Edge.js
+org/jmol/util/Elements.js
+org/jmol/util/Escape.js
+org/jmol/util/GData.js
+org/jmol/util/Geodesic.js
+org/jmol/util/Int2IntHash.js
+org/jmol/util/Int2IntHashEntry.js
+org/jmol/util/Logger.js
+org/jmol/util/LoggerInterface.js
+org/jmol/util/MeshSurface.js
+org/jmol/util/Node.js
+org/jmol/util/Normix.js
+org/jmol/util/Point3fi.js
+org/jmol/util/Rectangle.js
+org/jmol/util/Rgb16.js
+org/jmol/util/Shader.js
+org/jmol/util/SimpleEdge.js
+org/jmol/util/SimpleNode.js
+org/jmol/util/TempArray.js
+org/jmol/viewer/ActionManager.js
+org/jmol/viewer/AnimationManager.js
+org/jmol/viewer/ColorManager.js
+org/jmol/viewer/FileManager.js
+org/jmol/viewer/Gesture.js
+org/jmol/viewer/GlobalSettings.js
+org/jmol/viewer/JC.js
+org/jmol/viewer/ModelManager.js
+org/jmol/viewer/MotionPoint.js
+org/jmol/viewer/MouseState.js
+org/jmol/viewer/PropertyManager.js
+org/jmol/viewer/SelectionManager.js
+org/jmol/viewer/ShapeManager.js
+org/jmol/viewer/StateManager.js
+org/jmol/viewer/StatusManager.js
+org/jmol/viewer/TransformManager.js
+org/jmol/viewer/Viewer.js
+org/jmol/viewer/binding/Binding.js
+org/jmol/viewer/binding/JmolBinding.js
+sun/awt/image/OffScreenImageSource.js
+sun/font/AttributeValues.js
+sun/font/EAttribute.js
\ No newline at end of file
--- /dev/null
+com/stevesoft/pat/Multi.js
+com/stevesoft/pat/NotImplementedError.js
+com/stevesoft/pat/FileRegex.js
+com/stevesoft/pat/Validator.js
+com/stevesoft/pat/UnicodeCurrency.js
+com/stevesoft/pat/End.js
+com/stevesoft/pat/Ctrl.js
+com/stevesoft/pat/PopRule.js
+com/stevesoft/pat/UnicodePunct.js
+com/stevesoft/pat/StringLike.js
+com/stevesoft/pat/StrPos.js
+com/stevesoft/pat/Skip.js
+com/stevesoft/pat/Branch.js
+com/stevesoft/pat/Transformer.js
+com/stevesoft/pat/RegexReader.js
+com/stevesoft/pat/NUnicodeW.js
+com/stevesoft/pat/BackMatch.js
+com/stevesoft/pat/parsePerl.js
+com/stevesoft/pat/Skipped.js
+com/stevesoft/pat/patInf.js
+com/stevesoft/pat/CodeVal.js
+com/stevesoft/pat/oneChar.js
+com/stevesoft/pat/Replacer.js
+com/stevesoft/pat/wrap/CharArrayBufferWrap.js
+com/stevesoft/pat/wrap/CharArrayWrap.js
+com/stevesoft/pat/wrap/WriterWrap.js
+com/stevesoft/pat/wrap/StringWrap.js
+com/stevesoft/pat/wrap/RandomAccessFileWrap.js
+com/stevesoft/pat/wrap/StringBufferWrap.js
+com/stevesoft/pat/FastMulti.js
+com/stevesoft/pat/TransRepRule.js
+com/stevesoft/pat/RBuffer.js
+com/stevesoft/pat/MultiMin.js
+com/stevesoft/pat/lookAhead.js
+com/stevesoft/pat/SpecialRule.js
+com/stevesoft/pat/PushRule.js
+com/stevesoft/pat/FastChar.js
+com/stevesoft/pat/Multi_stage2.js
+com/stevesoft/pat/RegexTokenizer.js
+com/stevesoft/pat/NUnicodeDigit.js
+com/stevesoft/pat/BackG.js
+com/stevesoft/pat/BadRangeArgs.js
+com/stevesoft/pat/NullRule.js
+com/stevesoft/pat/NUnicodePunct.js
+com/stevesoft/pat/UnicodeDigit.js
+com/stevesoft/pat/UniValidator.js
+com/stevesoft/pat/Or.js
+com/stevesoft/pat/Custom.js
+com/stevesoft/pat/UnicodeW.js
+com/stevesoft/pat/DirFileRegex.js
+com/stevesoft/pat/RegHolder.js
+com/stevesoft/pat/RegRes.js
+com/stevesoft/pat/Bits.js
+com/stevesoft/pat/UnicodeMath.js
+com/stevesoft/pat/patInt.js
+com/stevesoft/pat/RegSyntax.js
+com/stevesoft/pat/Backup.js
+com/stevesoft/pat/TransPat.js
+com/stevesoft/pat/NullPattern.js
+com/stevesoft/pat/OrMark.js
+com/stevesoft/pat/NonDirFileRegex.js
+com/stevesoft/pat/ChangeRule.js
+com/stevesoft/pat/NoPattern.js
+com/stevesoft/pat/Boundary.js
+com/stevesoft/pat/RuleHolder.js
+com/stevesoft/pat/RightRule.js
+com/stevesoft/pat/CaseMgr.js
+com/stevesoft/pat/CustomEndpoint.js
+com/stevesoft/pat/NUnicodeMath.js
+com/stevesoft/pat/DotMulti.js
+com/stevesoft/pat/Bracket.js
+com/stevesoft/pat/Start.js
+com/stevesoft/pat/Any.js
+com/stevesoft/pat/UnicodeLower.js
+com/stevesoft/pat/PatternSub.js
+com/stevesoft/pat/WantMoreTextReplaceRule.js
+com/stevesoft/pat/Pthings.js
+com/stevesoft/pat/Regex.js
+com/stevesoft/pat/Group.js
+com/stevesoft/pat/UnicodeUpper.js
+com/stevesoft/pat/Skip2.js
+com/stevesoft/pat/RegexWriter.js
+com/stevesoft/pat/UnicodeWhite.js
+com/stevesoft/pat/Pattern.js
+com/stevesoft/pat/LeftRule.js
+com/stevesoft/pat/Range.js
+com/stevesoft/pat/RegOpt.js
+com/stevesoft/pat/PartialBuffer.js
+com/stevesoft/pat/UnicodeAlpha.js
+com/stevesoft/pat/Rthings.js
+com/stevesoft/pat/Prop.js
+com/stevesoft/pat/NUnicodeCurrency.js
+com/stevesoft/pat/BackRefRule.js
+com/stevesoft/pat/SubMark.js
+com/stevesoft/pat/NUnicodeAlpha.js
+com/stevesoft/pat/FastBracket.js
+com/stevesoft/pat/NUnicodeWhite.js
+com/stevesoft/pat/StringBufferLike.js
+com/stevesoft/pat/RegSyntaxError.js
+com/stevesoft/pat/BasicStringBufferLike.js
+com/stevesoft/pat/AmpersandRule.js
+com/stevesoft/pat/StringRule.js
+com/stevesoft/pat/ReplaceRule.js
+com/stevesoft/pat/CodeRule.js
+com/stevesoft/pat/SkipBMH.js
</head>
<body>
<script>
+J2S.addDirectDatabaseCall('www.compbio.dundee.ac.uk'),J2S.addDirectDatabaseCall('www.jalview.org'), J2S.addDirectDatabaseCall('ensembl.org')
+J2S.addDirectDatabaseCall('127.0.0.1'), J2S.addDirectDatabaseCall('localhost')
SwingJS.getApplet('testApplet', Info)
getClassList = function(){J2S._saveFile('_j2sclasslist.txt', Clazz.ClassFilesLoaded.sort().join('\n'))}
</script>
--- /dev/null
+<!DOCTYPE html>
+<html>
+<head><title>URL command line flags for SwingJS</title></head>
+<body><h3>URL command-line arguments for SwingJS</h3>
+<br>To enable these flags, simply add them after # or ? on your page.
+<br>The test is very simple -- just a case-sensitive string check.
+<br>Separate them with & For example:
+<br><a href="test_Test_Class.html?j2sverbose&j2snozcore&j2strace=applet">test_Test_Class.html?j2sverbose&j2snozcore&j2strace=applet</a>
+<br><br><table width=800 border=1 cellpadding=5>
+<tr><th colspan="2"></th></tr>
+<tr><td>j2sargs=a|b|c</td><td>arguments to be passed on to application.main(); use "|" to separate arguments. Overrides Info.args, which should be an array of strings, if present</td></tr>
+<tr><td>j2sdebugclip</td><td>shows all show/restore and clip operations in JSGraphics2D</td></tr>
+<tr><td>j2sdebugcode</td><td>deprecated; see j2snocore</td></tr>
+<tr><td>j2sdebugcore</td><td>deprecated; see j2snozcore</td></tr>
+<tr><td>j2sdebugpaint</td><td>report repaint manager information</td></tr>
+<tr><td>j2sevents</td><td>report ComponentEvent instances</td></tr>
+<tr><td>j2sfilter=xxx</td><td>remove messages with the specified text from System.out</td></tr>
+<tr><td>j2sheadless</td><td>run headlessly (must be a main()-based application or library without Swing or AWT)</td></tr>
+<tr><td>j2slang=en_US</td><td>default language for java.util.Locale (overrides Info.language)</td></tr>
+<tr><td>j2smouse</td><td>report mouse events other than mousemove</td></tr>
+<tr><td>j2smousemove</td><td>report all mouse events, including mousemove</td></tr>
+<tr><td>j2snocore</td><td>do not load core files (from j2s/core/)</td></tr>
+<tr><td>j2snoeval</td><td>use new Function() instead of eval(); breaks debugging, experimental</td></tr>
+<tr><td>j2snooutput</td><td>report only System.err message, not System.out </td></tr>
+<tr><td>j2snozcore</td><td>use the uncompressed j2s/core/xxxcore.js files, not the compressed core.z.js files</td></tr>
+<tr><td>j2sprofile</td><td>track object creation; use J2S.getProfile() when you want a report; J2S.getProfile() or J2S.getProfile(nsec) to restart profiling anytime.</td></tr>
+<tr><td>j2sstrict</td><td>strict mode -- experimental</td></tr>
+<tr><td>j2strace=xxx or j2strace="xxx"</td><td>throw up an alert in the browser and a debugger statement in the developer whenever the specified text is found in System.out or System.err; if quotes are used, this must be an exact match to the entire output text (particularly useful when the message is something like "0", which otherwise would be next to impossible to find.</td></tr>
+<tr><td>j2sverbose</td><td>report all files loaded using AJAX</td></tr>
+</table>
+</body>
+</html>
<script src="swingjs/swingjs2.js"></script>
<script>
+// NOTE: The applet on this page is "Jalview".
+
// BH 2019.10.06 adds Tree and Pca functionality
// BH see issue JAL-3451
jvGet = function(what) {
switch(what) {
case "tree":
- testApplet.app.openTreePanel$jalview_gui_AlignFrame$S$S(null, "NJ","BLOSUM62")
+ Jalview.app.openTreePanel("NJ","BLOSUM62")
break;
case "pca":
- testApplet.app.openPcaPanel$jalview_gui_AlignFrame$S(null, "BLOSUM62")
+ Jalview.app.openPcaPanel("BLOSUM62")
break;
case "3D":
+ Jalview.app.showStructure("1a70", "mmcif");
break;
}
$(document).ready(function() {
- SwingJS.getApplet('testApplet', Info);
+ SwingJS.getApplet('Jalview', Info);
});
across to our visitors with more than just text and images. The idea is to have a <b>dynamic</b> page that will involve <b>user interaction</b>.
<br><br>
We start with a Jalview desktop. You can't see it, because I have placed it in a <code>div</code> tag with style <i>width:0px;height:0px</i> just after the period that ends this sentence.
-<div id="jalview-desktop-div" style="width:0px;height:0px;"></div>
+<div id="Jalview-desktop-div" style="width:0px;height:0px;"></div>
<br>
The idea is NOT to teach visitors how to use Jalview. The idea is to seamlessly integrate components of Jalview that can be used to enrich a discussion.
Like JSmol in <a target="_blank" href="http://proteopedia.org/wiki/index.php/Main_Page"><img src=https://pbs.twimg.com/profile_images/818051034/proteopedia_135x200_small_logo_for_Twitter_400x400.png width=16 height=16/>Proteopedia</a>.
</div>
</td><td style="background-color:lightgray;padding:20px">
-<div id="jalview-alignment-div" style="padding:20px;position:relative;top:0px;left:0px;width:680px;height:400px">
+<div id="Jalview-alignment-div" style="padding:20px;position:relative;top:0px;left:0px;width:680px;height:400px">
<br><br>
The alignment frame will appear here momentarily. When it does, you can go ahead and manipulate the alignment with your mouse.
</div>
<table style="background-color:lightgray"><tr><td style="padding:0px 0px 0px 20px">
<b>Select a few alignments</b> by left-dragging across a few rows of the alignment to make a selection box.
Then click one of the buttons below to see more information about your selected subset of the alignment.
-<ul>
-<li><button onclick='jvGet("tree")'>similarity tree</button></li>
-<li><button onclick='jvGet("pca")'>principal component analysis</button></li>
-</ul>
-
+<br><br>
+<button onclick='jvGet("tree")'>similarity tree</button> <button onclick='jvGet("pca")'>principal component analysis</button>
+<br><br>
+One more thing. Let's take a <a href="javascript:jvGet('3D')" style="text-decoration:none;color:red">look at the 3D structure</a> of one these proteins. Ferredoxins are important, because they have
+iron-sulfur clusters that can accept and deliver electrons in metabolic processes. Let's see if we can find it.
+<br><br>
</td><td style="padding:0px 0px 0px 0px">
<table style="border-spacing:0"><tr><td style="background-color:lightgray;padding:10px 0px 10px 20px">
-<div id="jalview-tree-div" style="position:relative;top:0px;left:0px;width:500px;height:500px">
+<div id="Jalview-tree-div" style="position:relative;top:0px;left:0px;width:500px;height:500px">
<br><br><br><br>
-jalview-tree-div
+<a href="javascript:jvGet('tree')">Jalview-tree-div</a>
</div>
</td><td style="background-color:lightgray;padding:10px 20px 10px 0px">
-<div id="jalview-pca-div" style="position:relative;top:0px;left:0px;width:500px;height:500px">
+<div id="Jalview-pca-div" style="position:relative;top:0px;left:0px;width:500px;height:500px">
<br><br><br><br>
-jalview-pca-div
+<a href="javascript:jvGet('pca')">Jalview-pca-div</a>
+<br><br>
+
</div>
</td></tr></table>
</td></tr>
+<!-- let it float
<tr>
<td valign=top style="padding:20px;height:650px" >
-<div id="jalview-structureviewer-div" style="position:relative;top:0px;left:0px;width:600px;height:600px">
-jalview-strucddtureviewer-div
-</div>
+<div id="Jalview-structureviewer-div" style="position:relative;top:0px;left:0px;width:600px;height:600px">
+<a href="javascript:jvGet('3D')">Jalview-structureviewer-div</a>
+</div>
</td>
<td valign=top style="padding:20px;background-color:white" >
One more thing. Let's take a look at the 3D structure of one these proteins. Ferredoxins are important, because they have
iron-sulfur clusters that can accept and deliver electrons in metabolic processes. Let's see if we can find it.
<br><center><button onclick='jvGet("3D")'>add the 3D structure</button>
-</td></tr></table>
+</td></tr>
+ -->
+
+</table>
<!-- debugging (hidden) -->
--- /dev/null
+<!DOCTYPE html>
+<html>
+<head>
+<title>Embedded JalviewJS Example 2</title><meta charset="utf-8" />
+<script src="swingjs/swingjs2.js"></script>
+<script>
+
+// NOTE: The applet on this page is "Jalview".
+
+// BH 2019.10.06 adds Tree and Pca functionality
+// BH see issue JAL-3451
+
+if (!self.SwingJS)alert('swingjs2.js was not found. It needs to be in swingjs folder in the same directory as ' + document.location.href)
+Info = {
+ code: null,
+ main: "jalview.bin.JalviewJS2",
+ core: "NONE",
+// core:"_jalview",
+
+ oninit:function() {$("#links").show();},
+ noannotation: true,
+
+ readyFunction: null,
+ serverURL: 'https://chemapps.stolaf.edu/jmol/jsmol/php/jsmol.php',
+ j2sPath: 'swingjs/j2s',
+ console:'sysoutdiv',
+ allowjavascript: true
+}
+
+jvGet = function(what) {
+ switch(what) {
+ case "select1":
+ alert(Jalview1.getApp().getSelectedSequences());
+ break;
+ case "select2":
+ alert(Jalview2.getApp().getSelectedSequences());
+ break;
+ case "select1fasta":
+ alert(Jalview1.getApp().getSelectedSequencesAsAlignment("fasta",true));
+ break;
+ case "select2fasta":
+ alert(Jalview2.getApp().getSelectedSequencesAsAlignment("fasta",true));
+ break;
+ }
+
+}
+
+$(document).ready(function() {
+
+ SwingJS.getApplet('Jalview1', Info);
+ SwingJS.getApplet('Jalview2', Info);
+
+});
+
+</script>
+</head>
+<body style="background-image: url(images/coolVeryLightBG.png);">
+<table style="width:1000px;border:2px solid lightblue;border-spacing:0;font-size:16pt;" padding="10" valign="top">
+<tr>
+<td style="font-size:24;font-weight:bold;background-color:lightblue" colspan=2><center>Demonstration of embedded JalviewJS components</center>
+</td>
+
+
+</tr><tr>
+
+
+<td colspan=2 valign=top style="padding:20px;background-color:lightgray">
+this page tests two Jalview apps on the same page.
+<div id="Jalview1-desktop-div" style="width:0px;height:0px;"></div>
+<div id="Jalview2-desktop-div" style="width:0px;height:0px;"></div>
+</td></tr>
+<tr><td style="background-color:lightgray;padding:10px">
+<div id="Jalview1-alignment-div" style="padding:10px;position:relative;width:550px;height:300px">
+</td>
+<td style="background-color:lightgray;padding:10px">
+<div id="Jalview2-alignment-div" style="padding:10px;position:relative;width:550px;height:300px">
+</td>
+</tr>
+<tr><td>
+<div style="display:block;width:500px;height:300px;">
+<div id="sysoutdiv" style="border:1px solid green;width:100%;height:95%;overflow:auto"></div>
+This is System.out. <a href="javascript:J2S.thisApplet._clearConsole()">clear it</a> <br>Add ?j2snocore to URL to see full class list; ?j2sdebug to use uncompressed j2s/core files <br><a href="javascript:getClassList()">get _j2sClassList.txt</a>
+</div>
+
+</td><td valign=top>
+<div id=links style="display:none">
+<a href="javascript:jvGet('select1')">Show Jalview1 selections</a>
+
+<a href="javascript:jvGet('select2')">Show Jalview2 selections</a>
+
+<br>
+<a href="javascript:jvGet('select1fasta')">Show Jalview1 selections (fasta)</a>
+
+<a href="javascript:jvGet('select2fasta')">Show Jalview2 selections (fasta)</a>
+</div>
+</td></tr>
+</table>
+
+
+</body>
+</html>
width: 850,
height: 550,
readyFunction: null,
- serverURL: 'https://chemapps.stolaf.edu/jmol/jsmol/php/jsmol.php',
+ serverURL: '',
j2sPath: 'swingjs/j2s',
console:'sysoutdiv',
allowjavascript: true
}
+// direct access to these sites
</script>
</head>
<body>
<script>
+J2S.addDirectDatabaseCall('www.compbio.dundee.ac.uk'),J2S.addDirectDatabaseCall('www.jalview.org'), J2S.addDirectDatabaseCall('ensembl.org')
+J2S.addDirectDatabaseCall('127.0.0.1'), J2S.addDirectDatabaseCall('localhost')
SwingJS.getApplet('testApplet', Info)
getClassList = function(){J2S._saveFile('_j2sclasslist.txt', Clazz.ClassFilesLoaded.sort().join('\n'))}
</script>
<div style="position:absolute;left:900px;top:30px;width:600px;height:300px;">
<div id="sysoutdiv" contentEditable="true" style="border:1px solid green;width:100%;height:95%;overflow:auto"></div>
-This is System.out. <a href="javascript:testApplet._clearConsole()">clear it</a> <br>Add ?j2snocore to URL to see full class list; ?j2sdebug to use uncompressed j2s/core files <br><a href="javascript:getClassList()">get _j2sClassList.txt</a>
+This is System.out. <a href="javascript:testApplet._clearConsole()">clear it</a> <a href='javascript:J2S.getProfile()'>start/stop profiling</a><br>see <a href=___j2sflags.htm>___j2sflags.htm</a> for SwingJS URL command-line options<br><a href="javascript:getClassList()">get _j2sClassList.txt</a>
</div>
</body>
</html>