<file-match-pattern match-pattern="src/.*.java" include-pattern="true"/>
<file-match-pattern match-pattern="resources/.*.properties" include-pattern="true"/>
</fileset>
- <filter name="NonSrcDirs" enabled="false"/>
</fileset-config>
.gitattributes
TESTNG
/jalviewApplet.jar
+/benchmarking/lib
+*.class
\ No newline at end of file
java -Djava.ext.dirs=JALVIEW_HOME/lib -cp JALVIEW_HOME/jalview.jar jalview.bin.Jalview
-Replace JALVIEW_HOME with the full path to Jalview Installation Directory.
+Replace JALVIEW_HOME with the full path to Jalview Installation Directory. If building from source:
+
+java -Djava.ext.dirs=JALVIEW_BUILD/dist -cp JALVIEW_BUILD/dist/jalview.jar jalview.bin.Jalview
+
##################
-jalview.release=releases/Release_2_10_2b1_Branch
-jalview.version=2.10.2b1
+jalview.release=releases/Release_2_10_3_Branch
+jalview.version=2.10.3
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="src" output="target/classes" path="src/main/java">
+ <attributes>
+ <attribute name="optional" value="true"/>
+ <attribute name="maven.pomderived" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="src" output="target/test-classes" path="src/test/java">
+ <attributes>
+ <attribute name="optional" value="true"/>
+ <attribute name="maven.pomderived" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8">
+ <attributes>
+ <attribute name="maven.pomderived" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
+ <attributes>
+ <attribute name="maven.pomderived" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry combineaccessrules="false" kind="src" path="/Jalview Release 2.7"/>
+ <classpathentry kind="lib" path="/Jalview Release 2.7/jalviewApplet.jar"/>
+ <classpathentry kind="output" path="target/classes"/>
+</classpath>
--- /dev/null
+/target/
+/bin
+/results
+*.log
+*.json
+*~
--- /dev/null
+eclipse.preferences.version=1
+encoding//src/main/java=UTF-8
+encoding/<project>=UTF-8
--- /dev/null
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
+org.eclipse.jdt.core.compiler.compliance=1.8
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
+org.eclipse.jdt.core.compiler.source=1.8
--- /dev/null
+activeProfiles=
+eclipse.preferences.version=1
+resolveWorkspaceProjects=true
+version=1
--- /dev/null
+To set up benchmarking:
+
+1. In the jalview directory run
+ ant makedist
+
+This builds a jalview.jar file and puts it into dist/
+
+2. Make a lib directory in benchmarking/ if not already present.
+
+3. Purge any previous maven dependencies:
+ mvn dependency:purge-local-repository -DactTransitively=false -DreResolve=false
+
+4. Run
+ mvn install:install-file -Dfile=../dist/jalview.jar -DgroupId=jalview.org -DartifactId=jalview -Dversion=1.0 -Dpackaging=jar -DlocalRepositoryPath=lib
+
+to install the jalview.jar file in the local maven repository. The pom.xml in the benchmarking references this installation, so if you change the names the pom.xml file will also need to be updated.
+
+5. Build and run jmh benchmarking. In the benchmarking directory:
+ mvn clean install
+ java -jar target/benchmarks.jar
+
+ To get JSON output instead use:
+ java -jar target/benchmarks.jar -rf json
+
+ JSON output can be viewed quickly by drag-dropping on http://jmh.morethan.io/
\ No newline at end of file
--- /dev/null
+<!--
+Copyright (c) 2014, Oracle America, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of Oracle nor the names of its contributors may be used
+ to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+THE POSSIBILITY OF SUCH DAMAGE.
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.jalview</groupId>
+ <artifactId>benchmarking</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ <packaging>jar</packaging>
+
+ <name>JMH benchmark sample: Java</name>
+
+ <!--
+ This is the demo/sample template build script for building Java benchmarks with JMH.
+ Edit as needed.
+ -->
+
+ <repositories>
+ <repository>
+ <id>lib</id>
+ <url>file://${project.basedir}/lib</url>
+ </repository>
+ </repositories>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.openjdk.jmh</groupId>
+ <artifactId>jmh-core</artifactId>
+ <version>${jmh.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.openjdk.jmh</groupId>
+ <artifactId>jmh-generator-annprocess</artifactId>
+ <version>${jmh.version}</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>jalview.org</groupId>
+ <artifactId>jalview</artifactId>
+ <version>1.0</version>
+ </dependency>
+ </dependencies>
+
+ <properties>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+
+ <!--
+ JMH version to use with this project.
+ -->
+ <jmh.version>1.19</jmh.version>
+
+ <!--
+ Java source/target to use for compilation.
+ -->
+ <javac.target>1.8</javac.target>
+
+ <!--
+ Name of the benchmark Uber-JAR to generate.
+ -->
+ <uberjar.name>benchmarks</uberjar.name>
+ </properties>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>3.1</version>
+ <configuration>
+ <compilerVersion>${javac.target}</compilerVersion>
+ <source>${javac.target}</source>
+ <target>${javac.target}</target>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-shade-plugin</artifactId>
+ <version>2.2</version>
+ <executions>
+ <execution>
+ <phase>package</phase>
+ <goals>
+ <goal>shade</goal>
+ </goals>
+ <configuration>
+ <finalName>${uberjar.name}</finalName>
+ <transformers>
+ <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
+ <mainClass>org.openjdk.jmh.Main</mainClass>
+ </transformer>
+ </transformers>
+ <filters>
+ <filter>
+ <!--
+ Shading signed JARs will fail without this.
+ http://stackoverflow.com/questions/999489/invalid-signature-file-when-attempting-to-run-a-jar
+ -->
+ <artifact>*:*</artifact>
+ <excludes>
+ <exclude>META-INF/*.SF</exclude>
+ <exclude>META-INF/*.DSA</exclude>
+ <exclude>META-INF/*.RSA</exclude>
+ </excludes>
+ </filter>
+ </filters>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <artifactId>maven-clean-plugin</artifactId>
+ <version>2.5</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-deploy-plugin</artifactId>
+ <version>2.8.1</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-install-plugin</artifactId>
+ <version>2.5.1</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-jar-plugin</artifactId>
+ <version>2.4</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-javadoc-plugin</artifactId>
+ <version>2.9.1</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-resources-plugin</artifactId>
+ <version>2.6</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-site-plugin</artifactId>
+ <version>3.3</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-source-plugin</artifactId>
+ <version>2.2.1</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <version>2.17</version>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+ </build>
+
+</project>
--- /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 org.jalview;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Fork;
+import org.openjdk.jmh.annotations.Measurement;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.annotations.Warmup;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Param;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Random;
+import java.util.concurrent.TimeUnit;
+
+import jalview.datamodel.ColumnSelection;
+import jalview.datamodel.HiddenColumns;
+
+/*
+ * A class to benchmark hidden columns performance
+ */
+@Warmup(iterations = 10, time = 500, timeUnit = TimeUnit.MILLISECONDS)
+@Measurement(iterations = 10, time = 500, timeUnit = TimeUnit.MILLISECONDS)
+@Fork(1)
+public class HiddenColumnsBenchmark
+{
+ /*
+ * State with multiple hidden columns and a start position set
+ */
+ @State(Scope.Thread)
+ public static class HiddenColsAndStartState
+ {
+ @Param({"300", "10000", "100000"})
+ public int maxcols;
+
+ @Param({"1", "50", "90"})
+ public int startpcnt; // position as percentage of maxcols
+
+ @Param({"1","15","100"})
+ public int hide;
+
+ HiddenColumns h = new HiddenColumns();
+ Random rand = new Random();
+
+ public int hiddenColumn;
+ public int visibleColumn;
+
+ @Setup
+ public void setup()
+ {
+ rand.setSeed(1234);
+ int lastcol = 0;
+ while (lastcol < maxcols)
+ {
+ int count = rand.nextInt(100);
+ lastcol += count;
+ h.hideColumns(lastcol, lastcol+hide);
+ lastcol+=hide;
+ }
+
+ // make sure column at start is hidden
+ hiddenColumn = (int)(maxcols * startpcnt/100.0);
+ h.hideColumns(hiddenColumn, hiddenColumn);
+
+ // and column <hide> after start is visible
+ ColumnSelection sel = new ColumnSelection();
+ h.revealHiddenColumns(hiddenColumn+hide, sel);
+ visibleColumn = hiddenColumn+hide;
+
+ System.out.println("Maxcols: " + maxcols + " HiddenCol: " + hiddenColumn + " Hide: " + hide);
+ System.out.println("Number of hidden columns: " + h.getSize());
+ }
+ }
+
+ /* Convention: functions in alphabetical order */
+
+ @Benchmark
+ @BenchmarkMode({Mode.Throughput})
+ public int benchAdjustForHiddenColumns(HiddenColsAndStartState tstate)
+ {
+ return tstate.h.adjustForHiddenColumns(tstate.visibleColumn);
+ }
+
+ @Benchmark
+ @BenchmarkMode({Mode.Throughput})
+ public int benchFindColumnPosition(HiddenColsAndStartState tstate)
+ {
+ return tstate.h.findColumnPosition(tstate.visibleColumn);
+ }
+
+ @Benchmark
+ @BenchmarkMode({Mode.Throughput})
+ public List<Integer> benchFindHiddenRegionPositions(HiddenColsAndStartState tstate)
+ {
+ return tstate.h.findHiddenRegionPositions();
+ }
+
+ @Benchmark
+ @BenchmarkMode({Mode.Throughput})
+ public ArrayList<int[]> benchGetHiddenColumnsCopy(HiddenColsAndStartState tstate)
+ {
+ return tstate.h.getHiddenColumnsCopy();
+ }
+
+
+ @Benchmark
+ @BenchmarkMode({Mode.Throughput})
+ public int benchGetSize(HiddenColsAndStartState tstate)
+ {
+ return tstate.h.getSize();
+ }
+
+ @Benchmark
+ @BenchmarkMode({Mode.Throughput})
+ public HiddenColumns benchHideCols(HiddenColsAndStartState tstate)
+ {
+ tstate.h.hideColumns(tstate.visibleColumn,
+ tstate.visibleColumn+2000);
+ return tstate.h;
+ }
+
+ @Benchmark
+ @BenchmarkMode({Mode.Throughput})
+ public boolean benchIsVisible(HiddenColsAndStartState tstate)
+ {
+ return tstate.h.isVisible(tstate.hiddenColumn);
+ }
+
+ @Benchmark
+ @BenchmarkMode({Mode.Throughput})
+ public HiddenColumns benchReveal(HiddenColsAndStartState tstate)
+ {
+ ColumnSelection sel = new ColumnSelection();
+ tstate.h.revealHiddenColumns(tstate.hiddenColumn, sel);
+ return tstate.h;
+ }
+
+ @Benchmark
+ @BenchmarkMode({Mode.Throughput})
+ public HiddenColumns benchRevealAll(HiddenColsAndStartState tstate)
+ {
+ ColumnSelection sel = new ColumnSelection();
+ tstate.h.revealAllHiddenColumns(sel);
+ return tstate.h;
+ }
+
+
+}
\ No newline at end of file
<offline_allowed />
</information>
<resources>
- <j2se version="9+" />
+ <j2se version="1.7+" />
<jar main="true" href="jalview.jar"/>
<fileset dir="${packageDir}">
<exclude name="jalview.jar" />
</presetdef>
<jnlpf toFile="${jnlpFile}" />
- <!-- add a j2se entry for java 9 -->
+ <!-- add the add-modules j2se attribute for java 9 -->
<replace file="${jnlpFile}" value="j2se version="1.7+" initial-heap-size="${inih}" max-heap-size="${maxh}" java-vm-args="--add-modules=java.se.ee"">
- <replacetoken>j2se version="1.9+"</replacetoken>
+ <replacetoken>j2se version="1.7+"</replacetoken>
</replace>
</target>
--- /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.
+ */
+
+import jalview.analysis.scoremodels.ScoreModels
+import jalview.analysis.scoremodels.SimilarityParams
+
+// generate matrix for current selection using standard Jalview PID
+
+printSimilarityMatrix(true,true,SimilarityParams.Jalview)
+
+/**
+ * this function prints a sequence similarity matrix in PHYLIP format.
+ * printSimilarityMatrix(selected-only, include-ids, pidMethod)
+ *
+ * Allowed values for pidMethod:
+ *
+ * Jalview's Comparison.PID method includes matching gaps
+ * and counts over the length of the shorter gapped sequence
+ * SimilarityParams.Jalview;
+ *
+ * 'SeqSpace' mode PCA calculation does not count matching
+ * gaps but uses longest gapped sequence length
+ * SimilarityParams.SeqSpace;
+ *
+ * PID calcs from the Raghava-Barton paper
+ * SimilarityParams.PID1: ignores gap-gap, does not score gap-residue,
+ * includes gap-residue in lengths, matches on longer of two sequences.
+ *
+ * SimilarityParams.PID2: ignores gap-gap,ignores gap-residue,
+ * matches on longer of two sequences
+ *
+ * SimilarityParams.PID3: ignores gap-gap,ignores gap-residue,
+ * matches on shorter of sequences only
+ *
+ * SimilarityParams.PID4: ignores gap-gap,does not score gap-residue,
+ * includes gap-residue in lengths,matches on shorter of sequences only.
+ */
+
+void printSimilarityMatrix(boolean selview=false, boolean includeids=true, SimilarityParams pidMethod) {
+
+ def currentAlignFrame = jalview.bin.Jalview.getCurrentAlignFrame()
+
+ jalview.gui.AlignViewport av = currentAlignFrame.getCurrentView()
+
+ jalview.datamodel.AlignmentView seqStrings = av.getAlignmentView(selview)
+
+ if (!selview || av.getSelectionGroup()==null) {
+ start = 0
+ end = av.getAlignment().getWidth()
+ seqs = av.getAlignment().getSequencesArray()
+ } else {
+ start = av.getSelectionGroup().getStartRes()
+ end = av.getSelectionGroup().getEndRes() + 1
+ seqs = av.getSelectionGroup().getSequencesInOrder(av.getAlignment())
+ }
+
+ distanceCalc = ScoreModels.getInstance().getScoreModel("PID",
+ (jalview.api.AlignmentViewPanel) currentAlignFrame.alignPanel)
+
+ def distance=distanceCalc.findSimilarities(
+ seqStrings.getSequenceStrings(jalview.util.Comparison.GAP_DASH),pidMethod)
+
+ // output the PHYLIP Matrix
+
+ print distance.width()+" "+distance.height()+"\n"
+
+ p = 0
+
+ for (v in 1..distance.height()) {
+
+ if (includeids) {
+ print seqs[p++].getDisplayId(false)+" "
+ }
+
+ for (r in 1..distance.width()) {
+ print distance.getValue(v-1,r-1)+" "
+ }
+
+ print "\n"
+ }
+}
\ No newline at end of file
<mapID target="home" url="html/index.html" />
<mapID target="new" url="html/whatsNew.html"/>
- <mapID target="release" url="html/releases.html#Jalview.2.10.2b1"/>
+ <mapID target="release" url="html/releases.html#Jalview.2.10.3"/>
<mapID target="alannotation" url="html/features/annotation.html"/>
<mapID target="keys" url="html/keys.html"/>
<mapID target="newkeys" url="html/features/newkeystrokes.html"/>
<p>
Gap open : 12 <br> Gap extend : 2
</p>
- <p>When you select the pairwise alignment option a new window will
- come up which will display the alignments in a text format as they
- are calculated. Also displayed is information about the alignment
- such as alignment score, length and percentage identity between the
+ <p>When you select the pairwise alignment option, a new window
+ will come up which displays the alignments in a text format, for
+ example:</p>
+ <p>
+ <pre>
+ FER1_SPIOL/5-13 TTMMGMAT<br />
+ |. .. ||<br />
+ FER1_MESCR/5-15 TAALSGAT
+ </pre>
+ shows the aligned sequences, where '|' links identical residues, and
+ (for peptide) '.' links residues that have a positive PAM250 score.
+ <p>The window also shows information about the alignment such as
+ alignment score, length and percentage identity between the
sequences.</p>
- <p> </p>
+ <p>A button is also provided to allow you to view the sequences as
+ an alignment.</p>
</body>
</html>
<tr>
<td width="60" nowrap>
<div align="center">
+ <strong><a name="Jalview.2.10.3">2.10.3</a><br />
+ <em>10/10/2017</em></strong>
+ </div>
+ </td>
+ <td><div align="left">
+ <em></em>
+ <ul>
+ <li>
+ <!-- JAL-2446 -->Faster and more efficient management and
+ rendering of sequence features
+ </li>
+ <li>
+ <!-- JAL 2523-->More reliable Ensembl fetching with HTTP
+ 429 rate limit request hander
+ </li>
+ <li>
+ <!-- JAL-2773 -->Structure views don't get updated unless
+ their colours have changed
+ </li>
+ <li><!-- JAL-2495 -->All linked sequences are highlighted for a structure mousover (Jmol) or selection (Chimera)</li>
+ <li><!-- JAL-2790 -->'Cancel' button in progress bar for JABAWS AACon, RNAAliFold and Disorder prediction jobs
+ </li>
+
+ <li><!-- JAL-2617 -->Stop codons are excluded in CDS/Protein view from Ensembl locus cross-references</li>
+ <li><!-- JAL-2685 -->Start/End limits are shown in Pairwise Alignment report</li>
+ </ul>
+ <ul><li>Example groovy script for generating a matrix of percent identity scores for current alignment.</li></ul>
+ <em>Testing and Deployment</em>
+ <ul><li><!-- JAL-2727 -->Test to catch memory leaks in Jalview UI</li></ul>
+ </div>
+ </td>
+ <td><div align="left">
+ <em>General</em>
+ <ul>
+ <li><!-- JAL-2643 -->Pressing tab after updating the colour threshold text field doesn't trigger an update to the alignment view</li>
+ <li><!-- JAL-2682 -->Race condition when parsing sequence ID strings in parallel</li>
+ <li><!-- JAL-2608 -->Overview windows are also closed when alignment window is closed</li>
+ <li><!-- JAL-2548 -->Export of features doesn't always respect group visibility</li>
+ </ul>
+ <em>Desktop</em>
+ <ul>
+ <li><!-- JAL-2777 -->Structures with whitespace chainCode cannot be viewed in Chimera</li>
+ <li><!-- JAL-2728 -->Protein annotation panel too high in CDS/Protein view
+ </li>
+ <li><!-- JAL-2757 -->Can't edit the query after the server error warning icon is shown in Uniprot and PDB Free Text Search Dialogs
+ </li>
+ <li><!-- JAL-2253 -->Slow EnsemblGenome ID lookup</li>
+ <li><!-- JAL-2529 -->Revised Ensembl REST API CDNA query</li>
+ <li><!-- JAL-2739 -->Hidden column marker in last column not rendered when switching back from Wrapped to normal view</li>
+ <li><!-- JAL-2768 -->Annotation display corrupted when scrolling right in unwapped alignment view</li>
+ <li><!-- JAL-2542 -->Existing features on subsequence incorrectly relocated when full sequence retrieved from database</li>
+ <li><!-- JAL-2733 -->Last reported memory still shown when Desktop->Show Memory is unticked (OSX only)</li>
+ <li><!-- JAL-2658 -->Amend Features dialog doesn't allow features of same type and group to be selected for amending</li>
+ <li><!-- JAL-2524 -->Jalview becomes sluggish in wide alignments when hidden columns are present</li>
+ <li><!-- JAL-2392 -->Jalview freezes when loading and displaying several structures</li>
+ <li><!-- JAL-2732 -->Black outlines left after resizing or moving a window</li>
+ <li><!-- JAL-1900,JAL-1625 -->Unable to minimise windows within the Jalview desktop on OSX</li>
+ <li><!-- JAL-2667 -->Mouse wheel doesn't scroll vertically when in wrapped alignment mode</li>
+ <li><!-- JAL-2636 -->Scale mark not shown when close to right hand end of alignment</li>
+ <li><!-- JAL-2684 -->Pairwise alignment only aligns selected regions of each selected sequence</li>
+ <li><!-- JAL-2973 -->Alignment ruler height set incorrectly after canceling the Alignment Window's Font dialog</li>
+ <li><!-- JAL-2036 -->Show cross-references not enabled after restoring project until a new view is created</li>
+ <li><!-- JAL-2756 -->Warning popup about use of SEQUENCE_ID in URL links appears when only default EMBL-EBI link is configured (since 2.10.2b2)</li>
+ </ul>
+ <strong><em>Applet</em></strong><br/>
+ <ul>
+ <li><!-- JAL-2687 -->Concurrent modification exception when closing alignment panel</li>
+ </ul>
+ <strong><em>BioJSON</em></strong><br/>
+ <ul>
+ <li>
+ <!-- JAL-2546 -->BioJSON export does not preserve non-positional features
+ </li>
+ </ul>
+ </div>
+ </td>
+ </tr>
+ <tr>
+ <td width="60" nowrap>
+ <div align="center">
+ <strong><a name="Jalview.2.10.2b2">2.10.2b2</a><br />
+ <em>2/10/2017</em></strong>
+ </div>
+ </td>
+ <td><div align="left">
+ <em>New features in Jalview Desktop</em>
+ <ul>
+ <li>
+ <!-- JAL-2748 -->Uniprot Sequence Fetcher now uses web API at uniprot.org
+ </li>
+ <li> <!-- JAL-2745 -->HTTPS used for all connections to ebi.ac.uk
+ </li>
+ </ul>
+ </div></td>
+ <td><div align="left">
+ </div></td>
+ </tr>
+ <tr>
+ <td width="60" nowrap>
+ <div align="center">
<strong><a name="Jalview.2.10.2b1">2.10.2b1</a><br />
<em>7/9/2017</em></strong>
</div>
</li>
</ul>
</div></td>
-
+ </tr>
<tr>
<td width="60" nowrap>
<div align="center">
after clicking on it to create new annotation for a
column.
</li>
+ <li>
+ <!-- JAL-1980 -->Null Pointer Exception raised when
+ pressing Add on an orphaned cut'n'paste window.
+ </li>
<!-- may exclude, this is an external service stability issue JAL-1941
-- > RNA 3D structure not added via DSSR service</li> -->
</ul>
</head>
<body>
<p>
- <strong>Jalview 2.10.2b1 bugfix release</strong>
+ <strong>What's new in Jalview 2.10.3 ?</strong>
</p>
<p>
- This is patch release for 2.10.2. See the <a
- href="releases.html#Jalview.2.10.2b1">release notes</a> for full
- details about the bugs addressed. This release also introduces
- additional improvements to the overview panel, and patches for
- several minor issues including the ability to correctly recover
- cross-references for Uniprot protein sequences from Ensembl.
- </p>
- <p>
- <strong>What's new in Jalview 2.10.2 ?</strong>
- </p>
- <p>
- Version 2.10.2 was released in August 2017, and introduced new user
- interface features, improved and more extensible tree and PCA
- analysis, more robust 3D structure viewing with UCSF Chimera and an
- updated service client for JABAWS. The full list of bug fixes and
- new features can be found in the <a
- href="releases.html#Jalview.2.10.2"> 2.10.2 Release Notes</a>, but
+ Version 2.10.3 is due for release in October 2017. The full list of
+ bug fixes and new features can be found in the <a
+ href="releases.html#Jalview.2.10.3"> 2.10.3 Release Notes</a>, but
the highlights are below.
</p>
- <ul>
- <li><strong>New dialog and faster and more
- configurable Tree and PCA calculations</strong><br> Menu entries for
- calculating PCA and different types of tree have been replaced by
- a single <a href="calculations/calculations.html"><em>Calculations</em>
- dialog box</a>. The underlying implementation for the PCA and tree
- calculations have been made faster and more memory efficient.</li>
- <li><strong>Extensible score models</strong><br />A new
- framework has also been created for the score models used to
- calculate distances between sequences and shade alignments. This
- framework allows import of substitution matrices in NCBI and
- AAIndex format.<br /> <strong>PCA Bug Fixes</strong>. Jalview's
- implementation of PCA differed in its treatment of gaps and
- non-standard residues. The BLOSUM62 matrix also included a typo
- that affected results. See the <a
- href="releases.html#2102scoremodelbugs">2.10.2 release note
- about score model bugs</a> for details and how to reinstate legacy
- behaviour.</li>
- <li><strong>Update to JABAWS 2.2</strong><br />Jalview's
- alignment, protein conservation analysis, and protein disorder and
- RNA secondary structure prediction services are now provided by <a
- href="http://www.compbio.dundee.ac.uk/jabaws">JABAWS 2.2</a>.
- Several of the programs provided as JABAWS 2.2 services have been
- updated, so their options and parameters have changed.</li>
- <li><strong>URL linkouts to other bioinformatics
- databases</strong><br />New preferences for <a
- href="webServices/urllinks.html">opening web pages for
- database cross-references</a> via the UK Elixir's EMBL-EBI's MIRIAM
- database and identifiers.org services.</li>
- <li><strong>Showing and hiding regions</strong> <br /> <a
- href="menus/popupMenu.html#hideinserts">Hide insertions</a> in the
- PopUp menu has changed its behaviour. Prior to 2.10.2, columns
- were only shown or hidden according to gaps in the sequence under
- the popup menu. Now, only columns that are gapped in all selected
- sequences as well as the sequence under the popup menu are hidden,
- and column visibility outside the selected region is left as is.
- This makes it easy to filter insertions from the alignment view
- (just select the region containing insertions to remove) without
- affecting the rest of the hidden columns.</li>
- <li><strong>Gap count - a.k.a. the Occupancy
- Annotation Row</strong><br /> Another way to filter columns according to
- the presence of gaps is to enable the <strong>Occupancy
- Annotation</strong> row via Jalview's Preferences. This annotation row
- shows a histogram of the number of aligned residues at each
- column. The <a href="features/columnFilterByAnnotation.html">Select
- By Annotation</a> dialog now also includes a percentage threshold
- mode, to make it easy to filter alignments to show only those
- columns with a particular fraction of aligned sequences.</li>
- <li><strong>Recent search history for Find, PDBe and
- Uniprot</strong><br />Easily repeat a previous search for <a
- href="features/search.html#queryhistory">Find</a> and the free
- text search system (for querying Uniprot and the PDBe).</li>
- <li><strong>Improved Overview Window</strong><br />The <a
- href="features/overview.html">alignment overview</a> is now easier
- to use when working with alignments of more than 5000 rows and
- columns, and features a new pop-up menu that allows hidden regions
- to be excluded from the overview. It also works with CDS/Protein
- alignments and MSA views in wrapped mode.</li>
- <li><strong>3D Structure</strong><br />Jalview's communication
- with UCSF Chimera has been made more robust, particularly when
- working with many structures and long sequences. Regions in
- structures that correspond to hidden regions in an alignment view
- are now left un-coloured, making it easier to highlight specific
- features in 3D. See below for <a href="#experimental">experimental
- features for exchanging annotation between Chimera and Jalview.</a></li>
- </ul>
- <p>
- <strong>Scripting</strong><br />New <a
- href="http://www.jalview.org/examples/groovy">groovy examples</a>
- demonstrate Jalview 2.10.2 APIs for creation of data-driven
- colourschemes, and custom alignment file handlers. The <a
- href="groovy/featuresCounter.html">FeatureAnnotationWorker</a>
- introduced in Jalview 2.10 has also been refactored to allow
- efficient counting across multiple feature types. Please be aware
- that feature counter scripts created for earlier versions will not
- execute in Jalview 2.10.2.
- </p>
<p>
<strong><a name="experimental">Experimental Features</a></strong>
</p>
label.urltooltip = Only one url, which must use a sequence id, can be selected for the 'On Click' option
label.edit_sequence_url_link = Edit sequence URL link
warn.name_cannot_be_duplicate = User-defined URL names must be unique and cannot be MIRIAM ids
-label.invalid_name = Invalid Name !
label.output_seq_details = Output Sequence Details to list all database references
label.urllinks = Links
label.default_cache_size = Default Cache Size
label.urltooltip = Sólo una url, que debe usar una id de secuencia, puede ser seleccionada en la opción 'On Click'
label.edit_sequence_url_link = Editar link de secuencia URL
warn.name_cannot_be_duplicate = Los nombres URL definidos por el usuario deben ser únicos y no pueden ser ids de MIRIAM
-label.invalid_name = Nombre inválido !
label.output_seq_details = Seleccionar Detalles de la secuencia para ver todas
label.urllinks = Enlaces
label.default_cache_size = Tamaño del caché por defecto
try
{
- pdb = ssm.setMapping(seq, chains, pdbentry.getFile(), protocol);
+ pdb = ssm.setMapping(seq, chains, pdbentry.getFile(), protocol, null);
if (protocol == DataSourceType.PASTE)
{
try
{
- pdb = ssm.setMapping(seq, chains, pdbentry.getFile(), protocol);
+ pdb = ssm.setMapping(seq, chains, pdbentry.getFile(), protocol,
+ ap.alignFrame);
if (protocol.equals(jalview.io.DataSourceType.PASTE))
{
public void splitInsertionCode(String residue)
{
// OK, split the index into number and insertion code
+ // JBPNote - m.matches() can be true even if there is no resnum - this can
+ // cause NumberFormatExceptions below
Pattern p = Pattern.compile("(\\d*)([A-Z]?)");
Matcher m = p.matcher(residue);
if (m.matches())
import java.awt.Color;
import java.awt.Graphics;
+import java.io.PrintStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
*/
public class AlignSeq
{
+ private static final int MAX_NAME_LENGTH = 30;
+
+ private static final int GAP_OPEN_COST = 120;
+
+ private static final int GAP_EXTEND_COST = 20;
+
+ private static final int GAP_INDEX = -1;
+
public static final String PEP = "pep";
public static final String DNA = "dna";
float[][] F;
- int[][] traceback;
+ int[][] traceback; // todo is this actually used?
int[] seq1;
/** DOCUMENT ME!! */
public int seq2start;
- /** DOCUMENT ME!! */
public int seq2end;
int count;
- /** DOCUMENT ME!! */
public float maxscore;
- float pid;
-
int prev = 0;
- int gapOpen = 120;
-
- int gapExtend = 20;
-
StringBuffer output = new StringBuffer();
String type; // AlignSeq.PEP or AlignSeq.DNA
private ScoreMatrix scoreMatrix;
- private static final int GAP_INDEX = -1;
-
/**
* Creates a new AlignSeq object.
*
}
}
- // System.out.println(maxi + " " + maxj + " " + score[maxi][maxj]);
int i = maxi;
int j = maxj;
int trace;
- maxscore = score[i][j] / 10;
+ maxscore = score[i][j] / 10f;
seq1end = maxi + 1;
seq2end = maxj + 1;
/**
* DOCUMENT ME!
*/
- public void printAlignment(java.io.PrintStream os)
+ public void printAlignment(PrintStream os)
{
// TODO: Use original sequence characters rather than re-translated
// characters in output
// Find the biggest id length for formatting purposes
- String s1id = s1.getName(), s2id = s2.getName();
- int maxid = s1.getName().length();
- if (s2.getName().length() > maxid)
- {
- maxid = s2.getName().length();
- }
- if (maxid > 30)
+ String s1id = getAlignedSeq1().getDisplayId(true);
+ String s2id = getAlignedSeq2().getDisplayId(true);
+ int nameLength = Math.max(s1id.length(), s2id.length());
+ if (nameLength > MAX_NAME_LENGTH)
{
- maxid = 30;
+ int truncateBy = nameLength - MAX_NAME_LENGTH;
+ nameLength = MAX_NAME_LENGTH;
// JAL-527 - truncate the sequence ids
- if (s1.getName().length() > maxid)
+ if (s1id.length() > nameLength)
{
- s1id = s1.getName().substring(0, 30);
+ int slashPos = s1id.lastIndexOf('/');
+ s1id = s1id.substring(0, slashPos - truncateBy)
+ + s1id.substring(slashPos);
}
- if (s2.getName().length() > maxid)
+ if (s2id.length() > nameLength)
{
- s2id = s2.getName().substring(0, 30);
+ int slashPos = s2id.lastIndexOf('/');
+ s2id = s2id.substring(0, slashPos - truncateBy)
+ + s2id.substring(slashPos);
}
}
- int len = 72 - maxid - 1;
+ int len = 72 - nameLength - 1;
int nochunks = ((aseq1.length - count) / len)
+ ((aseq1.length - count) % len > 0 ? 1 : 0);
- pid = 0;
+ float pid = 0f;
output.append("Score = ").append(score[maxi][maxj]).append(NEWLINE);
output.append("Length of alignment = ")
.append(String.valueOf(aseq1.length - count)).append(NEWLINE);
output.append("Sequence ");
- output.append(new Format("%" + maxid + "s").form(s1.getName()));
- output.append(" : ").append(String.valueOf(s1.getStart()))
- .append(" - ").append(String.valueOf(s1.getEnd()));
+ Format nameFormat = new Format("%" + nameLength + "s");
+ output.append(nameFormat.form(s1id));
output.append(" (Sequence length = ")
.append(String.valueOf(s1str.length())).append(")")
.append(NEWLINE);
output.append("Sequence ");
- output.append(new Format("%" + maxid + "s").form(s2.getName()));
- output.append(" : ").append(String.valueOf(s2.getStart()))
- .append(" - ").append(String.valueOf(s2.getEnd()));
+ output.append(nameFormat.form(s2id));
output.append(" (Sequence length = ")
.append(String.valueOf(s2str.length())).append(")")
.append(NEWLINE).append(NEWLINE);
for (int j = 0; j < nochunks; j++)
{
// Print the first aligned sequence
- output.append(new Format("%" + (maxid) + "s").form(s1id)).append(" ");
+ output.append(nameFormat.form(s1id)).append(" ");
for (int i = 0; i < len; i++)
{
}
output.append(NEWLINE);
- output.append(new Format("%" + (maxid) + "s").form(" ")).append(" ");
+ output.append(nameFormat.form(" ")).append(" ");
/*
* Print out the match symbols:
pid++;
output.append("|");
}
- else if (type.equals("pep"))
+ else if (PEP.equals(type))
{
if (pam250.getPairwiseScore(c1, c2) > 0)
{
// Now print the second aligned sequence
output = output.append(NEWLINE);
- output = output.append(new Format("%" + (maxid) + "s").form(s2id))
- .append(" ");
+ output = output.append(nameFormat.form(s2id)).append(" ");
for (int i = 0; i < len; i++)
{
}
pid = pid / (aseq1.length - count) * 100;
- output = output.append(new Format("Percentage ID = %2.2f\n").form(pid));
+ output.append(new Format("Percentage ID = %3.2f\n").form(pid));
+ output.append(NEWLINE);
try
{
os.print(output.toString());
public int findTrace(int i, int j)
{
int t = 0;
- // float pairwiseScore = lookup[seq1[i]][seq2[j]];
float pairwiseScore = scoreMatrix.getPairwiseScore(s1str.charAt(i),
s2str.charAt(j));
float max = score[i - 1][j - 1] + (pairwiseScore * 10);
// top left hand element
score[0][0] = scoreMatrix.getPairwiseScore(s1str.charAt(0),
s2str.charAt(0)) * 10;
- E[0][0] = -gapExtend;
+ E[0][0] = -GAP_EXTEND_COST;
F[0][0] = 0;
// Calculate the top row first
for (int j = 1; j < m; j++)
{
// What should these values be? 0 maybe
- E[0][j] = max(score[0][j - 1] - gapOpen, E[0][j - 1] - gapExtend);
- F[0][j] = -gapExtend;
+ E[0][j] = max(score[0][j - 1] - GAP_OPEN_COST, E[0][j - 1] - GAP_EXTEND_COST);
+ F[0][j] = -GAP_EXTEND_COST;
float pairwiseScore = scoreMatrix.getPairwiseScore(s1str.charAt(0),
s2str.charAt(j));
- score[0][j] = max(pairwiseScore * 10, -gapOpen, -gapExtend);
+ score[0][j] = max(pairwiseScore * 10, -GAP_OPEN_COST, -GAP_EXTEND_COST);
traceback[0][j] = 1;
}
// Now do the left hand column
for (int i = 1; i < n; i++)
{
- E[i][0] = -gapOpen;
- F[i][0] = max(score[i - 1][0] - gapOpen, F[i - 1][0] - gapExtend);
+ E[i][0] = -GAP_OPEN_COST;
+ F[i][0] = max(score[i - 1][0] - GAP_OPEN_COST, F[i - 1][0] - GAP_EXTEND_COST);
float pairwiseScore = scoreMatrix.getPairwiseScore(s1str.charAt(i),
s2str.charAt(0));
{
for (int j = 1; j < m; j++)
{
- E[i][j] = max(score[i][j - 1] - gapOpen, E[i][j - 1] - gapExtend);
- F[i][j] = max(score[i - 1][j] - gapOpen, F[i - 1][j] - gapExtend);
+ E[i][j] = max(score[i][j - 1] - GAP_OPEN_COST, E[i][j - 1] - GAP_EXTEND_COST);
+ F[i][j] = max(score[i - 1][j] - GAP_OPEN_COST, F[i - 1][j] - GAP_EXTEND_COST);
float pairwiseScore = scoreMatrix.getPairwiseScore(s1str.charAt(i),
s2str.charAt(j));
/**
* Returns a mapping from dna to protein by inspecting sequence features of
- * type "CDS" on the dna.
+ * type "CDS" on the dna. A mapping is constructed if the total CDS feature
+ * length is 3 times the peptide length (optionally after dropping a trailing
+ * stop codon). This method does not check whether the CDS nucleotide sequence
+ * translates to the peptide sequence.
*
* @param dnaSeq
* @param proteinSeq
List<int[]> ranges = findCdsPositions(dnaSeq);
int mappedDnaLength = MappingUtils.getLength(ranges);
+ /*
+ * if not a whole number of codons, something is wrong,
+ * abort mapping
+ */
+ if (mappedDnaLength % CODON_LENGTH > 0)
+ {
+ return null;
+ }
+
int proteinLength = proteinSeq.getLength();
int proteinStart = proteinSeq.getStart();
int proteinEnd = proteinSeq.getEnd();
if (codesForResidues == (proteinLength + 1))
{
// assuming extra codon is for STOP and not in peptide
+ // todo: check trailing codon is indeed a STOP codon
codesForResidues--;
+ mappedDnaLength -= CODON_LENGTH;
+ MappingUtils.removeEndPositions(CODON_LENGTH, ranges);
}
+
if (codesForResidues == proteinLength)
{
proteinRange.add(new int[] { proteinStart, proteinEnd });
/**
* Returns a list of CDS ranges found (as sequence positions base 1), i.e. of
- * start/end positions of sequence features of type "CDS" (or a sub-type of
+ * [start, end] positions of sequence features of type "CDS" (or a sub-type of
* CDS in the Sequence Ontology). The ranges are sorted into ascending start
* position order, so this method is only valid for linear CDS in the same
* sense as the protein product.
return result;
}
SequenceFeatures.sortFeatures(sfs, true);
- int startPhase = 0;
for (SequenceFeature sf : sfs)
{
*/
int begin = sf.getBegin();
int end = sf.getEnd();
- if (result.isEmpty())
+ if (result.isEmpty() && phase > 0)
{
begin += phase;
if (begin > end)
}
/*
- * remove 'startPhase' positions (usually 0) from the first range
- * so we begin at the start of a complete codon
- */
- if (!result.isEmpty())
- {
- // TODO JAL-2022 correctly model start phase > 0
- result.get(0)[0] += startPhase;
- }
-
- /*
* Finally sort ranges by start position. This avoids a dependency on
* keeping features in order on the sequence (if they are in order anyway,
* the sort will have almost no work to do). The implicit assumption is CDS
package jalview.api;
import jalview.analysis.Conservation;
+import jalview.analysis.TreeModel;
import jalview.datamodel.AlignmentAnnotation;
import jalview.datamodel.AlignmentI;
import jalview.datamodel.AlignmentView;
-import jalview.datamodel.CigarArray;
import jalview.datamodel.ColumnSelection;
import jalview.datamodel.ProfilesI;
import jalview.datamodel.SearchResultsI;
void clearSequenceColours();
/**
- * This method returns the visible alignment as text, as seen on the GUI, ie
- * if columns are hidden they will not be returned in the result. Use this for
- * calculating trees, PCA, redundancy etc on views which contain hidden
- * columns.
- *
- * @return String[]
- */
- CigarArray getViewAsCigars(boolean selectedRegionOnly);
-
- /**
* return a compact representation of the current alignment selection to pass
* to an analysis function
*
*
* @return
*/
+ @Override
boolean isProteinFontAsCdna();
/**
*
* @return
*/
+ @Override
void setProteinFontAsCdna(boolean b);
+
+ public abstract TreeModel getCurrentTree();
+
+ public abstract void setCurrentTree(TreeModel tree);
}
*
* @param updateOverview
* - if true, the overview panel will also be updated and repainted
+ * @param updateStructures
+ * - if true then any linked structure views will also be updated
*/
-
- void paintAlignment(boolean updateOverview);
+ void paintAlignment(boolean updateOverview, boolean updateStructures);
/**
* automatically adjust annotation panel height for new annotation whilst
void addFeatureLinks(final SequenceI seq, List<String> links)
{
Menu linkMenu = new Menu(MessageManager.getString("action.link"));
- Map<String, List<String>> linkset = new LinkedHashMap<String, List<String>>();
+ Map<String, List<String>> linkset = new LinkedHashMap<>();
for (String link : links)
{
* Temporary store to hold distinct calcId / type pairs for the tooltip.
* Using TreeMap means calcIds are shown in alphabetical order.
*/
- SortedMap<String, String> tipEntries = new TreeMap<String, String>();
- final Map<SequenceI, List<AlignmentAnnotation>> candidates = new LinkedHashMap<SequenceI, List<AlignmentAnnotation>>();
+ SortedMap<String, String> tipEntries = new TreeMap<>();
+ final Map<SequenceI, List<AlignmentAnnotation>> candidates = new LinkedHashMap<>();
AlignmentI al = this.ap.av.getAlignment();
AlignmentUtils.findAddableReferenceAnnotations(forSequences, tipEntries,
candidates, al);
}
int gSize = sg.getSize();
- List<SequenceI> seqs = new ArrayList<SequenceI>();
- List<SequenceFeature> features = new ArrayList<SequenceFeature>();
+ List<SequenceI> seqs = new ArrayList<>();
+ List<SequenceFeature> features = new ArrayList<>();
for (int i = 0; i < gSize; i++)
{
{
seq.setName(dialog.getName());
seq.setDescription(dialog.getDescription());
- ap.paintAlignment(false);
+ ap.paintAlignment(false, false);
}
}
void refresh()
{
- ap.paintAlignment(true);
+ ap.paintAlignment(true, true);
}
protected void clustalColour_actionPerformed()
SequenceGroup sg = ap.av.getSelectionGroup();
ap.av.getAlignment().deleteGroup(sg);
ap.av.setSelectionGroup(null);
- ap.paintAlignment(true);
+ ap.paintAlignment(true, true);
}
void createGroupMenuItem_actionPerformed()
* the insertion order, which is the order of the annotations on the
* alignment.
*/
- Map<String, List<List<String>>> shownTypes = new LinkedHashMap<String, List<List<String>>>();
- Map<String, List<List<String>>> hiddenTypes = new LinkedHashMap<String, List<List<String>>>();
+ Map<String, List<List<String>>> shownTypes = new LinkedHashMap<>();
+ Map<String, List<List<String>>> hiddenTypes = new LinkedHashMap<>();
AlignmentAnnotationUtils.getShownHiddenTypes(shownTypes, hiddenTypes,
AlignmentAnnotationUtils.asList(annotations), forSequences);
createAlignFrameWindow(embedded);
validate();
alignPanel.adjustAnnotationHeight();
- alignPanel.paintAlignment(true);
+ alignPanel.paintAlignment(true, true);
}
public AlignViewport getAlignViewport()
{
viewport.featureSettings.refreshTable();
}
- alignPanel.paintAlignment(true);
+ alignPanel.paintAlignment(true, true);
statusBar.setText(MessageManager
.getString("label.successfully_added_features_alignment"));
}
break;
}
- alignPanel.paintAlignment(true);
+ // TODO: repaint flags set only if the keystroke warrants it
+ alignPanel.paintAlignment(true, true);
}
/**
{
applyAutoAnnotationSettings_actionPerformed();
}
- alignPanel.paintAlignment(true);
+ // TODO: repaint flags set only if warranted
+ alignPanel.paintAlignment(true, true);
}
/**
else if (source == invertColSel)
{
viewport.invertColumnSelection();
- alignPanel.paintAlignment(true);
+ alignPanel.paintAlignment(false, false);
viewport.sendSelection();
}
else if (source == remove2LeftMenuItem)
else if (source == showColumns)
{
viewport.showAllHiddenColumns();
- alignPanel.paintAlignment(true);
+ alignPanel.paintAlignment(true, true);
viewport.sendSelection();
}
else if (source == showSeqs)
{
viewport.showAllHiddenSeqs();
- alignPanel.paintAlignment(true);
+ alignPanel.paintAlignment(true, true);
// uncomment if we want to slave sequence selections in split frame
// viewport.sendSelection();
}
else if (source == hideColumns)
{
viewport.hideSelectedColumns();
- alignPanel.paintAlignment(true);
+ alignPanel.paintAlignment(true, true);
viewport.sendSelection();
}
else if (source == hideSequences
&& viewport.getSelectionGroup() != null)
{
viewport.hideAllSelectedSeqs();
- alignPanel.paintAlignment(true);
+ alignPanel.paintAlignment(true, true);
// uncomment if we want to slave sequence selections in split frame
// viewport.sendSelection();
}
else if (source == hideAllButSelection)
{
toggleHiddenRegions(false, false);
- alignPanel.paintAlignment(true);
+ alignPanel.paintAlignment(true, true);
viewport.sendSelection();
}
else if (source == hideAllSelection)
viewport.expandColSelection(sg, false);
viewport.hideAllSelectedSeqs();
viewport.hideSelectedColumns();
- alignPanel.paintAlignment(true);
+ alignPanel.paintAlignment(true, true);
viewport.sendSelection();
}
else if (source == showAllHidden)
{
viewport.showAllHiddenColumns();
viewport.showAllHiddenSeqs();
- alignPanel.paintAlignment(true);
+ alignPanel.paintAlignment(true, true);
viewport.sendSelection();
}
else if (source == showGroupConsensus)
{
System.exit(0);
}
- else
+
+ viewport = null;
+ if (alignPanel != null && alignPanel.overviewPanel != null)
{
+ alignPanel.overviewPanel.dispose();
}
- viewport = null;
alignPanel = null;
this.dispose();
}
}
viewport.getAlignment().moveSelectedSequencesByOne(sg,
up ? null : viewport.getHiddenRepSequences(), up);
- alignPanel.paintAlignment(true);
+ alignPanel.paintAlignment(true, false);
/*
* Also move cDNA/protein complement sequences
viewport, complement);
complement.getAlignment().moveSelectedSequencesByOne(mappedSelection,
up ? null : complement.getHiddenRepSequences(), up);
- getSplitFrame().getComplement(this).alignPanel.paintAlignment(true);
+ getSplitFrame().getComplement(this).alignPanel.paintAlignment(true,
+ false);
}
}
{
PaintRefresher.Refresh(this, viewport.getSequenceSetId());
alignPanel.updateAnnotation();
- alignPanel.paintAlignment(true);
+ alignPanel.paintAlignment(true, true);
}
}
// JAL-2034 - should delegate to
// alignPanel to decide if overview needs
// updating.
- alignPanel.paintAlignment(false);
+ alignPanel.paintAlignment(false, false);
PaintRefresher.Refresh(alignPanel, viewport.getSequenceSetId());
viewport.sendSelection();
}
// JAL-2034 - should delegate to
// alignPanel to decide if overview needs
// updating.
- alignPanel.paintAlignment(false);
+ alignPanel.paintAlignment(false, false);
PaintRefresher.Refresh(alignPanel, viewport.getSequenceSetId());
viewport.sendSelection();
}
public void invertColSel_actionPerformed()
{
viewport.invertColumnSelection();
- alignPanel.paintAlignment(true);
+ alignPanel.paintAlignment(true, false);
PaintRefresher.Refresh(alignPanel, viewport.getSequenceSetId());
viewport.sendSelection();
}
{
viewport.setShowJVSuffix(seqLimits.getState());
alignPanel.fontChanged();
- alignPanel.paintAlignment(true);
+ alignPanel.paintAlignment(true, false);
}
protected void colourTextMenuItem_actionPerformed()
{
viewport.setColourText(colourTextMenuItem.getState());
- alignPanel.paintAlignment(true);
+ alignPanel.paintAlignment(false, false);
}
protected void displayNonconservedMenuItem_actionPerformed()
{
viewport.setShowUnconserved(displayNonconservedMenuItem.getState());
- alignPanel.paintAlignment(true);
+ alignPanel.paintAlignment(false, false);
}
protected void wrapMenuItem_actionPerformed()
scaleAbove.setEnabled(wrapMenuItem.getState());
scaleLeft.setEnabled(wrapMenuItem.getState());
scaleRight.setEnabled(wrapMenuItem.getState());
- alignPanel.paintAlignment(true);
+ alignPanel.paintAlignment(true, false);
}
public void overviewMenuItem_actionPerformed()
{
viewport.setGlobalColourScheme(cs);
- alignPanel.paintAlignment(true);
+ alignPanel.paintAlignment(true, true);
}
protected void modifyPID_actionPerformed()
addHistoryItem(new OrderCommand("Pairwise Sort", oldOrder,
viewport.getAlignment()));
- alignPanel.paintAlignment(true);
+ alignPanel.paintAlignment(true, false);
}
public void sortIDMenuItem_actionPerformed()
AlignmentSorter.sortByID(viewport.getAlignment());
addHistoryItem(
new OrderCommand("ID Sort", oldOrder, viewport.getAlignment()));
- alignPanel.paintAlignment(true);
+ alignPanel.paintAlignment(true, false);
}
public void sortLengthMenuItem_actionPerformed()
AlignmentSorter.sortByLength(viewport.getAlignment());
addHistoryItem(new OrderCommand("Length Sort", oldOrder,
viewport.getAlignment()));
- alignPanel.paintAlignment(true);
+ alignPanel.paintAlignment(true, false);
}
public void sortGroupMenuItem_actionPerformed()
AlignmentSorter.sortByGroup(viewport.getAlignment());
addHistoryItem(new OrderCommand("Group Sort", oldOrder,
viewport.getAlignment()));
- alignPanel.paintAlignment(true);
+ alignPanel.paintAlignment(true, false);
}
current.insertCharAt(Width - 1, viewport.getGapCharacter());
}
}
- alignPanel.paintAlignment(true);
+ alignPanel.paintAlignment(false, false);
}
if ((viewport.getSelectionGroup() != null
current.insertCharAt(Width - 1, viewport.getGapCharacter());
}
}
- alignPanel.paintAlignment(true);
+ alignPanel.paintAlignment(false, false);
}
addHistoryItem(new OrderCommand(MessageManager
.formatMessage("label.order_by_params", new String[]
{ title }), oldOrder, viewport.getAlignment()));
- alignPanel.paintAlignment(true);
+ alignPanel.paintAlignment(true, false);
}
/**
addHistoryItem(new OrderCommand(undoname, oldOrder,
viewport.getAlignment()));
}
- alignPanel.paintAlignment(true);
+ alignPanel.paintAlignment(true, false);
return true;
}
{
// register the association(s) and quit, don't create any windows.
if (StructureSelectionManager.getStructureSelectionManager(applet)
- .setMapping(seqs, chains, pdb.getFile(), protocol) == null)
+ .setMapping(seqs, chains, pdb.getFile(), protocol, null) == null)
{
System.err.println("Failed to map " + pdb.getFile() + " ("
+ protocol + ") to any sequences");
*/
package jalview.appletgui;
-import jalview.analysis.TreeModel;
import jalview.api.AlignViewportI;
import jalview.api.FeatureSettingsModelI;
import jalview.bin.JalviewLite;
boolean validCharWidth = true;
- TreeModel currentTree = null;
-
public jalview.bin.JalviewLite applet;
boolean MAC = false;
private AnnotationColumnChooser annotationColumnSelectionState;
- @Override
- public void finalize()
- {
- applet = null;
- quality = null;
- alignment = null;
- colSel = null;
- }
-
public AlignViewport(AlignmentI al, JalviewLite applet)
{
super(al);
ranges.setEndSeq(height / getCharHeight());
}
- public void setCurrentTree(TreeModel tree)
- {
- currentTree = tree;
- }
-
- public TreeModel getCurrentTree()
- {
- return currentTree;
- }
-
boolean centreColumnLabels;
public boolean getCentreColumnLabels()
// this value is set false when selection area being dragged
boolean fastPaint = true;
- @Override
- public void finalize() throws Throwable
- {
- alignFrame = null;
- av = null;
- vpRanges = null;
- seqPanel = null;
- seqPanelHolder = null;
- sequenceHolderPanel = null;
- scalePanel = null;
- scalePanelHolder = null;
- annotationPanel = null;
- annotationPanelHolder = null;
- annotationSpaceFillerHolder = null;
- super.finalize();
- }
-
public AlignmentPanel(AlignFrame af, final AlignViewport av)
{
try
vpRanges.scrollToWrappedVisible(start);
}
- paintAlignment(redrawOverview);
+ paintAlignment(redrawOverview, false);
return true;
}
apvscroll.addNotify();
hscroll.addNotify();
validate();
- paintAlignment(true);
+ paintAlignment(true, false);
}
/**
* Repaint the alignment and annotations, and, optionally, any overview window
*/
@Override
- public void paintAlignment(boolean updateOverview)
+ public void paintAlignment(boolean updateOverview,
+ boolean updateStructures)
{
final AnnotationSorter sorter = new AnnotationSorter(getAlignment(),
av.isShowAutocalculatedAbove());
av.getSortAnnotationsBy());
repaint();
- if (updateOverview)
+ if (updateStructures)
{
- // TODO: determine if this paintAlignment changed structure colours
jalview.structure.StructureSelectionManager
.getStructureSelectionManager(av.applet)
.sequenceColoursChanged(this);
-
+ }
+ if (updateOverview)
+ {
if (overviewPanel != null)
{
overviewPanel.updateOverviewImage();
oldcs = av.getGlobalColourScheme();
if (av.getAlignment().getGroups() != null)
{
- oldgroupColours = new HashMap<SequenceGroup, ColourSchemeI>();
+ oldgroupColours = new HashMap<>();
for (SequenceGroup sg : ap.av.getAlignment().getGroups())
{
oldgroupColours.put(sg, sg.getColourScheme());
// TODO remove duplication with gui.AnnotationRowFilter
// TODO add 'per sequence only' option / parameter
- annotationLabels = new HashMap<AlignmentAnnotation, String>();
- Vector<String> list = new Vector<String>();
+ annotationLabels = new HashMap<>();
+ Vector<String> list = new Vector<>();
AlignmentAnnotation[] anns = av.getAlignment().getAlignmentAnnotation();
if (anns == null)
{
else if (evt.getSource() == cancel)
{
reset();
- ap.paintAlignment(true);
+ ap.paintAlignment(true, true);
frame.setVisible(false);
}
}
currentAnnotation.threshold.value = slider.getValue() / 1000f;
- ap.paintAlignment(false);
+ ap.paintAlignment(false, false);
}
}
// update colours in linked windows
ap.alignmentChanged();
- ap.paintAlignment(true);
+ ap.paintAlignment(true, true);
}
void reset()
sg.setColourScheme(oldgroupColours.get(sg));
}
}
- ap.paintAlignment(true);
+ ap.paintAlignment(true, true);
}
@Override
@Override
public void mouseReleased(MouseEvent evt)
{
- ap.paintAlignment(true);
+ ap.paintAlignment(true, true);
}
@Override
av.getAlignment().setHiddenColumns(oldHidden);
}
av.sendSelection();
- ap.paintAlignment(true);
+ ap.paintAlignment(true, true);
}
}
sliderDragging = false;
valueChanged(true);
}
- ap.paintAlignment(true);
+ ap.paintAlignment(true, true);
}
});
}
if (slider.isEnabled())
{
getCurrentAnnotation().threshold.value = slider.getValue() / 1000f;
- updateView();
- ap.paintAlignment(false);
+ updateView(); // this also calls paintAlignment(true,true)
}
}
filterParams = null;
av.setAnnotationColumnSelectionState(this);
av.sendSelection();
- ap.paintAlignment(true);
+ ap.paintAlignment(true, true);
}
public HiddenColumns getOldHiddenColumns()
ap.annotationPanel.adjustPanelHeight();
setSize(getSize().width, ap.annotationPanel.getSize().height);
ap.validate();
- ap.paintAlignment(true);
+ // TODO: only paint if we needed to
+ ap.paintAlignment(true, true);
}
boolean editLabelDescription(AlignmentAnnotation annotation)
{
ap.av.setIgnoreGapsConsensus(cbmi.getState(), ap);
}
- ap.paintAlignment(true);
+ ap.paintAlignment(true, true);
}
});
popup.add(cbmi);
}
}
}
- ap.paintAlignment(false);
+ ap.paintAlignment(false, false);
PaintRefresher.Refresh(ap, ap.av.getSequenceSetId());
ap.av.sendSelection();
}
sg.addSequence(aa[selectedRow].sequenceRef, false);
}
ap.av.setSelectionGroup(sg);
- ap.paintAlignment(false);
+ ap.paintAlignment(false, false);
PaintRefresher.Refresh(ap, ap.av.getSequenceSetId());
ap.av.sendSelection();
}
graphStretchY = evt.getY();
av.calcPanelHeight();
needValidating = true;
- ap.paintAlignment(true);
+ // TODO: only update overview visible geometry
+ ap.paintAlignment(true, false);
}
else
{
public void cancel_actionPerformed(ActionEvent e)
{
reset();
- ap.paintAlignment(true);
+ ap.paintAlignment(true, true);
frame.setVisible(false);
}
AlignmentPanel ap;
- List<AlignmentPanel> _aps = new ArrayList<AlignmentPanel>(); // remove? never
+ List<AlignmentPanel> _aps = new ArrayList<>(); // remove? never
// added to
String fileLoadingError;
{
reader = StructureSelectionManager
.getStructureSelectionManager(ap.av.applet)
- .setMapping(seq, chains, pdbentry.getFile(), protocol);
+ .setMapping(seq, chains, pdbentry.getFile(), protocol, null);
// PROMPT USER HERE TO ADD TO NEW OR EXISTING VIEW?
// FOR NOW, LETS JUST OPEN A NEW WINDOW
}
void centerViewer()
{
- Vector<String> toshow = new Vector<String>();
+ Vector<String> toshow = new Vector<>();
for (int i = 0; i < chainMenu.getItemCount(); i++)
{
if (chainMenu.getItem(i) instanceof CheckboxMenuItem)
import jalview.datamodel.PDBEntry;
import jalview.datamodel.SequenceI;
import jalview.ext.jmol.JalviewJmolBinding;
+import jalview.gui.IProgressIndicator;
import jalview.io.DataSourceType;
import jalview.structure.StructureSelectionManager;
// TODO Auto-generated method stub
return null;
}
+
+ @Override
+ protected IProgressIndicator getIProgressIndicator()
+ {
+ // no progress indicators on the applet
+ return null;
+ }
}
import jalview.datamodel.PDBEntry;
import jalview.datamodel.SequenceI;
import jalview.ext.jmol.JalviewJmolBinding;
+import jalview.gui.IProgressIndicator;
import jalview.io.DataSourceType;
import java.awt.Container;
}
@Override
+ protected IProgressIndicator getIProgressIndicator()
+ {
+ // no progress indicators on applet (could access javascript for this)
+ return null;
+ }
+
+ @Override
public void updateColours(Object source)
{
}
}
+
@Override
public SequenceRenderer getSequenceRenderer(AlignmentViewPanel alignment)
{
@Override
public void refreshPdbEntries()
{
- List<PDBEntry> pdbe = new ArrayList<PDBEntry>();
- List<String> fileids = new ArrayList<String>();
+ List<PDBEntry> pdbe = new ArrayList<>();
+ List<String> fileids = new ArrayList<>();
SequenceI[] sq = ap.av.getAlignment().getSequencesArray();
for (int s = 0; s < sq.length; s++)
{
}
// findAllFeatures();
- ap.paintAlignment(true);
+ ap.paintAlignment(true, true);
return true;
}
// Group selection states
void resetTable(boolean groupsChanged)
{
- List<String> displayableTypes = new ArrayList<String>();
- Set<String> foundGroups = new HashSet<String>();
+ List<String> displayableTypes = new ArrayList<>();
+ Set<String> foundGroups = new HashSet<>();
AlignmentI alignment = av.getAlignment();
* and keep track of which groups are visible
*/
Set<String> groups = seq.getFeatures().getFeatureGroups(true);
- Set<String> visibleGroups = new HashSet<String>();
+ Set<String> visibleGroups = new HashSet<>();
for (String group : groups)
{
// if (group == null || fr.checkGroupVisibility(group, true))
fr.setFeaturePriority(data);
- ap.paintAlignment(updateOverview);
+ ap.paintAlignment(updateOverview, updateOverview);
}
MyCheckbox selectedCheck;
{
featurePanel.removeAll();
resetTable(false);
- ap.paintAlignment(true);
+ ap.paintAlignment(true, true);
}
@Override
public void adjustmentValueChanged(AdjustmentEvent evt)
{
fr.setTransparency((100 - transparency.getValue()) / 100f);
- ap.paintAlignment(true);
+ ap.paintAlignment(true, true);
}
class MyCheckbox extends Checkbox
{
ap.av.setCharWidth(oldCharWidth);
}
- ap.paintAlignment(true);
+ ap.paintAlignment(true, false);
}
else if (tp != null)
{
// TODO: add in group link parameter
// make a list of label,url pairs
- HashMap<String, String> urlList = new HashMap<String, String>();
+ HashMap<String, String> urlList = new HashMap<>();
if (viewport.applet != null)
{
for (int i = 1; i < 10; i++)
}
lastid = seq;
- alignPanel.paintAlignment(false);
+ alignPanel.paintAlignment(false, false);
}
@Override
}
else
{
- nlinks = new ArrayList<String>();
+ nlinks = new ArrayList<>();
}
for (SequenceFeature sf : sq.getFeatures().getNonPositionalFeatures())
selectSeq(seq);
}
- alignPanel.paintAlignment(false);
+ alignPanel.paintAlignment(false, false);
}
void selectSeq(int seq)
running = false;
}
- alignPanel.paintAlignment(true);
+ alignPanel.paintAlignment(true, false);
try
{
Thread.sleep(100);
import java.awt.CheckboxMenuItem;
import java.awt.Cursor;
import java.awt.Dimension;
+import java.awt.Frame;
import java.awt.Panel;
import java.awt.PopupMenu;
import java.awt.event.ComponentAdapter;
av.getAlignment().getHiddenSequences(),
av.getAlignment().getHiddenColumns());
}
- ap.paintAlignment(false);
+ ap.paintAlignment(false, false);
}
}
try
{
av.getRanges().removePropertyChangeListener(this);
+ Frame parent = (Frame) getParent();
+ parent.dispose();
+ parent.setVisible(false);
} finally
{
av = null;
import jalview.datamodel.SequenceI;
import java.awt.Component;
-import java.util.Enumeration;
import java.util.Hashtable;
+import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Vector;
return;
}
- for (String id : components.keySet())
+ Iterator<String> it = components.keySet().iterator();
+ while (it.hasNext())
{
- Vector<Component> comps = components.get(id);
+ Vector<Component> comps = components.get(it.next());
comps.removeElement(comp);
- if (comps.size() == 0)
+ if (comps.isEmpty())
{
- components.remove(id);
+ it.remove();
}
}
}
return;
}
- Enumeration<Component> e = comps.elements();
- while (e.hasMoreElements())
+ Iterator<Component> it = comps.iterator();
+ while (it.hasNext())
{
- comp = e.nextElement();
+ comp = it.next();
if (comp == source)
{
if (!comp.isValid())
{
- comps.removeElement(comp);
+ it.remove();
}
else if (validateSequences && comp instanceof AlignmentPanel
&& source instanceof AlignmentPanel)
float value = slider.getValue();
- List<SequenceI> redundantSequences = new ArrayList<SequenceI>();
+ List<SequenceI> redundantSequences = new ArrayList<>();
for (int i = 0; i < redundancy.length; i++)
{
if (value <= redundancy[i])
ap.av.getAlignment().getSequences());
}
- ap.paintAlignment(true);
+ ap.paintAlignment(true, true);
if (historyList.size() == 0)
{
sg.setStartRes(min);
sg.setEndRes(max);
}
- ap.paintAlignment(false);
+ ap.paintAlignment(false, false);
av.sendSelection();
}
{
av.showColumn(reveal[0]);
reveal = null;
- ap.paintAlignment(true);
+ ap.paintAlignment(true, true);
av.sendSelection();
}
});
{
av.showAllHiddenColumns();
reveal = null;
- ap.paintAlignment(true);
+ ap.paintAlignment(true, true);
av.sendSelection();
}
});
av.setSelectionGroup(null);
}
- ap.paintAlignment(true);
+ ap.paintAlignment(true, true);
av.sendSelection();
}
});
if (!stretchingGroup)
{
- ap.paintAlignment(false);
+ ap.paintAlignment(false, false);
return;
}
}
stretchingGroup = false;
- ap.paintAlignment(false);
+ ap.paintAlignment(false, false);
av.sendSelection();
}
{
stretchingGroup = true;
cs.stretchGroup(res, sg, min, max);
- ap.paintAlignment(false);
+ ap.paintAlignment(false, false);
}
}
sg.addSequence(sequence, false);
av.setSelectionGroup(sg);
}
- ap.paintAlignment(false);
+ ap.paintAlignment(false, false);
av.sendSelection();
}
* alignment column
* @param seq
* index of sequence in alignment
- * @return position of column in sequence or -1 if at gap
*/
void setStatusMessage(SequenceI sequence, int column, int seq)
{
lastMousePress = evt.getPoint();
- ap.paintAlignment(false);
+ ap.paintAlignment(false, false);
ap.annotationPanel.image = null;
return;
}
{
if (links == null)
{
- links = new Vector<String>();
+ links = new Vector<>();
}
links.addAll(sf.links);
}
}
}
PaintRefresher.Refresh(ap, av.getSequenceSetId());
- ap.paintAlignment(needOverviewUpdate);
+ ap.paintAlignment(needOverviewUpdate, needOverviewUpdate);
needOverviewUpdate = false;
changeEndRes = false;
changeStartRes = false;
@Override
public void mouseReleased(MouseEvent evt)
{
- ap.paintAlignment(true);
+ ap.paintAlignment(true, true);
}
@Override
createSplitFrameWindow(embedded, applet);
validate();
topFrame.alignPanel.adjustAnnotationHeight();
- topFrame.alignPanel.paintAlignment(true);
+ topFrame.alignPanel.paintAlignment(true, true);
bottomFrame.alignPanel.adjustAnnotationHeight();
- bottomFrame.alignPanel.paintAlignment(true);
+ bottomFrame.alignPanel.paintAlignment(true, true);
}
/**
Button selectedButton;
- Vector<Color> oldColours = new Vector<Color>();
+ Vector<Color> oldColours = new Vector<>();
ColourSchemeI oldColourScheme;
ap.av.isIgnoreGapsConsensus());
}
ap.seqPanel.seqCanvas.img = null;
- ap.paintAlignment(true);
+ ap.paintAlignment(true, true);
}
else if (jmol != null)
{
{
ap.av.setGlobalColourScheme(oldColourScheme);
}
- ap.paintAlignment(true);
+ ap.paintAlignment(true, true);
}
frame.setVisible(false);
*/
private AlignViewControllerGuiI avcg;
- @Override
- protected void finalize() throws Throwable
- {
- viewport = null;
- alignPanel = null;
- avcg = null;
- };
-
public AlignViewController(AlignViewControllerGuiI alignFrame,
AlignViewportI viewport, AlignmentViewPanel alignPanel)
{
if (changed)
{
viewport.setColumnSelection(cs);
- alignPanel.paintAlignment(true);
+ alignPanel.paintAlignment(false, false);
int columnCount = invert
? (sqcol.getEndRes() - sqcol.getStartRes() + 1)
- bs.cardinality()
if (!extendCurrent)
{
cs.clear();
- alignPanel.paintAlignment(true);
+ alignPanel.paintAlignment(false, false);
}
}
return false;
AlignmentSorter.sortByFeature(typ, gps, start, stop, al, method);
avcg.addHistoryItem(new OrderCommand(methodText, oldOrder,
viewport.getAlignment()));
- alignPanel.paintAlignment(true);
+ alignPanel.paintAlignment(true, false);
}
{
avcg.getFeatureSettingsUI().discoverAllFeatureData();
}
- alignPanel.paintAlignment(true);
+ alignPanel.paintAlignment(true, true);
}
return featuresFile;
if (changed)
{
viewport.setColumnSelection(cs);
- alignPanel.paintAlignment(true);
+ alignPanel.paintAlignment(false, false);
int columnCount = invert
? (sqcol.getEndRes() - sqcol.getStartRes() + 1)
- bs.cardinality()
if (!extendCurrent)
{
cs.clear();
- alignPanel.paintAlignment(true);
+ alignPanel.paintAlignment(false, false);
}
}
return false;
private boolean isrna;
- /*
- * (non-Javadoc)
- *
- * @see java.lang.Object#finalize()
- */
- @Override
- protected void finalize() throws Throwable
- {
- sequenceRef = null;
- groupRef = null;
- super.finalize();
- }
-
public static int getGraphValueFromString(String string)
{
if (string.equalsIgnoreCase("BAR_GRAPH"))
hideStart = region[0];
hideEnd = region[1];
// edit hidden regions to selection range
- if (hideStart < last)
+
+ // just move on if hideEnd is before last
+ if (hideEnd < last)
{
- if (hideEnd > last)
- {
- hideStart = last;
- }
- else
- {
- continue;
- }
+ continue;
}
-
+ // exit if next region is after end
if (hideStart > end)
{
break;
}
- if (hideEnd > end)
+ // truncate region at start if last falls in region
+ if ((hideStart < last) && (hideEnd >= last))
{
- hideEnd = end;
+ hideStart = last;
}
- if (hideStart > hideEnd)
+ // truncate region at end if end falls in region
+ if (hideEnd > end) // already checked that hideStart<=end
{
- break;
+ hideEnd = end;
}
+
/**
* form operations...
*/
last = hideEnd + 1;
}
// Final match if necessary.
- if (last < end)
+ if (last <= end)
{
addOperation(CigarArray.M, end - last + 1);
}
to = tto;
}
- /*
- * (non-Javadoc)
- *
- * @see java.lang.Object#finalize()
- */
- @Override
- protected void finalize() throws Throwable
- {
- map = null;
- to = null;
- super.finalize();
- }
-
/**
* Returns an iterator which can serve up the aligned codon column positions
* and their corresponding peptide products
import java.util.ListIterator;
import java.util.Vector;
-import com.stevesoft.pat.Regex;
-
import fr.orsay.lri.varna.models.rna.RNA;
/**
*/
public class Sequence extends ASequence implements SequenceI
{
- private static final Regex limitrx = new Regex(
- "[/][0-9]{1,}[-][0-9]{1,}$");
-
- private static final Regex endrx = new Regex("[0-9]{1,}$");
-
SequenceI datasetSequence;
String name;
*/
int index = -1;
- private SequenceFeatures sequenceFeatureStore;
+ private SequenceFeaturesI sequenceFeatureStore;
/*
* A cursor holding the approximate current view position to the sequence,
checkValidRange();
}
+ /**
+ * If 'name' ends in /i-j, where i >= j > 0 are integers, extracts i and j as
+ * start and end respectively and removes the suffix from the name
+ */
void parseId()
{
if (name == null)
"POSSIBLE IMPLEMENTATION ERROR: null sequence name passed to constructor.");
name = "";
}
- // Does sequence have the /start-end signature?
- if (limitrx.search(name))
+ int slashPos = name.lastIndexOf('/');
+ if (slashPos > -1 && slashPos < name.length() - 1)
{
- name = limitrx.left();
- endrx.search(limitrx.stringMatched());
- setStart(Integer.parseInt(limitrx.stringMatched().substring(1,
- endrx.matchedFrom() - 1)));
- setEnd(Integer.parseInt(endrx.stringMatched()));
+ String suffix = name.substring(slashPos + 1);
+ String[] range = suffix.split("-");
+ if (range.length == 2)
+ {
+ try
+ {
+ int from = Integer.valueOf(range[0]);
+ int to = Integer.valueOf(range[1]);
+ if (from > 0 && to >= from)
+ {
+ name = name.substring(0, slashPos);
+ setStart(from);
+ setEnd(to);
+ checkValidRange();
+ }
+ } catch (NumberFormatException e)
+ {
+ // leave name unchanged if suffix is invalid
+ }
+ }
}
}
+ /**
+ * Ensures that 'end' is not before the end of the sequence, that is,
+ * (end-start+1) is at least as long as the count of ungapped positions. Note
+ * that end is permitted to be beyond the end of the sequence data.
+ */
void checkValidRange()
{
// Note: JAL-774 :
int endRes = 0;
for (int j = 0; j < sequence.length; j++)
{
- if (!jalview.util.Comparison.isGap(sequence[j]))
+ if (!Comparison.isGap(sequence[j]))
{
endRes++;
}
}
/**
- * DOCUMENT ME!
+ * Sets the sequence name. If the name ends in /start-end, then the start-end
+ * values are parsed out and set, and the suffix is removed from the name.
*
- * @param name
- * DOCUMENT ME!
+ * @param theName
*/
@Override
- public void setName(String name)
+ public void setName(String theName)
{
- this.name = name;
+ this.name = theName;
this.parseId();
}
* and we may have included adjacent or enclosing features;
* remove any that are not enclosing, non-contact features
*/
- if (endPos > this.end || Comparison.isGap(sequence[toColumn - 1]))
+ boolean endColumnIsGapped = toColumn > 0 && toColumn <= sequence.length
+ && Comparison.isGap(sequence[toColumn - 1]);
+ if (endPos > this.end || endColumnIsGapped)
{
ListIterator<SequenceFeature> it = result.listIterator();
while (it.hasNext())
}
Set<String> featureTypes = getFeatureTypes(ontologyTerm);
+ if (featureTypes.isEmpty())
+ {
+ /*
+ * no features of the specified type or any sub-type
+ */
+ return new ArrayList<>();
+ }
+
return getAllFeatures(featureTypes.toArray(new String[featureTypes
.size()]));
}
}
/**
- * Converts a query, which may contain one or more gene or transcript
- * identifiers, into a non-redundant list of gene identifiers.
+ * Converts a query, which may contain one or more gene, transcript, or
+ * external (to Ensembl) identifiers, into a non-redundant list of gene
+ * identifiers.
*
* @param accessions
* @return
for (String acc : accessions.split(getAccessionSeparator()))
{
- if (isGeneIdentifier(acc))
- {
- if (!geneIds.contains(acc))
- {
- geneIds.add(acc);
- }
- }
-
/*
- * if given a transcript id, look up its gene parent
+ * First try lookup as an Ensembl (gene or transcript) identifier
*/
- else if (isTranscriptIdentifier(acc))
+ String geneId = new EnsemblLookup(getDomain()).getGeneId(acc);
+ if (geneId != null)
{
- String geneId = new EnsemblLookup(getDomain()).getParent(acc);
- if (geneId != null && !geneIds.contains(geneId))
+ if (!geneIds.contains(geneId))
{
geneIds.add(geneId);
}
}
- else if (isProteinIdentifier(acc))
- {
- String tscriptId = new EnsemblLookup(getDomain()).getParent(acc);
- if (tscriptId != null)
- {
- String geneId = new EnsemblLookup(getDomain())
- .getParent(tscriptId);
-
- if (geneId != null && !geneIds.contains(geneId))
- {
- geneIds.add(geneId);
- }
- }
- // NOTE - acc is lost if it resembles an ENS.+ ID but isn't actually
- // resolving to one... e.g. ENSMICP00000009241
- }
- /*
- * if given a gene or other external name, lookup and fetch
- * the corresponding gene for all model organisms
- */
else
{
+ /*
+ * if given a gene or other external name, lookup and fetch
+ * the corresponding gene for all model organisms
+ */
List<String> ids = new EnsemblSymbol(getDomain(), getDbSource(),
- getDbVersion()).getIds(acc);
- for (String geneId : ids)
+ getDbVersion()).getGeneIds(acc);
+ for (String id : ids)
{
- if (!geneIds.contains(geneId))
+ if (!geneIds.contains(id))
{
- geneIds.add(geneId);
+ geneIds.add(id);
}
}
}
}
/**
- * Attempts to get Ensembl stable identifiers for model organisms for a gene
- * name by calling the xrefs symbol REST service to resolve the gene name.
- *
- * @param query
- * @return
- */
- protected String getGeneIdentifiersForName(String query)
- {
- List<String> ids = new EnsemblSymbol(getDomain(), getDbSource(),
- getDbVersion()).getIds(query);
- if (ids != null)
- {
- for (String id : ids)
- {
- if (isGeneIdentifier(id))
- {
- return id;
- }
- }
- }
- return null;
- }
-
- /**
* Constructs all transcripts for the gene, as identified by "transcript"
* features whose Parent is the requested gene. The coding transcript
* sequences (i.e. with introns omitted) are added to the alignment.
/**
* Returns a list of the transcript features on the sequence whose Parent is
* the gene for the accession id.
+ * <p>
+ * Transcript features are those of type "transcript", or any of its sub-types
+ * in the Sequence Ontology e.g. "mRNA", "processed_transcript". We also
+ * include "NMD_transcript_variant", because this type behaves like a
+ * transcript identifier in Ensembl, although strictly speaking it is not in
+ * the SO.
*
* @param accId
* @param geneSequence
List<SequenceFeature> transcriptFeatures = new ArrayList<SequenceFeature>();
String parentIdentifier = GENE_PREFIX + accId;
- // todo optimise here by transcript type!
+
List<SequenceFeature> sfs = geneSequence.getFeatures()
- .getPositionalFeatures();
+ .getFeaturesByOntology(SequenceOntologyI.TRANSCRIPT);
+ sfs.addAll(geneSequence.getFeatures().getPositionalFeatures(
+ SequenceOntologyI.NMD_TRANSCRIPT_VARIANT));
for (SequenceFeature sf : sfs)
{
- if (isTranscript(sf.getType()))
+ String parent = (String) sf.getValue(PARENT);
+ if (parentIdentifier.equals(parent))
{
- String parent = (String) sf.getValue(PARENT);
- if (parentIdentifier.equals(parent))
- {
- transcriptFeatures.add(sf);
- }
+ transcriptFeatures.add(sf);
}
}
}
@Override
- public boolean isGeneIdentifier(String query)
- {
- return true;
- }
-
- @Override
public String getDbName()
{
return "EnsemblGenomes";
}
+ private String Wrong[];
@Override
public String getTestQuery()
{
// flag set to true if REST major version is not the one expected
boolean restMajorVersionMismatch;
- /*
- * absolute time to wait till if we overloaded the REST service
- */
- long retryAfter;
-
/**
* Constructor given expected REST version number e.g 4.5 or 3.4.3
*
public class EnsemblLookup extends EnsemblRestClient
{
+ private static final String OBJECT_TYPE_TRANSLATION = "Translation";
+ private static final String PARENT = "Parent";
+ private static final String OBJECT_TYPE_TRANSCRIPT = "Transcript";
+ private static final String ID = "id";
+ private static final String OBJECT_TYPE_GENE = "Gene";
+ private static final String OBJECT_TYPE = "object_type";
+
/**
* Default constructor (to use rest.ensembl.org)
*/
protected URL getUrl(String identifier)
{
String url = getDomain() + "/lookup/id/" + identifier
- + "?content-type=application/json";
+ + CONTENT_TYPE_JSON;
try
{
return new URL(url);
* @param identifier
* @return
*/
- public String getParent(String identifier)
+ public String getGeneId(String identifier)
{
List<String> ids = Arrays.asList(new String[] { identifier });
{
br = getHttpResponse(url, ids);
}
- return (parseResponse(br));
+ return br == null ? null : parseResponse(br);
} catch (IOException e)
{
// ignore
}
/**
- * Parses "Parent" from the JSON response and returns the value, or null if
- * not found
+ * Parses the JSON response and returns the gene identifier, or null if not
+ * found. If the returned object_type is Gene, returns the id, if Transcript
+ * returns the Parent. If it is Translation (peptide identifier), then the
+ * Parent is the transcript identifier, so we redo the search with this value.
*
* @param br
* @return
*/
protected String parseResponse(BufferedReader br) throws IOException
{
- String parent = null;
+ String geneId = null;
JSONParser jp = new JSONParser();
try
{
JSONObject val = (JSONObject) jp.parse(br);
- parent = val.get("Parent").toString();
+ String type = val.get(OBJECT_TYPE).toString();
+ if (OBJECT_TYPE_GENE.equalsIgnoreCase(type))
+ {
+ geneId = val.get(ID).toString();
+ }
+ else if (OBJECT_TYPE_TRANSCRIPT.equalsIgnoreCase(type))
+ {
+ geneId = val.get(PARENT).toString();
+ }
+ else if (OBJECT_TYPE_TRANSLATION.equalsIgnoreCase(type))
+ {
+ String transcriptId = val.get(PARENT).toString();
+ try
+ {
+ geneId = getGeneId(transcriptId);
+ } catch (StackOverflowError e)
+ {
+ /*
+ * unlikely data condition error!
+ */
+ System.err
+ .println("** Ensembl lookup "
+ + getUrl(transcriptId).toString()
+ + " looping on Parent!");
+ }
+ }
} catch (ParseException e)
{
// ignore
}
- return parent;
+ return geneId;
}
}
import jalview.datamodel.AlignmentI;
import jalview.datamodel.SequenceFeature;
-import java.util.List;
-
import com.stevesoft.pat.Regex;
/**
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
+import java.net.ProtocolException;
import java.net.URL;
import java.util.HashMap;
import java.util.List;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
-import com.stevesoft.pat.Regex;
-
/**
* Base class for Ensembl REST service clients
*
private static final int CONNECT_TIMEOUT_MS = 10 * 1000; // 10 seconds
+ private static final int MAX_RETRIES = 3;
+
+ private static final int HTTP_OK = 200;
+
+ private static final int HTTP_OVERLOAD = 429;
+
/*
* update these constants when Jalview has been checked / updated for
* changes to Ensembl REST API (ref JAL-2105)
* @see https://github.com/Ensembl/ensembl-rest/wiki/Change-log
* @see http://rest.ensembl.org/info/rest?content-type=application/json
*/
- private static final String LATEST_ENSEMBLGENOMES_REST_VERSION = "5.0";
+ private static final String LATEST_ENSEMBLGENOMES_REST_VERSION = "6.0";
- private static final String LATEST_ENSEMBL_REST_VERSION = "5.0";
+ private static final String LATEST_ENSEMBL_REST_VERSION = "6.1";
private static final String REST_CHANGE_LOG = "https://github.com/Ensembl/ensembl-rest/wiki/Change-log";
private final static long VERSION_RETEST_INTERVAL = 1000L * 3600; // 1 hr
- private static final Regex PROTEIN_REGEX = new Regex(
- "(ENS)([A-Z]{3}|)P[0-9]{11}$");
-
- private static final Regex TRANSCRIPT_REGEX = new Regex(
- "(ENS)([A-Z]{3}|)T[0-9]{11}$");
-
- private static final Regex GENE_REGEX = new Regex(
- "(ENS)([A-Z]{3}|)G[0-9]{11}$");
+ protected static final String CONTENT_TYPE_JSON = "?content-type=application/json";
static
{
- domainData = new HashMap<String, EnsemblInfo>();
+ domainData = new HashMap<>();
domainData.put(ENSEMBL_REST,
new EnsemblInfo(ENSEMBL_REST, LATEST_ENSEMBL_REST_VERSION));
domainData.put(ENSEMBL_GENOMES_REST, new EnsemblInfo(
setDomain(d);
}
- /**
- * Answers true if the query matches the regular expression pattern for an
- * Ensembl transcript stable identifier
- *
- * @param query
- * @return
- */
- public boolean isTranscriptIdentifier(String query)
- {
- return query == null ? false : TRANSCRIPT_REGEX.search(query);
- }
-
- /**
- * Answers true if the query matches the regular expression pattern for an
- * Ensembl protein stable identifier
- *
- * @param query
- * @return
- */
- public boolean isProteinIdentifier(String query)
- {
- return query == null ? false : PROTEIN_REGEX.search(query);
- }
-
- /**
- * Answers true if the query matches the regular expression pattern for an
- * Ensembl gene stable identifier
- *
- * @param query
- * @return
- */
- public boolean isGeneIdentifier(String query)
- {
- return query == null ? false : GENE_REGEX.search(query);
- }
-
@Override
public boolean queryInProgress()
{
* @see http://rest.ensembl.org/documentation/info/ping
* @return
*/
- private boolean checkEnsembl()
+ boolean checkEnsembl()
{
BufferedReader br = null;
try
{
// note this format works for both ensembl and ensemblgenomes
// info/ping.json works for ensembl only (March 2016)
- URL ping = new URL(
- getDomain() + "/info/ping?content-type=application/json");
+ URL ping = new URL(getDomain() + "/info/ping" + CONTENT_TYPE_JSON);
/*
* expect {"ping":1} if ok
* if ping takes more than 2 seconds to respond, treat as if unavailable
*/
br = getHttpResponse(ping, null, 2 * 1000);
+ if (br == null)
+ {
+ // error reponse status
+ return false;
+ }
JSONParser jp = new JSONParser();
JSONObject val = (JSONObject) jp.parse(br);
String pingString = val.get("ping").toString();
}
/**
- * Writes the HTTP request and gets the response as a reader.
+ * Sends the HTTP request and gets the response as a reader
*
* @param url
* @param ids
protected BufferedReader getHttpResponse(URL url, List<String> ids,
int readTimeout) throws IOException
{
- // long now = System.currentTimeMillis();
+ int retriesLeft = MAX_RETRIES;
+ HttpURLConnection connection = null;
+ int responseCode = 0;
+
+ while (retriesLeft > 0)
+ {
+ connection = tryConnection(url, ids, readTimeout);
+ responseCode = connection.getResponseCode();
+ if (responseCode == HTTP_OVERLOAD) // 429
+ {
+ retriesLeft--;
+ checkRetryAfter(connection);
+ }
+ else
+ {
+ retriesLeft = 0;
+ }
+ }
+ if (responseCode != HTTP_OK) // 200
+ {
+ /*
+ * note: a GET request for an invalid id returns an error code e.g. 415
+ * but POST request returns 200 and an empty Fasta response
+ */
+ System.err.println("Response code " + responseCode + " for " + url);
+ return null;
+ }
+
+ InputStream response = connection.getInputStream();
+
+ // System.out.println(getClass().getName() + " took "
+ // + (System.currentTimeMillis() - now) + "ms to fetch");
+
+ BufferedReader reader = null;
+ reader = new BufferedReader(new InputStreamReader(response, "UTF-8"));
+ return reader;
+ }
+
+ /**
+ * @param url
+ * @param ids
+ * @param readTimeout
+ * @return
+ * @throws IOException
+ * @throws ProtocolException
+ */
+ protected HttpURLConnection tryConnection(URL url, List<String> ids,
+ int readTimeout) throws IOException, ProtocolException
+ {
+ // System.out.println(System.currentTimeMillis() + " " + url);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
/*
{
writePostBody(connection, ids);
}
-
- int responseCode = connection.getResponseCode();
-
- if (responseCode != 200)
- {
- /*
- * note: a GET request for an invalid id returns an error code e.g. 415
- * but POST request returns 200 and an empty Fasta response
- */
- System.err.println("Response code " + responseCode + " for " + url);
- return null;
- }
- // get content
- InputStream response = connection.getInputStream();
-
- // System.out.println(getClass().getName() + " took "
- // + (System.currentTimeMillis() - now) + "ms to fetch");
-
- checkRateLimits(connection);
-
- BufferedReader reader = null;
- reader = new BufferedReader(new InputStreamReader(response, "UTF-8"));
- return reader;
+ return connection;
}
/**
- * Inspect response headers for any sign of server overload and respect any
- * 'retry-after' directive
+ * Inspects response headers for a 'retry-after' directive, and waits for the
+ * directed period (if less than 10 seconds)
*
* @see https://github.com/Ensembl/ensembl-rest/wiki/Rate-Limits
* @param connection
*/
- void checkRateLimits(HttpURLConnection connection)
+ void checkRetryAfter(HttpURLConnection connection)
{
- // number of requests allowed per time interval:
- String limit = connection.getHeaderField("X-RateLimit-Limit");
- // length of quota time interval in seconds:
- // String period = connection.getHeaderField("X-RateLimit-Period");
- // seconds remaining until usage quota is reset:
- String reset = connection.getHeaderField("X-RateLimit-Reset");
- // number of requests remaining from quota for current period:
- String remaining = connection.getHeaderField("X-RateLimit-Remaining");
- // number of seconds to wait before retrying (if remaining == 0)
String retryDelay = connection.getHeaderField("Retry-After");
// to test:
// retryDelay = "5";
- EnsemblInfo info = domainData.get(getDomain());
if (retryDelay != null)
{
- System.err.println("Ensembl REST service rate limit exceeded, wait "
- + retryDelay + " seconds before retrying");
try
{
- info.retryAfter = System.currentTimeMillis()
- + (1000 * Integer.valueOf(retryDelay));
- } catch (NumberFormatException e)
+ int retrySecs = Integer.valueOf(retryDelay);
+ if (retrySecs > 0 && retrySecs < 10)
+ {
+ System.err
+ .println("Ensembl REST service rate limit exceeded, waiting "
+ + retryDelay + " seconds before retrying");
+ Thread.sleep(1000 * retrySecs);
+ }
+ } catch (NumberFormatException | InterruptedException e)
{
- System.err
- .println("Unexpected value for Retry-After: " + retryDelay);
+ System.err.println("Error handling Retry-After: " + e.getMessage());
}
}
- else
- {
- info.retryAfter = 0;
- // debug:
- // System.out.println(String.format(
- // "%s Ensembl requests remaining of %s (reset in %ss)",
- // remaining, limit, reset));
- }
}
/**
long now = System.currentTimeMillis();
/*
- * check if we are waiting for 'Retry-After' to expire
- */
- if (info.retryAfter > now)
- {
- System.err.println("Still " + (1 + (info.retryAfter - now) / 1000)
- + " secs to wait before retrying Ensembl");
- return false;
- }
- else
- {
- info.retryAfter = 0;
- }
-
- /*
* recheck if Ensembl is up if it was down, or the recheck period has elapsed
*/
boolean retestAvailability = (now
URL url = null;
try
{
- url = new URL(
- getDomain() + "/info/rest?content-type=application/json");
+ url = new URL(getDomain() + "/info/rest" + CONTENT_TYPE_JSON);
BufferedReader br = getHttpResponse(url, null);
+ if (br == null)
+ {
+ return;
+ }
JSONObject val = (JSONObject) jp.parse(br);
String version = val.get("release").toString();
String majorVersion = version.substring(0, version.indexOf("."));
{
JSONParser jp = new JSONParser();
URL url = null;
+ BufferedReader br = null;
+
try
{
- url = new URL(
- getDomain() + "/info/data?content-type=application/json");
- BufferedReader br = getHttpResponse(url, null);
- JSONObject val = (JSONObject) jp.parse(br);
- JSONArray versions = (JSONArray) val.get("releases");
- domainData.get(getDomain()).dataVersion = versions.get(0).toString();
+ url = new URL(getDomain() + "/info/data" + CONTENT_TYPE_JSON);
+ br = getHttpResponse(url, null);
+ if (br != null)
+ {
+ JSONObject val = (JSONObject) jp.parse(br);
+ JSONArray versions = (JSONArray) val.get("releases");
+ domainData.get(getDomain()).dataVersion = versions.get(0)
+ .toString();
+ }
} catch (Throwable t)
{
System.err.println(
"Error checking Ensembl data version: " + t.getMessage());
+ } finally
+ {
+ if (br != null)
+ {
+ try
+ {
+ br.close();
+ } catch (IOException e)
+ {
+ // ignore
+ }
+ }
}
}
*/
public class EnsemblSymbol extends EnsemblXref
{
+ private static final String GENE = "gene";
+ private static final String TYPE = "type";
+ private static final String ID = "id";
+
/**
* Constructor given the target domain to fetch data from
*
while (rvals.hasNext())
{
JSONObject val = (JSONObject) rvals.next();
- String id = val.get("id").toString();
- if (id != null && isGeneIdentifier(id))
+ String id = val.get(ID).toString();
+ String type = val.get(TYPE).toString();
+ if (id != null && GENE.equals(type))
{
result = id;
break;
return result;
}
- protected URL getUrl(String id, Species species)
+ /**
+ * Constructs the URL for the REST symbol endpoint
+ *
+ * @param id
+ * the accession id (Ensembl or external)
+ * @param species
+ * a species name recognisable by Ensembl
+ * @param type
+ * an optional type to filter the response (gene, transcript,
+ * translation)
+ * @return
+ */
+ protected URL getUrl(String id, Species species, String... type)
{
- String url = getDomain() + "/xrefs/symbol/" + species.toString() + "/"
- + id + "?content-type=application/json";
+ StringBuilder sb = new StringBuilder();
+ sb.append(getDomain()).append("/xrefs/symbol/")
+ .append(species.toString()).append("/").append(id)
+ .append(CONTENT_TYPE_JSON);
+ for (String t : type)
+ {
+ sb.append("&object_type=").append(t);
+ }
try
{
+ String url = sb.toString();
return new URL(url);
} catch (MalformedURLException e)
{
* @param identifier
* @return
*/
- public List<String> getIds(String identifier)
+ public List<String> getGeneIds(String identifier)
{
List<String> result = new ArrayList<String>();
List<String> ids = new ArrayList<String>();
{
for (String query : queries)
{
- for (Species taxon : Species.values())
+ for (Species taxon : Species.getModelOrganisms())
{
- if (taxon.isModelOrganism())
+ URL url = getUrl(query, taxon, GENE);
+ if (url != null)
{
- URL url = getUrl(query, taxon);
- if (url != null)
- {
- br = getHttpResponse(url, ids);
- }
- String geneId = parseSymbolResponse(br);
- if (geneId != null)
+ br = getHttpResponse(url, ids);
+ if (br != null)
{
- result.add(geneId);
+ String geneId = parseSymbolResponse(br);
+ System.out.println(url + " returned " + geneId);
+ if (geneId != null && !result.contains(geneId))
+ {
+ result.add(geneId);
+ }
}
}
}
if (url != null)
{
br = getHttpResponse(url, ids);
+ if (br != null)
+ {
+ result = parseResponse(br);
+ }
}
- return (parseResponse(br));
} catch (IOException e)
{
// ignore
while (rvals.hasNext())
{
JSONObject val = (JSONObject) rvals.next();
- String dbName = val.get("dbname").toString();
- if (dbName.equals(GO_GENE_ONTOLOGY))
- {
- continue;
- }
+ String db = val.get("dbname").toString();
String id = val.get("primary_id").toString();
- if (dbName != null && id != null)
+ if (db != null && id != null
+ && !GO_GENE_ONTOLOGY.equals(db))
{
- dbName = DBRefUtils.getCanonicalName(dbName);
- DBRefEntry dbref = new DBRefEntry(dbName, getXRefVersion(), id);
+ db = DBRefUtils.getCanonicalName(db);
+ DBRefEntry dbref = new DBRefEntry(db, getXRefVersion(), id);
result.add(dbref);
}
}
protected URL getUrl(String identifier)
{
String url = getDomain() + "/xrefs/id/" + identifier
- + "?content-type=application/json&all_levels=1";
+ + CONTENT_TYPE_JSON + "&all_levels=1";
try
{
return new URL(url);
*/
package jalview.ext.ensembl;
+import java.util.HashSet;
+import java.util.Set;
+
/**
* Selected species identifiers used by Ensembl
*
chimpanzee(false), cat(false), zebrafish(true), chicken(true),
dmelanogaster(true);
+ static Set<Species> modelOrganisms = new HashSet<>();
+
+ static
+ {
+ for (Species s : values())
+ {
+ if (s.isModelOrganism())
+ {
+ modelOrganisms.add(s);
+ }
+ }
+ }
boolean modelOrganism;
private Species(boolean model)
{
return modelOrganism;
}
+
+ public static Set<Species> getModelOrganisms()
+ {
+ return modelOrganisms;
+ }
}
import jalview.datamodel.HiddenColumns;
import jalview.datamodel.PDBEntry;
import jalview.datamodel.SequenceI;
+import jalview.gui.IProgressIndicator;
import jalview.io.DataSourceType;
import jalview.io.StructureFile;
import jalview.schemes.ColourSchemeI;
*/
private boolean associateNewStructs = false;
- Vector<String> atomsPicked = new Vector<String>();
+ Vector<String> atomsPicked = new Vector<>();
private List<String> chainNames;
}
if (modelFileNames == null)
{
- List<String> mset = new ArrayList<String>();
+ List<String> mset = new ArrayList<>();
_modelFileNameMap = new int[viewer.ms.mc];
String m = viewer.ms.getModelFileName(0);
if (m != null)
@Override
public synchronized String[] getStructureFiles()
{
- List<String> mset = new ArrayList<String>();
+ List<String> mset = new ArrayList<>();
if (viewer == null)
{
return new String[0];
notifyAtomPicked(((Integer) data[2]).intValue(), (String) data[1],
(String) data[0]);
// also highlight in alignment
+ // deliberate fall through
case HOVER:
notifyAtomHovered(((Integer) data[2]).intValue(), (String) data[1],
(String) data[0]);
fileLoadingError = null;
String[] oldmodels = modelFileNames;
modelFileNames = null;
- chainNames = new ArrayList<String>();
- chainFile = new Hashtable<String, String>();
+ chainNames = new ArrayList<>();
+ chainFile = new Hashtable<>();
boolean notifyLoaded = false;
String[] modelfilenames = getStructureFiles();
// first check if we've lost any structures
// see JAL-623 - need method of matching pasted data up
{
pdb = getSsm().setMapping(getSequence()[pe], getChains()[pe],
- pdbfile, DataSourceType.PASTE);
+ pdbfile, DataSourceType.PASTE,
+ getIProgressIndicator());
getPdbEntry(modelnum).setFile("INLINE" + pdb.getId());
matches = true;
foundEntry = true;
}
// Explicitly map to the filename used by Jmol ;
pdb = getSsm().setMapping(getSequence()[pe], getChains()[pe],
- fileName, protocol);
+ fileName, protocol, getIProgressIndicator());
// pdbentry[pe].getFile(), protocol);
}
return chainNames;
}
+ protected abstract IProgressIndicator getIProgressIndicator();
+
public void notifyNewPickingModeMeasurement(int iatom, String strMeasure)
{
notifyAtomPicked(iatom, strMeasure, null);
for (String chain : modelData.keySet())
{
- chain = chain.trim();
+ chain = " ".equals(chain) ? chain : chain.trim();
List<int[]> rangeList = modelData.get(chain);
{
sb.append(start).append("-").append(end);
}
- if (chain.length() > 0)
- {
- sb.append(".").append(chain);
+
+ sb.append(".");
+ if (!" ".equals(chain)) {
+ sb.append(chain);
}
}
}
private static final String PDB_FTS_CACHE_KEY = "CACHE.PDB_FTS";
- public PDBFTSPanel(SequenceFetcher seqFetcher)
+ public PDBFTSPanel(SequenceFetcher fetcher)
{
super();
pageLimit = PDBFTSRestClient.getInstance().getDefaultResponsePageSize();
- this.seqFetcher = seqFetcher;
- this.progressIndicator = (seqFetcher == null) ? null
- : seqFetcher.getProgressIndicator();
+ this.seqFetcher = fetcher;
+ this.progressIndicator = (fetcher == null) ? null
+ : fetcher.getProgressIndicator();
}
@Override
request.setSearchTerm(searchTerm + ")");
request.setOffSet(offSet);
request.setWantedFields(wantedFields);
- FTSRestClientI pdbRestCleint = PDBFTSRestClient.getInstance();
+ FTSRestClientI pdbRestClient = PDBFTSRestClient.getInstance();
FTSRestResponse resultList;
try
{
- resultList = pdbRestCleint.executeRequest(request);
+ resultList = pdbRestClient.executeRequest(request);
} catch (Exception e)
{
setErrorMessage(e.getMessage());
checkForErrors();
+ setSearchInProgress(false);
return;
}
private static FTSRestClientI instance = null;
- public static final String PDB_SEARCH_ENDPOINT = "http://www.ebi.ac.uk/pdbe/search/pdb/select?";
+ public static final String PDB_SEARCH_ENDPOINT = "https://www.ebi.ac.uk/pdbe/search/pdb/select?";
protected PDBFTSRestClient()
{
private static String defaultFTSFrameTitle = MessageManager
.getString("label.uniprot_sequence_fetcher");
- private static Map<String, Integer> tempUserPrefs = new HashMap<String, Integer>();
+ private static Map<String, Integer> tempUserPrefs = new HashMap<>();
private static final String UNIPROT_FTS_CACHE_KEY = "CACHE.UNIPROT_FTS";
- public UniprotFTSPanel(SequenceFetcher seqFetcher)
+ public UniprotFTSPanel(SequenceFetcher fetcher)
{
super();
pageLimit = UniProtFTSRestClient.getInstance()
.getDefaultResponsePageSize();
- this.seqFetcher = seqFetcher;
- this.progressIndicator = (seqFetcher == null) ? null
- : seqFetcher.getProgressIndicator();
+ this.seqFetcher = fetcher;
+ this.progressIndicator = (fetcher == null) ? null
+ : fetcher.getProgressIndicator();
}
@Override
request.setSearchTerm(searchTerm);
request.setOffSet(offSet);
request.setWantedFields(wantedFields);
- FTSRestClientI uniProtRestCleint = UniProtFTSRestClient
+ FTSRestClientI uniProtRestClient = UniProtFTSRestClient
.getInstance();
FTSRestResponse resultList;
try
{
- resultList = uniProtRestCleint.executeRequest(request);
+ resultList = uniProtRestClient.executeRequest(request);
} catch (Exception e)
{
- e.printStackTrace();
setErrorMessage(e.getMessage());
checkForErrors();
+ setSearchInProgress(false);
return;
}
{
disableActionButtons();
StringBuilder selectedIds = new StringBuilder();
- HashSet<String> selectedIdsSet = new HashSet<String>();
+ HashSet<String> selectedIdsSet = new HashSet<>();
int primaryKeyColIndex = 0;
try
{
AlignViewport viewport;
- ViewportRanges vpRanges;
-
public AlignViewControllerI avc;
List<AlignmentPanel> alignPanels = new ArrayList<>();
progressBar = new ProgressBar(this.statusPanel, this.statusBar);
}
- vpRanges = viewport.getRanges();
avc = new jalview.controller.AlignViewController(this, viewport,
alignPanel);
if (viewport.getAlignmentConservationAnnotation() == null)
{ (viewport.cursorMode ? "on" : "off") }));
if (viewport.cursorMode)
{
- alignPanel.getSeqPanel().seqCanvas.cursorX = vpRanges
+ ViewportRanges ranges = viewport.getRanges();
+ alignPanel.getSeqPanel().seqCanvas.cursorX = ranges
.getStartRes();
- alignPanel.getSeqPanel().seqCanvas.cursorY = vpRanges
+ alignPanel.getSeqPanel().seqCanvas.cursorY = ranges
.getStartSeq();
}
alignPanel.getSeqPanel().seqCanvas.repaint();
break;
}
case KeyEvent.VK_PAGE_UP:
- vpRanges.pageUp();
+ viewport.getRanges().pageUp();
break;
case KeyEvent.VK_PAGE_DOWN:
- vpRanges.pageDown();
+ viewport.getRanges().pageDown();
break;
}
}
}
viewport.getAlignment().moveSelectedSequencesByOne(sg,
viewport.getHiddenRepSequences(), up);
- alignPanel.paintAlignment(true);
+ alignPanel.paintAlignment(true, false);
}
synchronized void slideSequences(boolean right, int size)
{
// propagate alignment changed.
- vpRanges.setEndSeq(alignment.getHeight());
+ viewport.getRanges().setEndSeq(alignment.getHeight());
if (annotationAdded)
{
// Duplicate sequence annotation in all views.
{
PaintRefresher.Refresh(this, viewport.getSequenceSetId());
alignPanel.updateAnnotation();
- alignPanel.paintAlignment(true);
+ alignPanel.paintAlignment(true, true);
}
}
// JAL-2034 - should delegate to
// alignPanel to decide if overview needs
// updating.
- alignPanel.paintAlignment(false);
+ alignPanel.paintAlignment(false, false);
PaintRefresher.Refresh(alignPanel, viewport.getSequenceSetId());
}
// JAL-2034 - should delegate to
// alignPanel to decide if overview needs
// updating.
- alignPanel.paintAlignment(false);
+ alignPanel.paintAlignment(false, false);
PaintRefresher.Refresh(alignPanel, viewport.getSequenceSetId());
viewport.sendSelection();
}
// alignPanel to decide if overview needs
// updating.
- alignPanel.paintAlignment(true);
+ alignPanel.paintAlignment(true, false);
PaintRefresher.Refresh(alignPanel, viewport.getSequenceSetId());
viewport.sendSelection();
}
public void invertColSel_actionPerformed(ActionEvent e)
{
viewport.invertColumnSelection();
- alignPanel.paintAlignment(true);
+ alignPanel.paintAlignment(true, false);
viewport.sendSelection();
}
{
trimRegion = new TrimRegionCommand("Remove Left", true, seqs,
column, viewport.getAlignment());
- vpRanges.setStartRes(0);
+ viewport.getRanges().setStartRes(0);
}
else
{
// This is to maintain viewport position on first residue
// of first sequence
SequenceI seq = viewport.getAlignment().getSequenceAt(0);
- int startRes = seq.findPosition(vpRanges.getStartRes());
+ ViewportRanges ranges = viewport.getRanges();
+ int startRes = seq.findPosition(ranges.getStartRes());
// ShiftList shifts;
// viewport.getAlignment().removeGaps(shifts=new ShiftList());
// edit.alColumnChanges=shifts.getInverse();
// if (viewport.hasHiddenColumns)
// viewport.getColumnSelection().compensateForEdits(shifts);
- vpRanges.setStartRes(seq.findIndex(startRes) - 1);
+ ranges.setStartRes(seq.findIndex(startRes) - 1);
viewport.firePropertyChange("alignment", null,
viewport.getAlignment().getSequences());
// This is to maintain viewport position on first residue
// of first sequence
SequenceI seq = viewport.getAlignment().getSequenceAt(0);
- int startRes = seq.findPosition(vpRanges.getStartRes());
+ int startRes = seq.findPosition(viewport.getRanges().getStartRes());
addHistoryItem(new RemoveGapsCommand("Remove Gaps", seqs, start, end,
viewport.getAlignment()));
- vpRanges.setStartRes(seq.findIndex(startRes) - 1);
+ viewport.getRanges().setStartRes(seq.findIndex(startRes) - 1);
viewport.firePropertyChange("alignment", null,
viewport.getAlignment().getSequences());
/*
* Create a new AlignmentPanel (with its own, new Viewport)
*/
- AlignmentPanel newap = new Jalview2XML().copyAlignPanel(alignPanel,
- true);
+ AlignmentPanel newap = new Jalview2XML().copyAlignPanel(alignPanel);
if (!copyAnnotation)
{
/*
alignPanel.getIdPanel().getIdCanvas()
.setPreferredSize(alignPanel.calculateIdWidth());
- alignPanel.paintAlignment(true);
+ alignPanel.paintAlignment(true, false);
}
@Override
public void idRightAlign_actionPerformed(ActionEvent e)
{
viewport.setRightAlignIds(idRightAlign.isSelected());
- alignPanel.paintAlignment(true);
+ alignPanel.paintAlignment(false, false);
}
@Override
public void centreColumnLabels_actionPerformed(ActionEvent e)
{
viewport.setCentreColumnLabels(centreColumnLabelsMenuItem.getState());
- alignPanel.paintAlignment(true);
+ alignPanel.paintAlignment(false, false);
}
/*
protected void colourTextMenuItem_actionPerformed(ActionEvent e)
{
viewport.setColourText(colourTextMenuItem.isSelected());
- alignPanel.paintAlignment(true);
+ alignPanel.paintAlignment(false, false);
}
/**
public void showAllColumns_actionPerformed(ActionEvent e)
{
viewport.showAllHiddenColumns();
- alignPanel.paintAlignment(true);
+ alignPanel.paintAlignment(true, true);
viewport.sendSelection();
}
viewport.expandColSelection(sg, false);
viewport.hideAllSelectedSeqs();
viewport.hideSelectedColumns();
- alignPanel.paintAlignment(true);
+ alignPanel.paintAlignment(true, true);
viewport.sendSelection();
}
{
viewport.showAllHiddenColumns();
viewport.showAllHiddenSeqs();
- alignPanel.paintAlignment(true);
+ alignPanel.paintAlignment(true, true);
viewport.sendSelection();
}
public void hideSelColumns_actionPerformed(ActionEvent e)
{
viewport.hideSelectedColumns();
- alignPanel.paintAlignment(true);
+ alignPanel.paintAlignment(true, true);
viewport.sendSelection();
}
protected void scaleAbove_actionPerformed(ActionEvent e)
{
viewport.setScaleAboveWrapped(scaleAbove.isSelected());
- alignPanel.paintAlignment(true);
+ // TODO: do we actually need to update overview for scale above change ?
+ alignPanel.paintAlignment(true, false);
}
/**
protected void scaleLeft_actionPerformed(ActionEvent e)
{
viewport.setScaleLeftWrapped(scaleLeft.isSelected());
- alignPanel.paintAlignment(true);
+ alignPanel.paintAlignment(true, false);
}
/**
protected void scaleRight_actionPerformed(ActionEvent e)
{
viewport.setScaleRightWrapped(scaleRight.isSelected());
- alignPanel.paintAlignment(true);
+ alignPanel.paintAlignment(true, false);
}
/**
public void viewBoxesMenuItem_actionPerformed(ActionEvent e)
{
viewport.setShowBoxes(viewBoxesMenuItem.isSelected());
- alignPanel.paintAlignment(true);
+ alignPanel.paintAlignment(false, false);
}
/**
public void viewTextMenuItem_actionPerformed(ActionEvent e)
{
viewport.setShowText(viewTextMenuItem.isSelected());
- alignPanel.paintAlignment(true);
+ alignPanel.paintAlignment(false, false);
}
/**
protected void renderGapsMenuItem_actionPerformed(ActionEvent e)
{
viewport.setRenderGaps(renderGapsMenuItem.isSelected());
- alignPanel.paintAlignment(true);
+ alignPanel.paintAlignment(false, false);
}
public FeatureSettings featureSettings;
public void showSeqFeatures_actionPerformed(ActionEvent evt)
{
viewport.setShowSequenceFeatures(showSeqFeatures.isSelected());
- alignPanel.paintAlignment(true);
+ alignPanel.paintAlignment(true, true);
}
/**
viewport.setGlobalColourScheme(cs);
- alignPanel.paintAlignment(true);
+ alignPanel.paintAlignment(true, true);
}
/**
viewport.getAlignment().getSequenceAt(0));
addHistoryItem(new OrderCommand("Pairwise Sort", oldOrder,
viewport.getAlignment()));
- alignPanel.paintAlignment(true);
+ alignPanel.paintAlignment(true, false);
}
/**
AlignmentSorter.sortByID(viewport.getAlignment());
addHistoryItem(
new OrderCommand("ID Sort", oldOrder, viewport.getAlignment()));
- alignPanel.paintAlignment(true);
+ alignPanel.paintAlignment(true, false);
}
/**
AlignmentSorter.sortByLength(viewport.getAlignment());
addHistoryItem(new OrderCommand("Length Sort", oldOrder,
viewport.getAlignment()));
- alignPanel.paintAlignment(true);
+ alignPanel.paintAlignment(true, false);
}
/**
addHistoryItem(new OrderCommand("Group Sort", oldOrder,
viewport.getAlignment()));
- alignPanel.paintAlignment(true);
+ alignPanel.paintAlignment(true, false);
}
/**
addHistoryItem(new OrderCommand(order.getName(), oldOrder,
viewport.getAlignment()));
- alignPanel.paintAlignment(true);
+ alignPanel.paintAlignment(true, false);
}
});
}
viewport.getAlignment());// ,viewport.getSelectionGroup());
addHistoryItem(new OrderCommand("Sort by " + scoreLabel, oldOrder,
viewport.getAlignment()));
- alignPanel.paintAlignment(true);
+ alignPanel.paintAlignment(true, false);
}
});
}
addHistoryItem(new OrderCommand(undoname, oldOrder,
viewport.getAlignment()));
}
- alignPanel.paintAlignment(true);
+ alignPanel.paintAlignment(true, false);
return true;
}
assocfiles++;
}
}
- alignPanel.paintAlignment(true);
+ // TODO: do we need to update overview ? only if features are
+ // shown I guess
+ alignPanel.paintAlignment(true, false);
}
}
}
{
if (parseFeaturesFile(file, sourceType))
{
- alignPanel.paintAlignment(true);
+ alignPanel.paintAlignment(true, true);
}
}
else
alignPanel.adjustAnnotationHeight();
viewport.updateSequenceIdColours();
buildSortByAnnotationScoresMenu();
- alignPanel.paintAlignment(true);
+ alignPanel.paintAlignment(true, true);
}
} catch (Exception ex)
{
protected void showUnconservedMenuItem_actionPerformed(ActionEvent e)
{
viewport.setShowUnconserved(showNonconservedMenuItem.getState());
- alignPanel.paintAlignment(true);
+ alignPanel.paintAlignment(false, false);
}
/*
{
PaintRefresher.Refresh(this, viewport.getSequenceSetId());
alignPanel.updateAnnotation();
- alignPanel.paintAlignment(true);
+ alignPanel.paintAlignment(true, true);
}
}
viewport.getAlignment().setSeqrep(null);
PaintRefresher.Refresh(this, viewport.getSequenceSetId());
alignPanel.updateAnnotation();
- alignPanel.paintAlignment(true);
+ alignPanel.paintAlignment(true, true);
}
}
this.alignPanel.av.setSortAnnotationsBy(getAnnotationSortOrder());
this.alignPanel.av
.setShowAutocalculatedAbove(isShowAutoCalculatedAbove());
- alignPanel.paintAlignment(true);
+ alignPanel.paintAlignment(false, false);
}
/**
{
Font font;
- TreeModel currentTree = null;
-
boolean cursorMode = false;
boolean antiAlias = false;
}
/**
- * DOCUMENT ME!
- *
- * @param tree
- * DOCUMENT ME!
- */
- public void setCurrentTree(TreeModel tree)
- {
- currentTree = tree;
- }
-
- /**
- * DOCUMENT ME!
- *
- * @return DOCUMENT ME!
- */
- public TreeModel getCurrentTree()
- {
- return currentTree;
- }
-
- /**
* returns the visible column regions of the alignment
*
* @param selectedRegionOnly
}
fr.setTransparency(featureSettings.getTransparency());
}
-
}
{
public AlignViewport av;
- ViewportRanges vpRanges;
-
OverviewPanel overviewPanel;
private SeqPanel seqPanel;
private AnnotationLabels alabels;
- // this value is set false when selection area being dragged
- boolean fastPaint = true;
-
private int hextent = 0;
private int vextent = 0;
{
alignFrame = af;
this.av = av;
- vpRanges = av.getRanges();
setSeqPanel(new SeqPanel(av, this));
setIdPanel(new IdPanel(av, this));
// reset the viewport ranges when the alignment panel is resized
// in particular, this initialises the end residue value when Jalview
// is initialised
+ ViewportRanges ranges = av.getRanges();
if (av.getWrapAlignment())
{
int widthInRes = getSeqPanel().seqCanvas.getWrappedCanvasWidth(
getSeqPanel().seqCanvas.getWidth());
- vpRanges.setViewportWidth(widthInRes);
+ ranges.setViewportWidth(widthInRes);
}
else
{
int heightInSeq = getSeqPanel().seqCanvas.getHeight()
/ av.getCharHeight();
- vpRanges.setViewportWidth(widthInRes);
- vpRanges.setViewportHeight(heightInSeq);
+ ranges.setViewportWidth(widthInRes);
+ ranges.setViewportHeight(heightInSeq);
}
}
alignFrame.updateEditMenuBar();
- paintAlignment(true);
+ // no idea if we need to update structure
+ paintAlignment(true, true);
}
getIdPanel().getIdCanvas().setPreferredSize(d);
hscrollFillerPanel.setPreferredSize(d);
- if (this.alignFrame.getSplitViewContainer() != null)
- {
- ((SplitFrame) this.alignFrame.getSplitViewContainer()).adjustLayout();
- }
-
repaint();
}
int verticalOffset, boolean redrawOverview, boolean centre)
{
int startv, endv, starts, ends;
+ ViewportRanges ranges = av.getRanges();
if (results == null || results.isEmpty() || av == null
|| av.getAlignment() == null)
*/
if (centre)
{
- int offset = (vpRanges.getEndRes() - vpRanges.getStartRes() + 1) / 2 - 1;
+ int offset = (ranges.getEndRes() - ranges.getStartRes() + 1) / 2 - 1;
start = Math.max(start - offset, 0);
end = end + offset - 1;
}
if (!av.getWrapAlignment())
{
- if ((startv = vpRanges.getStartRes()) >= start)
+ if ((startv = ranges.getStartRes()) >= start)
{
/*
* Scroll left to make start of search results visible
*/
setScrollValues(start, seqIndex);
}
- else if ((endv = vpRanges.getEndRes()) <= end)
+ else if ((endv = ranges.getEndRes()) <= end)
{
/*
* Scroll right to make end of search results visible
*/
setScrollValues(startv + end - endv, seqIndex);
}
- else if ((starts = vpRanges.getStartSeq()) > seqIndex)
+ else if ((starts = ranges.getStartSeq()) > seqIndex)
{
/*
* Scroll up to make start of search results visible
*/
- setScrollValues(vpRanges.getStartRes(), seqIndex);
+ setScrollValues(ranges.getStartRes(), seqIndex);
}
- else if ((ends = vpRanges.getEndSeq()) <= seqIndex)
+ else if ((ends = ranges.getEndSeq()) <= seqIndex)
{
/*
* Scroll down to make end of search results visible
*/
- setScrollValues(vpRanges.getStartRes(), starts + seqIndex - ends
+ setScrollValues(ranges.getStartRes(), starts + seqIndex - ends
+ 1);
}
/*
}
else
{
- scrollNeeded = vpRanges.scrollToWrappedVisible(start);
+ scrollNeeded = ranges.scrollToWrappedVisible(start);
}
- paintAlignment(redrawOverview);
+ paintAlignment(redrawOverview, false);
return scrollNeeded;
}
}
validateAnnotationDimensions(true);
addNotify();
- paintAlignment(true);
+ // TODO: many places call this method and also paintAlignment with various
+ // different settings. this means multiple redraws are triggered...
+ paintAlignment(true, false);
}
/**
fontChanged();
setAnnotationVisible(av.isShowAnnotation());
boolean wrap = av.getWrapAlignment();
- vpRanges.setStartSeq(0);
+ ViewportRanges ranges = av.getRanges();
+ ranges.setStartSeq(0);
scalePanelHolder.setVisible(!wrap);
hscroll.setVisible(!wrap);
idwidthAdjuster.setVisible(!wrap);
{
int widthInRes = getSeqPanel().seqCanvas
.getWrappedCanvasWidth(canvasWidth);
- vpRanges.setViewportWidth(widthInRes);
+ ranges.setViewportWidth(widthInRes);
}
else
{
- int widthInRes = (canvasWidth / av.getCharWidth()) - 1;
+ int widthInRes = (canvasWidth / av.getCharWidth());
int heightInSeq = (getSeqPanel().seqCanvas.getHeight()
- / av.getCharHeight()) - 1;
+ / av.getCharHeight());
- vpRanges.setViewportWidth(widthInRes);
- vpRanges.setViewportHeight(heightInSeq);
+ ranges.setViewportWidth(widthInRes);
+ ranges.setViewportHeight(heightInSeq);
}
}
return;
}
+ ViewportRanges ranges = av.getRanges();
+
if (evt.getSource() == hscroll)
{
- int oldX = vpRanges.getStartRes();
- int oldwidth = vpRanges.getViewportWidth();
+ int oldX = ranges.getStartRes();
+ int oldwidth = ranges.getViewportWidth();
int x = hscroll.getValue();
int width = getSeqPanel().seqCanvas.getWidth() / av.getCharWidth();
{
return;
}
- vpRanges.setViewportStartAndWidth(x, width);
+ ranges.setViewportStartAndWidth(x, width);
}
else if (evt.getSource() == vscroll)
{
- int oldY = vpRanges.getStartSeq();
- int oldheight = vpRanges.getViewportHeight();
+ int oldY = ranges.getStartSeq();
+ int oldheight = ranges.getViewportHeight();
int y = vscroll.getValue();
int height = getSeqPanel().seqCanvas.getHeight() / av.getCharHeight();
{
return;
}
- vpRanges.setViewportStartAndHeight(y, height);
- }
- if (!fastPaint)
- {
- repaint();
+ ranges.setViewportStartAndHeight(y, height);
}
+ repaint();
}
/**
{
return; // no horizontal scroll when wrapped
}
+ final ViewportRanges ranges = av.getRanges();
+
if (evt.getSource() == vscroll)
{
int newY = vscroll.getValue();
* this prevents infinite recursion of events when the scroll/viewport
* ranges values are the same
*/
- int oldX = vpRanges.getStartRes();
- int oldY = vpRanges.getWrappedScrollPosition(oldX);
+ int oldX = ranges.getStartRes();
+ int oldY = ranges.getWrappedScrollPosition(oldX);
if (oldY == newY)
{
return;
/*
* limit page up/down to one width's worth of positions
*/
- int rowSize = vpRanges.getViewportWidth();
+ int rowSize = ranges.getViewportWidth();
int newX = newY > oldY ? oldX + rowSize : oldX - rowSize;
- vpRanges.setViewportStartAndWidth(Math.max(0, newX), rowSize);
+ ranges.setViewportStartAndWidth(Math.max(0, newX), rowSize);
}
}
else
"Unexpected path through code: Wrapped jar file opened with wrap alignment set in preferences");
// scroll to start of panel
- vpRanges.setStartRes(0);
- vpRanges.setStartSeq(0);
+ ranges.setStartRes(0);
+ ranges.setStartSeq(0);
}
});
}
repaint();
}
- /**
- * Repaint the alignment including the annotations and overview panels (if
- * shown).
+ /* (non-Javadoc)
+ * @see jalview.api.AlignmentViewPanel#paintAlignment(boolean)
*/
@Override
- public void paintAlignment(boolean updateOverview)
+ public void paintAlignment(boolean updateOverview,
+ boolean updateStructures)
{
final AnnotationSorter sorter = new AnnotationSorter(getAlignment(),
av.isShowAutocalculatedAbove());
av.getSortAnnotationsBy());
repaint();
- if (updateOverview)
+ if (updateStructures)
{
- // TODO: determine if this paintAlignment changed structure colours
av.getStructureSelectionManager().sequenceColoursChanged(this);
+ }
+ if (updateOverview)
+ {
if (overviewPanel != null)
{
/*
* set scroll bar positions
*/
- setScrollValues(vpRanges.getStartRes(), vpRanges.getStartSeq());
+ ViewportRanges ranges = av.getRanges();
+ setScrollValues(ranges.getStartRes(), ranges.getStartSeq());
}
/**
*/
private void setScrollingForWrappedPanel(int topLeftColumn)
{
- int scrollPosition = vpRanges.getWrappedScrollPosition(topLeftColumn);
- int maxScroll = vpRanges.getWrappedMaxScroll(topLeftColumn);
+ ViewportRanges ranges = av.getRanges();
+ int scrollPosition = ranges.getWrappedScrollPosition(topLeftColumn);
+ int maxScroll = ranges.getWrappedMaxScroll(topLeftColumn);
/*
* a scrollbar's value can be set to at most (maximum-extent)
if (annotationPanel != null)
{
annotationPanel.dispose();
+ annotationPanel = null;
}
if (av != null)
{
av.removePropertyChangeListener(propertyChangeListener);
- jalview.structure.StructureSelectionManager ssm = av
- .getStructureSelectionManager();
+ propertyChangeListener = null;
+ StructureSelectionManager ssm = av.getStructureSelectionManager();
ssm.removeStructureViewerListener(getSeqPanel(), null);
ssm.removeSelectionListener(getSeqPanel());
ssm.removeCommandListener(av);
*/
protected void closeChildFrames()
{
+ if (overviewPanel != null)
+ {
+ overviewPanel.dispose();
+ overviewPanel = null;
+ }
if (calculationDialog != null)
{
calculationDialog.closeFrame();
+ calculationDialog = null;
}
}
if (adjustHeight)
{
// sort, repaint, update overview
- paintAlignment(true);
+ paintAlignment(true, false);
}
else
{
public void propertyChange(PropertyChangeEvent evt)
{
// update this panel's scroll values based on the new viewport ranges values
- int x = vpRanges.getStartRes();
- int y = vpRanges.getStartSeq();
+ ViewportRanges ranges = av.getRanges();
+ int x = ranges.getStartRes();
+ int y = ranges.getStartSeq();
setScrollValues(x, y);
// now update any complementary alignment (its viewport ranges object
private boolean applyToUnselectedSequences;
// currently selected 'annotation type' checkboxes
- private Map<String, String> selectedTypes = new HashMap<String, String>();
+ private Map<String, String> selectedTypes = new HashMap<>();
/**
* Constructor.
// this.ap.alabels.setSize(this.ap.alabels.getSize().width,
// this.ap.annotationPanel.getSize().height);
// this.ap.validate();
- this.ap.paintAlignment(true);
+ this.ap.paintAlignment(true, false);
}
/**
// this.ap.alabels.setSize(this.ap.alabels.getSize().width,
// this.ap.annotationPanel.getSize().height);
// this.ap.validate();
- this.ap.paintAlignment(true);
+ this.ap.paintAlignment(true, false);
}
/**
this.ap.updateAnnotation();
// this.ap.annotationPanel.adjustPanelHeight();
- this.ap.paintAlignment(true);
+ this.ap.paintAlignment(true, false);
}
/**
public static List<String> getAnnotationTypes(AlignmentI alignment,
boolean sequenceSpecificOnly)
{
- List<String> result = new ArrayList<String>();
+ List<String> result = new ArrayList<>();
for (AlignmentAnnotation aa : alignment.getAlignmentAnnotation())
{
if (!sequenceSpecificOnly || aa.sequenceRef != null)
oldcs = av.getGlobalColourScheme();
if (av.getAlignment().getGroups() != null)
{
- oldgroupColours = new Hashtable<SequenceGroup, ColourSchemeI>();
+ oldgroupColours = new Hashtable<>();
for (SequenceGroup sg : ap.av.getAlignment().getGroups())
{
if (sg.getColourScheme() != null)
}
Vector<String> annotItems = getAnnotationItems(
seqAssociated.isSelected());
- annotations = new JComboBox<String>(annotItems);
+ annotations = new JComboBox<>(annotItems);
populateThresholdComboBox(threshold);
getCurrentAnnotation().threshold.value = slider.getValue() / 1000f;
propagateSeqAssociatedThreshold(updateAllAnnotation,
getCurrentAnnotation());
- ap.paintAlignment(false);
+ ap.paintAlignment(false, false);
}
}
colorAlignmentContaining(getCurrentAnnotation(), selectedThresholdItem);
ap.alignmentChanged();
- // ensure all associated views (overviews, structures, etc) are notified of
- // updated colours.
- ap.paintAlignment(true);
}
- protected boolean colorAlignmentContaining(AlignmentAnnotation currentAnn,
+ protected void colorAlignmentContaining(AlignmentAnnotation currentAnn,
int selectedThresholdOption)
{
acg.getInstance(sg, ap.av.getHiddenRepSequences()));
}
}
- return false;
}
}
av.getAlignment().setHiddenColumns(oldHidden);
}
av.sendSelection();
- ap.paintAlignment(true);
+ ap.paintAlignment(true, true);
}
}
updateView();
propagateSeqAssociatedThreshold(updateAllAnnotation,
getCurrentAnnotation());
- ap.paintAlignment(false);
+ ap.paintAlignment(false, false);
}
}
av.getColumnSelection().filterAnnotations(
getCurrentAnnotation().annotations, filterParams);
- if (getActionOption() == ACTION_OPTION_HIDE)
+ boolean hideCols = getActionOption() == ACTION_OPTION_HIDE;
+ if (hideCols)
{
av.hideSelectedColumns();
}
filterParams = null;
av.setAnnotationColumnSelectionState(this);
- ap.paintAlignment(true);
+ // only update overview and structures if columns were hidden
+ ap.paintAlignment(hideCols, hideCols);
}
public HiddenColumns getOldHiddenColumns()
d = ap.annotationSpaceFillerHolder.getPreferredSize();
ap.annotationSpaceFillerHolder
.setPreferredSize(new Dimension(d.width, d.height - dif));
- ap.paintAlignment(true);
+ ap.paintAlignment(true, false);
}
ap.addNotify();
}
}
- ap.paintAlignment(false);
+ ap.paintAlignment(false, false);
PaintRefresher.Refresh(ap, ap.av.getSequenceSetId());
ap.av.sendSelection();
}
sg.addSequence(aa[selectedRow].sequenceRef, false);
}
ap.av.setSelectionGroup(sg);
- ap.paintAlignment(false);
+ ap.paintAlignment(false, false);
PaintRefresher.Refresh(ap, ap.av.getSequenceSetId());
ap.av.sendSelection();
}
}
graphStretchY = evt.getY();
adjustPanelHeight();
- ap.paintAlignment(true);
+ ap.paintAlignment(false, false);
}
else
{
*/
protected boolean sliderDragging = false;
- protected JComboBox<String> threshold = new JComboBox<String>();
+ protected JComboBox<String> threshold = new JComboBox<>();
protected JComboBox<String> annotations;
sliderDragging = false;
valueChanged(true);
}
- ap.paintAlignment(true);
}
});
}
*/
public Vector<String> getAnnotationItems(boolean isSeqAssociated)
{
- annotationLabels = new HashMap<AlignmentAnnotation, String>();
+ annotationLabels = new HashMap<>();
- Vector<String> list = new Vector<String>();
+ Vector<String> list = new Vector<>();
int index = 1;
int[] anmap = new int[av.getAlignment()
.getAlignmentAnnotation().length];
public void cancel_actionPerformed()
{
reset();
- ap.paintAlignment(true);
+ ap.paintAlignment(true, true);
try
{
frame.setClosed(true);
this.currentAnnotation = annotation;
}
+ /**
+ * update associated view model and trigger any necessary repaints.
+ *
+ * @param updateAllAnnotation
+ */
protected abstract void valueChanged(boolean updateAllAnnotation);
protected abstract void updateView();
IProgressIndicator progressBar = null;
+ @Override
+ protected IProgressIndicator getIProgressIndicator()
+ {
+ return progressBar;
+ }
/**
* add a single PDB structure to a new or existing Jmol view
*
@Override
protected List<StructureViewerBase> getViewersFor(AlignmentPanel apanel)
{
- List<StructureViewerBase> result = new ArrayList<StructureViewerBase>();
+ List<StructureViewerBase> result = new ArrayList<>();
JInternalFrame[] frames = Desktop.instance.getAllFrames();
for (JInternalFrame frame : frames)
@Override
void showSelectedChains()
{
- Vector<String> toshow = new Vector<String>();
+ Vector<String> toshow = new Vector<>();
for (int i = 0; i < chainMenu.getItemCount(); i++)
{
if (chainMenu.getItem(i) instanceof JCheckBoxMenuItem)
// todo - record which pdbids were successfully imported.
StringBuilder errormsgs = new StringBuilder();
- List<String> files = new ArrayList<String>();
+ List<String> files = new ArrayList<>();
String pdbid = "";
try
{
}
@Override
+ protected IProgressIndicator getIProgressIndicator()
+ {
+ return appJmolWindow.progressBar;
+ }
+
+ @Override
public SequenceRenderer getSequenceRenderer(AlignmentViewPanel alignment)
{
return new SequenceRenderer(((AlignmentPanel) alignment).av);
--- /dev/null
+/*
+ * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jalview.gui;
+
+import java.awt.Container;
+import java.beans.PropertyVetoException;
+import java.util.Vector;
+
+import javax.swing.DefaultDesktopManager;
+import javax.swing.DesktopManager;
+import javax.swing.JInternalFrame;
+
+/**
+ * Based on AquaInternalFrameManager
+ *
+ * DesktopManager implementation for Aqua
+ *
+ * Mac is more like Windows than it's like Motif/Basic
+ *
+ * From WindowsDesktopManager:
+ *
+ * This class implements a DesktopManager which more closely follows the MDI
+ * model than the DefaultDesktopManager. Unlike the DefaultDesktopManager
+ * policy, MDI requires that the selected and activated child frames are the
+ * same, and that that frame always be the top-most window.
+ * <p>
+ * The maximized state is managed by the DesktopManager with MDI, instead of
+ * just being a property of the individual child frame. This means that if the
+ * currently selected window is maximized and another window is selected, that
+ * new window will be maximized.
+ *
+ * Downloaded from
+ * https://raw.githubusercontent.com/frohoff/jdk8u-jdk/master/src/macosx/classes/com/apple/laf/AquaInternalFrameManager.java
+ *
+ * Patch from Jim Procter - when the most recently opened frame is closed,
+ * correct behaviour is to go to the next most recent frame, rather than wrap
+ * around to the bottom of the window stack (as the original implementation
+ * does)
+ *
+ * @see com.sun.java.swing.plaf.windows.WindowsDesktopManager
+ */
+public class AquaInternalFrameManager extends DefaultDesktopManager
+{
+ // Variables
+
+ /* The frame which is currently selected/activated.
+ * We store this value to enforce Mac's single-selection model.
+ */
+ JInternalFrame fCurrentFrame;
+
+ JInternalFrame fInitialFrame;
+
+ /* The list of frames, sorted by order of creation.
+ * This list is necessary because by default the order of
+ * child frames in the JDesktopPane changes during frame
+ * activation (the activated frame is moved to index 0).
+ * We preserve the creation order so that "next" and "previous"
+ * frame actions make sense.
+ */
+ Vector<JInternalFrame> fChildFrames = new Vector<>(1);
+
+ /**
+ * keep a reference to the original LAF manager so we can iconise/de-iconise
+ * correctly
+ */
+ private DesktopManager ourManager;
+
+ public AquaInternalFrameManager(DesktopManager desktopManager)
+ {
+ ourManager = desktopManager;
+ }
+
+ @Override
+ public void closeFrame(final JInternalFrame f)
+ {
+ if (f == fCurrentFrame)
+ {
+ boolean mostRecentFrame = fChildFrames
+ .indexOf(f) == fChildFrames.size() - 1;
+ if (!mostRecentFrame)
+ {
+ activateNextFrame();
+ }
+ else
+ {
+ activatePreviousFrame();
+ }
+ }
+ fChildFrames.removeElement(f);
+ super.closeFrame(f);
+ }
+
+ @Override
+ public void deiconifyFrame(final JInternalFrame f)
+ {
+ JInternalFrame.JDesktopIcon desktopIcon;
+
+ desktopIcon = f.getDesktopIcon();
+ // If the icon moved, move the frame to that spot before expanding it
+ // reshape does delta checks for us
+ f.reshape(desktopIcon.getX(), desktopIcon.getY(), f.getWidth(),
+ f.getHeight());
+ ourManager.deiconifyFrame(f);
+ }
+
+ void addIcon(final Container c,
+ final JInternalFrame.JDesktopIcon desktopIcon)
+ {
+ c.add(desktopIcon);
+ }
+
+ /**
+ * Removes the frame from its parent and adds its desktopIcon to the parent.
+ */
+ @Override
+ public void iconifyFrame(final JInternalFrame f)
+ {
+ ourManager.iconifyFrame(f);
+ }
+
+ // WindowsDesktopManager code
+ @Override
+ public void activateFrame(final JInternalFrame f)
+ {
+ try
+ {
+ if (f != null)
+ {
+ super.activateFrame(f);
+ }
+
+ // If this is the first activation, add to child list.
+ if (fChildFrames.indexOf(f) == -1)
+ {
+ fChildFrames.addElement(f);
+ }
+
+ if (fCurrentFrame != null && f != fCurrentFrame)
+ {
+ if (fCurrentFrame.isSelected())
+ {
+ fCurrentFrame.setSelected(false);
+ }
+ }
+
+ if (f != null && !f.isSelected())
+ {
+ f.setSelected(true);
+ }
+
+ fCurrentFrame = f;
+ } catch (final PropertyVetoException e)
+ {
+ }
+ }
+
+ private void switchFrame(final boolean next)
+ {
+ if (fCurrentFrame == null)
+ {
+ // initialize first frame we find
+ if (fInitialFrame != null)
+ {
+ activateFrame(fInitialFrame);
+ }
+ return;
+ }
+
+ final int count = fChildFrames.size();
+ if (count <= 1)
+ {
+ // No other child frames.
+ return;
+ }
+
+ final int currentIndex = fChildFrames.indexOf(fCurrentFrame);
+ if (currentIndex == -1)
+ {
+ // the "current frame" is no longer in the list
+ fCurrentFrame = null;
+ return;
+ }
+
+ int nextIndex;
+ if (next)
+ {
+ nextIndex = currentIndex + 1;
+ if (nextIndex == count)
+ {
+ nextIndex = 0;
+ }
+ }
+ else
+ {
+ nextIndex = currentIndex - 1;
+ if (nextIndex == -1)
+ {
+ nextIndex = count - 1;
+ }
+ }
+ final JInternalFrame f = fChildFrames.elementAt(nextIndex);
+ activateFrame(f);
+ fCurrentFrame = f;
+ }
+
+ /**
+ * Activate the next child JInternalFrame, as determined by the frames'
+ * Z-order. If there is only one child frame, it remains activated. If there
+ * are no child frames, nothing happens.
+ */
+ public void activateNextFrame()
+ {
+ switchFrame(true);
+ }
+
+ /**
+ * same as above but will activate a frame if none have been selected
+ */
+ public void activateNextFrame(final JInternalFrame f)
+ {
+ fInitialFrame = f;
+ switchFrame(true);
+ }
+
+ /**
+ * Activate the previous child JInternalFrame, as determined by the frames'
+ * Z-order. If there is only one child frame, it remains activated. If there
+ * are no child frames, nothing happens.
+ */
+ public void activatePreviousFrame()
+ {
+ switchFrame(false);
+ }
+}
\ No newline at end of file
List<String> tips = new ArrayList<String>();
+ /*
+ * the most recently opened PCA results panel
+ */
+ private PCAPanel pcaPanel;
+
/**
* Constructor
*
JvOptionPane.WARNING_MESSAGE);
return;
}
- new PCAPanel(af.alignPanel, modelName, params);
+ pcaPanel = new PCAPanel(af.alignPanel, modelName, params);
}
/**
{
}
}
+
+ public PCAPanel getPcaPanel()
+ {
+ return pcaPanel;
+ }
}
@Override
protected List<StructureViewerBase> getViewersFor(AlignmentPanel ap)
{
- List<StructureViewerBase> result = new ArrayList<StructureViewerBase>();
+ List<StructureViewerBase> result = new ArrayList<>();
JInternalFrame[] frames = Desktop.instance.getAllFrames();
for (JInternalFrame frame : frames)
@Override
void showSelectedChains()
{
- List<String> toshow = new ArrayList<String>();
+ List<String> toshow = new ArrayList<>();
for (int i = 0; i < chainMenu.getItemCount(); i++)
{
if (chainMenu.getItem(i) instanceof JCheckBoxMenuItem)
// todo - record which pdbids were successfully imported.
StringBuilder errormsgs = new StringBuilder(128);
StringBuilder files = new StringBuilder(128);
- List<PDBEntry> filePDB = new ArrayList<PDBEntry>();
- List<Integer> filePDBpos = new ArrayList<Integer>();
+ List<PDBEntry> filePDB = new ArrayList<>();
+ List<Integer> filePDBpos = new ArrayList<>();
PDBEntry thePdbEntry = null;
StructureFile pdb = null;
try
stopProgressBar("", startTime);
}
// Explicitly map to the filename used by Chimera ;
+
pdb = jmb.getSsm().setMapping(jmb.getSequence()[pos],
- jmb.getChains()[pos], pe.getFile(), protocol);
+ jmb.getChains()[pos], pe.getFile(), protocol,
+ progressBar);
stashFoundChains(pdb, pe.getFile());
+
} catch (OutOfMemoryError oomerror)
{
new OOMWarning(
/**
* Fetch PDB data and save to a local file. Returns the full path to the file,
- * or null if fetch fails.
+ * or null if fetch fails. TODO: refactor to common with Jmol ? duplication
*
* @param processingEntry
* @return
}
return reply;
}
+
+ @Override
+ protected IProgressIndicator getIProgressIndicator()
+ {
+ return progressBar;
+ }
}
String linkedTitle = MessageManager
.getString("label.linked_view_title");
Desktop.addInternalFrame(sf, linkedTitle, -1, -1);
- sf.adjustDivider();
+ sf.adjustInitialLayout();
// finally add the top, then bottom frame to the view list
xrefViews.add(dna ? copyThis.alignPanel : newFrame.alignPanel);
import java.awt.dnd.DropTargetListener;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
-import java.awt.event.FocusEvent;
-import java.awt.event.FocusListener;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
public void endDraggingFrame(JComponent f)
{
delegate.endDraggingFrame(f);
+ desktop.repaint();
}
@Override
public void endResizingFrame(JComponent f)
{
delegate.endResizingFrame(f);
+ desktop.repaint();
}
@Override
boolean showjconsole = jalview.bin.Cache.getDefault("SHOW_JAVA_CONSOLE",
false);
desktop = new MyDesktopPane(selmemusage);
- if (Platform.isAMac())
- {
- desktop.setDoubleBuffered(false);
- }
showMemusage.setSelected(selmemusage);
desktop.setBackground(Color.white);
getContentPane().setLayout(new BorderLayout());
// This line prevents Windows Look&Feel resizing all new windows to maximum
// if previous window was maximised
desktop.setDesktopManager(
- new MyDesktopManager(new DefaultDesktopManager()));
+ new MyDesktopManager(
+ (Platform.isWindows() ? new DefaultDesktopManager()
+ : Platform.isAMac()
+ ? new AquaInternalFrameManager(
+ desktop.getDesktopManager())
+ : desktop.getDesktopManager())));
Rectangle dims = getLastKnownDimensions("");
if (dims != null)
});
desktop.addMouseListener(ma);
- this.addFocusListener(new FocusListener()
- {
-
- @Override
- public void focusLost(FocusEvent e)
- {
- // TODO Auto-generated method stub
-
- }
-
- @Override
- public void focusGained(FocusEvent e)
- {
- Cache.log.debug("Relaying windows after focus gain");
- // make sure that we sort windows properly after we gain focus
- instance.relayerWindows();
- }
- });
this.setDropTarget(new java.awt.dnd.DropTarget(desktop, this));
// Spawn a thread that shows the splashscreen
SwingUtilities.invokeLater(new Runnable()
frame.setResizable(resizable);
frame.setMaximizable(resizable);
frame.setIconifiable(resizable);
- if (Platform.isAMac())
- {
- frame.setIconifiable(false);
- frame.setFrameIcon(null);
- // frame.setDesktopIcon(null);
- frame.setDoubleBuffered(false);
- }
+
if (frame.getX() < 1 && frame.getY() < 1)
{
frame.setLocation(xOffset * openFrameCount,
JInternalFrame itf = desktop.getSelectedFrame();
if (itf != null)
{
+ if (itf instanceof AlignFrame)
+ {
+ Jalview.setCurrentAlignFrame((AlignFrame) itf);
+ }
itf.requestFocus();
}
}
menuItem.removeActionListener(menuItem.getActionListeners()[0]);
}
windowMenu.remove(menuItem);
- JInternalFrame itf = desktop.getSelectedFrame();
- if (itf != null)
- {
- itf.requestFocus();
- if (itf instanceof AlignFrame)
- {
- Jalview.setCurrentAlignFrame((AlignFrame) itf);
- }
- }
+
System.gc();
};
});
// Java's Transferable for native dnd
evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
Transferable t = evt.getTransferable();
- List<String> files = new ArrayList<String>();
- List<DataSourceType> protocols = new ArrayList<DataSourceType>();
+ List<String> files = new ArrayList<>();
+ List<DataSourceType> protocols = new ArrayList<>();
try
{
JPanel progressPanel;
- ArrayList<JPanel> fileLoadingPanels = new ArrayList<JPanel>();
+ ArrayList<JPanel> fileLoadingPanels = new ArrayList<>();
public void startLoading(final String fileName)
{
// TODO: verify that frames are recoverable when in headless mode
return null;
}
- List<AlignmentPanel> aps = new ArrayList<AlignmentPanel>();
+ List<AlignmentPanel> aps = new ArrayList<>();
AlignFrame[] frames = getAlignFrames();
if (frames == null)
{
*/
public static AlignmentViewport[] getViewports(String sequenceSetId)
{
- List<AlignmentViewport> viewp = new ArrayList<AlignmentViewport>();
+ List<AlignmentViewport> viewp = new ArrayList<>();
if (desktop != null)
{
AlignFrame[] frames = Desktop.getAlignFrames();
// SEQUENCE_ID which is not the default EMBL_EBI link
ListIterator<String> li = links.listIterator();
boolean check = false;
- List<JLabel> urls = new ArrayList<JLabel>();
+ List<JLabel> urls = new ArrayList<>();
while (li.hasNext())
{
String link = li.next();
if (link.contains(SEQUENCE_ID)
- && !link.equals(UrlConstants.DEFAULT_STRING))
+ && !UrlConstants.isDefaultString(link))
{
check = true;
int barPos = link.indexOf("|");
Thread worker = new Thread(this);
worker.start();
}
+ repaint();
}
public boolean isShowMemoryUsage()
}
}
- /**
- * fixes stacking order after a modal dialog to ensure windows that should be
- * on top actually are
- */
- public void relayerWindows()
- {
-
- }
/**
* Accessor method to quickly get all the AlignmentFrames loaded.
{
return null;
}
- List<AlignFrame> avp = new ArrayList<AlignFrame>();
+ List<AlignFrame> avp = new ArrayList<>();
// REVERSE ORDER
for (int i = frames.length - 1; i > -1; i--)
{
{
return null;
}
- List<GStructureViewer> avp = new ArrayList<GStructureViewer>();
+ List<GStructureViewer> avp = new ArrayList<>();
// REVERSE ORDER
for (int i = frames.length - 1; i > -1; i--)
{
{
if (progressBars == null)
{
- progressBars = new Hashtable<Long, JPanel>();
- progressBarHandlers = new Hashtable<Long, IProgressIndicatorHandler>();
+ progressBars = new Hashtable<>();
+ progressBarHandlers = new Hashtable<>();
}
if (progressBars.get(new Long(id)) != null)
*/
if (ap != null)
{
- ap.paintAlignment(true);
+ ap.paintAlignment(true, true);
}
}
});
* feature type, and repaints the alignment, and optionally the Overview
* and/or structure viewer if open
*
- * @param updateOverview
+ * @param updateStructsAndOverview
*/
- void changeColour(boolean updateOverview)
+ void changeColour(boolean updateStructsAndOverview)
{
// Check if combobox is still adjusting
if (adjusting)
}
fr.setColour(type, acg);
cs = acg;
- ap.paintAlignment(updateOverview);
+ ap.paintAlignment(updateStructsAndOverview, updateStructsAndOverview);
}
@Override
void reset()
{
fr.setColour(type, oldcs);
- ap.paintAlignment(true);
+ ap.paintAlignment(true, true);
cs = null;
}
/*
* force repaint of any Overview window or structure
*/
- ap.paintAlignment(true);
+ ap.paintAlignment(true, true);
} catch (NumberFormatException ex)
{
}
JPanel choosePanel = new JPanel();
choosePanel.add(new JLabel(
MessageManager.getString("label.select_feature") + ":"));
- final JComboBox<String> overlaps = new JComboBox<String>();
+ final JComboBox<String> overlaps = new JComboBox<>();
List<String> added = new ArrayList<>();
for (SequenceFeature sf : features)
{
featuresAdded();
- alignPanel.paintAlignment(true);
+ alignPanel.paintAlignment(true, true);
return true;
}
}
}
- alignPanel.paintAlignment(true);
+ alignPanel.paintAlignment(true, true);
return true;
}
private static final int MIN_WIDTH = 400;
private static final int MIN_HEIGHT = 400;
+
+ /**
+ * when true, constructor is still executing - so ignore UI events
+ */
+ protected volatile boolean inConstruction = true;
/**
* Constructor
};
});
frame.setLayer(JLayeredPane.PALETTE_LAYER);
+ inConstruction = false;
}
protected void popupSort(final int selectedRow, final String type,
@Override
synchronized public void discoverAllFeatureData()
{
- Set<String> allGroups = new HashSet<String>();
+ Set<String> allGroups = new HashSet<>();
AlignmentI alignment = af.getViewport().getAlignment();
for (int i = 0; i < alignment.getHeight(); i++)
final String grp = group;
final JCheckBox check = new JCheckBox(group, visible);
check.setFont(new Font("Serif", Font.BOLD, 12));
+ check.setToolTipText(group);
check.addItemListener(new ItemListener()
{
@Override
public void itemStateChanged(ItemEvent evt)
{
fr.setGroupVisibility(check.getText(), check.isSelected());
- af.alignPanel.getSeqPanel().seqCanvas.repaint();
- if (af.alignPanel.overviewPanel != null)
- {
- af.alignPanel.overviewPanel.updateOverviewImage();
- }
-
resetTable(new String[] { grp });
+ af.alignPanel.paintAlignment(true, true);
}
});
groupPanel.add(check);
return;
}
resettingTable = true;
- typeWidth = new Hashtable<String, float[]>();
+ typeWidth = new Hashtable<>();
// TODO: change avWidth calculation to 'per-sequence' average and use long
// rather than float
- Set<String> displayableTypes = new HashSet<String>();
- Set<String> foundGroups = new HashSet<String>();
+ Set<String> displayableTypes = new HashSet<>();
+ Set<String> foundGroups = new HashSet<>();
/*
* determine which feature types may be visible depending on
* and keep track of which groups are visible
*/
Set<String> groups = seq.getFeatures().getFeatureGroups(true);
- Set<String> visibleGroups = new HashSet<String>();
+ Set<String> visibleGroups = new HashSet<>();
for (String group : groups)
{
if (group == null || checkGroupState(group))
{
if (fr.setFeaturePriority(data, visibleNew))
{
- af.alignPanel.paintAlignment(true);
+ af.alignPanel.paintAlignment(true, true);
}
}
@Override
public void stateChanged(ChangeEvent evt)
{
- fr.setTransparency((100 - transparency.getValue()) / 100f);
- af.alignPanel.paintAlignment(true);
+ if (!inConstruction)
+ {
+ fr.setTransparency((100 - transparency.getValue()) / 100f);
+ af.alignPanel.paintAlignment(true,true);
+ }
}
});
{
ap.av.antiAlias = smoothFont.isSelected();
ap.getAnnotationPanel().image = null;
- ap.paintAlignment(true);
+ ap.paintAlignment(true, false);
if (ap.av.getCodingComplement() != null && ap.av.isProteinFontAsCdna())
{
((AlignViewport) ap.av
ap.av.setScaleProteinAsCdna(oldProteinScale);
ap.av.setProteinFontAsCdna(oldMirrorFont);
ap.av.antiAlias = oldSmoothFont;
- ap.paintAlignment(true);
+ ap.fontChanged();
if (scaleAsCdna.isVisible() && scaleAsCdna.isEnabled())
{
* is removed with a second call with same ID.
*
* @param message
- * - displayed message for operation
+ * - displayed message for operation. Please ensure message is
+ * internationalised.
* @param id
* - unique handle for this indicator
*/
}
lastid = seq;
- alignPanel.paintAlignment(false);
+ alignPanel.paintAlignment(false, false);
}
/**
{
av.getRanges().scrollRight(true);
}
- else if (!av.getWrapAlignment())
+ else
{
av.getRanges().scrollUp(false);
}
{
av.getRanges().scrollRight(false);
}
- else if (!av.getWrapAlignment())
+ else
{
av.getRanges().scrollUp(true);
}
av.isSelectionGroupChanged(true);
- alignPanel.paintAlignment(false);
+ alignPanel.paintAlignment(false, false);
}
/**
running = false;
}
- alignPanel.paintAlignment(false);
+ alignPanel.paintAlignment(false, false);
try
{
* @param evt
* DOCUMENT ME!
*/
+ @Override
public void mousePressed(MouseEvent evt)
{
oldX = evt.getX();
* @param evt
* DOCUMENT ME!
*/
+ @Override
public void mouseReleased(MouseEvent evt)
{
active = false;
* @param evt
* DOCUMENT ME!
*/
+ @Override
public void mouseEntered(MouseEvent evt)
{
active = true;
* @param evt
* DOCUMENT ME!
*/
+ @Override
public void mouseExited(MouseEvent evt)
{
active = false;
* @param evt
* DOCUMENT ME!
*/
+ @Override
public void mouseDragged(MouseEvent evt)
{
active = true;
{
viewport.setIdWidth(newWidth);
- ap.paintAlignment(true);
+ ap.paintAlignment(true, false);
}
oldX = evt.getX();
* @param evt
* DOCUMENT ME!
*/
+ @Override
public void mouseMoved(MouseEvent evt)
{
}
* @param evt
* DOCUMENT ME!
*/
+ @Override
public void mouseClicked(MouseEvent evt)
{
}
* @param g
* DOCUMENT ME!
*/
+ @Override
public void paintComponent(Graphics g)
{
g.setColor(Color.white);
}
}
- void clearSeqRefs()
- {
- if (_cleartables)
- {
- if (seqRefIds != null)
- {
- seqRefIds.clear();
- }
- if (seqsToIds != null)
- {
- seqsToIds.clear();
- }
- if (incompleteSeqs != null)
- {
- incompleteSeqs.clear();
- }
- // seqRefIds = null;
- // seqsToIds = null;
- }
- else
- {
- // do nothing
- warn("clearSeqRefs called when _cleartables was not set. Doing nothing.");
- // seqRefIds = new Hashtable();
- // seqsToIds = new IdentityHashMap();
- }
- }
-
void initSeqRefs()
{
if (seqsToIds == null)
// SAVE TREES
// /////////////////////////////////
- if (!storeDS && av.currentTree != null)
+ if (!storeDS && av.getCurrentTree() != null)
{
// FIND ANY ASSOCIATED TREES
// NOT IMPLEMENTED FOR HEADLESS STATE AT PRESENT
{
Tree tree = new Tree();
tree.setTitle(tp.getTitle());
- tree.setCurrentTree((av.currentTree == tp.getTree()));
+ tree.setCurrentTree((av.getCurrentTree() == tp.getTree()));
tree.setNewick(tp.getTree().print());
tree.setThreshold(tp.treeCanvas.threshold);
jarInputStreamProvider jprovider = createjarInputStreamProvider(file);
af = loadJalviewAlign(jprovider);
+ af.setMenusForViewport();
} catch (MalformedURLException e)
{
StructureData filedat = oldFiles.get(id);
String pdbFile = filedat.getFilePath();
SequenceI[] seq = filedat.getSeqList().toArray(new SequenceI[0]);
- binding.getSsm().setMapping(seq, null, pdbFile, DataSourceType.FILE);
+ binding.getSsm().setMapping(seq, null, pdbFile, DataSourceType.FILE,
+ null);
binding.addSequenceForStructFile(pdbFile, seq);
}
// and add the AlignmentPanel's reference to the view panel
}
- public jalview.gui.AlignmentPanel copyAlignPanel(AlignmentPanel ap,
- boolean keepSeqRefs)
+ /**
+ * Provides a 'copy' of an alignment view (on action New View) by 'saving' the
+ * view as XML (but not to file), and then reloading it
+ *
+ * @param ap
+ * @return
+ */
+ public AlignmentPanel copyAlignPanel(AlignmentPanel ap)
{
initSeqRefs();
JalviewModel jm = saveState(ap, null, null, null);
- if (!keepSeqRefs)
- {
- clearSeqRefs();
- jm.getJalviewModelSequence().getViewport(0).setSequenceSetId(null);
- }
- else
- {
- uniqueSetSuffix = "";
- jm.getJalviewModelSequence().getViewport(0).setId(null); // we don't
- // overwrite the
- // view we just
- // copied
- }
+ uniqueSetSuffix = "";
+ jm.getJalviewModelSequence().getViewport(0).setId(null);
+ // we don't overwrite the view we just copied
+
if (this.frefedSequence == null)
{
- frefedSequence = new Vector();
+ frefedSequence = new Vector<SeqFref>();
}
viewportsAdded.clear();
return af.alignPanel;
}
- /**
- * flag indicating if hashtables should be cleared on finalization TODO this
- * flag may not be necessary
- */
- private final boolean _cleartables = true;
-
private Hashtable jvids2vobj;
- /*
- * (non-Javadoc)
- *
- * @see java.lang.Object#finalize()
- */
- @Override
- protected void finalize() throws Throwable
- {
- // really make sure we have no buried refs left.
- if (_cleartables)
- {
- clearSeqRefs();
- }
- this.seqRefIds = null;
- this.seqsToIds = null;
- super.finalize();
- }
-
private void warn(String msg)
{
warn(msg, null);
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.beans.PropertyChangeEvent;
+import java.beans.PropertyVetoException;
import javax.swing.JCheckBoxMenuItem;
+import javax.swing.JInternalFrame;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.SwingUtilities;
{
try
{
- av.getRanges().removePropertyChangeListener(this);
+ if (av != null)
+ {
+ av.getRanges().removePropertyChangeListener(this);
+ }
+
oviewCanvas.dispose();
+
+ /*
+ * close the parent frame (which also removes it from the
+ * Desktop Windows menu)
+ */
+ ((JInternalFrame) SwingUtilities.getAncestorOfClass(
+ JInternalFrame.class, (this))).setClosed(true);
+ } catch (PropertyVetoException e)
+ {
+ // ignore
} finally
{
progressPanel = null;
int top = 0;
+ private boolean working;
+
/**
* Creates a new PCAPanel object using default score model and parameters
*
message = MessageManager.getString("label.pca_calculating");
}
progress.setProgressBar(message, progId);
+ working = true;
try
{
calcSettings.setEnabled(false);
} catch (OutOfMemoryError er)
{
new OOMWarning("calculating PCA", er);
+ working = false;
return;
} finally
{
.getString("label.principal_component_analysis"), 475, 450);
this.setMinimumSize(new Dimension(MIN_WIDTH, MIN_HEIGHT));
}
+ working = false;
}
@Override
top = t;
zCombobox.setSelectedIndex(2);
}
+
+ /**
+ * Answers true if PCA calculation is in progress, else false
+ *
+ * @return
+ */
+ public boolean isWorking()
+ {
+ return working;
+ }
}
import java.awt.Component;
import java.util.ArrayList;
import java.util.HashMap;
+import java.util.Iterator;
import java.util.List;
import java.util.Map;
-import java.util.Map.Entry;
/**
* Route datamodel/view update events for a sequence set to any display
*/
public static void RemoveComponent(Component comp)
{
- List<String> emptied = new ArrayList<String>();
- for (Entry<String, List<Component>> registered : components.entrySet())
+ if (components == null)
{
- String id = registered.getKey();
- List<Component> comps = components.get(id);
+ return;
+ }
+
+ Iterator<String> it = components.keySet().iterator();
+ while (it.hasNext())
+ {
+ List<Component> comps = components.get(it.next());
comps.remove(comp);
if (comps.isEmpty())
{
- emptied.add(id);
+ it.remove();
}
}
-
- /*
- * Remove now empty ids after the above (to avoid
- * ConcurrentModificationException).
- */
- for (String id : emptied)
- {
- components.remove(id);
- }
}
public static void Refresh(Component source, String id)
import jalview.analysis.AlignSeq;
import jalview.datamodel.Alignment;
-import jalview.datamodel.Sequence;
+import jalview.datamodel.AlignmentView;
+import jalview.datamodel.SequenceGroup;
import jalview.datamodel.SequenceI;
import jalview.jbgui.GPairwiseAlignPanel;
import jalview.util.MessageManager;
public class PairwiseAlignPanel extends GPairwiseAlignPanel
{
+ private static final String DASHES = "---------------------\n";
+
AlignmentViewport av;
- Vector sequences;
+ Vector<SequenceI> sequences;
/**
* Creates a new PairwiseAlignPanel object.
*
- * @param av
+ * @param viewport
* DOCUMENT ME!
*/
- public PairwiseAlignPanel(AlignmentViewport av)
+ public PairwiseAlignPanel(AlignmentViewport viewport)
{
super();
- this.av = av;
+ this.av = viewport;
- sequences = new Vector();
+ sequences = new Vector<SequenceI>();
- SequenceI[] seqs;
- String[] seqStrings = av.getViewAsString(true);
+ SequenceGroup selectionGroup = viewport.getSelectionGroup();
+ boolean isSelection = selectionGroup != null
+ && selectionGroup.getSize() > 0;
+ AlignmentView view = viewport.getAlignmentView(isSelection);
+ // String[] seqStrings = viewport.getViewAsString(true);
+ String[] seqStrings = view.getSequenceStrings(viewport
+ .getGapCharacter());
- if (av.getSelectionGroup() == null)
+ SequenceI[] seqs;
+ if (isSelection)
{
- seqs = av.getAlignment().getSequencesArray();
+ seqs = (SequenceI[]) view.getAlignmentAndHiddenColumns(viewport
+ .getGapCharacter())[0];
}
else
{
- seqs = av.getSelectionGroup().getSequencesInOrder(av.getAlignment());
+ seqs = av.getAlignment().getSequencesArray();
}
- String type = (av.getAlignment().isNucleotide()) ? AlignSeq.DNA
+ String type = (viewport.getAlignment().isNucleotide()) ? AlignSeq.DNA
: AlignSeq.PEP;
float[][] scores = new float[seqs.length][seqs.length];
- double totscore = 0;
+ double totscore = 0D;
int count = seqs.length;
-
- Sequence seq;
+ boolean first = true;
for (int i = 1; i < count; i++)
{
for (int j = 0; j < i; j++)
{
-
AlignSeq as = new AlignSeq(seqs[i], seqStrings[i], seqs[j],
seqStrings[j], type);
as.calcScoreMatrix();
as.traceAlignment();
+ if (!first)
+ {
+ System.out.println(DASHES);
+ textarea.append(DASHES);
+ }
+ first = false;
as.printAlignment(System.out);
- scores[i][j] = (float) as.getMaxScore()
- / (float) as.getASeq1().length;
+ scores[i][j] = as.getMaxScore()
+ / as.getASeq1().length;
totscore = totscore + scores[i][j];
textarea.append(as.getOutput());
if (count > 2)
{
- System.out.println(
- "Pairwise alignment scaled similarity score matrix\n");
+ printScoreMatrix(seqs, scores, totscore);
+ }
+ }
- for (int i = 0; i < count; i++)
- {
- jalview.util.Format.print(System.out, "%s \n",
- ("" + i) + " " + seqs[i].getName());
- }
+ /**
+ * Prints a matrix of seqi-seqj pairwise alignment scores to sysout
+ *
+ * @param seqs
+ * @param scores
+ * @param totscore
+ */
+ protected void printScoreMatrix(SequenceI[] seqs, float[][] scores,
+ double totscore)
+ {
+ System.out
+ .println("Pairwise alignment scaled similarity score matrix\n");
- System.out.println("\n");
+ for (int i = 0; i < seqs.length; i++)
+ {
+ System.out.println(String.format("%3d %s", i + 1,
+ seqs[i].getDisplayId(true)));
+ }
+
+ /*
+ * table heading columns for sequences 1, 2, 3...
+ */
+ System.out.print("\n ");
+ for (int i = 0; i < seqs.length; i++)
+ {
+ System.out.print(String.format("%7d", i + 1));
+ }
+ System.out.println();
- for (int i = 0; i < count; i++)
+ for (int i = 0; i < seqs.length; i++)
+ {
+ System.out.print(String.format("%3d", i + 1));
+ for (int j = 0; j < i; j++)
{
- for (int j = 0; j < i; j++)
- {
- jalview.util.Format.print(System.out, "%7.3f",
- scores[i][j] / totscore);
- }
+ /*
+ * as a fraction of tot score, outputs are 0 <= score <= 1
+ */
+ System.out.print(String.format("%7.3f", scores[i][j] / totscore));
}
-
- System.out.println("\n");
+ System.out.println();
}
+
+ System.out.println("\n");
}
/**
* @param e
* DOCUMENT ME!
*/
+ @Override
protected void viewInEditorButton_actionPerformed(ActionEvent e)
{
- Sequence[] seq = new Sequence[sequences.size()];
+ SequenceI[] seq = new SequenceI[sequences.size()];
for (int i = 0; i < sequences.size(); i++)
{
- seq[i] = (Sequence) sequences.elementAt(i);
+ seq[i] = sequences.elementAt(i);
}
AlignFrame af = new AlignFrame(new Alignment(seq),
}
sequence.setName(dialog.getName().replace(' ', '_'));
- ap.paintAlignment(false);
+ ap.paintAlignment(false, false);
}
sequence.setDescription(dialog.getDescription());
}
this.statusPanel = container;
this.statusBar = statusBar;
- this.progressBars = new Hashtable<Long, JPanel>();
- this.progressBarHandlers = new Hashtable<Long, IProgressIndicatorHandler>();
+ this.progressBars = new Hashtable<>();
+ this.progressBarHandlers = new Hashtable<>();
}
* execution.
*/
@Override
- public void setProgressBar(String message, long id)
+ public void setProgressBar(final String message, final long id)
{
- Long longId = Long.valueOf(id);
-
- JPanel progressPanel = progressBars.get(longId);
- if (progressPanel != null)
+ SwingUtilities.invokeLater(new Runnable()
{
- /*
- * Progress bar is displayed for this id - remove it now, and any handler
- */
- progressBars.remove(id);
- if (message != null && statusBar != null)
- {
- statusBar.setText(message);
- }
- if (progressBarHandlers.containsKey(longId))
+ @Override
+ public void run()
{
- progressBarHandlers.remove(longId);
- }
- removeRow(progressPanel);
- }
- else
- {
- /*
- * No progress bar for this id - add one now
- */
- progressPanel = new JPanel(new BorderLayout(10, 5));
+ JPanel progressPanel = progressBars.get(id);
+ if (progressPanel != null)
+ {
+ /*
+ * Progress bar is displayed for this id - remove it now, and any handler
+ */
+ progressBars.remove(id);
+ if (message != null && statusBar != null)
+ {
+ statusBar.setText(message);
+ }
+ if (progressBarHandlers.containsKey(id))
+ {
+ progressBarHandlers.remove(id);
+ }
+ removeRow(progressPanel);
+ }
+ else
+ {
+ /*
+ * No progress bar for this id - add one now
+ */
+ progressPanel = new JPanel(new BorderLayout(10, 5));
- JProgressBar progressBar = new JProgressBar();
- progressBar.setIndeterminate(true);
+ JProgressBar progressBar = new JProgressBar();
+ progressBar.setIndeterminate(true);
- progressPanel.add(new JLabel(message), BorderLayout.WEST);
- progressPanel.add(progressBar, BorderLayout.CENTER);
+ progressPanel.add(new JLabel(message), BorderLayout.WEST);
+ progressPanel.add(progressBar, BorderLayout.CENTER);
- addRow(progressPanel);
+ addRow(progressPanel);
- progressBars.put(longId, progressPanel);
- }
+ progressBars.put(id, progressPanel);
+ }
+
+ refreshLayout();
+ }
+ });
- refreshLayout();
}
/**
public void registerHandler(final long id,
final IProgressIndicatorHandler handler)
{
- Long longId = Long.valueOf(id);
- final JPanel progressPanel = progressBars.get(longId);
- if (progressPanel == null)
- {
- System.err.println(
- "call setProgressBar before registering the progress bar's handler.");
- return;
- }
-
- /*
- * Nothing useful to do if not a Cancel handler
- */
- if (!handler.canCancel())
- {
- return;
- }
-
- progressBarHandlers.put(longId, handler);
- JButton cancel = new JButton(MessageManager.getString("action.cancel"));
final IProgressIndicator us = this;
- cancel.addActionListener(new ActionListener()
- {
+ SwingUtilities.invokeLater(new Runnable()
+ {
@Override
- public void actionPerformed(ActionEvent e)
+ public void run()
{
- handler.cancelActivity(id);
- us.setProgressBar(MessageManager
- .formatMessage("label.cancelled_params", new Object[]
- { ((JLabel) progressPanel.getComponent(0)).getText() }),
- id);
+ final JPanel progressPanel = progressBars.get(id);
+ if (progressPanel == null)
+ {
+ System.err.println(
+ "call setProgressBar before registering the progress bar's handler.");
+ return;
+ }
+
+ /*
+ * Nothing useful to do if not a Cancel handler
+ */
+ if (!handler.canCancel())
+ {
+ return;
+ }
+
+ progressBarHandlers.put(id, handler);
+ JButton cancel = new JButton(
+ MessageManager.getString("action.cancel"));
+ cancel.addActionListener(new ActionListener()
+ {
+
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ handler.cancelActivity(id);
+ us.setProgressBar(MessageManager
+ .formatMessage("label.cancelled_params", new Object[]
+ { ((JLabel) progressPanel.getComponent(0)).getText() }),
+ id);
+ }
+ });
+ progressPanel.add(cancel, BorderLayout.EAST);
+ refreshLayout();
+
}
});
- progressPanel.add(cancel, BorderLayout.EAST);
- refreshLayout();
}
}
import java.awt.Component;
-import javax.swing.JOptionPane;
-
public class PromptUserConfig implements Runnable
{
/**
this.allowCancel = allowCancel;
}
+ @Override
public void run()
{
if (property == null)
(allowCancel) ? JvOptionPane.YES_NO_CANCEL_OPTION
: JvOptionPane.YES_NO_OPTION,
JvOptionPane.QUESTION_MESSAGE);
- // now, ask the desktop to relayer any external windows that might have
- // been obsured
- if (Desktop.instance != null)
- {
- Desktop.instance.relayerWindows();
- }
+
// and finish parsing the result
jalview.bin.Cache.log.debug("Got response : " + reply);
if (reply == JvOptionPane.YES_OPTION)
AlignmentPanel ap;
- Stack<CommandI> historyList = new Stack<CommandI>();
+ Stack<CommandI> historyList = new Stack<>();
// simpler than synching with alignFrame.
}
float value = slider.getValue();
- List<SequenceI> redundantSequences = new ArrayList<SequenceI>();
+ List<SequenceI> redundantSequences = new ArrayList<>();
for (int i = 0; i < redundancy.length; i++)
{
if (value <= redundancy[i])
af.updateEditMenuBar();
}
- ap.paintAlignment(true);
+ ap.paintAlignment(true, true);
if (historyList.size() == 0)
{
{
av.showColumn(reveal[0]);
reveal = null;
- ap.paintAlignment(true);
+ ap.paintAlignment(true, true);
av.sendSelection();
}
});
{
av.showAllHiddenColumns();
reveal = null;
- ap.paintAlignment(true);
+ ap.paintAlignment(true, true);
av.sendSelection();
}
});
av.setSelectionGroup(null);
}
- ap.paintAlignment(true);
+ ap.paintAlignment(true, true);
av.sendSelection();
}
});
sg.setEndRes(max);
}
av.setSelectionGroup(sg);
- ap.paintAlignment(false);
+ ap.paintAlignment(false, false);
av.sendSelection();
}
}
else
{
- ap.paintAlignment(false);
+ ap.paintAlignment(false, false);
}
return;
}
}
}
stretchingGroup = false;
- ap.paintAlignment(false);
+ ap.paintAlignment(false, false);
av.sendSelection();
}
{
stretchingGroup = true;
cs.stretchGroup(res, sg, min, max);
- ap.paintAlignment(false);
+ ap.paintAlignment(false, false);
}
}
import jalview.datamodel.SequenceI;
import jalview.renderer.ScaleRenderer;
import jalview.renderer.ScaleRenderer.ScaleMark;
+import jalview.util.Comparison;
import jalview.viewmodel.ViewportListenerI;
import jalview.viewmodel.ViewportRanges;
import javax.swing.JComponent;
/**
- * DOCUMENT ME!
+ * The Swing component on which the alignment sequences, and annotations (if
+ * shown), are drawn. This includes scales above, left and right (if shown) in
+ * Wrapped mode, but not the scale above in Unwrapped mode.
*
- * @author $author$
- * @version $Revision$
*/
public class SeqCanvas extends JComponent implements ViewportListenerI
{
- private static String ZEROS = "0000000000";
+ private static final String ZEROS = "0000000000";
final FeatureRenderer fr;
- final SequenceRenderer seqRdr;
-
BufferedImage img;
- Graphics2D gg;
-
AlignViewport av;
- boolean fastPaint = false;
+ int cursorX = 0;
- int labelWidthWest;
+ int cursorY = 0;
- int labelWidthEast;
+ private final SequenceRenderer seqRdr;
- int cursorX = 0;
+ private boolean fastPaint = false;
- int cursorY = 0;
+ private boolean fastpainting = false;
- int charHeight = 0;
+ private AnnotationPanel annotations;
- int charWidth = 0;
+ /*
+ * measurements for drawing a wrapped alignment
+ */
+ private int labelWidthEast; // label right width in pixels if shown
+
+ private int labelWidthWest; // label left width in pixels if shown
- boolean fastpainting = false;
+ private int wrappedSpaceAboveAlignment; // gap between widths
- AnnotationPanel annotations;
+ private int wrappedRepeatHeightPx; // height in pixels of wrapped width
+
+ private int wrappedVisibleWidths; // number of wrapped widths displayed
+
+ private Graphics2D gg;
/**
* Creates a new SeqCanvas object.
*
- * @param av
- * DOCUMENT ME!
+ * @param ap
*/
public SeqCanvas(AlignmentPanel ap)
{
this.av = ap.av;
- updateViewport();
fr = new FeatureRenderer(ap);
seqRdr = new SequenceRenderer(av);
setLayout(new BorderLayout());
return fr;
}
- private void updateViewport()
- {
- charHeight = av.getCharHeight();
- charWidth = av.getCharWidth();
- }
-
/**
- * DOCUMENT ME!
+ * Draws the scale above a region of a wrapped alignment, consisting of a
+ * column number every major interval (10 columns).
*
* @param g
- * DOCUMENT ME!
+ * the graphics context to draw on, positioned at the start (bottom
+ * left) of the line on which to draw any scale marks
* @param startx
- * DOCUMENT ME!
+ * start alignment column (0..)
* @param endx
- * DOCUMENT ME!
+ * end alignment column (0..)
* @param ypos
- * DOCUMENT ME!
+ * y offset to draw at
*/
private void drawNorthScale(Graphics g, int startx, int endx, int ypos)
{
- updateViewport();
- for (ScaleMark mark : new ScaleRenderer().calculateMarks(av, startx,
- endx))
+ int charHeight = av.getCharHeight();
+ int charWidth = av.getCharWidth();
+
+ /*
+ * white fill the scale space (for the fastPaint case)
+ */
+ g.setColor(Color.white);
+ g.fillRect(0, ypos - charHeight - charHeight / 2, getWidth(),
+ charHeight * 3 / 2 + 2);
+ g.setColor(Color.black);
+
+ List<ScaleMark> marks = new ScaleRenderer().calculateMarks(av, startx,
+ endx);
+ for (ScaleMark mark : marks)
{
int mpos = mark.column; // (i - startx - 1)
if (mpos < 0)
{
g.drawString(mstring, mpos * charWidth, ypos - (charHeight / 2));
}
- g.drawLine((mpos * charWidth) + (charWidth / 2),
- (ypos + 2) - (charHeight / 2),
- (mpos * charWidth) + (charWidth / 2), ypos - 2);
+
+ /*
+ * draw a tick mark below the column number, centred on the column;
+ * height of tick mark is 4 pixels less than half a character
+ */
+ int xpos = (mpos * charWidth) + (charWidth / 2);
+ g.drawLine(xpos, (ypos + 2) - (charHeight / 2), xpos, ypos - 2);
}
}
}
/**
- * DOCUMENT ME!
+ * Draw the scale to the left or right of a wrapped alignment
*
* @param g
- * DOCUMENT ME!
+ * graphics context, positioned at the start of the scale to be drawn
* @param startx
- * DOCUMENT ME!
+ * first column of wrapped width (0.. excluding any hidden columns)
* @param endx
- * DOCUMENT ME!
+ * last column of wrapped width (0.. excluding any hidden columns)
* @param ypos
- * DOCUMENT ME!
+ * vertical offset at which to begin the scale
+ * @param left
+ * if true, scale is left of residues, if false, scale is right
*/
- void drawWestScale(Graphics g, int startx, int endx, int ypos)
+ void drawVerticalScale(Graphics g, final int startx, final int endx,
+ final int ypos, final boolean left)
{
- FontMetrics fm = getFontMetrics(av.getFont());
- ypos += charHeight;
+ int charHeight = av.getCharHeight();
+ int charWidth = av.getCharWidth();
- if (av.hasHiddenColumns())
- {
- startx = av.getAlignment().getHiddenColumns()
- .adjustForHiddenColumns(startx);
- endx = av.getAlignment().getHiddenColumns()
- .adjustForHiddenColumns(endx);
- }
+ int yPos = ypos + charHeight;
+ int startX = startx;
+ int endX = endx;
- int maxwidth = av.getAlignment().getWidth();
if (av.hasHiddenColumns())
{
- maxwidth = av.getAlignment().getHiddenColumns()
- .findColumnPosition(maxwidth) - 1;
+ HiddenColumns hiddenColumns = av.getAlignment().getHiddenColumns();
+ startX = hiddenColumns.adjustForHiddenColumns(startx);
+ endX = hiddenColumns.adjustForHiddenColumns(endx);
}
+ FontMetrics fm = getFontMetrics(av.getFont());
- // WEST SCALE
for (int i = 0; i < av.getAlignment().getHeight(); i++)
{
SequenceI seq = av.getAlignment().getSequenceAt(i);
- int index = startx;
- int value = -1;
- while (index < endx)
+ /*
+ * find sequence position of first non-gapped position -
+ * to the right if scale left, to the left if scale right
+ */
+ int index = left ? startX : endX;
+ int value = -1;
+ while (index >= startX && index <= endX)
{
- if (jalview.util.Comparison.isGap(seq.getCharAt(index)))
+ if (!Comparison.isGap(seq.getCharAt(index)))
+ {
+ value = seq.findPosition(index);
+ break;
+ }
+ if (left)
{
index++;
-
- continue;
}
-
- value = av.getAlignment().getSequenceAt(i).findPosition(index);
-
- break;
- }
-
- if (value != -1)
- {
- int x = labelWidthWest - fm.stringWidth(String.valueOf(value))
- - charWidth / 2;
- g.drawString(value + "", x,
- (ypos + (i * charHeight)) - (charHeight / 5));
- }
- }
- }
-
- /**
- * DOCUMENT ME!
- *
- * @param g
- * DOCUMENT ME!
- * @param startx
- * DOCUMENT ME!
- * @param endx
- * DOCUMENT ME!
- * @param ypos
- * DOCUMENT ME!
- */
- void drawEastScale(Graphics g, int startx, int endx, int ypos)
- {
- ypos += charHeight;
-
- if (av.hasHiddenColumns())
- {
- endx = av.getAlignment().getHiddenColumns()
- .adjustForHiddenColumns(endx);
- }
-
- SequenceI seq;
- // EAST SCALE
- for (int i = 0; i < av.getAlignment().getHeight(); i++)
- {
- seq = av.getAlignment().getSequenceAt(i);
- int index = endx;
- int value = -1;
-
- while (index > startx)
- {
- if (jalview.util.Comparison.isGap(seq.getCharAt(index)))
+ else
{
index--;
-
- continue;
}
-
- value = seq.findPosition(index);
-
- break;
}
+ /*
+ * white fill the space for the scale
+ */
+ g.setColor(Color.white);
+ int y = (yPos + (i * charHeight)) - (charHeight / 5);
+ // fillRect origin is top left of rectangle
+ g.fillRect(0, y - charHeight, left ? labelWidthWest : labelWidthEast,
+ charHeight + 1);
+
if (value != -1)
{
- g.drawString(String.valueOf(value), 0,
- (ypos + (i * charHeight)) - (charHeight / 5));
+ /*
+ * draw scale value, right justified within its width less half a
+ * character width padding on the right
+ */
+ int labelSpace = left ? labelWidthWest : labelWidthEast;
+ labelSpace -= charWidth / 2; // leave space to the right
+ String valueAsString = String.valueOf(value);
+ int labelLength = fm.stringWidth(valueAsString);
+ int xOffset = labelSpace - labelLength;
+ g.setColor(Color.black);
+ g.drawString(valueAsString, xOffset, y);
}
}
}
-
/**
- * need to make this thread safe move alignment rendering in response to
- * slider adjustment
+ * Does a fast paint of an alignment in response to a scroll. Most of the
+ * visible region is simply copied and shifted, and then any newly visible
+ * columns or rows are drawn. The scroll may be horizontal or vertical, but
+ * not both at once. Scrolling may be the result of
+ * <ul>
+ * <li>dragging a scroll bar</li>
+ * <li>clicking in the scroll bar</li>
+ * <li>scrolling by trackpad, middle mouse button, or other device</li>
+ * <li>by moving the box in the Overview window</li>
+ * <li>programmatically to make a highlighted position visible</li>
+ * </ul>
*
* @param horizontal
- * shift along
+ * columns to shift right (positive) or left (negative)
* @param vertical
- * shift up or down in repaint
+ * rows to shift down (positive) or up (negative)
*/
public void fastPaint(int horizontal, int vertical)
{
}
fastpainting = true;
fastPaint = true;
- updateViewport();
- ViewportRanges ranges = av.getRanges();
- int startRes = ranges.getStartRes();
- int endRes = ranges.getEndRes();
- int startSeq = ranges.getStartSeq();
- int endSeq = ranges.getEndSeq();
- int transX = 0;
- int transY = 0;
+ try
+ {
+ int charHeight = av.getCharHeight();
+ int charWidth = av.getCharWidth();
+
+ ViewportRanges ranges = av.getRanges();
+ int startRes = ranges.getStartRes();
+ int endRes = ranges.getEndRes();
+ int startSeq = ranges.getStartSeq();
+ int endSeq = ranges.getEndSeq();
+ int transX = 0;
+ int transY = 0;
gg.copyArea(horizontal * charWidth, vertical * charHeight,
img.getWidth(), img.getHeight(), -horizontal * charWidth,
gg.translate(-transX, -transY);
repaint();
- fastpainting = false;
+ } finally
+ {
+ fastpainting = false;
+ }
}
@Override
public void paintComponent(Graphics g)
{
- super.paintComponent(g);
-
- updateViewport();
+ super.paintComponent(g);
+
+ int charHeight = av.getCharHeight();
+ int charWidth = av.getCharWidth();
ViewportRanges ranges = av.getRanges();
g.drawImage(lcimg, 0, 0, this);
}
}
-
+
/**
* Draw an alignment panel for printing
*
{
BufferedImage lcimg = null;
+ int charWidth = av.getCharWidth();
+ int charHeight = av.getCharHeight();
+
int width = getWidth();
int height = getHeight();
*/
public int getWrappedCanvasWidth(int canvasWidth)
{
- FontMetrics fm = getFontMetrics(av.getFont());
+ int charWidth = av.getCharWidth();
- labelWidthEast = 0;
- labelWidthWest = 0;
+ FontMetrics fm = getFontMetrics(av.getFont());
- if (av.getScaleRightWrapped())
+ int labelWidth = 0;
+
+ if (av.getScaleRightWrapped() || av.getScaleLeftWrapped())
{
- labelWidthEast = getLabelWidth(fm);
+ labelWidth = getLabelWidth(fm);
}
- if (av.getScaleLeftWrapped())
- {
- labelWidthWest = labelWidthEast > 0 ? labelWidthEast
- : getLabelWidth(fm);
- }
+ labelWidthEast = av.getScaleRightWrapped() ? labelWidth : 0;
+
+ labelWidthWest = av.getScaleLeftWrapped() ? labelWidth : 0;
return (canvasWidth - labelWidthEast - labelWidthWest) / charWidth;
}
/**
- * Returns a pixel width suitable for showing the largest sequence coordinate
- * (end position) in the alignment. Returns 2 plus the number of decimal
- * digits to be shown (3 for 1-10, 4 for 11-99 etc).
+ * Returns a pixel width sufficient to show the largest sequence coordinate
+ * (end position) in the alignment, calculated as the FontMetrics width of
+ * zeroes "0000000" limited to the number of decimal digits to be shown (3 for
+ * 1-10, 4 for 11-99 etc). One character width is added to this, to allow for
+ * half a character width space on either side.
*
* @param fm
* @return
maxWidth = Math.max(maxWidth, alignment.getSequenceAt(i).getEnd());
}
- int length = 2;
+ int length = 0;
for (int i = maxWidth; i > 0; i /= 10)
{
length++;
}
- return fm.stringWidth(ZEROS.substring(0, length));
+ return fm.stringWidth(ZEROS.substring(0, length)) + av.getCharWidth();
}
/**
- * DOCUMENT ME!
+ * Draws as many widths of a wrapped alignment as can fit in the visible
+ * window
*
* @param g
- * DOCUMENT ME!
* @param canvasWidth
- * DOCUMENT ME!
+ * available width in pixels
* @param canvasHeight
- * DOCUMENT ME!
- * @param startRes
- * DOCUMENT ME!
+ * available height in pixels
+ * @param startColumn
+ * the first column (0...) of the alignment to draw
*/
- private void drawWrappedPanel(Graphics g, int canvasWidth,
- int canvasHeight, int startRes)
+ public void drawWrappedPanel(Graphics g, int canvasWidth,
+ int canvasHeight, final int startColumn)
{
- updateViewport();
- AlignmentI al = av.getAlignment();
+ int wrappedWidthInResidues = calculateWrappedGeometry(canvasWidth,
+ canvasHeight);
- int labelWidth = 0;
- if (av.getScaleRightWrapped() || av.getScaleLeftWrapped())
+ av.setWrappedWidth(wrappedWidthInResidues);
+
+ ViewportRanges ranges = av.getRanges();
+ ranges.setViewportStartAndWidth(startColumn, wrappedWidthInResidues);
+
+ /*
+ * draw one width at a time (including any scales or annotation shown),
+ * until we have run out of either alignment or vertical space available
+ */
+ int ypos = wrappedSpaceAboveAlignment;
+ int maxWidth = ranges.getVisibleAlignmentWidth();
+
+ int start = startColumn;
+ int currentWidth = 0;
+ while ((currentWidth < wrappedVisibleWidths) && (start < maxWidth))
{
- FontMetrics fm = getFontMetrics(av.getFont());
- labelWidth = getLabelWidth(fm);
+ int endColumn = Math
+ .min(maxWidth, start + wrappedWidthInResidues - 1);
+ drawWrappedWidth(g, ypos, start, endColumn, canvasHeight);
+ ypos += wrappedRepeatHeightPx;
+ start += wrappedWidthInResidues;
+ currentWidth++;
}
- labelWidthEast = av.getScaleRightWrapped() ? labelWidth : 0;
- labelWidthWest = av.getScaleLeftWrapped() ? labelWidth : 0;
+ drawWrappedDecorators(g, startColumn);
+ }
- int hgap = charHeight;
- if (av.getScaleAboveWrapped())
+ /**
+ * Calculates and saves values needed when rendering a wrapped alignment.
+ * These depend on many factors, including
+ * <ul>
+ * <li>canvas width and height</li>
+ * <li>number of visible sequences, and height of annotations if shown</li>
+ * <li>font and character width</li>
+ * <li>whether scales are shown left, right or above the alignment</li>
+ * </ul>
+ *
+ * @param canvasWidth
+ * @param canvasHeight
+ * @return the number of residue columns in each width
+ */
+ protected int calculateWrappedGeometry(int canvasWidth, int canvasHeight)
+ {
+ int charHeight = av.getCharHeight();
+
+ /*
+ * vertical space in pixels between wrapped widths of alignment
+ * - one character height, or two if scale above is drawn
+ */
+ wrappedSpaceAboveAlignment = charHeight
+ * (av.getScaleAboveWrapped() ? 2 : 1);
+
+ /*
+ * height in pixels of the wrapped widths
+ */
+ wrappedRepeatHeightPx = wrappedSpaceAboveAlignment;
+ // add sequences
+ wrappedRepeatHeightPx += av.getRanges().getViewportHeight()
+ * charHeight;
+ // add annotations panel height if shown
+ wrappedRepeatHeightPx += getAnnotationHeight();
+
+ /*
+ * number of visible widths (the last one may be part height),
+ * ensuring a part height includes at least one sequence
+ */
+ ViewportRanges ranges = av.getRanges();
+ wrappedVisibleWidths = canvasHeight / wrappedRepeatHeightPx;
+ int remainder = canvasHeight % wrappedRepeatHeightPx;
+ if (remainder >= (wrappedSpaceAboveAlignment + charHeight))
{
- hgap += charHeight;
+ wrappedVisibleWidths++;
}
- int cWidth = (canvasWidth - labelWidthEast - labelWidthWest) / charWidth;
- int cHeight = av.getAlignment().getHeight() * charHeight;
+ /*
+ * compute width in residues; this also sets East and West label widths
+ */
+ int wrappedWidthInResidues = getWrappedCanvasWidth(canvasWidth);
- av.setWrappedWidth(cWidth);
+ /*
+ * limit visibleWidths to not exceed width of alignment
+ */
+ int xMax = ranges.getVisibleAlignmentWidth();
+ int startToEnd = xMax - ranges.getStartRes();
+ int maxWidths = startToEnd / wrappedWidthInResidues;
+ if (startToEnd % wrappedWidthInResidues > 0)
+ {
+ maxWidths++;
+ }
+ wrappedVisibleWidths = Math.min(wrappedVisibleWidths, maxWidths);
- av.getRanges().setViewportStartAndWidth(startRes, cWidth);
+ return wrappedWidthInResidues;
+ }
- int endx;
- int ypos = hgap;
- int maxwidth = av.getAlignment().getWidth();
+ /**
+ * Draws one width of a wrapped alignment, including sequences and
+ * annnotations, if shown, but not scales or hidden column markers
+ *
+ * @param g
+ * @param ypos
+ * @param startColumn
+ * @param endColumn
+ * @param canvasHeight
+ */
+ protected void drawWrappedWidth(Graphics g, int ypos, int startColumn,
+ int endColumn, int canvasHeight)
+ {
+ ViewportRanges ranges = av.getRanges();
+ int viewportWidth = ranges.getViewportWidth();
- if (av.hasHiddenColumns())
+ int endx = Math.min(startColumn + viewportWidth - 1, endColumn);
+
+ /*
+ * move right before drawing by the width of the scale left (if any)
+ * plus column offset from left margin (usually zero, but may be non-zero
+ * when fast painting is drawing just a few columns)
+ */
+ int charWidth = av.getCharWidth();
+ int xOffset = labelWidthWest
+ + ((startColumn - ranges.getStartRes()) % viewportWidth)
+ * charWidth;
+ g.translate(xOffset, 0);
+
+ // When printing we have an extra clipped region,
+ // the Printable page which we need to account for here
+ Shape clip = g.getClip();
+
+ if (clip == null)
{
- maxwidth = av.getAlignment().getHiddenColumns()
- .findColumnPosition(maxwidth);
+ g.setClip(0, 0, viewportWidth * charWidth, canvasHeight);
+ }
+ else
+ {
+ g.setClip(0, (int) clip.getBounds().getY(),
+ viewportWidth * charWidth, (int) clip.getBounds().getHeight());
}
- int annotationHeight = getAnnotationHeight();
+ /*
+ * white fill the region to be drawn (so incremental fast paint doesn't
+ * scribble over an existing image)
+ */
+ gg.setColor(Color.white);
+ gg.fillRect(0, ypos, (endx - startColumn + 1) * charWidth,
+ wrappedRepeatHeightPx);
- while ((ypos <= canvasHeight) && (startRes < maxwidth))
- {
- endx = startRes + cWidth - 1;
+ drawPanel(g, startColumn, endx, 0, av.getAlignment().getHeight() - 1,
+ ypos);
- if (endx > maxwidth)
+ int cHeight = av.getAlignment().getHeight() * av.getCharHeight();
+
+ if (av.isShowAnnotation())
+ {
+ g.translate(0, cHeight + ypos + 3);
+ if (annotations == null)
{
- endx = maxwidth;
+ annotations = new AnnotationPanel(av);
}
- g.setFont(av.getFont());
- g.setColor(Color.black);
+ annotations.renderer.drawComponent(annotations, av, g, -1,
+ startColumn, endx + 1);
+ g.translate(0, -cHeight - ypos - 3);
+ }
+ g.setClip(clip);
+ g.translate(-xOffset, 0);
+ }
+
+ /**
+ * Draws scales left, right and above (if shown), and any hidden column
+ * markers, on all widths of the wrapped alignment
+ *
+ * @param g
+ * @param startColumn
+ */
+ protected void drawWrappedDecorators(Graphics g, final int startColumn)
+ {
+ int charWidth = av.getCharWidth();
+
+ g.setFont(av.getFont());
+ g.setColor(Color.black);
+
+ int ypos = wrappedSpaceAboveAlignment;
+ ViewportRanges ranges = av.getRanges();
+ int viewportWidth = ranges.getViewportWidth();
+ int maxWidth = ranges.getVisibleAlignmentWidth();
+ int widthsDrawn = 0;
+ int startCol = startColumn;
+
+ while (widthsDrawn < wrappedVisibleWidths)
+ {
+ int endColumn = Math.min(maxWidth, startCol + viewportWidth - 1);
if (av.getScaleLeftWrapped())
{
- drawWestScale(g, startRes, endx, ypos);
+ drawVerticalScale(g, startCol, endColumn - 1, ypos, true);
}
if (av.getScaleRightWrapped())
{
- g.translate(canvasWidth - labelWidthEast, 0);
- drawEastScale(g, startRes, endx, ypos);
- g.translate(-(canvasWidth - labelWidthEast), 0);
+ int x = labelWidthWest + viewportWidth * charWidth;
+ g.translate(x, 0);
+ drawVerticalScale(g, startCol, endColumn, ypos, false);
+ g.translate(-x, 0);
}
+ /*
+ * white fill region of scale above and hidden column markers
+ * (to support incremental fast paint of image)
+ */
+ g.translate(labelWidthWest, 0);
+ g.setColor(Color.white);
+ g.fillRect(0, ypos - wrappedSpaceAboveAlignment, viewportWidth
+ * charWidth + labelWidthWest, wrappedSpaceAboveAlignment);
+ g.setColor(Color.black);
+ g.translate(-labelWidthWest, 0);
+
g.translate(labelWidthWest, 0);
if (av.getScaleAboveWrapped())
{
- drawNorthScale(g, startRes, endx, ypos);
+ drawNorthScale(g, startCol, endColumn, ypos);
}
if (av.hasHiddenColumns() && av.getShowHiddenMarkers())
{
- g.setColor(Color.blue);
- int res;
- HiddenColumns hidden = av.getAlignment().getHiddenColumns();
- List<Integer> positions = hidden.findHiddenRegionPositions();
- for (int pos : positions)
- {
- res = pos - startRes;
-
- if (res < 0 || res > endx - startRes)
- {
- continue;
- }
-
- gg.fillPolygon(
- new int[]
- { res * charWidth - charHeight / 4,
- res * charWidth + charHeight / 4, res * charWidth },
- new int[]
- { ypos - (charHeight / 2), ypos - (charHeight / 2),
- ypos - (charHeight / 2) + 8 },
- 3);
-
- }
+ drawHiddenColumnMarkers(g, ypos, startCol, endColumn);
}
- // When printing we have an extra clipped region,
- // the Printable page which we need to account for here
- Shape clip = g.getClip();
+ g.translate(-labelWidthWest, 0);
- if (clip == null)
- {
- g.setClip(0, 0, cWidth * charWidth, canvasHeight);
- }
- else
- {
- g.setClip(0, (int) clip.getBounds().getY(), cWidth * charWidth,
- (int) clip.getBounds().getHeight());
- }
+ ypos += wrappedRepeatHeightPx;
+ startCol += viewportWidth;
+ widthsDrawn++;
+ }
+ }
+
+ /**
+ * Draws markers (triangles) above hidden column positions between startColumn
+ * and endColumn.
+ *
+ * @param g
+ * @param ypos
+ * @param startColumn
+ * @param endColumn
+ */
+ protected void drawHiddenColumnMarkers(Graphics g, int ypos,
+ int startColumn, int endColumn)
+ {
+ int charHeight = av.getCharHeight();
+ int charWidth = av.getCharWidth();
- drawPanel(g, startRes, endx, 0, al.getHeight() - 1, ypos);
+ g.setColor(Color.blue);
+ HiddenColumns hidden = av.getAlignment().getHiddenColumns();
+ List<Integer> positions = hidden.findHiddenRegionPositions();
+ for (int pos : positions)
+ {
+ int res = pos - startColumn;
- if (av.isShowAnnotation())
+ if (res < 0 || res > endColumn - startColumn + 1)
{
- g.translate(0, cHeight + ypos + 3);
- if (annotations == null)
- {
- annotations = new AnnotationPanel(av);
- }
-
- annotations.renderer.drawComponent(annotations, av, g, -1, startRes,
- endx + 1);
- g.translate(0, -cHeight - ypos - 3);
+ continue;
}
- g.setClip(clip);
- g.translate(-labelWidthWest, 0);
-
- ypos += cHeight + annotationHeight + hgap;
- startRes += cWidth;
+ /*
+ * draw a downward-pointing triangle at the hidden columns location
+ * (before the following visible column)
+ */
+ int xMiddle = res * charWidth;
+ int[] xPoints = new int[] { xMiddle - charHeight / 4,
+ xMiddle + charHeight / 4, xMiddle };
+ int yTop = ypos - (charHeight / 2);
+ int[] yPoints = new int[] { yTop, yTop, yTop + 8 };
+ g.fillPolygon(xPoints, yPoints, 3);
}
}
int canvasWidth,
int canvasHeight, int startRes)
{
+ int charHeight = av.getCharHeight();
+ int charWidth = av.getCharWidth();
+
// height gap above each panel
int hgap = charHeight;
if (av.getScaleAboveWrapped())
* marker.
*
* @param g1
- * Graphics object to draw with
+ * the graphics context, positioned at the first residue to be drawn
* @param startRes
- * offset of the first column in the visible region (0..)
+ * offset of the first column to draw (0..)
* @param endRes
- * offset of the last column in the visible region (0..)
+ * offset of the last column to draw (0..)
* @param startSeq
- * offset of the first sequence in the visible region (0..)
+ * offset of the first sequence to draw (0..)
* @param endSeq
- * offset of the last sequence in the visible region (0..)
+ * offset of the last sequence to draw (0..)
* @param yOffset
* vertical offset at which to draw (for wrapped alignments)
*/
public void drawPanel(Graphics g1, final int startRes, final int endRes,
final int startSeq, final int endSeq, final int yOffset)
{
- updateViewport();
+ int charHeight = av.getCharHeight();
+ int charWidth = av.getCharWidth();
+
if (!av.hasHiddenColumns())
{
draw(g1, startRes, endRes, startSeq, endSeq, yOffset);
private void draw(Graphics g, int startRes, int endRes, int startSeq,
int endSeq, int offset)
{
+ int charHeight = av.getCharHeight();
+ int charWidth = av.getCharWidth();
+
g.setFont(av.getFont());
seqRdr.prepare(g, av.isRenderGaps());
private void drawUnwrappedSelection(Graphics2D g, SequenceGroup group,
int startRes, int endRes, int startSeq, int endSeq, int offset)
{
+ int charWidth = av.getCharWidth();
+
if (!av.hasHiddenColumns())
{
drawPartialGroupOutline(g, group, startRes, endRes, startSeq, endSeq,
int startRes, int endRes, int startSeq, int endSeq,
int verticalOffset)
{
+ int charHeight = av.getCharHeight();
+ int charWidth = av.getCharWidth();
+
int visWidth = (endRes - startRes + 1) * charWidth;
int oldY = -1;
return false;
}
boolean wrapped = av.getWrapAlignment();
-
try
{
fastPaint = !noFastPaint;
fastpainting = fastPaint;
- updateViewport();
-
/*
* to avoid redrawing the whole visible region, we instead
* redraw just the minimal regions to remove previous highlights
{
fastPaint = true;
repaint();
+ return;
}
- else if (av.getWrapAlignment())
+
+ int scrollX = 0;
+ if (eventName.equals(ViewportRanges.STARTRES))
{
- if (eventName.equals(ViewportRanges.STARTRES))
+ // Make sure we're not trying to draw a panel
+ // larger than the visible window
+ ViewportRanges vpRanges = av.getRanges();
+ scrollX = (int) evt.getNewValue() - (int) evt.getOldValue();
+ int range = vpRanges.getViewportWidth();
+ if (scrollX > range)
{
- repaint();
+ scrollX = range;
+ }
+ else if (scrollX < -range)
+ {
+ scrollX = -range;
}
}
- else
+
+ // 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.
+
+ // scroll - startres and endres both change
+ if (eventName.equals(ViewportRanges.STARTRES))
{
- int scrollX = 0;
- if (eventName.equals(ViewportRanges.STARTRES))
+ if (av.getWrapAlignment())
{
- // Make sure we're not trying to draw a panel
- // larger than the visible window
- ViewportRanges vpRanges = av.getRanges();
- scrollX = (int) evt.getNewValue() - (int) evt.getOldValue();
- int range = vpRanges.getEndRes() - vpRanges.getStartRes();
- if (scrollX > range)
- {
- scrollX = range;
- }
- else if (scrollX < -range)
- {
- scrollX = -range;
- }
+ fastPaintWrapped(scrollX);
}
-
- // 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))
+ else
{
- // scroll - startres and endres both change
fastPaint(scrollX, 0);
}
- else if (eventName.equals(ViewportRanges.STARTSEQ))
+ }
+ else if (eventName.equals(ViewportRanges.STARTSEQ))
+ {
+ // scroll
+ fastPaint(0, (int) evt.getNewValue() - (int) evt.getOldValue());
+ }
+ }
+
+ /**
+ * Does a minimal update of the image for a scroll movement. This method
+ * handles scroll movements of up to one width of the wrapped alignment (one
+ * click in the vertical scrollbar). Larger movements (for example after a
+ * scroll to highlight a mapped position) trigger a full redraw instead.
+ *
+ * @param scrollX
+ * number of positions scrolled (right if positive, left if negative)
+ */
+ protected void fastPaintWrapped(int scrollX)
+ {
+ ViewportRanges ranges = av.getRanges();
+
+ if (Math.abs(scrollX) > ranges.getViewportWidth())
+ {
+ /*
+ * shift of more than one view width is
+ * overcomplicated to handle in this method
+ */
+ fastPaint = false;
+ repaint();
+ return;
+ }
+
+ if (fastpainting || gg == null)
+ {
+ return;
+ }
+
+ fastPaint = true;
+ fastpainting = true;
+
+ try
+ {
+ calculateWrappedGeometry(getWidth(), getHeight());
+
+ /*
+ * relocate the regions of the alignment that are still visible
+ */
+ shiftWrappedAlignment(-scrollX);
+
+ /*
+ * add new columns (sequence, annotation)
+ * - at top left if scrollX < 0
+ * - at right of last two widths if scrollX > 0
+ */
+ if (scrollX < 0)
+ {
+ int startRes = ranges.getStartRes();
+ drawWrappedWidth(gg, wrappedSpaceAboveAlignment, startRes, startRes
+ - scrollX - 1, getHeight());
+ }
+ else
+ {
+ fastPaintWrappedAddRight(scrollX);
+ }
+
+ /*
+ * draw all scales (if shown) and hidden column markers
+ */
+ drawWrappedDecorators(gg, ranges.getStartRes());
+
+ repaint();
+ } finally
+ {
+ fastpainting = false;
+ }
+ }
+
+ /**
+ * Draws the specified number of columns at the 'end' (bottom right) of a
+ * wrapped alignment view, including sequences and annotations if shown, but
+ * not scales. Also draws the same number of columns at the right hand end of
+ * the second last width shown, if the last width is not full height (so
+ * cannot simply be copied from the graphics image).
+ *
+ * @param columns
+ */
+ protected void fastPaintWrappedAddRight(int columns)
+ {
+ if (columns == 0)
+ {
+ return;
+ }
+
+ ViewportRanges ranges = av.getRanges();
+ int viewportWidth = ranges.getViewportWidth();
+ int charWidth = av.getCharWidth();
+
+ /**
+ * draw full height alignment in the second last row, last columns, if the
+ * last row was not full height
+ */
+ int visibleWidths = wrappedVisibleWidths;
+ int canvasHeight = getHeight();
+ boolean lastWidthPartHeight = (wrappedVisibleWidths * wrappedRepeatHeightPx) > canvasHeight;
+
+ if (lastWidthPartHeight)
+ {
+ int widthsAbove = Math.max(0, visibleWidths - 2);
+ int ypos = wrappedRepeatHeightPx * widthsAbove
+ + wrappedSpaceAboveAlignment;
+ int endRes = ranges.getEndRes();
+ endRes += widthsAbove * viewportWidth;
+ int startRes = endRes - columns;
+ int xOffset = ((startRes - ranges.getStartRes()) % viewportWidth)
+ * charWidth;
+
+ /*
+ * white fill first to erase annotations
+ */
+ gg.translate(xOffset, 0);
+ gg.setColor(Color.white);
+ gg.fillRect(labelWidthWest, ypos,
+ (endRes - startRes + 1) * charWidth, wrappedRepeatHeightPx);
+ gg.translate(-xOffset, 0);
+
+ drawWrappedWidth(gg, ypos, startRes, endRes, canvasHeight);
+ }
+
+ /*
+ * draw newly visible columns in last wrapped width (none if we
+ * have reached the end of the alignment)
+ * y-offset for drawing last width is height of widths above,
+ * plus one gap row
+ */
+ int widthsAbove = visibleWidths - 1;
+ int ypos = wrappedRepeatHeightPx * widthsAbove
+ + wrappedSpaceAboveAlignment;
+ int endRes = ranges.getEndRes();
+ endRes += widthsAbove * viewportWidth;
+ int startRes = endRes - columns + 1;
+
+ /*
+ * white fill first to erase annotations
+ */
+ int xOffset = ((startRes - ranges.getStartRes()) % viewportWidth)
+ * charWidth;
+ gg.translate(xOffset, 0);
+ gg.setColor(Color.white);
+ int width = viewportWidth * charWidth - xOffset;
+ gg.fillRect(labelWidthWest, ypos, width, wrappedRepeatHeightPx);
+ gg.translate(-xOffset, 0);
+
+ gg.setFont(av.getFont());
+ gg.setColor(Color.black);
+
+ if (startRes < ranges.getVisibleAlignmentWidth())
+ {
+ drawWrappedWidth(gg, ypos, startRes, endRes, canvasHeight);
+ }
+
+ /*
+ * and finally, white fill any space below the visible alignment
+ */
+ int heightBelow = canvasHeight - visibleWidths * wrappedRepeatHeightPx;
+ if (heightBelow > 0)
+ {
+ gg.setColor(Color.white);
+ gg.fillRect(0, canvasHeight - heightBelow, getWidth(), heightBelow);
+ }
+ }
+
+ /**
+ * Shifts the visible alignment by the specified number of columns - left if
+ * negative, right if positive. Copies and moves sequences and annotations (if
+ * shown). Scales, hidden column markers and any newly visible columns must be
+ * drawn separately.
+ *
+ * @param positions
+ */
+ protected void shiftWrappedAlignment(int positions)
+ {
+ if (positions == 0)
+ {
+ return;
+ }
+ int charWidth = av.getCharWidth();
+
+ int canvasHeight = getHeight();
+ ViewportRanges ranges = av.getRanges();
+ int viewportWidth = ranges.getViewportWidth();
+ int widthToCopy = (ranges.getViewportWidth() - Math.abs(positions))
+ * charWidth;
+ int heightToCopy = wrappedRepeatHeightPx - wrappedSpaceAboveAlignment;
+ int xMax = ranges.getVisibleAlignmentWidth();
+
+ if (positions > 0)
+ {
+ /*
+ * shift right (after scroll left)
+ * for each wrapped width (starting with the last), copy (width-positions)
+ * columns from the left margin to the right margin, and copy positions
+ * columns from the right margin of the row above (if any) to the
+ * left margin of the current row
+ */
+
+ /*
+ * get y-offset of last wrapped width, first row of sequences
+ */
+ int y = canvasHeight / wrappedRepeatHeightPx * wrappedRepeatHeightPx;
+ y += wrappedSpaceAboveAlignment;
+ int copyFromLeftStart = labelWidthWest;
+ int copyFromRightStart = copyFromLeftStart + widthToCopy;
+
+ while (y >= 0)
+ {
+ gg.copyArea(copyFromLeftStart, y, widthToCopy, heightToCopy,
+ positions * charWidth, 0);
+ if (y > 0)
+ {
+ gg.copyArea(copyFromRightStart, y - wrappedRepeatHeightPx,
+ positions * charWidth, heightToCopy, -widthToCopy,
+ wrappedRepeatHeightPx);
+ }
+
+ y -= wrappedRepeatHeightPx;
+ }
+ }
+ else
+ {
+ /*
+ * shift left (after scroll right)
+ * for each wrapped width (starting with the first), copy (width-positions)
+ * columns from the right margin to the left margin, and copy positions
+ * columns from the left margin of the row below (if any) to the
+ * right margin of the current row
+ */
+ int xpos = av.getRanges().getStartRes();
+ int y = wrappedSpaceAboveAlignment;
+ int copyFromRightStart = labelWidthWest - positions * charWidth;
+
+ while (y < canvasHeight)
{
- // scroll
- fastPaint(0, (int) evt.getNewValue() - (int) evt.getOldValue());
+ gg.copyArea(copyFromRightStart, y, widthToCopy, heightToCopy,
+ positions * charWidth, 0);
+ if (y + wrappedRepeatHeightPx < canvasHeight - wrappedRepeatHeightPx
+ && (xpos + viewportWidth <= xMax))
+ {
+ gg.copyArea(labelWidthWest, y + wrappedRepeatHeightPx, -positions
+ * charWidth, heightToCopy, widthToCopy,
+ -wrappedRepeatHeightPx);
+ }
+
+ y += wrappedRepeatHeightPx;
+ xpos += viewportWidth;
}
}
}
+
/**
* Redraws any positions in the search results in the visible region of a
* wrapped alignment. Any highlights are drawn depending on the search results
{
return false;
}
-
+ int charHeight = av.getCharHeight();
+
boolean matchFound = false;
+ calculateWrappedGeometry(getWidth(), getHeight());
int wrappedWidth = av.getWrappedWidth();
- int wrappedHeight = getRepeatHeightWrapped();
+ int wrappedHeight = wrappedRepeatHeightPx;
ViewportRanges ranges = av.getRanges();
int canvasHeight = getHeight();
}
/**
- * Answers the height in pixels of a repeating section of the wrapped
- * alignment, including space above, scale above if shown, sequences, and
- * annotation panel if shown
+ * Answers the width in pixels of the left scale labels (0 if not shown)
*
* @return
*/
- protected int getRepeatHeightWrapped()
+ int getLabelWidthWest()
{
- // gap (and maybe scale) above
- int repeatHeight = charHeight * (av.getScaleAboveWrapped() ? 2 : 1);
-
- // add sequences
- repeatHeight += av.getRanges().getViewportHeight() * charHeight;
-
- // add annotations panel height if shown
- repeatHeight += getAnnotationHeight();
-
- return repeatHeight;
+ return labelWidthWest;
}
}
+ hgap + seqCanvas.getAnnotationHeight();
int y = evt.getY();
- y -= hgap;
- x = Math.max(0, x - seqCanvas.labelWidthWest);
+ y = Math.max(0, y - hgap);
+ x = Math.max(0, x - seqCanvas.getLabelWidthWest());
int cwidth = seqCanvas.getWrappedCanvasWidth(this.getWidth());
if (cwidth < 1)
av.setSelectionGroup(sg);
}
- ap.paintAlignment(false);
+ ap.paintAlignment(false, false);
av.sendSelection();
}
}
/**
- * DOCUMENT ME!
+ * Action on mouse movement is to update the status bar to show the current
+ * sequence position, and (if features are shown) to show any features at the
+ * position in a tooltip. Does nothing if the mouse move does not change
+ * residue position.
*
* @param evt
- * DOCUMENT ME!
*/
@Override
public void mouseMoved(MouseEvent evt)
}
final int column = findColumn(evt);
- int seq = findSeq(evt);
+ final int seq = findSeq(evt);
+
if (column < 0 || seq < 0 || seq >= av.getAlignment().getHeight())
{
lastMouseSeq = -1;
/**
* set when the current UI interaction has resulted in a change that requires
- * overview shading to be recalculated. this could be changed to something
- * more expressive that indicates what actually has changed, so selective
- * redraws can be applied
+ * shading in overviews and structures to be recalculated. this could be
+ * changed to a something more expressive that indicates what actually has
+ * changed, so selective redraws can be applied (ie. only structures, only
+ * overview, etc)
*/
- private boolean needOverviewUpdate = false; // TODO: refactor to avcontroller
+ private boolean updateOverviewAndStructs = false; // TODO: refactor to avcontroller
/**
* set if av.getSelectionGroup() refers to a group that is defined on the
}
if (newWidth > 0)
{
- ap.paintAlignment(false);
+ ap.paintAlignment(false, false);
if (copyChanges)
{
/*
av.getRanges().scrollRight(true);
}
- else if (!av.getWrapAlignment())
+ else
{
av.getRanges().scrollUp(false);
}
{
av.getRanges().scrollRight(false);
}
- else if (!av.getWrapAlignment())
+ else
{
av.getRanges().scrollUp(true);
}
}
- // TODO Update tooltip for new position.
+
+ /*
+ * update status bar and tooltip for new position
+ * (need to synthesize a mouse movement to refresh tooltip)
+ */
+ mouseMoved(e);
+ ToolTipManager.sharedInstance().mouseMoved(e);
}
/**
final int res = findColumn(evt);
final int seq = findSeq(evt);
oldSeq = seq;
- needOverviewUpdate = false;
+ updateOverviewAndStructs = false;
startWrapBlock = wrappedBlock;
// always do this - annotation has own state
// but defer colourscheme update until hidden sequences are passed in
boolean vischange = stretchGroup.recalcConservation(true);
- needOverviewUpdate |= vischange && av.isSelectionDefinedGroup()
+ updateOverviewAndStructs |= vischange && av.isSelectionDefinedGroup()
&& afterDrag;
if (stretchGroup.cs != null)
{
}
}
PaintRefresher.Refresh(this, av.getSequenceSetId());
- ap.paintAlignment(needOverviewUpdate);
- needOverviewUpdate = false;
+ // TODO: structure colours only need updating if stretchGroup used to or now
+ // does contain sequences with structure views
+ ap.paintAlignment(updateOverviewAndStructs, updateOverviewAndStructs);
+ updateOverviewAndStructs = false;
changeEndRes = false;
changeStartRes = false;
stretchGroup = null;
if (res > (stretchGroup.getStartRes() - 1))
{
stretchGroup.setEndRes(res);
- needOverviewUpdate |= av.isSelectionDefinedGroup();
+ updateOverviewAndStructs |= av.isSelectionDefinedGroup();
}
}
else if (changeStartRes)
if (res < (stretchGroup.getEndRes() + 1))
{
stretchGroup.setStartRes(res);
- needOverviewUpdate |= av.isSelectionDefinedGroup();
+ updateOverviewAndStructs |= av.isSelectionDefinedGroup();
}
}
if (stretchGroup.getSequences(null).contains(nextSeq))
{
stretchGroup.deleteSequence(seq, false);
- needOverviewUpdate |= av.isSelectionDefinedGroup();
+ updateOverviewAndStructs |= av.isSelectionDefinedGroup();
}
else
{
}
stretchGroup.addSequence(nextSeq, false);
- needOverviewUpdate |= av.isSelectionDefinedGroup();
+ updateOverviewAndStructs |= av.isSelectionDefinedGroup();
}
}
@Override
public void mouseReleased(MouseEvent evt)
{
- ap.paintAlignment(true);
+ ap.paintAlignment(true, true);
}
});
}
/**
- * Adjust the divider for a sensible split of the real estate (for example,
+ * Adjusts the divider for a sensible split of the real estate (for example,
* when many transcripts are shown with a single protein). This should only be
* called after the split pane has been laid out (made visible) so it has a
- * height.
+ * height. The aim is to avoid unnecessary vertical scroll bars, while
+ * ensuring that at least 2 sequences are visible in each panel.
+ * <p>
+ * Once laid out, the user may choose to customise as they wish, so this
+ * method is not called again after the initial layout.
*/
- protected void adjustDivider()
+ protected void adjustInitialLayout()
{
- final AlignViewport topViewport = ((AlignFrame) getTopFrame()).viewport;
- final AlignViewport bottomViewport = ((AlignFrame) getBottomFrame()).viewport;
+ AlignFrame topFrame = (AlignFrame) getTopFrame();
+ AlignFrame bottomFrame = (AlignFrame) getBottomFrame();
+
+ /*
+ * recompute layout of top and bottom panels to reflect their
+ * actual (rather than requested) height
+ */
+ topFrame.alignPanel.adjustAnnotationHeight();
+ bottomFrame.alignPanel.adjustAnnotationHeight();
+
+ final AlignViewport topViewport = topFrame.viewport;
+ final AlignViewport bottomViewport = bottomFrame.viewport;
final AlignmentI topAlignment = topViewport.getAlignment();
final AlignmentI bottomAlignment = bottomViewport.getAlignment();
boolean topAnnotations = topViewport.isShowAnnotation();
int bottomCharHeight = bottomViewport.getViewStyle().getCharHeight();
/*
+ * calculate the minimum ratio that leaves at least the height
+ * of two sequences (after rounding) visible in the top panel
+ */
+ int topPanelHeight = topFrame.getHeight();
+ int bottomPanelHeight = bottomFrame.getHeight();
+ int topSequencesHeight = topFrame.alignPanel.getSeqPanel().seqCanvas
+ .getHeight();
+ int topPanelMinHeight = topPanelHeight
+ - Math.max(0, topSequencesHeight - 3 * topCharHeight);
+ double totalHeight = (double) topPanelHeight + bottomPanelHeight;
+ double minRatio = topPanelMinHeight / totalHeight;
+
+ /*
+ * calculate the maximum ratio that leaves at least the height
+ * of two sequences (after rounding) visible in the bottom panel
+ */
+ int bottomSequencesHeight = bottomFrame.alignPanel.getSeqPanel().seqCanvas
+ .getHeight();
+ int bottomPanelMinHeight = bottomPanelHeight
+ - Math.max(0, bottomSequencesHeight - 3 * bottomCharHeight);
+ double maxRatio = (totalHeight - bottomPanelMinHeight) / totalHeight;
+
+ /*
* estimate ratio of (topFrameContent / bottomFrameContent)
*/
int insets = Platform.isAMac() ? MAC_INSETS_HEIGHT
+ (topAnnotations ? topViewport.calcPanelHeight() : 0);
int bottomHeight = insets + (3 + bottomCount) * bottomCharHeight
+ (bottomAnnotations ? bottomViewport.calcPanelHeight() : 0);
- double ratio = ((double) topHeight) / (topHeight + bottomHeight);
+ double ratio = ((double) topHeight)
+ / (double) (topHeight + bottomHeight);
/*
- * limit to 0.2 <= ratio <= 0.8 to avoid concealing all sequences
+ * limit ratio to avoid concealing all sequences
*/
- ratio = Math.min(ratio, 0.8d);
- ratio = Math.max(ratio, 0.2d);
+ ratio = Math.min(ratio, maxRatio);
+ ratio = Math.max(ratio, minRatio);
setRelativeDividerLocation(ratio);
}
Collection<FTSDataColumnI> wantedFields = pdbDocFieldPrefs
.getStructureSummaryFields();
- discoveredStructuresSet = new LinkedHashSet<FTSData>();
- HashSet<String> errors = new HashSet<String>();
+ discoveredStructuresSet = new LinkedHashSet<>();
+ HashSet<String> errors = new HashSet<>();
for (SequenceI seq : selectedSequences)
{
FTSRestRequest pdbRequest = new FTSRestRequest();
public void loadLocalCachedPDBEntries()
{
- ArrayList<CachedPDB> entries = new ArrayList<CachedPDB>();
+ ArrayList<CachedPDB> entries = new ArrayList<>();
for (SequenceI seq : selectedSequences)
{
if (seq.getDatasetSequence() != null
boolean isPDBRefsFound = false;
boolean isUniProtRefsFound = false;
StringBuilder queryBuilder = new StringBuilder();
- Set<String> seqRefs = new LinkedHashSet<String>();
+ Set<String> seqRefs = new LinkedHashSet<>();
if (seq.getAllPDBEntries() != null
&& queryBuilder.length() < MAX_QLENGTH)
lbl_loading.setVisible(true);
Collection<FTSDataColumnI> wantedFields = pdbDocFieldPrefs
.getStructureSummaryFields();
- Collection<FTSData> filteredResponse = new HashSet<FTSData>();
- HashSet<String> errors = new HashSet<String>();
+ Collection<FTSData> filteredResponse = new HashSet<>();
+ HashSet<String> errors = new HashSet<>();
for (SequenceI seq : selectedSequences)
{
if (!filteredResponse.isEmpty())
{
final int filterResponseCount = filteredResponse.size();
- Collection<FTSData> reorderedStructuresSet = new LinkedHashSet<FTSData>();
+ Collection<FTSData> reorderedStructuresSet = new LinkedHashSet<>();
reorderedStructuresSet.addAll(filteredResponse);
reorderedStructuresSet.addAll(discoveredStructuresSet);
getResultTable().setModel(FTSRestResponse
@Override
public void ok_ActionPerformed()
{
- final long progressSessionId = System.currentTimeMillis();
final StructureSelectionManager ssm = ap.getStructureSelectionManager();
+
final int preferredHeight = pnl_filter.getHeight();
- ssm.setProgressIndicator(this);
- ssm.setProgressSessionId(progressSessionId);
+
new Thread(new Runnable()
{
@Override
int[] selectedRows = getResultTable().getSelectedRows();
PDBEntry[] pdbEntriesToView = new PDBEntry[selectedRows.length];
int count = 0;
- List<SequenceI> selectedSeqsToView = new ArrayList<SequenceI>();
+ List<SequenceI> selectedSeqsToView = new ArrayList<>();
for (int row : selectedRows)
{
String pdbIdStr = getResultTable()
pdbEntry = getFindEntry(pdbIdStr,
selectedSeq.getAllPDBEntries());
}
+
if (pdbEntry == null)
{
pdbEntry = new PDBEntry();
.getModelIndex();
int refSeqColIndex = tbl_local_pdb.getColumn("Ref Sequence")
.getModelIndex();
- List<SequenceI> selectedSeqsToView = new ArrayList<SequenceI>();
+ List<SequenceI> selectedSeqsToView = new ArrayList<>();
for (int row : selectedRows)
{
PDBEntry pdbEntry = (PDBEntry) tbl_local_pdb.getValueAt(row,
{
selectedSequence = userSelectedSeq;
}
-
String pdbIdStr = txt_search.getText();
PDBEntry pdbEntry = selectedSequence.getPDBEntry(pdbIdStr);
if (pdbEntry == null)
{ selectedSequence });
}
closeAction(preferredHeight);
+ mainFrame.dispose();
}
}).start();
}
final PDBEntry[] pdbEntriesToView,
final AlignmentPanel alignPanel, SequenceI[] sequences)
{
- ssm.setProgressBar(MessageManager
- .getString("status.launching_3d_structure_viewer"));
+ long progressId = sequences.hashCode();
+ setProgressBar(MessageManager
+ .getString("status.launching_3d_structure_viewer"), progressId);
final StructureViewer sViewer = new StructureViewer(ssm);
+ setProgressBar(null, progressId);
if (SiftsSettings.isMapWithSifts())
{
- List<SequenceI> seqsWithoutSourceDBRef = new ArrayList<SequenceI>();
+ List<SequenceI> seqsWithoutSourceDBRef = new ArrayList<>();
int p = 0;
// TODO: skip PDBEntry:Sequence pairs where PDBEntry doesn't look like a
// real PDB ID. For moment, we can also safely do this if there is already
if (!seqsWithoutSourceDBRef.isEmpty())
{
int y = seqsWithoutSourceDBRef.size();
- ssm.setProgressBar(null);
- ssm.setProgressBar(MessageManager.formatMessage(
+ setProgressBar(MessageManager.formatMessage(
"status.fetching_dbrefs_for_sequences_without_valid_refs",
- y));
+ y), progressId);
SequenceI[] seqWithoutSrcDBRef = new SequenceI[y];
int x = 0;
for (SequenceI fSeq : seqsWithoutSourceDBRef)
{
seqWithoutSrcDBRef[x++] = fSeq;
}
+
DBRefFetcher dbRefFetcher = new DBRefFetcher(seqWithoutSrcDBRef);
dbRefFetcher.fetchDBRefs(true);
+
+ setProgressBar("Fetch complete.", progressId); // todo i18n
}
}
if (pdbEntriesToView.length > 1)
{
- ArrayList<SequenceI[]> seqsMap = new ArrayList<SequenceI[]>();
+ ArrayList<SequenceI[]> seqsMap = new ArrayList<>();
for (SequenceI seq : sequences)
{
seqsMap.add(new SequenceI[] { seq });
}
SequenceI[][] collatedSeqs = seqsMap.toArray(new SequenceI[0][0]);
- ssm.setProgressBar(null);
- ssm.setProgressBar(MessageManager.getString(
- "status.fetching_3d_structures_for_selected_entries"));
+
+ setProgressBar(MessageManager
+ .getString("status.fetching_3d_structures_for_selected_entries"), progressId);
sViewer.viewStructures(pdbEntriesToView, collatedSeqs, alignPanel);
}
else
{
- ssm.setProgressBar(null);
- ssm.setProgressBar(MessageManager.formatMessage(
+ setProgressBar(MessageManager.formatMessage(
"status.fetching_3d_structures_for",
- pdbEntriesToView[0].getId()));
+ pdbEntriesToView[0].getId()),progressId);
sViewer.viewStructures(pdbEntriesToView[0], sequences, alignPanel);
}
+ setProgressBar(null, progressId);
}
/**
String searchTerm = txt_search.getText().toLowerCase();
searchTerm = searchTerm.split(":")[0];
// System.out.println(">>>>> search term : " + searchTerm);
- List<FTSDataColumnI> wantedFields = new ArrayList<FTSDataColumnI>();
+ List<FTSDataColumnI> wantedFields = new ArrayList<>();
FTSRestRequest pdbRequest = new FTSRestRequest();
pdbRequest.setAllowEmptySeq(false);
pdbRequest.setResponseSize(1);
public PDBEntryTableModel(List<CachedPDB> pdbEntries)
{
- this.pdbEntries = new ArrayList<CachedPDB>(pdbEntries);
+ this.pdbEntries = new ArrayList<>(pdbEntries);
}
@Override
/**
* list of sequenceSet ids associated with the view
*/
- protected List<String> _aps = new ArrayList<String>();
+ protected List<String> _aps = new ArrayList<>();
/**
* list of alignment panels to use for superposition
*/
- protected Vector<AlignmentPanel> _alignwith = new Vector<AlignmentPanel>();
+ protected Vector<AlignmentPanel> _alignwith = new Vector<>();
/**
* list of alignment panels that are used for colouring structures by aligned
* sequences
*/
- protected Vector<AlignmentPanel> _colourwith = new Vector<AlignmentPanel>();
+ protected Vector<AlignmentPanel> _colourwith = new Vector<>();
private String viewId = null;
{
if (_alignwith == null)
{
- _alignwith = new Vector<AlignmentPanel>();
+ _alignwith = new Vector<>();
}
if (_alignwith.size() == 0 && ap != null)
{
public abstract ViewerType getViewerType();
+ protected abstract IProgressIndicator getIProgressIndicator();
+
/**
* add a new structure (with associated sequences and chains) to this viewer,
* retrieving it if necessary first.
* create the mappings
*/
apanel.getStructureSelectionManager().setMapping(seq, chains,
- pdbFilename, DataSourceType.FILE);
+ pdbFilename, DataSourceType.FILE, getIProgressIndicator());
/*
* alert the FeatureRenderer to show new (PDB RESNUM) features
if (apanel.getSeqPanel().seqCanvas.fr != null)
{
apanel.getSeqPanel().seqCanvas.fr.featuresAdded();
- apanel.paintAlignment(true);
+ // note - we don't do a refresh for structure here because we do it
+ // explicitly for all panels later on
+ apanel.paintAlignment(true, false);
}
/*
if (_colourwith == null)
{
- _colourwith = new Vector<AlignmentPanel>();
+ _colourwith = new Vector<>();
}
if (_alignwith == null)
{
- _alignwith = new Vector<AlignmentPanel>();
+ _alignwith = new Vector<>();
}
ViewSelectionMenu seqColourBy = new ViewSelectionMenu(
binding.setColourBySequence(seqColour.isSelected());
if (_colourwith == null)
{
- _colourwith = new Vector<AlignmentPanel>();
+ _colourwith = new Vector<>();
}
if (binding.isColourBySequence())
{
*/
protected void saveInitialSettings()
{
- groupColour1 = new HashMap<SequenceGroup, Color>();
- groupColour2 = new HashMap<SequenceGroup, Color>();
- groupThreshold = new HashMap<SequenceGroup, Integer>();
+ groupColour1 = new HashMap<>();
+ groupColour2 = new HashMap<>();
+ groupThreshold = new HashMap<>();
if (sg == null)
{
sg.textColour = col;
}
- ap.paintAlignment(true);
+ ap.paintAlignment(false, false);
}
void colour2Changed(Color col)
sg.textColour2 = col;
}
- ap.paintAlignment(true);
+ ap.paintAlignment(false, false);
}
void thresholdChanged(int value)
sg.thresholdTextColour = value;
}
- ap.paintAlignment(true);
+ ap.paintAlignment(false, false);
}
void setGroupTextColour()
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.List;
import javax.swing.ButtonGroup;
import javax.swing.JMenuItem;
import javax.swing.JRadioButtonMenuItem;
+import javax.swing.event.InternalFrameAdapter;
+import javax.swing.event.InternalFrameEvent;
import org.jibble.epsgraphics.EpsGraphics2D;
buildAssociatedViewMenu();
- av.addPropertyChangeListener(new java.beans.PropertyChangeListener()
+ final PropertyChangeListener listener = addAlignmentListener();
+
+ /*
+ * remove listener when window is closed, so that this
+ * panel can be garbage collected
+ */
+ addInternalFrameListener(new InternalFrameAdapter()
+ {
+ @Override
+ public void internalFrameClosed(InternalFrameEvent evt)
+ {
+ if (av != null)
+ {
+ av.removePropertyChangeListener(listener);
+ }
+ }
+ });
+
+ TreeLoader tl = new TreeLoader(newTree, inputData);
+ tl.start();
+
+ }
+
+ /**
+ * @return
+ */
+ protected PropertyChangeListener addAlignmentListener()
+ {
+ final PropertyChangeListener listener = new PropertyChangeListener()
{
@Override
public void propertyChange(PropertyChangeEvent evt)
repaint();
}
}
- });
-
- TreeLoader tl = new TreeLoader(newTree, inputData);
- tl.start();
-
+ };
+ av.addPropertyChangeListener(listener);
+ return listener;
}
@Override
if (treeCanvas.applyToAllViews)
{
- final ArrayList<CommandI> commands = new ArrayList<CommandI>();
+ final ArrayList<CommandI> commands = new ArrayList<>();
for (AlignmentPanel ap : PaintRefresher
.getAssociatedPanels(av.getSequenceSetId()))
{
public CommandI sortAlignmentIn(AlignmentPanel ap)
{
+ // TODO: move to alignment view controller
AlignmentViewport viewport = ap.av;
SequenceI[] oldOrder = viewport.getAlignment().getSequencesArray();
AlignmentSorter.sortByTree(viewport.getAlignment(), tree);
CommandI undo;
undo = new OrderCommand("Tree Sort", oldOrder, viewport.getAlignment());
- ap.paintAlignment(true);
+ ap.paintAlignment(true, false);
return undo;
}
UserDefinedColours()
{
super();
- selectedButtons = new ArrayList<JButton>();
+ selectedButtons = new ArrayList<>();
}
void showFrame()
if (upperCaseButtons == null)
{
- upperCaseButtons = new ArrayList<JButton>();
+ upperCaseButtons = new ArrayList<>();
}
for (int i = 0; i < 20; i++)
if (lowerCaseButtons == null)
{
- lowerCaseButtons = new ArrayList<JButton>();
+ lowerCaseButtons = new ArrayList<>();
}
for (int i = 0; i < 20; i++)
@Override
protected void loadbutton_actionPerformed()
{
- upperCaseButtons = new ArrayList<JButton>();
- lowerCaseButtons = new ArrayList<JButton>();
+ upperCaseButtons = new ArrayList<>();
+ lowerCaseButtons = new ArrayList<>();
JalviewFileChooser chooser = new JalviewFileChooser("jc",
"Jalview User Colours");
protected void cancelButton_actionPerformed()
{
ap.alignFrame.changeColour(oldColourScheme);
- ap.paintAlignment(true);
+ ap.paintAlignment(true, true);
try
{
private ItemListener _handler;
- @Override
- protected void finalize() throws Throwable
- {
- _selectedviews = null;
- _handler = null;
- _allviews = null;
- super.finalize();
- }
-
/**
* create a new view selection menu. This menu has some standard entries
* (select all, invert selection), and a checkbox for every view. Mousing over
return tempStructFile.toString();
}
- /*
- * (non-Javadoc)
- *
- * @see java.lang.Object#finalize()
- */
- @Override
- protected void finalize() throws Throwable
- {
- source = null;
- alignFrame = null;
- viewport = null;
- super.finalize();
- }
-
}
error = false;
}
- @Override
- protected void finalize() throws Throwable
- {
- dataIn = null;
- super.finalize();
- }
-
}
}
}
}
- ap.paintAlignment(true);
+ ap.paintAlignment(true, false);
}
jvlite.setExecutor(this);
}
- @Override
- protected void finalize() throws Throwable
- {
- jvlite = null;
- executor = null;
- if (jsExecQueue != null)
- {
- jsExecQueue.clear();
- }
- jsExecQueue = null;
- super.finalize();
- }
-
private Vector jsExecQueue;
private Thread executor = null;
}
@Override
- public void finalize() throws Throwable
- {
- jvlite = null;
- super.finalize();
- }
-
- @Override
public void releaseReferences(Object svl)
{
*/
public class ScaleRenderer
{
+ /**
+ * Represents one major or minor scale mark
+ */
public final class ScaleMark
{
+ /**
+ * true for a major scale mark, false for minor
+ */
public final boolean major;
+ /**
+ * visible column position (0..) e.g. 19
+ */
public final int column;
+ /**
+ * text (if any) to show e.g. "20"
+ */
public final String text;
ScaleMark(boolean isMajor, int col, String txt)
column = col;
text = txt;
}
+
+ /**
+ * String representation for inspection when debugging only
+ */
+ @Override
+ public String toString()
+ {
+ return String.format("%s:%d:%s", major ? "major" : "minor", column,
+ text);
+ }
}
/**
- * calculate positions markers on the alignment ruler
+ * Calculates position markers on the alignment ruler
*
* @param av
* @param startx
- * left-most column in visible view
+ * left-most column in visible view (0..)
* @param endx
- * - right-most column in visible view
- * @return List of ScaleMark holding boolean: true/false for major/minor mark,
- * marker position in alignment column coords, a String to be rendered
- * at the position (or null)
+ * - right-most column in visible view (0..)
+ * @return
*/
public List<ScaleMark> calculateMarks(AlignViewportI av, int startx,
int endx)
scalestartx += 5;
}
List<ScaleMark> marks = new ArrayList<ScaleMark>();
- String string;
- int refN, iadj;
// todo: add a 'reference origin column' to set column number relative to
- for (int i = scalestartx; i < endx; i += 5)
+ for (int i = scalestartx; i <= endx; i += 5)
{
if (((i - refSp) % 10) == 0)
{
+ String text;
if (refSeq == null)
{
- iadj = av.getAlignment().getHiddenColumns()
+ int iadj = av.getAlignment().getHiddenColumns()
.adjustForHiddenColumns(i - 1) + 1;
- string = String.valueOf(iadj);
+ text = String.valueOf(iadj);
}
else
{
- iadj = av.getAlignment().getHiddenColumns()
+ int iadj = av.getAlignment().getHiddenColumns()
.adjustForHiddenColumns(i - 1);
- refN = refSeq.findPosition(iadj);
+ int refN = refSeq.findPosition(iadj);
// TODO show bounds if position is a gap
// - ie L--R -> "1L|2R" for
// marker
if (iadj < refStartI)
{
- string = String.valueOf(iadj - refStartI);
+ text = String.valueOf(iadj - refStartI);
}
else if (iadj > refEndI)
{
- string = "+" + String.valueOf(iadj - refEndI);
+ text = "+" + String.valueOf(iadj - refEndI);
}
else
{
- string = String.valueOf(refN) + refSeq.getCharAt(iadj);
+ text = String.valueOf(refN) + refSeq.getCharAt(iadj);
}
}
- marks.add(new ScaleMark(true, i - startx - 1, string));
+ marks.add(new ScaleMark(true, i - startx - 1, text));
}
else
{
return null;
}
- if (Comparison.isGap(seq.getCharAt(column)))
+ // column is 'base 1' but getCharAt is an array index (ie from 0)
+ if (Comparison.isGap(seq.getCharAt(column - 1)))
{
/*
* returning null allows the colour scheme to provide gap colour
}
/**
-<<<<<<< HEAD
-=======
- * Answers true if the feature belongs to a feature group which is not
- * currently displayed, else false
- *
- * @param sequenceFeature
- * @return
- */
- @Override
- protected boolean featureGroupNotShown(
- final SequenceFeature sequenceFeature)
- {
- return featureGroups != null && sequenceFeature.featureGroup != null
- && sequenceFeature.featureGroup.length() != 0
- && featureGroups.containsKey(sequenceFeature.featureGroup)
- && !featureGroups.get(sequenceFeature.featureGroup)
- .booleanValue();
- }
-
- /**
->>>>>>> refs/heads/develop
* Called when alignment in associated view has new/modified features to
* discover and display.
*
oldcs = av.getGlobalColourScheme();
if (av.getAlignment().getGroups() != null)
{
- oldgroupColours = new Hashtable<SequenceGroup, ColourSchemeI>();
+ oldgroupColours = new Hashtable<>();
for (SequenceGroup sg : ap.getAlignment().getGroups())
{
if (sg.getColourScheme() != null)
this.ap = ap;
adjusting = true;
- Vector<String> list = new Vector<String>();
+ Vector<String> list = new Vector<>();
int index = 1;
AlignmentAnnotation[] anns = av.getAlignment().getAlignmentAnnotation();
if (anns != null)
av.setGlobalColourScheme(rhc);
- ap.paintAlignment(true);
+ ap.paintAlignment(true, true);
}
}
static IdentityHashMap<StructureSelectionManagerProvider, StructureSelectionManager> instances;
- private List<StructureMapping> mappings = new ArrayList<StructureMapping>();
+ private List<StructureMapping> mappings = new ArrayList<>();
private boolean processSecondaryStructure = false;
private boolean addTempFacAnnot = false;
- private IProgressIndicator progressIndicator;
-
private SiftsClient siftsClient = null;
- private long progressSessionId;
-
/*
* Set of any registered mappings between (dataset) sequences.
*/
- private List<AlignedCodonFrame> seqmappings = new ArrayList<AlignedCodonFrame>();
+ private List<AlignedCodonFrame> seqmappings = new ArrayList<>();
- private List<CommandListener> commandListeners = new ArrayList<CommandListener>();
+ private List<CommandListener> commandListeners = new ArrayList<>();
- private List<SelectionListener> sel_listeners = new ArrayList<SelectionListener>();
+ private List<SelectionListener> sel_listeners = new ArrayList<>();
/**
* @return true if will try to use external services for processing secondary
* map between the PDB IDs (or structure identifiers) used by Jalview and the
* absolute filenames for PDB data that corresponds to it
*/
- Map<String, String> pdbIdFileName = new HashMap<String, String>();
+ Map<String, String> pdbIdFileName = new HashMap<>();
- Map<String, String> pdbFileNameId = new HashMap<String, String>();
+ Map<String, String> pdbFileNameId = new HashMap<>();
public void registerPDBFile(String idForFile, String absoluteFile)
{
}
if (instances == null)
{
- instances = new java.util.IdentityHashMap<StructureSelectionManagerProvider, StructureSelectionManager>();
+ instances = new java.util.IdentityHashMap<>();
}
StructureSelectionManager instance = instances.get(context);
if (instance == null)
* @return null or the structure data parsed as a pdb file
*/
synchronized public StructureFile setMapping(SequenceI[] sequence,
- String[] targetChains, String pdbFile, DataSourceType protocol)
+ String[] targetChains, String pdbFile, DataSourceType protocol,
+ IProgressIndicator progress)
{
- return setMapping(true, sequence, targetChains, pdbFile, protocol);
+ return computeMapping(true, sequence, targetChains, pdbFile, protocol,
+ progress);
}
/**
SequenceI[] sequenceArray, String[] targetChainIds,
String pdbFile, DataSourceType sourceType)
{
+ return computeMapping(forStructureView, sequenceArray, targetChainIds,
+ pdbFile, sourceType, null);
+ }
+
+ synchronized public StructureFile computeMapping(
+ boolean forStructureView, SequenceI[] sequenceArray,
+ String[] targetChainIds, String pdbFile, DataSourceType sourceType,
+ IProgressIndicator progress)
+ {
+ long progressSessionId = System.currentTimeMillis() * 3;
/*
* There will be better ways of doing this in the future, for now we'll use
* the tried and tested MCview pdb mapping
pdbFile = "INLINE" + pdb.getId();
}
- List<StructureMapping> seqToStrucMapping = new ArrayList<StructureMapping>();
+ List<StructureMapping> seqToStrucMapping = new ArrayList<>();
if (isMapUsingSIFTs && seq.isProtein())
{
- setProgressBar(null);
- setProgressBar(MessageManager
- .getString("status.obtaining_mapping_with_sifts"));
+ if (progress!=null) {
+ progress.setProgressBar(MessageManager
+ .getString("status.obtaining_mapping_with_sifts"),
+ progressSessionId);
+ }
jalview.datamodel.Mapping sqmpping = maxAlignseq
.getMappingFromS1(false);
if (targetChainId != null && !targetChainId.trim().isEmpty())
}
else
{
- List<StructureMapping> foundSiftsMappings = new ArrayList<StructureMapping>();
+ List<StructureMapping> foundSiftsMappings = new ArrayList<>();
for (PDBChain chain : pdb.getChains())
{
try
}
else
{
- setProgressBar(null);
- setProgressBar(MessageManager
- .getString("status.obtaining_mapping_with_nw_alignment"));
+ if (progress != null)
+ {
+ progress.setProgressBar(MessageManager
+ .getString("status.obtaining_mapping_with_nw_alignment"),
+ progressSessionId);
+ }
StructureMapping nwMapping = getNWMappings(seq, pdbFile, maxChainId,
maxChain, pdb, maxAlignseq);
seqToStrucMapping.add(nwMapping);
ds.addPDBId(maxChain.sequence.getAllPDBEntries().get(0));
-
}
-
if (forStructureView)
{
mappings.addAll(seqToStrucMapping);
}
+ if (progress != null)
+ {
+ progress.setProgressBar(null, progressSessionId);
+ }
}
return pdb;
}
.getMappingFromS1(false);
maxChain.transferRESNUMFeatures(seq, null);
- HashMap<Integer, int[]> mapping = new HashMap<Integer, int[]>();
+ HashMap<Integer, int[]> mapping = new HashMap<>();
int resNum = -10000;
int index = 0;
char insCode = ' ';
* Remove mappings to the closed listener's PDB files, but first check if
* another listener is still interested
*/
- List<String> pdbs = new ArrayList<String>(Arrays.asList(pdbfiles));
+ List<String> pdbs = new ArrayList<>(Arrays.asList(pdbfiles));
StructureListener sl;
for (int i = 0; i < listeners.size(); i++)
*/
if (pdbs.size() > 0)
{
- List<StructureMapping> tmp = new ArrayList<StructureMapping>();
+ List<StructureMapping> tmp = new ArrayList<>();
for (StructureMapping sm : mappings)
{
if (!pdbs.contains(sm.pdbfile))
&& sm.pdbchain.equals(atom.getChain()))
{
int indexpos = sm.getSeqPos(atom.getPdbResNum());
- if (lastipos != indexpos && lastseq != sm.sequence)
+ if (lastipos != indexpos || lastseq != sm.sequence)
{
results.addResult(sm.sequence, indexpos, indexpos);
lastipos = indexpos;
return;
}
int atomNo;
- List<AtomSpec> atoms = new ArrayList<AtomSpec>();
+ List<AtomSpec> atoms = new ArrayList<>();
for (StructureMapping sm : mappings)
{
if (sm.sequence == seq || sm.sequence == seq.getDatasetSequence()
public StructureMapping[] getMapping(String pdbfile)
{
- List<StructureMapping> tmp = new ArrayList<StructureMapping>();
+ List<StructureMapping> tmp = new ArrayList<>();
for (StructureMapping sm : mappings)
{
if (sm.pdbfile.equals(pdbfile))
}
}
- Vector<AlignmentViewPanelListener> view_listeners = new Vector<AlignmentViewPanelListener>();
+ Vector<AlignmentViewPanelListener> view_listeners = new Vector<>();
public synchronized void sendViewPosition(
jalview.api.AlignmentViewPanel source, int startRes, int endRes,
return null;
}
- public IProgressIndicator getProgressIndicator()
- {
- return progressIndicator;
- }
-
- public void setProgressIndicator(IProgressIndicator progressIndicator)
- {
- this.progressIndicator = progressIndicator;
- }
-
- public long getProgressSessionId()
- {
- return progressSessionId;
- }
-
- public void setProgressSessionId(long progressSessionId)
- {
- this.progressSessionId = progressSessionId;
- }
-
- public void setProgressBar(String message)
- {
- if (progressIndicator == null)
- {
- return;
- }
- progressIndicator.setProgressBar(message, progressSessionId);
- }
-
public List<AlignedCodonFrame> getSequenceMappings()
{
return seqmappings;
*/
private void upgradeOldLinks(HashMap<String, UrlLink> urls)
{
+ boolean upgrade = false;
// upgrade old SRS link
if (urls.containsKey(SRS_LABEL))
{
urls.remove(SRS_LABEL);
+ upgrade = true;
+ }
+ // upgrade old EBI link - easier just to remove and re-add than faffing
+ // around checking exact url
+ if (urls.containsKey(UrlConstants.DEFAULT_LABEL))
+ {
+ // note because this is called separately for selected and nonselected
+ // urls, the default url will not always be present
+ urls.remove(UrlConstants.DEFAULT_LABEL);
+ upgrade = true;
+ }
+ if (upgrade)
+ {
UrlLink link = new UrlLink(UrlConstants.DEFAULT_STRING);
link.setLabel(UrlConstants.DEFAULT_LABEL);
urls.put(UrlConstants.DEFAULT_LABEL, link);
}
return copy;
}
+
+ /**
+ * Removes the specified number of positions from the given ranges. Provided
+ * to allow a stop codon to be stripped from a CDS sequence so that it matches
+ * the peptide translation length.
+ *
+ * @param positions
+ * @param ranges
+ * a list of (single) [start, end] ranges
+ * @return
+ */
+ public static void removeEndPositions(int positions,
+ List<int[]> ranges)
+ {
+ int toRemove = positions;
+ Iterator<int[]> it = new ReverseListIterator<>(ranges);
+ while (toRemove > 0)
+ {
+ int[] endRange = it.next();
+ if (endRange.length != 2)
+ {
+ /*
+ * not coded for [start1, end1, start2, end2, ...]
+ */
+ System.err
+ .println("MappingUtils.removeEndPositions doesn't handle multiple ranges");
+ return;
+ }
+
+ int length = endRange[1] - endRange[0] + 1;
+ if (length <= 0)
+ {
+ /*
+ * not coded for a reverse strand range (end < start)
+ */
+ System.err
+ .println("MappingUtils.removeEndPositions doesn't handle reverse strand");
+ return;
+ }
+ if (length > toRemove)
+ {
+ endRange[1] -= toRemove;
+ toRemove = 0;
+ }
+ else
+ {
+ toRemove -= length;
+ it.remove();
+ }
+ }
+ }
}
*/
public class Platform
{
- private static Boolean isAMac = null;
+ private static Boolean isAMac = null, isWindows = null;
private static Boolean isHeadless = null;
{
isAMac = System.getProperty("os.name").indexOf("Mac") > -1;
}
+
return isAMac.booleanValue();
}
+ /**
+ * Check if we are on a Microsoft plaform...
+ *
+ * @return true if we have to cope with another platform variation
+ */
+ public static boolean isWindows()
+ {
+ if (isWindows == null)
+ {
+ isWindows = System.getProperty("os.name").indexOf("Win") > -1;
+ }
+ return isWindows.booleanValue();
+ }
+
+ /**
+ *
+ * @return true if we are running in non-interactive no UI mode
+ */
public static boolean isHeadless()
{
if (isHeadless == null)
* Default sequence URL link string for EMBL-EBI search
*/
public static final String DEFAULT_STRING = DEFAULT_LABEL
- + "|http://www.ebi.ac.uk/ebisearch/search.ebi?db=allebi&query=$SEQUENCE_ID$";
+ + "|https://www.ebi.ac.uk/ebisearch/search.ebi?db=allebi&query=$SEQUENCE_ID$";
+
+ private static final String COLON = ":";
/*
* not instantiable
private UrlConstants()
{
}
+
+ public static boolean isDefaultString(String link)
+ {
+ String sublink = link.substring(link.indexOf(COLON) + 1);
+ String subdefault = DEFAULT_STRING
+ .substring(DEFAULT_STRING.indexOf(COLON) + 1);
+ return sublink.equalsIgnoreCase(subdefault);
+ }
}
import jalview.analysis.AnnotationSorter.SequenceAnnotationOrder;
import jalview.analysis.Conservation;
+import jalview.analysis.TreeModel;
import jalview.api.AlignCalcManagerI;
import jalview.api.AlignViewportI;
import jalview.api.AlignmentViewPanel;
import jalview.datamodel.AlignmentI;
import jalview.datamodel.AlignmentView;
import jalview.datamodel.Annotation;
-import jalview.datamodel.CigarArray;
import jalview.datamodel.ColumnSelection;
import jalview.datamodel.HiddenColumns;
import jalview.datamodel.HiddenSequences;
public abstract class AlignmentViewport
implements AlignViewportI, CommandListener, VamsasSource
{
- final protected ViewportRanges ranges;
+ protected ViewportRanges ranges;
protected ViewStyleI viewStyle = new ViewStyle();
groupConsensus = null;
groupConservation = null;
hconsensus = null;
+ hconservation = null;
hcomplementConsensus = null;
- // colour scheme may hold reference to consensus
- residueShading = null;
- // TODO remove listeners from changeSupport?
+ gapcounts = null;
+ calculator = null;
+ residueShading = null; // may hold a reference to Consensus
changeSupport = null;
+ ranges = null;
+ currentTree = null;
+ selectionGroup = null;
setAlignment(null);
}
public void removePropertyChangeListener(
java.beans.PropertyChangeListener listener)
{
- changeSupport.removePropertyChangeListener(listener);
+ if (changeSupport != null)
+ {
+ changeSupport.removePropertyChangeListener(listener);
+ }
}
/**
}
@Override
- public CigarArray getViewAsCigars(boolean selectedRegionOnly)
- {
- return new CigarArray(alignment, alignment.getHiddenColumns(),
- (selectedRegionOnly ? selectionGroup : null));
- }
-
- @Override
public jalview.datamodel.AlignmentView getAlignmentView(
boolean selectedOnly)
{
*/
private SearchResultsI searchResults = null;
+ protected TreeModel currentTree = null;
+
@Override
public boolean hasSearchResults()
{
+ ((ignoreGapsInConsensusCalculation) ? " without gaps" : ""));
return sq;
}
+
+ @Override
+ public void setCurrentTree(TreeModel tree)
+ {
+ currentTree = tree;
+ }
+
+ @Override
+ public TreeModel getCurrentTree()
+ {
+ return currentTree;
+ }
}
*/
public boolean scrollUp(boolean up)
{
+ /*
+ * if in unwrapped mode, scroll up or down one sequence row;
+ * if in wrapped mode, scroll by one visible width of columns
+ */
if (up)
{
- if (startSeq < 1)
+ if (wrappedMode)
{
- return false;
+ pageUp();
+ }
+ else
+ {
+ if (startSeq < 1)
+ {
+ return false;
+ }
+ setStartSeq(startSeq - 1);
}
-
- setStartSeq(startSeq - 1);
}
else
{
- if (endSeq >= getVisibleAlignmentHeight() - 1)
+ if (wrappedMode)
{
- return false;
+ pageDown();
+ }
+ else
+ {
+ if (endSeq >= getVisibleAlignmentHeight() - 1)
+ {
+ return false;
+ }
+ setStartSeq(startSeq + 1);
}
-
- setStartSeq(startSeq + 1);
}
return true;
}
AnnotationProviderI counter)
{
super(viewport, panel);
- ourAnnots = new ArrayList<AlignmentAnnotation>();
+ ourAnnots = new ArrayList<>();
this.counter = counter;
calcMan.registerWorker(this);
}
if (ap != null)
{
ap.adjustAnnotationHeight();
- ap.paintAlignment(true);
+ // TODO: only need to update colour and geometry if panel height changes
+ // and view is coloured by annotation, and the annotation is actually
+ // changed!
+ ap.paintAlignment(true, true);
}
}
AlignmentViewPanel panel, FeatureSetCounterI counter)
{
super(viewport, panel);
- ourAnnots = new ArrayList<AlignmentAnnotation>();
+ ourAnnots = new ArrayList<>();
this.counter = counter;
calcMan.registerWorker(this);
}
{
ap.adjustAnnotationHeight();
}
- ap.paintAlignment(true);
+ ap.paintAlignment(true, true);
}
}
{
if (ap != null)
{
- ap.paintAlignment(false);
+ ap.paintAlignment(false, false);
}
Thread.sleep(200);
} catch (Exception ex)
if (ap != null)
{
- ap.paintAlignment(true);
+ ap.paintAlignment(true, true);
}
} catch (OutOfMemoryError error)
{
abortAndDestroy();
return;
}
- List<AlignmentAnnotation> ourAnnot = new ArrayList<AlignmentAnnotation>();
+ List<AlignmentAnnotation> ourAnnot = new ArrayList<>();
AlignmentI alignment = alignViewport.getAlignment();
conservation = alignViewport.getAlignmentConservationAnnotation();
quality = alignViewport.getAlignmentQualityAnnot();
}
if (ap != null)
{
- ap.paintAlignment(true);
+ ap.paintAlignment(true, true);
}
}
calcMan.workerComplete(this);
if (ap != null)
{
- ap.paintAlignment(true);
+ ap.paintAlignment(true, true);
}
}
boolean useJDasMultiThread)
{
this.useJDASMultiThread = useJDasMultiThread;
- this.selectedSources = new ArrayList<jalviewSourceI>();
+ this.selectedSources = new ArrayList<>();
// filter both sequences and sources to eliminate duplicates
for (jalviewSourceI src : selectedSources2)
{
FeaturesClientMultipleSources fc = new FeaturesClientMultipleSources();
fc.setConnProps(sourceRegistry.getSessionHandler());
// Now sending requests one at a time to each server
- ArrayList<jalviewSourceI> srcobj = new ArrayList<jalviewSourceI>();
- ArrayList<String> src = new ArrayList<String>();
- List<List<String>> ids = new ArrayList<List<String>>();
- List<List<DBRefEntry>> idobj = new ArrayList<List<DBRefEntry>>();
- List<Map<String, SequenceI>> sqset = new ArrayList<Map<String, SequenceI>>();
+ ArrayList<jalviewSourceI> srcobj = new ArrayList<>();
+ ArrayList<String> src = new ArrayList<>();
+ List<List<String>> ids = new ArrayList<>();
+ List<List<DBRefEntry>> idobj = new ArrayList<>();
+ List<Map<String, SequenceI>> sqset = new ArrayList<>();
for (jalviewSourceI _sr : selectedSources)
{
- Map<String, SequenceI> slist = new HashMap<String, SequenceI>();
- List<DBRefEntry> idob = new ArrayList<DBRefEntry>();
- List<String> qset = new ArrayList<String>();
+ Map<String, SequenceI> slist = new HashMap<>();
+ List<DBRefEntry> idob = new ArrayList<>();
+ List<String> qset = new ArrayList<>();
for (SequenceI seq : sequences)
{
sqset.add(slist);
}
}
- Map<String, Map<List<String>, Exception>> errors = new HashMap<String, Map<List<String>, Exception>>();
- Map<String, Map<List<String>, DasGFFAdapter>> results = new HashMap<String, Map<List<String>, DasGFFAdapter>>();
+ Map<String, Map<List<String>, Exception>> errors = new HashMap<>();
+ Map<String, Map<List<String>, DasGFFAdapter>> results = new HashMap<>();
if (!useJDASMultiThread)
{
Iterator<String> sources = src.iterator();
if (ers == null)
{
results.put(source,
- ers = new HashMap<List<String>, DasGFFAdapter>());
+ ers = new HashMap<>());
}
ers.put(qid, dga);
} catch (Exception ex)
if (ers == null)
{
errors.put(source,
- ers = new HashMap<List<String>, Exception>());
+ ers = new HashMap<>());
}
ers.put(qid, ex);
}
Map<List<String>, DasGFFAdapter> results,
Map<List<String>, Exception> errors)
{
- Set<SequenceI> sequences = new HashSet<SequenceI>();
+ Set<SequenceI> sequences = new HashSet<>();
String source = jvsource.getSourceURL();
// process features
DasGFFAdapter result = (results == null) ? null : results.get(ids);
if (seq == af.getViewport().getAlignment().getSequenceAt(index)
.getDatasetSequence())
{
- af.alignPanel.paintAlignment(true);
+ af.alignPanel.paintAlignment(true, true);
index = end;
break;
}
// TODO: minimal list of DAS queries to make by querying with untyped ID if
// distinct from any typed IDs
- List<DBRefEntry> ids = new ArrayList<DBRefEntry>();
- List<String> qstring = new ArrayList<String>();
+ List<DBRefEntry> ids = new ArrayList<>();
+ List<String> qstring = new ArrayList<>();
boolean dasCoordSysFound = false;
if (uprefs != null)
import jalview.datamodel.xdb.uniprot.UniprotEntry;
import jalview.datamodel.xdb.uniprot.UniprotFeature;
import jalview.datamodel.xdb.uniprot.UniprotFile;
-import jalview.ws.ebi.EBIFetchClient;
import jalview.ws.seqfetcher.DbSourceProxyImpl;
-import java.io.File;
-import java.io.FileReader;
+import java.io.InputStream;
+import java.io.InputStreamReader;
import java.io.Reader;
import java.net.URL;
+import java.net.URLConnection;
import java.util.ArrayList;
import java.util.Vector;
queries = queries.toUpperCase().replaceAll(
"(UNIPROT\\|?|UNIPROT_|UNIREF\\d+_|UNIREF\\d+\\|?)", "");
AlignmentI al = null;
- EBIFetchClient ebi = new EBIFetchClient();
- // uniprotxml parameter required since december 2007
- // uniprotkb dbname changed introduced december 2008
- File file = ebi.fetchDataAsFile("uniprotkb:" + queries, "uniprotxml",
- "xml");
+
+ String downloadstring = "http://www.uniprot.org/uniprot/" + queries
+ + ".xml";
+ URL url = null;
+ URLConnection urlconn = null;
+
+ url = new URL(downloadstring);
+ urlconn = url.openConnection();
+ InputStream istr = urlconn.getInputStream();
Vector<UniprotEntry> entries = getUniprotEntries(
- new FileReader(file));
+ new InputStreamReader(istr, "UTF-8"));
if (entries != null)
{
- ArrayList<SequenceI> seqs = new ArrayList<SequenceI>();
+ ArrayList<SequenceI> seqs = new ArrayList<>();
for (UniprotEntry entry : entries)
{
seqs.add(uniprotEntryToSequenceI(entry));
return al;
} catch (Exception e)
{
- stopQuery();
throw (e);
+ } finally
+ {
+ stopQuery();
}
}
sequence.setDescription(getUniprotEntryDescription(entry));
final String dbVersion = getDbVersion();
- ArrayList<DBRefEntry> dbRefs = new ArrayList<DBRefEntry>();
+ ArrayList<DBRefEntry> dbRefs = new ArrayList<>();
for (String accessionId : entry.getAccession())
{
DBRefEntry dbRef = new DBRefEntry(DBRefSource.UNIPROT, dbVersion,
dbRefs.add(dbRef);
}
- Vector<PDBEntry> onlyPdbEntries = new Vector<PDBEntry>();
+ Vector<PDBEntry> onlyPdbEntries = new Vector<>();
for (PDBEntry pdb : entry.getDbReference())
{
DBRefEntry dbr = new DBRefEntry();
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
+import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
{
URL rcall = new URL(url);
- InputStream is = new BufferedInputStream(rcall.openStream());
+ HttpURLConnection conn = (HttpURLConnection) rcall.openConnection();
+ int responseCode = conn.getResponseCode();
+ if (responseCode != 200)
+ {
+ System.err.println("Warning: response code " + responseCode
+ + " for " + url);
+ }
+ InputStream is = new BufferedInputStream(conn.getInputStream());
if (outFile != null)
{
FileOutputStream fio = new FileOutputStream(outFile);
if (database.equalsIgnoreCase(DBRefSource.EMBL)
|| database.equalsIgnoreCase(DBRefSource.EMBLCDS))
{
- url = "http://www.ebi.ac.uk/ena/data/view/" + ids.toLowerCase()
+ url = "https://www.ebi.ac.uk/ena/data/view/" + ids.toLowerCase()
+ (format != null ? "&" + format : "");
}
else
{
- url = "http://www.ebi.ac.uk/Tools/dbfetch/dbfetch/"
+ url = "https://www.ebi.ac.uk/Tools/dbfetch/dbfetch/"
+ database.toLowerCase() + "/" + ids.toLowerCase()
+ (format != null ? "/" + format : "");
}
{
// TODO: turn this into some kind of configuration file that's a bit easier
// to edit
- featureMap = new HashMap<String, Map<String, String[]>>();
+ featureMap = new HashMap<>();
Map<String, String[]> fmap;
featureMap.put(compbio.ws.client.Services.IUPredWS.toString(),
- fmap = new HashMap<String, String[]>());
+ fmap = new HashMap<>());
fmap.put("Glob",
new String[]
{ "Globular Domain", "Predicted globular domain" });
featureMap.put(compbio.ws.client.Services.JronnWS.toString(),
- fmap = new HashMap<String, String[]>());
+ fmap = new HashMap<>());
featureMap.put(compbio.ws.client.Services.DisemblWS.toString(),
- fmap = new HashMap<String, String[]>());
+ 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<String, String[]>());
+ fmap = new HashMap<>());
fmap.put("GlobDoms",
new String[]
{ "Globular Domain", "Predicted globular domain" });
new String[]
{ "Protein Disorder", "Probable unstructured peptide region" });
Map<String, Map<String, Object>> amap;
- annotMap = new HashMap<String, Map<String, Map<String, Object>>>();
+ annotMap = new HashMap<>();
annotMap.put(compbio.ws.client.Services.GlobPlotWS.toString(),
- amap = new HashMap<String, Map<String, Object>>());
+ 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.put("RawScore", new HashMap<String, Object>());
amap.get("RawScore").put(INVISIBLE, INVISIBLE);
annotMap.put(compbio.ws.client.Services.DisemblWS.toString(),
- amap = new HashMap<String, Map<String, Object>>());
+ 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("REM465").put(RANGE, new float[] { 0, 1 });
annotMap.put(compbio.ws.client.Services.IUPredWS.toString(),
- amap = new HashMap<String, Map<String, Object>>());
+ 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("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<String, Map<String, Object>>());
+ 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 });
Map<String, Map<String, Object>> annotTypeMap = annotMap
.get(service.serviceType);
boolean dispFeatures = false;
- Map<String, Object> fc = new Hashtable<String, Object>();
- List<AlignmentAnnotation> ourAnnot = new ArrayList<AlignmentAnnotation>();
+ Map<String, Object> fc = new Hashtable<>();
+ List<AlignmentAnnotation> ourAnnot = new ArrayList<>();
/**
* grouping for any annotation rows created
*/
// only do this if the alignFrame is currently showing this view.
af.setShowSeqFeatures(true);
}
- ap.paintAlignment(true);
}
if (ourAnnot.size() > 0)
{
// new alignment annotation rows created.
updateOurAnnots(ourAnnot);
ap.adjustAnnotationHeight();
+ ap.paintAlignment(true, true);
}
}
}
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;
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
{
guiProgress.setProgressBar("", progressId);
}
- ap.paintAlignment(true);
+ // TODO: may not need to paintAlignment again !
+ ap.paintAlignment(false, false);
}
if (msg.length() > 0)
{
protected boolean checkDone()
{
calcMan.notifyStart(this);
- ap.paintAlignment(false);
+ ap.paintAlignment(false, false);
while (!calcMan.notifyWorking(this))
{
if (calcMan.isWorking(this))
{
if (ap != null)
{
- ap.paintAlignment(false);
+ ap.paintAlignment(false, false);
}
Thread.sleep(200);
{
try
{
- Closeable svc = (Closeable) service;
- service = null;
- svc.close();
- } catch (Exception e)
+ ((Closeable) service).close();
+ } catch (Throwable t)
{
+ // ignore
}
- ;
}
super.finalize();
}
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;
/**
- * Generates, and outputs in Fasta format, a random DNA alignment for given
+ * Generates, and outputs in Fasta format, a random peptide or nucleotide alignment for given
* sequence length and count. Will regenerate the same alignment each time if
* the same random seed is used (so may be used for reproducible unit tests).
* Not guaranteed to reproduce the same results between versions, as the rules
* may get tweaked to produce more 'realistic' results.
*
- * Arguments:
- * <ul>
- * <li>length (number of bases in each sequence)</li>
- * <li>height (number of sequences)</li>
- * <li>a whole number random seed</li>
- * <li>percentage of gaps to include (0-100)</li>
- * <li>percentage chance of variation of each position (0-100)</li>
- * </ul>
- *
* @author gmcarstairs
- *
*/
public class AlignmentGenerator
{
- @BeforeClass(alwaysRun = true)
- public void setUpJvOptionPane()
- {
- JvOptionPane.setInteractiveMode(false);
- JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
- }
-
private static final char GAP = '-';
private static final char ZERO = '0';
private Random random;
+ private PrintStream ps;
/**
- * Outputs a DNA 'alignment' where each position is a random choice from
- * 'GTCA-'.
+ * Outputs a pseudo-randomly generated nucleotide or peptide alignment
+ * Arguments:
+ * <ul>
+ * <li>n (for nucleotide) or p (for peptide)</li>
+ * <li>length (number of bases in each sequence)</li>
+ * <li>height (number of sequences)</li>
+ * <li>a whole number random seed</li>
+ * <li>percentage of gaps to include (0-100)</li>
+ * <li>percentage chance of variation of each position (0-100)</li>
+ * <li>(optional) path to a file to write the alignment to</li>
+ * </ul>
+ *
*
* @param args
+ * @throws FileNotFoundException
*/
- public static void main(String[] args)
+ public static void main(String[] args) throws FileNotFoundException
{
- if (args.length != 6)
+ if (args.length != 6 && args.length != 7)
{
usage();
return;
}
+
+ PrintStream ps = System.out;
+ if (args.length == 7)
+ {
+ ps = new PrintStream(new File(args[6]));
+ }
+
boolean nucleotide = args[0].toLowerCase().startsWith("n");
int width = Integer.parseInt(args[1]);
int height = Integer.parseInt(args[2]);
long randomSeed = Long.valueOf(args[3]);
int gapPercentage = Integer.valueOf(args[4]);
int changePercentage = Integer.valueOf(args[5]);
- AlignmentI al = new AlignmentGenerator(nucleotide).generate(width,
- height,
- randomSeed, gapPercentage, changePercentage);
- System.out.println("; " + height + " sequences of " + width
+ ps.println("; " + height + " sequences of " + width
+ " bases with " + gapPercentage + "% gaps and "
+ changePercentage + "% mutations (random seed = " + randomSeed
+ ")");
- System.out.println(new FastaFile().print(al.getSequencesArray(), true));
+
+ new AlignmentGenerator(nucleotide, ps).generate(width, height,
+ randomSeed, gapPercentage, changePercentage);
+
+ if (ps != System.out)
+ {
+ ps.close();
+ }
}
/**
- * Print parameter help.
+ * Prints parameter help
*/
private static void usage()
{
System.out.println("Usage:");
System.out.println("arg0: n (for nucleotide) or p (for peptide)");
System.out.println("arg1: number of (non-gap) bases per sequence");
- System.out.println("arg2: number sequences");
+ System.out.println("arg2: number of sequences");
System.out
.println("arg3: an integer as random seed (same seed = same results)");
System.out.println("arg4: percentage of gaps to (randomly) generate");
System.out
.println("arg5: percentage of 'mutations' to (randomly) generate");
+ System.out
+ .println("arg6: (optional) path to output file (default is sysout)");
System.out.println("Example: AlignmentGenerator n 12 15 387 10 5");
System.out
.println("- 15 nucleotide sequences of 12 bases each, approx 10% gaps and 5% mutations, random seed = 387");
}
/**
- * Constructor that sets nucleotide or peptide symbol set
+ * Constructor that sets nucleotide or peptide symbol set, and also writes the
+ * generated alignment to sysout
*/
public AlignmentGenerator(boolean nuc)
{
- BASES = nuc ? NUCS : PEPS;
+ this(nuc, System.out);
+ }
+
+ /**
+ * Constructor that sets nucleotide or peptide symbol set, and also writes the
+ * generated alignment to the specified output stream (if not null). This can
+ * be used to write the alignment to a file or sysout.
+ */
+ public AlignmentGenerator(boolean nucleotide, PrintStream printStream)
+ {
+ BASES = nucleotide ? NUCS : PEPS;
+ ps = printStream;
}
/**
- * Outputs a DNA 'alignment' of given width and height, where each position is
- * a random choice from 'GTCA-'.
+ * Outputs an 'alignment' of given width and height, where each position is a
+ * random choice from the symbol alphabet, or - for gap
*
* @param width
* @param height
seqno + 1, width, changePercentage);
}
AlignmentI al = new Alignment(seqs);
+
+ if (ps != null)
+ {
+ ps.println(new FastaFile().print(al.getSequencesArray(), true));
+ }
+
return al;
}
assertEquals(s_as3, uas3.getSequenceAsString());
}
+ /**
+ * Tests for the method that maps nucleotide to protein based on CDS features
+ */
+ @Test(groups = "Functional")
+ public void testMapCdsToProtein()
+ {
+ SequenceI peptide = new Sequence("pep", "KLQ");
+
+ /*
+ * Case 1: CDS 3 times length of peptide
+ * NB method only checks lengths match, not translation
+ */
+ SequenceI dna = new Sequence("dna", "AACGacgtCTCCT");
+ dna.createDatasetSequence();
+ dna.addSequenceFeature(new SequenceFeature("CDS", "", 1, 4, null));
+ dna.addSequenceFeature(new SequenceFeature("CDS", "", 9, 13, null));
+ MapList ml = AlignmentUtils.mapCdsToProtein(dna, peptide);
+ assertEquals(3, ml.getFromRatio());
+ assertEquals(1, ml.getToRatio());
+ assertEquals("[[1, 3]]",
+ Arrays.deepToString(ml.getToRanges().toArray()));
+ assertEquals("[[1, 4], [9, 13]]",
+ Arrays.deepToString(ml.getFromRanges().toArray()));
+
+ /*
+ * Case 2: CDS 3 times length of peptide + stop codon
+ * (note code does not currently check trailing codon is a stop codon)
+ */
+ dna = new Sequence("dna", "AACGacgtCTCCTTGA");
+ dna.createDatasetSequence();
+ dna.addSequenceFeature(new SequenceFeature("CDS", "", 1, 4, null));
+ dna.addSequenceFeature(new SequenceFeature("CDS", "", 9, 16, null));
+ ml = AlignmentUtils.mapCdsToProtein(dna, peptide);
+ assertEquals(3, ml.getFromRatio());
+ assertEquals(1, ml.getToRatio());
+ assertEquals("[[1, 3]]",
+ Arrays.deepToString(ml.getToRanges().toArray()));
+ assertEquals("[[1, 4], [9, 13]]",
+ Arrays.deepToString(ml.getFromRanges().toArray()));
+
+ /*
+ * Case 3: CDS not 3 times length of peptide - no mapping is made
+ */
+ dna = new Sequence("dna", "AACGacgtCTCCTTG");
+ dna.createDatasetSequence();
+ dna.addSequenceFeature(new SequenceFeature("CDS", "", 1, 4, null));
+ dna.addSequenceFeature(new SequenceFeature("CDS", "", 9, 15, null));
+ ml = AlignmentUtils.mapCdsToProtein(dna, peptide);
+ assertNull(ml);
+
+ /*
+ * Case 4: incomplete start codon corresponding to X in peptide
+ */
+ dna = new Sequence("dna", "ACGacgtCTCCTTGG");
+ dna.createDatasetSequence();
+ SequenceFeature sf = new SequenceFeature("CDS", "", 1, 3, null);
+ sf.setPhase("2"); // skip 2 positions (AC) to start of next codon (GCT)
+ dna.addSequenceFeature(sf);
+ dna.addSequenceFeature(new SequenceFeature("CDS", "", 8, 15, null));
+ peptide = new Sequence("pep", "XLQ");
+ ml = AlignmentUtils.mapCdsToProtein(dna, peptide);
+ assertEquals("[[2, 3]]",
+ Arrays.deepToString(ml.getToRanges().toArray()));
+ assertEquals("[[3, 3], [8, 12]]",
+ Arrays.deepToString(ml.getFromRanges().toArray()));
+ }
+
}
s2 = new Sequence("Seq2", "ASDFA");
s2.setStart(5);
s2.setEnd(9);
- s3 = new Sequence("Seq1", "SDFAQQQSSS");
+ s3 = new Sequence("Seq3", "SDFAQQQSSS");
}
};
as.printAlignment(ps);
- String expected = "Score = 320.0\nLength of alignment = 10\nSequence Seq1 : 3 - 18 (Sequence length = 14)\nSequence Seq1 : 1 - 10 (Sequence length = 10)\n\n"
- + "Seq1 SDFAQQQRRR\n"
- + " ||||||| \n"
- + "Seq1 SDFAQQQSSS\n\n" + "Percentage ID = 70.00\n";
+ String expected = "Score = 320.0\nLength of alignment = 10\nSequence Seq1/4-13 (Sequence length = 14)\nSequence Seq3/1-10 (Sequence length = 10)\n\n"
+ + "Seq1/4-13 SDFAQQQRRR\n"
+ + " ||||||| \n"
+ + "Seq3/1-10 SDFAQQQSSS\n\n" + "Percentage ID = 70.00\n\n";
assertEquals(expected, baos.toString());
}
}
--- /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.datamodel;
+
+import static org.testng.Assert.assertEquals;
+
+import jalview.gui.JvOptionPane;
+
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+public class CigarArrayTest
+{
+ @BeforeClass(alwaysRun = true)
+ public void setUpJvOptionPane()
+ {
+ JvOptionPane.setInteractiveMode(false);
+ JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+ }
+
+ @Test(groups = "Functional")
+ public void testConstructor()
+ {
+ SequenceI seq1 = new Sequence("sq1",
+ "ASFDDABACBACBACBACBACBACBABCABCBACBABCAB");
+ Sequence seq2 = new Sequence("sq2",
+ "TTTTTTACBCBABCABCABCABCBACBACBABCABCABCBA");
+
+ // construct alignment
+ AlignmentI al = new Alignment(new SequenceI[] { seq1, seq2 });
+
+ // hide columns
+ HiddenColumns hc = new HiddenColumns();
+ hc.hideColumns(3, 6);
+ hc.hideColumns(16, 20);
+
+ // select group
+ SequenceGroup sg1 = new SequenceGroup();
+ sg1.addSequence(seq1, false);
+ sg1.setStartRes(2);
+ sg1.setEndRes(23);
+
+ // Cigar array meanings:
+ // M = match
+ // D = deletion
+ // I = insertion
+ // number preceding M/D/I is the number of residues which
+ // match/are deleted/are inserted
+ // In the CigarArray constructor only matches or deletions are created, as
+ // we are comparing a sequence to its own subsequence (the group) + hidden
+ // columns.
+
+ // no hidden columns case
+ CigarArray cig = new CigarArray(al, null, sg1);
+ String result = cig.getCigarstring();
+ assertEquals(result, "22M");
+
+ cig = new CigarArray(al, hc, sg1);
+ result = cig.getCigarstring();
+ assertEquals(result, "1M4D9M5D3M");
+
+ // group starts at hidden cols
+ sg1.setStartRes(3);
+ cig = new CigarArray(al, hc, sg1);
+ result = cig.getCigarstring();
+ assertEquals(result, "4D9M5D3M");
+
+ // group starts at last but 1 hidden col
+ sg1.setStartRes(5);
+ cig = new CigarArray(al, hc, sg1);
+ result = cig.getCigarstring();
+ assertEquals(result, "2D9M5D3M");
+
+ // group starts at last hidden col
+ sg1.setStartRes(6);
+ cig = new CigarArray(al, hc, sg1);
+ result = cig.getCigarstring();
+ assertEquals(result, "1D9M5D3M");
+
+ // group starts just after hidden region
+ sg1.setStartRes(7);
+ cig = new CigarArray(al, hc, sg1);
+ result = cig.getCigarstring();
+ assertEquals(result, "9M5D3M");
+
+ // group ends just before start of hidden region
+ sg1.setStartRes(5);
+ sg1.setEndRes(15);
+ cig = new CigarArray(al, hc, sg1);
+ result = cig.getCigarstring();
+ assertEquals(result, "2D9M");
+
+ // group ends at start of hidden region
+ sg1.setEndRes(16);
+ cig = new CigarArray(al, hc, sg1);
+ result = cig.getCigarstring();
+ assertEquals(result, "2D9M1D");
+
+ // group ends 1 after start of hidden region
+ sg1.setEndRes(17);
+ cig = new CigarArray(al, hc, sg1);
+ result = cig.getCigarstring();
+ assertEquals(result, "2D9M2D");
+
+ // group ends at end of hidden region
+ sg1.setEndRes(20);
+ cig = new CigarArray(al, hc, sg1);
+ result = cig.getCigarstring();
+ assertEquals(result, "2D9M5D");
+
+ // group ends just after end of hidden region
+ sg1.setEndRes(21);
+ cig = new CigarArray(al, hc, sg1);
+ result = cig.getCigarstring();
+ assertEquals(result, "2D9M5D1M");
+
+ // group ends 2 after end of hidden region
+ sg1.setEndRes(22);
+ cig = new CigarArray(al, hc, sg1);
+ result = cig.getCigarstring();
+ assertEquals(result, "2D9M5D2M");
+ }
+}
assertEquals(".K..BCD.EF..", sq.getSequenceAsString());
assertEquals(2, PA.getValue(sq, "changeCount"));
}
+
+ @Test(groups = { "Functional" })
+ public void testFindFeatures_largeEndPos()
+ {
+ /*
+ * imitate a PDB sequence where end is larger than end position
+ */
+ SequenceI sq = new Sequence("test", "-ABC--DEF--", 1, 20);
+ sq.createDatasetSequence();
+
+ assertTrue(sq.findFeatures(1, 9).isEmpty());
+ // should be no array bounds exception - JAL-2772
+ assertTrue(sq.findFeatures(1, 15).isEmpty());
+
+ // add feature on BCD
+ SequenceFeature sfBCD = new SequenceFeature("Cath", "desc", 2, 4, 2f,
+ null);
+ sq.addSequenceFeature(sfBCD);
+
+ // no features in columns 1-2 (-A)
+ List<SequenceFeature> found = sq.findFeatures(1, 2);
+ assertTrue(found.isEmpty());
+
+ // columns 1-6 (-ABC--) includes BCD
+ found = sq.findFeatures(1, 6);
+ assertEquals(1, found.size());
+ assertTrue(found.contains(sfBCD));
+
+ // columns 10-11 (--) should find nothing
+ found = sq.findFeatures(10, 11);
+ assertEquals(0, found.size());
+ }
+
+ @Test(groups = { "Functional" })
+ public void testSetName()
+ {
+ SequenceI sq = new Sequence("test", "-ABC---DE-F--");
+ assertEquals("test", sq.getName());
+ assertEquals(1, sq.getStart());
+ assertEquals(6, sq.getEnd());
+
+ sq.setName("testing");
+ assertEquals("testing", sq.getName());
+
+ sq.setName("test/8-10");
+ assertEquals("test", sq.getName());
+ assertEquals(8, sq.getStart());
+ assertEquals(13, sq.getEnd()); // note end is recomputed
+
+ sq.setName("testing/7-99");
+ assertEquals("testing", sq.getName());
+ assertEquals(7, sq.getStart());
+ assertEquals(99, sq.getEnd()); // end may be beyond physical end
+
+ sq.setName("/2-3");
+ assertEquals("", sq.getName());
+ assertEquals(2, sq.getStart());
+ assertEquals(7, sq.getEnd());
+
+ sq.setName("test/"); // invalid
+ assertEquals("test/", sq.getName());
+ assertEquals(2, sq.getStart());
+ assertEquals(7, sq.getEnd());
+
+ sq.setName("test/6-13/7-99");
+ assertEquals("test/6-13", sq.getName());
+ assertEquals(7, sq.getStart());
+ assertEquals(99, sq.getEnd());
+
+ sq.setName("test/0-5"); // 0 is invalid - ignored
+ assertEquals("test/0-5", sq.getName());
+ assertEquals(7, sq.getStart());
+ assertEquals(99, sq.getEnd());
+
+ sq.setName("test/a-5"); // a is invalid - ignored
+ assertEquals("test/a-5", sq.getName());
+ assertEquals(7, sq.getStart());
+ assertEquals(99, sq.getEnd());
+
+ sq.setName("test/6-5"); // start > end is invalid - ignored
+ assertEquals("test/6-5", sq.getName());
+ assertEquals(7, sq.getStart());
+ assertEquals(99, sq.getEnd());
+
+ sq.setName("test/5"); // invalid - ignored
+ assertEquals("test/5", sq.getName());
+ assertEquals(7, sq.getStart());
+ assertEquals(99, sq.getEnd());
+
+ sq.setName("test/-5"); // invalid - ignored
+ assertEquals("test/-5", sq.getName());
+ assertEquals(7, sq.getStart());
+ assertEquals(99, sq.getEnd());
+
+ sq.setName("test/5-"); // invalid - ignored
+ assertEquals("test/5-", sq.getName());
+ assertEquals(7, sq.getStart());
+ assertEquals(99, sq.getEnd());
+
+ sq.setName("test/5-6-7"); // invalid - ignored
+ assertEquals("test/5-6-7", sq.getName());
+ assertEquals(7, sq.getStart());
+ assertEquals(99, sq.getEnd());
+
+ sq.setName(null); // invalid, gets converted to space
+ assertEquals("", sq.getName());
+ assertEquals(7, sq.getStart());
+ assertEquals(99, sq.getEnd());
+ }
+
+ @Test(groups = { "Functional" })
+ public void testCheckValidRange()
+ {
+ Sequence sq = new Sequence("test/7-12", "-ABC---DE-F--");
+ assertEquals(7, sq.getStart());
+ assertEquals(12, sq.getEnd());
+
+ /*
+ * checkValidRange ensures end is at least the last residue position
+ */
+ PA.setValue(sq, "end", 2);
+ sq.checkValidRange();
+ assertEquals(12, sq.getEnd());
+
+ /*
+ * end may be beyond the last residue position
+ */
+ PA.setValue(sq, "end", 22);
+ sq.checkValidRange();
+ assertEquals(22, sq.getEnd());
+ }
}
assertEquals(features.size(), 2);
assertTrue(features.contains(sf2));
assertTrue(features.contains(sf3));
+
+ features = store.getFeaturesByOntology("sequence_variant");
+ assertTrue(features.isEmpty());
}
@Test(groups = "Functional")
assertEquals(-1, fc.compare("coding_exon", "feature_variant"));
assertEquals(1f, fc.getTransparency());
}
+
+ @Test(groups = "Network")
+ public void testGetGeneIds()
+ {
+ /*
+ * ENSG00000158828 gene id PINK1 human
+ * ENST00000321556 transcript for the same gene - should not be duplicated
+ * P30419 Uniprot identifier for ENSG00000136448
+ * ENST00000592782 transcript for Uniprot gene - should not be duplicated
+ * BRAF - gene name resolvabe (at time of writing) for 6 model species
+ */
+ String ids = "ENSG00000158828 ENST00000321556 P30419 ENST00000592782 BRAF";
+ EnsemblGene testee = new EnsemblGene();
+ List<String> geneIds = testee.getGeneIds(ids);
+ assertEquals(8, geneIds.size());
+ assertTrue(geneIds.contains("ENSG00000158828"));
+ assertTrue(geneIds.contains("ENSG00000136448"));
+ assertTrue(geneIds.contains("ENSG00000157764")); // BRAF human
+ assertTrue(geneIds.contains("ENSMUSG00000002413")); // mouse
+ assertTrue(geneIds.contains("ENSRNOG00000010957")); // rat
+ assertTrue(geneIds.contains("ENSXETG00000004845")); // xenopus
+ assertTrue(geneIds.contains("ENSDARG00000017661")); // zebrafish
+ assertTrue(geneIds.contains("ENSGALG00000012865")); // chicken
+ }
}
*/
package jalview.ext.ensembl;
+import static org.testng.Assert.assertTrue;
+
import jalview.datamodel.AlignmentI;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.List;
+import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
public class EnsemblRestClientTest
{
+ private EnsemblRestClient sf;
@Test(suiteName = "live")
public void testIsEnsemblAvailable()
{
- EnsemblRestClient sf = new EnsemblRestClient()
+ boolean isAvailable = sf.isEnsemblAvailable();
+ if (isAvailable)
+ {
+ System.out.println("Ensembl is UP!");
+ }
+ else
+ {
+ System.err
+ .println("Ensembl is DOWN or unreachable ******************* BAD!");
+ }
+ }
+
+ @BeforeMethod(alwaysRun = true)
+ protected void setUp()
+ {
+ sf = new EnsemblRestClient()
{
@Override
}
};
- boolean isAvailable = sf.isEnsemblAvailable();
- if (isAvailable)
- {
- System.out.println("Ensembl is UP!");
- }
- else
+ }
+
+ @Test(groups = "Network")
+ public void testCheckEnsembl_overload()
+ {
+ for (int i = 0; i < 20; i++)
{
- System.err
- .println("Ensembl is DOWN or unreachable ******************* BAD!");
+ assertTrue(sf.checkEnsembl(), "Error on " + (i + 1) + "th ping");
}
}
-
}
}
- @Test(groups = "Functional")
- public void testIsTranscriptIdentifier()
- {
- EnsemblSeqProxy testee = new EnsemblGene();
- assertFalse(testee.isTranscriptIdentifier(null));
- assertFalse(testee.isTranscriptIdentifier(""));
- assertFalse(testee.isTranscriptIdentifier("ENSG00000012345"));
- assertTrue(testee.isTranscriptIdentifier("ENST00000012345"));
- assertTrue(testee.isTranscriptIdentifier("ENSMUST00000012345"));
- assertFalse(testee.isTranscriptIdentifier("enst00000012345"));
- assertFalse(testee.isTranscriptIdentifier("ENST000000123456"));
- assertFalse(testee.isTranscriptIdentifier("ENST0000001234"));
- }
-
- @Test(groups = "Functional")
- public void testIsGeneIdentifier()
- {
- EnsemblSeqProxy testee = new EnsemblGene();
- assertFalse(testee.isGeneIdentifier(null));
- assertFalse(testee.isGeneIdentifier(""));
- assertFalse(testee.isGeneIdentifier("ENST00000012345"));
- assertTrue(testee.isGeneIdentifier("ENSG00000012345"));
- assertTrue(testee.isGeneIdentifier("ENSMUSG00000012345"));
- assertFalse(testee.isGeneIdentifier("ensg00000012345"));
- assertFalse(testee.isGeneIdentifier("ENSG000000123456"));
- assertFalse(testee.isGeneIdentifier("ENSG0000001234"));
- }
-
/**
* Test the method that appends a single allele's reverse complement to a
* string buffer
--- /dev/null
+package jalview.ext.ensembl;
+
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertTrue;
+
+import java.util.Set;
+
+import org.testng.annotations.Test;
+
+public class SpeciesTest
+{
+ @Test
+ public void testGetModelOrganisms()
+ {
+ Set<Species> models = Species.getModelOrganisms();
+ assertTrue(models.contains(Species.human));
+ assertFalse(models.contains(Species.horse));
+ for (Species s : Species.values())
+ {
+ if (s.isModelOrganism())
+ {
+ assertTrue(models.contains(s));
+ }
+ else
+ {
+ assertFalse(models.contains(s));
+ }
+ }
+ }
+}
assertEquals(model.getAtomSpec(), "#0:1-4.B,5-9.C|#1:2-5.A,8.A,5-10.B");
model.addRange(0, 3, 10, "C"); // subsumes 5-9
assertEquals(model.getAtomSpec(), "#0:1-4.B,3-10.C|#1:2-5.A,8.A,5-10.B");
+ model.addRange(5, 25, 35, " "); // empty chain code - e.g. from homology
+ // modelling
+ assertEquals(model.getAtomSpec(),
+ "#0:1-4.B,3-10.C|#1:2-5.A,8.A,5-10.B|#5:25-35.");
+
}
}
package jalview.gui;
import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotEquals;
import jalview.bin.Cache;
import jalview.bin.Jalview;
.getAlignment().getWidth() - 1 - 21); // 21 is the number of hidden
// columns
}
+
+ /**
+ * Test that update layout reverts to original (unwrapped) values for endRes
+ * and endSeq when switching from wrapped to unwrapped mode (JAL-2739)
+ */
+ @Test(groups = "Functional")
+ public void TestUpdateLayout_endRes()
+ {
+ // get details of original alignment dimensions
+ ViewportRanges ranges = af.getViewport().getRanges();
+ int endres = ranges.getEndRes();
+
+ // wrap
+ af.alignPanel.getAlignViewport().setWrapAlignment(true);
+ af.alignPanel.updateLayout();
+
+ // endRes changes
+ assertNotEquals(ranges.getEndRes(), endres);
+
+ // unwrap
+ af.alignPanel.getAlignViewport().setWrapAlignment(false);
+ af.alignPanel.updateLayout();
+
+ // endRes and endSeq back to original values
+ assertEquals(ranges.getEndRes(), endres);
+
+ }
}
--- /dev/null
+package jalview.gui;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+
+import jalview.analysis.AlignmentGenerator;
+import jalview.bin.Cache;
+import jalview.bin.Jalview;
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.SequenceGroup;
+import jalview.io.DataSourceType;
+import jalview.io.FileLoader;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.PrintStream;
+
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+public class FreeUpMemoryTest
+{
+ private static final int ONE_MB = 1000 * 1000;
+
+ /**
+ * Configure (read-only) Jalview property settings for test
+ */
+ @BeforeClass(alwaysRun = true)
+ public void setUp()
+ {
+ Jalview.main(new String[] { "-nonews", "-props",
+ "test/jalview/testProps.jvprops" });
+ Cache.applicationProperties.setProperty("SHOW_ANNOTATIONS",
+ Boolean.TRUE.toString());
+ Cache.applicationProperties.setProperty("SHOW_QUALITY",
+ Boolean.TRUE.toString());
+ Cache.applicationProperties.setProperty("SHOW_CONSERVATION",
+ Boolean.TRUE.toString());
+ Cache.applicationProperties.setProperty("SHOW_OCCUPANCY",
+ Boolean.TRUE.toString());
+ Cache.applicationProperties.setProperty("SHOW_IDENTITY",
+ Boolean.TRUE.toString());
+ }
+
+ /**
+ * 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();
+
+ doStuffInJalview(f);
+
+ Desktop.instance.closeAll_actionPerformed(null);
+
+ checkUsedMemory(35L);
+ }
+
+ /**
+ * Requests garbage collection and then checks whether remaining memory in use
+ * is less than the expected value (in Megabytes)
+ *
+ * @param expectedMax
+ */
+ protected void checkUsedMemory(long expectedMax)
+ {
+ /*
+ * request garbage collection and wait briefly for it to run;
+ * NB there is no guarantee when, or whether, it will do so
+ */
+ System.gc();
+ waitFor(100);
+
+ /*
+ * a second gc() call should not be necessary - but it is!
+ * the test passes with it, and fails without it
+ */
+ System.gc();
+ waitFor(100);
+
+ /*
+ * check used memory is 'reasonably low'
+ */
+ long availableMemory = Runtime.getRuntime().totalMemory() / ONE_MB;
+ long freeMemory = Runtime.getRuntime().freeMemory() / ONE_MB;
+ long usedMemory = availableMemory - freeMemory;
+
+ /*
+ * sanity check - fails if any frame was added after
+ * closeAll_actionPerformed
+ */
+ assertEquals(Desktop.instance.getAllFrames().length, 0);
+
+ /*
+ * if this assertion fails
+ * - set a breakpoint here
+ * - run jvisualvm to inspect a heap dump of Jalview
+ * - identify large objects in the heap and their referers
+ * - fix code as necessary to null the references on close
+ */
+ System.out.println("Used memory after gc = " + usedMemory + "MB");
+ assertTrue(usedMemory < expectedMax, String.format(
+ "Used memory %d should be less than %d (Recommend running test manually to verify)",
+ usedMemory,
+ expectedMax));
+ }
+
+ /**
+ * Loads an alignment from file and exercises various operations in Jalview
+ *
+ * @param f
+ */
+ protected void doStuffInJalview(File f)
+ {
+ /*
+ * load alignment, wait for consensus and other threads to complete
+ */
+ AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(f.getPath(),
+ DataSourceType.FILE);
+ while (af.getViewport().isCalcInProgress())
+ {
+ waitFor(200);
+ }
+
+ /*
+ * set a selection group - potential memory leak if it retains
+ * a reference to the alignment
+ */
+ SequenceGroup sg = new SequenceGroup();
+ sg.setStartRes(0);
+ sg.setEndRes(100);
+ AlignmentI al = af.viewport.getAlignment();
+ for (int i = 0; i < al.getHeight(); i++)
+ {
+ sg.addSequence(al.getSequenceAt(i), false);
+ }
+ af.viewport.setSelectionGroup(sg);
+
+ /*
+ * compute Tree and PCA (on all sequences, 100 columns)
+ */
+ af.openTreePcaDialog();
+ CalculationChooser dialog = af.alignPanel.getCalculationDialog();
+ dialog.openPcaPanel("BLOSUM62", dialog.getSimilarityParameters(true));
+ dialog.openTreePanel("BLOSUM62", dialog.getSimilarityParameters(false));
+
+ /*
+ * wait until Tree and PCA have been computed
+ */
+ while (af.viewport.getCurrentTree() == null
+ && dialog.getPcaPanel().isWorking())
+ {
+ waitFor(10);
+ }
+
+ /*
+ * give Swing time to add the PCA panel (?!?)
+ */
+ waitFor(100);
+ }
+
+ /**
+ * Wait for waitMs miliseconds
+ *
+ * @param waitMs
+ */
+ protected void waitFor(int waitMs)
+ {
+ try
+ {
+ Thread.sleep(waitMs);
+ } catch (InterruptedException e)
+ {
+ }
+ }
+
+ /**
+ * Generates an alignment and saves it in a temporary file, to be loaded by
+ * Jalview. We use a peptide alignment (so Conservation and Quality are
+ * calculated), which is wide enough to ensure Consensus, Conservation and
+ * Occupancy have a significant memory footprint (if not removed from the
+ * heap).
+ *
+ * @return
+ * @throws IOException
+ */
+ private File generateAlignment() throws IOException
+ {
+ File f = File.createTempFile("MemoryTest", "fa");
+ PrintStream ps = new PrintStream(f);
+ AlignmentGenerator ag = new AlignmentGenerator(false, ps);
+ int width = 100000;
+ int height = 100;
+ ag.generate(width, height, 0, 10, 15);
+ return f;
+ }
+}
--- /dev/null
+package jalview.gui;
+
+import static org.testng.Assert.assertEquals;
+
+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;
+
+public class PairwiseAlignmentPanelTest
+{
+ @Test(groups = "Functional")
+ public void testConstructor_withSelectionGroup()
+ {
+ AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
+ "examples/uniref50.fa", DataSourceType.FILE);
+ AlignViewport viewport = af.getViewport();
+ AlignmentI al = viewport.getAlignment();
+
+ /*
+ * select columns 29-36 of sequences 4 and 5 for alignment
+ * Q93XJ9_SOLTU/23-29 L-KAISNV
+ * FER1_PEA/26-32 V-TTTKAF
+ */
+ SequenceGroup sg = new SequenceGroup();
+ sg.addSequence(al.getSequenceAt(3), false);
+ sg.addSequence(al.getSequenceAt(4), false);
+ sg.setStartRes(28);
+ sg.setEndRes(35);
+ viewport.setSelectionGroup(sg);
+
+ PairwiseAlignPanel testee = new PairwiseAlignPanel(viewport);
+
+ String text = ((JTextArea) PA.getValue(testee, "textarea")).getText();
+ 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"
+ + " FER1_PEA/29-32 TKAF\n" + " ||.\n"
+ + "Q93XJ9_SOLTU/23-26 LKAI\n\n" + "Percentage ID = 50.00\n\n";
+ assertEquals(text, expected);
+ }
+
+ /**
+ * This test aligns the same sequences as testConstructor_withSelectionGroup
+ * but as a complete alignment (no selection). Note that in fact the user is
+ * currently required to make a selection in order to calculate pairwise
+ * alignments, so this case does not arise.
+ */
+ @Test(groups = "Functional")
+ public void testConstructor_noSelectionGroup()
+ {
+ 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();
+
+ PairwiseAlignPanel testee = new PairwiseAlignPanel(viewport);
+
+ String text = ((JTextArea) PA.getValue(testee, "textarea")).getText();
+ 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"
+ + " FER1_PEA/29-32 TKAF\n" + " ||.\n"
+ + "Q93XJ9_SOLTU/23-26 LKAI\n\n" + "Percentage ID = 50.00\n\n";
+ assertEquals(text, expected);
+ }
+}
import javax.swing.JLabel;
import javax.swing.JPanel;
+import javax.swing.SwingUtilities;
import org.testng.Assert;
import org.testng.annotations.BeforeClass;
* @param layout
* @param msgs
*/
- private void verifyProgress(GridLayout layout, String[] msgs)
+ private void verifyProgress(final GridLayout layout, final String[] msgs)
{
+ try
+ {
+ SwingUtilities.invokeAndWait(new Runnable()
+ {
+ @Override
+ public void run()
+ {
int msgCount = msgs.length;
assertEquals(1 + msgCount, layout.getRows());
assertEquals(msgCount, statusPanel.getComponentCount());
assertEquals(msgs[i++],
((JLabel) ((JPanel) c).getComponent(0)).getText());
}
+ }
+ });
+ } catch (Exception e)
+ {
+ throw new AssertionError(
+ "Unexpected exception waiting for progress bar validation",
+ e);
+ }
}
}
--- /dev/null
+package jalview.gui;
+
+import static org.testng.Assert.assertEquals;
+
+import jalview.datamodel.AlignmentI;
+import jalview.io.DataSourceType;
+import jalview.io.FileLoader;
+
+import java.awt.Font;
+import java.awt.FontMetrics;
+
+import junit.extensions.PA;
+
+import org.testng.annotations.Test;
+
+import sun.swing.SwingUtilities2;
+
+public class SeqCanvasTest
+{
+ /**
+ * Test the method that computes wrapped width in residues, height of wrapped
+ * widths in pixels, and the number of widths visible
+ */
+ @Test(groups = "Functional")
+ public void testCalculateWrappedGeometry_noAnnotations()
+ {
+ AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
+ "examples/uniref50.fa", DataSourceType.FILE);
+ AlignViewport av = af.getViewport();
+ AlignmentI al = av.getAlignment();
+ assertEquals(al.getWidth(), 157);
+ assertEquals(al.getHeight(), 15);
+
+ av.setWrapAlignment(true);
+ av.getRanges().setStartEndSeq(0, 14);
+ av.setFont(new Font("SansSerif", Font.PLAIN, 14), true);
+ int charHeight = av.getCharHeight();
+ int charWidth = av.getCharWidth();
+ assertEquals(charHeight, 17);
+ assertEquals(charWidth, 12);
+
+ SeqCanvas testee = af.alignPanel.getSeqPanel().seqCanvas;
+
+ /*
+ * first with scales above, left, right
+ */
+ av.setShowAnnotation(false);
+ av.setScaleAboveWrapped(true);
+ av.setScaleLeftWrapped(true);
+ av.setScaleRightWrapped(true);
+ FontMetrics fm = SwingUtilities2.getFontMetrics(testee, av.getFont());
+ int labelWidth = fm.stringWidth("000") + charWidth;
+ assertEquals(labelWidth, 39); // 3 x 9 + charWidth
+
+ /*
+ * width 400 pixels leaves (400 - 2*labelWidth) for residue columns
+ * take the whole multiple of character widths
+ */
+ int canvasWidth = 400;
+ int canvasHeight = 300;
+ int residueColumns = (canvasWidth - 2 * labelWidth) / charWidth;
+ int wrappedWidth = testee.calculateWrappedGeometry(canvasWidth, canvasHeight);
+ assertEquals(wrappedWidth, residueColumns);
+ assertEquals(PA.getValue(testee, "labelWidthWest"), labelWidth);
+ assertEquals(PA.getValue(testee, "labelWidthEast"), labelWidth);
+ assertEquals(PA.getValue(testee, "wrappedSpaceAboveAlignment"),
+ 2 * charHeight);
+ int repeatingHeight = (int) PA.getValue(testee, "wrappedRepeatHeightPx");
+ assertEquals(repeatingHeight, charHeight * (2 + al.getHeight()));
+ assertEquals(PA.getValue(testee, "wrappedVisibleWidths"), 1);
+
+ /*
+ * repeat height is 17 * (2 + 15) = 289
+ * make canvas height 2 * 289 + 3 * charHeight so just enough to
+ * draw 2 widths and the first sequence of a third
+ */
+ canvasHeight = charHeight * (17 * 2 + 3);
+ testee.calculateWrappedGeometry(canvasWidth, canvasHeight);
+ assertEquals(PA.getValue(testee, "wrappedVisibleWidths"), 3);
+
+ /*
+ * reduce canvas height by 1 pixel - should not be enough height
+ * to draw 3 widths
+ */
+ canvasHeight -= 1;
+ testee.calculateWrappedGeometry(canvasWidth, canvasHeight);
+ assertEquals(PA.getValue(testee, "wrappedVisibleWidths"), 2);
+
+ /*
+ * turn off scale above - can now fit in 2 and a bit widths
+ */
+ av.setScaleAboveWrapped(false);
+ testee.calculateWrappedGeometry(canvasWidth, canvasHeight);
+ assertEquals(PA.getValue(testee, "wrappedVisibleWidths"), 3);
+
+ /*
+ * reduce height to enough for 2 widths and not quite a third
+ * i.e. two repeating heights + spacer + sequence - 1 pixel
+ */
+ canvasHeight = charHeight * (16 * 2 + 2) - 1;
+ testee.calculateWrappedGeometry(canvasWidth, canvasHeight);
+ assertEquals(PA.getValue(testee, "wrappedVisibleWidths"), 2);
+
+ /*
+ * make canvas width enough for scales and 20 residues
+ */
+ canvasWidth = 2 * labelWidth + 20 * charWidth;
+ wrappedWidth = testee.calculateWrappedGeometry(canvasWidth,
+ canvasHeight);
+ assertEquals(wrappedWidth, 20);
+
+ /*
+ * reduce width by 1 pixel - rounds down to 19 residues
+ */
+ canvasWidth -= 1;
+ wrappedWidth = testee.calculateWrappedGeometry(canvasWidth,
+ canvasHeight);
+ assertEquals(wrappedWidth, 19);
+
+ /*
+ * turn off West scale - adds labelWidth (39) to available for residues
+ * which with the 11 remainder makes 50 which is 4 more charWidths rem 2
+ */
+ av.setScaleLeftWrapped(false);
+ wrappedWidth = testee.calculateWrappedGeometry(canvasWidth,
+ canvasHeight);
+ assertEquals(wrappedWidth, 23);
+
+ /*
+ * add 10 pixels to width to fit in another whole residue column
+ */
+ canvasWidth += 9;
+ wrappedWidth = testee.calculateWrappedGeometry(canvasWidth,
+ canvasHeight);
+ assertEquals(wrappedWidth, 23);
+ canvasWidth += 1;
+ wrappedWidth = testee.calculateWrappedGeometry(canvasWidth,
+ canvasHeight);
+ assertEquals(wrappedWidth, 24);
+
+ /*
+ * turn off East scale to gain 39 more pixels (3 columns remainder 3)
+ */
+ av.setScaleRightWrapped(false);
+ wrappedWidth = testee.calculateWrappedGeometry(canvasWidth,
+ canvasHeight);
+ assertEquals(wrappedWidth, 27);
+
+ /*
+ * add 9 pixels to width to gain a residue column
+ */
+ canvasWidth += 8;
+ wrappedWidth = testee.calculateWrappedGeometry(canvasWidth,
+ canvasHeight);
+ assertEquals(wrappedWidth, 27);
+ canvasWidth += 1;
+ wrappedWidth = testee.calculateWrappedGeometry(canvasWidth,
+ canvasHeight);
+ assertEquals(wrappedWidth, 28);
+
+ /*
+ * now West but not East scale - lose 39 pixels or 4 columns
+ */
+ av.setScaleLeftWrapped(true);
+ wrappedWidth = testee.calculateWrappedGeometry(canvasWidth,
+ canvasHeight);
+ assertEquals(wrappedWidth, 24);
+
+ /*
+ * adding 3 pixels to width regains one column
+ */
+ canvasWidth += 2;
+ wrappedWidth = testee.calculateWrappedGeometry(canvasWidth,
+ canvasHeight);
+ assertEquals(wrappedWidth, 24);
+ canvasWidth += 1;
+ wrappedWidth = testee.calculateWrappedGeometry(canvasWidth,
+ canvasHeight);
+ assertEquals(wrappedWidth, 25);
+
+ /*
+ * turn off scales left and right, make width exactly 157 columns
+ */
+ av.setScaleLeftWrapped(false);
+ canvasWidth = al.getWidth() * charWidth;
+ testee.calculateWrappedGeometry(canvasWidth, canvasHeight);
+ assertEquals(PA.getValue(testee, "wrappedVisibleWidths"), 1);
+ }
+
+ /**
+ * Test the method that computes wrapped width in residues, height of wrapped
+ * widths in pixels, and the number of widths visible
+ */
+ @Test(groups = "Functional")
+ public void testCalculateWrappedGeometry_withAnnotations()
+ {
+ AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
+ "examples/uniref50.fa", DataSourceType.FILE);
+ AlignViewport av = af.getViewport();
+ AlignmentI al = av.getAlignment();
+ assertEquals(al.getWidth(), 157);
+ assertEquals(al.getHeight(), 15);
+
+ av.setWrapAlignment(true);
+ av.getRanges().setStartEndSeq(0, 14);
+ av.setFont(new Font("SansSerif", Font.PLAIN, 14), true);
+ int charHeight = av.getCharHeight();
+ int charWidth = av.getCharWidth();
+ assertEquals(charHeight, 17);
+ assertEquals(charWidth, 12);
+
+ SeqCanvas testee = af.alignPanel.getSeqPanel().seqCanvas;
+
+ /*
+ * first with scales above, left, right
+ */
+ av.setShowAnnotation(true);
+ av.setScaleAboveWrapped(true);
+ av.setScaleLeftWrapped(true);
+ av.setScaleRightWrapped(true);
+ FontMetrics fm = SwingUtilities2.getFontMetrics(testee, av.getFont());
+ int labelWidth = fm.stringWidth("000") + charWidth;
+ assertEquals(labelWidth, 39); // 3 x 9 + charWidth
+ int annotationHeight = testee.getAnnotationHeight();
+
+ /*
+ * width 400 pixels leaves (400 - 2*labelWidth) for residue columns
+ * take the whole multiple of character widths
+ */
+ int canvasWidth = 400;
+ int canvasHeight = 300;
+ int residueColumns = (canvasWidth - 2 * labelWidth) / charWidth;
+ int wrappedWidth = testee.calculateWrappedGeometry(canvasWidth, canvasHeight);
+ assertEquals(wrappedWidth, residueColumns);
+ assertEquals(PA.getValue(testee, "labelWidthWest"), labelWidth);
+ assertEquals(PA.getValue(testee, "labelWidthEast"), labelWidth);
+ assertEquals(PA.getValue(testee, "wrappedSpaceAboveAlignment"),
+ 2 * charHeight);
+ int repeatingHeight = (int) PA.getValue(testee, "wrappedRepeatHeightPx");
+ assertEquals(repeatingHeight, charHeight * (2 + al.getHeight())
+ + annotationHeight);
+ assertEquals(PA.getValue(testee, "wrappedVisibleWidths"), 1);
+
+ /*
+ * repeat height is 17 * (2 + 15) = 289 + annotationHeight = 507
+ * make canvas height 2 * 289 + 3 * charHeight so just enough to
+ * draw 2 widths and the first sequence of a third
+ */
+ canvasHeight = charHeight * (17 * 2 + 3) + 2 * annotationHeight;
+ testee.calculateWrappedGeometry(canvasWidth, canvasHeight);
+ assertEquals(PA.getValue(testee, "wrappedVisibleWidths"), 3);
+
+ /*
+ * reduce canvas height by 1 pixel - should not be enough height
+ * to draw 3 widths
+ */
+ canvasHeight -= 1;
+ testee.calculateWrappedGeometry(canvasWidth, canvasHeight);
+ assertEquals(PA.getValue(testee, "wrappedVisibleWidths"), 2);
+
+ /*
+ * turn off scale above - can now fit in 2 and a bit widths
+ */
+ av.setScaleAboveWrapped(false);
+ testee.calculateWrappedGeometry(canvasWidth, canvasHeight);
+ assertEquals(PA.getValue(testee, "wrappedVisibleWidths"), 3);
+
+ /*
+ * reduce height to enough for 2 widths and not quite a third
+ * i.e. two repeating heights + spacer + sequence - 1 pixel
+ */
+ canvasHeight = charHeight * (16 * 2 + 2) + 2 * annotationHeight - 1;
+ testee.calculateWrappedGeometry(canvasWidth, canvasHeight);
+ assertEquals(PA.getValue(testee, "wrappedVisibleWidths"), 2);
+
+ /*
+ * add 1 pixel to height - should now get 3 widths drawn
+ */
+ canvasHeight += 1;
+ testee.calculateWrappedGeometry(canvasWidth, canvasHeight);
+ assertEquals(PA.getValue(testee, "wrappedVisibleWidths"), 3);
+ }
+}
AlignViewport av = af.getViewport();
/*
- * scale has minor ticks at 5 and 15, major at 10 and 20
+ * scale has minor ticks at 5, 15, 25, major at 10 and 20
* (these are base 1, ScaleMark holds base 0 values)
*/
List<ScaleMark> marks = new ScaleRenderer().calculateMarks(av, 0, 25);
- assertEquals(marks.size(), 4);
+ assertEquals(marks.size(), 5);
assertFalse(marks.get(0).major);
assertEquals(marks.get(0).column, 4);
assertEquals(marks.get(3).column, 19);
assertEquals(marks.get(3).text, "20");
+ assertFalse(marks.get(4).major);
+ assertEquals(marks.get(4).column, 24);
+ assertNull(marks.get(4).text);
+
/*
* now hide columns 9-11 and 18-20 (base 1)
* scale marks are now in the same columns as before, but
av.hideColumns(8, 10);
av.hideColumns(17, 19);
marks = new ScaleRenderer().calculateMarks(av, 0, 25);
- assertEquals(marks.size(), 4);
+ assertEquals(marks.size(), 5);
assertFalse(marks.get(0).major);
assertEquals(marks.get(0).column, 4);
assertNull(marks.get(0).text);
assertTrue(marks.get(3).major);
assertEquals(marks.get(3).column, 19);
assertEquals(marks.get(3).text, "26"); // +6 hidden columns
+ assertFalse(marks.get(4).major);
+ assertEquals(marks.get(4).column, 24);
+ assertNull(marks.get(4).text);
}
}
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertNotEquals;
import static org.testng.Assert.assertNull;
import static org.testng.Assert.assertTrue;
}
@Test(groups = "Functional")
+ public void testFindFeatureAtEnd()
+ {
+ /*
+ * terminal residue feature
+ */
+ seq.addSequenceFeature(new SequenceFeature("PDBRESNUM", "pdb res 1",
+ seq.getEnd(), seq.getEnd(), Float.NaN, "1seq.pdb"));
+ fr.setColour("PDBRESNUM", new FeatureColour(Color.red));
+ fr.featuresAdded();
+ av.setShowSequenceFeatures(true);
+
+ /*
+ * final column should have PDBRESNUM feature, the others not
+ */
+ Color c = finder.findFeatureColour(Color.blue, seq,
+ seq.getLength() - 2);
+ assertNotEquals(c, Color.red);
+ c = finder.findFeatureColour(Color.blue, seq, seq.getLength() - 1);
+ assertEquals(c, Color.red);
+ }
+
+ @Test(groups = "Functional")
public void testFindFeatureColour_graduatedFeatureColour()
{
seq.addSequenceFeature(new SequenceFeature("kd", "hydrophobicity", 2,
StructureSelectionManager ssm = new StructureSelectionManager();
ssm.setMapping(new SequenceI[] { seq1a, seq1b }, null, PDB_1,
- DataSourceType.PASTE);
+ DataSourceType.PASTE, null);
ssm.setMapping(new SequenceI[] { seq2 }, null, PDB_2,
- DataSourceType.PASTE);
+ DataSourceType.PASTE, null);
ssm.setMapping(new SequenceI[] { seq3 }, null, PDB_3,
- DataSourceType.PASTE);
+ DataSourceType.PASTE, null);
testee = new AAStructureBindingModel(ssm, pdbFiles, seqs, null)
{
assertEquals("[12, 11, 8, 4]", Arrays.toString(ranges));
}
+ @Test(groups = "Functional")
+ public void testRemoveEndPositions()
+ {
+ List<int[]> ranges = new ArrayList<>();
+
+ /*
+ * case 1: truncate last range
+ */
+ ranges.add(new int[] { 1, 10 });
+ ranges.add(new int[] { 20, 30 });
+ MappingUtils.removeEndPositions(5, ranges);
+ assertEquals(2, ranges.size());
+ assertEquals(25, ranges.get(1)[1]);
+
+ /*
+ * case 2: remove last range
+ */
+ ranges.clear();
+ ranges.add(new int[] { 1, 10 });
+ ranges.add(new int[] { 20, 22 });
+ MappingUtils.removeEndPositions(3, ranges);
+ assertEquals(1, ranges.size());
+ assertEquals(10, ranges.get(0)[1]);
+
+ /*
+ * case 3: truncate penultimate range
+ */
+ ranges.clear();
+ ranges.add(new int[] { 1, 10 });
+ ranges.add(new int[] { 20, 21 });
+ MappingUtils.removeEndPositions(3, ranges);
+ assertEquals(1, ranges.size());
+ assertEquals(9, ranges.get(0)[1]);
+
+ /*
+ * case 4: remove last two ranges
+ */
+ ranges.clear();
+ ranges.add(new int[] { 1, 10 });
+ ranges.add(new int[] { 20, 20 });
+ ranges.add(new int[] { 30, 30 });
+ MappingUtils.removeEndPositions(3, ranges);
+ assertEquals(1, ranges.size());
+ assertEquals(9, ranges.get(0)[1]);
+ }
}
}
}
}
+
+ @Test(groups = { "Functional" })
+ public void testScrollUp_wrapped()
+ {
+ /*
+ * alignment 30 tall and 45 wide
+ */
+ AlignmentI al2 = gen.generate(45, 30, 1, 0, 5);
+
+ /*
+ * wrapped view, 5 sequences high, start at sequence offset 1
+ */
+ ViewportRanges vr = new ViewportRanges(al2);
+ vr.setWrappedMode(true);
+ vr.setViewportStartAndHeight(1, 5);
+
+ /*
+ * offset wrapped view to column 3
+ */
+ vr.setStartEndRes(3, 22);
+
+ int startRes = vr.getStartRes();
+ int width = vr.getViewportWidth();
+ assertEquals(startRes, 3);
+ assertEquals(width, 20);
+
+ // in wrapped mode, we change startRes but not startSeq
+ // scroll down:
+ vr.scrollUp(false);
+ assertEquals(vr.getStartSeq(), 1);
+ assertEquals(vr.getStartRes(), 23);
+
+ // scroll up returns to original position
+ vr.scrollUp(true);
+ assertEquals(vr.getStartSeq(), 1);
+ assertEquals(vr.getStartRes(), 3);
+
+ // scroll up again returns to 'origin'
+ vr.scrollUp(true);
+ assertEquals(vr.getStartSeq(), 1);
+ assertEquals(vr.getStartRes(), 0);
+
+ /*
+ * offset 3 columns once more and do some scroll downs
+ */
+ vr.setStartEndRes(3, 22);
+ vr.scrollUp(false);
+ assertEquals(vr.getStartSeq(), 1);
+ assertEquals(vr.getStartRes(), 23);
+ vr.scrollUp(false);
+ assertEquals(vr.getStartSeq(), 1);
+ assertEquals(vr.getStartRes(), 43);
+
+ /*
+ * scroll down beyond end of alignment does nothing
+ */
+ vr.scrollUp(false);
+ assertEquals(vr.getStartSeq(), 1);
+ assertEquals(vr.getStartRes(), 43);
+ }
}
// mock listener for property change events
/*
* EMBL
*/
- assertEquals("http://www.ebi.ac.uk/ena/data/view/x53838&display=xml",
+ assertEquals("https://www.ebi.ac.uk/ena/data/view/x53838&display=xml",
EBIFetchClient.buildUrl("X53838", "EMBL", "display=xml"));
/*
* EMBLCDS
*/
- assertEquals("http://www.ebi.ac.uk/ena/data/view/caa37824&display=xml",
+ assertEquals("https://www.ebi.ac.uk/ena/data/view/caa37824&display=xml",
EBIFetchClient.buildUrl("CAA37824", "EMBL", "display=xml"));
/*
- * Uniprot
- */
- assertEquals(
- "http://www.ebi.ac.uk/Tools/dbfetch/dbfetch/uniprot/p00340/uniprotxml",
- EBIFetchClient.buildUrl("P00340", "UNIPROT", "uniprotxml"));
-
- /*
* PDB / pdb
*/
- assertEquals("http://www.ebi.ac.uk/Tools/dbfetch/dbfetch/pdb/3a6s/pdb",
+ assertEquals("https://www.ebi.ac.uk/Tools/dbfetch/dbfetch/pdb/3a6s/pdb",
EBIFetchClient.buildUrl("3A6S", "PDB", "pdb"));
/*
* PDB / mmCIF
*/
assertEquals(
- "http://www.ebi.ac.uk/Tools/dbfetch/dbfetch/pdb/3a6s/mmCIF",
+ "https://www.ebi.ac.uk/Tools/dbfetch/dbfetch/pdb/3a6s/mmCIF",
EBIFetchClient.buildUrl("3A6S", "PDB", "mmCIF"));
}
<!--
Suppress check of externally sourced code
-->
- <suppress checks="[a-zA-Z0-9]*" files="com[\\/]*"/>
- <suppress checks="[a-zA-Z0-9]*" files="ext[\\/]*"/>
- <suppress checks="[a-zA-Z0-9]*" files="org[\\/]*"/>
- <suppress checks="[a-zA-Z0-9]*" files="uk[\\/]*"/>
+ <suppress checks="[a-zA-Z0-9]*" files="[\\/]com[\\/]github*"/>
+ <suppress checks="[a-zA-Z0-9]*" files="[\\/]com[\\/]stevesoft*"/>
+ <suppress checks="[a-zA-Z0-9]*" files="[\\/]ext[\\/]edu*"/>
+ <suppress checks="[a-zA-Z0-9]*" files="[\\/]ext[\\/]vamsas*"/>
+ <suppress checks="[a-zA-Z0-9]*" files="[\\/]org[\\/]jibble*"/>
+ <suppress checks="[a-zA-Z0-9]*" files="[\\/]uk[\\/]ac*"/>
<!--
ImportControl can only handle one top level package
<subpackage name="datamodel">
<disallow pkg="jalview.gui"/>
<allow pkg="fr.orsay.lri.varna"/>
- <subpackage name="xdb">
- <subpackage name="embl">
- <allow pkg="org.exolab.castor"/>
- </subpackage>
+ <subpackage name="xdb.embl">
+ <allow pkg="org.exolab.castor"/>
</subpackage>
</subpackage>
+ <subpackage name="ext">
+ <subpackage name="ensembl">
+ <allow pkg="javax.ws"/>
+ <allow pkg="org.json"/>
+ </subpackage>
+ <subpackage name="htsjdk">
+ <allow pkg="htsjdk"/>
+ </subpackage>
+ <subpackage name="jmol">
+ <allow pkg="MCview"/>
+ <allow pkg="org.jmol"/>
+ </subpackage>
+ <subpackage name="paradise">
+ <allow pkg="org.apache"/>
+ <allow pkg="org.json"/>
+ </subpackage>
+ <subpackage name="rbvi">
+ <allow pkg="ext.edu.ucsf"/>
+ <allow pkg="javax.servlet"/>
+ </subpackage>
+ <subpackage name="so">
+ <allow pkg="org.biojava"/>
+ </subpackage>
+ <subpackage name="varna">
+ <allow pkg="fr.orsay"/>
+ </subpackage>
+ </subpackage>
+
<subpackage name="fts">
<allow pkg="javax.swing"/>
<allow pkg="javax.ws"/>
<allow pkg="javax.servlet"/>
</subpackage>
+ <subpackage name="schemes">
+ <allow pkg="org.exolab.castor" class="jalview.schemes.ColourSchemeLoader"/>
+ </subpackage>
+
<subpackage name="structure">
<allow pkg="MCview"/>
</subpackage>
+
+ <subpackage name="urls">
+ <allow pkg="javax.swing" class="jalview.urls.UrlLinkTableModel"/>
+ <allow pkg="org.json"/>
+ </subpackage>
<subpackage name="util">
<allow pkg="javax.swing"/>