To get JSON output instead use:
java -jar target/benchmarks.jar -rf json
+ To run a specific benchmark file use:
+ java -jar target/benchmarks.jar <Benchmark class name>
+
JSON output can be viewed quickly by drag-dropping on http://jmh.morethan.io/
To get help use the standard -h option:
6. If you make changes to the Jalview code everything will need to be refreshed, by performing steps 3-5 again.
+
--- /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.infra.Blackhole;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Param;
+
+import java.util.Iterator;
+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 HiddenColsIteratorsBenchmark {
+ /*
+ * 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 benchStartIterator(HiddenColsAndStartState tstate)
+ {
+ int res = 0;
+ int startx = tstate.visibleColumn;
+ Iterator<Integer> it = tstate.h.getStartRegionIterator(startx,
+ startx+60);
+ while (it.hasNext())
+ {
+ res = it.next() - startx;
+ Blackhole.consumeCPU(5);
+ }
+ return res;
+ }
+
+ @Benchmark
+ @BenchmarkMode({Mode.Throughput})
+ public int benchBoundedIterator(HiddenColsAndStartState tstate)
+ {
+ int startx = tstate.visibleColumn;
+ int blockStart = startx;
+ int blockEnd;
+ int screenY = 0;
+ Iterator<int[]> it = tstate.h.getBoundedIterator(startx,
+ startx+60);
+ while (it.hasNext())
+ {
+ int[] region = it.next();
+
+ blockEnd = Math.min(region[0] - 1, blockStart + 60 - screenY);
+
+ screenY += blockEnd - blockStart + 1;
+ blockStart = region[1] + 1;
+
+ Blackhole.consumeCPU(5);
+ }
+ return blockStart;
+ }
+}
@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()
+{
+ /*
+ * State with multiple hidden columns and a start position set
+ */
+ @State(Scope.Thread)
+ public static class HiddenColsAndStartState
+ {
+ @Param({"100", "1000", "10000", "100000", "1000000"})
+ 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.visibleToAbsoluteColumn(tstate.visibleColumn);
+ }
+
+ @Benchmark
+ @BenchmarkMode({Mode.Throughput})
+ public int benchFindColumnPosition(HiddenColsAndStartState tstate)
+ {
+ return tstate.h.absoluteToVisibleColumn(tstate.visibleColumn);
+ }
+
+ @Benchmark
+ @BenchmarkMode({Mode.Throughput})
+ public int benchGetSize(HiddenColsAndStartState tstate)
{
- 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());
+ return tstate.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;
- }
+ @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
--- /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.jalview.HiddenColumnsBenchmark.HiddenColsAndStartState;
+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.Alignment;
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.Sequence;
+import jalview.datamodel.SequenceI;
+
+/*
+ * 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 SeqWidthBenchmark {
+
+ /*
+ * State with multiple hidden columns and a start position set
+ */
+ @State(Scope.Thread)
+ public static class AlignmentState
+ {
+ @Param({"100", "1000", "10000", "100000"})
+ public int numSeqs;
+
+ Random rand = new Random();
+
+ AlignmentI al;
+
+ @Setup
+ public void setup()
+ {
+ rand.setSeed(1234);
+
+ SequenceI[] seqs = new Sequence[numSeqs];
+ for (int i = 0; i < numSeqs; i++)
+ {
+ int count = rand.nextInt(10000);
+ StringBuilder aas = new StringBuilder();
+ for (int j=0; j<count; j++)
+ {
+ aas.append("a");
+ }
+
+ seqs[i] = new Sequence("Sequence" + i, aas.toString());
+ }
+ al = new Alignment(seqs);
+ }
+ }
+
+
+ @Benchmark
+ @BenchmarkMode({Mode.Throughput})
+ public int benchSeqGetWidth(AlignmentState tstate)
+ {
+ return tstate.al.getWidth();
+ }
+
+}
* 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.
-->
-<project name="jalviewX" default="usage" basedir=".">
+<project name="jalviewX" default="usage" basedir="."
+ xmlns:if="ant:if"
+ xmlns:unless="ant:unless">
<target name="help" depends="usage" />
<target name="usage" depends="init">
<echo message="~~~Jalview Ant build.xml Usage~~~~" />
<!-- default TestNG groups to run -->
<property name="testng-groups" value="Functional" />
+ <!-- Java 9 JVM args -->
+ <condition property="java9">
+ <equals arg1="${ant.java.version}" arg2="9"/>
+ </condition>
<!-- Don't change anything below here unless you know what you are doing! -->
<!-- Url path for WebStart in JNLP file -->
<pathelement location="${testOutputDir}" />
<path refid="test.classpath" />
</classpath>
+ <jvmarg value="--add-modules=java.se.ee" if:set="java9"/>
+ <jvmarg value="--illegal-access=warn" if:set="java9"/>
<classfileset dir="${testOutputDir}" includes="**/*.class" />
</testng>
</target>
<exclude name="jalview.jar" />
<include name="*.jar" />
<include name="*_*.jar" />
- <exclude name="*jnilib.jar" />
+ <exclude name="*quaqua*.jar" />
</fileset>
<property name="jalview.version" value="${JALVIEW_VERSION}" />
</resources>
<resources os="Mac OS X">
<fileset dir="${packageDir}">
- <include name="*quaqua*.jnilib.jar" />
+ <include name="quaqua-filechooser-only-8.0.jar"/>
+ <include name="*quaqua64*.jnilib.jar" />
</fileset>
</resources>
</target>
<target name="packageApplet" depends="compileApplet, buildPropertiesFile">
- <copy file="${resourceDir}/images/idwidth.gif" toFile="${outputDir}/images/idwidth.gif" />
<copy file="${resourceDir}/images/link.gif" toFile="${outputDir}/images/link.gif" />
<copy todir="${outputDir}/lang">
<fileset dir="${resourceDir}/lang">
<include name="MCview/**" />
<include name="jalview/**" />
<include name=".build_properties" />
- <include name="images/idwidth.gif" />
<include name="images/link.gif" />
<include name="lang/**" />
</fileset>
--- /dev/null
+HEADER TRANSFERASE/TRANSFERASE INHIBITOR 01-JAN-13 4IM2
+TITLE STRUCTURE OF TANK-BINDING KINASE 1 (Truncated test file)
+ATOM 3510 N LEU A 468 76.337 90.332 -7.628 1.00168.53 N
+ANISOU 3510 N LEU A 468 19760 15191 29082 5189 1248 -1702 N
+ATOM 3511 CA LEU A 468 75.576 90.788 -6.476 1.00181.60 C
+ANISOU 3511 CA LEU A 468 21073 16927 30998 5158 1421 -2051 C
+ATOM 3512 C LEU A 468 76.285 91.971 -5.836 1.00196.57 C
+ANISOU 3512 C LEU A 468 23029 18636 33021 5053 1667 -2229 C
+ATOM 3513 O LEU A 468 75.727 93.067 -5.733 1.00197.97 O
+ANISOU 3513 O LEU A 468 23115 18581 33523 5166 1662 -2304 O
+ATOM 3514 CB LEU A 468 75.409 89.671 -5.449 1.00173.72 C
+ANISOU 3514 CB LEU A 468 19829 16340 29836 4981 1593 -2304 C
+ATOM 3515 CG LEU A 468 74.099 88.882 -5.420 1.00170.58 C
+ANISOU 3515 CG LEU A 468 19142 16142 29529 5074 1449 -2345 C
+ATOM 3516 CD1 LEU A 468 74.023 87.940 -6.581 1.00167.98 C
+ANISOU 3516 CD1 LEU A 468 18951 15858 29015 5180 1156 -2025 C
+ATOM 3517 CD2 LEU A 468 73.988 88.096 -4.145 1.00165.16 C
+ANISOU 3517 CD2 LEU A 468 18217 15818 28720 4865 1706 -2656 C
+ATOM 3518 N ASP A 469 77.529 91.753 -5.429 1.00208.80 N
+ANISOU 3518 N ASP A 469 24731 20282 34322 4836 1875 -2296 N
+ATOM 3519 CA ASP A 469 78.267 92.785 -4.720 1.00223.11 C
+ANISOU 3519 CA ASP A 469 26577 21960 36233 4701 2123 -2500 C
+ATOM 3520 C ASP A 469 78.653 93.973 -5.599 1.00231.96 C
+ANISOU 3520 C ASP A 469 27954 22654 37525 4817 2037 -2283 C
+ATOM 3521 O ASP A 469 78.718 95.100 -5.118 1.00235.71 O
+ANISOU 3521 O ASP A 469 28377 22940 38242 4798 2175 -2449 O
+ATOM 3522 CB ASP A 469 79.506 92.197 -4.057 1.00224.50 C
+ANISOU 3522 CB ASP A 469 26841 22370 36089 4433 2350 -2633 C
+ATOM 3523 CG ASP A 469 79.748 92.767 -2.679 1.00229.51 C
+ANISOU 3523 CG ASP A 469 27303 23107 36794 4254 2637 -3018 C
+ATOM 3524 OD1 ASP A 469 79.958 93.992 -2.564 1.00232.36 O
+ANISOU 3524 OD1 ASP A 469 27695 23203 37387 4262 2718 -3093 O
+ATOM 3525 OD2 ASP A 469 79.751 91.979 -1.709 1.00229.48 O
+ANISOU 3525 OD2 ASP A 469 27145 23450 36598 4098 2779 -3242 O
+ATOM 3526 N PHE A 470 78.904 93.735 -6.882 1.00233.88 N
+ANISOU 3526 N PHE A 470 28481 22742 37641 4931 1813 -1912 N
+ATOM 3527 CA PHE A 470 79.292 94.831 -7.766 1.00237.73 C
+ANISOU 3527 CA PHE A 470 29252 22819 38256 5033 1733 -1677 C
+ATOM 3528 C PHE A 470 78.103 95.470 -8.467 1.00232.15 C
+ANISOU 3528 C PHE A 470 28512 21868 37828 5322 1470 -1512 C
+ATOM 3529 O PHE A 470 78.021 96.691 -8.532 1.00230.69 O
+ANISOU 3529 O PHE A 470 28371 21372 37909 5402 1493 -1517 O
+ATOM 3530 CB PHE A 470 80.344 94.379 -8.784 1.00242.99 C
+ANISOU 3530 CB PHE A 470 30297 23410 38616 4976 1661 -1357 C
+ATOM 3531 CG PHE A 470 80.663 95.388 -9.839 1.00251.53 C
+ANISOU 3531 CG PHE A 470 31709 24074 39788 5089 1550 -1064 C
+ATOM 3532 CD1 PHE A 470 81.658 96.315 -9.620 1.00252.90 C
+ANISOU 3532 CD1 PHE A 470 32021 24036 40032 4942 1771 -1133 C
+ATOM 3533 CD2 PHE A 470 80.005 95.389 -11.059 1.00255.02 C
+ANISOU 3533 CD2 PHE A 470 32335 24339 40221 5330 1225 -715 C
+ATOM 3534 CE1 PHE A 470 81.981 97.242 -10.575 1.00254.75 C
+ANISOU 3534 CE1 PHE A 470 32569 23879 40344 5028 1688 -862 C
+ATOM 3535 CE2 PHE A 470 80.321 96.320 -12.027 1.00256.76 C
+ANISOU 3535 CE2 PHE A 470 32894 24173 40491 5427 1126 -433 C
+ATOM 3536 CZ PHE A 470 81.313 97.248 -11.784 1.00256.57 C
+ANISOU 3536 CZ PHE A 470 33006 23929 40550 5272 1365 -504 C
+ATOM 3537 N CYS A 471 77.190 94.665 -8.997 1.00176.88 N
+ANISOU 3537 N CYS A 471 20955 21812 24441 2225 -3821 -3711 N
+ATOM 3538 CA CYS A 471 76.124 95.233 -9.815 1.00176.41 C
+ANISOU 3538 CA CYS A 471 20820 21906 24301 2124 -3576 -3614 C
+ATOM 3539 C CYS A 471 74.868 95.631 -9.050 1.00176.82 C
+ANISOU 3539 C CYS A 471 21026 22206 23952 2247 -3588 -3734 C
+ATOM 3540 O CYS A 471 74.632 96.811 -8.854 1.00178.66 O
+ANISOU 3540 O CYS A 471 21175 22393 24314 2353 -3749 -3873 O
+ATOM 3541 CB CYS A 471 75.805 94.346 -11.019 1.00173.95 C
+ANISOU 3541 CB CYS A 471 20521 21694 23877 1925 -3217 -3359 C
+ATOM 3542 SG CYS A 471 76.954 94.571 -12.398 1.00273.04 S
+ANISOU 3542 SG CYS A 471 32850 33934 36957 1863 -3075 -3146 S
+ATOM 3543 N ILE A 472 74.068 94.670 -8.603 1.00173.50 N
+ANISOU 3543 N ILE A 472 20813 22023 23085 2253 -3402 -3662 N
+ATOM 3544 CA ILE A 472 72.771 95.033 -8.022 1.00171.09 C
+ANISOU 3544 CA ILE A 472 20616 21936 22453 2374 -3307 -3694 C
+ATOM 3545 C ILE A 472 72.832 96.022 -6.874 1.00177.82 C
+ANISOU 3545 C ILE A 472 21591 22750 23222 2698 -3611 -3931 C
+ATOM 3546 O ILE A 472 71.992 96.914 -6.776 1.00182.92 O
+ANISOU 3546 O ILE A 472 22220 23491 23792 2778 -3598 -3985 O
+ATOM 3547 CB ILE A 472 71.979 93.843 -7.518 1.00159.41 C
+ANISOU 3547 CB ILE A 472 19318 20653 20599 2393 -3038 -3546 C
+ATOM 3548 CG1 ILE A 472 70.708 93.667 -8.341 1.00147.27 C
+ANISOU 3548 CG1 ILE A 472 17653 19253 19051 2196 -2745 -3384 C
+ATOM 3549 CG2 ILE A 472 71.526 94.090 -6.105 1.00155.95 C
+ANISOU 3549 CG2 ILE A 472 19129 20312 19812 2752 -3085 -3637 C
+ATOM 3550 CD1 ILE A 472 70.927 92.915 -9.606 1.00135.92 C
+ANISOU 3550 CD1 ILE A 472 16097 17752 17794 1929 -2643 -3254 C
+ATOM 3551 N ARG A 473 73.812 95.865 -5.996 1.00180.33 N
+ANISOU 3551 N ARG A 473 22055 22917 23544 2920 -3920 -4092 N
+ATOM 3552 CA ARG A 473 73.860 96.762 -4.877 1.00189.65 C
+ANISOU 3552 CA ARG A 473 23415 24034 24610 3307 -4283 -4357 C
+ATOM 3553 C ARG A 473 74.328 98.021 -5.558 1.00185.98 C
+ANISOU 3553 C ARG A 473 22628 23344 24692 3195 -4530 -4477 C
+ATOM 3554 O ARG A 473 73.519 98.885 -5.866 1.00181.76 O
+ANISOU 3554 O ARG A 473 22002 22904 24153 3165 -4446 -4474 O
+ATOM 3555 CB ARG A 473 74.803 96.287 -3.768 1.00205.24 C
+ANISOU 3555 CB ARG A 473 25661 25862 26460 3635 -4629 -4545 C
+ATOM 3556 CG ARG A 473 74.468 96.921 -2.433 1.00220.50 C
+ANISOU 3556 CG ARG A 473 27955 27814 28011 4171 -4923 -4787 C
+ATOM 3557 CD ARG A 473 75.337 96.433 -1.295 1.00232.58 C
+ANISOU 3557 CD ARG A 473 29837 29192 29341 4591 -5300 -5003 C
+ATOM 3558 NE ARG A 473 76.763 96.602 -1.549 1.00237.46 N
+ANISOU 3558 NE ARG A 473 30220 29440 30564 4489 -5773 -5205 N
+ATOM 3559 CZ ARG A 473 77.716 95.991 -0.861 1.00240.32 C
+ANISOU 3559 CZ ARG A 473 30786 29623 30903 4725 -6098 -5371 C
+ATOM 3560 NH1 ARG A 473 77.388 95.172 0.115 1.00241.12 N
+ANISOU 3560 NH1 ARG A 473 31370 29900 30344 5100 -5978 -5355 N
+ATOM 3561 NH2 ARG A 473 78.988 96.195 -1.159 1.00241.54 N
+ANISOU 3561 NH2 ARG A 473 30651 29398 31724 4605 -6518 -5533 N
+ATOM 3562 N ASN A 474 75.608 98.073 -5.901 1.00188.74 N
+ANISOU 3562 N ASN A 474 22768 23381 25563 3107 -4772 -4534 N
+ATOM 3563 CA ASN A 474 76.168 99.264 -6.526 1.00188.61 C
+ANISOU 3563 CA ASN A 474 22395 23075 26194 3026 -4977 -4605 C
+ATOM 3564 C ASN A 474 75.420 99.892 -7.729 1.00173.98 C
+ANISOU 3564 C ASN A 474 20312 21326 24467 2781 -4623 -4414 C
+ATOM 3565 O ASN A 474 75.482 101.107 -7.891 1.00176.08 O
+ANISOU 3565 O ASN A 474 20374 21426 25104 2827 -4803 -4518 O
+ATOM 3566 CB ASN A 474 77.650 99.066 -6.857 1.00199.45 C
+ANISOU 3566 CB ASN A 474 23514 24060 28207 2939 -5170 -4595 C
+ATOM 3567 CG ASN A 474 78.504 98.809 -5.625 1.00210.23 C
+ANISOU 3567 CG ASN A 474 25062 25219 29597 3243 -5689 -4883 C
+ATOM 3568 OD1 ASN A 474 78.174 99.240 -4.527 1.00215.26 O
+ANISOU 3568 OD1 ASN A 474 25969 25891 29928 3596 -6043 -5160 O
+ATOM 3569 ND2 ASN A 474 79.613 98.103 -5.810 1.00212.07 N
+ANISOU 3569 ND2 ASN A 474 25176 25222 30179 3148 -5748 -4822 N
+ATOM 3570 N ILE A 475 74.722 99.114 -8.562 1.00161.86 N
+ANISOU 3570 N ILE A 475 18813 20033 22652 2556 -4165 -4158 N
+ATOM 3571 CA ILE A 475 74.022 99.727 -9.709 1.00154.84 C
+ANISOU 3571 CA ILE A 475 17755 19216 21861 2390 -3885 -4015 C
+ATOM 3572 C ILE A 475 72.785 100.520 -9.312 1.00159.27 C
+ANISOU 3572 C ILE A 475 18401 19995 22121 2490 -3891 -4125 C
+ATOM 3573 O ILE A 475 72.662 101.687 -9.663 1.00162.60 O
+ANISOU 3573 O ILE A 475 18651 20327 22804 2505 -3962 -4186 O
+ATOM 3574 CB ILE A 475 73.600 98.727 -10.818 1.00214.93 C
+ANISOU 3574 CB ILE A 475 25397 26975 29293 2173 -3475 -3753 C
+ATOM 3575 CG1 ILE A 475 74.808 98.227 -11.613 1.00218.74 C
+ANISOU 3575 CG1 ILE A 475 25753 27211 30145 2083 -3390 -3585 C
+ATOM 3576 CG2 ILE A 475 72.618 99.379 -11.789 1.00210.37 C
+ANISOU 3576 CG2 ILE A 475 24743 26509 28681 2097 -3256 -3677 C
+ATOM 3577 CD1 ILE A 475 74.446 97.201 -12.664 1.00218.15 C
+ANISOU 3577 CD1 ILE A 475 25777 27260 29850 1946 -3056 -3359 C
+ATOM 3578 N GLU A 476 71.856 99.893 -8.600 1.00156.45 N
+ANISOU 3578 N GLU A 476 18293 19907 21245 2571 -3778 -4120 N
+ATOM 3579 CA GLU A 476 70.623 100.594 -8.252 1.00142.72 C
+ANISOU 3579 CA GLU A 476 16627 18370 19231 2677 -3720 -4176 C
+ATOM 3580 C GLU A 476 70.845 101.560 -7.094 1.00144.41 C
+ANISOU 3580 C GLU A 476 16959 18500 19412 3012 -4114 -4440 C
+ATOM 3581 O GLU A 476 70.012 102.417 -6.811 1.00142.58 O
+ANISOU 3581 O GLU A 476 16768 18380 19024 3141 -4136 -4517 O
+ATOM 3582 CB GLU A 476 69.486 99.616 -7.958 1.00128.68 C
+ANISOU 3582 CB GLU A 476 15020 16860 17012 2665 -3395 -4018 C
+ATOM 3583 CG GLU A 476 69.562 98.905 -6.628 1.00128.73 C
+ANISOU 3583 CG GLU A 476 15321 16930 16662 2941 -3433 -4041 C
+ATOM 3584 CD GLU A 476 68.465 97.866 -6.484 1.00133.35 C
+ANISOU 3584 CD GLU A 476 15992 17719 16955 2900 -3026 -3806 C
+ATOM 3585 OE1 GLU A 476 68.285 97.061 -7.422 1.00132.30 O
+ANISOU 3585 OE1 GLU A 476 15710 17598 16962 2603 -2816 -3643 O
+ATOM 3586 OE2 GLU A 476 67.768 97.860 -5.448 1.00136.37 O
+ANISOU 3586 OE2 GLU A 476 16588 18223 17003 3196 -2912 -3773 O
+ATOM 3587 N LYS A 477 71.990 101.424 -6.439 1.00148.46 N
+ANISOU 3587 N LYS A 477 17534 18788 20087 3179 -4467 -4596 N
+ATOM 3588 CA LYS A 477 72.399 102.365 -5.405 1.00154.25 C
+ANISOU 3588 CA LYS A 477 18378 19348 20882 3544 -4976 -4907 C
+ATOM 3589 C LYS A 477 72.634 103.732 -5.994 1.00159.76 C
+ANISOU 3589 C LYS A 477 18754 19833 22117 3467 -5183 -5014 C
+ATOM 3590 O LYS A 477 72.568 104.742 -5.292 1.00158.01 O
+ANISOU 3590 O LYS A 477 18598 19516 21921 3749 -5568 -5266 O
+ATOM 3591 CB LYS A 477 73.667 101.883 -4.706 1.00154.03 C
+ANISOU 3591 CB LYS A 477 18446 19057 21022 3730 -5372 -5076 C
+ATOM 3592 CG LYS A 477 73.367 100.787 -3.750 1.00149.76 C
+ANISOU 3592 CG LYS A 477 18324 18717 19861 3975 -5258 -5042 C
+ATOM 3593 CD LYS A 477 74.437 100.554 -2.740 1.00143.39 C
+ANISOU 3593 CD LYS A 477 17737 17664 19082 4327 -5762 -5306 C
+ATOM 3594 CE LYS A 477 73.739 100.087 -1.488 1.00145.72 C
+ANISOU 3594 CE LYS A 477 18569 18186 18613 4805 -5697 -5337 C
+ATOM 3595 NZ LYS A 477 74.661 99.556 -0.469 1.00149.42 N
+ANISOU 3595 NZ LYS A 477 19366 18470 18936 5206 -6108 -5561 N
+ATOM 3596 N THR A 478 72.908 103.757 -7.293 1.00166.45 N
+ANISOU 3596 N THR A 478 19271 20589 23384 3124 -4918 -4810 N
+ATOM 3597 CA THR A 478 73.186 105.012 -7.968 1.00170.99 C
+ANISOU 3597 CA THR A 478 19509 20929 24531 3052 -5023 -4844 C
+ATOM 3598 C THR A 478 71.905 105.733 -8.391 1.00172.33 C
+ANISOU 3598 C THR A 478 19686 21358 24435 2999 -4780 -4796 C
+ATOM 3599 O THR A 478 71.021 105.170 -9.046 1.00163.10 O
+ANISOU 3599 O THR A 478 18581 20461 22928 2823 -4356 -4594 O
+ATOM 3600 CB THR A 478 74.217 104.856 -9.128 1.00146.93 C
+ANISOU 3600 CB THR A 478 16115 17589 22125 2815 -4843 -4626 C
+ATOM 3601 OG1 THR A 478 74.873 106.106 -9.369 1.00147.15 O
+ANISOU 3601 OG1 THR A 478 15790 17239 22881 2857 -5085 -4705 O
+ATOM 3602 CG2 THR A 478 73.562 104.391 -10.425 1.00144.32 C
+ANISOU 3602 CG2 THR A 478 15764 17473 21597 2570 -4282 -4318 C
+ATOM 3603 N VAL A 479 71.809 106.979 -7.944 1.00177.73 N
+ANISOU 3603 N VAL A 479 20309 21929 25291 3181 -5110 -5014 N
+ATOM 3604 CA VAL A 479 70.674 107.838 -8.218 1.00175.65 C
+ANISOU 3604 CA VAL A 479 20044 21875 24819 3171 -4959 -5013 C
+ATOM 3605 C VAL A 479 71.176 109.077 -8.939 1.00177.67 C
+ANISOU 3605 C VAL A 479 19928 21830 25749 3101 -5069 -5035 C
+ATOM 3606 O VAL A 479 72.353 109.417 -8.840 1.00179.02 O
+ANISOU 3606 O VAL A 479 19865 21600 26555 3150 -5387 -5121 O
+ATOM 3607 CB VAL A 479 69.983 108.266 -6.909 1.00168.37 C
+ANISOU 3607 CB VAL A 479 19442 21113 23418 3524 -5243 -5249 C
+ATOM 3608 CG1 VAL A 479 69.008 109.403 -7.169 1.00162.23 C
+ANISOU 3608 CG1 VAL A 479 18603 20470 22565 3531 -5176 -5285 C
+ATOM 3609 CG2 VAL A 479 69.288 107.080 -6.256 1.00163.89 C
+ANISOU 3609 CG2 VAL A 479 19236 20856 22180 3624 -4991 -5142 C
+ATOM 3610 N MET A 486 57.931 103.433 -6.150 1.00 92.00 N
+ANISOU 3610 N MET A 486 10154 13425 11375 3371 -1523 -3283 N
+ATOM 3611 CA MET A 486 56.824 104.104 -5.482 1.00110.61 C
+ANISOU 3611 CA MET A 486 12558 15882 13585 3644 -1287 -3161 C
+ATOM 3612 C MET A 486 56.182 105.150 -6.389 1.00111.38 C
+ANISOU 3612 C MET A 486 12428 16016 13877 3424 -1416 -3308 C
+ATOM 3613 O MET A 486 56.000 106.305 -6.002 1.00120.35 O
+ANISOU 3613 O MET A 486 13691 17243 14794 3639 -1526 -3430 O
+ATOM 3614 CB MET A 486 57.288 104.743 -4.170 1.00120.60 C
+ANISOU 3614 CB MET A 486 14253 17221 14347 4174 -1395 -3243 C
+ATOM 3615 CG MET A 486 58.405 105.768 -4.316 1.00126.87 C
+ANISOU 3615 CG MET A 486 15171 17987 15047 4196 -1944 -3629 C
+ATOM 3616 SD MET A 486 58.150 107.169 -3.210 1.00146.78 S
+ANISOU 3616 SD MET A 486 18044 20597 17128 4757 -2124 -3782 S
+ATOM 3617 CE MET A 486 58.003 106.326 -1.640 1.00102.35 C
+ANISOU 3617 CE MET A 486 12883 15002 11003 5391 -1797 -3524 C
+ATOM 3618 N GLY A 496 57.154 99.412 -2.065 1.00157.62 N
+ANISOU 3618 N GLY A 496 19150 21656 19083 4616 82 -2024 N
+ATOM 3619 CA GLY A 496 57.031 99.217 -3.498 1.00158.07 C
+ANISOU 3619 CA GLY A 496 18749 21636 19677 3991 -116 -2141 C
+ATOM 3620 C GLY A 496 57.664 97.914 -3.942 1.00163.71 C
+ANISOU 3620 C GLY A 496 19349 22235 20619 3709 -140 -2093 C
+ATOM 3621 O GLY A 496 58.040 97.090 -3.111 1.00167.17 O
+ANISOU 3621 O GLY A 496 20009 22652 20858 3970 79 -1915 O
+ATOM 3622 N GLU A 497 57.778 97.722 -5.254 1.00166.67 N
+ANISOU 3622 N GLU A 497 19413 22530 21383 3222 -403 -2250 N
+ATOM 3623 CA GLU A 497 58.431 96.534 -5.792 1.00170.73 C
+ANISOU 3623 CA GLU A 497 19840 22933 22098 2955 -485 -2239 C
+ATOM 3624 C GLU A 497 59.931 96.621 -5.556 1.00172.64 C
+ANISOU 3624 C GLU A 497 20403 23228 21965 3043 -809 -2472 C
+ATOM 3625 O GLU A 497 60.589 95.609 -5.311 1.00173.01 O
+ANISOU 3625 O GLU A 497 20547 23223 21965 3047 -764 -2395 O
+ATOM 3626 CB GLU A 497 58.173 96.394 -7.290 1.00169.62 C
+ANISOU 3626 CB GLU A 497 19361 22681 22408 2505 -727 -2374 C
+ATOM 3627 CG GLU A 497 56.882 97.012 -7.777 1.00173.11 C
+ANISOU 3627 CG GLU A 497 19518 23086 23171 2413 -663 -2350 C
+ATOM 3628 CD GLU A 497 56.703 96.840 -9.270 1.00173.61 C
+ANISOU 3628 CD GLU A 497 19329 23013 23621 2054 -974 -2531 C
+ATOM 3629 OE1 GLU A 497 57.597 96.241 -9.908 1.00170.78 O
+ANISOU 3629 OE1 GLU A 497 19040 22600 23250 1901 -1202 -2647 O
+ATOM 3630 OE2 GLU A 497 55.672 97.300 -9.805 1.00174.73 O
+ANISOU 3630 OE2 GLU A 497 19233 23093 24064 1967 -999 -2559 O
+ATOM 3631 N ILE A 498 60.466 97.836 -5.652 1.00171.44 N
+ANISOU 3631 N ILE A 498 20381 23149 21608 3107 -1147 -2757 N
+ATOM 3632 CA ILE A 498 61.883 98.078 -5.403 1.00167.93 C
+ANISOU 3632 CA ILE A 498 20186 22695 20926 3210 -1503 -2995 C
+ATOM 3633 C ILE A 498 62.251 97.620 -4.004 1.00173.82 C
+ANISOU 3633 C ILE A 498 21298 23465 21280 3659 -1379 -2903 C
+ATOM 3634 O ILE A 498 63.315 97.034 -3.789 1.00168.12 O
+ANISOU 3634 O ILE A 498 20732 22684 20462 3692 -1544 -2980 O
+ATOM 3635 CB ILE A 498 62.227 99.564 -5.520 1.00165.53 C
+ANISOU 3635 CB ILE A 498 19934 22420 20540 3287 -1855 -3283 C
+ATOM 3636 CG1 ILE A 498 61.848 100.100 -6.901 1.00171.37 C
+ANISOU 3636 CG1 ILE A 498 20360 23137 21618 2911 -1947 -3365 C
+ATOM 3637 CG2 ILE A 498 63.706 99.798 -5.239 1.00153.61 C
+ANISOU 3637 CG2 ILE A 498 18613 20820 18931 3398 -2256 -3525 C
+ATOM 3638 CD1 ILE A 498 61.891 101.605 -6.996 1.00174.73 C
+ANISOU 3638 CD1 ILE A 498 20793 23594 22004 2996 -2195 -3587 C
+ATOM 3639 N SER A 499 61.362 97.890 -3.054 1.00187.32 N
+ANISOU 3639 N SER A 499 23169 25252 22753 4049 -1074 -2727 N
+ATOM 3640 CA SER A 499 61.558 97.444 -1.683 1.00198.47 C
+ANISOU 3640 CA SER A 499 24999 26682 23729 4594 -880 -2593 C
+ATOM 3641 C SER A 499 61.611 95.926 -1.651 1.00206.95 C
+ANISOU 3641 C SER A 499 26003 27687 24943 4481 -548 -2315 C
+ATOM 3642 O SER A 499 62.302 95.334 -0.823 1.00211.11 O
+ANISOU 3642 O SER A 499 26867 28195 25151 4806 -533 -2293 O
+ATOM 3643 CB SER A 499 60.435 97.952 -0.780 1.00200.16 C
+ANISOU 3643 CB SER A 499 25385 26976 23690 5064 -498 -2368 C
+ATOM 3644 OG SER A 499 60.635 97.541 0.556 1.00203.12 O
+ANISOU 3644 OG SER A 499 26244 27359 23574 5697 -286 -2224 O
+ATOM 3645 N ASP A 500 60.877 95.300 -2.564 1.00209.43 N
+ANISOU 3645 N ASP A 500 25883 27938 25751 4040 -320 -2123 N
+ATOM 3646 CA ASP A 500 60.862 93.851 -2.655 1.00212.36 C
+ANISOU 3646 CA ASP A 500 26120 28207 26361 3883 -39 -1865 C
+ATOM 3647 C ASP A 500 62.097 93.307 -3.366 1.00203.21 C
+ANISOU 3647 C ASP A 500 24946 26999 25265 3557 -426 -2093 C
+ATOM 3648 O ASP A 500 62.511 92.195 -3.092 1.00204.96 O
+ANISOU 3648 O ASP A 500 25238 27165 25472 3573 -286 -1954 O
+ATOM 3649 CB ASP A 500 59.580 93.355 -3.335 1.00221.23 C
+ANISOU 3649 CB ASP A 500 26765 29217 28075 3573 287 -1593 C
+ATOM 3650 CG ASP A 500 58.346 93.583 -2.486 1.00233.55 C
+ANISOU 3650 CG ASP A 500 28310 30773 29657 3938 816 -1243 C
+ATOM 3651 OD1 ASP A 500 58.502 93.807 -1.272 1.00239.09 O
+ANISOU 3651 OD1 ASP A 500 29432 31558 29852 4492 1029 -1137 O
+ATOM 3652 OD2 ASP A 500 57.226 93.532 -3.034 1.00237.24 O
+ANISOU 3652 OD2 ASP A 500 28355 31128 30656 3709 1011 -1072 O
+ATOM 3653 N ILE A 501 62.692 94.094 -4.258 1.00192.67 N
+ANISOU 3653 N ILE A 501 23525 25673 24008 3292 -875 -2413 N
+ATOM 3654 CA ILE A 501 63.864 93.633 -5.007 1.00181.71 C
+ANISOU 3654 CA ILE A 501 22108 24215 22719 3006 -1195 -2587 C
+ATOM 3655 C ILE A 501 65.165 93.699 -4.196 1.00170.68 C
+ANISOU 3655 C ILE A 501 21064 22814 20972 3287 -1450 -2764 C
+ATOM 3656 O ILE A 501 65.940 92.735 -4.173 1.00164.70 O
+ANISOU 3656 O ILE A 501 20376 21999 20202 3222 -1476 -2736 O
+ATOM 3657 CB ILE A 501 64.023 94.385 -6.353 1.00138.03 C
+ANISOU 3657 CB ILE A 501 16341 18649 17453 2657 -1507 -2802 C
+ATOM 3658 CG1 ILE A 501 63.385 93.589 -7.491 1.00130.33 C
+ANISOU 3658 CG1 ILE A 501 15061 17587 16872 2296 -1411 -2683 C
+ATOM 3659 CG2 ILE A 501 65.491 94.642 -6.682 1.00137.98 C
+ANISOU 3659 CG2 ILE A 501 16437 18581 17410 2596 -1883 -3037 C
+ATOM 3660 CD1 ILE A 501 61.877 93.516 -7.426 1.00127.50 C
+ANISOU 3660 CD1 ILE A 501 14480 17217 16748 2292 -1111 -2482 C
+ATOM 3661 N HIS A 502 65.396 94.829 -3.532 1.00164.00 N
+ANISOU 3661 N HIS A 502 20439 22007 19869 3613 -1676 -2964 N
+ATOM 3662 CA HIS A 502 66.603 95.022 -2.737 1.00157.69 C
+ANISOU 3662 CA HIS A 502 19968 21147 18800 3931 -2029 -3195 C
+ATOM 3663 C HIS A 502 66.627 94.018 -1.594 1.00162.64 C
+ANISOU 3663 C HIS A 502 20933 21795 19069 4322 -1761 -3012 C
+ATOM 3664 O HIS A 502 67.677 93.496 -1.229 1.00164.35 O
+ANISOU 3664 O HIS A 502 21348 21935 19163 4433 -1971 -3125 O
+ATOM 3665 CB HIS A 502 66.654 96.452 -2.195 1.00150.83 C
+ANISOU 3665 CB HIS A 502 19272 20282 17755 4264 -2351 -3452 C
+ATOM 3666 CG HIS A 502 67.989 97.117 -2.348 1.00143.78 C
+ANISOU 3666 CG HIS A 502 18387 19223 17019 4248 -2929 -3804 C
+ATOM 3667 ND1 HIS A 502 68.672 97.155 -3.544 1.00137.00 N
+ANISOU 3667 ND1 HIS A 502 17193 18253 16609 3785 -3096 -3872 N
+ATOM 3668 CD2 HIS A 502 68.759 97.787 -1.457 1.00140.15 C
+ANISOU 3668 CD2 HIS A 502 18217 18647 16387 4674 -3387 -4099 C
+ATOM 3669 CE1 HIS A 502 69.807 97.814 -3.383 1.00131.33 C
+ANISOU 3669 CE1 HIS A 502 16503 17343 16055 3893 -3583 -4155 C
+ATOM 3670 NE2 HIS A 502 69.883 98.208 -2.125 1.00130.34 N
+ANISOU 3670 NE2 HIS A 502 16741 17200 15583 4416 -3815 -4326 N
+ATOM 3671 N THR A 503 65.450 93.751 -1.039 1.00163.37 N
+ANISOU 3671 N THR A 503 21080 21971 19022 4552 -1268 -2705 N
+ATOM 3672 CA THR A 503 65.295 92.771 0.033 1.00163.31 C
+ANISOU 3672 CA THR A 503 21384 21972 18696 4974 -872 -2437 C
+ATOM 3673 C THR A 503 65.393 91.327 -0.475 1.00151.49 C
+ANISOU 3673 C THR A 503 19659 20415 17484 4610 -614 -2206 C
+ATOM 3674 O THR A 503 65.955 90.464 0.198 1.00146.11 O
+ANISOU 3674 O THR A 503 19247 19705 16563 4853 -520 -2130 O
+ATOM 3675 CB THR A 503 63.956 92.972 0.783 1.00170.09 C
+ANISOU 3675 CB THR A 503 22342 22899 19387 5379 -334 -2106 C
+ATOM 3676 OG1 THR A 503 64.026 94.162 1.576 1.00176.61 O
+ANISOU 3676 OG1 THR A 503 23551 23775 19778 5902 -585 -2325 O
+ATOM 3677 CG2 THR A 503 63.645 91.790 1.693 1.00171.53 C
+ANISOU 3677 CG2 THR A 503 22747 23054 19374 5760 235 -1707 C
+ATOM 3678 N LYS A 504 64.865 91.071 -1.669 1.00141.41 N
+ANISOU 3678 N LYS A 504 17911 19106 16711 4058 -541 -2117 N
+ATOM 3679 CA LYS A 504 64.918 89.730 -2.251 1.00138.96 C
+ANISOU 3679 CA LYS A 504 17368 18711 16719 3706 -369 -1930 C
+ATOM 3680 C LYS A 504 66.335 89.382 -2.646 1.00142.04 C
+ANISOU 3680 C LYS A 504 17848 19062 17058 3520 -779 -2178 C
+ATOM 3681 O LYS A 504 66.762 88.230 -2.559 1.00134.46 O
+ANISOU 3681 O LYS A 504 16927 18053 16108 3463 -666 -2057 O
+ATOM 3682 CB LYS A 504 64.010 89.614 -3.477 1.00129.82 C
+ANISOU 3682 CB LYS A 504 15721 17488 16116 3223 -303 -1839 C
+ATOM 3683 CG LYS A 504 62.585 89.222 -3.164 1.00130.75 C
+ANISOU 3683 CG LYS A 504 15616 17544 16518 3307 225 -1458 C
+ATOM 3684 N LEU A 505 67.053 90.395 -3.100 1.00138.41 N
+ANISOU 3684 N LEU A 505 17394 18602 16593 3427 -1237 -2505 N
+ATOM 3685 CA LEU A 505 68.435 90.224 -3.458 1.00120.29 C
+ANISOU 3685 CA LEU A 505 15154 16230 14322 3285 -1619 -2726 C
+ATOM 3686 C LEU A 505 69.260 89.889 -2.223 1.00124.70 C
+ANISOU 3686 C LEU A 505 16126 16770 14484 3724 -1710 -2800 C
+ATOM 3687 O LEU A 505 70.166 89.052 -2.259 1.00124.02 O
+ANISOU 3687 O LEU A 505 16106 16619 14396 3643 -1808 -2823 O
+ATOM 3688 CB LEU A 505 68.966 91.499 -4.066 1.00109.42 C
+ANISOU 3688 CB LEU A 505 13673 14807 13094 3171 -2036 -3016 C
+ATOM 3689 CG LEU A 505 70.386 91.097 -4.404 1.00128.61 C
+ANISOU 3689 CG LEU A 505 16120 17111 15635 3034 -2336 -3157 C
+ATOM 3690 CD1 LEU A 505 70.509 91.048 -5.920 1.00141.22 C
+ANISOU 3690 CD1 LEU A 505 17393 18648 17616 2580 -2370 -3131 C
+ATOM 3691 CD2 LEU A 505 71.441 91.946 -3.655 1.00114.58 C
+ANISOU 3691 CD2 LEU A 505 14554 15224 13758 3350 -2784 -3462 C
+ATOM 3692 N LEU A 506 68.951 90.579 -1.132 1.00130.40 N
+ANISOU 3692 N LEU A 506 17159 17539 14847 4233 -1705 -2854 N
+ATOM 3693 CA LEU A 506 69.612 90.336 0.139 1.00131.63 C
+ANISOU 3693 CA LEU A 506 17798 17665 14549 4786 -1814 -2947 C
+ATOM 3694 C LEU A 506 69.501 88.865 0.507 1.00144.65 C
+ANISOU 3694 C LEU A 506 19548 19330 16080 4841 -1380 -2638 C
+ATOM 3695 O LEU A 506 70.448 88.287 1.024 1.00156.36 O
+ANISOU 3695 O LEU A 506 21304 20754 17351 5038 -1550 -2741 O
+ATOM 3696 CB LEU A 506 69.008 91.206 1.240 1.00120.17 C
+ANISOU 3696 CB LEU A 506 16713 16270 12675 5409 -1772 -2980 C
+ATOM 3697 N ARG A 507 68.351 88.260 0.214 1.00146.01 N
+ANISOU 3697 N ARG A 507 19470 19552 16453 4658 -839 -2263 N
+ATOM 3698 CA ARG A 507 68.159 86.831 0.443 1.00152.26 C
+ANISOU 3698 CA ARG A 507 20261 20320 17271 4649 -394 -1930 C
+ATOM 3699 C ARG A 507 69.164 86.004 -0.360 1.00145.14 C
+ANISOU 3699 C ARG A 507 19199 19352 16597 4200 -653 -2042 C
+ATOM 3700 O ARG A 507 69.471 84.873 0.007 1.00142.95 O
+ANISOU 3700 O ARG A 507 19044 19045 16224 4273 -450 -1882 O
+ATOM 3701 CB ARG A 507 66.724 86.401 0.111 1.00161.16 C
+ANISOU 3701 CB ARG A 507 21023 21434 18777 4463 165 -1523 C
+ATOM 3702 CG ARG A 507 65.661 86.975 1.046 1.00177.63 C
+ANISOU 3702 CG ARG A 507 23283 23565 20645 4978 585 -1290 C
+ATOM 3703 CD ARG A 507 64.263 86.468 0.696 1.00187.68 C
+ANISOU 3703 CD ARG A 507 24111 24757 22442 4769 1148 -857 C
+ATOM 3704 NE ARG A 507 63.229 87.082 1.527 1.00198.88 N
+ANISOU 3704 NE ARG A 507 25661 26202 23704 5259 1588 -600 N
+ATOM 3705 CZ ARG A 507 61.923 86.883 1.368 1.00205.71 C
+ANISOU 3705 CZ ARG A 507 26137 26967 25058 5169 2095 -210 C
+ATOM 3706 NH1 ARG A 507 61.484 86.084 0.406 1.00207.33 N
+ANISOU 3706 NH1 ARG A 507 25797 27020 25959 4610 2159 -75 N
+ATOM 3707 NH2 ARG A 507 61.055 87.485 2.171 1.00208.11 N
+ANISOU 3707 NH2 ARG A 507 26596 27293 25185 5668 2517 41 N
+ATOM 3708 N LEU A 508 69.681 86.579 -1.445 1.00134.19 N
+ANISOU 3708 N LEU A 508 17555 17933 15496 3776 -1072 -2294 N
+ATOM 3709 CA LEU A 508 70.654 85.888 -2.287 1.00125.06 C
+ANISOU 3709 CA LEU A 508 16259 16704 14555 3385 -1304 -2382 C
+ATOM 3710 C LEU A 508 72.070 85.983 -1.730 1.00133.75 C
+ANISOU 3710 C LEU A 508 17660 17739 15419 3609 -1705 -2655 C
+ATOM 3711 O LEU A 508 72.775 84.975 -1.650 1.00132.42 O
+ANISOU 3711 O LEU A 508 17581 17530 15202 3562 -1700 -2615 O
+ATOM 3712 CB LEU A 508 70.606 86.404 -3.726 1.00112.64 C
+ANISOU 3712 CB LEU A 508 14312 15095 13392 2907 -1513 -2482 C
+ATOM 3713 CG LEU A 508 69.271 86.186 -4.436 1.00113.17 C
+ANISOU 3713 CG LEU A 508 14056 15174 13769 2653 -1215 -2260 C
+ATOM 3714 CD1 LEU A 508 69.459 86.184 -5.945 1.00106.22 C
+ANISOU 3714 CD1 LEU A 508 12898 14225 13237 2216 -1432 -2343 C
+ATOM 3715 CD2 LEU A 508 68.613 84.894 -3.968 1.00117.32 C
+ANISOU 3715 CD2 LEU A 508 14560 15678 14341 2703 -779 -1932 C
+ATOM 3716 N SER A 509 72.491 87.188 -1.355 1.00130.72 N
+ANISOU 3716 N SER A 509 17414 17317 14936 3856 -2085 -2944 N
+ATOM 3717 CA SER A 509 73.767 87.347 -0.663 1.00136.66 C
+ANISOU 3717 CA SER A 509 18457 17948 15519 4156 -2531 -3236 C
+ATOM 3718 C SER A 509 73.698 86.583 0.646 1.00143.40 C
+ANISOU 3718 C SER A 509 19773 18845 15866 4687 -2319 -3138 C
+ATOM 3719 O SER A 509 74.680 85.977 1.082 1.00138.35 O
+ANISOU 3719 O SER A 509 19358 18121 15090 4839 -2521 -3256 O
+ATOM 3720 CB SER A 509 74.089 88.820 -0.410 1.00130.15 C
+ANISOU 3720 CB SER A 509 17685 17028 14738 4382 -3008 -3572 C
+ATOM 3721 OG SER A 509 74.991 89.319 -1.384 1.00125.27 O
+ANISOU 3721 OG SER A 509 16739 16248 14609 4003 -3376 -3749 O
+ATOM 3722 N SER A 510 72.520 86.615 1.263 1.00144.65 N
+ANISOU 3722 N SER A 510 20078 19123 15761 4999 -1878 -2899 N
+ATOM 3723 CA SER A 510 72.236 85.777 2.417 1.00148.97 C
+ANISOU 3723 CA SER A 510 21044 19713 15846 5526 -1487 -2677 C
+ATOM 3724 C SER A 510 72.424 84.315 2.046 1.00145.48 C
+ANISOU 3724 C SER A 510 20455 19266 15554 5204 -1182 -2426 C
+ATOM 3725 O SER A 510 73.001 83.552 2.811 1.00140.49 O
+ANISOU 3725 O SER A 510 20177 18606 14598 5539 -1145 -2415 O
+ATOM 3726 CB SER A 510 70.807 85.999 2.911 1.00149.05 C
+ANISOU 3726 CB SER A 510 21111 19824 15699 5832 -930 -2348 C
+ATOM 3727 OG SER A 510 70.346 84.882 3.643 1.00147.27 O
+ANISOU 3727 OG SER A 510 21097 19617 15240 6154 -337 -1962 O
+ATOM 3728 N SER A 511 71.946 83.946 0.858 1.00139.39 N
+ANISOU 3728 N SER A 511 19184 18508 15269 4583 -1004 -2249 N
+ATOM 3729 CA SER A 511 72.011 82.573 0.365 1.00129.68 C
+ANISOU 3729 CA SER A 511 17763 17254 14255 4236 -745 -2013 C
+ATOM 3730 C SER A 511 73.437 82.171 0.006 1.00129.30 C
+ANISOU 3730 C SER A 511 17762 17135 14232 4035 -1175 -2258 C
+ATOM 3731 O SER A 511 73.792 80.991 0.047 1.00109.17 O
+ANISOU 3731 O SER A 511 15254 14565 11659 3957 -1019 -2119 O
+ATOM 3732 CB SER A 511 71.108 82.416 -0.862 1.00125.40 C
+ANISOU 3732 CB SER A 511 16701 16703 14243 3684 -564 -1828 C
+ATOM 3733 OG SER A 511 71.167 81.106 -1.394 1.00137.08 O
+ANISOU 3733 OG SER A 511 17990 18125 15969 3359 -392 -1635 O
+ATOM 3734 N GLN A 512 74.247 83.164 -0.347 1.00131.12 N
+ANISOU 3734 N GLN A 512 17958 17304 14560 3957 -1699 -2603 N
+ATOM 3735 CA GLN A 512 75.621 82.941 -0.774 1.00120.52 C
+ANISOU 3735 CA GLN A 512 16587 15845 13361 3755 -2110 -2821 C
+ATOM 3736 C GLN A 512 76.508 82.796 0.431 1.00123.24 C
+ANISOU 3736 C GLN A 512 17385 16120 13322 4264 -2359 -3023 C
+ATOM 3737 O GLN A 512 77.569 82.174 0.385 1.00128.94 O
+ANISOU 3737 O GLN A 512 18162 16749 14081 4188 -2573 -3124 O
+ATOM 3738 CB GLN A 512 76.096 84.150 -1.546 1.00118.44 C
+ANISOU 3738 CB GLN A 512 16077 15483 13440 3537 -2531 -3073 C
+ATOM 3739 CG GLN A 512 76.798 83.822 -2.807 1.00125.91 C
+ANISOU 3739 CG GLN A 512 16711 16343 14787 3048 -2644 -3057 C
+ATOM 3740 CD GLN A 512 76.915 85.020 -3.690 1.00137.22 C
+ANISOU 3740 CD GLN A 512 17859 17690 16589 2843 -2877 -3186 C
+ATOM 3741 OE1 GLN A 512 77.456 86.052 -3.281 1.00153.03 O
+ANISOU 3741 OE1 GLN A 512 19904 19568 18672 3053 -3245 -3442 O
+ATOM 3742 NE2 GLN A 512 76.353 84.922 -4.897 1.00128.62 N
+ANISOU 3742 NE2 GLN A 512 16487 16643 15739 2470 -2678 -3017 N
+ATOM 3743 N GLY A 513 76.073 83.422 1.510 1.00128.93 N
+ANISOU 3743 N GLY A 513 18453 16869 13665 4826 -2362 -3100 N
+ATOM 3744 CA GLY A 513 76.767 83.309 2.761 1.00135.31 C
+ANISOU 3744 CA GLY A 513 19790 17602 14021 5449 -2610 -3308 C
+ATOM 3745 C GLY A 513 76.597 81.908 3.295 1.00133.10 C
+ANISOU 3745 C GLY A 513 19748 17398 13425 5620 -2132 -3010 C
+ATOM 3746 O GLY A 513 77.464 81.407 3.988 1.00135.48 O
+ANISOU 3746 O GLY A 513 20407 17622 13448 5952 -2344 -3163 O
+ATOM 3747 N THR A 514 75.478 81.270 2.971 1.00130.00 N
+ANISOU 3747 N THR A 514 19139 17128 13128 5402 -1499 -2584 N
+ATOM 3748 CA THR A 514 75.252 79.899 3.409 1.00136.05 C
+ANISOU 3748 CA THR A 514 20053 17932 13707 5525 -990 -2248 C
+ATOM 3749 C THR A 514 76.125 78.980 2.571 1.00136.91 C
+ANISOU 3749 C THR A 514 19914 17993 14111 4991 -1151 -2279 C
+ATOM 3750 O THR A 514 76.451 77.859 2.971 1.00136.85 O
+ANISOU 3750 O THR A 514 20093 17981 13923 5102 -944 -2139 O
+ATOM 3751 CB THR A 514 73.784 79.475 3.234 1.00141.83 C
+ANISOU 3751 CB THR A 514 20522 18734 14631 5408 -287 -1768 C
+ATOM 3752 OG1 THR A 514 73.591 78.921 1.927 1.00142.93 O
+ANISOU 3752 OG1 THR A 514 20113 18858 15336 4676 -233 -1640 O
+ATOM 3753 CG2 THR A 514 72.861 80.659 3.413 1.00145.09 C
+ANISOU 3753 CG2 THR A 514 20916 19192 15018 5620 -214 -1761 C
+ATOM 3754 N ILE A 515 76.491 79.473 1.394 1.00129.08 N
+ANISOU 3754 N ILE A 515 18518 16960 13565 4442 -1494 -2442 N
+ATOM 3755 CA ILE A 515 77.327 78.735 0.468 1.00119.39 C
+ANISOU 3755 CA ILE A 515 17053 15677 12633 3951 -1657 -2465 C
+ATOM 3756 C ILE A 515 78.787 78.796 0.895 1.00127.05 C
+ANISOU 3756 C ILE A 515 18275 16524 13475 4143 -2161 -2798 C
+ATOM 3757 O ILE A 515 79.482 77.778 0.906 1.00128.44 O
+ANISOU 3757 O ILE A 515 18530 16671 13600 4065 -2153 -2760 O
+ATOM 3758 CB ILE A 515 77.220 79.308 -0.945 1.00110.42 C
+ANISOU 3758 CB ILE A 515 15452 14516 11987 3401 -1815 -2500 C
+ATOM 3759 CG1 ILE A 515 75.801 79.150 -1.481 1.00109.39 C
+ANISOU 3759 CG1 ILE A 515 15038 14466 12060 3177 -1388 -2203 C
+ATOM 3760 CG2 ILE A 515 78.168 78.587 -1.861 1.00112.80 C
+ANISOU 3760 CG2 ILE A 515 15581 14743 12533 2997 -1979 -2516 C
+ATOM 3761 CD1 ILE A 515 75.570 79.879 -2.780 1.00110.01 C
+ANISOU 3761 CD1 ILE A 515 14740 14519 12538 2759 -1561 -2268 C
+ATOM 3762 N GLU A 516 79.240 79.996 1.247 1.00122.76 N
+ANISOU 3762 N GLU A 516 17837 15878 12927 4400 -2627 -3132 N
+ATOM 3763 CA GLU A 516 80.636 80.218 1.589 1.00124.18 C
+ANISOU 3763 CA GLU A 516 18172 15860 13149 4571 -3208 -3493 C
+ATOM 3764 C GLU A 516 81.099 79.274 2.681 1.00126.09 C
+ANISOU 3764 C GLU A 516 18894 16095 12918 5029 -3183 -3522 C
+ATOM 3765 O GLU A 516 82.117 78.595 2.539 1.00116.84 O
+ANISOU 3765 O GLU A 516 17721 14825 11848 4893 -3381 -3605 O
+ATOM 3766 CB GLU A 516 80.863 81.656 2.046 1.00135.21 C
+ANISOU 3766 CB GLU A 516 19658 17112 14603 4907 -3722 -3854 C
+ATOM 3767 CG GLU A 516 82.315 82.045 1.962 1.00146.41 C
+ANISOU 3767 CG GLU A 516 20992 18238 16400 4885 -4381 -4215 C
+ATOM 3768 CD GLU A 516 82.865 81.775 0.582 1.00151.28 C
+ANISOU 3768 CD GLU A 516 21100 18789 17590 4220 -4329 -4073 C
+ATOM 3769 OE1 GLU A 516 82.373 82.413 -0.367 1.00146.52 O
+ANISOU 3769 OE1 GLU A 516 20133 18221 17316 3867 -4198 -3957 O
+ATOM 3770 OE2 GLU A 516 83.763 80.917 0.441 1.00154.24 O
+ANISOU 3770 OE2 GLU A 516 21471 19078 18055 4089 -4397 -4065 O
+END
--- /dev/null
+TITLE STRUCTURE OF TANK-BINDING KINASE 1 (Truncated test file)
+ATOM 3510 N LEU A 468 76.337 90.332 -7.628 1.00168.53 N
+ANISOU 3510 N LEU A 468 19760 15191 29082 5189 1248 -1702 N
+ATOM 3511 CA LEU A 468 75.576 90.788 -6.476 1.00181.60 C
+ANISOU 3511 CA LEU A 468 21073 16927 30998 5158 1421 -2051 C
+ATOM 3512 C LEU A 468 76.285 91.971 -5.836 1.00196.57 C
+ANISOU 3512 C LEU A 468 23029 18636 33021 5053 1667 -2229 C
+ATOM 3513 O LEU A 468 75.727 93.067 -5.733 1.00197.97 O
+ANISOU 3513 O LEU A 468 23115 18581 33523 5166 1662 -2304 O
+ATOM 3514 CB LEU A 468 75.409 89.671 -5.449 1.00173.72 C
+ANISOU 3514 CB LEU A 468 19829 16340 29836 4981 1593 -2304 C
+ATOM 3515 CG LEU A 468 74.099 88.882 -5.420 1.00170.58 C
+ANISOU 3515 CG LEU A 468 19142 16142 29529 5074 1449 -2345 C
+ATOM 3516 CD1 LEU A 468 74.023 87.940 -6.581 1.00167.98 C
+ANISOU 3516 CD1 LEU A 468 18951 15858 29015 5180 1156 -2025 C
+ATOM 3517 CD2 LEU A 468 73.988 88.096 -4.145 1.00165.16 C
+ANISOU 3517 CD2 LEU A 468 18217 15818 28720 4865 1706 -2656 C
+ATOM 3518 N ASP A 469 77.529 91.753 -5.429 1.00208.80 N
+ANISOU 3518 N ASP A 469 24731 20282 34322 4836 1875 -2296 N
+ATOM 3519 CA ASP A 469 78.267 92.785 -4.720 1.00223.11 C
+ANISOU 3519 CA ASP A 469 26577 21960 36233 4701 2123 -2500 C
+ATOM 3520 C ASP A 469 78.653 93.973 -5.599 1.00231.96 C
+ANISOU 3520 C ASP A 469 27954 22654 37525 4817 2037 -2283 C
+ATOM 3521 O ASP A 469 78.718 95.100 -5.118 1.00235.71 O
+ANISOU 3521 O ASP A 469 28377 22940 38242 4798 2175 -2449 O
+ATOM 3522 CB ASP A 469 79.506 92.197 -4.057 1.00224.50 C
+ANISOU 3522 CB ASP A 469 26841 22370 36089 4433 2350 -2633 C
+ATOM 3523 CG ASP A 469 79.748 92.767 -2.679 1.00229.51 C
+ANISOU 3523 CG ASP A 469 27303 23107 36794 4254 2637 -3018 C
+ATOM 3524 OD1 ASP A 469 79.958 93.992 -2.564 1.00232.36 O
+ANISOU 3524 OD1 ASP A 469 27695 23203 37387 4262 2718 -3093 O
+ATOM 3525 OD2 ASP A 469 79.751 91.979 -1.709 1.00229.48 O
+ANISOU 3525 OD2 ASP A 469 27145 23450 36598 4098 2779 -3242 O
+ATOM 3526 N PHE A 470 78.904 93.735 -6.882 1.00233.88 N
+ANISOU 3526 N PHE A 470 28481 22742 37641 4931 1813 -1912 N
+ATOM 3527 CA PHE A 470 79.292 94.831 -7.766 1.00237.73 C
+ANISOU 3527 CA PHE A 470 29252 22819 38256 5033 1733 -1677 C
+ATOM 3528 C PHE A 470 78.103 95.470 -8.467 1.00232.15 C
+ANISOU 3528 C PHE A 470 28512 21868 37828 5322 1470 -1512 C
+ATOM 3529 O PHE A 470 78.021 96.691 -8.532 1.00230.69 O
+ANISOU 3529 O PHE A 470 28371 21372 37909 5402 1493 -1517 O
+ATOM 3530 CB PHE A 470 80.344 94.379 -8.784 1.00242.99 C
+ANISOU 3530 CB PHE A 470 30297 23410 38616 4976 1661 -1357 C
+ATOM 3531 CG PHE A 470 80.663 95.388 -9.839 1.00251.53 C
+ANISOU 3531 CG PHE A 470 31709 24074 39788 5089 1550 -1064 C
+ATOM 3532 CD1 PHE A 470 81.658 96.315 -9.620 1.00252.90 C
+ANISOU 3532 CD1 PHE A 470 32021 24036 40032 4942 1771 -1133 C
+ATOM 3533 CD2 PHE A 470 80.005 95.389 -11.059 1.00255.02 C
+ANISOU 3533 CD2 PHE A 470 32335 24339 40221 5330 1225 -715 C
+ATOM 3534 CE1 PHE A 470 81.981 97.242 -10.575 1.00254.75 C
+ANISOU 3534 CE1 PHE A 470 32569 23879 40344 5028 1688 -862 C
+ATOM 3535 CE2 PHE A 470 80.321 96.320 -12.027 1.00256.76 C
+ANISOU 3535 CE2 PHE A 470 32894 24173 40491 5427 1126 -433 C
+ATOM 3536 CZ PHE A 470 81.313 97.248 -11.784 1.00256.57 C
+ANISOU 3536 CZ PHE A 470 33006 23929 40550 5272 1365 -504 C
+ATOM 3537 N CYS A 471 77.190 94.665 -8.997 1.00176.88 N
+ANISOU 3537 N CYS A 471 20955 21812 24441 2225 -3821 -3711 N
+ATOM 3538 CA CYS A 471 76.124 95.233 -9.815 1.00176.41 C
+ANISOU 3538 CA CYS A 471 20820 21906 24301 2124 -3576 -3614 C
+ATOM 3539 C CYS A 471 74.868 95.631 -9.050 1.00176.82 C
+ANISOU 3539 C CYS A 471 21026 22206 23952 2247 -3588 -3734 C
+ATOM 3540 O CYS A 471 74.632 96.811 -8.854 1.00178.66 O
+ANISOU 3540 O CYS A 471 21175 22393 24314 2353 -3749 -3873 O
+ATOM 3541 CB CYS A 471 75.805 94.346 -11.019 1.00173.95 C
+ANISOU 3541 CB CYS A 471 20521 21694 23877 1925 -3217 -3359 C
+ATOM 3542 SG CYS A 471 76.954 94.571 -12.398 1.00273.04 S
+ANISOU 3542 SG CYS A 471 32850 33934 36957 1863 -3075 -3146 S
+ATOM 3543 N ILE A 472 74.068 94.670 -8.603 1.00173.50 N
+ANISOU 3543 N ILE A 472 20813 22023 23085 2253 -3402 -3662 N
+ATOM 3544 CA ILE A 472 72.771 95.033 -8.022 1.00171.09 C
+ANISOU 3544 CA ILE A 472 20616 21936 22453 2374 -3307 -3694 C
+ATOM 3545 C ILE A 472 72.832 96.022 -6.874 1.00177.82 C
+ANISOU 3545 C ILE A 472 21591 22750 23222 2698 -3611 -3931 C
+ATOM 3546 O ILE A 472 71.992 96.914 -6.776 1.00182.92 O
+ANISOU 3546 O ILE A 472 22220 23491 23792 2778 -3598 -3985 O
+ATOM 3547 CB ILE A 472 71.979 93.843 -7.518 1.00159.41 C
+ANISOU 3547 CB ILE A 472 19318 20653 20599 2393 -3038 -3546 C
+ATOM 3548 CG1 ILE A 472 70.708 93.667 -8.341 1.00147.27 C
+ANISOU 3548 CG1 ILE A 472 17653 19253 19051 2196 -2745 -3384 C
+ATOM 3549 CG2 ILE A 472 71.526 94.090 -6.105 1.00155.95 C
+ANISOU 3549 CG2 ILE A 472 19129 20312 19812 2752 -3085 -3637 C
+ATOM 3550 CD1 ILE A 472 70.927 92.915 -9.606 1.00135.92 C
+ANISOU 3550 CD1 ILE A 472 16097 17752 17794 1929 -2643 -3254 C
+ATOM 3551 N ARG A 473 73.812 95.865 -5.996 1.00180.33 N
+ANISOU 3551 N ARG A 473 22055 22917 23544 2920 -3920 -4092 N
+ATOM 3552 CA ARG A 473 73.860 96.762 -4.877 1.00189.65 C
+ANISOU 3552 CA ARG A 473 23415 24034 24610 3307 -4283 -4357 C
+ATOM 3553 C ARG A 473 74.328 98.021 -5.558 1.00185.98 C
+ANISOU 3553 C ARG A 473 22628 23344 24692 3195 -4530 -4477 C
+ATOM 3554 O ARG A 473 73.519 98.885 -5.866 1.00181.76 O
+ANISOU 3554 O ARG A 473 22002 22904 24153 3165 -4446 -4474 O
+ATOM 3555 CB ARG A 473 74.803 96.287 -3.768 1.00205.24 C
+ANISOU 3555 CB ARG A 473 25661 25862 26460 3635 -4629 -4545 C
+ATOM 3556 CG ARG A 473 74.468 96.921 -2.433 1.00220.50 C
+ANISOU 3556 CG ARG A 473 27955 27814 28011 4171 -4923 -4787 C
+ATOM 3557 CD ARG A 473 75.337 96.433 -1.295 1.00232.58 C
+ANISOU 3557 CD ARG A 473 29837 29192 29341 4591 -5300 -5003 C
+ATOM 3558 NE ARG A 473 76.763 96.602 -1.549 1.00237.46 N
+ANISOU 3558 NE ARG A 473 30220 29440 30564 4489 -5773 -5205 N
+ATOM 3559 CZ ARG A 473 77.716 95.991 -0.861 1.00240.32 C
+ANISOU 3559 CZ ARG A 473 30786 29623 30903 4725 -6098 -5371 C
+ATOM 3560 NH1 ARG A 473 77.388 95.172 0.115 1.00241.12 N
+ANISOU 3560 NH1 ARG A 473 31370 29900 30344 5100 -5978 -5355 N
+ATOM 3561 NH2 ARG A 473 78.988 96.195 -1.159 1.00241.54 N
+ANISOU 3561 NH2 ARG A 473 30651 29398 31724 4605 -6518 -5533 N
+ATOM 3562 N ASN A 474 75.608 98.073 -5.901 1.00188.74 N
+ANISOU 3562 N ASN A 474 22768 23381 25563 3107 -4772 -4534 N
+ATOM 3563 CA ASN A 474 76.168 99.264 -6.526 1.00188.61 C
+ANISOU 3563 CA ASN A 474 22395 23075 26194 3026 -4977 -4605 C
+ATOM 3564 C ASN A 474 75.420 99.892 -7.729 1.00173.98 C
+ANISOU 3564 C ASN A 474 20312 21326 24467 2781 -4623 -4414 C
+ATOM 3565 O ASN A 474 75.482 101.107 -7.891 1.00176.08 O
+ANISOU 3565 O ASN A 474 20374 21426 25104 2827 -4803 -4518 O
+ATOM 3566 CB ASN A 474 77.650 99.066 -6.857 1.00199.45 C
+ANISOU 3566 CB ASN A 474 23514 24060 28207 2939 -5170 -4595 C
+ATOM 3567 CG ASN A 474 78.504 98.809 -5.625 1.00210.23 C
+ANISOU 3567 CG ASN A 474 25062 25219 29597 3243 -5689 -4883 C
+ATOM 3568 OD1 ASN A 474 78.174 99.240 -4.527 1.00215.26 O
+ANISOU 3568 OD1 ASN A 474 25969 25891 29928 3596 -6043 -5160 O
+ATOM 3569 ND2 ASN A 474 79.613 98.103 -5.810 1.00212.07 N
+ANISOU 3569 ND2 ASN A 474 25176 25222 30179 3148 -5748 -4822 N
+ATOM 3570 N ILE A 475 74.722 99.114 -8.562 1.00161.86 N
+ANISOU 3570 N ILE A 475 18813 20033 22652 2556 -4165 -4158 N
+ATOM 3571 CA ILE A 475 74.022 99.727 -9.709 1.00154.84 C
+ANISOU 3571 CA ILE A 475 17755 19216 21861 2390 -3885 -4015 C
+ATOM 3572 C ILE A 475 72.785 100.520 -9.312 1.00159.27 C
+ANISOU 3572 C ILE A 475 18401 19995 22121 2490 -3891 -4125 C
+ATOM 3573 O ILE A 475 72.662 101.687 -9.663 1.00162.60 O
+ANISOU 3573 O ILE A 475 18651 20327 22804 2505 -3962 -4186 O
+ATOM 3574 CB ILE A 475 73.600 98.727 -10.818 1.00214.93 C
+ANISOU 3574 CB ILE A 475 25397 26975 29293 2173 -3475 -3753 C
+ATOM 3575 CG1 ILE A 475 74.808 98.227 -11.613 1.00218.74 C
+ANISOU 3575 CG1 ILE A 475 25753 27211 30145 2083 -3390 -3585 C
+ATOM 3576 CG2 ILE A 475 72.618 99.379 -11.789 1.00210.37 C
+ANISOU 3576 CG2 ILE A 475 24743 26509 28681 2097 -3256 -3677 C
+ATOM 3577 CD1 ILE A 475 74.446 97.201 -12.664 1.00218.15 C
+ANISOU 3577 CD1 ILE A 475 25777 27260 29850 1946 -3056 -3359 C
+ATOM 3578 N GLU A 476 71.856 99.893 -8.600 1.00156.45 N
+ANISOU 3578 N GLU A 476 18293 19907 21245 2571 -3778 -4120 N
+ATOM 3579 CA GLU A 476 70.623 100.594 -8.252 1.00142.72 C
+ANISOU 3579 CA GLU A 476 16627 18370 19231 2677 -3720 -4176 C
+ATOM 3580 C GLU A 476 70.845 101.560 -7.094 1.00144.41 C
+ANISOU 3580 C GLU A 476 16959 18500 19412 3012 -4114 -4440 C
+ATOM 3581 O GLU A 476 70.012 102.417 -6.811 1.00142.58 O
+ANISOU 3581 O GLU A 476 16768 18380 19024 3141 -4136 -4517 O
+ATOM 3582 CB GLU A 476 69.486 99.616 -7.958 1.00128.68 C
+ANISOU 3582 CB GLU A 476 15020 16860 17012 2665 -3395 -4018 C
+ATOM 3583 CG GLU A 476 69.562 98.905 -6.628 1.00128.73 C
+ANISOU 3583 CG GLU A 476 15321 16930 16662 2941 -3433 -4041 C
+ATOM 3584 CD GLU A 476 68.465 97.866 -6.484 1.00133.35 C
+ANISOU 3584 CD GLU A 476 15992 17719 16955 2900 -3026 -3806 C
+ATOM 3585 OE1 GLU A 476 68.285 97.061 -7.422 1.00132.30 O
+ANISOU 3585 OE1 GLU A 476 15710 17598 16962 2603 -2816 -3643 O
+ATOM 3586 OE2 GLU A 476 67.768 97.860 -5.448 1.00136.37 O
+ANISOU 3586 OE2 GLU A 476 16588 18223 17003 3196 -2912 -3773 O
+ATOM 3587 N LYS A 477 71.990 101.424 -6.439 1.00148.46 N
+ANISOU 3587 N LYS A 477 17534 18788 20087 3179 -4467 -4596 N
+ATOM 3588 CA LYS A 477 72.399 102.365 -5.405 1.00154.25 C
+ANISOU 3588 CA LYS A 477 18378 19348 20882 3544 -4976 -4907 C
+ATOM 3589 C LYS A 477 72.634 103.732 -5.994 1.00159.76 C
+ANISOU 3589 C LYS A 477 18754 19833 22117 3467 -5183 -5014 C
+ATOM 3590 O LYS A 477 72.568 104.742 -5.292 1.00158.01 O
+ANISOU 3590 O LYS A 477 18598 19516 21921 3749 -5568 -5266 O
+ATOM 3591 CB LYS A 477 73.667 101.883 -4.706 1.00154.03 C
+ANISOU 3591 CB LYS A 477 18446 19057 21022 3730 -5372 -5076 C
+ATOM 3592 CG LYS A 477 73.367 100.787 -3.750 1.00149.76 C
+ANISOU 3592 CG LYS A 477 18324 18717 19861 3975 -5258 -5042 C
+ATOM 3593 CD LYS A 477 74.437 100.554 -2.740 1.00143.39 C
+ANISOU 3593 CD LYS A 477 17737 17664 19082 4327 -5762 -5306 C
+ATOM 3594 CE LYS A 477 73.739 100.087 -1.488 1.00145.72 C
+ANISOU 3594 CE LYS A 477 18569 18186 18613 4805 -5697 -5337 C
+ATOM 3595 NZ LYS A 477 74.661 99.556 -0.469 1.00149.42 N
+ANISOU 3595 NZ LYS A 477 19366 18470 18936 5206 -6108 -5561 N
+ATOM 3596 N THR A 478 72.908 103.757 -7.293 1.00166.45 N
+ANISOU 3596 N THR A 478 19271 20589 23384 3124 -4918 -4810 N
+ATOM 3597 CA THR A 478 73.186 105.012 -7.968 1.00170.99 C
+ANISOU 3597 CA THR A 478 19509 20929 24531 3052 -5023 -4844 C
+ATOM 3598 C THR A 478 71.905 105.733 -8.391 1.00172.33 C
+ANISOU 3598 C THR A 478 19686 21358 24435 2999 -4780 -4796 C
+ATOM 3599 O THR A 478 71.021 105.170 -9.046 1.00163.10 O
+ANISOU 3599 O THR A 478 18581 20461 22928 2823 -4356 -4594 O
+ATOM 3600 CB THR A 478 74.217 104.856 -9.128 1.00146.93 C
+ANISOU 3600 CB THR A 478 16115 17589 22125 2815 -4843 -4626 C
+ATOM 3601 OG1 THR A 478 74.873 106.106 -9.369 1.00147.15 O
+ANISOU 3601 OG1 THR A 478 15790 17239 22881 2857 -5085 -4705 O
+ATOM 3602 CG2 THR A 478 73.562 104.391 -10.425 1.00144.32 C
+ANISOU 3602 CG2 THR A 478 15764 17473 21597 2570 -4282 -4318 C
+ATOM 3603 N VAL A 479 71.809 106.979 -7.944 1.00177.73 N
+ANISOU 3603 N VAL A 479 20309 21929 25291 3181 -5110 -5014 N
+ATOM 3604 CA VAL A 479 70.674 107.838 -8.218 1.00175.65 C
+ANISOU 3604 CA VAL A 479 20044 21875 24819 3171 -4959 -5013 C
+ATOM 3605 C VAL A 479 71.176 109.077 -8.939 1.00177.67 C
+ANISOU 3605 C VAL A 479 19928 21830 25749 3101 -5069 -5035 C
+ATOM 3606 O VAL A 479 72.353 109.417 -8.840 1.00179.02 O
+ANISOU 3606 O VAL A 479 19865 21600 26555 3150 -5387 -5121 O
+ATOM 3607 CB VAL A 479 69.983 108.266 -6.909 1.00168.37 C
+ANISOU 3607 CB VAL A 479 19442 21113 23418 3524 -5243 -5249 C
+ATOM 3608 CG1 VAL A 479 69.008 109.403 -7.169 1.00162.23 C
+ANISOU 3608 CG1 VAL A 479 18603 20470 22565 3531 -5176 -5285 C
+ATOM 3609 CG2 VAL A 479 69.288 107.080 -6.256 1.00163.89 C
+ANISOU 3609 CG2 VAL A 479 19236 20856 22180 3624 -4991 -5142 C
+ATOM 3610 N MET A 486 57.931 103.433 -6.150 1.00 92.00 N
+ANISOU 3610 N MET A 486 10154 13425 11375 3371 -1523 -3283 N
+ATOM 3611 CA MET A 486 56.824 104.104 -5.482 1.00110.61 C
+ANISOU 3611 CA MET A 486 12558 15882 13585 3644 -1287 -3161 C
+ATOM 3612 C MET A 486 56.182 105.150 -6.389 1.00111.38 C
+ANISOU 3612 C MET A 486 12428 16016 13877 3424 -1416 -3308 C
+ATOM 3613 O MET A 486 56.000 106.305 -6.002 1.00120.35 O
+ANISOU 3613 O MET A 486 13691 17243 14794 3639 -1526 -3430 O
+ATOM 3614 CB MET A 486 57.288 104.743 -4.170 1.00120.60 C
+ANISOU 3614 CB MET A 486 14253 17221 14347 4174 -1395 -3243 C
+ATOM 3615 CG MET A 486 58.405 105.768 -4.316 1.00126.87 C
+ANISOU 3615 CG MET A 486 15171 17987 15047 4196 -1944 -3629 C
+ATOM 3616 SD MET A 486 58.150 107.169 -3.210 1.00146.78 S
+ANISOU 3616 SD MET A 486 18044 20597 17128 4757 -2124 -3782 S
+ATOM 3617 CE MET A 486 58.003 106.326 -1.640 1.00102.35 C
+ANISOU 3617 CE MET A 486 12883 15002 11003 5391 -1797 -3524 C
+ATOM 3618 N GLY A 496 57.154 99.412 -2.065 1.00157.62 N
+ANISOU 3618 N GLY A 496 19150 21656 19083 4616 82 -2024 N
+ATOM 3619 CA GLY A 496 57.031 99.217 -3.498 1.00158.07 C
+ANISOU 3619 CA GLY A 496 18749 21636 19677 3991 -116 -2141 C
+ATOM 3620 C GLY A 496 57.664 97.914 -3.942 1.00163.71 C
+ANISOU 3620 C GLY A 496 19349 22235 20619 3709 -140 -2093 C
+ATOM 3621 O GLY A 496 58.040 97.090 -3.111 1.00167.17 O
+ANISOU 3621 O GLY A 496 20009 22652 20858 3970 79 -1915 O
+ATOM 3622 N GLU A 497 57.778 97.722 -5.254 1.00166.67 N
+ANISOU 3622 N GLU A 497 19413 22530 21383 3222 -403 -2250 N
+ATOM 3623 CA GLU A 497 58.431 96.534 -5.792 1.00170.73 C
+ANISOU 3623 CA GLU A 497 19840 22933 22098 2955 -485 -2239 C
+ATOM 3624 C GLU A 497 59.931 96.621 -5.556 1.00172.64 C
+ANISOU 3624 C GLU A 497 20403 23228 21965 3043 -809 -2472 C
+ATOM 3625 O GLU A 497 60.589 95.609 -5.311 1.00173.01 O
+ANISOU 3625 O GLU A 497 20547 23223 21965 3047 -764 -2395 O
+ATOM 3626 CB GLU A 497 58.173 96.394 -7.290 1.00169.62 C
+ANISOU 3626 CB GLU A 497 19361 22681 22408 2505 -727 -2374 C
+ATOM 3627 CG GLU A 497 56.882 97.012 -7.777 1.00173.11 C
+ANISOU 3627 CG GLU A 497 19518 23086 23171 2413 -663 -2350 C
+ATOM 3628 CD GLU A 497 56.703 96.840 -9.270 1.00173.61 C
+ANISOU 3628 CD GLU A 497 19329 23013 23621 2054 -974 -2531 C
+ATOM 3629 OE1 GLU A 497 57.597 96.241 -9.908 1.00170.78 O
+ANISOU 3629 OE1 GLU A 497 19040 22600 23250 1901 -1202 -2647 O
+ATOM 3630 OE2 GLU A 497 55.672 97.300 -9.805 1.00174.73 O
+ANISOU 3630 OE2 GLU A 497 19233 23093 24064 1967 -999 -2559 O
+ATOM 3631 N ILE A 498 60.466 97.836 -5.652 1.00171.44 N
+ANISOU 3631 N ILE A 498 20381 23149 21608 3107 -1147 -2757 N
+ATOM 3632 CA ILE A 498 61.883 98.078 -5.403 1.00167.93 C
+ANISOU 3632 CA ILE A 498 20186 22695 20926 3210 -1503 -2995 C
+ATOM 3633 C ILE A 498 62.251 97.620 -4.004 1.00173.82 C
+ANISOU 3633 C ILE A 498 21298 23465 21280 3659 -1379 -2903 C
+ATOM 3634 O ILE A 498 63.315 97.034 -3.789 1.00168.12 O
+ANISOU 3634 O ILE A 498 20732 22684 20462 3692 -1544 -2980 O
+ATOM 3635 CB ILE A 498 62.227 99.564 -5.520 1.00165.53 C
+ANISOU 3635 CB ILE A 498 19934 22420 20540 3287 -1855 -3283 C
+ATOM 3636 CG1 ILE A 498 61.848 100.100 -6.901 1.00171.37 C
+ANISOU 3636 CG1 ILE A 498 20360 23137 21618 2911 -1947 -3365 C
+ATOM 3637 CG2 ILE A 498 63.706 99.798 -5.239 1.00153.61 C
+ANISOU 3637 CG2 ILE A 498 18613 20820 18931 3398 -2256 -3525 C
+ATOM 3638 CD1 ILE A 498 61.891 101.605 -6.996 1.00174.73 C
+ANISOU 3638 CD1 ILE A 498 20793 23594 22004 2996 -2195 -3587 C
+ATOM 3639 N SER A 499 61.362 97.890 -3.054 1.00187.32 N
+ANISOU 3639 N SER A 499 23169 25252 22753 4049 -1074 -2727 N
+ATOM 3640 CA SER A 499 61.558 97.444 -1.683 1.00198.47 C
+ANISOU 3640 CA SER A 499 24999 26682 23729 4594 -880 -2593 C
+ATOM 3641 C SER A 499 61.611 95.926 -1.651 1.00206.95 C
+ANISOU 3641 C SER A 499 26003 27687 24943 4481 -548 -2315 C
+ATOM 3642 O SER A 499 62.302 95.334 -0.823 1.00211.11 O
+ANISOU 3642 O SER A 499 26867 28195 25151 4806 -533 -2293 O
+ATOM 3643 CB SER A 499 60.435 97.952 -0.780 1.00200.16 C
+ANISOU 3643 CB SER A 499 25385 26976 23690 5064 -498 -2368 C
+ATOM 3644 OG SER A 499 60.635 97.541 0.556 1.00203.12 O
+ANISOU 3644 OG SER A 499 26244 27359 23574 5697 -286 -2224 O
+ATOM 3645 N ASP A 500 60.877 95.300 -2.564 1.00209.43 N
+ANISOU 3645 N ASP A 500 25883 27938 25751 4040 -320 -2123 N
+ATOM 3646 CA ASP A 500 60.862 93.851 -2.655 1.00212.36 C
+ANISOU 3646 CA ASP A 500 26120 28207 26361 3883 -39 -1865 C
+ATOM 3647 C ASP A 500 62.097 93.307 -3.366 1.00203.21 C
+ANISOU 3647 C ASP A 500 24946 26999 25265 3557 -426 -2093 C
+ATOM 3648 O ASP A 500 62.511 92.195 -3.092 1.00204.96 O
+ANISOU 3648 O ASP A 500 25238 27165 25472 3573 -286 -1954 O
+ATOM 3649 CB ASP A 500 59.580 93.355 -3.335 1.00221.23 C
+ANISOU 3649 CB ASP A 500 26765 29217 28075 3573 287 -1593 C
+ATOM 3650 CG ASP A 500 58.346 93.583 -2.486 1.00233.55 C
+ANISOU 3650 CG ASP A 500 28310 30773 29657 3938 816 -1243 C
+ATOM 3651 OD1 ASP A 500 58.502 93.807 -1.272 1.00239.09 O
+ANISOU 3651 OD1 ASP A 500 29432 31558 29852 4492 1029 -1137 O
+ATOM 3652 OD2 ASP A 500 57.226 93.532 -3.034 1.00237.24 O
+ANISOU 3652 OD2 ASP A 500 28355 31128 30656 3709 1011 -1072 O
+ATOM 3653 N ILE A 501 62.692 94.094 -4.258 1.00192.67 N
+ANISOU 3653 N ILE A 501 23525 25673 24008 3292 -875 -2413 N
+ATOM 3654 CA ILE A 501 63.864 93.633 -5.007 1.00181.71 C
+ANISOU 3654 CA ILE A 501 22108 24215 22719 3006 -1195 -2587 C
+ATOM 3655 C ILE A 501 65.165 93.699 -4.196 1.00170.68 C
+ANISOU 3655 C ILE A 501 21064 22814 20972 3287 -1450 -2764 C
+ATOM 3656 O ILE A 501 65.940 92.735 -4.173 1.00164.70 O
+ANISOU 3656 O ILE A 501 20376 21999 20202 3222 -1476 -2736 O
+ATOM 3657 CB ILE A 501 64.023 94.385 -6.353 1.00138.03 C
+ANISOU 3657 CB ILE A 501 16341 18649 17453 2657 -1507 -2802 C
+ATOM 3658 CG1 ILE A 501 63.385 93.589 -7.491 1.00130.33 C
+ANISOU 3658 CG1 ILE A 501 15061 17587 16872 2296 -1411 -2683 C
+ATOM 3659 CG2 ILE A 501 65.491 94.642 -6.682 1.00137.98 C
+ANISOU 3659 CG2 ILE A 501 16437 18581 17410 2596 -1883 -3037 C
+ATOM 3660 CD1 ILE A 501 61.877 93.516 -7.426 1.00127.50 C
+ANISOU 3660 CD1 ILE A 501 14480 17217 16748 2292 -1111 -2482 C
+ATOM 3661 N HIS A 502 65.396 94.829 -3.532 1.00164.00 N
+ANISOU 3661 N HIS A 502 20439 22007 19869 3613 -1676 -2964 N
+ATOM 3662 CA HIS A 502 66.603 95.022 -2.737 1.00157.69 C
+ANISOU 3662 CA HIS A 502 19968 21147 18800 3931 -2029 -3195 C
+ATOM 3663 C HIS A 502 66.627 94.018 -1.594 1.00162.64 C
+ANISOU 3663 C HIS A 502 20933 21795 19069 4322 -1761 -3012 C
+ATOM 3664 O HIS A 502 67.677 93.496 -1.229 1.00164.35 O
+ANISOU 3664 O HIS A 502 21348 21935 19163 4433 -1971 -3125 O
+ATOM 3665 CB HIS A 502 66.654 96.452 -2.195 1.00150.83 C
+ANISOU 3665 CB HIS A 502 19272 20282 17755 4264 -2351 -3452 C
+ATOM 3666 CG HIS A 502 67.989 97.117 -2.348 1.00143.78 C
+ANISOU 3666 CG HIS A 502 18387 19223 17019 4248 -2929 -3804 C
+ATOM 3667 ND1 HIS A 502 68.672 97.155 -3.544 1.00137.00 N
+ANISOU 3667 ND1 HIS A 502 17193 18253 16609 3785 -3096 -3872 N
+ATOM 3668 CD2 HIS A 502 68.759 97.787 -1.457 1.00140.15 C
+ANISOU 3668 CD2 HIS A 502 18217 18647 16387 4674 -3387 -4099 C
+ATOM 3669 CE1 HIS A 502 69.807 97.814 -3.383 1.00131.33 C
+ANISOU 3669 CE1 HIS A 502 16503 17343 16055 3893 -3583 -4155 C
+ATOM 3670 NE2 HIS A 502 69.883 98.208 -2.125 1.00130.34 N
+ANISOU 3670 NE2 HIS A 502 16741 17200 15583 4416 -3815 -4326 N
+ATOM 3671 N THR A 503 65.450 93.751 -1.039 1.00163.37 N
+ANISOU 3671 N THR A 503 21080 21971 19022 4552 -1268 -2705 N
+ATOM 3672 CA THR A 503 65.295 92.771 0.033 1.00163.31 C
+ANISOU 3672 CA THR A 503 21384 21972 18696 4974 -872 -2437 C
+ATOM 3673 C THR A 503 65.393 91.327 -0.475 1.00151.49 C
+ANISOU 3673 C THR A 503 19659 20415 17484 4610 -614 -2206 C
+ATOM 3674 O THR A 503 65.955 90.464 0.198 1.00146.11 O
+ANISOU 3674 O THR A 503 19247 19705 16563 4853 -520 -2130 O
+ATOM 3675 CB THR A 503 63.956 92.972 0.783 1.00170.09 C
+ANISOU 3675 CB THR A 503 22342 22899 19387 5379 -334 -2106 C
+ATOM 3676 OG1 THR A 503 64.026 94.162 1.576 1.00176.61 O
+ANISOU 3676 OG1 THR A 503 23551 23775 19778 5902 -585 -2325 O
+ATOM 3677 CG2 THR A 503 63.645 91.790 1.693 1.00171.53 C
+ANISOU 3677 CG2 THR A 503 22747 23054 19374 5760 235 -1707 C
+ATOM 3678 N LYS A 504 64.865 91.071 -1.669 1.00141.41 N
+ANISOU 3678 N LYS A 504 17911 19106 16711 4058 -541 -2117 N
+ATOM 3679 CA LYS A 504 64.918 89.730 -2.251 1.00138.96 C
+ANISOU 3679 CA LYS A 504 17368 18711 16719 3706 -369 -1930 C
+ATOM 3680 C LYS A 504 66.335 89.382 -2.646 1.00142.04 C
+ANISOU 3680 C LYS A 504 17848 19062 17058 3520 -779 -2178 C
+ATOM 3681 O LYS A 504 66.762 88.230 -2.559 1.00134.46 O
+ANISOU 3681 O LYS A 504 16927 18053 16108 3463 -666 -2057 O
+ATOM 3682 CB LYS A 504 64.010 89.614 -3.477 1.00129.82 C
+ANISOU 3682 CB LYS A 504 15721 17488 16116 3223 -303 -1839 C
+ATOM 3683 CG LYS A 504 62.585 89.222 -3.164 1.00130.75 C
+ANISOU 3683 CG LYS A 504 15616 17544 16518 3307 225 -1458 C
+ATOM 3684 N LEU A 505 67.053 90.395 -3.100 1.00138.41 N
+ANISOU 3684 N LEU A 505 17394 18602 16593 3427 -1237 -2505 N
+ATOM 3685 CA LEU A 505 68.435 90.224 -3.458 1.00120.29 C
+ANISOU 3685 CA LEU A 505 15154 16230 14322 3285 -1619 -2726 C
+ATOM 3686 C LEU A 505 69.260 89.889 -2.223 1.00124.70 C
+ANISOU 3686 C LEU A 505 16126 16770 14484 3724 -1710 -2800 C
+ATOM 3687 O LEU A 505 70.166 89.052 -2.259 1.00124.02 O
+ANISOU 3687 O LEU A 505 16106 16619 14396 3643 -1808 -2823 O
+ATOM 3688 CB LEU A 505 68.966 91.499 -4.066 1.00109.42 C
+ANISOU 3688 CB LEU A 505 13673 14807 13094 3171 -2036 -3016 C
+ATOM 3689 CG LEU A 505 70.386 91.097 -4.404 1.00128.61 C
+ANISOU 3689 CG LEU A 505 16120 17111 15635 3034 -2336 -3157 C
+ATOM 3690 CD1 LEU A 505 70.509 91.048 -5.920 1.00141.22 C
+ANISOU 3690 CD1 LEU A 505 17393 18648 17616 2580 -2370 -3131 C
+ATOM 3691 CD2 LEU A 505 71.441 91.946 -3.655 1.00114.58 C
+ANISOU 3691 CD2 LEU A 505 14554 15224 13758 3350 -2784 -3462 C
+ATOM 3692 N LEU A 506 68.951 90.579 -1.132 1.00130.40 N
+ANISOU 3692 N LEU A 506 17159 17539 14847 4233 -1705 -2854 N
+ATOM 3693 CA LEU A 506 69.612 90.336 0.139 1.00131.63 C
+ANISOU 3693 CA LEU A 506 17798 17665 14549 4786 -1814 -2947 C
+ATOM 3694 C LEU A 506 69.501 88.865 0.507 1.00144.65 C
+ANISOU 3694 C LEU A 506 19548 19330 16080 4841 -1380 -2638 C
+ATOM 3695 O LEU A 506 70.448 88.287 1.024 1.00156.36 O
+ANISOU 3695 O LEU A 506 21304 20754 17351 5038 -1550 -2741 O
+ATOM 3696 CB LEU A 506 69.008 91.206 1.240 1.00120.17 C
+ANISOU 3696 CB LEU A 506 16713 16270 12675 5409 -1772 -2980 C
+ATOM 3697 N ARG A 507 68.351 88.260 0.214 1.00146.01 N
+ANISOU 3697 N ARG A 507 19470 19552 16453 4658 -839 -2263 N
+ATOM 3698 CA ARG A 507 68.159 86.831 0.443 1.00152.26 C
+ANISOU 3698 CA ARG A 507 20261 20320 17271 4649 -394 -1930 C
+ATOM 3699 C ARG A 507 69.164 86.004 -0.360 1.00145.14 C
+ANISOU 3699 C ARG A 507 19199 19352 16597 4200 -653 -2042 C
+ATOM 3700 O ARG A 507 69.471 84.873 0.007 1.00142.95 O
+ANISOU 3700 O ARG A 507 19044 19045 16224 4273 -450 -1882 O
+ATOM 3701 CB ARG A 507 66.724 86.401 0.111 1.00161.16 C
+ANISOU 3701 CB ARG A 507 21023 21434 18777 4463 165 -1523 C
+ATOM 3702 CG ARG A 507 65.661 86.975 1.046 1.00177.63 C
+ANISOU 3702 CG ARG A 507 23283 23565 20645 4978 585 -1290 C
+ATOM 3703 CD ARG A 507 64.263 86.468 0.696 1.00187.68 C
+ANISOU 3703 CD ARG A 507 24111 24757 22442 4769 1148 -857 C
+ATOM 3704 NE ARG A 507 63.229 87.082 1.527 1.00198.88 N
+ANISOU 3704 NE ARG A 507 25661 26202 23704 5259 1588 -600 N
+ATOM 3705 CZ ARG A 507 61.923 86.883 1.368 1.00205.71 C
+ANISOU 3705 CZ ARG A 507 26137 26967 25058 5169 2095 -210 C
+ATOM 3706 NH1 ARG A 507 61.484 86.084 0.406 1.00207.33 N
+ANISOU 3706 NH1 ARG A 507 25797 27020 25959 4610 2159 -75 N
+ATOM 3707 NH2 ARG A 507 61.055 87.485 2.171 1.00208.11 N
+ANISOU 3707 NH2 ARG A 507 26596 27293 25185 5668 2517 41 N
+ATOM 3708 N LEU A 508 69.681 86.579 -1.445 1.00134.19 N
+ANISOU 3708 N LEU A 508 17555 17933 15496 3776 -1072 -2294 N
+ATOM 3709 CA LEU A 508 70.654 85.888 -2.287 1.00125.06 C
+ANISOU 3709 CA LEU A 508 16259 16704 14555 3385 -1304 -2382 C
+ATOM 3710 C LEU A 508 72.070 85.983 -1.730 1.00133.75 C
+ANISOU 3710 C LEU A 508 17660 17739 15419 3609 -1705 -2655 C
+ATOM 3711 O LEU A 508 72.775 84.975 -1.650 1.00132.42 O
+ANISOU 3711 O LEU A 508 17581 17530 15202 3562 -1700 -2615 O
+ATOM 3712 CB LEU A 508 70.606 86.404 -3.726 1.00112.64 C
+ANISOU 3712 CB LEU A 508 14312 15095 13392 2907 -1513 -2482 C
+ATOM 3713 CG LEU A 508 69.271 86.186 -4.436 1.00113.17 C
+ANISOU 3713 CG LEU A 508 14056 15174 13769 2653 -1215 -2260 C
+ATOM 3714 CD1 LEU A 508 69.459 86.184 -5.945 1.00106.22 C
+ANISOU 3714 CD1 LEU A 508 12898 14225 13237 2216 -1432 -2343 C
+ATOM 3715 CD2 LEU A 508 68.613 84.894 -3.968 1.00117.32 C
+ANISOU 3715 CD2 LEU A 508 14560 15678 14341 2703 -779 -1932 C
+ATOM 3716 N SER A 509 72.491 87.188 -1.355 1.00130.72 N
+ANISOU 3716 N SER A 509 17414 17317 14936 3856 -2085 -2944 N
+ATOM 3717 CA SER A 509 73.767 87.347 -0.663 1.00136.66 C
+ANISOU 3717 CA SER A 509 18457 17948 15519 4156 -2531 -3236 C
+ATOM 3718 C SER A 509 73.698 86.583 0.646 1.00143.40 C
+ANISOU 3718 C SER A 509 19773 18845 15866 4687 -2319 -3138 C
+ATOM 3719 O SER A 509 74.680 85.977 1.082 1.00138.35 O
+ANISOU 3719 O SER A 509 19358 18121 15090 4839 -2521 -3256 O
+ATOM 3720 CB SER A 509 74.089 88.820 -0.410 1.00130.15 C
+ANISOU 3720 CB SER A 509 17685 17028 14738 4382 -3008 -3572 C
+ATOM 3721 OG SER A 509 74.991 89.319 -1.384 1.00125.27 O
+ANISOU 3721 OG SER A 509 16739 16248 14609 4003 -3376 -3749 O
+ATOM 3722 N SER A 510 72.520 86.615 1.263 1.00144.65 N
+ANISOU 3722 N SER A 510 20078 19123 15761 4999 -1878 -2899 N
+ATOM 3723 CA SER A 510 72.236 85.777 2.417 1.00148.97 C
+ANISOU 3723 CA SER A 510 21044 19713 15846 5526 -1487 -2677 C
+ATOM 3724 C SER A 510 72.424 84.315 2.046 1.00145.48 C
+ANISOU 3724 C SER A 510 20455 19266 15554 5204 -1182 -2426 C
+ATOM 3725 O SER A 510 73.001 83.552 2.811 1.00140.49 O
+ANISOU 3725 O SER A 510 20177 18606 14598 5539 -1145 -2415 O
+ATOM 3726 CB SER A 510 70.807 85.999 2.911 1.00149.05 C
+ANISOU 3726 CB SER A 510 21111 19824 15699 5832 -930 -2348 C
+ATOM 3727 OG SER A 510 70.346 84.882 3.643 1.00147.27 O
+ANISOU 3727 OG SER A 510 21097 19617 15240 6154 -337 -1962 O
+ATOM 3728 N SER A 511 71.946 83.946 0.858 1.00139.39 N
+ANISOU 3728 N SER A 511 19184 18508 15269 4583 -1004 -2249 N
+ATOM 3729 CA SER A 511 72.011 82.573 0.365 1.00129.68 C
+ANISOU 3729 CA SER A 511 17763 17254 14255 4236 -745 -2013 C
+ATOM 3730 C SER A 511 73.437 82.171 0.006 1.00129.30 C
+ANISOU 3730 C SER A 511 17762 17135 14232 4035 -1175 -2258 C
+ATOM 3731 O SER A 511 73.792 80.991 0.047 1.00109.17 O
+ANISOU 3731 O SER A 511 15254 14565 11659 3957 -1019 -2119 O
+ATOM 3732 CB SER A 511 71.108 82.416 -0.862 1.00125.40 C
+ANISOU 3732 CB SER A 511 16701 16703 14243 3684 -564 -1828 C
+ATOM 3733 OG SER A 511 71.167 81.106 -1.394 1.00137.08 O
+ANISOU 3733 OG SER A 511 17990 18125 15969 3359 -392 -1635 O
+ATOM 3734 N GLN A 512 74.247 83.164 -0.347 1.00131.12 N
+ANISOU 3734 N GLN A 512 17958 17304 14560 3957 -1699 -2603 N
+ATOM 3735 CA GLN A 512 75.621 82.941 -0.774 1.00120.52 C
+ANISOU 3735 CA GLN A 512 16587 15845 13361 3755 -2110 -2821 C
+ATOM 3736 C GLN A 512 76.508 82.796 0.431 1.00123.24 C
+ANISOU 3736 C GLN A 512 17385 16120 13322 4264 -2359 -3023 C
+ATOM 3737 O GLN A 512 77.569 82.174 0.385 1.00128.94 O
+ANISOU 3737 O GLN A 512 18162 16749 14081 4188 -2573 -3124 O
+ATOM 3738 CB GLN A 512 76.096 84.150 -1.546 1.00118.44 C
+ANISOU 3738 CB GLN A 512 16077 15483 13440 3537 -2531 -3073 C
+ATOM 3739 CG GLN A 512 76.798 83.822 -2.807 1.00125.91 C
+ANISOU 3739 CG GLN A 512 16711 16343 14787 3048 -2644 -3057 C
+ATOM 3740 CD GLN A 512 76.915 85.020 -3.690 1.00137.22 C
+ANISOU 3740 CD GLN A 512 17859 17690 16589 2843 -2877 -3186 C
+ATOM 3741 OE1 GLN A 512 77.456 86.052 -3.281 1.00153.03 O
+ANISOU 3741 OE1 GLN A 512 19904 19568 18672 3053 -3245 -3442 O
+ATOM 3742 NE2 GLN A 512 76.353 84.922 -4.897 1.00128.62 N
+ANISOU 3742 NE2 GLN A 512 16487 16643 15739 2470 -2678 -3017 N
+ATOM 3743 N GLY A 513 76.073 83.422 1.510 1.00128.93 N
+ANISOU 3743 N GLY A 513 18453 16869 13665 4826 -2362 -3100 N
+ATOM 3744 CA GLY A 513 76.767 83.309 2.761 1.00135.31 C
+ANISOU 3744 CA GLY A 513 19790 17602 14021 5449 -2610 -3308 C
+ATOM 3745 C GLY A 513 76.597 81.908 3.295 1.00133.10 C
+ANISOU 3745 C GLY A 513 19748 17398 13425 5620 -2132 -3010 C
+ATOM 3746 O GLY A 513 77.464 81.407 3.988 1.00135.48 O
+ANISOU 3746 O GLY A 513 20407 17622 13448 5952 -2344 -3163 O
+ATOM 3747 N THR A 514 75.478 81.270 2.971 1.00130.00 N
+ANISOU 3747 N THR A 514 19139 17128 13128 5402 -1499 -2584 N
+ATOM 3748 CA THR A 514 75.252 79.899 3.409 1.00136.05 C
+ANISOU 3748 CA THR A 514 20053 17932 13707 5525 -990 -2248 C
+ATOM 3749 C THR A 514 76.125 78.980 2.571 1.00136.91 C
+ANISOU 3749 C THR A 514 19914 17993 14111 4991 -1151 -2279 C
+ATOM 3750 O THR A 514 76.451 77.859 2.971 1.00136.85 O
+ANISOU 3750 O THR A 514 20093 17981 13923 5102 -944 -2139 O
+ATOM 3751 CB THR A 514 73.784 79.475 3.234 1.00141.83 C
+ANISOU 3751 CB THR A 514 20522 18734 14631 5408 -287 -1768 C
+ATOM 3752 OG1 THR A 514 73.591 78.921 1.927 1.00142.93 O
+ANISOU 3752 OG1 THR A 514 20113 18858 15336 4676 -233 -1640 O
+ATOM 3753 CG2 THR A 514 72.861 80.659 3.413 1.00145.09 C
+ANISOU 3753 CG2 THR A 514 20916 19192 15018 5620 -214 -1761 C
+ATOM 3754 N ILE A 515 76.491 79.473 1.394 1.00129.08 N
+ANISOU 3754 N ILE A 515 18518 16960 13565 4442 -1494 -2442 N
+ATOM 3755 CA ILE A 515 77.327 78.735 0.468 1.00119.39 C
+ANISOU 3755 CA ILE A 515 17053 15677 12633 3951 -1657 -2465 C
+ATOM 3756 C ILE A 515 78.787 78.796 0.895 1.00127.05 C
+ANISOU 3756 C ILE A 515 18275 16524 13475 4143 -2161 -2798 C
+ATOM 3757 O ILE A 515 79.482 77.778 0.906 1.00128.44 O
+ANISOU 3757 O ILE A 515 18530 16671 13600 4065 -2153 -2760 O
+ATOM 3758 CB ILE A 515 77.220 79.308 -0.945 1.00110.42 C
+ANISOU 3758 CB ILE A 515 15452 14516 11987 3401 -1815 -2500 C
+ATOM 3759 CG1 ILE A 515 75.801 79.150 -1.481 1.00109.39 C
+ANISOU 3759 CG1 ILE A 515 15038 14466 12060 3177 -1388 -2203 C
+ATOM 3760 CG2 ILE A 515 78.168 78.587 -1.861 1.00112.80 C
+ANISOU 3760 CG2 ILE A 515 15581 14743 12533 2997 -1979 -2516 C
+ATOM 3761 CD1 ILE A 515 75.570 79.879 -2.780 1.00110.01 C
+ANISOU 3761 CD1 ILE A 515 14740 14519 12538 2759 -1561 -2268 C
+ATOM 3762 N GLU A 516 79.240 79.996 1.247 1.00122.76 N
+ANISOU 3762 N GLU A 516 17837 15878 12927 4400 -2627 -3132 N
+ATOM 3763 CA GLU A 516 80.636 80.218 1.589 1.00124.18 C
+ANISOU 3763 CA GLU A 516 18172 15860 13149 4571 -3208 -3493 C
+ATOM 3764 C GLU A 516 81.099 79.274 2.681 1.00126.09 C
+ANISOU 3764 C GLU A 516 18894 16095 12918 5029 -3183 -3522 C
+ATOM 3765 O GLU A 516 82.117 78.595 2.539 1.00116.84 O
+ANISOU 3765 O GLU A 516 17721 14825 11848 4893 -3381 -3605 O
+ATOM 3766 CB GLU A 516 80.863 81.656 2.046 1.00135.21 C
+ANISOU 3766 CB GLU A 516 19658 17112 14603 4907 -3722 -3854 C
+ATOM 3767 CG GLU A 516 82.315 82.045 1.962 1.00146.41 C
+ANISOU 3767 CG GLU A 516 20992 18238 16400 4885 -4381 -4215 C
+ATOM 3768 CD GLU A 516 82.865 81.775 0.582 1.00151.28 C
+ANISOU 3768 CD GLU A 516 21100 18789 17590 4220 -4329 -4073 C
+ATOM 3769 OE1 GLU A 516 82.373 82.413 -0.367 1.00146.52 O
+ANISOU 3769 OE1 GLU A 516 20133 18221 17316 3867 -4198 -3957 O
+ATOM 3770 OE2 GLU A 516 83.763 80.917 0.441 1.00154.24 O
+ANISOU 3770 OE2 GLU A 516 21471 19078 18055 4089 -4397 -4065 O
+END
--- /dev/null
+HEADER TRANSFERASE/TRANSFERASE INHIBITOR 01-JAN-13 4IM2
+TITLE STRUCTURE OF TANK-BINDING KINASE 1 (Truncated test file)
+DBREF 4IM2 A 1 657 UNP Q9UHD2 TBK1_HUMAN 1 657
+SEQADV 4IM2 GLY A -5 UNP Q9UHD2 EXPRESSION TAG
+SEQADV 4IM2 SER A -4 UNP Q9UHD2 EXPRESSION TAG
+SEQADV 4IM2 GLY A -3 UNP Q9UHD2 EXPRESSION TAG
+SEQADV 4IM2 SER A -2 UNP Q9UHD2 EXPRESSION TAG
+SEQADV 4IM2 GLY A -1 UNP Q9UHD2 EXPRESSION TAG
+SEQADV 4IM2 SER A 0 UNP Q9UHD2 EXPRESSION TAG
+SEQRES 1 A 663 GLY SER GLY SER GLY SER MET GLN SER THR SER ASN HIS
+ATOM 1 N GLY A -1 126.784 4.226 -23.353 1.00158.13 N
+ANISOU 1 N GLY A -1 19370 17517 23197 6628 1162 2075 N
+ATOM 2 CA GLY A -1 125.521 4.306 -24.062 1.00150.94 C
+ANISOU 2 CA GLY A -1 18746 16231 22374 6153 1277 1996 C
+ATOM 3 C GLY A -1 125.742 4.361 -25.557 1.00146.29 C
+ANISOU 3 C GLY A -1 18187 15453 21943 5900 1405 1498 C
+ATOM 4 O GLY A -1 126.691 4.980 -26.029 1.00150.85 O
+ANISOU 4 O GLY A -1 18536 16366 22413 5906 1385 1160 O
+ATOM 5 N SER A 0 124.869 3.710 -26.313 1.00137.36 N
+ANISOU 5 N SER A 0 17328 13796 21068 5675 1550 1432 N
+ATOM 6 CA SER A 0 125.052 3.672 -27.755 1.00139.44 C
+ANISOU 6 CA SER A 0 17634 13884 21461 5464 1674 953 C
+ATOM 7 C SER A 0 123.846 4.104 -28.574 1.00137.43 C
+ANISOU 7 C SER A 0 17591 13478 21149 4975 1714 755 C
+ATOM 8 O SER A 0 122.737 4.275 -28.071 1.00128.25 O
+ANISOU 8 O SER A 0 16566 12244 19921 4780 1667 988 O
+ATOM 9 CB SER A 0 125.578 2.312 -28.214 1.00155.09 C
+ANISOU 9 CB SER A 0 19671 15395 23862 5752 1827 887 C
+ATOM 10 OG SER A 0 126.993 2.281 -28.131 1.00164.59 O
+ANISOU 10 OG SER A 0 20608 16866 25062 6113 1802 781 O
+ATOM 11 N MET A 1 124.096 4.270 -29.861 1.00134.87 N
+ANISOU 11 N MET A 1 17283 13123 20839 4799 1805 311 N
+ATOM 12 CA MET A 1 123.214 5.039 -30.698 1.00125.22 C
+ANISOU 12 CA MET A 1 16193 11958 19428 4369 1804 70 C
+ATOM 13 C MET A 1 122.885 4.351 -32.006 1.00124.69 C
+ANISOU 13 C MET A 1 16293 11510 19572 4225 1942 -293 C
+ATOM 14 O MET A 1 123.723 3.686 -32.606 1.00129.61 O
+ANISOU 14 O MET A 1 16868 11984 20394 4414 2057 -519 O
+ATOM 15 CB MET A 1 123.867 6.392 -30.970 1.00122.51 C
+ANISOU 15 CB MET A 1 15675 12140 18732 4254 1762 -132 C
+ATOM 16 CG MET A 1 125.074 6.368 -31.866 1.00120.74 C
+ANISOU 16 CG MET A 1 15318 12013 18544 4369 1884 -495 C
+ATOM 17 SD MET A 1 125.834 7.982 -31.850 1.00196.33 S
+ANISOU 17 SD MET A 1 24655 22193 27747 4246 1861 -642 S
+ATOM 18 CE MET A 1 126.785 7.896 -30.345 1.00132.53 C
+ANISOU 18 CE MET A 1 16264 14397 19693 4639 1728 -355 C
+ATOM 19 N GLN A 2 121.643 4.496 -32.440 1.00123.78 N
+ANISOU 19 N GLN A 2 16363 11253 19416 3898 1925 -369 N
+ATOM 20 CA GLN A 2 121.313 4.161 -33.809 1.00128.51 C
+ANISOU 20 CA GLN A 2 17093 11643 20094 3714 2020 -799 C
+ATOM 21 C GLN A 2 121.639 5.396 -34.617 1.00121.06 C
+ANISOU 21 C GLN A 2 16105 11138 18752 3541 2004 -1065 C
+ATOM 22 O GLN A 2 121.959 6.442 -34.059 1.00107.32 O
+ANISOU 22 O GLN A 2 14247 9790 16739 3528 1928 -906 O
+ATOM 23 CB GLN A 2 119.832 3.845 -33.965 1.00136.11 C
+ANISOU 23 CB GLN A 2 18240 12314 21161 3439 1994 -809 C
+ATOM 24 CG GLN A 2 119.171 3.277 -32.740 1.00148.45 C
+ANISOU 24 CG GLN A 2 19841 13613 22949 3500 1973 -376 C
+ATOM 25 CD GLN A 2 117.773 2.799 -33.042 1.00158.28 C
+ANISOU 25 CD GLN A 2 21243 14511 24385 3221 1993 -473 C
+ATOM 26 OE1 GLN A 2 116.827 3.097 -32.313 1.00163.28 O
+ANISOU 26 OE1 GLN A 2 21915 15160 24966 3070 1921 -211 O
+ATOM 27 NE2 GLN A 2 117.631 2.057 -34.134 1.00155.02 N
+ANISOU 27 NE2 GLN A 2 20902 13797 24200 3144 2095 -885 N
+ATOM 28 N SER A 3 121.547 5.280 -35.931 1.00124.66 N
+ANISOU 28 N SER A 3 16661 11530 19175 3410 2090 -1474 N
+ATOM 29 CA SER A 3 121.742 6.432 -36.781 1.00120.35 C
+ANISOU 29 CA SER A 3 16121 11369 18236 3242 2107 -1703 C
+ATOM 30 C SER A 3 121.190 6.186 -38.161 1.00125.27 C
+ANISOU 30 C SER A 3 16914 11882 18801 3073 2165 -2108 C
+ATOM 31 O SER A 3 120.746 5.090 -38.489 1.00135.86 O
+ANISOU 31 O SER A 3 18337 12848 20436 3082 2197 -2268 O
+ATOM 32 CB SER A 3 123.217 6.751 -36.923 1.00116.70 C
+ANISOU 32 CB SER A 3 15475 11153 17711 3435 2220 -1807 C
+ATOM 33 OG SER A 3 123.770 5.974 -37.974 1.00112.78 O
+ANISOU 33 OG SER A 3 15005 10478 17367 3528 2375 -2175 O
+ATOM 34 N THR A 4 121.244 7.232 -38.972 1.00116.48 N
+ANISOU 34 N THR A 4 15849 11109 17301 2928 2191 -2281 N
+ATOM 35 CA THR A 4 120.978 7.130 -40.394 1.00113.12 C
+ANISOU 35 CA THR A 4 15568 10691 16723 2823 2262 -2692 C
+ATOM 36 C THR A 4 122.118 7.839 -41.119 1.00116.32 C
+ANISOU 36 C THR A 4 15918 11410 16867 2884 2432 -2867 C
+ATOM 37 O THR A 4 123.106 8.236 -40.495 1.00117.17 O
+ANISOU 37 O THR A 4 15851 11671 16998 3007 2493 -2706 O
+ATOM 38 CB THR A 4 119.615 7.756 -40.775 1.00106.20 C
+ANISOU 38 CB THR A 4 14854 9927 15568 2568 2121 -2713 C
+ATOM 39 OG1 THR A 4 119.774 9.154 -41.043 1.00107.14 O
+ANISOU 39 OG1 THR A 4 15001 10451 15258 2480 2138 -2644 O
+ATOM 40 CG2 THR A 4 118.597 7.567 -39.657 1.00 99.42 C
+ANISOU 40 CG2 THR A 4 13990 8889 14896 2483 1956 -2396 C
+ATOM 41 N SER A 5 121.981 7.982 -42.432 1.00116.70 N
+ANISOU 41 N SER A 5 16106 11564 16670 2803 2517 -3210 N
+ATOM 42 CA SER A 5 122.975 8.671 -43.247 1.00122.60 C
+ANISOU 42 CA SER A 5 16837 12604 17144 2839 2721 -3385 C
+ATOM 43 C SER A 5 123.317 10.064 -42.713 1.00128.43 C
+ANISOU 43 C SER A 5 17501 13666 17630 2768 2748 -3105 C
+ATOM 44 O SER A 5 124.481 10.467 -42.712 1.00133.01 O
+ANISOU 44 O SER A 5 17934 14410 18193 2852 2925 -3133 O
+ATOM 45 CB SER A 5 122.473 8.779 -44.687 1.00127.34 C
+ANISOU 45 CB SER A 5 17646 13318 17418 2741 2774 -3729 C
+ATOM 46 OG SER A 5 121.108 9.163 -44.712 1.00135.31 O
+ANISOU 46 OG SER A 5 18807 14370 18235 2568 2576 -3643 O
+ATOM 47 N ASN A 6 122.303 10.783 -42.240 1.00122.78 N
+ANISOU 47 N ASN A 6 16868 13033 16750 2608 2581 -2859 N
+ATOM 48 CA ASN A 6 122.460 12.194 -41.897 1.00114.44 C
+ANISOU 48 CA ASN A 6 15777 12275 15429 2507 2620 -2639 C
+ATOM 49 C ASN A 6 122.348 12.537 -40.412 1.00108.55 C
+ANISOU 49 C ASN A 6 14870 11544 14832 2498 2474 -2282 C
+ATOM 50 O ASN A 6 122.712 13.640 -40.004 1.00110.16 O
+ANISOU 50 O ASN A 6 14983 11984 14890 2435 2531 -2135 O
+ATOM 51 CB ASN A 6 121.461 13.034 -42.695 1.00113.00 C
+ANISOU 51 CB ASN A 6 15832 12254 14850 2339 2583 -2658 C
+ATOM 52 CG ASN A 6 121.646 12.886 -44.191 1.00118.14 C
+ANISOU 52 CG ASN A 6 16648 12982 15257 2366 2743 -2999 C
+ATOM 53 OD1 ASN A 6 122.765 12.952 -44.698 1.00122.16 O
+ANISOU 53 OD1 ASN A 6 17097 13580 15737 2449 2985 -3154 O
+ATOM 54 ND2 ASN A 6 120.546 12.672 -44.905 1.00118.96 N
+ANISOU 54 ND2 ASN A 6 16946 13074 15179 2302 2609 -3139 N
+ATOM 55 N HIS A 7 121.845 11.605 -39.608 1.00100.48 N
+ANISOU 55 N HIS A 7 13810 10269 14098 2560 2305 -2149 N
+ATOM 56 CA HIS A 7 121.657 11.871 -38.183 1.00 91.49 C
+ANISOU 56 CA HIS A 7 12535 9160 13066 2569 2162 -1799 C
+ATOM 57 C HIS A 7 122.134 10.725 -37.300 1.00 97.74 C
+ANISOU 57 C HIS A 7 13180 9725 14232 2793 2117 -1685 C
+ATOM 58 O HIS A 7 122.456 9.647 -37.791 1.00101.23 O
+ANISOU 58 O HIS A 7 13643 9923 14898 2924 2188 -1876 O
+ATOM 59 CB HIS A 7 120.189 12.175 -37.884 1.00 86.30 C
+ANISOU 59 CB HIS A 7 12021 8464 12306 2383 1977 -1628 C
+ATOM 60 CG HIS A 7 119.634 13.303 -38.694 1.00101.46 C
+ANISOU 60 CG HIS A 7 14094 10603 13853 2201 2000 -1699 C
+ATOM 61 ND1 HIS A 7 119.265 13.157 -40.015 1.00 99.83 N
+ANISOU 61 ND1 HIS A 7 14076 10384 13472 2153 2049 -1976 N
+ATOM 62 CD2 HIS A 7 119.401 14.600 -38.379 1.00 89.60 C
+ANISOU 62 CD2 HIS A 7 12588 9342 12114 2078 1988 -1527 C
+ATOM 63 CE1 HIS A 7 118.823 14.314 -40.476 1.00 97.86 C
+ANISOU 63 CE1 HIS A 7 13944 10363 12875 2029 2062 -1939 C
+ATOM 64 NE2 HIS A 7 118.896 15.206 -39.503 1.00 93.14 N
+ANISOU 64 NE2 HIS A 7 13235 9899 12253 1975 2035 -1667 N
+END
or <strong>"View→Nucleotide"</strong> (in the protein panel)
allows you to show or hide one or other of the linked alignment
panels.</li>
- <li>Panel heights are adjusted dragging the divider between
+ <li>Panel heights are adjusted by dragging the divider between
them using the mouse</li>
<li><a href="../menus/alwview.html"><strong>"View→New
View / Expand Views / Gather Views"</strong></a> behave as for a normal
<tr>
<td width="60" nowrap>
<div align="center">
+ <strong><a name="Jalview.2.10.4">2.10.4</a><br /> <em>27/02/2018</em></strong>
+ </div>
+ </td>
+ <td><div align="left">
+ <em></em>
+ <ul>
+ <li>
+ <!-- JAL-984 -->Mouse cursor changes to indicate Sequence ID and annotation area margins can be click-dragged to adjust them.</li>
+ <li>
+ <!-- JAL-2885 -->Jalview uses HTTPS for Uniprot, Xfam and Ensembl services
+ </li>
+ <li>
+ <!-- JAL-2759 -->Improved performance for large alignments and lots of hidden columns
+ </li>
+ </ul>
+ </div>
+ </td>
+ <td><div align="left">
+ <ul>
+ <li>
+ <!-- JAL-2778 -->Slow redraw when Overview panel shown overlapping alignment panel
+ </li>
+ <li>
+ <!-- JAL-2666 -->Linked scrolling via protein horizontal scroll bar doesn't work for some CDS/Protein views
+ </li>
+ </ul>
+ </div>
+ </td>
+ </tr>
+ <tr>
+ <td width="60" nowrap>
+ <div align="center">
<strong><a name="Jalview.2.10.3b1">2.10.3b1</a><br /> <em>24/1/2018</em></strong>
</div>
</td>
<tr>
<td width="60" nowrap>
<div align="center">
- <strong><a name="Jalview.2.10.4">2.10.4</a><br /> <em>27/02/2018</em></strong>
- </div>
- </td>
- <td><div align="left">
- <em></em>
- <ul>
- <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.3">2.10.3</a><br /> <em>17/11/2017</em></strong>
</div>
</td>
}
/**
+ * Annotate the residues with their corresponding positions in s1 using the
+ * alignment in as NOTE: This clears all atom.alignmentMapping values on the
+ * structure.
+ *
+ * @param as
+ * @param s1
+ */
+ public void makeExactMapping(StructureMapping mapping, SequenceI s1)
+ {
+ // first clear out any old alignmentMapping values:
+ for (Atom atom : atoms)
+ {
+ atom.alignmentMapping = -1;
+ }
+ SequenceI ds = s1;
+ while (ds.getDatasetSequence() != null)
+ {
+ ds = ds.getDatasetSequence();
+ }
+ int pdboffset = 0;
+ for (Residue res : residues)
+ {
+ // res.number isn't set correctly for discontinuous/mismapped residues
+ int seqpos = mapping.getSeqPos(res.atoms.get(0).resNumber);
+ char strchar = sequence.getCharAt(pdboffset++);
+ if (seqpos == StructureMapping.UNASSIGNED_VALUE)
+ {
+ continue;
+ }
+ char seqchar = ds.getCharAt(seqpos - ds.getStart());
+
+ boolean sameResidue = Comparison.isSameResidue(
+ seqchar, strchar, false);
+ if (sameResidue)
+ {
+ for (Atom atom : res.atoms)
+ {
+ atom.alignmentMapping = seqpos - 1;
+ }
+ }
+ }
+ }
+
+ /**
* Copies over the RESNUM seqfeatures from the internal chain sequence to the
* mapped sequence
*
{
SequenceI sq = mapping.getSequence();
SequenceI dsq = sq;
+ if (sqmpping == null)
+ {
+ // SIFTS mappings are recorded in the StructureMapping object...
+
+ sqmpping = mapping.getSeqToPdbMapping();
+ }
if (sq != null)
{
while (dsq.getDatasetSequence() != null)
* @param seqMappings
* the set of mappings involving dnaSeq
* @param aMapping
- * an initial candidate from seqMappings
+ * a transcript-to-peptide mapping
* @return
*/
static SequenceI findCdsForProtein(List<AlignedCodonFrame> mappings,
if (mappedFromLength == dnaLength
|| mappedFromLength == dnaLength - CODON_LENGTH)
{
- return seqDss;
+ /*
+ * if sequence has CDS features, this is a transcript with no UTR
+ * - do not take this as the CDS sequence! (JAL-2789)
+ */
+ if (seqDss.getFeatures().getFeaturesByOntology(SequenceOntologyI.CDS)
+ .isEmpty())
+ {
+ return seqDss;
+ }
}
/*
{
/*
* found a 3:1 mapping to the protein product which covers
- * the whole dna sequence i.e. is from CDS; finally check it
- * is from the dna start sequence
+ * the whole dna sequence i.e. is from CDS; finally check the CDS
+ * is mapped from the given dna start sequence
*/
SequenceI cdsSeq = map.getFromSeq();
+ // todo this test is weak if seqMappings contains multiple mappings;
+ // we get away with it if transcript:cds relationship is 1:1
List<AlignedCodonFrame> dnaToCdsMaps = MappingUtils
.findMappingsForSequence(cdsSeq, seqMappings);
if (!dnaToCdsMaps.isEmpty())
protected static List<DBRefEntry> propagateDBRefsToCDS(SequenceI cdsSeq,
SequenceI contig, SequenceI proteinProduct, Mapping mapping)
{
+
// gather direct refs from contig congruent with mapping
List<DBRefEntry> direct = new ArrayList<>();
HashSet<String> directSources = new HashSet<>();
+
if (contig.getDBRefs() != null)
{
for (DBRefEntry dbr : contig.getDBRefs())
int mappedDnaLength = MappingUtils.getLength(ranges);
/*
- * if not a whole number of codons, something is wrong,
- * abort mapping
+ * if not a whole number of codons, truncate mapping
*/
- if (mappedDnaLength % CODON_LENGTH > 0)
+ int codonRemainder = mappedDnaLength % CODON_LENGTH;
+ if (codonRemainder > 0)
{
- return null;
+ mappedDnaLength -= codonRemainder;
+ MappingUtils.removeEndPositions(codonRemainder, ranges);
}
int proteinLength = proteinSeq.getLength();
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
+import java.util.Iterator;
import java.util.List;
public class Dna
* 'final' variables describe the inputs to the translation, which should not
* be modified.
*/
- final private List<SequenceI> selection;
+ private final List<SequenceI> selection;
- final private String[] seqstring;
+ private final String[] seqstring;
- final private int[] contigs;
+ private final Iterator<int[]> contigs;
- final private char gapChar;
+ private final char gapChar;
- final private AlignmentAnnotation[] annotations;
+ private final AlignmentAnnotation[] annotations;
- final private int dnaWidth;
+ private final int dnaWidth;
- final private AlignmentI dataset;
+ private final AlignmentI dataset;
+
+ private ShiftList vismapping;
+
+ private int[] startcontigs;
/*
* Working variables for the translation.
* @param viewport
* @param visibleContigs
*/
- public Dna(AlignViewportI viewport, int[] visibleContigs)
+ public Dna(AlignViewportI viewport, Iterator<int[]> visibleContigs)
{
this.selection = Arrays.asList(viewport.getSequenceSelection());
this.seqstring = viewport.getViewAsString(true);
this.annotations = viewport.getAlignment().getAlignmentAnnotation();
this.dnaWidth = viewport.getAlignment().getWidth();
this.dataset = viewport.getAlignment().getDataset();
+ initContigs();
+ }
+
+ /**
+ * Initialise contigs used as starting point for translateCodingRegion
+ */
+ private void initContigs()
+ {
+ vismapping = new ShiftList(); // map from viscontigs to seqstring
+ // intervals
+
+ int npos = 0;
+ int[] lastregion = null;
+ ArrayList<Integer> tempcontigs = new ArrayList<>();
+ while (contigs.hasNext())
+ {
+ int[] region = contigs.next();
+ if (lastregion == null)
+ {
+ vismapping.addShift(npos, region[0]);
+ }
+ else
+ {
+ // hidden region
+ vismapping.addShift(npos, region[0] - lastregion[1] + 1);
+ }
+ lastregion = region;
+ tempcontigs.add(region[0]);
+ tempcontigs.add(region[1]);
+ }
+
+ startcontigs = new int[tempcontigs.size()];
+ int i = 0;
+ for (Integer val : tempcontigs)
+ {
+ startcontigs[i] = val;
+ i++;
+ }
+ tempcontigs = null;
}
/**
List<SequenceI> proteinSeqs)
{
List<int[]> skip = new ArrayList<>();
- int skipint[] = null;
- ShiftList vismapping = new ShiftList(); // map from viscontigs to seqstring
- // intervals
- int vc;
- int[] scontigs = new int[contigs.length];
+ int[] skipint = null;
+
int npos = 0;
- for (vc = 0; vc < contigs.length; vc += 2)
- {
- if (vc == 0)
- {
- vismapping.addShift(npos, contigs[vc]);
- }
- else
- {
- // hidden region
- vismapping.addShift(npos, contigs[vc] - contigs[vc - 1] + 1);
- }
- scontigs[vc] = contigs[vc];
- scontigs[vc + 1] = contigs[vc + 1];
- }
+ int vc = 0;
+
+ int[] scontigs = new int[startcontigs.length];
+ System.arraycopy(startcontigs, 0, scontigs, 0, startcontigs.length);
// allocate a roughly sized buffer for the protein sequence
StringBuilder protein = new StringBuilder(seqstring.length() / 2);
*/
void setJalviewColourScheme(ColourSchemeI colourScheme);
+ /**
+ *
+ * @return true if all background sequence/structure binding threads have
+ * completed for this viewer instance
+ */
+ boolean hasMapping();
+
}
static StringBuffer copiedSequences;
- static Vector<int[]> copiedHiddenColumns;
+ static HiddenColumns copiedHiddenColumns;
protected void copy_actionPerformed()
{
if (viewport.hasHiddenColumns() && viewport.getSelectionGroup() != null)
{
- copiedHiddenColumns = new Vector<>(viewport.getAlignment()
- .getHiddenColumns().getHiddenColumnsCopy());
int hiddenOffset = viewport.getSelectionGroup().getStartRes();
- for (int[] region : copiedHiddenColumns)
- {
- region[0] = region[0] - hiddenOffset;
- region[1] = region[1] - hiddenOffset;
- }
+ int hiddenCutoff = viewport.getSelectionGroup().getEndRes();
+
+ // create new HiddenColumns object with copy of hidden regions
+ // between startRes and endRes, offset by startRes
+ copiedHiddenColumns = new HiddenColumns(
+ viewport.getAlignment().getHiddenColumns(), hiddenOffset,
+ hiddenCutoff, hiddenOffset);
}
else
{
{
try
{
-
if (copiedSequences == null)
{
return;
}
- StringTokenizer st = new StringTokenizer(copiedSequences.toString());
+ StringTokenizer st = new StringTokenizer(copiedSequences.toString(),
+ "\t");
Vector seqs = new Vector();
while (st.hasMoreElements())
{
}
AlignFrame af = new AlignFrame(new Alignment(newSeqs),
viewport.applet, newtitle, false);
- if (copiedHiddenColumns != null)
- {
- for (int i = 0; i < copiedHiddenColumns.size(); i++)
- {
- int[] region = copiedHiddenColumns.elementAt(i);
- af.viewport.hideColumns(region[0], region[1]);
- }
- }
+ af.viewport.setHiddenColumns(copiedHiddenColumns);
jalview.bin.JalviewLite.addFrame(af, newtitle, frameWidth,
frameHeight);
if (av.hasHiddenColumns())
{
AlignmentI al = av.getAlignment();
- start = al.getHiddenColumns().findColumnPosition(ostart);
- end = al.getHiddenColumns().findColumnPosition(end);
+ start = al.getHiddenColumns().absoluteToVisibleColumn(ostart);
+ end = al.getHiddenColumns().absoluteToVisibleColumn(end);
if (start == end)
{
if (!scrollToNearest && !al.getHiddenColumns().isVisible(ostart))
if (av.hasHiddenColumns())
{
width = av.getAlignment().getHiddenColumns()
- .findColumnPosition(width);
+ .absoluteToVisibleColumn(width);
}
if (x < 0)
{
import jalview.analysis.AlignmentUtils;
import jalview.datamodel.AlignmentAnnotation;
import jalview.datamodel.Annotation;
+import jalview.datamodel.HiddenColumns;
import jalview.datamodel.SequenceGroup;
import jalview.datamodel.SequenceI;
import jalview.util.MessageManager;
import java.awt.event.MouseMotionListener;
import java.util.Arrays;
import java.util.Collections;
-import java.util.Vector;
public class AnnotationLabels extends Panel
implements ActionListener, MouseListener, MouseMotionListener
{
Image image;
+ /**
+ * width in pixels within which height adjuster arrows are shown and active
+ */
+ private static final int HEIGHT_ADJUSTER_WIDTH = 50;
+
+ /**
+ * height in pixels for allowing height adjuster to be active
+ */
+ private static int HEIGHT_ADJUSTER_HEIGHT = 10;
+
boolean active = false;
AlignmentPanel ap;
this.ap = ap;
this.av = ap.av;
setLayout(null);
-
- /**
- * this retrieves the adjustable height glyph from resources. we don't use
- * it at the moment. java.net.URL url =
- * getClass().getResource("/images/idwidth.gif"); Image temp = null;
- *
- * if (url != null) { temp =
- * java.awt.Toolkit.getDefaultToolkit().createImage(url); }
- *
- * try { MediaTracker mt = new MediaTracker(this); mt.addImage(temp, 0);
- * mt.waitForID(0); } catch (Exception ex) { }
- *
- * BufferedImage bi = new BufferedImage(temp.getHeight(this),
- * temp.getWidth(this), BufferedImage.TYPE_INT_RGB); Graphics2D g =
- * (Graphics2D) bi.getGraphics(); g.rotate(Math.toRadians(90));
- * g.drawImage(temp, 0, -bi.getWidth(this), this); image = (Image) bi;
- */
addMouseListener(this);
addMouseMotionListener(this);
}
}
else if (evt.getActionCommand().equals(COPYCONS_SEQ))
{
- SequenceI cons = av.getConsensusSeq();
+ SequenceGroup group = aa[selectedRow].groupRef;
+ SequenceI cons = group == null ? av.getConsensusSeq()
+ : group.getConsensusSeq();
if (cons != null)
{
copy_annotseqtoclipboard(cons);
@Override
public void mouseMoved(MouseEvent evt)
{
- resizePanel = evt.getY() < 10 && evt.getX() < 14;
+ resizePanel = evt.getY() < HEIGHT_ADJUSTER_HEIGHT
+ && evt.getX() < HEIGHT_ADJUSTER_WIDTH;
setCursor(Cursor.getPredefinedCursor(
resizePanel ? Cursor.S_RESIZE_CURSOR : Cursor.DEFAULT_CURSOR));
int row = getSelectedRow(evt.getY() + scrollOffset);
+ "\t" + sq.getSequenceAsString() + "\n");
if (av.hasHiddenColumns())
{
- jalview.appletgui.AlignFrame.copiedHiddenColumns = new Vector<>(
- av.getAlignment().getHiddenColumns().getHiddenColumnsCopy());
+ jalview.appletgui.AlignFrame.copiedHiddenColumns = new HiddenColumns(
+ av.getAlignment().getHiddenColumns());
}
}
}
}
g.translate(0, +scrollOffset);
- if (resizePanel)
- {
- // g.setColor(Color.red);
- // g.setPaintMode();
- // g.drawLine(2, 8, 5, 2);
- // g.drawLine(5, 2, 8, 8);
- }
- else if (!dragCancelled && dragEvent != null && aa != null)
+
+ if (!resizePanel && !dragCancelled && dragEvent != null && aa != null)
{
g.setColor(Color.lightGray);
g.drawString(aa[selectedRow].label, dragEvent.getX(),
if (av.hasHiddenColumns())
{
column = av.getAlignment().getHiddenColumns()
- .adjustForHiddenColumns(column);
+ .visibleToAbsoluteColumn(column);
}
if (row > -1 && column < aa[row].annotations.length
public class FeatureSettings extends Panel
implements ItemListener, MouseListener, MouseMotionListener,
- ActionListener, AdjustmentListener, FeatureSettingsControllerI
+ AdjustmentListener, FeatureSettingsControllerI
{
FeatureRenderer fr;
add(scrollPane, BorderLayout.CENTER);
}
- Button invert = new Button("Invert Selection");
- invert.addActionListener(this);
+ Button invert = new Button(
+ MessageManager.getString("label.invert_selection"));
+ invert.addActionListener(new ActionListener()
+ {
+
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ invertSelection();
+ }
+ });
Panel lowerPanel = new Panel(new GridLayout(2, 1, 5, 10));
lowerPanel.add(invert);
}
}
- @Override
- public void actionPerformed(ActionEvent evt)
+ protected void invertSelection()
{
for (int i = 0; i < featurePanel.getComponentCount(); i++)
{
if (av.hasHiddenColumns())
{
maxwidth = av.getAlignment().getHiddenColumns()
- .findColumnPosition(maxwidth) - 1;
+ .absoluteToVisibleColumn(maxwidth) - 1;
}
int annotationHeight = 0;
*/
package jalview.appletgui;
+import java.awt.Color;
import java.awt.Cursor;
import java.awt.Dimension;
-import java.awt.Graphics;
-import java.awt.Image;
import java.awt.Panel;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
int oldX = 0;
- Image image;
-
AlignmentPanel ap;
public IdwidthAdjuster(AlignmentPanel ap)
{
setLayout(null);
this.ap = ap;
- java.net.URL url = getClass().getResource("/images/idwidth.gif");
- if (url != null)
- {
- image = java.awt.Toolkit.getDefaultToolkit().getImage(url);
- }
-
+ setBackground(Color.WHITE);
addMouseListener(this);
addMouseMotionListener(this);
}
public void mouseClicked(MouseEvent evt)
{
}
-
- @Override
- public void paint(Graphics g)
- {
- // g.setColor(Color.white);
- // g.fillRect(0, 0, getSize().width, getSize().height);
- // if (active)
- // {
- // if (image != null)
- // {
- // g.drawImage(image, getSize().width - 20, 2, this);
- // }
- // }
- }
-
}
if (!od.isPositionInBox(evt.getX(), evt.getY()))
{
draggingBox = false;
+
+ // display drag cursor at mouse position
+ setCursor(Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR));
+
od.updateViewportFromMouse(evt.getX(), evt.getY(),
av.getAlignment().getHiddenSequences(),
av.getAlignment().getHiddenColumns());
@Override
public void mouseReleased(MouseEvent evt)
{
+ draggingBox = false;
}
@Override
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.beans.PropertyChangeEvent;
+import java.util.Iterator;
import java.util.List;
public class ScalePanel extends Panel
if (av.hasHiddenColumns())
{
- res = av.getAlignment().getHiddenColumns().adjustForHiddenColumns(x);
+ res = av.getAlignment().getHiddenColumns().visibleToAbsoluteColumn(x);
}
else
{
});
pop.add(item);
- if (av.getAlignment().getHiddenColumns().hasManyHiddenColumns())
+ if (av.getAlignment().getHiddenColumns().hasMultiHiddenColumnRegions())
{
item = new MenuItem(MessageManager.getString("action.reveal_all"));
item.addActionListener(new ActionListener()
if (av.hasHiddenColumns())
{
res = av.getAlignment().getHiddenColumns()
- .adjustForHiddenColumns(res);
+ .visibleToAbsoluteColumn(res);
}
if (!stretchingGroup)
int res = (evt.getX() / av.getCharWidth())
+ av.getRanges().getStartRes();
res = Math.max(0, res);
- res = av.getAlignment().getHiddenColumns().adjustForHiddenColumns(res);
+ res = av.getAlignment().getHiddenColumns().visibleToAbsoluteColumn(res);
res = Math.min(res, av.getAlignment().getWidth() - 1);
min = Math.min(res, min);
max = Math.max(res, max);
{
if (hidden.isVisible(sel))
{
- sel = hidden.findColumnPosition(sel);
+ sel = hidden.absoluteToVisibleColumn(sel);
}
else
{
if (av.getShowHiddenMarkers())
{
int widthx = 1 + endx - startx;
- List<Integer> positions = hidden.findHiddenRegionPositions();
- for (int pos : positions)
+ Iterator<Integer> it = hidden.getStartRegionIterator(startx,
+ startx + widthx + 1);
+ while (it.hasNext())
{
-
- res = pos - startx;
-
- if (res < 0 || res > widthx)
- {
- continue;
- }
+ res = it.next() - startx;
gg.fillPolygon(
new int[]
- { -1 + res * avCharWidth - avcharHeight / 4,
- -1 + res * avCharWidth + avcharHeight / 4,
- -1 + res * avCharWidth },
- new int[]
- { y, y, y + 2 * yOf }, 3);
+ { -1 + res * avCharWidth - avcharHeight / 4, -1 + res * avCharWidth + avcharHeight / 4,
+ -1 + res * avCharWidth }, new int[]
+ { y, y, y + 2 * yOf }, 3);
}
}
}
import jalview.datamodel.SearchResultsI;
import jalview.datamodel.SequenceGroup;
import jalview.datamodel.SequenceI;
+import jalview.datamodel.VisibleContigsIterator;
import jalview.renderer.ScaleRenderer;
import jalview.renderer.ScaleRenderer.ScaleMark;
import jalview.viewmodel.AlignmentViewport;
import java.awt.Image;
import java.awt.Panel;
import java.beans.PropertyChangeEvent;
-import java.util.List;
+import java.util.Iterator;
public class SeqCanvas extends Panel implements ViewportListenerI
{
if (av.hasHiddenColumns())
{
startx = av.getAlignment().getHiddenColumns()
- .adjustForHiddenColumns(startx);
+ .visibleToAbsoluteColumn(startx);
endx = av.getAlignment().getHiddenColumns()
- .adjustForHiddenColumns(endx);
+ .visibleToAbsoluteColumn(endx);
}
int maxwidth = av.getAlignment().getWidth();
if (av.hasHiddenColumns())
{
maxwidth = av.getAlignment().getHiddenColumns()
- .findColumnPosition(maxwidth) - 1;
+ .absoluteToVisibleColumn(maxwidth) - 1;
}
// WEST SCALE
if (av.hasHiddenColumns())
{
endx = av.getAlignment().getHiddenColumns()
- .adjustForHiddenColumns(endx);
+ .visibleToAbsoluteColumn(endx);
}
SequenceI seq;
int canvasHeight, int startRes)
{
AlignmentI al = av.getAlignment();
-
+
FontMetrics fm = getFontMetrics(av.getFont());
-
+
LABEL_EAST = 0;
LABEL_WEST = 0;
-
+
if (av.getScaleRightWrapped())
{
LABEL_EAST = fm.stringWidth(getMask());
}
-
+
if (av.getScaleLeftWrapped())
{
LABEL_WEST = fm.stringWidth(getMask());
}
-
+
int hgap = avcharHeight;
if (av.getScaleAboveWrapped())
{
hgap += avcharHeight;
}
-
+
int cWidth = (canvasWidth - LABEL_EAST - LABEL_WEST) / avcharWidth;
int cHeight = av.getAlignment().getHeight() * avcharHeight;
-
+
av.setWrappedWidth(cWidth);
-
+
av.getRanges().setViewportStartAndWidth(startRes, cWidth);
-
+
int endx;
int ypos = hgap;
-
+
int maxwidth = av.getAlignment().getWidth();
-
+
if (av.hasHiddenColumns())
{
maxwidth = av.getAlignment().getHiddenColumns()
- .findColumnPosition(maxwidth);
+ .absoluteToVisibleColumn(maxwidth);
}
-
+
while ((ypos <= canvasHeight) && (startRes < maxwidth))
{
endx = startRes + cWidth - 1;
-
+
if (endx > maxwidth)
{
endx = maxwidth;
}
-
+
g.setColor(Color.black);
-
+
if (av.getScaleLeftWrapped())
{
drawWestScale(g, startRes, endx, ypos);
}
-
+
if (av.getScaleRightWrapped())
{
g.translate(canvasWidth - LABEL_EAST, 0);
drawEastScale(g, startRes, endx, ypos);
g.translate(-(canvasWidth - LABEL_EAST), 0);
}
-
+
g.translate(LABEL_WEST, 0);
-
+
if (av.getScaleAboveWrapped())
{
drawNorthScale(g, startRes, endx, ypos);
HiddenColumns hidden = av.getAlignment().getHiddenColumns();
g.setColor(Color.blue);
int res;
- List<Integer> positions = hidden.findHiddenRegionPositions();
- for (int pos : positions)
+ Iterator<Integer> it = hidden.getStartRegionIterator(startRes,
+ endx + 1);
+ while (it.hasNext())
{
- res = pos - startRes;
-
- if (res < 0 || res > endx - startRes)
- {
- continue;
- }
-
+ res = it.next() - startRes;
gg.fillPolygon(
new int[]
- { res * avcharWidth - avcharHeight / 4,
- res * avcharWidth + avcharHeight / 4,
- res * avcharWidth },
+ { res * avcharWidth - avcharHeight / 4, res * avcharWidth + avcharHeight / 4, res * avcharWidth },
new int[]
- { ypos - (avcharHeight / 2), ypos - (avcharHeight / 2),
- ypos - (avcharHeight / 2) + 8 },
- 3);
-
+ { ypos - (avcharHeight / 2), ypos - (avcharHeight / 2), ypos - (avcharHeight / 2) + 8 }, 3);
}
}
-
+
if (g.getClip() == null)
{
g.setClip(0, 0, cWidth * avcharWidth, canvasHeight);
}
-
+
drawPanel(g, startRes, endx, 0, al.getHeight() - 1, ypos);
g.setClip(null);
-
+
if (av.isShowAnnotation())
{
g.translate(0, cHeight + ypos + 4);
{
annotations = new AnnotationPanel(av);
}
-
+
annotations.drawComponent(g, startRes, endx + 1);
g.translate(0, -cHeight - ypos - 4);
}
g.translate(-LABEL_WEST, 0);
-
+
ypos += cHeight + getAnnotationHeight() + hgap;
-
+
startRes += cWidth;
}
-
+
}
AnnotationPanel annotations;
else
{
int screenY = 0;
- final int screenYMax = endRes - startRes;
- int blockStart = startRes;
- int blockEnd = endRes;
-
- if (av.hasHiddenColumns())
- {
- HiddenColumns hidden = av.getAlignment().getHiddenColumns();
- for (int[] region : hidden.getHiddenColumnsCopy())
- {
- int hideStart = region[0];
- int hideEnd = region[1];
-
- if (hideStart <= blockStart)
- {
- blockStart += (hideEnd - hideStart) + 1;
- continue;
- }
-
- /*
- * draw up to just before the next hidden region, or the end of
- * the visible region, whichever comes first
- */
- blockEnd = Math.min(hideStart - 1, blockStart + screenYMax
- - screenY);
-
- g1.translate(screenY * avcharWidth, 0);
+ int blockStart;
+ int blockEnd;
- draw(g1, blockStart, blockEnd, startSeq, endSeq, offset);
+ HiddenColumns hidden = av.getAlignment().getHiddenColumns();
+ VisibleContigsIterator regions = (VisibleContigsIterator) hidden
+ .getVisContigsIterator(startRes, endRes + 1, true);
- /*
- * draw the downline of the hidden column marker (ScalePanel draws the
- * triangle on top) if we reached it
- */
- if (av.getShowHiddenMarkers() && blockEnd == hideStart - 1)
- {
- g1.setColor(Color.blue);
- g1.drawLine((blockEnd - blockStart + 1) * avcharWidth - 1,
- 0 + offset,
- (blockEnd - blockStart + 1) * avcharWidth - 1,
- (endSeq - startSeq + 1) * avcharHeight + offset);
- }
-
- g1.translate(-screenY * avcharWidth, 0);
- screenY += blockEnd - blockStart + 1;
- blockStart = hideEnd + 1;
-
- if (screenY > screenYMax)
- {
- // already rendered last block
- return;
- }
- }
- }
- if (screenY <= screenYMax)
+ while (regions.hasNext())
{
- // remaining visible region to render
- blockEnd = blockStart + (endRes - startRes) - screenY;
+ int[] region = regions.next();
+ blockEnd = region[1];
+ blockStart = region[0];
+
+ /*
+ * draw up to just before the next hidden region, or the end of
+ * the visible region, whichever comes first
+ */
g1.translate(screenY * avcharWidth, 0);
+
draw(g1, blockStart, blockEnd, startSeq, endSeq, offset);
+ /*
+ * draw the downline of the hidden column marker (ScalePanel draws the
+ * triangle on top) if we reached it
+ */
+ if (av.getShowHiddenMarkers()
+ && (regions.hasNext() || regions.endsAtHidden()))
+ {
+ g1.setColor(Color.blue);
+ g1.drawLine((blockEnd - blockStart + 1) * avcharWidth - 1,
+ 0 + offset, (blockEnd - blockStart + 1) * avcharWidth - 1,
+ (endSeq - startSeq + 1) * avcharHeight + offset);
+ }
+
g1.translate(-screenY * avcharWidth, 0);
+ screenY += blockEnd - blockStart + 1;
}
}
-
}
// int startRes, int endRes, int startSeq, int endSeq, int x, int y,
if (av.hasHiddenColumns())
{
res = av.getAlignment().getHiddenColumns()
- .adjustForHiddenColumns(res);
+ .visibleToAbsoluteColumn(res);
}
return res;
{
fixedColumns = true;
int y1 = av.getAlignment().getHiddenColumns()
- .getHiddenBoundaryLeft(startres);
+ .getNextHiddenBoundary(true, startres);
int y2 = av.getAlignment().getHiddenColumns()
- .getHiddenBoundaryRight(startres);
+ .getNextHiddenBoundary(false, startres);
if ((insertGap && startres > y1 && lastres < y1)
|| (!insertGap && startres < y2 && lastres > y2))
if (sg.getSize() == av.getAlignment().getHeight())
{
if ((av.hasHiddenColumns() && startres < av.getAlignment()
- .getHiddenColumns().getHiddenBoundaryRight(startres)))
+ .getHiddenColumns()
+ .getNextHiddenBoundary(false, startres)))
{
endEditing();
return;
* <li>FIGURE_AUTOIDWIDTH (false) Expand the left hand column of an exported
* alignment figure to accommodate even the longest sequence ID or annotation
* label.</li>
- * <li>FIGURE_FIXEDIDWIDTH Specifies the width to use for the left-hand column
+ * <li>FIGURE_USERIDWIDTH Specifies the width to use for the left-hand column
* when exporting an alignment as a figure (setting FIGURE_AUTOIDWIDTH to true
* will override this).</li>
* <li>STRUCT_FROM_PDB (false) derive secondary structure annotation from PDB
}
}
- /** Called when Jalview is started */
+ /**
+ * Loads properties from the given properties file. Any existing properties
+ * are first cleared.
+ */
public static void loadProperties(String propsFile)
{
propertiesFile = propsFile;
{
fis = new FileInputStream(propertiesFile);
}
+ applicationProperties.clear();
applicationProperties.load(fis);
// remove any old build properties
* @param obj
* String value of property
*
- * @return String value of property
+ * @return previous value of property (or null)
*/
- public static String setProperty(String key, String obj)
+ public static Object setProperty(String key, String obj)
{
-
+ Object oldValue = null;
try
{
- applicationProperties.setProperty(key, obj);
+ oldValue = applicationProperties.setProperty(key, obj);
if (!propsAreReadOnly)
{
FileOutputStream out = new FileOutputStream(propertiesFile);
System.out.println(
"Error setting property: " + key + " " + obj + "\n" + ex);
}
- return obj;
+ return oldValue;
}
/**
import jalview.datamodel.AlignmentI;
import jalview.datamodel.AlignmentOrder;
import jalview.datamodel.ColumnSelection;
-import jalview.datamodel.HiddenColumns;
import jalview.datamodel.PDBEntry;
import jalview.datamodel.Sequence;
import jalview.datamodel.SequenceGroup;
SequenceI rs = sel.getSequenceAt(0);
start = rs.findIndex(start);
end = rs.findIndex(end);
- List<Integer> cs = new ArrayList<Integer>(csel.getSelected());
+ List<Integer> cs = new ArrayList<>(csel.getSelected());
csel.clear();
for (Integer selectedCol : cs)
{
setMouseoverListener(currentAlignFrame, listener);
}
- private Vector<jalview.javascript.JSFunctionExec> javascriptListeners = new Vector<jalview.javascript.JSFunctionExec>();
+ private Vector<jalview.javascript.JSFunctionExec> javascriptListeners = new Vector<>();
/*
* (non-Javadoc)
else
{
param = st.nextToken();
- List<SequenceI> tmp = new ArrayList<SequenceI>();
- List<String> tmp2 = new ArrayList<String>();
+ List<SequenceI> tmp = new ArrayList<>();
+ List<String> tmp2 = new ArrayList<>();
while (st.hasMoreTokens())
{
JnetAnnotationMaker.add_annotation(predictions,
alignFrame.viewport.getAlignment(), 0, false);
// false == do not add sequence profile from concise output
- SequenceI repseq = alignFrame.viewport.getAlignment()
- .getSequenceAt(0);
- alignFrame.viewport.getAlignment().setSeqrep(repseq);
- HiddenColumns cs = new HiddenColumns();
- cs.hideInsertionsFor(repseq);
- alignFrame.viewport.getAlignment().setHiddenColumns(cs);
+
+ alignFrame.viewport.getAlignment().setupJPredAlignment();
+
alignFrame.alignPanel.fontChanged();
alignFrame.alignPanel.setScrollValues(0, 0);
result = true;
// callInitCallback();
}
- private Hashtable<String, long[]> jshashes = new Hashtable<String, long[]>();
+ private Hashtable<String, long[]> jshashes = new Hashtable<>();
- private Hashtable<String, Hashtable<String, String[]>> jsmessages = new Hashtable<String, Hashtable<String, String[]>>();
+ private Hashtable<String, Hashtable<String, String[]>> jsmessages = new Hashtable<>();
public void setJsMessageSet(String messageclass, String viewId,
String[] colcommands)
Hashtable<String, String[]> msgset = jsmessages.get(messageclass);
if (msgset == null)
{
- msgset = new Hashtable<String, String[]>();
+ msgset = new Hashtable<>();
jsmessages.put(messageclass, msgset);
}
msgset.put(viewId, colcommands);
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.BitSet;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Hashtable;
+import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
{
private Alignment dataset;
- protected List<SequenceI> sequences;
+ private List<SequenceI> sequences;
private SequenceI hmmConsensus;
return sequences.get(i);
}
}
+
return null;
}
public int getWidth()
{
int maxLength = -1;
-
+
for (int i = 0; i < sequences.size(); i++)
{
if (getSequenceAt(i).getLength() > maxLength)
maxLength = getSequenceAt(i).getLength();
}
}
-
+
return maxLength;
}
+ /*
+ @Override
+ public int getWidth()
+ {
+ final Wrapper temp = new Wrapper();
+
+ forEachSequence(new Consumer<SequenceI>()
+ {
+ @Override
+ public void accept(SequenceI s)
+ {
+ if (s.getLength() > temp.inner)
+ {
+ temp.inner = s.getLength();
+ }
+ }
+ }, 0, sequences.size() - 1);
+
+ return temp.inner;
+ }
+
+ public static class Wrapper
+ {
+ public int inner;
+ }*/
/**
* DOCUMENT ME!
AlignmentAnnotation annot = new AlignmentAnnotation(name, name,
new Annotation[1], 0f, 0f, AlignmentAnnotation.BAR_GRAPH);
annot.hasText = false;
- annot.setCalcId(new String(calcId));
+ if (calcId != null)
+ {
+ annot.setCalcId(new String(calcId));
+ }
annot.autoCalculated = autoCalc;
if (seqRef != null)
{
{
this.hmmConsensus = hmmConsensus;
}
+
+ @Override
+ public void setupJPredAlignment()
+ {
+ SequenceI repseq = getSequenceAt(0);
+ setSeqrep(repseq);
+ HiddenColumns cs = new HiddenColumns();
+ cs.hideList(repseq.getInsertions());
+ setHiddenColumns(cs);
+ }
+
+ @Override
+ public HiddenColumns propagateInsertions(SequenceI profileseq,
+ AlignmentView input)
+ {
+ int profsqpos = 0;
+
+ char gc = getGapCharacter();
+ Object[] alandhidden = input.getAlignmentAndHiddenColumns(gc);
+ HiddenColumns nview = (HiddenColumns) alandhidden[1];
+ SequenceI origseq = ((SequenceI[]) alandhidden[0])[profsqpos];
+ return propagateInsertions(profileseq, origseq, nview);
+ }
+
+ /**
+ *
+ * @param profileseq
+ * sequence in al which corresponds to origseq
+ * @param al
+ * alignment which is to have gaps inserted into it
+ * @param origseq
+ * sequence corresponding to profileseq which defines gap map for
+ * modifying al
+ */
+ private HiddenColumns propagateInsertions(SequenceI profileseq,
+ SequenceI origseq, HiddenColumns hc)
+ {
+ // take the set of hidden columns, and the set of gaps in origseq,
+ // and remove all the hidden gaps from hiddenColumns
+
+ // first get the gaps as a Bitset
+ // then calculate hidden ^ not(gap)
+ BitSet gaps = origseq.gapBitset();
+ hc.andNot(gaps);
+
+ // for each sequence in the alignment, except the profile sequence,
+ // insert gaps corresponding to each hidden region but where each hidden
+ // column region is shifted backwards by the number of preceding visible
+ // gaps update hidden columns at the same time
+ HiddenColumns newhidden = new HiddenColumns();
+
+ int numGapsBefore = 0;
+ int gapPosition = 0;
+ Iterator<int[]> it = hc.iterator();
+ while (it.hasNext())
+ {
+ int[] region = it.next();
+
+ // get region coordinates accounting for gaps
+ // we can rely on gaps not being *in* hidden regions because we already
+ // removed those
+ while (gapPosition < region[0])
+ {
+ gapPosition++;
+ if (gaps.get(gapPosition))
+ {
+ numGapsBefore++;
+ }
+ }
+
+ int left = region[0] - numGapsBefore;
+ int right = region[1] - numGapsBefore;
+
+ newhidden.hideColumns(left, right);
+ padGaps(left, right, profileseq);
+ }
+ return newhidden;
+ }
+
+ /**
+ * Pad gaps in all sequences in alignment except profileseq
+ *
+ * @param left
+ * position of first gap to insert
+ * @param right
+ * position of last gap to insert
+ * @param profileseq
+ * sequence not to pad
+ */
+ private void padGaps(int left, int right, SequenceI profileseq)
+ {
+ char gc = getGapCharacter();
+
+ // make a string with number of gaps = length of hidden region
+ StringBuilder sb = new StringBuilder();
+ for (int g = 0; g < right - left + 1; g++)
+ {
+ sb.append(gc);
+ }
+
+ // loop over the sequences and pad with gaps where required
+ for (int s = 0, ns = getHeight(); s < ns; s++)
+ {
+ SequenceI sqobj = getSequenceAt(s);
+ if ((sqobj != profileseq) && (sqobj.getLength() >= left))
+ {
+ String sq = sqobj.getSequenceAsString();
+ sqobj.setSequence(
+ sq.substring(0, left) + sb.toString() + sq.substring(left));
+ }
+ }
+ }
}
{
return;
}
- hidden.makeVisibleAnnotation(this);
+ makeVisibleAnnotation(hidden);
}
/**
return graphMin < graphMax;
}
+ /**
+ * delete any columns in alignmentAnnotation that are hidden (including
+ * sequence associated annotation).
+ *
+ * @param hiddenColumns
+ * the set of hidden columns
+ */
+ public void makeVisibleAnnotation(HiddenColumns hiddenColumns)
+ {
+ if (annotations != null)
+ {
+ makeVisibleAnnotation(0, annotations.length, hiddenColumns);
+ }
+ }
+
+ /**
+ * delete any columns in alignmentAnnotation that are hidden (including
+ * sequence associated annotation).
+ *
+ * @param start
+ * remove any annotation to the right of this column
+ * @param end
+ * remove any annotation to the left of this column
+ * @param hiddenColumns
+ * the set of hidden columns
+ */
+ public void makeVisibleAnnotation(int start, int end,
+ HiddenColumns hiddenColumns)
+ {
+ if (annotations != null)
+ {
+ if (hiddenColumns.hasHiddenColumns())
+ {
+ removeHiddenAnnotation(start, end, hiddenColumns);
+ }
+ else
+ {
+ restrict(start, end);
+ }
+ }
+ }
+
+ /**
+ * The actual implementation of deleting hidden annotation columns
+ *
+ * @param start
+ * remove any annotation to the right of this column
+ * @param end
+ * remove any annotation to the left of this column
+ * @param hiddenColumns
+ * the set of hidden columns
+ */
+ private void removeHiddenAnnotation(int start, int end,
+ HiddenColumns hiddenColumns)
+ {
+ // mangle the alignmentAnnotation annotation array
+ ArrayList<Annotation[]> annels = new ArrayList<>();
+ Annotation[] els = null;
+
+ int w = 0;
+
+ Iterator<int[]> blocks = hiddenColumns.getVisContigsIterator(start,
+ end + 1, false);
+
+ int copylength;
+ int annotationLength;
+ while (blocks.hasNext())
+ {
+ int[] block = blocks.next();
+ annotationLength = block[1] - block[0] + 1;
+
+ if (blocks.hasNext())
+ {
+ // copy just the visible segment of the annotation row
+ copylength = annotationLength;
+ }
+ else
+ {
+ if (annotationLength + block[0] <= annotations.length)
+ {
+ // copy just the visible segment of the annotation row
+ copylength = annotationLength;
+ }
+ else
+ {
+ // copy to the end of the annotation row
+ copylength = annotations.length - block[0];
+ }
+ }
+
+ els = new Annotation[annotationLength];
+ annels.add(els);
+ System.arraycopy(annotations, block[0], els, 0, copylength);
+ w += annotationLength;
+ }
+
+ if (w != 0)
+ {
+ annotations = new Annotation[w];
+
+ w = 0;
+ for (Annotation[] chnk : annels)
+ {
+ System.arraycopy(chnk, 0, annotations, w, chnk.length);
+ w += chnk.length;
+ }
+ }
+ }
+
public static Iterable<AlignmentAnnotation> findAnnotations(
Iterable<AlignmentAnnotation> list, SequenceI seq, String calcId,
String label)
*/
AlignedCodonFrame getMapping(SequenceI mapFrom, SequenceI mapTo);
+ /**
+ * Set the hidden columns collection on the alignment
+ *
+ * @param cols
+ */
public void setHiddenColumns(HiddenColumns cols);
/**
* Insert a sequence at a position in an alignment
*
* @param i
- * The idnex of the position.
+ * The index of the position.
* @param snew
* The new sequence.
*/
void insertSequenceAt(int i, SequenceI snew);
-
+ /**
+ * Set the first sequence as representative and hide its insertions. Typically
+ * used when loading JPred files.
+ */
+ public void setupJPredAlignment();
+ /**
+ * Add gaps into the sequences aligned to profileseq under the given
+ * AlignmentView
+ *
+ * @param profileseq
+ * sequence in al which sequences are aligned to
+ * @param input
+ * alignment view where sequence corresponding to profileseq is first
+ * entry
+ * @return new HiddenColumns for new alignment view, with insertions into
+ * profileseq marked as hidden.
+ */
+ public HiddenColumns propagateInsertions(SequenceI profileseq,
+ AlignmentView input);
}
*/
package jalview.datamodel;
-import java.util.List;
+import java.util.Iterator;
public class CigarArray extends CigarBase
{
SequenceGroup selectionGroup)
{
this(constructSeqCigarArray(alignment, selectionGroup));
- constructFromAlignment(alignment,
- hidden != null ? hidden.getHiddenColumnsCopy() : null,
- selectionGroup);
+ constructFromAlignment(alignment, hidden, selectionGroup);
}
private static int[] _calcStartEndBounds(AlignmentI alignment,
* @param selectionGroup
*/
private void constructFromAlignment(AlignmentI alignment,
- List<int[]> list, SequenceGroup selectionGroup)
+ HiddenColumns hidden, SequenceGroup selectionGroup)
{
int[] _startend = _calcStartEndBounds(alignment, selectionGroup);
- int start = _startend[1], end = _startend[2];
+ int start = _startend[1];
+ int end = _startend[2];
// now construct the CigarArray operations
- if (list != null)
+ if (hidden != null)
{
int[] region;
- int hideStart, hideEnd;
+ int hideStart;
+ int hideEnd;
int last = start;
- for (int j = 0; last < end & j < list.size(); j++)
+
+ Iterator<int[]> regions = hidden.getBoundedIterator(start, end);
+ while (regions.hasNext())
{
- region = list.get(j);
+ region = regions.next();
hideStart = region[0];
hideEnd = region[1];
- // edit hidden regions to selection range
-
- // just move on if hideEnd is before last
- if (hideEnd < last)
- {
- continue;
- }
- // exit if next region is after end
- if (hideStart > end)
- {
- break;
- }
// truncate region at start if last falls in region
if ((hideStart < last) && (hideEnd >= last))
addOperation(CigarArray.D, 1 + hideEnd - hideStart);
last = hideEnd + 1;
}
+
// Final match if necessary.
if (last <= end)
{
*/
package jalview.datamodel;
-import jalview.util.Comparison;
-import jalview.util.ShiftList;
-
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.BitSet;
-import java.util.Collections;
+import java.util.Iterator;
import java.util.List;
-import java.util.Vector;
import java.util.concurrent.locks.ReentrantReadWriteLock;
+/**
+ * This class manages the collection of hidden columns associated with an
+ * alignment. To iterate over the collection, or over visible columns/regions,
+ * use an iterator obtained from one of:
+ *
+ * - getBoundedIterator: iterates over the hidden regions, within some bounds,
+ * returning *absolute* positions
+ *
+ * - getBoundedStartIterator: iterates over the start positions of hidden
+ * regions, within some bounds, returning *visible* positions
+ *
+ * - getVisContigsIterator: iterates over visible regions in a range, returning
+ * *absolute* positions
+ *
+ * - getVisibleColsIterator: iterates over the visible *columns*
+ *
+ * For performance reasons, provide bounds where possible. Note that column
+ * numbering begins at 0 throughout this class.
+ *
+ * @author kmourao
+ */
+
+/* Implementation notes:
+ *
+ * Methods which change the hiddenColumns collection should use a writeLock to
+ * prevent other threads accessing the hiddenColumns collection while changes
+ * are being made. They should also reset the hidden columns cursor, and either
+ * update the hidden columns count, or set it to 0 (so that it will later be
+ * updated when needed).
+ *
+ *
+ * Methods which only need read access to the hidden columns collection should
+ * use a readLock to prevent other threads changing the hidden columns
+ * collection while it is in use.
+ */
public class HiddenColumns
{
+ private static final int HASH_MULTIPLIER = 31;
+
private static final ReentrantReadWriteLock LOCK = new ReentrantReadWriteLock();
/*
+ * Cursor which tracks the last used hidden columns region, and the number
+ * of hidden columns up to (but not including) that region.
+ */
+ private HiddenColumnsCursor cursor = new HiddenColumnsCursor();
+
+ /*
+ * cache of the number of hidden columns: must be kept up to date by methods
+ * which add or remove hidden columns
+ */
+ private int numColumns = 0;
+
+ /*
* list of hidden column [start, end] ranges; the list is maintained in
* ascending start column order
*/
- private ArrayList<int[]> hiddenColumns;
+ private List<int[]> hiddenColumns = new ArrayList<>();
/**
* Constructor
* Copy constructor
*
* @param copy
+ * the HiddenColumns object to copy from
*/
public HiddenColumns(HiddenColumns copy)
{
+ this(copy, Integer.MIN_VALUE, Integer.MAX_VALUE, 0);
+ }
+
+ /**
+ * Copy constructor within bounds and with offset. Copies hidden column
+ * regions fully contained between start and end, and offsets positions by
+ * subtracting offset.
+ *
+ * @param copy
+ * HiddenColumns instance to copy from
+ * @param start
+ * lower bound to copy from
+ * @param end
+ * upper bound to copy to
+ * @param offset
+ * offset to subtract from each region boundary position
+ *
+ */
+ public HiddenColumns(HiddenColumns copy, int start, int end, int offset)
+ {
try
{
LOCK.writeLock().lock();
if (copy != null)
{
- if (copy.hiddenColumns != null)
+ numColumns = 0;
+ Iterator<int[]> it = copy.getBoundedIterator(start, end);
+ while (it.hasNext())
+ {
+ int[] region = it.next();
+ // still need to check boundaries because iterator returns
+ // all overlapping regions and we need contained regions
+ if (region[0] >= start && region[1] <= end)
+ {
+ hiddenColumns.add(
+ new int[]
+ { region[0] - offset, region[1] - offset });
+ numColumns += region[1] - region[0] + 1;
+ }
+ }
+ cursor = new HiddenColumnsCursor(hiddenColumns);
+ }
+ } finally
+ {
+ LOCK.writeLock().unlock();
+ }
+ }
+
+ /**
+ * Adds the specified column range to the hidden columns collection
+ *
+ * @param start
+ * start of range to add (absolute position in alignment)
+ * @param end
+ * end of range to add (absolute position in alignment)
+ */
+ public void hideColumns(int start, int end)
+ {
+ try
+ {
+ LOCK.writeLock().lock();
+
+ int previndex = 0;
+ int prevHiddenCount = 0;
+ int regionindex = 0;
+ if (!hiddenColumns.isEmpty())
+ {
+ // set up cursor reset values
+ HiddenCursorPosition cursorPos = cursor.findRegionForColumn(start, false);
+ regionindex = cursorPos.getRegionIndex();
+
+ if (regionindex > 0)
+ {
+ // get previous index and hidden count for updating the cursor later
+ previndex = regionindex - 1;
+ int[] prevRegion = hiddenColumns.get(previndex);
+ prevHiddenCount = cursorPos.getHiddenSoFar()
+ - (prevRegion[1] - prevRegion[0] + 1);
+ }
+ }
+
+ // new range follows everything else; check first to avoid looping over
+ // whole hiddenColumns collection
+ if (hiddenColumns.isEmpty()
+ || start > hiddenColumns.get(hiddenColumns.size() - 1)[1])
+ {
+ hiddenColumns.add(new int[] { start, end });
+ numColumns += end - start + 1;
+ }
+ else
+ {
+ /*
+ * traverse existing hidden ranges and insert / amend / append as
+ * appropriate
+ */
+ boolean added = false;
+ if (regionindex > 0)
+ {
+ added = insertRangeAtRegion(regionindex - 1, start, end);
+ }
+ if (!added && regionindex < hiddenColumns.size())
+ {
+ insertRangeAtRegion(regionindex, start, end);
+ }
+ }
+
+ // reset the cursor to just before our insertion point: this saves
+ // a lot of reprocessing in large alignments
+ cursor = new HiddenColumnsCursor(hiddenColumns, previndex,
+ prevHiddenCount);
+ } finally
+ {
+ LOCK.writeLock().unlock();
+ }
+ }
+
+ /**
+ * Insert [start, range] at the region at index i in hiddenColumns, if
+ * feasible
+ *
+ * @param i
+ * index to insert at
+ * @param start
+ * start of range to insert
+ * @param end
+ * end of range to insert
+ * @return true if range was successfully inserted
+ */
+ private boolean insertRangeAtRegion(int i, int start, int end)
+ {
+ boolean added = false;
+
+ int[] region = hiddenColumns.get(i);
+ if (end < region[0] - 1)
+ {
+ /*
+ * insert discontiguous preceding range
+ */
+ hiddenColumns.add(i, new int[] { start, end });
+ numColumns += end - start + 1;
+ added = true;
+ }
+ else if (end <= region[1])
+ {
+ /*
+ * new range overlaps existing, or is contiguous preceding it - adjust
+ * start column
+ */
+ int oldstart = region[0];
+ region[0] = Math.min(region[0], start);
+ numColumns += oldstart - region[0]; // new columns are between old and
+ // adjusted starts
+ added = true;
+ }
+ else if (start <= region[1] + 1)
+ {
+ /*
+ * new range overlaps existing, or is contiguous following it - adjust
+ * start and end columns
+ */
+ insertRangeAtOverlap(i, start, end, region);
+ added = true;
+ }
+ return added;
+ }
+
+ /**
+ * Insert a range whose start position overlaps an existing region and/or is
+ * contiguous to the right of the region
+ *
+ * @param i
+ * index to insert at
+ * @param start
+ * start of range to insert
+ * @param end
+ * end of range to insert
+ * @param region
+ * the overlapped/continued region
+ */
+ private void insertRangeAtOverlap(int i, int start, int end, int[] region)
+ {
+ int oldstart = region[0];
+ int oldend = region[1];
+ region[0] = Math.min(region[0], start);
+ region[1] = Math.max(region[1], end);
+
+ numColumns += oldstart - region[0];
+
+ /*
+ * also update or remove any subsequent ranges
+ * that are overlapped
+ */
+ int endi = i;
+ while (endi < hiddenColumns.size() - 1)
+ {
+ int[] nextRegion = hiddenColumns.get(endi + 1);
+ if (nextRegion[0] > end + 1)
+ {
+ /*
+ * gap to next hidden range - no more to update
+ */
+ break;
+ }
+ numColumns -= nextRegion[1] - nextRegion[0] + 1;
+ region[1] = Math.max(nextRegion[1], end);
+ endi++;
+ }
+ numColumns += region[1] - oldend;
+ hiddenColumns.subList(i + 1, endi + 1).clear();
+ }
+
+ /**
+ * hide a list of ranges
+ *
+ * @param ranges
+ */
+ public void hideList(List<int[]> ranges)
+ {
+ try
+ {
+ LOCK.writeLock().lock();
+ for (int[] r : ranges)
+ {
+ hideColumns(r[0], r[1]);
+ }
+ cursor = new HiddenColumnsCursor(hiddenColumns);
+
+ } finally
+ {
+ LOCK.writeLock().unlock();
+ }
+ }
+
+ /**
+ * Unhides, and adds to the selection list, all hidden columns
+ */
+ public void revealAllHiddenColumns(ColumnSelection sel)
+ {
+ try
+ {
+ LOCK.writeLock().lock();
+
+ for (int[] region : hiddenColumns)
+ {
+ for (int j = region[0]; j < region[1] + 1; j++)
{
- hiddenColumns = copy.copyHiddenRegionsToArrayList();
+ sel.addElement(j);
}
}
+ hiddenColumns.clear();
+ cursor = new HiddenColumnsCursor(hiddenColumns);
+ numColumns = 0;
+
} finally
{
LOCK.writeLock().unlock();
}
/**
- * This method is used to return all the HiddenColumn regions and is intended
- * to remain private. External callers which need a copy of the regions can
- * call getHiddenColumnsCopyAsList.
+ * Reveals, and marks as selected, the hidden column range with the given
+ * start column
*
- * @return empty list or List of hidden column intervals
+ * @param start
+ * the start column to look for
+ * @param sel
+ * the column selection to add the hidden column range to
*/
- private List<int[]> getHiddenRegions()
+ public void revealHiddenColumns(int start, ColumnSelection sel)
{
- return hiddenColumns == null ? Collections.<int[]> emptyList()
- : hiddenColumns;
+ try
+ {
+ LOCK.writeLock().lock();
+
+ if (!hiddenColumns.isEmpty())
+ {
+ int regionIndex = cursor.findRegionForColumn(start, false)
+ .getRegionIndex();
+
+ if (regionIndex != -1 && regionIndex != hiddenColumns.size())
+ {
+ // regionIndex is the region which either contains start
+ // or lies to the right of start
+ int[] region = hiddenColumns.get(regionIndex);
+ if (start == region[0])
+ {
+ for (int j = region[0]; j < region[1] + 1; j++)
+ {
+ sel.addElement(j);
+ }
+ int colsToRemove = region[1] - region[0] + 1;
+ hiddenColumns.remove(regionIndex);
+ numColumns -= colsToRemove;
+ }
+ }
+ }
+ } finally
+ {
+ LOCK.writeLock().unlock();
+ }
}
/**
{
LOCK.readLock().lock();
StringBuilder regionBuilder = new StringBuilder();
- if (hiddenColumns != null)
+
+ boolean first = true;
+ for (int[] range : hiddenColumns)
{
- for (int[] range : hiddenColumns)
+ if (!first)
+ {
+ regionBuilder.append(delimiter);
+ }
+ else
{
- regionBuilder.append(delimiter).append(range[0]).append(between)
- .append(range[1]);
+ first = false;
}
+ regionBuilder.append(range[0]).append(between).append(range[1]);
- regionBuilder.deleteCharAt(0);
}
+
return regionBuilder.toString();
} finally
{
*/
public int getSize()
{
+ return numColumns;
+ }
+
+ /**
+ * Get the number of distinct hidden regions
+ *
+ * @return number of regions
+ */
+ public int getNumberOfRegions()
+ {
try
{
LOCK.readLock().lock();
- int size = 0;
- if (hasHiddenColumns())
- {
- for (int[] range : hiddenColumns)
- {
- size += range[1] - range[0] + 1;
- }
- }
- return size;
+ return hiddenColumns.size();
} finally
{
LOCK.readLock().unlock();
/*
* check hidden columns are either both null, or match
*/
- if (this.hiddenColumns == null)
- {
- return (that.hiddenColumns == null);
- }
- if (that.hiddenColumns == null
- || that.hiddenColumns.size() != this.hiddenColumns.size())
+
+ if (that.hiddenColumns.size() != this.hiddenColumns.size())
{
return false;
}
- int i = 0;
- for (int[] thisRange : hiddenColumns)
+
+ Iterator<int[]> it = this.iterator();
+ Iterator<int[]> thatit = that.iterator();
+ while (it.hasNext())
{
- int[] thatRange = that.hiddenColumns.get(i++);
- if (thisRange[0] != thatRange[0] || thisRange[1] != thatRange[1])
+ if (!(Arrays.equals(it.next(), thatit.next())))
{
return false;
}
}
return true;
+
} finally
{
LOCK.readLock().unlock();
* int column index in alignment view (count from zero)
* @return alignment column index for column
*/
- public int adjustForHiddenColumns(int column)
+ public int visibleToAbsoluteColumn(int column)
{
try
{
LOCK.readLock().lock();
int result = column;
- if (hiddenColumns != null)
+
+ if (!hiddenColumns.isEmpty())
{
- for (int i = 0; i < hiddenColumns.size(); i++)
- {
- int[] region = hiddenColumns.get(i);
- if (result >= region[0])
- {
- result += region[1] - region[0] + 1;
- }
- }
+ result += cursor.findRegionForColumn(column, true)
+ .getHiddenSoFar();
}
+
return result;
} finally
{
/**
* Use this method to find out where a column will appear in the visible
* alignment when hidden columns exist. If the column is not visible, then the
- * left-most visible column will always be returned.
+ * index of the next visible column on the left will be returned (or 0 if
+ * there is no visible column on the left)
*
* @param hiddenColumn
* the column index in the full alignment including hidden columns
* @return the position of the column in the visible alignment
*/
- public int findColumnPosition(int hiddenColumn)
+ public int absoluteToVisibleColumn(int hiddenColumn)
{
try
{
LOCK.readLock().lock();
int result = hiddenColumn;
- if (hiddenColumns != null)
- {
- int index = 0;
- int[] region;
- do
- {
- region = hiddenColumns.get(index++);
- if (hiddenColumn > region[1])
- {
- result -= region[1] + 1 - region[0];
- }
- } while ((hiddenColumn > region[1])
- && (index < hiddenColumns.size()));
- if (hiddenColumn >= region[0] && hiddenColumn <= region[1])
+ if (!hiddenColumns.isEmpty())
+ {
+ HiddenCursorPosition cursorPos = cursor
+ .findRegionForColumn(hiddenColumn, false);
+ int index = cursorPos.getRegionIndex();
+ int hiddenBeforeCol = cursorPos.getHiddenSoFar();
+
+ // just subtract hidden cols count - this works fine if column is
+ // visible
+ result = hiddenColumn - hiddenBeforeCol;
+
+ // now check in case column is hidden - it will be in the returned
+ // hidden region
+ if (index < hiddenColumns.size())
{
- // Here the hidden column is within a region, so
- // we want to return the position of region[0]-1, adjusted for any
- // earlier hidden columns.
- // Calculate the difference between the actual hidden col position
- // and region[0]-1, and then subtract from result to convert result
- // from
- // the adjusted hiddenColumn value to the adjusted region[0]-1 value
-
- // However, if the region begins at 0 we cannot return region[0]-1
- // just return 0
- if (region[0] == 0)
- {
- return 0;
- }
- else
+ int[] region = hiddenColumns.get(index);
+ if (hiddenColumn >= region[0] && hiddenColumn <= region[1])
{
- return result - (hiddenColumn - region[0] + 1);
+ // actually col is hidden, return region[0]-1
+ // unless region[0]==0 in which case return 0
+ if (region[0] == 0)
+ {
+ result = 0;
+ }
+ else
+ {
+ result = region[0] - 1 - hiddenBeforeCol;
+ }
}
}
}
+
return result; // return the shifted position after removing hidden
// columns.
} finally
/**
* Find the visible column which is a given visible number of columns to the
- * left of another visible column. i.e. for a startColumn x, the column which
- * is distance 1 away will be column x-1.
+ * left (negative visibleDistance) or right (positive visibleDistance) of
+ * startColumn. If startColumn is not visible, we use the visible column at
+ * the left boundary of the hidden region containing startColumn.
*
* @param visibleDistance
- * the number of visible columns to offset by
+ * the number of visible columns to offset by (left offset = negative
+ * value; right offset = positive value)
* @param startColumn
- * the column to start from
- * @return the position of the column in the visible alignment
+ * the position of the column to start from (absolute position)
+ * @return the position of the column which is <visibleDistance> away
+ * (absolute position)
*/
- public int subtractVisibleColumns(int visibleDistance, int startColumn)
+ public int offsetByVisibleColumns(int visibleDistance, int startColumn)
{
try
{
-
LOCK.readLock().lock();
- int distance = visibleDistance;
-
- // in case startColumn is in a hidden region, move it to the left
- int start = adjustForHiddenColumns(findColumnPosition(startColumn));
-
- // get index of hidden region to left of start
- int index = getHiddenIndexLeft(start);
- if (index == -1)
- {
- // no hidden regions to left of startColumn
- return start - distance;
- }
-
- // walk backwards through the alignment subtracting the counts of visible
- // columns from distance
- int[] region;
- int gap = 0;
- int nextstart = start;
-
- while ((index > -1) && (distance - gap > 0))
- {
- // subtract the gap to right of region from distance
- distance -= gap;
- start = nextstart;
-
- // calculate the next gap
- region = hiddenColumns.get(index);
- gap = start - region[1];
-
- // set start to just to left of current region
- nextstart = region[0] - 1;
- index--;
- }
+ int start = absoluteToVisibleColumn(startColumn);
+ return visibleToAbsoluteColumn(start + visibleDistance);
- if (distance - gap > 0)
- {
- // fell out of loop because there are no more hidden regions
- distance -= gap;
- return nextstart - distance;
- }
- return start - distance;
} finally
{
LOCK.readLock().unlock();
}
-
}
/**
- * Use this method to determine the set of hiddenRegion start positions
+ * This method returns the rightmost limit of a region of an alignment with
+ * hidden columns. In otherwords, the next hidden column.
*
- * @return list of column number in visible view where hidden regions start
+ * @param alPos
+ * the absolute (visible) alignmentPosition to find the next hidden
+ * column for
+ * @return the index of the next hidden column, or alPos if there is no next
+ * hidden column
*/
- public List<Integer> findHiddenRegionPositions()
+ public int getNextHiddenBoundary(boolean left, int alPos)
{
try
{
LOCK.readLock().lock();
- List<Integer> positions = null;
-
- if (hiddenColumns != null)
+ if (!hiddenColumns.isEmpty())
{
- positions = new ArrayList<>(hiddenColumns.size());
+ int index = cursor.findRegionForColumn(alPos, false)
+ .getRegionIndex();
- positions.add(hiddenColumns.get(0)[0]);
- for (int i = 1; i < hiddenColumns.size(); ++i)
+ if (left && index > 0)
{
-
- int result = 0;
- if (hiddenColumns != null)
+ int[] region = hiddenColumns.get(index - 1);
+ return region[1];
+ }
+ else if (!left && index < hiddenColumns.size())
+ {
+ int[] region = hiddenColumns.get(index);
+ if (alPos < region[0])
{
- int index = 0;
- int gaps = 0;
- do
- {
- int[] region = hiddenColumns.get(index);
- gaps += region[1] + 1 - region[0];
- result = region[1] + 1;
- index++;
- } while (index <= i);
-
- result -= gaps;
+ return region[0];
+ }
+ else if ((alPos <= region[1])
+ && (index + 1 < hiddenColumns.size()))
+ {
+ // alPos is within a hidden region, return the next one
+ // if there is one
+ region = hiddenColumns.get(index + 1);
+ return region[0];
}
- positions.add(result);
}
}
- else
- {
- positions = new ArrayList<>();
- }
-
- return positions;
+ return alPos;
} finally
{
LOCK.readLock().unlock();
}
/**
- * This method returns the rightmost limit of a region of an alignment with
- * hidden columns. In otherwords, the next hidden column.
+ * Answers if a column in the alignment is visible
*
- * @param index
- * int
+ * @param column
+ * absolute position of column in the alignment
+ * @return true if column is visible
*/
- public int getHiddenBoundaryRight(int alPos)
+ public boolean isVisible(int column)
{
try
{
LOCK.readLock().lock();
- if (hiddenColumns != null)
+
+ if (!hiddenColumns.isEmpty())
{
- int index = 0;
- do
+ int regionindex = cursor.findRegionForColumn(column, false)
+ .getRegionIndex();
+ if (regionindex > -1 && regionindex < hiddenColumns.size())
{
- int[] region = hiddenColumns.get(index);
- if (alPos < region[0])
+ int[] region = hiddenColumns.get(regionindex);
+ // already know that column <= region[1] as cursor returns containing
+ // region or region to right
+ if (column >= region[0])
{
- return region[0];
+ return false;
}
-
- index++;
- } while (index < hiddenColumns.size());
+ }
}
+ return true;
- return alPos;
} finally
{
LOCK.readLock().unlock();
}
-
}
/**
- * This method returns the leftmost limit of a region of an alignment with
- * hidden columns. In otherwords, the previous hidden column.
*
- * @param index
- * int
+ * @return true if there are columns hidden
*/
- public int getHiddenBoundaryLeft(int alPos)
+ public boolean hasHiddenColumns()
{
try
{
LOCK.readLock().lock();
- if (hiddenColumns != null)
- {
- int index = hiddenColumns.size() - 1;
- do
- {
- int[] region = hiddenColumns.get(index);
- if (alPos > region[1])
- {
- return region[1];
- }
-
- index--;
- } while (index > -1);
- }
-
- return alPos;
+ // we don't use getSize()>0 here because it has to iterate over
+ // the full hiddenColumns collection and so will be much slower
+ return (!hiddenColumns.isEmpty());
} finally
{
LOCK.readLock().unlock();
}
/**
- * This method returns the index of the hidden region to the left of a column
- * position. If the column is in a hidden region it returns the index of the
- * region to the left. If there is no hidden region to the left it returns -1.
*
- * @param pos
- * int
+ * @return true if there is more than one hidden column region
*/
- private int getHiddenIndexLeft(int pos)
+ public boolean hasMultiHiddenColumnRegions()
{
try
{
-
LOCK.readLock().lock();
- if (hiddenColumns != null)
- {
- int index = hiddenColumns.size() - 1;
- do
- {
- int[] region = hiddenColumns.get(index);
- if (pos > region[1])
- {
- return index;
- }
-
- index--;
- } while (index > -1);
- }
-
- return -1;
+ return !hiddenColumns.isEmpty() && hiddenColumns.size() > 1;
} finally
{
LOCK.readLock().unlock();
}
-
}
+
/**
- * Adds the specified column range to the hidden columns
- *
- * @param start
- * @param end
+ * Returns a hashCode built from hidden column ranges
*/
- public void hideColumns(int start, int end)
+ @Override
+ public int hashCode()
{
- boolean wasAlreadyLocked = false;
try
{
- // check if the write lock was already locked by this thread,
- // as this method can be called internally in loops within HiddenColumns
- if (!LOCK.isWriteLockedByCurrentThread())
- {
- LOCK.writeLock().lock();
- }
- else
- {
- wasAlreadyLocked = true;
- }
-
- if (hiddenColumns == null)
- {
- hiddenColumns = new ArrayList<>();
- }
+ LOCK.readLock().lock();
+ int hashCode = 1;
- /*
- * traverse existing hidden ranges and insert / amend / append as
- * appropriate
- */
- for (int i = 0; i < hiddenColumns.size(); i++)
+ for (int[] hidden : hiddenColumns)
{
- int[] region = hiddenColumns.get(i);
-
- if (end < region[0] - 1)
- {
- /*
- * insert discontiguous preceding range
- */
- hiddenColumns.add(i, new int[] { start, end });
- return;
- }
-
- if (end <= region[1])
- {
- /*
- * new range overlaps existing, or is contiguous preceding it - adjust
- * start column
- */
- region[0] = Math.min(region[0], start);
- return;
- }
-
- if (start <= region[1] + 1)
- {
- /*
- * new range overlaps existing, or is contiguous following it - adjust
- * start and end columns
- */
- region[0] = Math.min(region[0], start);
- region[1] = Math.max(region[1], end);
-
- /*
- * also update or remove any subsequent ranges
- * that are overlapped
- */
- while (i < hiddenColumns.size() - 1)
- {
- int[] nextRegion = hiddenColumns.get(i + 1);
- if (nextRegion[0] > end + 1)
- {
- /*
- * gap to next hidden range - no more to update
- */
- break;
- }
- region[1] = Math.max(nextRegion[1], end);
- hiddenColumns.remove(i + 1);
- }
- return;
- }
+ hashCode = HASH_MULTIPLIER * hashCode + hidden[0];
+ hashCode = HASH_MULTIPLIER * hashCode + hidden[1];
}
-
- /*
- * remaining case is that the new range follows everything else
- */
- hiddenColumns.add(new int[] { start, end });
+ return hashCode;
} finally
{
- if (!wasAlreadyLocked)
- {
- LOCK.writeLock().unlock();
- }
+ LOCK.readLock().unlock();
}
}
- public boolean isVisible(int column)
+ /**
+ * Hide columns corresponding to the marked bits
+ *
+ * @param inserts
+ * - columns mapped to bits starting from zero
+ */
+ public void hideColumns(BitSet inserts)
+ {
+ hideColumns(inserts, 0, inserts.length() - 1);
+ }
+
+ /**
+ * Hide columns corresponding to the marked bits, within the range
+ * [start,end]. Entries in tohide which are outside [start,end] are ignored.
+ *
+ * @param tohide
+ * columns mapped to bits starting from zero
+ * @param start
+ * start of range to hide columns within
+ * @param end
+ * end of range to hide columns within
+ */
+ private void hideColumns(BitSet tohide, int start, int end)
{
try
{
- LOCK.readLock().lock();
-
- if (hiddenColumns != null)
+ LOCK.writeLock().lock();
+ for (int firstSet = tohide
+ .nextSetBit(start), lastSet = start; firstSet >= start
+ && lastSet <= end; firstSet = tohide
+ .nextSetBit(lastSet))
{
- for (int[] region : hiddenColumns)
+ lastSet = tohide.nextClearBit(firstSet);
+ if (lastSet <= end)
{
- if (column >= region[0] && column <= region[1])
- {
- return false;
- }
+ hideColumns(firstSet, lastSet - 1);
+ }
+ else if (firstSet <= end)
+ {
+ hideColumns(firstSet, end);
}
}
-
- return true;
+ cursor = new HiddenColumnsCursor(hiddenColumns);
} finally
{
- LOCK.readLock().unlock();
- }
- }
-
- private ArrayList<int[]> copyHiddenRegionsToArrayList()
- {
- int size = 0;
- if (hiddenColumns != null)
- {
- size = hiddenColumns.size();
- }
- ArrayList<int[]> copy = new ArrayList<>(size);
-
- for (int i = 0, j = size; i < j; i++)
- {
- int[] rh;
- int[] cp;
- rh = hiddenColumns.get(i);
- if (rh != null)
- {
- cp = new int[rh.length];
- System.arraycopy(rh, 0, cp, 0, rh.length);
- copy.add(cp);
- }
+ LOCK.writeLock().unlock();
}
-
- return copy;
}
/**
- * Returns a copy of the vector of hidden regions, as an ArrayList. Before
- * using this method please consider if you really need access to the hidden
- * regions - a new (or existing!) method on HiddenColumns might be more
- * appropriate.
+ * Hide columns corresponding to the marked bits, within the range
+ * [start,end]. Entries in tohide which are outside [start,end] are ignored.
+ * NB Existing entries in [start,end] are cleared.
*
- * @return hidden regions as an ArrayList of [start,end] pairs
+ * @param tohide
+ * columns mapped to bits starting from zero
+ * @param start
+ * start of range to hide columns within
+ * @param end
+ * end of range to hide columns within
*/
- public ArrayList<int[]> getHiddenColumnsCopy()
+ public void clearAndHideColumns(BitSet tohide, int start, int end)
{
- try
- {
- LOCK.readLock().lock();
- return copyHiddenRegionsToArrayList();
- } finally
- {
- LOCK.readLock().unlock();
- }
+ clearHiddenColumnsInRange(start, end);
+ hideColumns(tohide, start, end);
}
/**
- * propagate shift in alignment columns to column selection
+ * Make all columns in the range [start,end] visible
*
* @param start
- * beginning of edit
- * @param left
- * shift in edit (+ve for removal, or -ve for inserts)
+ * start of range to show columns
+ * @param end
+ * end of range to show columns
*/
- public List<int[]> compensateForEdit(int start, int change,
- ColumnSelection sel)
+ private void clearHiddenColumnsInRange(int start, int end)
{
try
{
LOCK.writeLock().lock();
- List<int[]> deletedHiddenColumns = null;
-
- if (hiddenColumns != null)
+
+ if (!hiddenColumns.isEmpty())
{
- deletedHiddenColumns = new ArrayList<>();
- int hSize = hiddenColumns.size();
- for (int i = 0; i < hSize; i++)
+ HiddenCursorPosition pos = cursor.findRegionForColumn(start, false);
+ int index = pos.getRegionIndex();
+
+ if (index != -1 && index != hiddenColumns.size())
{
- int[] region = hiddenColumns.get(i);
- if (region[0] > start && start + change > region[1])
+ // regionIndex is the region which either contains start
+ // or lies to the right of start
+ int[] region = hiddenColumns.get(index);
+ if (region[0] < start && region[1] >= start)
{
- deletedHiddenColumns.add(region);
-
- hiddenColumns.remove(i);
- i--;
- hSize--;
- continue;
+ // region contains start, truncate so that it ends just before start
+ numColumns -= region[1] - start + 1;
+ region[1] = start - 1;
+ index++;
}
- if (region[0] > start)
+ int endi = index;
+ while (endi < hiddenColumns.size())
{
- region[0] -= change;
- region[1] -= change;
- }
+ region = hiddenColumns.get(endi);
- if (region[0] < 0)
- {
- region[0] = 0;
+ if (region[1] > end)
+ {
+ if (region[0] <= end)
+ {
+ // region contains end, truncate so it starts just after end
+ numColumns -= end - region[0] + 1;
+ region[0] = end + 1;
+ }
+ break;
+ }
+
+ numColumns -= region[1] - region[0] + 1;
+ endi++;
}
+ hiddenColumns.subList(index, endi).clear();
}
- this.revealHiddenColumns(0, sel);
+ cursor = new HiddenColumnsCursor(hiddenColumns);
}
-
- return deletedHiddenColumns;
} finally
{
LOCK.writeLock().unlock();
}
/**
- * propagate shift in alignment columns to column selection special version of
- * compensateForEdit - allowing for edits within hidden regions
*
- * @param start
- * beginning of edit
- * @param left
- * shift in edit (+ve for removal, or -ve for inserts)
+ * @param updates
+ * BitSet where hidden columns will be marked
*/
- public void compensateForDelEdits(int start, int change)
+ protected void andNot(BitSet updates)
{
try
{
LOCK.writeLock().lock();
- if (hiddenColumns != null)
- {
- for (int i = 0; i < hiddenColumns.size(); i++)
- {
- int[] region = hiddenColumns.get(i);
- if (region[0] >= start)
- {
- region[0] -= change;
- }
- if (region[1] >= start)
- {
- region[1] -= change;
- }
- if (region[1] < region[0])
- {
- hiddenColumns.remove(i--);
- }
- if (region[0] < 0)
- {
- region[0] = 0;
- }
- if (region[1] < 0)
- {
- region[1] = 0;
- }
- }
+ BitSet hiddenBitSet = new BitSet();
+ for (int[] range : hiddenColumns)
+ {
+ hiddenBitSet.set(range[0], range[1] + 1);
}
+ hiddenBitSet.andNot(updates);
+ hiddenColumns.clear();
+ hideColumns(hiddenBitSet);
} finally
{
LOCK.writeLock().unlock();
}
/**
- * return all visible segments between the given start and end boundaries
+ * Calculate the visible start and end index of an alignment.
*
- * @param start
- * (first column inclusive from 0)
- * @param end
- * (last column - not inclusive)
- * @return int[] {i_start, i_end, ..} where intervals lie in
- * start<=i_start<=i_end<end
+ * @param width
+ * full alignment width
+ * @return integer array where: int[0] = startIndex, and int[1] = endIndex
*/
- public int[] getVisibleContigs(int start, int end)
+ public int[] getVisibleStartAndEndIndex(int width)
{
try
{
LOCK.readLock().lock();
- if (hiddenColumns != null && hiddenColumns.size() > 0)
- {
- List<int[]> visiblecontigs = new ArrayList<>();
- List<int[]> regions = getHiddenRegions();
- int vstart = start;
- int[] region;
- int hideStart;
- int hideEnd;
+ int firstVisible = 0;
+ int lastVisible = width - 1;
- for (int j = 0; vstart < end && j < regions.size(); j++)
- {
- region = regions.get(j);
- hideStart = region[0];
- hideEnd = region[1];
-
- if (hideEnd < vstart)
- {
- continue;
- }
- if (hideStart > vstart)
- {
- visiblecontigs.add(new int[] { vstart, hideStart - 1 });
- }
- vstart = hideEnd + 1;
- }
+ if (!hiddenColumns.isEmpty())
+ {
+ // first visible col with index 0, convert to absolute index
+ firstVisible = visibleToAbsoluteColumn(0);
- if (vstart < end)
+ // last visible column is either immediately to left of
+ // last hidden region, or is just the last column in the alignment
+ int[] lastregion = hiddenColumns.get(hiddenColumns.size() - 1);
+ if (lastregion[1] == width - 1)
{
- visiblecontigs.add(new int[] { vstart, end - 1 });
+ // last region is at very end of alignment
+ // last visible column immediately precedes it
+ lastVisible = lastregion[0] - 1;
}
- int[] vcontigs = new int[visiblecontigs.size() * 2];
- for (int i = 0, j = visiblecontigs.size(); i < j; i++)
- {
- int[] vc = visiblecontigs.get(i);
- visiblecontigs.set(i, null);
- vcontigs[i * 2] = vc[0];
- vcontigs[i * 2 + 1] = vc[1];
- }
- visiblecontigs.clear();
- return vcontigs;
- }
- else
- {
- return new int[] { start, end - 1 };
}
+ return new int[] { firstVisible, lastVisible };
+
} finally
{
LOCK.readLock().unlock();
}
}
- public String[] getVisibleSequenceStrings(int start, int end,
- SequenceI[] seqs)
+ /**
+ * Finds the hidden region (if any) which starts or ends at res
+ *
+ * @param res
+ * visible residue position, unadjusted for hidden columns
+ * @return region as [start,end] or null if no matching region is found. If
+ * res is adjacent to two regions, returns the left region.
+ */
+ public int[] getRegionWithEdgeAtRes(int res)
{
try
{
LOCK.readLock().lock();
- int iSize = seqs.length;
- String[] selections = new String[iSize];
- if (hiddenColumns != null && hiddenColumns.size() > 0)
- {
- for (int i = 0; i < iSize; i++)
- {
- StringBuffer visibleSeq = new StringBuffer();
- List<int[]> regions = getHiddenRegions();
-
- int blockStart = start;
- int blockEnd = end;
- int[] region;
- int hideStart;
- int hideEnd;
+ int adjres = visibleToAbsoluteColumn(res);
- for (int j = 0; j < regions.size(); j++)
- {
- region = regions.get(j);
- hideStart = region[0];
- hideEnd = region[1];
-
- if (hideStart < start)
- {
- continue;
- }
-
- blockStart = Math.min(blockStart, hideEnd + 1);
- blockEnd = Math.min(blockEnd, hideStart);
-
- if (blockStart > blockEnd)
- {
- break;
- }
-
- visibleSeq.append(seqs[i].getSequence(blockStart, blockEnd));
-
- blockStart = hideEnd + 1;
- blockEnd = end;
- }
-
- if (end > blockStart)
- {
- visibleSeq.append(seqs[i].getSequence(blockStart, end));
- }
+ int[] reveal = null;
- selections[i] = visibleSeq.toString();
- }
- }
- else
+ if (!hiddenColumns.isEmpty())
{
- for (int i = 0; i < iSize; i++)
+ // look for a region ending just before adjres
+ int regionindex = cursor.findRegionForColumn(adjres - 1, false)
+ .getRegionIndex();
+ if (regionindex < hiddenColumns.size()
+ && hiddenColumns.get(regionindex)[1] == adjres - 1)
+ {
+ reveal = hiddenColumns.get(regionindex);
+ }
+ // check if the region ends just after adjres
+ else if (regionindex < hiddenColumns.size()
+ && hiddenColumns.get(regionindex)[0] == adjres + 1)
{
- selections[i] = seqs[i].getSequenceAsString(start, end);
+ reveal = hiddenColumns.get(regionindex);
}
}
+ return reveal;
- return selections;
} finally
{
LOCK.readLock().unlock();
}
/**
- * Locate the first and last position visible for this sequence. if seq isn't
- * visible then return the position of the left and right of the hidden
- * boundary region, and the corresponding alignment column indices for the
- * extent of the sequence
- *
- * @param seq
- * @return int[] { visible start, visible end, first seqpos, last seqpos,
- * alignment index for seq start, alignment index for seq end }
+ * Return an iterator over the hidden regions
*/
- public int[] locateVisibleBoundsOfSequence(SequenceI seq)
+ public Iterator<int[]> iterator()
{
try
{
LOCK.readLock().lock();
- int fpos = seq.getStart();
- int lpos = seq.getEnd();
- int start = 0;
-
- if (hiddenColumns == null || hiddenColumns.size() == 0)
- {
- int ifpos = seq.findIndex(fpos) - 1;
- int ilpos = seq.findIndex(lpos) - 1;
- return new int[] { ifpos, ilpos, fpos, lpos, ifpos, ilpos };
- }
-
- // Simply walk along the sequence whilst watching for hidden column
- // boundaries
- List<int[]> regions = getHiddenRegions();
- int spos = fpos;
- int lastvispos = -1;
- int rcount = 0;
- int hideStart = seq.getLength();
- int hideEnd = -1;
- int visPrev = 0;
- int visNext = 0;
- int firstP = -1;
- int lastP = -1;
- boolean foundStart = false;
- for (int p = 0, pLen = seq.getLength(); spos <= seq.getEnd()
- && p < pLen; p++)
- {
- if (!Comparison.isGap(seq.getCharAt(p)))
- {
- // keep track of first/last column
- // containing sequence data regardless of visibility
- if (firstP == -1)
- {
- firstP = p;
- }
- lastP = p;
- // update hidden region start/end
- while (hideEnd < p && rcount < regions.size())
- {
- int[] region = regions.get(rcount++);
- visPrev = visNext;
- visNext += region[0] - visPrev;
- hideStart = region[0];
- hideEnd = region[1];
- }
- if (hideEnd < p)
- {
- hideStart = seq.getLength();
- }
- // update visible boundary for sequence
- if (p < hideStart)
- {
- if (!foundStart)
- {
- fpos = spos;
- start = p;
- foundStart = true;
- }
- lastvispos = p;
- lpos = spos;
- }
- // look for next sequence position
- spos++;
- }
- }
- if (foundStart)
- {
- return new int[] { findColumnPosition(start),
- findColumnPosition(lastvispos), fpos, lpos, firstP, lastP };
- }
- // otherwise, sequence was completely hidden
- return new int[] { visPrev, visNext, 0, 0, firstP, lastP };
+ return new RangeIterator(hiddenColumns);
} finally
{
LOCK.readLock().unlock();
}
/**
- * delete any columns in alignmentAnnotation that are hidden (including
- * sequence associated annotation).
+ * Return a bounded iterator over the hidden regions
*
- * @param alignmentAnnotation
+ * @param start
+ * position to start from (inclusive, absolute column position)
+ * @param end
+ * position to end at (inclusive, absolute column position)
+ * @return
*/
- public void makeVisibleAnnotation(AlignmentAnnotation alignmentAnnotation)
+ public Iterator<int[]> getBoundedIterator(int start, int end)
{
- makeVisibleAnnotation(-1, -1, alignmentAnnotation);
+ try
+ {
+ LOCK.readLock().lock();
+ return new RangeIterator(start, end, hiddenColumns);
+ } finally
+ {
+ LOCK.readLock().unlock();
+ }
}
/**
- * delete any columns in alignmentAnnotation that are hidden (including
- * sequence associated annotation).
+ * Return a bounded iterator over the *visible* start positions of hidden
+ * regions
*
* @param start
- * remove any annotation to the right of this column
+ * position to start from (inclusive, visible column position)
* @param end
- * remove any annotation to the left of this column
- * @param alignmentAnnotation
- * the annotation to operate on
+ * position to end at (inclusive, visible column position)
*/
- public void makeVisibleAnnotation(int start, int end,
- AlignmentAnnotation alignmentAnnotation)
+ public Iterator<Integer> getStartRegionIterator(int start, int end)
{
try
{
LOCK.readLock().lock();
- if (alignmentAnnotation.annotations == null)
- {
- return;
- }
- if (start == end && end == -1)
- {
- start = 0;
- end = alignmentAnnotation.annotations.length;
- }
- if (hiddenColumns != null && hiddenColumns.size() > 0)
- {
- // then mangle the alignmentAnnotation annotation array
- Vector<Annotation[]> annels = new Vector<>();
- Annotation[] els = null;
- List<int[]> regions = getHiddenRegions();
- int blockStart = start;
- int blockEnd = end;
- int[] region;
- int hideStart;
- int hideEnd;
- int w = 0;
-
- for (int j = 0; j < regions.size(); j++)
- {
- region = regions.get(j);
- hideStart = region[0];
- hideEnd = region[1];
-
- if (hideStart < start)
- {
- continue;
- }
-
- blockStart = Math.min(blockStart, hideEnd + 1);
- blockEnd = Math.min(blockEnd, hideStart);
-
- if (blockStart > blockEnd)
- {
- break;
- }
-
- annels.addElement(els = new Annotation[blockEnd - blockStart]);
- System.arraycopy(alignmentAnnotation.annotations, blockStart, els,
- 0, els.length);
- w += els.length;
- blockStart = hideEnd + 1;
- blockEnd = end;
- }
- if (end > blockStart)
- {
- annels.addElement(els = new Annotation[end - blockStart + 1]);
- if ((els.length
- + blockStart) <= alignmentAnnotation.annotations.length)
- {
- // copy just the visible segment of the annotation row
- System.arraycopy(alignmentAnnotation.annotations, blockStart,
- els, 0, els.length);
- }
- else
- {
- // copy to the end of the annotation row
- System.arraycopy(alignmentAnnotation.annotations, blockStart,
- els, 0,
- (alignmentAnnotation.annotations.length - blockStart));
- }
- w += els.length;
- }
- if (w == 0)
- {
- return;
- }
+ // get absolute position of column in alignment
+ int absoluteStart = visibleToAbsoluteColumn(start);
- alignmentAnnotation.annotations = new Annotation[w];
- w = 0;
+ // Get cursor position and supply it to the iterator:
+ // Since we want visible region start, we look for a cursor for the
+ // (absoluteStart-1), then if absoluteStart is the start of a visible
+ // region we'll get the cursor pointing to the region before, which is
+ // what we want
+ HiddenCursorPosition pos = cursor
+ .findRegionForColumn(absoluteStart - 1, false);
- for (Annotation[] chnk : annels)
- {
- System.arraycopy(chnk, 0, alignmentAnnotation.annotations, w,
- chnk.length);
- w += chnk.length;
- }
- }
- else
- {
- alignmentAnnotation.restrict(start, end);
- }
+ return new StartRegionIterator(pos, start, end,
+ hiddenColumns);
} finally
{
LOCK.readLock().unlock();
}
/**
+ * Return an iterator over visible *columns* (not regions) between the given
+ * start and end boundaries
*
- * @return true if there are columns hidden
+ * @param start
+ * first column (inclusive)
+ * @param end
+ * last column (inclusive)
*/
- public boolean hasHiddenColumns()
+ public Iterator<Integer> getVisibleColsIterator(int start, int end)
{
try
{
LOCK.readLock().lock();
- return hiddenColumns != null && hiddenColumns.size() > 0;
+ return new RangeElementsIterator(
+ new VisibleContigsIterator(start, end + 1, hiddenColumns));
} finally
{
LOCK.readLock().unlock();
}
/**
+ * return an iterator over visible segments between the given start and end
+ * boundaries
*
- * @return true if there are more than one set of columns hidden
+ * @param start
+ * first column, inclusive from 0
+ * @param end
+ * last column - not inclusive
+ * @param useVisibleCoords
+ * if true, start and end are visible column positions, not absolute
+ * positions*
*/
- public boolean hasManyHiddenColumns()
+ public VisibleContigsIterator getVisContigsIterator(int start,
+ int end,
+ boolean useVisibleCoords)
{
+ int adjstart = start;
+ int adjend = end;
+ if (useVisibleCoords)
+ {
+ adjstart = visibleToAbsoluteColumn(start);
+ adjend = visibleToAbsoluteColumn(end);
+ }
+
try
{
LOCK.readLock().lock();
- return hiddenColumns != null && hiddenColumns.size() > 1;
+ return new VisibleContigsIterator(adjstart, adjend, hiddenColumns);
} finally
{
LOCK.readLock().unlock();
}
}
-
- /**
- * mark the columns corresponding to gap characters as hidden in the column
- * selection
- *
- * @param sr
- */
- public void hideInsertionsFor(SequenceI sr)
- {
- try
- {
- LOCK.writeLock().lock();
- List<int[]> inserts = sr.getInsertions();
- for (int[] r : inserts)
- {
- hideColumns(r[0], r[1]);
- }
- } finally
- {
- LOCK.writeLock().unlock();
- }
- }
-
- /**
- * Unhides, and adds to the selection list, all hidden columns
- */
- public void revealAllHiddenColumns(ColumnSelection sel)
- {
- try
- {
- LOCK.writeLock().lock();
- if (hiddenColumns != null)
- {
- for (int i = 0; i < hiddenColumns.size(); i++)
- {
- int[] region = hiddenColumns.get(i);
- for (int j = region[0]; j < region[1] + 1; j++)
- {
- sel.addElement(j);
- }
- }
- }
-
- hiddenColumns = null;
- } finally
- {
- LOCK.writeLock().unlock();
- }
- }
-
- /**
- * Reveals, and marks as selected, the hidden column range with the given
- * start column
- *
- * @param start
- */
- public void revealHiddenColumns(int start, ColumnSelection sel)
- {
- try
- {
- LOCK.writeLock().lock();
- for (int i = 0; i < hiddenColumns.size(); i++)
- {
- int[] region = hiddenColumns.get(i);
- if (start == region[0])
- {
- for (int j = region[0]; j < region[1] + 1; j++)
- {
- sel.addElement(j);
- }
-
- hiddenColumns.remove(region);
- break;
- }
- }
- if (hiddenColumns.size() == 0)
- {
- hiddenColumns = null;
- }
- } finally
- {
- LOCK.writeLock().unlock();
- }
- }
-
- /**
- * removes intersection of position,length ranges in deletions from the
- * start,end regions marked in intervals.
- *
- * @param shifts
- * @param intervals
- * @return
- */
- private boolean pruneIntervalList(final List<int[]> shifts,
- ArrayList<int[]> intervals)
- {
- boolean pruned = false;
- int i = 0;
- int j = intervals.size() - 1;
- int s = 0;
- int t = shifts.size() - 1;
- int[] hr = intervals.get(i);
- int[] sr = shifts.get(s);
- while (i <= j && s <= t)
- {
- boolean trailinghn = hr[1] >= sr[0];
- if (!trailinghn)
- {
- if (i < j)
- {
- hr = intervals.get(++i);
- }
- else
- {
- i++;
- }
- continue;
- }
- int endshift = sr[0] + sr[1]; // deletion ranges - -ve means an insert
- if (endshift < hr[0] || endshift < sr[0])
- { // leadinghc disjoint or not a deletion
- if (s < t)
- {
- sr = shifts.get(++s);
- }
- else
- {
- s++;
- }
- continue;
- }
- boolean leadinghn = hr[0] >= sr[0];
- boolean leadinghc = hr[0] < endshift;
- boolean trailinghc = hr[1] < endshift;
- if (leadinghn)
- {
- if (trailinghc)
- { // deleted hidden region.
- intervals.remove(i);
- pruned = true;
- j--;
- if (i <= j)
- {
- hr = intervals.get(i);
- }
- continue;
- }
- if (leadinghc)
- {
- hr[0] = endshift; // clip c terminal region
- leadinghn = !leadinghn;
- pruned = true;
- }
- }
- if (!leadinghn)
- {
- if (trailinghc)
- {
- if (trailinghn)
- {
- hr[1] = sr[0] - 1;
- pruned = true;
- }
- }
- else
- {
- // sr contained in hr
- if (s < t)
- {
- sr = shifts.get(++s);
- }
- else
- {
- s++;
- }
- continue;
- }
- }
- }
- return pruned; // true if any interval was removed or modified by
- // operations.
- }
-
- /**
- * remove any hiddenColumns or selected columns and shift remaining based on a
- * series of position, range deletions.
- *
- * @param deletions
- */
- public void pruneDeletions(List<int[]> shifts)
- {
- try
- {
- LOCK.writeLock().lock();
- // delete any intervals intersecting.
- if (hiddenColumns != null)
- {
- pruneIntervalList(shifts, hiddenColumns);
- if (hiddenColumns != null && hiddenColumns.size() == 0)
- {
- hiddenColumns = null;
- }
- }
- } finally
- {
- LOCK.writeLock().unlock();
- }
- }
-
- /**
- * Add gaps into the sequences aligned to profileseq under the given
- * AlignmentView
- *
- * @param profileseq
- * @param al
- * - alignment to have gaps inserted into it
- * @param input
- * - alignment view where sequence corresponding to profileseq is
- * first entry
- * @return new HiddenColumns for new alignment view, with insertions into
- * profileseq marked as hidden.
- */
- public static HiddenColumns propagateInsertions(SequenceI profileseq,
- AlignmentI al, AlignmentView input)
- {
- int profsqpos = 0;
-
- char gc = al.getGapCharacter();
- Object[] alandhidden = input.getAlignmentAndHiddenColumns(gc);
- HiddenColumns nview = (HiddenColumns) alandhidden[1];
- SequenceI origseq = ((SequenceI[]) alandhidden[0])[profsqpos];
- nview.propagateInsertions(profileseq, al, origseq);
- return nview;
- }
-
- /**
- *
- * @param profileseq
- * - sequence in al which corresponds to origseq
- * @param al
- * - alignment which is to have gaps inserted into it
- * @param origseq
- * - sequence corresponding to profileseq which defines gap map for
- * modifying al
- */
- private void propagateInsertions(SequenceI profileseq, AlignmentI al,
- SequenceI origseq)
- {
- char gc = al.getGapCharacter();
- // recover mapping between sequence's non-gap positions and positions
- // mapping to view.
- pruneDeletions(ShiftList.parseMap(origseq.gapMap()));
- int[] viscontigs = getVisibleContigs(0, profileseq.getLength());
- int spos = 0;
- int offset = 0;
-
- // add profile to visible contigs
- for (int v = 0; v < viscontigs.length; v += 2)
- {
- if (viscontigs[v] > spos)
- {
- StringBuffer sb = new StringBuffer();
- for (int s = 0, ns = viscontigs[v] - spos; s < ns; s++)
- {
- sb.append(gc);
- }
- for (int s = 0, ns = al.getHeight(); s < ns; s++)
- {
- SequenceI sqobj = al.getSequenceAt(s);
- if (sqobj != profileseq)
- {
- String sq = al.getSequenceAt(s).getSequenceAsString();
- if (sq.length() <= spos + offset)
- {
- // pad sequence
- int diff = spos + offset - sq.length() - 1;
- if (diff > 0)
- {
- // pad gaps
- sq = sq + sb;
- while ((diff = spos + offset - sq.length() - 1) > 0)
- {
- // sq = sq
- // + ((diff >= sb.length()) ? sb.toString() : sb
- // .substring(0, diff));
- if (diff >= sb.length())
- {
- sq += sb.toString();
- }
- else
- {
- char[] buf = new char[diff];
- sb.getChars(0, diff, buf, 0);
- sq += buf.toString();
- }
- }
- }
- sq += sb.toString();
- }
- else
- {
- al.getSequenceAt(s).setSequence(sq.substring(0, spos + offset)
- + sb.toString() + sq.substring(spos + offset));
- }
- }
- }
- // offset+=sb.length();
- }
- spos = viscontigs[v + 1] + 1;
- }
- if ((offset + spos) < profileseq.getLength())
- {
- // pad the final region with gaps.
- StringBuffer sb = new StringBuffer();
- for (int s = 0, ns = profileseq.getLength() - spos
- - offset; s < ns; s++)
- {
- sb.append(gc);
- }
- for (int s = 0, ns = al.getHeight(); s < ns; s++)
- {
- SequenceI sqobj = al.getSequenceAt(s);
- if (sqobj == profileseq)
- {
- continue;
- }
- String sq = sqobj.getSequenceAsString();
- // pad sequence
- int diff = origseq.getLength() - sq.length();
- while (diff > 0)
- {
- // sq = sq
- // + ((diff >= sb.length()) ? sb.toString() : sb
- // .substring(0, diff));
- if (diff >= sb.length())
- {
- sq += sb.toString();
- }
- else
- {
- char[] buf = new char[diff];
- sb.getChars(0, diff, buf, 0);
- sq += buf.toString();
- }
- diff = origseq.getLength() - sq.length();
- }
- }
- }
- }
-
- /**
- * remove any hiddenColumns or selected columns and shift remaining based on a
- * series of position, range deletions.
- *
- * @param deletions
- */
- private void pruneDeletions(ShiftList deletions)
- {
- if (deletions != null)
- {
- final List<int[]> shifts = deletions.getShifts();
- if (shifts != null && shifts.size() > 0)
- {
- pruneDeletions(shifts);
-
- // and shift the rest.
- this.compensateForEdits(deletions);
- }
- }
- }
-
- /**
- * Adjust hidden column boundaries based on a series of column additions or
- * deletions in visible regions.
- *
- * @param shiftrecord
- * @return
- */
- private ShiftList compensateForEdits(ShiftList shiftrecord)
- {
- if (shiftrecord != null)
- {
- final List<int[]> shifts = shiftrecord.getShifts();
- if (shifts != null && shifts.size() > 0)
- {
- int shifted = 0;
- for (int i = 0, j = shifts.size(); i < j; i++)
- {
- int[] sh = shifts.get(i);
- compensateForDelEdits(shifted + sh[0], sh[1]);
- shifted -= sh[1];
- }
- }
- return shiftrecord.getInverse();
- }
- return null;
- }
-
- /**
- * Returns a hashCode built from hidden column ranges
- */
- @Override
- public int hashCode()
- {
- try
- {
- LOCK.readLock().lock();
- int hashCode = 1;
- if (hiddenColumns != null)
- {
- for (int[] hidden : hiddenColumns)
- {
- hashCode = 31 * hashCode + hidden[0];
- hashCode = 31 * hashCode + hidden[1];
- }
- }
- return hashCode;
- } finally
- {
- LOCK.readLock().unlock();
- }
- }
-
- /**
- * Hide columns corresponding to the marked bits
- *
- * @param inserts
- * - columns map to bits starting from zero
- */
- public void hideMarkedBits(BitSet inserts)
- {
- try
- {
- LOCK.writeLock().lock();
- for (int firstSet = inserts
- .nextSetBit(0), lastSet = 0; firstSet >= 0; firstSet = inserts
- .nextSetBit(lastSet))
- {
- lastSet = inserts.nextClearBit(firstSet);
- hideColumns(firstSet, lastSet - 1);
- }
- } finally
- {
- LOCK.writeLock().unlock();
- }
- }
-
- /**
- *
- * @param inserts
- * BitSet where hidden columns will be marked
- */
- public void markHiddenRegions(BitSet inserts)
- {
- try
- {
- LOCK.readLock().lock();
- if (hiddenColumns == null)
- {
- return;
- }
- for (int[] range : hiddenColumns)
- {
- inserts.set(range[0], range[1] + 1);
- }
- } finally
- {
- LOCK.readLock().unlock();
- }
- }
-
- /**
- * Calculate the visible start and end index of an alignment.
- *
- * @param width
- * full alignment width
- * @return integer array where: int[0] = startIndex, and int[1] = endIndex
- */
- public int[] getVisibleStartAndEndIndex(int width)
- {
- try
- {
- LOCK.readLock().lock();
- int[] alignmentStartEnd = new int[] { 0, width - 1 };
- int startPos = alignmentStartEnd[0];
- int endPos = alignmentStartEnd[1];
-
- int[] lowestRange = new int[] { -1, -1 };
- int[] higestRange = new int[] { -1, -1 };
-
- if (hiddenColumns == null)
- {
- return new int[] { startPos, endPos };
- }
-
- for (int[] hiddenCol : hiddenColumns)
- {
- lowestRange = (hiddenCol[0] <= startPos) ? hiddenCol : lowestRange;
- higestRange = (hiddenCol[1] >= endPos) ? hiddenCol : higestRange;
- }
-
- if (lowestRange[0] == -1 && lowestRange[1] == -1)
- {
- startPos = alignmentStartEnd[0];
- }
- else
- {
- startPos = lowestRange[1] + 1;
- }
-
- if (higestRange[0] == -1 && higestRange[1] == -1)
- {
- endPos = alignmentStartEnd[1];
- }
- else
- {
- endPos = higestRange[0] - 1;
- }
- return new int[] { startPos, endPos };
- } finally
- {
- LOCK.readLock().unlock();
- }
-
- }
-
- /**
- * Finds the hidden region (if any) which starts or ends at res
- *
- * @param res
- * visible residue position, unadjusted for hidden columns
- * @return region as [start,end] or null if no matching region is found
- */
- public int[] getRegionWithEdgeAtRes(int res)
- {
- try
- {
- LOCK.readLock().lock();
- int adjres = adjustForHiddenColumns(res);
-
- int[] reveal = null;
- if (hiddenColumns != null)
- {
- for (int[] region : hiddenColumns)
- {
- if (adjres + 1 == region[0] || adjres - 1 == region[1])
- {
- reveal = region;
- break;
- }
- }
- }
- return reveal;
- } finally
- {
- LOCK.readLock().unlock();
- }
- }
-
}
--- /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 java.util.ArrayList;
+import java.util.List;
+
+public class HiddenColumnsCursor
+{
+ // absolute position of first hidden column
+ private int firstColumn;
+
+ private List<int[]> hiddenColumns = new ArrayList<>();
+
+ private HiddenCursorPosition cursorPos = new HiddenCursorPosition(0, 0);
+
+ protected HiddenColumnsCursor()
+ {
+
+ }
+
+ protected HiddenColumnsCursor(List<int[]> hiddenCols)
+ {
+ resetCursor(hiddenCols, 0, 0);
+ }
+
+ protected HiddenColumnsCursor(List<int[]> hiddenCols, int index,
+ int hiddencount)
+ {
+ resetCursor(hiddenCols, index, hiddencount);
+ }
+
+ /**
+ * Reset the cursor with a new hidden columns collection, where we know in
+ * advance the index and hidden columns count of a particular location.
+ *
+ * @param hiddenCols
+ * new hidden columns collection
+ * @param index
+ * cursor index to reset to
+ * @param hiddencount
+ * hidden columns count to reset to
+ */
+ private void resetCursor(List<int[]> hiddenCols, int index,
+ int hiddencount)
+ {
+ hiddenColumns = hiddenCols;
+ if (!hiddenCols.isEmpty())
+ {
+ firstColumn = hiddenColumns.get(0)[0];
+ cursorPos = new HiddenCursorPosition(index,
+ hiddencount);
+ }
+ }
+
+ /**
+ * Get the cursor pointing to the hidden region that column is within (if
+ * column is hidden) or which is to the right of column (if column is
+ * visible). If no hidden columns are to the right, returns a cursor pointing
+ * to an imaginary hidden region beyond the end of the hidden columns
+ * collection (this ensures the count of previous hidden columns is correct).
+ * If hidden columns is empty returns null.
+ *
+ * @param column
+ * index of column in visible or absolute coordinates
+ * @param useVisible
+ * true if column is in visible coordinates, false if absolute
+ * @return cursor pointing to hidden region containing the column (if hidden)
+ * or to the right of the column (if visible)
+ */
+ protected HiddenCursorPosition findRegionForColumn(int column,
+ boolean useVisible)
+ {
+ if (hiddenColumns.isEmpty())
+ {
+ return null;
+ }
+
+ // used to add in hiddenColumns offset when working with visible columns
+ int offset = (useVisible ? 1 : 0);
+
+ HiddenCursorPosition pos = cursorPos;
+ int index = pos.getRegionIndex();
+ int hiddenCount = pos.getHiddenSoFar();
+
+ if (column < firstColumn)
+ {
+ pos = new HiddenCursorPosition(0, 0);
+ }
+
+ // column is after current region
+ else if ((index < hiddenColumns.size())
+ && (hiddenColumns.get(index)[0] <= column
+ + offset * hiddenCount))
+ {
+ // iterate from where we are now, if we're lucky we'll be close by
+ // (but still better than iterating from 0)
+ // stop when we find the region *before* column
+ // i.e. the next region starts after column or if not, ends after column
+ pos = searchForward(pos, column, useVisible);
+ }
+
+ // column is before current region
+ else
+ {
+ pos = searchBackward(pos, column, useVisible);
+ }
+ cursorPos = pos;
+ return pos;
+ }
+
+ /**
+ * Search forwards through the hidden columns collection to find the hidden
+ * region immediately before a column
+ *
+ * @param pos
+ * current position
+ * @param column
+ * column to locate
+ * @param useVisible
+ * whether using visible or absolute coordinates
+ * @return position of region before column
+ */
+ private HiddenCursorPosition searchForward(HiddenCursorPosition pos,
+ int column, boolean useVisible)
+ {
+ HiddenCursorPosition p = pos;
+ if (useVisible)
+ {
+ while ((p.getRegionIndex() < hiddenColumns.size())
+ && hiddenColumns.get(p.getRegionIndex())[0] <= column
+ + p.getHiddenSoFar())
+ {
+ p = stepForward(p);
+ }
+ }
+ else
+ {
+ while ((p.getRegionIndex() < hiddenColumns.size())
+ && hiddenColumns.get(p.getRegionIndex())[1] < column)
+ {
+ p = stepForward(p);
+ }
+ }
+ return p;
+ }
+
+ /**
+ * Move to the next (rightwards) hidden region after a given cursor position
+ *
+ * @param p
+ * current position of cursor
+ * @return new position of cursor at next region
+ */
+ private HiddenCursorPosition stepForward(HiddenCursorPosition p)
+ {
+ int[] region = hiddenColumns.get(p.getRegionIndex());
+
+ // increment the index, and add this region's hidden columns to the hidden
+ // column count
+ return new HiddenCursorPosition(p.getRegionIndex() + 1,
+ p.getHiddenSoFar() + region[1] - region[0] + 1);
+ }
+
+ /**
+ * Search backwards through the hidden columns collection to find the hidden
+ * region immediately before (left of) a given column
+ *
+ * @param pos
+ * current position
+ * @param column
+ * column to locate
+ * @param useVisible
+ * whether using visible or absolute coordinates
+ * @return position of region immediately to left of column
+ */
+ private HiddenCursorPosition searchBackward(HiddenCursorPosition p,
+ int column, boolean useVisible)
+ {
+ int i = p.getRegionIndex();
+ int h = p.getHiddenSoFar();
+
+ // used to add in hiddenColumns offset when working with visible columns
+ int offset = (useVisible ? 1 : 0);
+
+ while ((i > 0) && (hiddenColumns.get(i - 1)[1] >= column + offset * h))
+ {
+ i--;
+ int[] region = hiddenColumns.get(i);
+ h -= region[1] - region[0] + 1;
+ }
+ return new HiddenCursorPosition(i, h);
+ }
+
+}
--- /dev/null
+package jalview.datamodel;
+
+public final class HiddenCursorPosition
+{
+ // index of last visited region
+ private final int regionIndex;
+
+ // number of hidden columns before last visited region
+ private final int hiddenSoFar;
+
+ public HiddenCursorPosition(int index, int hiddencount)
+ {
+ regionIndex = index;
+ hiddenSoFar = hiddencount;
+ }
+
+ public int getRegionIndex()
+ {
+ return regionIndex;
+ }
+
+ public int getHiddenSoFar()
+ {
+ return hiddenSoFar;
+ }
+}
--- /dev/null
+package jalview.datamodel;
+
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+
+/**
+ * Iterator over each element in a set of ranges i.e. if ranges is {[3,6],
+ * [12,15]} it will iterate over {3,4,5,6,12,13,14,15}. Uses a local copy of the
+ * set of ranges.
+ *
+ * @author kmourao
+ *
+ */
+public class RangeElementsIterator implements Iterator<Integer>
+{
+ private int last;
+
+ private int current;
+
+ private int next;
+
+ private Iterator<int[]> rangeIterator;
+
+ private int[] nextRange = null;
+
+ RangeElementsIterator(Iterator<int[]> it)
+ {
+ rangeIterator = it;
+ if (rangeIterator.hasNext())
+ {
+ nextRange = rangeIterator.next();
+ next = nextRange[0];
+ last = nextRange[1];
+ }
+ }
+
+ @Override
+ public boolean hasNext()
+ {
+ return rangeIterator.hasNext() || next <= last;
+ }
+
+ @Override
+ public Integer next()
+ {
+ if (!hasNext())
+ {
+ throw new NoSuchElementException();
+ }
+
+ current = next;
+
+ // recalculate next
+ next++;
+
+ // if there are more ranges need to check if next is in a range
+ checkNextRange();
+ return current;
+ }
+
+ /**
+ * Check how next position relates to next range, and update next position if
+ * necessary
+ */
+ private void checkNextRange()
+ {
+ if (nextRange != null && next > nextRange[1])
+ {
+ if (rangeIterator.hasNext())
+ {
+ nextRange = rangeIterator.next();
+ next = nextRange[0];
+ last = nextRange[1];
+ }
+ else
+ {
+ nextRange = null;
+ }
+
+ }
+ }
+
+ @Override
+ public void remove()
+ {
+ throw new UnsupportedOperationException();
+ }
+}
--- /dev/null
+package jalview.datamodel;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * An iterator which iterates over a list of ranges. Works with a copy of the
+ * collection of ranges.
+ */
+public class RangeIterator implements Iterator<int[]>
+{
+ // current index in rangeList
+ private int currentPosition = 0;
+
+ // current range in rangeList
+ private int[] currentRange;
+
+ // local copy or reference to rangeList
+ private List<int[]> localRanges;
+
+ /**
+ * Unbounded constructor
+ *
+ * @param rangeList
+ * list of ranges to iterate over
+ */
+ RangeIterator(List<int[]> rangeList)
+ {
+ if (!rangeList.isEmpty())
+ {
+ int last = rangeList.get(rangeList.size() - 1)[1];
+ init(0, last, rangeList);
+ }
+ else
+ {
+ init(0, 0, rangeList);
+ }
+ }
+
+ /**
+ * Construct an iterator over rangeList bounded at [lowerBound,upperBound]
+ *
+ * @param lowerBound
+ * lower bound to iterate from
+ * @param upperBound
+ * upper bound to iterate to
+ * @param rangeList
+ * list of ranges to iterate over
+ */
+ RangeIterator(int lowerBound, int upperBound,
+ List<int[]> rangeList)
+ {
+ init(lowerBound, upperBound, rangeList);
+ }
+
+ /**
+ * Construct an iterator over rangeList bounded at [lowerBound,upperBound]
+ *
+ * @param lowerBound
+ * lower bound to iterate from
+ * @param upperBound
+ * upper bound to iterate to
+ */
+ private void init(int lowerBound, int upperBound,
+ List<int[]> rangeList)
+ {
+ int start = lowerBound;
+ int end = upperBound;
+
+ if (rangeList != null)
+ {
+ localRanges = new ArrayList<>();
+
+ // iterate until a range overlaps with [start,end]
+ int i = 0;
+ while ((i < rangeList.size()) && (rangeList.get(i)[1] < start))
+ {
+ i++;
+ }
+
+ // iterate from start to end, adding each range. Positions are
+ // absolute, and all ranges which *overlap* [start,end] are added.
+ while (i < rangeList.size() && (rangeList.get(i)[0] <= end))
+ {
+ int[] rh = rangeList.get(i);
+ int[] cp = new int[2];
+ System.arraycopy(rh, 0, cp, 0, rh.length);
+ localRanges.add(cp);
+ i++;
+ }
+ }
+ }
+
+ @Override
+ public boolean hasNext()
+ {
+ return (localRanges != null) && (currentPosition < localRanges.size());
+ }
+
+ @Override
+ public int[] next()
+ {
+ currentRange = localRanges.get(currentPosition);
+ currentPosition++;
+ return currentRange;
+ }
+
+ @Override
+ public void remove()
+ {
+ localRanges.remove(--currentPosition);
+ }
+}
import java.util.BitSet;
import java.util.Collections;
import java.util.Enumeration;
+import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import java.util.Vector;
return map;
}
+ /**
+ * Build a bitset corresponding to sequence gaps
+ *
+ * @return a BitSet where set values correspond to gaps in the sequence
+ */
+ @Override
+ public BitSet gapBitset()
+ {
+ BitSet gaps = new BitSet(sequence.length);
+ int j = 0;
+ while (j < sequence.length)
+ {
+ if (jalview.util.Comparison.isGap(sequence[j]))
+ {
+ gaps.set(j);
+ }
+ j++;
+ }
+ return gaps;
+ }
+
@Override
public int[] findPositionMap()
{
return count;
}
+
+ @Override
+ public String getSequenceStringFromIterator(Iterator<int[]> it)
+ {
+ StringBuilder newSequence = new StringBuilder();
+ while (it.hasNext())
+ {
+ int[] block = it.next();
+ if (it.hasNext())
+ {
+ newSequence.append(getSequence(block[0], block[1] + 1));
+ }
+ else
+ {
+ newSequence.append(getSequence(block[0], block[1]));
+ }
+ }
+
+ return newSequence.toString();
+ }
+
+ @Override
+ public int firstResidueOutsideIterator(Iterator<int[]> regions)
+ {
+ int start = 0;
+
+ if (!regions.hasNext())
+ {
+ return findIndex(getStart()) - 1;
+ }
+
+ // Simply walk along the sequence whilst watching for region
+ // boundaries
+ int hideStart = getLength();
+ int hideEnd = -1;
+ boolean foundStart = false;
+
+ // step through the non-gapped positions of the sequence
+ for (int i = getStart(); i <= getEnd() && (!foundStart); i++)
+ {
+ // get alignment position of this residue in the sequence
+ int p = findIndex(i) - 1;
+
+ // update region start/end
+ while (hideEnd < p && regions.hasNext())
+ {
+ int[] region = regions.next();
+ hideStart = region[0];
+ hideEnd = region[1];
+ }
+ if (hideEnd < p)
+ {
+ hideStart = getLength();
+ }
+ // update boundary for sequence
+ if (p < hideStart)
+ {
+ start = p;
+ foundStart = true;
+ }
+ }
+
+ if (foundStart)
+ {
+ return start;
+ }
+ // otherwise, sequence was completely hidden
+ return 0;
+ }
}
{
if (consensus.annotations[i] != null)
{
- if (consensus.annotations[i].description.charAt(0) == '[')
+ String desc = consensus.annotations[i].description;
+ if (desc.length() > 1 && desc.charAt(0) == '[')
{
- seqs.append(consensus.annotations[i].description.charAt(1));
+ seqs.append(desc.charAt(1));
}
else
{
import jalview.util.MapList;
import java.util.BitSet;
+import java.util.Iterator;
import java.util.List;
import java.util.Vector;
public int[] gapMap();
/**
+ * Build a bitset corresponding to sequence gaps
+ *
+ * @return a BitSet where set values correspond to gaps in the sequence
+ */
+ public BitSet gapBitset();
+
+ /**
* Returns an int array where indices correspond to each position in sequence
* char array and the element value gives the result of findPosition for that
* index in the sequence.
*/
void setGeneLoci(String speciesId, String assemblyId,
String chromosomeId, MapList map);
+
+
+ /**
+ * Returns the sequence string constructed from the substrings of a sequence
+ * defined by the int[] ranges provided by an iterator. E.g. the iterator
+ * could iterate over all visible regions of the alignment
+ *
+ * @param it
+ * the iterator to use
+ * @return a String corresponding to the sequence
+ */
+ public String getSequenceStringFromIterator(Iterator<int[]> it);
+
+ /**
+ * Locate the first position in this sequence which is not contained in an
+ * iterator region. If no such position exists, return 0
+ *
+ * @param it
+ * iterator over regions
+ * @return first residue not contained in regions
+ */
+ public int firstResidueOutsideIterator(Iterator<int[]> it);
}
--- /dev/null
+package jalview.datamodel;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * An iterator which iterates over visible start positions of hidden column
+ * regions in a range.
+ */
+public class StartRegionIterator implements Iterator<Integer>
+{
+ // start position to iterate from
+ private int start;
+
+ // end position to iterate to
+ private int end;
+
+ // current index in hiddenColumns
+ private int currentPosition = 0;
+
+ // local copy or reference to hiddenColumns
+ private List<Integer> positions = null;
+
+ /**
+ * Construct an iterator over hiddenColums bounded at [lowerBound,upperBound]
+ *
+ * @param lowerBound
+ * lower bound to iterate from
+ * @param upperBound
+ * upper bound to iterate to
+ * @param useCopyCols
+ * whether to make a local copy of hiddenColumns for iteration (set
+ * to true if calling from outwith the HiddenColumns class)
+ */
+ StartRegionIterator(int lowerBound, int upperBound,
+ List<int[]> hiddenColumns)
+ {
+ this(null, lowerBound, upperBound, hiddenColumns);
+ }
+
+ /**
+ * Construct an iterator over hiddenColums bounded at [lowerBound,upperBound]
+ *
+ * @param pos
+ * a hidden cursor position to start from - may be null
+ * @param lowerBound
+ * lower bound to iterate from - will be ignored if pos != null
+ * @param upperBound
+ * upper bound to iterate to
+ * @param hiddenColumns
+ * the hidden columns collection to use
+ */
+ StartRegionIterator(HiddenCursorPosition pos, int lowerBound,
+ int upperBound, List<int[]> hiddenColumns)
+ {
+ start = lowerBound;
+ end = upperBound;
+
+ if (hiddenColumns != null)
+ {
+ positions = new ArrayList<>(hiddenColumns.size());
+
+ // navigate to start, keeping count of hidden columns
+ int i = 0;
+ int hiddenSoFar = 0;
+
+ if (pos != null)
+ {
+ // use the cursor position provided
+ i = pos.getRegionIndex();
+ hiddenSoFar = pos.getHiddenSoFar();
+ }
+ else
+ {
+ // navigate to start
+ while ((i < hiddenColumns.size())
+ && (hiddenColumns.get(i)[0] < start + hiddenSoFar))
+ {
+ int[] region = hiddenColumns.get(i);
+ hiddenSoFar += region[1] - region[0] + 1;
+ i++;
+ }
+ }
+
+ // iterate from start to end, adding start positions of each
+ // hidden region. Positions are visible columns count, not absolute
+ while (i < hiddenColumns.size()
+ && (hiddenColumns.get(i)[0] <= end + hiddenSoFar))
+ {
+ int[] region = hiddenColumns.get(i);
+ positions.add(region[0] - hiddenSoFar);
+ hiddenSoFar += region[1] - region[0] + 1;
+ i++;
+ }
+ }
+ else
+ {
+ positions = new ArrayList<>();
+ }
+
+ }
+
+ @Override
+ public boolean hasNext()
+ {
+ return (currentPosition < positions.size());
+ }
+
+ /**
+ * Get next hidden region start position
+ *
+ * @return the start position in *visible* coordinates
+ */
+ @Override
+ public Integer next()
+ {
+ int result = positions.get(currentPosition);
+ currentPosition++;
+ return result;
+ }
+}
+
HiddenColumns hidden;
- public VisibleColsCollection(int s, int e, AlignmentI al)
+ public VisibleColsCollection(int s, int e, HiddenColumns h)
{
start = s;
end = e;
- hidden = al.getHiddenColumns();
+ hidden = h;
}
@Override
public Iterator<Integer> iterator()
{
- return new VisibleColsIterator(start, end, hidden);
+ return hidden.getVisibleColsIterator(start, end);
}
@Override
+++ /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 java.util.Iterator;
-import java.util.List;
-import java.util.NoSuchElementException;
-
-/**
- * An iterator which iterates over all visible columns in an alignment
- *
- * @author kmourao
- *
- */
-public class VisibleColsIterator implements Iterator<Integer>
-{
- private int last;
-
- private int current;
-
- private int next;
-
- private List<int[]> hidden;
-
- private int lasthiddenregion;
-
- public VisibleColsIterator(int firstcol, int lastcol,
- HiddenColumns hiddenCols)
- {
- last = lastcol;
- current = firstcol;
- next = firstcol;
- hidden = hiddenCols.getHiddenColumnsCopy();
- lasthiddenregion = -1;
-
- if (hidden != null)
- {
- int i = 0;
- for (i = 0; i < hidden.size(); ++i)
- {
- if (current >= hidden.get(i)[0] && current <= hidden.get(i)[1])
- {
- // current is hidden, move to right
- current = hidden.get(i)[1] + 1;
- next = current;
- }
- if (current < hidden.get(i)[0])
- {
- break;
- }
- }
- lasthiddenregion = i - 1;
-
- for (i = hidden.size() - 1; i >= 0; --i)
- {
- if (last >= hidden.get(i)[0] && last <= hidden.get(i)[1])
- {
- // last is hidden, move to left
- last = hidden.get(i)[0] - 1;
- }
- if (last > hidden.get(i)[1])
- {
- break;
- }
- }
- }
- }
-
- @Override
- public boolean hasNext()
- {
- return next <= last;
- }
-
- @Override
- public Integer next()
- {
- if (next > last)
- {
- throw new NoSuchElementException();
- }
- current = next;
- if ((hidden != null) && (lasthiddenregion + 1 < hidden.size()))
- {
- // still some more hidden regions
- if (next + 1 < hidden.get(lasthiddenregion + 1)[0])
- {
- // next+1 is still before the next hidden region
- next++;
- }
- else if ((next + 1 >= hidden.get(lasthiddenregion + 1)[0])
- && (next + 1 <= hidden.get(lasthiddenregion + 1)[1]))
- {
- // next + 1 is in the next hidden region
- next = hidden.get(lasthiddenregion + 1)[1] + 1;
- lasthiddenregion++;
- }
- }
- else
- {
- // finished with hidden regions, just increment normally
- next++;
- }
- return current;
- }
-
- @Override
- public void remove()
- {
- throw new UnsupportedOperationException();
- }
-}
--- /dev/null
+package jalview.datamodel;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * An iterator which iterates over visible regions in a range. Provides a
+ * special "endsAtHidden" indicator to allow callers to determine if the final
+ * visible column is adjacent to a hidden region.
+ */
+public class VisibleContigsIterator implements Iterator<int[]>
+{
+ private List<int[]> vcontigs = new ArrayList<>();
+
+ private int currentPosition = 0;
+
+ private boolean endsAtHidden = false;
+
+ VisibleContigsIterator(int start, int end,
+ List<int[]> hiddenColumns)
+ {
+ if (hiddenColumns != null && hiddenColumns.size() > 0)
+ {
+ int vstart = start;
+ int hideStart;
+ int hideEnd;
+
+ for (int[] region : hiddenColumns)
+ {
+ endsAtHidden = false;
+ hideStart = region[0];
+ hideEnd = region[1];
+
+ // navigate to start
+ if (hideEnd < vstart)
+ {
+ continue;
+ }
+ if (hideStart > vstart)
+ {
+ if (end - 1 > hideStart - 1)
+ {
+ int[] contig = new int[] { vstart, hideStart - 1 };
+ vcontigs.add(contig);
+ endsAtHidden = true;
+ }
+ else
+ {
+ int[] contig = new int[] { vstart, end - 1 };
+ vcontigs.add(contig);
+ }
+ }
+ vstart = hideEnd + 1;
+
+ // exit if we're past the end
+ if (vstart >= end)
+ {
+ break;
+ }
+ }
+
+ if (vstart < end)
+ {
+ int[] contig = new int[] { vstart, end - 1 };
+ vcontigs.add(contig);
+ endsAtHidden = false;
+ }
+ }
+ else
+ {
+ int[] contig = new int[] { start, end - 1 };
+ vcontigs.add(contig);
+ }
+ }
+
+ @Override
+ public boolean hasNext()
+ {
+ return (currentPosition < vcontigs.size());
+ }
+
+ @Override
+ public int[] next()
+ {
+ int[] result = vcontigs.get(currentPosition);
+ currentPosition++;
+ return result;
+ }
+
+ public boolean endsAtHidden()
+ {
+ return endsAtHidden;
+ }
+}
+
*/
package jalview.ext.ensembl;
+import jalview.bin.Cache;
+
/**
* A class to behave much like EnsemblGene but referencing the ensemblgenomes
* domain and data
*/
public EnsemblGenomes()
{
- super(ENSEMBL_GENOMES_REST);
+ super();
+ setDomain(Cache.getDefault(ENSEMBL_GENOMES_BASEURL,
+ DEFAULT_ENSEMBL_GENOMES_BASEURL));
}
@Override
/*
* for convenience, pre-fill ensembl.org as the domain for "ENSEMBL"
*/
- divisions.put(DBRefSource.ENSEMBL.toUpperCase(), ENSEMBL_REST);
+ divisions.put(DBRefSource.ENSEMBL.toUpperCase(), ensemblDomain);
BufferedReader br = null;
try
{
- URL url = getDivisionsUrl(ENSEMBL_GENOMES_REST);
+ URL url = getDivisionsUrl(ensemblGenomesDomain);
if (url != null)
{
br = getHttpResponse(url, null);
}
- parseResponse(br, ENSEMBL_GENOMES_REST);
+ parseResponse(br, ensemblGenomesDomain);
} catch (IOException e)
{
// ignore
private static final String SPECIES = "species";
/**
+ * keep track of last identifier retrieved to break loops
+ */
+ private String lastId;
+
+ /**
* Default constructor (to use rest.ensembl.org)
*/
public EnsemblLookup()
*/
public String getGeneId(String identifier)
{
- return parseGeneId(getResult(identifier, null));
+ return getGeneId(identifier, null);
+ }
+
+ /**
+ * Returns the gene id related to the given identifier (which may be for a
+ * gene, transcript or protein)
+ *
+ * @param identifier
+ * @param objectType
+ * @return
+ */
+ public String getGeneId(String identifier, String objectType)
+ {
+ List<String> ids = Arrays.asList(new String[] { identifier });
+
+ BufferedReader br = null;
+ try
+ {
+ URL url = getUrl(identifier, objectType);
+ if (url != null)
+ {
+ br = getHttpResponse(url, ids);
+ }
+ return br == null ? null : parseResponse(br);
+ } catch (IOException e)
+ {
+ // ignore
+ return null;
+ } finally
+ {
+ if (br != null)
+ {
+ try
+ {
+ br.close();
+ } catch (IOException e)
+ {
+ // ignore
+ }
+ }
+ }
+ }
+
+ /**
+ * 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
+ * @throws IOException
+ */
+ protected String parseResponse(BufferedReader br) throws IOException
+ {
+ String geneId = null;
+ JSONParser jp = new JSONParser();
+ try
+ {
+ JSONObject val = (JSONObject) jp.parse(br);
+ String type = val.get(OBJECT_TYPE).toString();
+ if (OBJECT_TYPE_GENE.equalsIgnoreCase(type))
+ {
+ // got the gene - just returns its id
+ geneId = val.get(JSON_ID).toString();
+ }
+ else if (OBJECT_TYPE_TRANSCRIPT.equalsIgnoreCase(type))
+ {
+ // got the transcript - return its (Gene) Parent
+ geneId = val.get(PARENT).toString();
+ }
+ else if (OBJECT_TYPE_TRANSLATION.equalsIgnoreCase(type))
+ {
+ // got the protein - get its Parent, restricted to type Transcript
+ String transcriptId = val.get(PARENT).toString();
+ geneId = getGeneId(transcriptId, OBJECT_TYPE_TRANSCRIPT);
+ }
+ } catch (ParseException e)
+ {
+ // ignore
+ }
+ return geneId;
}
/**
BufferedReader br = null;
try
{
+
URL url = getUrl(identifier, objectType);
+
+ if (identifier.equals(lastId))
+ {
+ System.err.println("** Ensembl lookup " + url.toString()
+ + " looping on Parent!");
+ return null;
+ }
+
+ lastId = identifier;
+
if (url != null)
{
br = getHttpResponse(url, ids);
static
{
domainData = new HashMap<>();
- domainData.put(ENSEMBL_REST,
- new EnsemblData(ENSEMBL_REST, LATEST_ENSEMBL_REST_VERSION));
- domainData.put(ENSEMBL_GENOMES_REST, new EnsemblData(
- ENSEMBL_GENOMES_REST, LATEST_ENSEMBLGENOMES_REST_VERSION));
+ domainData.put(DEFAULT_ENSEMBL_BASEURL,
+ new EnsemblData(DEFAULT_ENSEMBL_BASEURL, LATEST_ENSEMBL_REST_VERSION));
+ domainData.put(DEFAULT_ENSEMBL_GENOMES_BASEURL, new EnsemblData(
+ DEFAULT_ENSEMBL_GENOMES_BASEURL, LATEST_ENSEMBLGENOMES_REST_VERSION));
}
protected volatile boolean inProgress = false;
*/
public EnsemblRestClient()
{
- this(ENSEMBL_REST);
+ super();
+
+ /*
+ * initialise domain info lazily
+ */
+ if (!domainData.containsKey(ensemblDomain))
+ {
+ domainData.put(ensemblDomain,
+ new EnsemblData(ensemblDomain, LATEST_ENSEMBL_REST_VERSION));
+ }
+ if (!domainData.containsKey(ensemblGenomesDomain))
+ {
+ domainData.put(ensemblGenomesDomain, new EnsemblData(
+ ensemblGenomesDomain, LATEST_ENSEMBLGENOMES_REST_VERSION));
+ }
}
/**
boolean checkEnsembl()
{
BufferedReader br = null;
+ String pingUrl = getDomain() + "/info/ping" + CONTENT_TYPE_JSON;
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_JSON);
+ URL ping = new URL(pingUrl);
/*
* expect {"ping":1} if ok
} catch (Throwable t)
{
System.err.println(
- "Error connecting to " + PING_URL + ": " + t.getMessage());
+ "Error connecting to " + pingUrl + ": " + t.getMessage());
} finally
{
if (br != null)
*/
package jalview.ext.ensembl;
+import jalview.bin.Cache;
import jalview.datamodel.DBRefSource;
import jalview.ws.seqfetcher.DbSourceProxyImpl;
*/
abstract class EnsemblSequenceFetcher extends DbSourceProxyImpl
{
+ // domain properties lookup keys:
+ protected static final String ENSEMBL_BASEURL = "ENSEMBL_BASEURL";
+
+ protected static final String ENSEMBL_GENOMES_BASEURL = "ENSEMBL_GENOMES_BASEURL";
+
+ // domain properties default values:
+ protected static final String DEFAULT_ENSEMBL_BASEURL = "https://rest.ensembl.org";
+
+ protected static final String DEFAULT_ENSEMBL_GENOMES_BASEURL = "https://rest.ensemblgenomes.org";
+
/*
* accepts ENSG/T/E/P with 11 digits
* or ENSMUSP or similar for other species
"(ENS([A-Z]{3}|)[GTEP]{1}[0-9]{11}$)" + "|"
+ "(CCDS[0-9.]{3,}$)");
- protected static final String ENSEMBL_GENOMES_REST = "http://rest.ensemblgenomes.org";
+ protected final String ensemblGenomesDomain;
- protected static final String ENSEMBL_REST = "http://rest.ensembl.org";
+ protected final String ensemblDomain;
protected static final String OBJECT_TYPE_TRANSLATION = "Translation";
constrained, regulatory
}
- private String domain = ENSEMBL_REST;
+ private String domain;
+
+ /**
+ * Constructor
+ */
+ public EnsemblSequenceFetcher()
+ {
+ /*
+ * the default domain names may be overridden in .jalview_properties;
+ * this allows an easy change from http to https in future if needed
+ */
+ ensemblDomain = Cache.getDefault(ENSEMBL_BASEURL,
+ DEFAULT_ENSEMBL_BASEURL);
+ ensemblGenomesDomain = Cache.getDefault(ENSEMBL_GENOMES_BASEURL,
+ DEFAULT_ENSEMBL_GENOMES_BASEURL);
+ domain = ensemblDomain;
+ }
@Override
public String getDbSource()
{
// NB ensure Uniprot xrefs are canonicalised from "Ensembl" to "ENSEMBL"
- if (ENSEMBL_GENOMES_REST.equals(getDomain()))
+ if (ensemblGenomesDomain.equals(getDomain()))
{
return DBRefSource.ENSEMBLGENOMES;
}
continue;
}
- int lastPos = -1;
for (int s = 0; s < sequence[pdbfnum].length; s++)
{
for (int sp, m = 0; m < mapping.length; m++)
if (mapping[m].getSequence() == sequence[pdbfnum][s]
&& (sp = al.findIndex(sequence[pdbfnum][s])) > -1)
{
+ int lastPos = StructureMapping.UNASSIGNED_VALUE;
SequenceI asp = al.getSequenceAt(sp);
for (int r = 0; r < asp.getLength(); r++)
{
}
int pos = mapping[m].getPDBResNum(asp.findPosition(r));
- if (pos < 1 || pos == lastPos)
+ if (pos == lastPos)
{
continue;
}
+ if (pos == StructureMapping.UNASSIGNED_VALUE)
+ {
+ // terminate current colour op
+ if (command.length() > 0
+ && command.charAt(command.length() - 1) != ';')
+ {
+ command.append(";");
+ }
+ // reset lastPos
+ lastPos = StructureMapping.UNASSIGNED_VALUE;
+ continue;
+ }
lastPos = pos;
// TODO: deal with case when buffer is too large for Jmol to parse
// - execute command and flush
- command.append(";");
+ if (command.length() > 0
+ && command.charAt(command.length() - 1) != ';')
+ {
+ command.append(";");
+ }
+
if (command.length() > 51200)
{
// add another chunk
package jalview.fts.service.uniprot;
+import jalview.bin.Cache;
import jalview.fts.api.FTSData;
import jalview.fts.api.FTSDataColumnI;
import jalview.fts.api.FTSRestClientI;
public class UniProtFTSRestClient extends FTSRestClient
{
+ private static final String DEFAULT_UNIPROT_DOMAIN = "https://www.uniprot.org";
+
private static FTSRestClientI instance = null;
- public static final String UNIPROT_SEARCH_ENDPOINT = "http://www.uniprot.org/uniprot/?";
+ public final String uniprotSearchEndpoint;
+
+ public UniProtFTSRestClient()
+ {
+ super();
+ uniprotSearchEndpoint = Cache.getDefault("UNIPROT_DOMAIN",
+ DEFAULT_UNIPROT_DOMAIN) + "/uniprot/?";
+ }
@Override
public FTSRestResponse executeRequest(FTSRestRequest uniportRestRequest)
}
WebResource webResource = null;
- webResource = client.resource(UNIPROT_SEARCH_ENDPOINT)
+ webResource = client.resource(uniprotSearchEndpoint)
.queryParam("format", "tab")
.queryParam("columns", wantedFields)
.queryParam("limit", String.valueOf(responseSize))
String[] foundDataRow = uniProtTabDelimittedResponseString.split("\n");
if (foundDataRow != null && foundDataRow.length > 0)
{
- result = new ArrayList<FTSData>();
+ result = new ArrayList<>();
boolean firstRow = true;
for (String dataRow : foundDataRow)
{
return;
}
- ArrayList<int[]> hiddenColumns = null;
+ HiddenColumns hiddenColumns = null;
if (viewport.hasHiddenColumns())
{
- hiddenColumns = new ArrayList<>();
-
int hiddenOffset = viewport.getSelectionGroup().getStartRes();
int hiddenCutoff = viewport.getSelectionGroup().getEndRes();
- ArrayList<int[]> hiddenRegions = viewport.getAlignment()
- .getHiddenColumns().getHiddenColumnsCopy();
- for (int[] region : hiddenRegions)
- {
- if (region[0] >= hiddenOffset && region[1] <= hiddenCutoff)
- {
- hiddenColumns
- .add(new int[]
- { region[0] - hiddenOffset, region[1] - hiddenOffset });
- }
- }
+ // create new HiddenColumns object with copy of hidden regions
+ // between startRes and endRes, offset by startRes
+ hiddenColumns = new HiddenColumns(
+ viewport.getAlignment().getHiddenColumns(), hiddenOffset,
+ hiddenCutoff, hiddenOffset);
}
Desktop.jalviewClipboard = new Object[] { seqs,
if (Desktop.jalviewClipboard != null
&& Desktop.jalviewClipboard[2] != null)
{
- List<int[]> hc = (List<int[]>) Desktop.jalviewClipboard[2];
- for (int[] region : hc)
- {
- af.viewport.hideColumns(region[0], region[1]);
- }
+ HiddenColumns hc = (HiddenColumns) Desktop.jalviewClipboard[2];
+ af.viewport.setHiddenColumns(hc);
}
// >>>This is a fix for the moment, until a better solution is
if (Desktop.jalviewClipboard != null
&& Desktop.jalviewClipboard[2] != null)
{
- List<int[]> hc = (List<int[]>) Desktop.jalviewClipboard[2];
- for (int region[] : hc)
- {
- af.viewport.hideColumns(region[0], region[1]);
- }
+ HiddenColumns hc = (HiddenColumns) Desktop.jalviewClipboard[2];
+ af.viewport.setHiddenColumns(hc);
}
// >>>This is a fix for the moment, until a better solution is
new JnetAnnotationMaker();
JnetAnnotationMaker.add_annotation(predictions,
viewport.getAlignment(), 0, false);
- SequenceI repseq = viewport.getAlignment().getSequenceAt(0);
- viewport.getAlignment().setSeqrep(repseq);
- HiddenColumns cs = new HiddenColumns();
- cs.hideInsertionsFor(repseq);
- viewport.getAlignment().setHiddenColumns(cs);
+ viewport.getAlignment().setupJPredAlignment();
isAnnotation = true;
}
// else if (IdentifyFile.FeaturesFile.equals(format))
MessageManager.getString("option.trim_retrieved_seqs"));
trimrs.setToolTipText(
MessageManager.getString("label.trim_retrieved_sequences"));
- trimrs.setSelected(Cache.getDefault("TRIM_FETCHED_DATASET_SEQS", true));
+ trimrs.setSelected(
+ Cache.getDefault(DBRefFetcher.TRIM_RETRIEVED_SEQUENCES, true));
trimrs.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
trimrs.setSelected(trimrs.isSelected());
- Cache.setProperty("TRIM_FETCHED_DATASET_SEQS",
+ Cache.setProperty(DBRefFetcher.TRIM_RETRIEVED_SEQUENCES,
Boolean.valueOf(trimrs.isSelected()).toString());
};
});
import java.awt.Rectangle;
import java.util.ArrayList;
import java.util.Hashtable;
+import java.util.Iterator;
import java.util.List;
import java.util.Vector;
}
/**
- * returns the visible column regions of the alignment
+ * Returns an iterator over the visible column regions of the alignment
*
* @param selectedRegionOnly
* true to just return the contigs intersecting with the selected
* area
* @return
*/
- public int[] getViewAsVisibleContigs(boolean selectedRegionOnly)
+ public Iterator<int[]> getViewAsVisibleContigs(boolean selectedRegionOnly)
{
- int[] viscontigs = null;
- int start = 0, end = 0;
+ int start = 0;
+ int end = 0;
if (selectedRegionOnly && selectionGroup != null)
{
start = selectionGroup.getStartRes();
{
end = getAlignment().getWidth();
}
- viscontigs = getAlignment().getHiddenColumns().getVisibleContigs(start,
- end);
- return viscontigs;
+
+ return getAlignment().getHiddenColumns().getVisContigsIterator(start,
+ end, false);
}
/**
.getStructureSelectionManager(Desktop.instance);
}
- /**
- *
- * @param pdbEntries
- * @return an array of SequenceI arrays, one for each PDBEntry, listing which
- * sequences in the alignment hold a reference to it
- */
- public SequenceI[][] collateForPDB(PDBEntry[] pdbEntries)
- {
- List<SequenceI[]> seqvectors = new ArrayList<>();
- for (PDBEntry pdb : pdbEntries)
- {
- List<SequenceI> choosenSeqs = new ArrayList<>();
- for (SequenceI sq : getAlignment().getSequences())
- {
- Vector<PDBEntry> pdbRefEntries = sq.getDatasetSequence()
- .getAllPDBEntries();
- if (pdbRefEntries == null)
- {
- continue;
- }
- for (PDBEntry pdbRefEntry : pdbRefEntries)
- {
- if (pdbRefEntry.getId().equals(pdb.getId()))
- {
- if (pdbRefEntry.getChainCode() != null
- && pdb.getChainCode() != null)
- {
- if (pdbRefEntry.getChainCode().equalsIgnoreCase(
- pdb.getChainCode()) && !choosenSeqs.contains(sq))
- {
- choosenSeqs.add(sq);
- continue;
- }
- }
- else
- {
- if (!choosenSeqs.contains(sq))
- {
- choosenSeqs.add(sq);
- continue;
- }
- }
-
- }
- }
- }
- seqvectors
- .add(choosenSeqs.toArray(new SequenceI[choosenSeqs.size()]));
- }
- return seqvectors.toArray(new SequenceI[seqvectors.size()][]);
- }
-
@Override
public boolean isNormaliseSequenceLogo()
{
if (av.hasHiddenColumns())
{
HiddenColumns hidden = av.getAlignment().getHiddenColumns();
- start = hidden.findColumnPosition(start);
- end = hidden.findColumnPosition(end);
+ start = hidden.absoluteToVisibleColumn(start);
+ end = hidden.absoluteToVisibleColumn(end);
if (start == end)
{
if (!hidden.isVisible(r[0]))
{
// reset the width to exclude hidden columns
width = av.getAlignment().getHiddenColumns()
- .findColumnPosition(width);
+ .absoluteToVisibleColumn(width);
}
hextent = getSeqPanel().seqCanvas.getWidth() / av.getCharWidth();
@Override
public void paintComponent(Graphics g)
{
- invalidate();
+ invalidate(); // needed so that the id width adjuster works correctly
Dimension d = getIdPanel().getIdCanvas().getPreferredSize();
idPanelHolder.setPreferredSize(d);
hscrollFillerPanel.setPreferredSize(new Dimension(d.width, 12));
- validate();
+
+ validate(); // needed so that the id width adjuster works correctly
/*
- * set scroll bar positions
+ * set scroll bar positions - tried to remove but necessary for split panel to resize correctly
+ * though I still think this call should be elsewhere.
*/
ViewportRanges ranges = av.getRanges();
setScrollValues(ranges.getStartRes(), ranges.getStartSeq());
if (av.hasHiddenColumns())
{
maxwidth = av.getAlignment().getHiddenColumns()
- .findColumnPosition(maxwidth) - 1;
+ .absoluteToVisibleColumn(maxwidth) - 1;
}
int resWidth = getSeqPanel().seqCanvas
}
Integer idwidth = null;
if (onscreen || (idwidth = Cache
- .getIntegerProperty("FIGURE_FIXEDIDWIDTH")) == null)
+ .getIntegerProperty("FIGURE_USERIDWIDTH")) == null)
{
int w = getIdPanel().getWidth();
return (w > 0 ? w : calculateIdWidth().width + 4);
if (av.hasHiddenColumns())
{
maxwidth = av.getAlignment().getHiddenColumns()
- .findColumnPosition(maxwidth);
+ .absoluteToVisibleColumn(maxwidth);
}
int height = ((av.getAlignment().getHeight() + 1) * av.getCharHeight())
if (av.hasHiddenColumns())
{
maxwidth = av.getAlignment().getHiddenColumns()
- .findColumnPosition(maxwidth) - 1;
+ .absoluteToVisibleColumn(maxwidth) - 1;
}
int height = ((maxwidth / chunkWidth) + 1) * cHeight;
*/
protected void scrollToCentre(SearchResultsI sr, int verticalOffset)
{
- /*
- * To avoid jumpy vertical scrolling (if some sequences are gapped or not
- * mapped), we can make the scroll-to location a sequence above the one
- * actually mapped.
- */
- SequenceI mappedTo = sr.getResults().get(0).getSequence();
- List<SequenceI> seqs = av.getAlignment().getSequences();
-
- /*
- * This is like AlignmentI.findIndex(seq) but here we are matching the
- * dataset sequence not the aligned sequence
- */
- boolean matched = false;
- for (SequenceI seq : seqs)
- {
- if (mappedTo == seq.getDatasetSequence())
- {
- matched = true;
- break;
- }
- }
- if (!matched)
- {
- return; // failsafe, shouldn't happen
- }
-
- /*
- * Scroll to position but centring the target residue.
- */
scrollToPosition(sr, verticalOffset, true, true);
}
import jalview.datamodel.Alignment;
import jalview.datamodel.AlignmentAnnotation;
import jalview.datamodel.Annotation;
+import jalview.datamodel.HiddenColumns;
import jalview.datamodel.Sequence;
import jalview.datamodel.SequenceGroup;
import jalview.datamodel.SequenceI;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
-import java.awt.Image;
-import java.awt.MediaTracker;
import java.awt.RenderingHints;
import java.awt.Toolkit;
import java.awt.datatransfer.StringSelection;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.geom.AffineTransform;
-import java.awt.image.BufferedImage;
-import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
+import java.util.Iterator;
import java.util.regex.Pattern;
import javax.swing.JCheckBoxMenuItem;
public class AnnotationLabels extends JPanel
implements MouseListener, MouseMotionListener, ActionListener
{
- // width in pixels within which height adjuster arrows are shown and active
+ /**
+ * width in pixels within which height adjuster arrows are shown and active
+ */
private static final int HEIGHT_ADJUSTER_WIDTH = 50;
+ /**
+ * height in pixels for allowing height adjuster to be active
+ */
+ private static int HEIGHT_ADJUSTER_HEIGHT = 10;
+
private static final Pattern LEFT_ANGLE_BRACKET_PATTERN = Pattern
.compile("<");
private static final String COPYCONS_SEQ = MessageManager
.getString("label.copy_consensus_sequence");
- private static Image adjusterImage;
-
- private static int adjusterImageHeight;
-
private final boolean debugRedraw = false;
private AlignmentPanel ap;
av = ap.av;
ToolTipManager.sharedInstance().registerComponent(this);
- if (adjusterImage == null)
- {
- loadAdjusterImage();
- }
-
addMouseListener(this);
addMouseMotionListener(this);
addMouseWheelListener(ap.getAnnotationPanel());
}
/**
- * Loads the gif for the panel height adjustment
- */
- protected void loadAdjusterImage()
- {
- java.net.URL url = getClass().getResource("/images/idwidth.gif");
- Image temp = null;
-
- if (url != null)
- {
- temp = Toolkit.getDefaultToolkit().createImage(url);
- }
-
- try
- {
- MediaTracker mt = new MediaTracker(this);
- mt.addImage(temp, 0);
- mt.waitForID(0);
- } catch (Exception ex)
- {
- }
-
- BufferedImage bi = new BufferedImage(temp.getHeight(this),
- temp.getWidth(this), BufferedImage.TYPE_INT_RGB);
- Graphics2D g = (Graphics2D) bi.getGraphics();
- g.rotate(Math.toRadians(90));
- g.drawImage(temp, 0, -bi.getWidth(this), this);
- adjusterImage = bi;
- adjusterImageHeight = bi.getHeight();
- }
-
- /**
* DOCUMENT ME!
*
* @param y
protected void showOrHideAdjuster(MouseEvent evt)
{
boolean was = resizePanel;
- resizePanel = evt.getY() < adjusterImageHeight && evt.getX() < HEIGHT_ADJUSTER_WIDTH;
+ resizePanel = evt.getY() < HEIGHT_ADJUSTER_HEIGHT && evt.getX() < HEIGHT_ADJUSTER_WIDTH;
if (resizePanel != was)
{
Alignment ds = new Alignment(dseqs);
if (av.hasHiddenColumns())
{
- omitHidden = av.getAlignment().getHiddenColumns()
- .getVisibleSequenceStrings(0, sq.getLength(), seqs);
+ Iterator<int[]> it = av.getAlignment().getHiddenColumns()
+ .getVisContigsIterator(0, sq.getLength(), false);
+ omitHidden = new String[] { sq.getSequenceStringFromIterator(it) };
}
int[] alignmentStartEnd = new int[] { 0, ds.getWidth() - 1 };
Toolkit.getDefaultToolkit().getSystemClipboard()
.setContents(new StringSelection(output), Desktop.instance);
- ArrayList<int[]> hiddenColumns = null;
+ HiddenColumns hiddenColumns = null;
if (av.hasHiddenColumns())
{
-
- hiddenColumns = av.getAlignment().getHiddenColumns()
- .getHiddenColumnsCopy();
+ hiddenColumns = new HiddenColumns(
+ av.getAlignment().getHiddenColumns());
}
Desktop.jalviewClipboard = new Object[] { seqs, ds, // what is the dataset
}
}
- if (resizePanel)
- {
- // g.drawImage(adjusterImage, 2, 0 - getScrollOffset(), this);
- }
- else if (dragEvent != null && aa != null)
+ if (!resizePanel && dragEvent != null && aa != null)
{
g.setColor(Color.lightGray);
g.drawString(aa[selectedRow].label, dragEvent.getX(),
if (e.isShiftDown())
{
e.consume();
- if (e.getWheelRotation() > 0)
+ double wheelRotation = e.getPreciseWheelRotation();
+ if (wheelRotation > 0)
{
av.getRanges().scrollRight(true);
}
- else
+ else if (wheelRotation < 0)
{
av.getRanges().scrollRight(false);
}
if (av.hasHiddenColumns())
{
column = av.getAlignment().getHiddenColumns()
- .adjustForHiddenColumns(column);
+ .visibleToAbsoluteColumn(column);
}
AlignmentAnnotation ann = aa[row];
{
this.setToolTipText(JvSwingUtils.wrapTooltip(true, description));
}
+ else
+ {
+ this.setToolTipText(null); // no tooltip if null or empty description
+ }
}
else
{
@Override
public void paintComponent(Graphics g)
{
+ super.paintComponent(g);
+
g.setColor(Color.white);
g.fillRect(0, 0, getWidth(), getHeight());
gg.fillRect(0, 0, imgWidth, image.getHeight());
imageFresh = true;
}
-
+
drawComponent(gg, av.getRanges().getStartRes(),
av.getRanges().getEndRes() + 1);
imageFresh = false;
int er = av.getRanges().getEndRes() + 1;
int transX = 0;
- long stime = System.currentTimeMillis();
gg.copyArea(0, 0, imgWidth, getHeight(),
-horizontal * av.getCharWidth(), 0);
- long mtime = System.currentTimeMillis();
if (horizontal > 0) // scrollbar pulled right, image to the left
{
drawComponent(gg, sr, er);
gg.translate(-transX, 0);
- long dtime = System.currentTimeMillis();
+
fastPaint = true;
- repaint();
- long rtime = System.currentTimeMillis();
- if (debugRedraw)
- {
- System.err.println("Scroll:\t" + horizontal + "\tCopyArea:\t"
- + (mtime - stime) + "\tDraw component:\t" + (dtime - mtime)
- + "\tRepaint call:\t" + (rtime - dtime));
- }
+ // Call repaint on alignment panel so that repaints from other alignment
+ // panel components can be aggregated. Otherwise performance of the overview
+ // window and others may be adversely affected.
+ av.getAlignPanel().repaint();
}
private volatile boolean lastImageGood = false;
frame.setResizable(resizable);
frame.setMaximizable(resizable);
frame.setIconifiable(resizable);
+ frame.setOpaque(false);
if (frame.getX() < 1 && frame.getY() < 1)
{
public void invertSelection()
{
- for (int i = 0; i < table.getRowCount(); i++)
+ Object[][] data = ((FeatureTableModel) table.getModel()).getData();
+ for (int i = 0; i < data.length; i++)
{
- Boolean value = (Boolean) table.getValueAt(i, SHOW_COLUMN);
-
- table.setValueAt(new Boolean(!value.booleanValue()), i, SHOW_COLUMN);
+ data[i][2] = !(Boolean) data[i][2];
}
+ af.alignPanel.paintAlignment(true, true);
}
public void orderByAvWidth()
this.av = av;
PaintRefresher.Register(this, av.getSequenceSetId());
av.getRanges().addPropertyChangeListener(this);
- }
+ }
/**
* DOCUMENT ME!
gg.translate(0, -transY);
fastPaint = true;
- repaint();
+
+ // Call repaint on alignment panel so that repaints from other alignment
+ // panel components can be aggregated. Otherwise performance of the overview
+ // window and others may be adversely affected.
+ av.getAlignPanel().repaint();
}
/**
@Override
public void paintComponent(Graphics g)
{
+ super.paintComponent(g);
+
g.setColor(Color.white);
g.fillRect(0, 0, getWidth(), getHeight());
-
+
if (fastPaint)
{
fastPaint = false;
g.drawImage(image, 0, 0, this);
-
+
return;
}
-
+
int oldHeight = imgHeight;
-
+
imgHeight = getHeight();
imgHeight -= (imgHeight % av.getCharHeight());
-
+
if (imgHeight < 1)
{
return;
}
-
+
if (oldHeight != imgHeight || image.getWidth(this) != getWidth())
{
- image = new BufferedImage(getWidth(), imgHeight,
- BufferedImage.TYPE_INT_RGB);
+ image = new BufferedImage(getWidth(), imgHeight,
+ BufferedImage.TYPE_INT_RGB);
}
-
+
gg = (Graphics2D) image.getGraphics();
-
+
// Fill in the background
gg.setColor(Color.white);
gg.fillRect(0, 0, getWidth(), imgHeight);
-
+
drawIds(av.getRanges().getStartSeq(), av.getRanges().getEndSeq());
-
+
g.drawImage(image, 0, 0, this);
}
if (av.hasHiddenColumns())
{
maxwidth = av.getAlignment().getHiddenColumns()
- .findColumnPosition(maxwidth) - 1;
+ .absoluteToVisibleColumn(maxwidth) - 1;
}
int annotationHeight = 0;
public void mouseWheelMoved(MouseWheelEvent e)
{
e.consume();
- if (e.getWheelRotation() > 0)
+ double wheelRotation = e.getPreciseWheelRotation();
+ if (wheelRotation > 0)
{
if (e.isShiftDown())
{
av.getRanges().scrollUp(false);
}
}
- else
+ else if (wheelRotation < 0)
{
if (e.isShiftDown())
{
import java.awt.Color;
import java.awt.Cursor;
import java.awt.Graphics;
-import java.awt.Image;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
int oldX = 0;
- Image image;
-
AlignmentPanel ap;
/**
public IdwidthAdjuster(AlignmentPanel ap)
{
this.ap = ap;
-
- java.net.URL url = getClass().getResource("/images/idwidth.gif");
-
- if (url != null)
- {
- image = java.awt.Toolkit.getDefaultToolkit().createImage(url);
- }
-
+ setBackground(Color.white);
addMouseListener(this);
addMouseMotionListener(this);
}
if (active)
{
- if (image != null)
- {
- // g.drawImage(image, getWidth() - 20, 2, this);
setCursor(Cursor.getPredefinedCursor(Cursor.W_RESIZE_CURSOR));
- }
- else
- {
- setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
- }
}
}
}
}
else
{
- ArrayList<int[]> hiddenRegions = hidden.getHiddenColumnsCopy();
- for (int[] region : hiddenRegions)
+ Iterator<int[]> hiddenRegions = hidden.iterator();
+ while (hiddenRegions.hasNext())
{
+ int[] region = hiddenRegions.next();
HiddenColumns hc = new HiddenColumns();
hc.setStart(region[0]);
hc.setEnd(region[1]);
@Override
public void paintComponent(Graphics g)
{
- // super.paintComponent(g);
+ super.paintComponent(g);
if (restart)
{
@Override
public void mouseMoved(MouseEvent evt)
{
- if (od.isPositionInBox(evt.getX(), evt.getY()))
+ if (!draggingBox)
+ // don't bother changing the cursor if we're dragging the box
+ // as we can't have moved inside or out of the box in that case
{
- // display drag cursor at mouse position
- setCursor(Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR));
- }
- else
- {
- // reset cursor
- setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
+ if (od.isPositionInBox(evt.getX(), evt.getY()))
+ {
+ // display drag cursor at mouse position
+ setCursor(Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR));
+ }
+ else
+ {
+ // reset cursor
+ setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
+ }
}
}
});
if (!od.isPositionInBox(evt.getX(), evt.getY()))
{
draggingBox = false;
+
+ // display drag cursor at mouse position
+ setCursor(Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR));
+
od.updateViewportFromMouse(evt.getX(), evt.getY(),
av.getAlignment().getHiddenSequences(),
av.getAlignment().getHiddenColumns());
showPopupMenu(evt);
}
}
+
+ @Override
+ public void mouseReleased(MouseEvent evt)
+ {
+ draggingBox = false;
+ }
+
});
}
protected void hideInsertions_actionPerformed(ActionEvent actionEvent)
{
-
- HiddenColumns hidden = new HiddenColumns();
- BitSet inserts = new BitSet(), mask = new BitSet();
-
- // set mask to preserve existing hidden columns outside selected group
- if (ap.av.hasHiddenColumns())
- {
- ap.av.getAlignment().getHiddenColumns().markHiddenRegions(mask);
- }
+ HiddenColumns hidden = ap.av.getAlignment().getHiddenColumns();
+ BitSet inserts = new BitSet();
boolean markedPopup = false;
// mark inserts in current selection
{
// mark just the columns in the selection group to be hidden
inserts.set(ap.av.getSelectionGroup().getStartRes(),
- ap.av.getSelectionGroup().getEndRes() + 1);
-
- // and clear that part of the mask
- mask.andNot(inserts);
+ ap.av.getSelectionGroup().getEndRes() + 1); // TODO why +1?
// now clear columns without gaps
for (SequenceI sq : ap.av.getSelectionGroup().getSequences())
}
inserts.and(sq.getInsertionsAsBits());
}
- }
- else
- {
- // initially, mark all columns to be hidden
- inserts.set(0, ap.av.getAlignment().getWidth());
-
- // and clear out old hidden regions completely
- mask.clear();
+ hidden.clearAndHideColumns(inserts, ap.av.getSelectionGroup().getStartRes(),
+ ap.av.getSelectionGroup().getEndRes());
}
// now mark for sequence under popup if we haven't already done it
- if (!markedPopup && sequence != null)
+ else if (!markedPopup && sequence != null)
{
- inserts.and(sequence.getInsertionsAsBits());
- }
+ inserts.or(sequence.getInsertionsAsBits());
- // finally, preserve hidden regions outside selection
- inserts.or(mask);
-
- // and set hidden columns accordingly
- hidden.hideMarkedBits(inserts);
-
- ap.av.getAlignment().setHiddenColumns(hidden);
+ // and set hidden columns accordingly
+ hidden.hideColumns(inserts);
+ }
refresh();
}
boolean applyToAllViews = false;
- // Controller controller;
public RotatableCanvas(AlignmentPanel ap)
{
this.av = ap.av;
addMouseWheelListener(new MouseWheelListener()
{
+ @Override
public void mouseWheelMoved(MouseWheelEvent e)
{
- if (e.getWheelRotation() > 0)
+ double wheelRotation = e.getPreciseWheelRotation();
+ if (wheelRotation > 0)
{
+ /*
+ * zoom in
+ */
scale = (float) (scale * 1.1);
repaint();
}
-
- else
+ else if (wheelRotation < 0)
{
+ /*
+ * zoom out
+ */
scale = (float) (scale * 0.9);
repaint();
}
boolean first = true;
+ @Override
public void setPoints(Vector points, int npoint)
{
this.points = points;
dim = height;
}
- return (float) ((dim * scalefactor) / (2 * maxwidth));
+ return (dim * scalefactor) / (2 * maxwidth);
}
/**
*
* @return DOCUMENT ME!
*/
+ @Override
public Dimension getPreferredSize()
{
if (prefsize != null)
*
* @return DOCUMENT ME!
*/
+ @Override
public Dimension getMinimumSize()
{
return getPreferredSize();
* @param g
* DOCUMENT ME!
*/
+ @Override
public void paintComponent(Graphics g1)
{
for (int i = 0; i < npoint; i++)
{
SequencePoint sp = (SequencePoint) points.elementAt(i);
- int x = (int) ((float) (sp.coord[0] - centre[0]) * scale) + halfwidth;
- int y = (int) ((float) (sp.coord[1] - centre[1]) * scale)
+ int x = (int) ((sp.coord[0] - centre[0]) * scale) + halfwidth;
+ int y = (int) ((sp.coord[1] - centre[1]) * scale)
+ halfheight;
float z = sp.coord[1] - centre[2];
* @param evt
* DOCUMENT ME!
*/
+ @Override
public void keyTyped(KeyEvent evt)
{
}
* @param evt
* DOCUMENT ME!
*/
+ @Override
public void keyReleased(KeyEvent evt)
{
}
* @param evt
* DOCUMENT ME!
*/
+ @Override
public void keyPressed(KeyEvent evt)
{
if (evt.getKeyCode() == KeyEvent.VK_UP)
* @param evt
* DOCUMENT ME!
*/
+ @Override
public void mouseClicked(MouseEvent evt)
{
}
* @param evt
* DOCUMENT ME!
*/
+ @Override
public void mouseEntered(MouseEvent evt)
{
}
* @param evt
* DOCUMENT ME!
*/
+ @Override
public void mouseExited(MouseEvent evt)
{
}
* @param evt
* DOCUMENT ME!
*/
+ @Override
public void mouseReleased(MouseEvent evt)
{
}
* @param evt
* DOCUMENT ME!
*/
+ @Override
public void mousePressed(MouseEvent evt)
{
int x = evt.getX();
// controller.handleSequenceSelectionEvent(new
// SequenceSelectionEvent(this,sel));
// }
+ @Override
public void mouseMoved(MouseEvent evt)
{
SequenceI found = findPoint(evt.getX(), evt.getY());
* @param evt
* DOCUMENT ME!
*/
+ @Override
public void mouseDragged(MouseEvent evt)
{
mx = evt.getX();
{
rotmat.setIdentity();
- rotmat.rotate((float) (my - omy), 'x');
- rotmat.rotate((float) (mx - omx), 'y');
+ rotmat.rotate(my - omy, 'x');
+ rotmat.rotate(mx - omx, 'y');
for (int i = 0; i < npoint; i++)
{
{
SequencePoint sp = (SequencePoint) points.elementAt(i);
int tmp1 = (int) (((sp.coord[0] - centre[0]) * scale)
- + ((float) getWidth() / 2.0));
+ + (getWidth() / 2.0));
int tmp2 = (int) (((sp.coord[1] - centre[1]) * scale)
- + ((float) getHeight() / 2.0));
+ + (getHeight() / 2.0));
if ((tmp1 > x1) && (tmp1 < x2) && (tmp2 > y1) && (tmp2 < y2))
{
for (int i = 0; i < npoint; i++)
{
SequencePoint sp = (SequencePoint) points.elementAt(i);
- int px = (int) ((float) (sp.coord[0] - centre[0]) * scale)
+ int px = (int) ((sp.coord[0] - centre[0]) * scale)
+ halfwidth;
- int py = (int) ((float) (sp.coord[1] - centre[1]) * scale)
+ int py = (int) ((sp.coord[1] - centre[1]) * scale)
+ halfheight;
if ((Math.abs(px - x) < 3) && (Math.abs(py - y) < 3))
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.beans.PropertyChangeEvent;
+import java.util.Iterator;
import java.util.List;
import javax.swing.JMenuItem;
if (av.hasHiddenColumns())
{
- x = av.getAlignment().getHiddenColumns().adjustForHiddenColumns(x);
+ x = av.getAlignment().getHiddenColumns().visibleToAbsoluteColumn(x);
}
if (x >= av.getAlignment().getWidth())
});
pop.add(item);
- if (av.getAlignment().getHiddenColumns().hasHiddenColumns())
+ if (av.getAlignment().getHiddenColumns().hasMultiHiddenColumnRegions())
{
item = new JMenuItem(MessageManager.getString("action.reveal_all"));
item.addActionListener(new ActionListener()
if (av.hasHiddenColumns())
{
res = av.getAlignment().getHiddenColumns()
- .adjustForHiddenColumns(res);
+ .visibleToAbsoluteColumn(res);
}
if (res >= av.getAlignment().getWidth())
int res = (evt.getX() / av.getCharWidth())
+ av.getRanges().getStartRes();
res = Math.max(0, res);
- res = hidden.adjustForHiddenColumns(res);
+ res = hidden.visibleToAbsoluteColumn(res);
res = Math.min(res, av.getAlignment().getWidth() - 1);
min = Math.min(res, min);
max = Math.max(res, max);
reveal = av.getAlignment().getHiddenColumns()
.getRegionWithEdgeAtRes(res);
- res = av.getAlignment().getHiddenColumns().adjustForHiddenColumns(res);
+ res = av.getAlignment().getHiddenColumns().visibleToAbsoluteColumn(res);
ToolTipManager.sharedInstance().registerComponent(this);
this.setToolTipText(
@Override
public void paintComponent(Graphics g)
{
+ super.paintComponent(g);
+
/*
* shouldn't get called in wrapped mode as the scale above is
* drawn instead by SeqCanvas.drawNorthScale
{
if (hidden.isVisible(sel))
{
- sel = hidden.findColumnPosition(sel);
+ sel = hidden.absoluteToVisibleColumn(sel);
}
else
{
if (av.getShowHiddenMarkers())
{
- List<Integer> positions = hidden.findHiddenRegionPositions();
- for (int pos : positions)
+ Iterator<Integer> it = hidden.getStartRegionIterator(startx,
+ startx + widthx + 1);
+ while (it.hasNext())
{
- res = pos - startx;
-
- if (res < 0 || res > widthx)
- {
- continue;
- }
+ res = it.next() - startx;
gg.fillPolygon(
new int[]
- { -1 + res * avCharWidth - avCharHeight / 4,
- -1 + res * avCharWidth + avCharHeight / 4,
- -1 + res * avCharWidth },
- new int[]
- { y, y, y + 2 * yOf }, 3);
+ { -1 + res * avCharWidth - avCharHeight / 4,
+ -1 + res * avCharWidth + avCharHeight / 4,
+ -1 + res * avCharWidth }, new int[]
+ { y, y, y + 2 * yOf }, 3);
}
}
}
|| evt.getPropertyName().equals(ViewportRanges.MOVE_VIEWPORT))
{
// scroll event, repaint panel
- repaint();
+
+ // Call repaint on alignment panel so that repaints from other alignment
+ // panel components can be aggregated. Otherwise performance of the overview
+ // window and others may be adversely affected.
+ av.getAlignPanel().repaint();
}
}
import jalview.datamodel.SearchResultsI;
import jalview.datamodel.SequenceGroup;
import jalview.datamodel.SequenceI;
+import jalview.datamodel.VisibleContigsIterator;
import jalview.renderer.ScaleRenderer;
import jalview.renderer.ScaleRenderer.ScaleMark;
import jalview.util.Comparison;
import java.awt.Shape;
import java.awt.image.BufferedImage;
import java.beans.PropertyChangeEvent;
+import java.util.Iterator;
import java.util.List;
import javax.swing.JComponent;
if (av.hasHiddenColumns())
{
HiddenColumns hiddenColumns = av.getAlignment().getHiddenColumns();
- startX = hiddenColumns.adjustForHiddenColumns(startx);
- endX = hiddenColumns.adjustForHiddenColumns(endx);
+ startX = hiddenColumns.visibleToAbsoluteColumn(startx);
+ endX = hiddenColumns.visibleToAbsoluteColumn(endx);
}
FontMetrics fm = getFontMetrics(av.getFont());
int endSeq = ranges.getEndSeq();
int transX = 0;
int transY = 0;
-
+
gg.copyArea(horizontal * charWidth, vertical * charHeight,
img.getWidth(), img.getHeight(), -horizontal * charWidth,
-vertical * charHeight);
drawPanel(gg, startRes, endRes, startSeq, endSeq, 0);
gg.translate(-transX, -transY);
- repaint();
+ // Call repaint on alignment panel so that repaints from other alignment
+ // panel components can be aggregated. Otherwise performance of the
+ // overview window and others may be adversely affected.
+ av.getAlignPanel().repaint();
} finally
{
fastpainting = false;
int charHeight = av.getCharHeight();
int charWidth = av.getCharWidth();
-
+
ViewportRanges ranges = av.getRanges();
-
+
int width = getWidth();
int height = getHeight();
-
+
width -= (width % charWidth);
height -= (height % charHeight);
-
+
// selectImage is the selection group outline image
BufferedImage selectImage = drawSelectionGroup(
ranges.getStartRes(), ranges.getEndRes(),
ranges.getStartSeq(), ranges.getEndSeq());
-
+
if ((img != null) && (fastPaint
|| (getVisibleRect().width != g.getClipBounds().width)
|| (getVisibleRect().height != g.getClipBounds().height)))
gg = (Graphics2D) img.getGraphics();
gg.setFont(av.getFont());
}
-
+
if (av.antiAlias)
{
gg.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
}
-
+
gg.setColor(Color.white);
gg.fillRect(0, 0, img.getWidth(), img.getHeight());
-
+
if (av.getWrapAlignment())
{
drawWrappedPanel(gg, getWidth(), getHeight(), ranges.getStartRes());
drawPanel(gg, ranges.getStartRes(), ranges.getEndRes(),
ranges.getStartSeq(), ranges.getEndSeq(), 0);
}
-
+
// lcimg is a local *copy* of img which we'll draw selectImage on top of
BufferedImage lcimg = buildLocalImage(selectImage);
g.drawImage(lcimg, 0, 0, this);
private BufferedImage buildLocalImage(BufferedImage selectImage)
{
// clone the cached image
- BufferedImage lcimg = new BufferedImage(img.getWidth(), img.getHeight(),
- img.getType());
+ BufferedImage lcimg = new BufferedImage(img.getWidth(), img.getHeight(),
+ img.getType());
+
+ // BufferedImage lcimg = new BufferedImage(img.getWidth(), img.getHeight(),
+ // img.getType());
Graphics2D g2d = lcimg.createGraphics();
g2d.drawImage(img, 0, 0, null);
try
{
- lcimg = new BufferedImage(width, height,
- BufferedImage.TYPE_INT_ARGB); // ARGB so alpha compositing works
+ lcimg = new BufferedImage(width, height,
+ BufferedImage.TYPE_INT_ARGB); // ARGB so alpha compositing works
} catch (OutOfMemoryError er)
{
System.gc();
int charWidth = av.getCharWidth();
g.setColor(Color.blue);
+ int res;
HiddenColumns hidden = av.getAlignment().getHiddenColumns();
- List<Integer> positions = hidden.findHiddenRegionPositions();
- for (int pos : positions)
+
+ Iterator<Integer> it = hidden.getStartRegionIterator(startColumn,
+ endColumn);
+ while (it.hasNext())
{
- int res = pos - startColumn;
+ res = it.next() - startColumn;
if (res < 0 || res > endColumn - startColumn + 1)
{
if (av.hasHiddenColumns())
{
maxwidth = av.getAlignment().getHiddenColumns()
- .findColumnPosition(maxwidth);
+ .absoluteToVisibleColumn(maxwidth);
}
// chop the wrapped alignment extent up into panel-sized blocks and treat
else
{
int screenY = 0;
- final int screenYMax = endRes - startRes;
- int blockStart = startRes;
- int blockEnd = endRes;
+ int blockStart;
+ int blockEnd;
- for (int[] region : av.getAlignment().getHiddenColumns()
- .getHiddenColumnsCopy())
- {
- int hideStart = region[0];
- int hideEnd = region[1];
+ HiddenColumns hidden = av.getAlignment().getHiddenColumns();
+ VisibleContigsIterator regions = hidden
+ .getVisContigsIterator(startRes, endRes + 1, true);
- if (hideStart <= blockStart)
- {
- blockStart += (hideEnd - hideStart) + 1;
- continue;
- }
+ while (regions.hasNext())
+ {
+ int[] region = regions.next();
+ blockEnd = region[1];
+ blockStart = region[0];
/*
* draw up to just before the next hidden region, or the end of
* the visible region, whichever comes first
*/
- blockEnd = Math.min(hideStart - 1, blockStart + screenYMax
- - screenY);
-
g1.translate(screenY * charWidth, 0);
draw(g1, blockStart, blockEnd, startSeq, endSeq, yOffset);
* draw the downline of the hidden column marker (ScalePanel draws the
* triangle on top) if we reached it
*/
- if (av.getShowHiddenMarkers() && blockEnd == hideStart - 1)
+ if (av.getShowHiddenMarkers()
+ && (regions.hasNext() || regions.endsAtHidden()))
{
g1.setColor(Color.blue);
g1.translate(-screenY * charWidth, 0);
screenY += blockEnd - blockStart + 1;
- blockStart = hideEnd + 1;
-
- if (screenY > screenYMax)
- {
- // already rendered last block
- return;
- }
- }
-
- if (screenY <= screenYMax)
- {
- // remaining visible region to render
- blockEnd = blockStart + screenYMax - screenY;
- g1.translate(screenY * charWidth, 0);
- draw(g1, blockStart, blockEnd, startSeq, endSeq, yOffset);
-
- g1.translate(-screenY * charWidth, 0);
}
}
if (av.hasSearchResults())
{
SearchResultsI searchResults = av.getSearchResults();
- int[] visibleResults = searchResults.getResults(nextSeq,
- startRes, endRes);
+ int[] visibleResults = searchResults.getResults(nextSeq, startRes,
+ endRes);
if (visibleResults != null)
{
for (int r = 0; r < visibleResults.length; r += 2)
{
seqRdr.drawHighlightedText(nextSeq, visibleResults[r],
- visibleResults[r + 1], (visibleResults[r] - startRes)
- * charWidth, offset
- + ((i - startSeq) * charHeight));
+ visibleResults[r + 1],
+ (visibleResults[r] - startRes) * charWidth,
+ offset + ((i - startSeq) * charHeight));
}
}
}
// convert the cursorX into a position on the visible alignment
int cursor_xpos = av.getAlignment().getHiddenColumns()
- .findColumnPosition(cursorX);
+ .absoluteToVisibleColumn(cursorX);
if (av.getAlignment().getHiddenColumns().isVisible(cursorX))
{
{
// package into blocks of visible columns
int screenY = 0;
- int blockStart = startRes;
- int blockEnd = endRes;
+ int blockStart;
+ int blockEnd;
- for (int[] region : av.getAlignment().getHiddenColumns()
- .getHiddenColumnsCopy())
+ HiddenColumns hidden = av.getAlignment().getHiddenColumns();
+ VisibleContigsIterator regions = hidden
+ .getVisContigsIterator(startRes, endRes + 1, true);
+ while (regions.hasNext())
{
- int hideStart = region[0];
- int hideEnd = region[1];
-
- if (hideStart <= blockStart)
- {
- blockStart += (hideEnd - hideStart) + 1;
- continue;
- }
-
- blockEnd = hideStart - 1;
+ int[] region = regions.next();
+ blockEnd = region[1];
+ blockStart = region[0];
g.translate(screenY * charWidth, 0);
drawPartialGroupOutline(g, group,
g.translate(-screenY * charWidth, 0);
screenY += blockEnd - blockStart + 1;
- blockStart = hideEnd + 1;
-
- if (screenY > (endRes - startRes))
- {
- // already rendered last block
- break;
- }
- }
-
- if (screenY <= (endRes - startRes))
- {
- // remaining visible region to render
- blockEnd = blockStart + (endRes - startRes) - screenY;
- g.translate(screenY * charWidth, 0);
- drawPartialGroupOutline(g, group,
- blockStart, blockEnd, startSeq, endSeq, offset);
-
- g.translate(-screenY * charWidth, 0);
}
}
}
if (av.hasHiddenColumns())
{
firstVisibleColumn = alignment.getHiddenColumns()
- .adjustForHiddenColumns(firstVisibleColumn);
+ .visibleToAbsoluteColumn(firstVisibleColumn);
lastVisibleColumn = alignment.getHiddenColumns()
- .adjustForHiddenColumns(lastVisibleColumn);
+ .visibleToAbsoluteColumn(lastVisibleColumn);
}
for (int seqNo = ranges.getStartSeq(); seqNo <= ranges
if (av.hasHiddenColumns())
{
firstCol = alignment.getHiddenColumns()
- .findColumnPosition(firstCol);
- lastCol = alignment.getHiddenColumns().findColumnPosition(lastCol);
+ .absoluteToVisibleColumn(firstCol);
+ lastCol = alignment.getHiddenColumns().absoluteToVisibleColumn(lastCol);
}
int transX = (firstCol - ranges.getStartRes()) * av.getCharWidth();
int transY = (firstSeq - ranges.getStartSeq()) * av.getCharHeight();
scrollX = -range;
}
}
- // Both scrolling and resizing change viewport ranges: scrolling changes
- // both start and end points, but resize only changes end values.
- // Here we only want to fastpaint on a scroll, with resize using a normal
- // paint, so scroll events are identified as changes to the horizontal or
- // vertical start value.
- if (eventName.equals(ViewportRanges.STARTRES))
- {
- if (av.getWrapAlignment())
+ // Both scrolling and resizing change viewport ranges: scrolling changes
+ // both start and end points, but resize only changes end values.
+ // Here we only want to fastpaint on a scroll, with resize using a normal
+ // paint, so scroll events are identified as changes to the horizontal or
+ // vertical start value.
+ if (eventName.equals(ViewportRanges.STARTRES))
+ {
+ if (av.getWrapAlignment())
+ {
+ fastPaintWrapped(scrollX);
+ }
+ else
+ {
+ fastPaint(scrollX, 0);
+ }
+ }
+ else if (eventName.equals(ViewportRanges.STARTSEQ))
+ {
+ // scroll
+ fastPaint(0, (int) evt.getNewValue() - (int) evt.getOldValue());
+ }
+ else if (eventName.equals(ViewportRanges.STARTRESANDSEQ))
+ {
+ if (av.getWrapAlignment())
{
fastPaintWrapped(scrollX);
}
{
fastPaintWrapped(scrollX);
}
- else
- {
- fastPaint(scrollX, 0);
- }
- // bizarrely, we only need to scroll on the x value here as fastpaint
- // copies the full height of the image anyway. Passing in the y value
- // causes nasty repaint artefacts, which only disappear on a full
- // repaint.
}
}
{
ViewportRanges ranges = av.getRanges();
- // if (Math.abs(scrollX) > ranges.getViewportWidth())
- // JAL-2836, 2836 temporarily removed wrapped fastpaint for release 2.10.3
- if (true)
+ if (Math.abs(scrollX) > ranges.getViewportWidth())
{
/*
* shift of more than one view width is
if (av.hasHiddenColumns())
{
firstVisibleColumn = alignment.getHiddenColumns()
- .adjustForHiddenColumns(firstVisibleColumn);
+ .visibleToAbsoluteColumn(firstVisibleColumn);
lastVisibleColumn = alignment.getHiddenColumns()
- .adjustForHiddenColumns(lastVisibleColumn);
+ .visibleToAbsoluteColumn(lastVisibleColumn);
}
int gapHeight = charHeight * (av.getScaleAboveWrapped() ? 2 : 1);
if (av.hasHiddenColumns())
{
displayColumn = alignment.getHiddenColumns()
- .findColumnPosition(displayColumn);
+ .absoluteToVisibleColumn(displayColumn);
}
/*
if (av.hasHiddenColumns())
{
res = av.getAlignment().getHiddenColumns()
- .adjustForHiddenColumns(res);
+ .visibleToAbsoluteColumn(res);
}
return res;
int original = seqCanvas.cursorX - dx;
int maxWidth = av.getAlignment().getWidth();
- // TODO: once JAL-2759 is ready, change this loop to something more
- // efficient
- while (!hidden.isVisible(seqCanvas.cursorX)
- && seqCanvas.cursorX < maxWidth && seqCanvas.cursorX > 0
- && dx != 0)
+ if (!hidden.isVisible(seqCanvas.cursorX))
{
- seqCanvas.cursorX += dx;
+ int visx = hidden.absoluteToVisibleColumn(seqCanvas.cursorX - dx);
+ int[] region = hidden.getRegionWithEdgeAtRes(visx);
+
+ if (region != null) // just in case
+ {
+ if (dx == 1)
+ {
+ // moving right
+ seqCanvas.cursorX = region[1] + 1;
+ }
+ else if (dx == -1)
+ {
+ // moving left
+ seqCanvas.cursorX = region[0] - 1;
+ }
+ }
+ seqCanvas.cursorX = (seqCanvas.cursorX < 0) ? 0 : seqCanvas.cursorX;
}
if (seqCanvas.cursorX >= maxWidth
{
// scrollToWrappedVisible expects x-value to have hidden cols subtracted
int x = av.getAlignment().getHiddenColumns()
- .findColumnPosition(seqCanvas.cursorX);
+ .absoluteToVisibleColumn(seqCanvas.cursorX);
av.getRanges().scrollToWrappedVisible(x);
}
else
{
fixedColumns = true;
int y1 = av.getAlignment().getHiddenColumns()
- .getHiddenBoundaryLeft(startres);
+ .getNextHiddenBoundary(true, startres);
int y2 = av.getAlignment().getHiddenColumns()
- .getHiddenBoundaryRight(startres);
+ .getNextHiddenBoundary(false, startres);
if ((insertGap && startres > y1 && lastres < y1)
|| (!insertGap && startres < y2 && lastres > y2))
if (sg.getSize() == av.getAlignment().getHeight())
{
if ((av.hasHiddenColumns() && startres < av.getAlignment()
- .getHiddenColumns().getHiddenBoundaryRight(startres)))
+ .getHiddenColumns()
+ .getNextHiddenBoundary(false, startres)))
{
endEditing();
return;
public void mouseWheelMoved(MouseWheelEvent e)
{
e.consume();
- if (e.getWheelRotation() > 0)
+ double wheelRotation = e.getPreciseWheelRotation();
+ if (wheelRotation > 0)
{
if (e.isShiftDown())
{
av.getRanges().scrollUp(false);
}
}
- else
+ else if (wheelRotation < 0)
{
if (e.isShiftDown())
{
package jalview.gui;
+import jalview.api.structures.JalviewStructureDisplayI;
import jalview.bin.Jalview;
import jalview.datamodel.DBRefEntry;
import jalview.datamodel.DBRefSource;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JLabel;
+import javax.swing.JTable;
+import javax.swing.SwingUtilities;
import javax.swing.table.AbstractTableModel;
/**
}
/**
+ * select structures for viewing by their PDB IDs
+ *
+ * @param pdbids
+ * @return true if structures were found and marked as selected
+ */
+ public boolean selectStructure(String... pdbids)
+ {
+ boolean found = false;
+
+ FilterOption selectedFilterOpt = ((FilterOption) cmb_filterOption
+ .getSelectedItem());
+ String currentView = selectedFilterOpt.getView();
+ JTable restable = (currentView == VIEWS_FILTER) ? getResultTable()
+ : (currentView == VIEWS_LOCAL_PDB) ? tbl_local_pdb : null;
+
+ if (restable == null)
+ {
+ // can't select (enter PDB ID, or load file - need to also select which
+ // sequence to associate with)
+ return false;
+ }
+
+ int pdbIdColIndex = restable.getColumn("PDB Id").getModelIndex();
+ for (int r = 0; r < restable.getRowCount(); r++)
+ {
+ for (int p = 0; p < pdbids.length; p++)
+ {
+ if (String.valueOf(restable.getValueAt(r, pdbIdColIndex))
+ .equalsIgnoreCase(pdbids[p]))
+ {
+ restable.setRowSelectionInterval(r, r);
+ found = true;
+ }
+ }
+ }
+ return found;
+ }
+ /**
* Handles action event for btn_ok
*/
@Override
public void ok_ActionPerformed()
{
+ showStructures(false);
+ }
+
+ /**
+ * structure viewer opened by this dialog, or null
+ */
+ private StructureViewer sViewer = null;
+
+ public void showStructures(boolean waitUntilFinished)
+ {
+
final StructureSelectionManager ssm = ap.getStructureSelectionManager();
final int preferredHeight = pnl_filter.getHeight();
- new Thread(new Runnable()
+ Runnable viewStruc = new Runnable()
{
@Override
public void run()
FilterOption selectedFilterOpt = ((FilterOption) cmb_filterOption
.getSelectedItem());
String currentView = selectedFilterOpt.getView();
+ JTable restable = (currentView == VIEWS_FILTER) ? getResultTable()
+ : tbl_local_pdb;
+
if (currentView == VIEWS_FILTER)
{
- int pdbIdColIndex = getResultTable().getColumn("PDB Id")
+ int pdbIdColIndex = restable.getColumn("PDB Id")
.getModelIndex();
- int refSeqColIndex = getResultTable().getColumn("Ref Sequence")
+ int refSeqColIndex = restable.getColumn("Ref Sequence")
.getModelIndex();
- int[] selectedRows = getResultTable().getSelectedRows();
+ int[] selectedRows = restable.getSelectedRows();
PDBEntry[] pdbEntriesToView = new PDBEntry[selectedRows.length];
int count = 0;
List<SequenceI> selectedSeqsToView = new ArrayList<>();
for (int row : selectedRows)
{
- String pdbIdStr = getResultTable()
+ String pdbIdStr = restable
.getValueAt(row, pdbIdColIndex).toString();
- SequenceI selectedSeq = (SequenceI) getResultTable()
+ SequenceI selectedSeq = (SequenceI) restable
.getValueAt(row, refSeqColIndex);
selectedSeqsToView.add(selectedSeq);
PDBEntry pdbEntry = selectedSeq.getPDBEntry(pdbIdStr);
}
SequenceI[] selectedSeqs = selectedSeqsToView
.toArray(new SequenceI[selectedSeqsToView.size()]);
- launchStructureViewer(ssm, pdbEntriesToView, ap, selectedSeqs);
+ sViewer = launchStructureViewer(ssm, pdbEntriesToView, ap,
+ selectedSeqs);
}
else if (currentView == VIEWS_LOCAL_PDB)
{
}
SequenceI[] selectedSeqs = selectedSeqsToView
.toArray(new SequenceI[selectedSeqsToView.size()]);
- launchStructureViewer(ssm, pdbEntriesToView, ap, selectedSeqs);
+ sViewer = launchStructureViewer(ssm, pdbEntriesToView, ap,
+ selectedSeqs);
}
else if (currentView == VIEWS_ENTER_ID)
{
}
PDBEntry[] pdbEntriesToView = new PDBEntry[] { pdbEntry };
- launchStructureViewer(ssm, pdbEntriesToView, ap,
+ sViewer = launchStructureViewer(ssm, pdbEntriesToView, ap,
new SequenceI[]
{ selectedSequence });
}
DataSourceType.FILE, selectedSequence, true,
Desktop.instance);
- launchStructureViewer(ssm, new PDBEntry[] { fileEntry }, ap,
+ sViewer = launchStructureViewer(
+ ssm, new PDBEntry[]
+ { fileEntry }, ap,
new SequenceI[]
{ selectedSequence });
}
- closeAction(preferredHeight);
- mainFrame.dispose();
+ SwingUtilities.invokeLater(new Runnable()
+ {
+ @Override
+ public void run()
+ {
+ closeAction(preferredHeight);
+ mainFrame.dispose();
+ }
+ });
}
- }).start();
+ };
+ Thread runner = new Thread(viewStruc);
+ runner.start();
+ if (waitUntilFinished)
+ {
+ while (sViewer == null ? runner.isAlive()
+ : (sViewer.sview == null ? true
+ : !sViewer.sview.hasMapping()))
+ {
+ try
+ {
+ Thread.sleep(300);
+ } catch (InterruptedException ie)
+ {
+
+ }
+ }
+ }
}
private PDBEntry getFindEntry(String id, Vector<PDBEntry> pdbEntries)
return foundEntry;
}
- private void launchStructureViewer(StructureSelectionManager ssm,
+ private StructureViewer launchStructureViewer(
+ StructureSelectionManager ssm,
final PDBEntry[] pdbEntriesToView,
final AlignmentPanel alignPanel, SequenceI[] sequences)
{
sViewer.viewStructures(pdbEntriesToView[0], sequences, alignPanel);
}
setProgressBar(null, progressId);
+ return sViewer;
}
/**
{
return progressBar.operationInProgress();
}
+
+ public JalviewStructureDisplayI getOpenedStructureViewer()
+ {
+ return sViewer == null ? null : sViewer.sview;
+ }
}
new PDBEntry[seqsForPdbs.size()]);
SequenceI[][] theSeqs = seqsForPdbs.values().toArray(
new SequenceI[seqsForPdbs.size()][]);
- JalviewStructureDisplayI sview = null;
+
if (viewerType.equals(ViewerType.JMOL))
{
sview = new AppJmol(ap, pdbsForFile, theSeqs);
private JalviewStructureDisplayI onlyOnePdb(PDBEntry[] pdbs,
SequenceI[] seqsForPdbs, AlignmentPanel ap)
{
- List<SequenceI> seqs = new ArrayList<SequenceI>();
+ List<SequenceI> seqs = new ArrayList<>();
if (pdbs == null || pdbs.length == 0)
{
return null;
ap);
}
+ JalviewStructureDisplayI sview = null;
+
public JalviewStructureDisplayI viewStructures(PDBEntry pdb,
SequenceI[] seqsForPdb, AlignmentPanel ap)
{
ViewerType viewerType = getViewerType();
- JalviewStructureDisplayI sview = null;
if (viewerType.equals(ViewerType.JMOL))
{
sview = new AppJmol(pdb, seqsForPdb, null, ap);
final boolean usetoColourbyseq = viewerData.isColourWithAlignPanel();
final boolean viewerColouring = viewerData.isColourByViewer();
- JalviewStructureDisplayI sview = null;
switch (type)
{
case JMOL:
return sview;
}
+ public boolean isBusy()
+ {
+ if (sview != null)
+ {
+ if (!sview.hasMapping())
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+
}
import jalview.jbgui.GStructureViewer;
import jalview.schemes.ColourSchemeI;
import jalview.schemes.ColourSchemes;
+import jalview.structure.StructureMapping;
import jalview.structures.models.AAStructureBindingModel;
import jalview.util.MessageManager;
protected boolean alignAddedStructures = false;
- protected boolean _started = false;
+ protected volatile boolean _started = false;
- protected boolean addingStructures = false;
+ protected volatile boolean addingStructures = false;
protected Thread worker = null;
protected JMenu viewSelectionMenu;
/**
+ * set after sequence colouring has been applied for this structure viewer.
+ * used to determine if the final sequence/structure mapping has been
+ * determined
+ */
+ protected volatile boolean seqColoursApplied = false;
+
+ /**
* Default constructor
*/
public StructureViewerBase()
{
binding.colourBySequence(ap);
}
+ seqColoursApplied = true;
}
}
seqColour_actionPerformed(null);
}
}
+
+ @Override
+ public boolean hasMapping()
+ {
+ if (worker != null && (addingStructures || _started))
+ {
+ return false;
+ }
+ if (getBinding() == null)
+ {
+ if (_aps == null || _aps.size() == 0)
+ {
+ // viewer has been closed, but we did at some point run.
+ return true;
+ }
+ return false;
+ }
+ String[] pdbids = getBinding().getStructureFiles();
+ if (pdbids == null)
+ {
+ return false;
+ }
+ int p=0;
+ for (String pdbid:pdbids) {
+ StructureMapping sm[] = getBinding().getSsm().getMapping(pdbid);
+ if (sm!=null && sm.length>0 && sm[0]!=null) {
+ p++;
+ }
+ }
+ // only return true if there is a mapping for every structure file we have loaded
+ if (p == 0 || p != pdbids.length)
+ {
+ return false;
+ }
+ // and that coloring has been applied
+ return seqColoursApplied;
+ }
+
}
}
else
{
- // int[] intervals = colsel.getVisibleContigs(
- // seqsel.getStartRes(), seqsel.getEndRes() + 1);
- int[] intervals = hidden.getVisibleContigs(
- seqsel.getStartRes(), seqsel.getEndRes() + 1);
- for (int iv = 0; iv < intervals.length; iv += 2)
+ Iterator<int[]> intervals = hidden
+ .getVisContigsIterator(seqsel.getStartRes(),
+ seqsel.getEndRes() + 1, false);
+ while (intervals.hasNext())
{
+ int[] region = intervals.next();
Seg s = new Seg();
- s.setStart(intervals[iv] + 1); // vamsas indices begin at
- // 1, not zero.
- s.setEnd(intervals[iv + 1] + 1);
+ s.setStart(region[0] + 1); // vamsas indices begin at 1,
+ // not zero.
+ s.setEnd(region[1] + 1);
s.setInclusive(true);
range.addSeg(s);
}
else
{
// consider deferring this till after the file has been parsed ?
- hidden.hideInsertionsFor(sr);
+ hidden.hideList(sr.getInsertions());
}
}
modified = true;
AlignmentAnnotation na = new AlignmentAnnotation(ala[i]);
if (selgp != null)
{
- hidden.makeVisibleAnnotation(selgp.getStartRes(),
- selgp.getEndRes(), na);
+ na.makeVisibleAnnotation(selgp.getStartRes(), selgp.getEndRes(),
+ hidden);
}
else
{
- hidden.makeVisibleAnnotation(na);
+ na.makeVisibleAnnotation(hidden);
}
alv.addAnnotation(na);
}
{
g.setColor(STEM_COLOUR);
int sCol = (lastSSX / charWidth)
- + hiddenColumns.adjustForHiddenColumns(startRes);
+ + hiddenColumns.visibleToAbsoluteColumn(startRes);
int x1 = lastSSX;
int x2 = (x * charWidth);
g.setColor(nonCanColor);
int sCol = (lastSSX / charWidth)
- + hiddenColumns.adjustForHiddenColumns(startRes);
+ + hiddenColumns.visibleToAbsoluteColumn(startRes);
int x1 = lastSSX;
int x2 = (x * charWidth);
{
if (hasHiddenColumns)
{
- column = hiddenColumns.adjustForHiddenColumns(startRes + x);
+ column = hiddenColumns.visibleToAbsoluteColumn(startRes + x);
if (column > row_annotations.length - 1)
{
break;
g.setColor(HELIX_COLOUR);
int sCol = (lastSSX / charWidth)
- + hiddenColumns.adjustForHiddenColumns(startRes);
+ + hiddenColumns.visibleToAbsoluteColumn(startRes);
int x1 = lastSSX;
int x2 = (x * charWidth);
column = sRes + x;
if (hasHiddenColumns)
{
- column = hiddenColumns.adjustForHiddenColumns(column);
+ column = hiddenColumns.visibleToAbsoluteColumn(column);
}
if (column > aaMax)
column = sRes + x;
if (hasHiddenColumns)
{
- column = hiddenColumns.adjustForHiddenColumns(column);
+ column = hiddenColumns.visibleToAbsoluteColumn(column);
}
if (column > aaMax)
package jalview.renderer;
import jalview.api.AlignViewportI;
+import jalview.datamodel.HiddenColumns;
import jalview.datamodel.SequenceI;
import java.util.ArrayList;
+import java.util.Iterator;
import java.util.List;
/**
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);
- }
}
/**
- * Calculates position markers on the alignment ruler
+ * calculate positions markers on the alignment ruler
*
* @param av
* @param startx
- * left-most column in visible view (0..)
+ * left-most column in visible view
* @param endx
- * - right-most column in visible view (0..)
- * @return
+ * - 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)
*/
public List<ScaleMark> calculateMarks(AlignViewportI av, int startx,
int endx)
int scalestartx = (startx / 10) * 10;
SequenceI refSeq = av.getAlignment().getSeqrep();
- int refSp = 0, refStartI = 0, refEndI = -1;
+ int refSp = 0;
+ int refStartI = 0;
+ int refEndI = -1;
+
+ HiddenColumns hc = av.getAlignment().getHiddenColumns();
+
if (refSeq != null)
{
- // find bounds and set origin appopriately
- // locate first visible position for this sequence
- int[] refbounds = av.getAlignment().getHiddenColumns()
- .locateVisibleBoundsOfSequence(refSeq);
+ // find bounds and set origin appropriately
+ // locate first residue in sequence which is not hidden
+ Iterator<int[]> it = hc.iterator();
+ int index = refSeq.firstResidueOutsideIterator(it);
+ refSp = hc.absoluteToVisibleColumn(index);
+
+ refStartI = refSeq.findIndex(refSeq.getStart()) - 1;
+
+ int seqlength = refSeq.getLength();
+ // get sequence position past the end of the sequence
+ int pastEndPos = refSeq.findPosition(seqlength + 1);
+ refEndI = refSeq.findIndex(pastEndPos - 1) - 1;
- refSp = refbounds[0];
- refStartI = refbounds[4];
- refEndI = refbounds[5];
scalestartx = refSp + ((scalestartx - refSp) / 10) * 10;
}
{
scalestartx += 5;
}
- List<ScaleMark> marks = new ArrayList<ScaleMark>();
+ List<ScaleMark> marks = new ArrayList<>();
+ 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)
{
if (((i - refSp) % 10) == 0)
{
- String text;
if (refSeq == null)
{
- int iadj = av.getAlignment().getHiddenColumns()
- .adjustForHiddenColumns(i - 1) + 1;
- text = String.valueOf(iadj);
+ iadj = hc.visibleToAbsoluteColumn(i - 1) + 1;
+ string = String.valueOf(iadj);
}
else
{
- int iadj = av.getAlignment().getHiddenColumns()
- .adjustForHiddenColumns(i - 1);
- int refN = refSeq.findPosition(iadj);
+ iadj = hc.visibleToAbsoluteColumn(i - 1);
+ refN = refSeq.findPosition(iadj);
// TODO show bounds if position is a gap
// - ie L--R -> "1L|2R" for
// marker
if (iadj < refStartI)
{
- text = String.valueOf(iadj - refStartI);
+ string = String.valueOf(iadj - refStartI);
}
else if (iadj > refEndI)
{
- text = "+" + String.valueOf(iadj - refEndI);
+ string = "+" + String.valueOf(iadj - refEndI);
}
else
{
- text = String.valueOf(refN) + refSeq.getCharAt(iadj);
+ string = String.valueOf(refN) + refSeq.getCharAt(iadj);
}
}
- marks.add(new ScaleMark(true, i - startx - 1, text));
+ marks.add(new ScaleMark(true, i - startx - 1, string));
}
else
{
package jalview.structure;
import jalview.datamodel.AlignmentAnnotation;
+import jalview.datamodel.Mapping;
import jalview.datamodel.SequenceI;
import java.util.ArrayList;
String pdbchain;
- public static final int UNASSIGNED_VALUE = -1;
+ public static final int UNASSIGNED_VALUE = Integer.MIN_VALUE;
private static final int PDB_RES_NUM_INDEX = 0;
// and atomNo
HashMap<Integer, int[]> mapping;
+ jalview.datamodel.Mapping seqToPdbMapping = null;
/**
* Constructor
*
this.mappingDetails = mappingDetails;
}
+ public StructureMapping(SequenceI seq, String pdbFile2, String pdbId2,
+ String chain, HashMap<Integer, int[]> mapping2,
+ String mappingOutput, Mapping seqToPdbMapping)
+ {
+ this(seq, pdbFile2, pdbId2, chain, mapping2, mappingOutput);
+ this.seqToPdbMapping = seqToPdbMapping;
+ }
+
public SequenceI getSequence()
{
return sequence;
/**
*
* @param seqpos
- * @return 0 or the corresponding residue number for the sequence position
+ * @return UNASSIGNED_VALUE or the corresponding residue number for the
+ * sequence position
*/
public int getPDBResNum(int seqpos)
{
{
return mapping;
}
+
+ public Mapping getSeqToPdbMapping()
+ {
+ return seqToPdbMapping;
+ }
}
private boolean addTempFacAnnot = false;
- private SiftsClient siftsClient = null;
-
/*
* Set of any registered mappings between (dataset) sequences.
*/
}
/**
- * create sequence structure mappings between each sequence and the given
- * pdbFile (retrieved via the given protocol).
+ * Import a single structure file and register sequence structure mappings for
+ * broadcasting colouring, mouseovers and selection events (convenience
+ * wrapper).
*
* @param forStructureView
* when true, record the mapping for use in mouseOvers
- *
- * @param sequenceArray
+ * @param sequence
* - one or more sequences to be mapped to pdbFile
- * @param targetChainIds
+ * @param targetChains
* - optional chain specification for mapping each sequence to pdb
- * (may be nill, individual elements may be nill) - JBPNote: JAL-2693
- * - this should be List<List<String>>, empty lists indicate no
- * predefined mappings
+ * (may be nill, individual elements may be nill)
* @param pdbFile
* - structure data resource
- * @param sourceType
+ * @param protocol
* - how to resolve data from resource
* @return null or the structure data parsed as a pdb file
*/
pdbFile, sourceType, null);
}
+ /**
+ * create sequence structure mappings between each sequence and the given
+ * pdbFile (retrieved via the given protocol). Either constructs a mapping
+ * using NW alignment or derives one from any available SIFTS mapping data.
+ *
+ * @param forStructureView
+ * when true, record the mapping for use in mouseOvers
+ *
+ * @param sequenceArray
+ * - one or more sequences to be mapped to pdbFile
+ * @param targetChainIds
+ * - optional chain specification for mapping each sequence to pdb
+ * (may be nill, individual elements may be nill) - JBPNote: JAL-2693
+ * - this should be List<List<String>>, empty lists indicate no
+ * predefined mappings
+ * @param pdbFile
+ * - structure data resource
+ * @param sourceType
+ * - how to resolve data from resource
+ * @param IProgressIndicator
+ * reference to UI component that maintains a progress bar for the
+ * mapping operation
+ * @return null or the structure data parsed as a pdb file
+ */
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
+
+ /**
+ * do we extract and transfer annotation from 3D data ?
*/
- boolean parseSecStr = processSecondaryStructure;
- if (isPDBFileRegistered(pdbFile))
- {
- for (SequenceI sq : sequenceArray)
- {
- SequenceI ds = sq;
- while (ds.getDatasetSequence() != null)
- {
- ds = ds.getDatasetSequence();
- }
- ;
- if (ds.getAnnotation() != null)
- {
- for (AlignmentAnnotation ala : ds.getAnnotation())
- {
- // false if any annotation present from this structure
- // JBPNote this fails for jmol/chimera view because the *file* is
- // passed, not the structure data ID -
- if (PDBfile.isCalcIdForFile(ala, findIdForPDBFile(pdbFile)))
- {
- parseSecStr = false;
- }
- }
- }
- }
- }
+ // FIXME: possibly should just delete
+
+ boolean parseSecStr = processSecondaryStructure
+ ? isStructureFileProcessed(pdbFile, sequenceArray)
+ : false;
+
StructureFile pdb = null;
boolean isMapUsingSIFTs = SiftsSettings.isMapWithSifts();
try
{
+ // FIXME if sourceType is not null, we've lost data here
sourceType = AppletFormatAdapter.checkProtocol(pdbFile);
pdb = new JmolParser(pdbFile, sourceType);
ex.printStackTrace();
return null;
}
-
+ /*
+ * sifts client - non null if SIFTS mappings are to be used
+ */
+ SiftsClient siftsClient = null;
try
{
if (isMapUsingSIFTs)
{
isMapUsingSIFTs = false;
e.printStackTrace();
+ siftsClient = null;
}
String targetChainId;
try
{
siftsMapping = getStructureMapping(seq, pdbFile, targetChainId,
- pdb, maxChain, sqmpping, maxAlignseq);
+ pdb, maxChain, sqmpping, maxAlignseq, siftsClient);
seqToStrucMapping.add(siftsMapping);
- maxChain.makeExactMapping(maxAlignseq, seq);
- maxChain.transferRESNUMFeatures(seq, null);// FIXME: is this
+ maxChain.makeExactMapping(siftsMapping, seq);
+ maxChain.transferRESNUMFeatures(seq, "IEA: SIFTS");// FIXME: is this
// "IEA:SIFTS" ?
- maxChain.transferResidueAnnotation(siftsMapping, sqmpping);
+ maxChain.transferResidueAnnotation(siftsMapping, null);
ds.addPDBId(maxChain.sequence.getAllPDBEntries().get(0));
} catch (SiftsException e)
targetChainId, maxChain, pdb, maxAlignseq);
seqToStrucMapping.add(nwMapping);
maxChain.makeExactMapping(maxAlignseq, seq);
- maxChain.transferRESNUMFeatures(seq, null); // FIXME: is this
+ maxChain.transferRESNUMFeatures(seq, "IEA:Jalview"); // FIXME: is
+ // this
// "IEA:Jalview" ?
maxChain.transferResidueAnnotation(nwMapping, sqmpping);
ds.addPDBId(maxChain.sequence.getAllPDBEntries().get(0));
List<StructureMapping> foundSiftsMappings = new ArrayList<>();
for (PDBChain chain : pdb.getChains())
{
+ StructureMapping siftsMapping = null;
try
{
- StructureMapping siftsMapping = getStructureMapping(seq,
- pdbFile, chain.id, pdb, chain, sqmpping, maxAlignseq);
+ siftsMapping = getStructureMapping(seq,
+ pdbFile, chain.id, pdb, chain, sqmpping, maxAlignseq,
+ siftsClient);
foundSiftsMappings.add(siftsMapping);
+ chain.makeExactMapping(siftsMapping, seq);
+ chain.transferRESNUMFeatures(seq, "IEA: SIFTS");// FIXME: is this
+ // "IEA:SIFTS" ?
+ chain.transferResidueAnnotation(siftsMapping, null);
} catch (SiftsException e)
{
System.err.println(e.getMessage());
if (!foundSiftsMappings.isEmpty())
{
seqToStrucMapping.addAll(foundSiftsMappings);
- maxChain.makeExactMapping(maxAlignseq, seq);
- maxChain.transferRESNUMFeatures(seq, null);// FIXME: is this
- // "IEA:SIFTS" ?
- maxChain.transferResidueAnnotation(foundSiftsMappings.get(0),
- sqmpping);
ds.addPDBId(sqmpping.getTo().getAllPDBEntries().get(0));
}
else
return pdb;
}
+ /**
+ * check if we need to extract secondary structure from given pdbFile and
+ * transfer to sequences
+ *
+ * @param pdbFile
+ * @param sequenceArray
+ * @return
+ */
+ private boolean isStructureFileProcessed(String pdbFile,
+ SequenceI[] sequenceArray)
+ {
+ boolean parseSecStr = true;
+ if (isPDBFileRegistered(pdbFile))
+ {
+ for (SequenceI sq : sequenceArray)
+ {
+ SequenceI ds = sq;
+ while (ds.getDatasetSequence() != null)
+ {
+ ds = ds.getDatasetSequence();
+ }
+ ;
+ if (ds.getAnnotation() != null)
+ {
+ for (AlignmentAnnotation ala : ds.getAnnotation())
+ {
+ // false if any annotation present from this structure
+ // JBPNote this fails for jmol/chimera view because the *file* is
+ // passed, not the structure data ID -
+ if (PDBfile.isCalcIdForFile(ala, findIdForPDBFile(pdbFile)))
+ {
+ parseSecStr = false;
+ }
+ }
+ }
+ }
+ }
+ return parseSecStr;
+ }
+
public void addStructureMapping(StructureMapping sm)
{
mappings.add(sm);
* @param maxChain
* @param sqmpping
* @param maxAlignseq
+ * @param siftsClient
+ * client for retrieval of SIFTS mappings for this structure
* @return
* @throws SiftsException
*/
private StructureMapping getStructureMapping(SequenceI seq,
String pdbFile, String targetChainId, StructureFile pdb,
PDBChain maxChain, jalview.datamodel.Mapping sqmpping,
- AlignSeq maxAlignseq) throws SiftsException
+ AlignSeq maxAlignseq, SiftsClient siftsClient) throws SiftsException
{
StructureMapping curChainMapping = siftsClient
.getSiftsStructureMapping(seq, pdbFile, targetChainId);
PDBChain chain = pdb.findChain(targetChainId);
if (chain != null)
{
- chain.transferResidueAnnotation(curChainMapping, sqmpping);
+ chain.transferResidueAnnotation(curChainMapping, null);
}
} catch (Exception e)
{
toSequences, fromGapChar);
}
- for (int[] hidden : hiddencols.getHiddenColumnsCopy())
+ Iterator<int[]> regions = hiddencols.iterator();
+ while (regions.hasNext())
{
- mapHiddenColumns(hidden, codonFrames, newHidden, fromSequences,
+ mapHiddenColumns(regions.next(), codonFrames, newHidden,
+ fromSequences,
toSequences, fromGapChar);
}
return; // mappedColumns;
import java.util.Deque;
import java.util.HashMap;
import java.util.Hashtable;
+import java.util.Iterator;
import java.util.List;
import java.util.Map;
if (alignment.getHiddenColumns() != null
&& alignment.getHiddenColumns().hasHiddenColumns())
{
- selection = alignment.getHiddenColumns()
- .getVisibleSequenceStrings(start, end, seqs);
+ for (i = 0; i < iSize; i++)
+ {
+ Iterator<int[]> blocks = alignment.getHiddenColumns()
+ .getVisContigsIterator(start, end + 1, false);
+ selection[i] = seqs[i].getSequenceStringFromIterator(blocks);
+ }
}
else
{
{
if (start == 0)
{
- start = hidden.adjustForHiddenColumns(start);
+ start = hidden.visibleToAbsoluteColumn(start);
}
- end = hidden.getHiddenBoundaryRight(start);
+ end = hidden.getNextHiddenBoundary(false, start);
if (start == end)
{
end = max;
if (hidden != null && hidden.hasHiddenColumns())
{
- start = hidden.adjustForHiddenColumns(end);
- start = hidden.getHiddenBoundaryLeft(start) + 1;
+ start = hidden.visibleToAbsoluteColumn(end);
+ start = hidden.getNextHiddenBoundary(true, start) + 1;
}
} while (end < max);
AlignmentAnnotation clone = new AlignmentAnnotation(annot);
if (selectedOnly && selectionGroup != null)
{
- alignment.getHiddenColumns().makeVisibleAnnotation(
+ clone.makeVisibleAnnotation(
selectionGroup.getStartRes(), selectionGroup.getEndRes(),
- clone);
+ alignment.getHiddenColumns());
}
else
{
- alignment.getHiddenColumns().makeVisibleAnnotation(clone);
+ clone.makeVisibleAnnotation(alignment.getHiddenColumns());
}
ala.add(clone);
}
int lastSeq = alignment.getHeight() - 1;
List<AlignedCodonFrame> seqMappings = null;
for (int seqNo = ranges
- .getStartSeq(); seqNo < lastSeq; seqNo++, seqOffset++)
+ .getStartSeq(); seqNo <= lastSeq; seqNo++, seqOffset++)
{
sequence = getAlignment().getSequenceAt(seqNo);
if (hiddenSequences != null && hiddenSequences.isHidden(sequence))
protected int alheight;
+ protected float widthRatio;
+
+ protected float heightRatio;
+
/**
* Create an OverviewDimensions object
*
public float getPixelsPerCol()
{
resetAlignmentDims();
- return (float) width / alwidth;
+ return 1 / widthRatio;
}
public float getPixelsPerSeq()
{
resetAlignmentDims();
- return (float) sequencesHeight / alheight;
+ return 1 / heightRatio;
}
public void setWidth(int w)
{
width = w;
+ widthRatio = (float) alwidth / width;
}
public void setHeight(int h)
{
sequencesHeight = h - graphHeight;
+ heightRatio = (float) alheight / sequencesHeight;
}
/**
// boxX, boxY is the x,y location equivalent to startRes, startSeq
int xPos = Math.min(startRes, alwidth - vpwidth + 1);
- boxX = Math.round((float) xPos * width / alwidth);
- boxY = Math.round((float) startSeq * sequencesHeight / alheight);
+ boxX = Math.round(xPos / widthRatio);
+ boxY = Math.round(startSeq / heightRatio);
// boxWidth is the width in residues translated to pixels
- boxWidth = Math.round((float) vpwidth * width / alwidth);
+ boxWidth = Math.round(vpwidth / widthRatio);
// boxHeight is the height in sequences translated to pixels
- boxHeight = Math.round((float) vpheight * sequencesHeight / alheight);
+ boxHeight = Math.round(vpheight / heightRatio);
}
/**
public void updateViewportFromMouse(int mousex, int mousey,
HiddenSequences hiddenSeqs, HiddenColumns hiddenCols)
{
+ resetAlignmentDims();
+
int xAsRes = getLeftXFromCentreX(mousex, hiddenCols);
int yAsSeq = getTopYFromCentreY(mousey, hiddenSeqs);
public void adjustViewportFromMouse(int mousex, int mousey,
HiddenSequences hiddenSeqs, HiddenColumns hiddenCols)
{
+ resetAlignmentDims();
+
// calculate translation in pixel terms:
// get mouse location in viewport coords, add translation in viewport
// coords, and update viewport as usual
- int vpx = Math.round((float) mousex * alwidth / width);
- int vpy = Math.round((float) mousey * alheight / sequencesHeight);
+ int vpx = Math.round(mousex * widthRatio);
+ int vpy = Math.round(mousey * heightRatio);
updateViewportFromTopLeft(vpx + xdiff, vpy + ydiff, hiddenSeqs,
hiddenCols);
}
+ /**
+ * {@inheritDoc} Callers should have already called resetAlignmentDims to
+ * refresh alwidth, alheight and width/height ratios
+ */
@Override
protected void updateViewportFromTopLeft(int leftx, int topy,
HiddenSequences hiddenSeqs, HiddenColumns hiddenCols)
{
int xAsRes = leftx;
int yAsSeq = topy;
- resetAlignmentDims();
if (xAsRes < 0)
{
public AlignmentColsCollectionI getColumns(AlignmentI al)
{
return new VisibleColsCollection(0,
- ranges.getAbsoluteAlignmentWidth() - 1, al);
+ ranges.getAbsoluteAlignmentWidth() - 1, al.getHiddenColumns());
}
@Override
{
alwidth = ranges.getVisibleAlignmentWidth();
alheight = ranges.getVisibleAlignmentHeight();
+
+ widthRatio = (float) alwidth / width;
+ heightRatio = (float) alheight / sequencesHeight;
}
+ /**
+ * {@inheritDoc} Callers should have already called resetAlignmentDims to
+ * refresh widthRatio
+ */
@Override
protected int getLeftXFromCentreX(int mousex, HiddenColumns hidden)
{
- int vpx = Math.round((float) mousex * alwidth / width);
+ int vpx = Math.round(mousex * widthRatio);
return vpx - ranges.getViewportWidth() / 2;
}
+ /**
+ * {@inheritDoc} Callers should have already called resetAlignmentDims to
+ * refresh heightRatio
+ */
@Override
protected int getTopYFromCentreY(int mousey, HiddenSequences hidden)
{
- int vpy = Math.round((float) mousey * alheight / sequencesHeight);
+ int vpy = Math.round(mousey * heightRatio);
return vpy - ranges.getViewportHeight() / 2;
}
public void setDragPoint(int x, int y, HiddenSequences hiddenSeqs,
HiddenColumns hiddenCols)
{
+ resetAlignmentDims();
+
// get alignment position of x and box (can get directly from vpranges) and
// calculate difference between the positions
- int vpx = Math.round((float) x * alwidth / width);
- int vpy = Math.round((float) y * alheight / sequencesHeight);
+ int vpx = Math.round(x * widthRatio);
+ int vpy = Math.round(y * heightRatio);
xdiff = ranges.getStartRes() - vpx;
ydiff = ranges.getStartSeq() - vpy;
public void updateViewportFromMouse(int mousex, int mousey,
HiddenSequences hiddenSeqs, HiddenColumns hiddenCols)
{
+ resetAlignmentDims();
+
// convert mousex and mousey to alignment units as well as
// translating to top left corner of viewport - this is an absolute position
int xAsRes = getLeftXFromCentreX(mousex, hiddenCols);
int yAsSeq = getTopYFromCentreY(mousey, hiddenSeqs);
// convert to visible positions
- int visXAsRes = hiddenCols.findColumnPosition(xAsRes);
+ int visXAsRes = hiddenCols.absoluteToVisibleColumn(xAsRes);
yAsSeq = hiddenSeqs.adjustForHiddenSeqs(
hiddenSeqs.findIndexWithoutHiddenSeqs(yAsSeq));
yAsSeq = Math.max(yAsSeq, 0); // -1 if before first visible sequence
public void adjustViewportFromMouse(int mousex, int mousey,
HiddenSequences hiddenSeqs, HiddenColumns hiddenCols)
{
+ resetAlignmentDims();
+
// calculate translation in pixel terms:
// get mouse location in viewport coords, add translation in viewport
// coords,
// convert back to pixel coords
int vpx = Math.round((float) mousex * alwidth / width);
- int visXAsRes = hiddenCols.findColumnPosition(vpx) + xdiff;
+ int visXAsRes = hiddenCols.absoluteToVisibleColumn(vpx) + xdiff;
- int vpy = Math.round((float) mousey * alheight / sequencesHeight);
+ int vpy = Math.round(mousey * heightRatio);
int visYAsRes = hiddenSeqs.findIndexWithoutHiddenSeqs(vpy) + ydiff;
// update viewport accordingly
updateViewportFromTopLeft(visXAsRes, visYAsRes, hiddenSeqs, hiddenCols);
}
+ /**
+ * {@inheritDoc} Callers should have already called resetAlignmentDims to
+ * refresh alwidth, alheight and width/height ratios
+ */
@Override
protected void updateViewportFromTopLeft(int leftx, int topy,
HiddenSequences hiddenSeqs, HiddenColumns hiddenCols)
{
int visXAsRes = leftx;
int visYAsSeq = topy;
- resetAlignmentDims();
if (visXAsRes < 0)
{
int vpwidth = ranges.getViewportWidth();
// check in case we went off the edge of the alignment
- int visAlignWidth = hiddenCols.findColumnPosition(alwidth - 1);
+ int visAlignWidth = hiddenCols.absoluteToVisibleColumn(alwidth - 1);
if (visXAsRes + vpwidth - 1 > visAlignWidth)
{
// went past the end of the alignment, adjust backwards
// if last position was before the end of the alignment, need to update
if (ranges.getEndRes() < visAlignWidth)
{
- visXAsRes = hiddenCols.findColumnPosition(hiddenCols
- .subtractVisibleColumns(vpwidth - 1, alwidth - 1));
+ visXAsRes = hiddenCols.absoluteToVisibleColumn(hiddenCols
+ .offsetByVisibleColumns(-(vpwidth - 1), alwidth - 1));
}
else
{
HiddenColumns hiddenCols)
{
// work with absolute values of startRes and endRes
- int startRes = hiddenCols.adjustForHiddenColumns(ranges.getStartRes());
- int endRes = hiddenCols.adjustForHiddenColumns(ranges.getEndRes());
+ int startRes = hiddenCols.visibleToAbsoluteColumn(ranges.getStartRes());
+ int endRes = hiddenCols.visibleToAbsoluteColumn(ranges.getEndRes());
// work with absolute values of startSeq and endSeq
int startSeq = hiddenSeqs.adjustForHiddenSeqs(ranges.getStartSeq());
{
alwidth = ranges.getAbsoluteAlignmentWidth();
alheight = ranges.getAbsoluteAlignmentHeight();
+
+ widthRatio = (float) alwidth / width;
+ heightRatio = (float) alheight / sequencesHeight;
}
+
+ /**
+ * {@inheritDoc} Callers should have already called resetAlignmentDims to
+ * refresh widthRatio
+ */
@Override
protected int getLeftXFromCentreX(int mousex, HiddenColumns hidden)
{
int vpx = Math.round((float) mousex * alwidth / width);
- return hidden.subtractVisibleColumns(ranges.getViewportWidth() / 2,
+ return hidden.offsetByVisibleColumns(-ranges.getViewportWidth() / 2,
vpx);
}
+ /**
+ * {@inheritDoc} Callers should have already called resetAlignmentDims to
+ * refresh heightRatio
+ */
@Override
protected int getTopYFromCentreY(int mousey, HiddenSequences hidden)
{
- int vpy = Math.round((float) mousey * alheight / sequencesHeight);
+ int vpy = Math.round(mousey * heightRatio);
return hidden.subtractVisibleRows(ranges.getViewportHeight() / 2, vpy);
}
public void setDragPoint(int x, int y, HiddenSequences hiddenSeqs,
HiddenColumns hiddenCols)
{
+ resetAlignmentDims();
+
// get alignment position of x and box (can get directly from vpranges) and
// calculate difference between the positions
- int vpx = Math.round((float) x * alwidth / width);
- int vpy = Math.round((float) y * alheight / sequencesHeight);
+ int vpx = Math.round(x * widthRatio);
+ int vpy = Math.round(y * heightRatio);
- xdiff = ranges.getStartRes() - hiddenCols.findColumnPosition(vpx);
+ xdiff = ranges.getStartRes() - hiddenCols.absoluteToVisibleColumn(vpx);
ydiff = ranges.getStartSeq()
- hiddenSeqs.findIndexWithoutHiddenSeqs(vpy);
}
}
HiddenColumns hidden = al.getHiddenColumns();
- while (x < hidden.adjustForHiddenColumns(startRes))
+ while (x < hidden.visibleToAbsoluteColumn(startRes))
{
if (!scrollRight(false))
{
break;
}
}
- while (x > hidden.adjustForHiddenColumns(endRes))
+ while (x > hidden.visibleToAbsoluteColumn(endRes))
{
if (!scrollRight(true))
{
boolean changedLocation = false;
// convert the x,y location to visible coordinates
- int visX = al.getHiddenColumns().findColumnPosition(x);
+ int visX = al.getHiddenColumns().absoluteToVisibleColumn(x);
int visY = al.getHiddenSequences().findIndexWithoutHiddenSeqs(y);
// if (vis_x,vis_y) is already visible don't do anything
{
private static final String NEWLINE = System.lineSeparator();
+ public static final String TRIM_RETRIEVED_SEQUENCES = "TRIM_FETCHED_DATASET_SEQS";
+
public interface FetchFinishedListenerI
{
void finished();
.getSequenceFetcherSingleton(progressIndicatorFrame);
// set default behaviour for transferring excess sequence data to the
// dataset
- trimDsSeqs = Cache.getDefault("TRIM_FETCHED_DATASET_SEQS", true);
+ trimDsSeqs = Cache.getDefault(TRIM_RETRIEVED_SEQUENCES, true);
if (sources == null)
{
setDatabaseSources(featureSettings, isNucleotide);
*/
package jalview.ws.dbsources;
+import jalview.bin.Cache;
import jalview.datamodel.DBRefSource;
import com.stevesoft.pat.Regex;
*/
abstract public class Pfam extends Xfam
{
+ static final String PFAM_BASEURL_KEY = "PFAM_BASEURL";
+
+ private static final String DEFAULT_PFAM_BASEURL = "https://pfam.xfam.org";
public Pfam()
{
@Override
public String getAccessionSeparator()
{
- // TODO Auto-generated method stub
return null;
}
@Override
public Regex getAccessionValidator()
{
- // TODO Auto-generated method stub
return null;
}
@Override
public String getDbVersion()
{
- // TODO Auto-generated method stub
return null;
}
- /**
- * Returns base URL for selected Pfam alignment type
- *
- * @return PFAM URL stub for this DbSource
- */
@Override
- protected abstract String getXFAMURL();
+ protected String getURLPrefix()
+ {
+ return Cache.getDefault(PFAM_BASEURL_KEY, DEFAULT_PFAM_BASEURL);
+ }
/*
* (non-Javadoc)
super();
}
- /*
- * (non-Javadoc)
- *
- * @see jalview.ws.dbsources.Pfam#getPFAMURL()
- */
- @Override
- protected String getXFAMURL()
- {
- return "http://pfam.xfam.org/family/";
-
- }
-
@Override
- public String getXFAMURLSUFFIX()
+ public String getURLSuffix()
{
return "/alignment/full";
}
super();
}
- /*
- * (non-Javadoc)
- *
- * @see jalview.ws.dbsources.Pfam#getPFAMURL()
- */
- @Override
- protected String getXFAMURL()
- {
- return "http://pfam.xfam.org/family/";
- }
-
@Override
- public String getXFAMURLSUFFIX()
+ public String getURLSuffix()
{
return "/alignment/seed";
}
*/
package jalview.ws.dbsources;
+import jalview.bin.Cache;
import jalview.datamodel.DBRefSource;
import com.stevesoft.pat.Regex;
*/
abstract public class Rfam extends Xfam
{
+ static final String RFAM_BASEURL_KEY = "RFAM_BASEURL";
+
+ private static final String DEFAULT_RFAM_BASEURL = "https://rfam.xfam.org";
+
+ @Override
+ protected String getURLPrefix()
+ {
+ return Cache.getDefault(RFAM_BASEURL_KEY, DEFAULT_RFAM_BASEURL);
+ }
public Rfam()
{
@Override
public String getAccessionSeparator()
{
- // TODO Auto-generated method stub
return null;
}
@Override
public Regex getAccessionValidator()
{
- // TODO Auto-generated method stub
return null;
}
@Override
public String getDbVersion()
{
- // TODO Auto-generated method stub
return null;
}
- /**
- * Returns base URL for selected Rfam alignment type
- *
- * @return RFAM URL stub for this DbSource
- */
- @Override
- protected abstract String getXFAMURL();
-
/*
* (non-Javadoc)
*
super();
}
- /*
- * (non-Javadoc)
- *
- * @see jalview.ws.dbsources.Rfam#getXFAMURL()
- */
- @Override
- protected String getXFAMURL()
- {
- return "http://rfam.xfam.org/family/";
-
- }
-
@Override
- public String getXFAMURLSUFFIX()
+ public String getURLSuffix()
{
return "/alignment/full";
}
super();
}
- /*
- * (non-Javadoc)
- *
- * @see jalview.ws.dbsources.Rfam#getRFAMURL()
- */
- @Override
- protected String getXFAMURL()
- {
- return "http://rfam.xfam.org/family/";
- }
-
@Override
- public String getXFAMURLSUFFIX()
+ public String getURLSuffix()
{
// to download gzipped file add '?gzip=1'
return "/alignment/stockholm";
*/
package jalview.ws.dbsources;
+import jalview.bin.Cache;
import jalview.datamodel.Alignment;
import jalview.datamodel.AlignmentI;
import jalview.datamodel.DBRefEntry;
*/
public class Uniprot extends DbSourceProxyImpl
{
+ private static final String DEFAULT_UNIPROT_DOMAIN = "https://www.uniprot.org";
+
private static final String BAR_DELIMITER = "|";
/*
super();
}
+ private String getDomain()
+ {
+ return Cache.getDefault("UNIPROT_DOMAIN", DEFAULT_UNIPROT_DOMAIN);
+ }
+
/*
* (non-Javadoc)
*
"(UNIPROT\\|?|UNIPROT_|UNIREF\\d+_|UNIREF\\d+\\|?)", "");
AlignmentI al = null;
- String downloadstring = "http://www.uniprot.org/uniprot/" + queries
+ String downloadstring = getDomain() + "/uniprot/" + queries
+ ".xml";
URL url = null;
URLConnection urlconn = null;
super();
}
- protected abstract String getXFAMURL();
+ /**
+ * the base URL for this Xfam-like service
+ *
+ * @return
+ */
+ protected abstract String getURLPrefix();
@Override
public abstract String getDbVersion();
// retrieved.
startQuery();
// TODO: trap HTTP 404 exceptions and return null
- String xfamUrl = getXFAMURL() + queries.trim().toUpperCase()
- + getXFAMURLSUFFIX();
+ String xfamUrl = getURL(queries);
if (Cache.log != null)
{
return rcds;
}
+ String getURL(String queries)
+ {
+ return getURLPrefix() + "/family/" + queries.trim().toUpperCase()
+ + getURLSuffix();
+ }
+
/**
* Pfam and Rfam provide alignments
*/
*
* @return "" for most Xfam sources
*/
- public String getXFAMURLSUFFIX()
+ public String getURLSuffix()
{
return "";
}
{
// Adjust input view for gaps
// propagate insertions into profile
- alhidden = HiddenColumns.propagateInsertions(profileseq, al,
- input);
+ alhidden = al.propagateInsertions(profileseq, input);
}
}
}
private CoordinateSys seqCoordSys = CoordinateSys.UNIPROT;
+ /**
+ * PDB sequence position to sequence coordinate mapping as derived from SIFTS
+ * record for the identified SeqCoordSys Used for lift-over from sequence
+ * derived from PDB (with first extracted PDBRESNUM as 'start' to the sequence
+ * being annotated with PDB data
+ */
+ private jalview.datamodel.Mapping seqFromPdbMapping;
+
private static final int BUFFER_SIZE = 4096;
- public static final int UNASSIGNED = -1;
+ public static final int UNASSIGNED = Integer.MIN_VALUE;
private static final int PDB_RES_POS = 0;
private static final int PDB_ATOM_POS = 1;
+ private static final int PDBE_POS = 2;
+
private static final String NOT_OBSERVED = "Not_Observed";
private static final String SIFTS_FTP_BASE_URL = "http://ftp.ebi.ac.uk/pub/databases/msd/sifts/xml/";
public StructureMapping getSiftsStructureMapping(SequenceI seq,
String pdbFile, String chain) throws SiftsException
{
+ SequenceI aseq = seq;
+ while (seq.getDatasetSequence() != null)
+ {
+ seq = seq.getDatasetSequence();
+ }
structId = (chain == null) ? pdbId : pdbId + "|" + chain;
System.out.println("Getting SIFTS mapping for " + structId + ": seq "
+ seq.getName());
HashMap<Integer, int[]> mapping = getGreedyMapping(chain, seq, ps);
String mappingOutput = mappingDetails.toString();
- StructureMapping siftsMapping = new StructureMapping(seq, pdbFile,
- pdbId, chain, mapping, mappingOutput);
+ StructureMapping siftsMapping = new StructureMapping(aseq, pdbFile,
+ pdbId, chain, mapping, mappingOutput, seqFromPdbMapping);
+
return siftsMapping;
}
public HashMap<Integer, int[]> getGreedyMapping(String entityId,
SequenceI seq, java.io.PrintStream os) throws SiftsException
{
- List<Integer> omitNonObserved = new ArrayList<Integer>();
- int nonObservedShiftIndex = 0;
+ List<Integer> omitNonObserved = new ArrayList<>();
+ int nonObservedShiftIndex = 0,pdbeNonObserved=0;
// System.out.println("Generating mappings for : " + entityId);
Entity entity = null;
entity = getEntityById(entityId);
TreeMap<Integer, String> resNumMap = new TreeMap<Integer, String>();
List<Segment> segments = entity.getSegment();
SegmentHelperPojo shp = new SegmentHelperPojo(seq, mapping, resNumMap,
- omitNonObserved, nonObservedShiftIndex);
+ omitNonObserved, nonObservedShiftIndex,pdbeNonObserved);
processSegments(segments, shp);
try
{
{
throw new SiftsException("SIFTS mapping failed");
}
+ // also construct a mapping object between the seq-coord sys and the PDB seq's coord sys
Integer[] keys = mapping.keySet().toArray(new Integer[0]);
Arrays.sort(keys);
seqStart = keys[0];
seqEnd = keys[keys.length - 1];
-
+ List<int[]> from=new ArrayList<>(),to=new ArrayList<>();
+ int[]_cfrom=null,_cto=null;
String matchedSeq = originalSeq;
- if (seqStart != UNASSIGNED)
+ if (seqStart != UNASSIGNED) // fixme! seqStart can map to -1 for a pdb sequence that starts <-1
{
+ for (int seqps:keys)
+ {
+ int pdbpos = mapping.get(seqps)[PDBE_POS];
+ if (pdbpos == UNASSIGNED)
+ {
+ // not correct - pdbpos might be -1, but leave it for now
+ continue;
+ }
+ if (_cfrom==null || seqps!=_cfrom[1]+1)
+ {
+ _cfrom = new int[] { seqps,seqps};
+ from.add(_cfrom);
+ _cto = null; // discontinuity
+ } else {
+ _cfrom[1]= seqps;
+ }
+ if (_cto==null || pdbpos!=1+_cto[1])
+ {
+ _cto = new int[] { pdbpos,pdbpos};
+ to.add(_cto);
+ } else {
+ _cto[1] = pdbpos;
+ }
+ }
+ _cfrom = new int[from.size() * 2];
+ _cto = new int[to.size() * 2];
+ int p = 0;
+ for (int[] range : from)
+ {
+ _cfrom[p++] = range[0];
+ _cfrom[p++] = range[1];
+ }
+ ;
+ p = 0;
+ for (int[] range : to)
+ {
+ _cto[p++] = range[0];
+ _cto[p++] = range[1];
+ }
+ ;
+
+ seqFromPdbMapping = new jalview.datamodel.Mapping(null, _cto, _cfrom,
+ 1,
+ 1);
pdbStart = mapping.get(seqStart)[PDB_RES_POS];
pdbEnd = mapping.get(seqEnd)[PDB_RES_POS];
int orignalSeqStart = seq.getStart();
TreeMap<Integer, String> resNumMap = shp.getResNumMap();
List<Integer> omitNonObserved = shp.getOmitNonObserved();
int nonObservedShiftIndex = shp.getNonObservedShiftIndex();
+ int pdbeNonObservedCount = shp.getPdbeNonObserved();
+ int firstPDBResNum = UNASSIGNED;
for (Segment segment : segments)
{
// System.out.println("Mapping segments : " + segment.getSegId() + "\\"s
List<Residue> residues = segment.getListResidue().getResidue();
for (Residue residue : residues)
{
+ boolean isObserved = isResidueObserved(residue);
+ int pdbeIndex = getLeadingIntegerValue(residue.getDbResNum(),
+ UNASSIGNED);
int currSeqIndex = UNASSIGNED;
List<CrossRefDb> cRefDbs = residue.getCrossRefDb();
CrossRefDb pdbRefDb = null;
if (cRefDb.getDbSource().equalsIgnoreCase(DBRefSource.PDB))
{
pdbRefDb = cRefDb;
+ if (firstPDBResNum == UNASSIGNED)
+ {
+ firstPDBResNum = getLeadingIntegerValue(cRefDb.getDbResNum(),
+ UNASSIGNED);
+ }
+ else
+ {
+ if (isObserved)
+ {
+ // after we find the first observed residue we just increment
+ firstPDBResNum++;
+ }
+ }
}
if (cRefDb.getDbCoordSys().equalsIgnoreCase(seqCoordSys.getName())
&& isAccessionMatched(cRefDb.getDbAccessionId()))
}
}
}
+ if (!isObserved)
+ {
+ ++pdbeNonObservedCount;
+ }
+ if (seqCoordSys == seqCoordSys.PDB) // FIXME: is seqCoordSys ever PDBe
+ // ???
+ {
+ // if the sequence has a primary reference to the PDB, then we are
+ // dealing with a sequence extracted directly from the PDB. In that
+ // case, numbering is PDBe - non-observed residues
+ currSeqIndex = seq.getStart() - 1 + pdbeIndex;
+ }
+ if (!isObserved)
+ {
+ if (seqCoordSys != CoordinateSys.UNIPROT) // FIXME: PDB or PDBe only
+ // here
+ {
+ // mapping to PDB or PDBe so we need to bookkeep for the
+ // non-observed
+ // SEQRES positions
+ omitNonObserved.add(currSeqIndex);
+ ++nonObservedShiftIndex;
+ }
+ }
if (currSeqIndex == UNASSIGNED)
{
+ // change in logic - unobserved residues with no currSeqIndex
+ // corresponding are still counted in both nonObservedShiftIndex and
+ // pdbeIndex...
continue;
}
- if (currSeqIndex >= seq.getStart() && currSeqIndex <= seq.getEnd())
+ // if (currSeqIndex >= seq.getStart() && currSeqIndex <= seqlength) //
+ // true
+ // numbering
+ // is
+ // not
+ // up
+ // to
+ // seq.getEnd()
{
int resNum = (pdbRefDb == null)
: getLeadingIntegerValue(pdbRefDb.getDbResNum(),
UNASSIGNED);
- if (isResidueObserved(residue)
- || seqCoordSys == CoordinateSys.UNIPROT)
+ if (isObserved)
{
char resCharCode = ResidueProperties
.getSingleCharacterCode(ResidueProperties
.getCanonicalAminoAcid(residue.getDbResName()));
resNumMap.put(currSeqIndex, String.valueOf(resCharCode));
+
+ int[] mappingcols = new int[] { Integer.valueOf(resNum),
+ UNASSIGNED, isObserved ? firstPDBResNum : UNASSIGNED };
+
+ mapping.put(currSeqIndex - nonObservedShiftIndex, mappingcols);
}
- else
- {
- omitNonObserved.add(currSeqIndex);
- ++nonObservedShiftIndex;
- }
- mapping.put(currSeqIndex - nonObservedShiftIndex,
- new int[]
- { Integer.valueOf(resNum), UNASSIGNED });
}
}
}
private int nonObservedShiftIndex;
+ /**
+ * count of number of 'not observed' positions in the PDB record's SEQRES
+ * (total number of residues with coordinates == length(SEQRES) -
+ * pdbeNonObserved
+ */
+ private int pdbeNonObserved;
+
public SegmentHelperPojo(SequenceI seq, HashMap<Integer, int[]> mapping,
TreeMap<Integer, String> resNumMap,
- List<Integer> omitNonObserved, int nonObservedShiftIndex)
+ List<Integer> omitNonObserved, int nonObservedShiftIndex,
+ int pdbeNonObserved)
{
setSeq(seq);
setMapping(mapping);
setResNumMap(resNumMap);
setOmitNonObserved(omitNonObserved);
setNonObservedShiftIndex(nonObservedShiftIndex);
+ setPdbeNonObserved(pdbeNonObserved);
+
}
+ public void setPdbeNonObserved(int pdbeNonObserved2)
+ {
+ this.pdbeNonObserved = pdbeNonObserved2;
+ }
+
+ public int getPdbeNonObserved()
+ {
+ return pdbeNonObserved;
+ }
public SequenceI getSeq()
{
return seq;
{
this.nonObservedShiftIndex = nonObservedShiftIndex;
}
+
}
@Override
import jalview.io.FileFormat;
import jalview.io.FileFormatI;
import jalview.io.FormatAdapter;
+import jalview.io.gff.SequenceOntologyI;
import jalview.util.MapList;
import jalview.util.MappingUtils;
List<DnaVariant> codon1Variants = new ArrayList<>();
List<DnaVariant> codon2Variants = new ArrayList<>();
List<DnaVariant> codon3Variants = new ArrayList<>();
+
List<DnaVariant> codonVariants[] = new ArrayList[3];
codonVariants[0] = codon1Variants;
codonVariants[1] = codon2Variants;
* 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 = new Sequence("dna", "AACGacgtCTCCTCCC");
dna.createDatasetSequence();
dna.addSequenceFeature(new SequenceFeature("CDS", "", 1, 4, null));
dna.addSequenceFeature(new SequenceFeature("CDS", "", 9, 16, null));
Arrays.deepToString(ml.getFromRanges().toArray()));
/*
- * Case 3: CDS not 3 times length of peptide - no mapping is made
+ * Case 3: CDS longer than 3 * peptide + stop codon - no mapping is made
+ */
+ dna = new Sequence("dna", "AACGacgtCTCCTTGATCA");
+ dna.createDatasetSequence();
+ dna.addSequenceFeature(new SequenceFeature("CDS", "", 1, 4, null));
+ dna.addSequenceFeature(new SequenceFeature("CDS", "", 9, 19, null));
+ ml = AlignmentUtils.mapCdsToProtein(dna, peptide);
+ assertNull(ml);
+
+ /*
+ * Case 4: CDS shorter than 3 * peptide - no mapping is made
+ */
+ dna = new Sequence("dna", "AACGacgtCTCC");
+ dna.createDatasetSequence();
+ dna.addSequenceFeature(new SequenceFeature("CDS", "", 1, 4, null));
+ dna.addSequenceFeature(new SequenceFeature("CDS", "", 9, 12, null));
+ ml = AlignmentUtils.mapCdsToProtein(dna, peptide);
+ assertNull(ml);
+
+ /*
+ * Case 5: CDS 3 times length of peptide + part codon - mapping is truncated
*/
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);
+ 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 4: incomplete start codon corresponding to X in peptide
+ * Case 6: incomplete start codon corresponding to X in peptide
*/
dna = new Sequence("dna", "ACGacgtCTCCTTGG");
dna.createDatasetSequence();
assertEquals("[[3, 3], [8, 12]]",
Arrays.deepToString(ml.getFromRanges().toArray()));
}
+
+ /**
+ * Tests for the method that locates the CDS sequence that has a mapping to
+ * the given protein. That is, given a transcript-to-peptide mapping, find the
+ * cds-to-peptide mapping that relates to both, and return the CDS sequence.
+ */
+ @Test
+ public void testFindCdsForProtein()
+ {
+ List<AlignedCodonFrame> mappings = new ArrayList<>();
+ AlignedCodonFrame acf1 = new AlignedCodonFrame();
+ mappings.add(acf1);
+
+ SequenceI dna1 = new Sequence("dna1", "cgatATcgGCTATCTATGacg");
+ dna1.createDatasetSequence();
+
+ // NB we currently exclude STOP codon from CDS sequences
+ // the test would need to change if this changes in future
+ SequenceI cds1 = new Sequence("cds1", "ATGCTATCT");
+ cds1.createDatasetSequence();
+
+ SequenceI pep1 = new Sequence("pep1", "MLS");
+ pep1.createDatasetSequence();
+ List<AlignedCodonFrame> seqMappings = new ArrayList<>();
+ MapList mapList = new MapList(
+ new int[]
+ { 5, 6, 9, 15 }, new int[] { 1, 3 }, 3, 1);
+ Mapping dnaToPeptide = new Mapping(pep1.getDatasetSequence(), mapList);
+
+ // add dna to peptide mapping
+ seqMappings.add(acf1);
+ acf1.addMap(dna1.getDatasetSequence(), pep1.getDatasetSequence(),
+ mapList);
+
+ /*
+ * first case - no dna-to-CDS mapping exists - search fails
+ */
+ SequenceI seq = AlignmentUtils.findCdsForProtein(mappings, dna1,
+ seqMappings, dnaToPeptide);
+ assertNull(seq);
+
+ /*
+ * second case - CDS-to-peptide mapping exists but no dna-to-CDS
+ * - search fails
+ */
+ // todo this test fails if the mapping is added to acf1, not acf2
+ // need to tidy up use of lists of mappings in AlignedCodonFrame
+ AlignedCodonFrame acf2 = new AlignedCodonFrame();
+ mappings.add(acf2);
+ MapList cdsToPeptideMapping = new MapList(new int[]
+ { 1, 9 }, new int[] { 1, 3 }, 3, 1);
+ acf2.addMap(cds1.getDatasetSequence(), pep1.getDatasetSequence(),
+ cdsToPeptideMapping);
+ assertNull(AlignmentUtils.findCdsForProtein(mappings, dna1, seqMappings,
+ dnaToPeptide));
+
+ /*
+ * third case - add dna-to-CDS mapping - CDS is now found!
+ */
+ MapList dnaToCdsMapping = new MapList(new int[] { 5, 6, 9, 15 },
+ new int[]
+ { 1, 9 }, 1, 1);
+ acf1.addMap(dna1.getDatasetSequence(), cds1.getDatasetSequence(),
+ dnaToCdsMapping);
+ seq = AlignmentUtils.findCdsForProtein(mappings, dna1, seqMappings,
+ dnaToPeptide);
+ assertSame(seq, cds1.getDatasetSequence());
+ }
+
+ /**
+ * Tests for the method that locates the CDS sequence that has a mapping to
+ * the given protein. That is, given a transcript-to-peptide mapping, find the
+ * cds-to-peptide mapping that relates to both, and return the CDS sequence.
+ * This test is for the case where transcript and CDS are the same length.
+ */
+ @Test
+ public void testFindCdsForProtein_noUTR()
+ {
+ List<AlignedCodonFrame> mappings = new ArrayList<>();
+ AlignedCodonFrame acf1 = new AlignedCodonFrame();
+ mappings.add(acf1);
+
+ SequenceI dna1 = new Sequence("dna1", "ATGCTATCTTAA");
+ dna1.createDatasetSequence();
+
+ // NB we currently exclude STOP codon from CDS sequences
+ // the test would need to change if this changes in future
+ SequenceI cds1 = new Sequence("cds1", "ATGCTATCT");
+ cds1.createDatasetSequence();
+
+ SequenceI pep1 = new Sequence("pep1", "MLS");
+ pep1.createDatasetSequence();
+ List<AlignedCodonFrame> seqMappings = new ArrayList<>();
+ MapList mapList = new MapList(
+ new int[]
+ { 1, 9 }, new int[] { 1, 3 }, 3, 1);
+ Mapping dnaToPeptide = new Mapping(pep1.getDatasetSequence(), mapList);
+
+ // add dna to peptide mapping
+ seqMappings.add(acf1);
+ acf1.addMap(dna1.getDatasetSequence(), pep1.getDatasetSequence(),
+ mapList);
+
+ /*
+ * first case - transcript lacks CDS features - it appears to be
+ * the CDS sequence and is returned
+ */
+ SequenceI seq = AlignmentUtils.findCdsForProtein(mappings, dna1,
+ seqMappings, dnaToPeptide);
+ assertSame(seq, dna1.getDatasetSequence());
+
+ /*
+ * second case - transcript has CDS feature - this means it is
+ * not returned as a match for CDS (CDS sequences don't have CDS features)
+ */
+ dna1.addSequenceFeature(
+ new SequenceFeature(SequenceOntologyI.CDS, "cds", 1, 12, null));
+ seq = AlignmentUtils.findCdsForProtein(mappings, dna1, seqMappings,
+ dnaToPeptide);
+ assertNull(seq);
+
+ /*
+ * third case - CDS-to-peptide mapping exists but no dna-to-CDS
+ * - search fails
+ */
+ // todo this test fails if the mapping is added to acf1, not acf2
+ // need to tidy up use of lists of mappings in AlignedCodonFrame
+ AlignedCodonFrame acf2 = new AlignedCodonFrame();
+ mappings.add(acf2);
+ MapList cdsToPeptideMapping = new MapList(new int[]
+ { 1, 9 }, new int[] { 1, 3 }, 3, 1);
+ acf2.addMap(cds1.getDatasetSequence(), pep1.getDatasetSequence(),
+ cdsToPeptideMapping);
+ assertNull(AlignmentUtils.findCdsForProtein(mappings, dna1, seqMappings,
+ dnaToPeptide));
+
+ /*
+ * fourth case - add dna-to-CDS mapping - CDS is now found!
+ */
+ MapList dnaToCdsMapping = new MapList(new int[] { 1, 9 },
+ new int[]
+ { 1, 9 }, 1, 1);
+ acf1.addMap(dna1.getDatasetSequence(), cds1.getDatasetSequence(),
+ dnaToCdsMapping);
+ seq = AlignmentUtils.findCdsForProtein(mappings, dna1, seqMappings,
+ dnaToPeptide);
+ assertSame(seq, cds1.getDatasetSequence());
+ }
}
import jalview.io.FormatAdapter;
import java.io.IOException;
+import java.util.Iterator;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
FileFormat.Fasta);
HiddenColumns cs = new HiddenColumns();
AlignViewportI av = new AlignViewport(alf, cs);
- Dna dna = new Dna(av, new int[] { 0, alf.getWidth() - 1 });
+ Iterator<int[]> contigs = cs.getVisContigsIterator(0, alf.getWidth(),
+ false);
+ Dna dna = new Dna(av, contigs);
AlignmentI translated = dna.translateCdna();
assertNotNull("Couldn't do a full width translation of test data.",
translated);
cs.hideColumns(0, ipos - 1);
}
cs.hideColumns(ipos + vwidth, alf.getWidth());
- int[] vcontigs = cs.getVisibleContigs(0, alf.getWidth());
+ Iterator<int[]> vcontigs = cs.getVisContigsIterator(0,
+ alf.getWidth(), false);
AlignViewportI av = new AlignViewport(alf, cs);
Dna dna = new Dna(av, vcontigs);
AlignmentI transAlf = dna.translateCdna();
DataSourceType.PASTE, FileFormat.Fasta);
HiddenColumns cs = new HiddenColumns();
AlignViewportI av = new AlignViewport(alf, cs);
- Dna dna = new Dna(av, new int[] { 0, alf.getWidth() - 1 });
+ Iterator<int[]> contigs = cs.getVisContigsIterator(0, alf.getWidth(),
+ false);
+ Dna dna = new Dna(av, contigs);
AlignmentI translated = dna.translateCdna();
String aa = translated.getSequenceAt(0).getSequenceAsString();
assertEquals(
cs.hideColumns(24, 35); // hide codons 9-12
cs.hideColumns(177, 191); // hide codons 60-64
AlignViewportI av = new AlignViewport(alf, cs);
- Dna dna = new Dna(av, new int[] { 0, alf.getWidth() - 1 });
+ Iterator<int[]> contigs = cs.getVisContigsIterator(0, alf.getWidth(),
+ false);
+ Dna dna = new Dna(av, contigs);
AlignmentI translated = dna.translateCdna();
String aa = translated.getSequenceAt(0).getSequenceAsString();
assertEquals("AACDDGGGGHHIIIKKLLLLLLMNNPPPPQQRRRRRRSSSSSSTTTTVVVVW", aa);
.generate(12, 8, 97, 5, 5);
HiddenColumns cs = new HiddenColumns();
AlignViewportI av = new AlignViewport(cdna, cs);
- Dna dna = new Dna(av, new int[] { 0, cdna.getWidth() - 1 });
+ Iterator<int[]> contigs = cs.getVisContigsIterator(0, cdna.getWidth(),
+ false);
+ Dna dna = new Dna(av, contigs);
AlignmentI translated = dna.translateCdna();
/*
}
AlignmentI cdnaReordered = new Alignment(sorted);
av = new AlignViewport(cdnaReordered, cs);
- dna = new Dna(av, new int[] { 0, cdna.getWidth() - 1 });
+ contigs = cs.getVisContigsIterator(0, cdna.getWidth(), false);
+ dna = new Dna(av, contigs);
AlignmentI translated2 = dna.translateCdna();
/*
HiddenColumns cs = new HiddenColumns();
AlignViewportI av = new AlignViewport(al, cs);
- Dna testee = new Dna(av, new int[] { 0, al.getWidth() - 1 });
+ Iterator<int[]> contigs = cs.getVisContigsIterator(0, al.getWidth(),
+ false);
+ Dna testee = new Dna(av, contigs);
AlignmentI reversed = testee.reverseCdna(false);
assertEquals(1, reversed.getHeight());
assertEquals(seqRev, reversed.getSequenceAt(0).getSequenceAsString());
*/
package jalview.datamodel;
+import static org.testng.Assert.assertNull;
import static org.testng.AssertJUnit.assertEquals;
-import static org.testng.AssertJUnit.assertNull;
import jalview.analysis.AlignSeq;
import jalview.gui.JvOptionPane;
Assert.assertTrue(ann.isQuantitative(),
"Mixed 'E' annotation set should be quantitative.");
}
+
+ @Test(groups = "Functional")
+ public void testMakeVisibleAnnotation()
+ {
+ HiddenColumns h = new HiddenColumns();
+ Annotation[] anns = new Annotation[] { null, null, new Annotation(1),
+ new Annotation(2), new Annotation(3), null, null, new Annotation(4),
+ new Annotation(5), new Annotation(6), new Annotation(7),
+ new Annotation(8) };
+ AlignmentAnnotation ann = new AlignmentAnnotation("an", "some an",
+ anns);
+
+ // null annotations
+ AlignmentAnnotation emptyann = new AlignmentAnnotation("an", "some ann",
+ null);
+ emptyann.makeVisibleAnnotation(h);
+ assertNull(emptyann.annotations);
+
+ emptyann.makeVisibleAnnotation(3, 4, h);
+ assertNull(emptyann.annotations);
+
+ // without bounds, does everything
+ ann.makeVisibleAnnotation(h);
+ assertEquals(12, ann.annotations.length);
+ assertNull(ann.annotations[0]);
+ assertNull(ann.annotations[1]);
+ assertEquals(1.0f, ann.annotations[2].value);
+ assertEquals(2.0f, ann.annotations[3].value);
+ assertEquals(3.0f, ann.annotations[4].value);
+ assertNull(ann.annotations[5]);
+ assertNull(ann.annotations[6]);
+ assertEquals(4.0f, ann.annotations[7].value);
+ assertEquals(5.0f, ann.annotations[8].value);
+ assertEquals(6.0f, ann.annotations[9].value);
+ assertEquals(7.0f, ann.annotations[10].value);
+ assertEquals(8.0f, ann.annotations[11].value);
+
+ // without hidden cols, just truncates
+ ann.makeVisibleAnnotation(3, 5, h);
+ assertEquals(3, ann.annotations.length);
+ assertEquals(2.0f, ann.annotations[0].value);
+ assertEquals(3.0f, ann.annotations[1].value);
+ assertNull(ann.annotations[2]);
+
+ anns = new Annotation[] { null, null, new Annotation(1),
+ new Annotation(2), new Annotation(3), null, null, new Annotation(4),
+ new Annotation(5), new Annotation(6), new Annotation(7),
+ new Annotation(8) };
+ ann = new AlignmentAnnotation("an", "some an", anns);
+ h.hideColumns(4, 7);
+ ann.makeVisibleAnnotation(1, 9, h);
+ assertEquals(5, ann.annotations.length);
+ assertNull(ann.annotations[0]);
+ assertEquals(1.0f, ann.annotations[1].value);
+ assertEquals(2.0f, ann.annotations[2].value);
+ assertEquals(5.0f, ann.annotations[3].value);
+ assertEquals(6.0f, ann.annotations[4].value);
+
+ anns = new Annotation[] { null, null, new Annotation(1),
+ new Annotation(2), new Annotation(3), null, null, new Annotation(4),
+ new Annotation(5), new Annotation(6), new Annotation(7),
+ new Annotation(8) };
+ ann = new AlignmentAnnotation("an", "some an", anns);
+ h.hideColumns(1, 2);
+ ann.makeVisibleAnnotation(1, 9, h);
+ assertEquals(3, ann.annotations.length);
+ assertEquals(2.0f, ann.annotations[0].value);
+ assertEquals(5.0f, ann.annotations[1].value);
+ assertEquals(6.0f, ann.annotations[2].value);
+
+ anns = new Annotation[] { null, null, new Annotation(1),
+ new Annotation(2), new Annotation(3), null, null, new Annotation(4),
+ new Annotation(5), new Annotation(6), new Annotation(7),
+ new Annotation(8), new Annotation(9), new Annotation(10),
+ new Annotation(11), new Annotation(12), new Annotation(13),
+ new Annotation(14), new Annotation(15) };
+ ann = new AlignmentAnnotation("an", "some an", anns);
+ h = new HiddenColumns();
+ h.hideColumns(5, 18);
+ h.hideColumns(20, 21);
+ ann.makeVisibleAnnotation(1, 21, h);
+ assertEquals(5, ann.annotations.length);
+ assertEquals(1.0f, ann.annotations[1].value);
+ assertEquals(2.0f, ann.annotations[2].value);
+ assertEquals(3.0f, ann.annotations[3].value);
+ assertNull(ann.annotations[0]);
+ assertNull(ann.annotations[4]);
+ }
}
import jalview.io.FileFormat;
import jalview.io.FileFormatI;
import jalview.io.FormatAdapter;
+import jalview.util.Comparison;
import jalview.util.MapList;
import java.io.IOException;
// third found.. so
assertFalse(iter.hasNext());
+ // search for annotation on one sequence with a particular label - expect
+ // one
+ SequenceI sqfound;
+ anns = al.findAnnotations(sqfound = al.getSequenceAt(1), null,
+ "Secondary Structure");
+ iter = anns.iterator();
+ assertTrue(iter.hasNext());
+ // expect reference to sequence 1 in the alignment
+ assertTrue(sqfound == iter.next().sequenceRef);
+ assertFalse(iter.hasNext());
+
// null on all parameters == find all annotations
anns = al.findAnnotations(null, null, null);
iter = anns.iterator();
// todo test coverage for annotations, mappings, groups,
// hidden sequences, properties
}
+
+ /**
+ * test that calcId == null on findOrCreate doesn't raise an NPE, and yields
+ * an annotation with a null calcId
+ *
+ */
+ @Test(groups = "Functional")
+ public void testFindOrCreateForNullCalcId()
+ {
+ SequenceI seq = new Sequence("seq1", "FRMLPSRT-A--L-");
+ AlignmentI alignment = new Alignment(new SequenceI[] { seq });
+
+ AlignmentAnnotation ala = alignment.findOrCreateAnnotation(
+ "Temperature Factor", null, false, seq, null);
+ assertNotNull(ala);
+ assertEquals(seq, ala.sequenceRef);
+ assertEquals("", ala.getCalcId());
+ }
+
+ @Test(groups = "Functional")
+ public void testPropagateInsertions()
+ {
+ // create an alignment with no gaps - this will be the profile seq and other
+ // JPRED seqs
+ AlignmentGenerator gen = new AlignmentGenerator(false);
+ AlignmentI al = gen.generate(25, 10, 1234, 0, 0);
+
+ // get the profileseq
+ SequenceI profileseq = al.getSequenceAt(0);
+ SequenceI gappedseq = new Sequence(profileseq);
+ gappedseq.insertCharAt(5, al.getGapCharacter());
+ gappedseq.insertCharAt(6, al.getGapCharacter());
+ gappedseq.insertCharAt(7, al.getGapCharacter());
+ gappedseq.insertCharAt(8, al.getGapCharacter());
+
+ // force different kinds of padding
+ al.getSequenceAt(3).deleteChars(2, 23);
+ al.getSequenceAt(4).deleteChars(2, 27);
+ al.getSequenceAt(5).deleteChars(10, 27);
+
+ // create an alignment view with the gapped sequence
+ SequenceI[] seqs = new SequenceI[1];
+ seqs[0] = gappedseq;
+ AlignmentI newal = new Alignment(seqs);
+ HiddenColumns hidden = new HiddenColumns();
+ hidden.hideColumns(15, 17);
+
+ AlignmentView view = new AlignmentView(newal, hidden, null, true, false,
+ false);
+
+ // confirm that original contigs are as expected
+ Iterator<int[]> visible = hidden.getVisContigsIterator(0, 25, false);
+ int[] region = visible.next();
+ assertEquals("[0, 14]", Arrays.toString(region));
+ region = visible.next();
+ assertEquals("[18, 24]", Arrays.toString(region));
+
+ // propagate insertions
+ HiddenColumns result = al.propagateInsertions(profileseq, view);
+
+ // confirm that the contigs have changed to account for the gaps
+ visible = result.getVisContigsIterator(0, 25, false);
+ region = visible.next();
+ assertEquals("[0, 10]", Arrays.toString(region));
+ region = visible.next();
+ assertEquals("[14, 24]", Arrays.toString(region));
+
+ // confirm the alignment has been changed so that the other sequences have
+ // gaps inserted where the columns are hidden
+ assertFalse(Comparison.isGap(al.getSequenceAt(1).getSequence()[10]));
+ assertTrue(Comparison.isGap(al.getSequenceAt(1).getSequence()[11]));
+ assertTrue(Comparison.isGap(al.getSequenceAt(1).getSequence()[12]));
+ assertTrue(Comparison.isGap(al.getSequenceAt(1).getSequence()[13]));
+ assertFalse(Comparison.isGap(al.getSequenceAt(1).getSequence()[14]));
+
+ }
+
+ @Test(groups = "Functional")
+ public void testPropagateInsertionsOverlap()
+ {
+ // test propagateInsertions where gaps and hiddenColumns overlap
+
+ // create an alignment with no gaps - this will be the profile seq and other
+ // JPRED seqs
+ AlignmentGenerator gen = new AlignmentGenerator(false);
+ AlignmentI al = gen.generate(20, 10, 1234, 0, 0);
+
+ // get the profileseq
+ SequenceI profileseq = al.getSequenceAt(0);
+ SequenceI gappedseq = new Sequence(profileseq);
+ gappedseq.insertCharAt(5, al.getGapCharacter());
+ gappedseq.insertCharAt(6, al.getGapCharacter());
+ gappedseq.insertCharAt(7, al.getGapCharacter());
+ gappedseq.insertCharAt(8, al.getGapCharacter());
+
+ // create an alignment view with the gapped sequence
+ SequenceI[] seqs = new SequenceI[1];
+ seqs[0] = gappedseq;
+ AlignmentI newal = new Alignment(seqs);
+
+ // hide columns so that some overlap with the gaps
+ HiddenColumns hidden = new HiddenColumns();
+ hidden.hideColumns(7, 10);
+
+ AlignmentView view = new AlignmentView(newal, hidden, null, true, false,
+ false);
+
+ // confirm that original contigs are as expected
+ Iterator<int[]> visible = hidden.getVisContigsIterator(0, 20, false);
+ int[] region = visible.next();
+ assertEquals("[0, 6]", Arrays.toString(region));
+ region = visible.next();
+ assertEquals("[11, 19]", Arrays.toString(region));
+ assertFalse(visible.hasNext());
+
+ // propagate insertions
+ HiddenColumns result = al.propagateInsertions(profileseq, view);
+
+ // confirm that the contigs have changed to account for the gaps
+ visible = result.getVisContigsIterator(0, 20, false);
+ region = visible.next();
+ assertEquals("[0, 4]", Arrays.toString(region));
+ region = visible.next();
+ assertEquals("[7, 19]", Arrays.toString(region));
+ assertFalse(visible.hasNext());
+
+ // confirm the alignment has been changed so that the other sequences have
+ // gaps inserted where the columns are hidden
+ assertFalse(Comparison.isGap(al.getSequenceAt(1).getSequence()[4]));
+ assertTrue(Comparison.isGap(al.getSequenceAt(1).getSequence()[5]));
+ assertTrue(Comparison.isGap(al.getSequenceAt(1).getSequence()[6]));
+ assertFalse(Comparison.isGap(al.getSequenceAt(1).getSequence()[7]));
+ }
+
+ @Test(groups = { "Functional" })
+ public void testPadGaps()
+ {
+ SequenceI seq1 = new Sequence("seq1", "ABCDEF--");
+ SequenceI seq2 = new Sequence("seq2", "-JKLMNO--");
+ SequenceI seq3 = new Sequence("seq2", "-PQR");
+ AlignmentI a = new Alignment(new SequenceI[] { seq1, seq2, seq3 });
+ a.setGapCharacter('.'); // this replaces existing gaps
+ assertEquals("ABCDEF..", seq1.getSequenceAsString());
+ a.padGaps();
+ // trailing gaps are pruned, short sequences padded with gap character
+ assertEquals("ABCDEF.", seq1.getSequenceAsString());
+ assertEquals(".JKLMNO", seq2.getSequenceAsString());
+ assertEquals(".PQR...", seq3.getSequenceAsString());
+ }
}
import java.util.BitSet;
import java.util.Collections;
import java.util.ConcurrentModificationException;
+import java.util.Iterator;
import java.util.List;
import org.testng.annotations.BeforeClass;
// hide column 5 (and adjacent):
cs.hideSelectedColumns(5, al.getHiddenColumns());
// 4,5,6 now hidden:
- List<int[]> hidden = al.getHiddenColumns().getHiddenColumnsCopy();
- assertEquals(1, hidden.size());
- assertEquals("[4, 6]", Arrays.toString(hidden.get(0)));
+ Iterator<int[]> regions = al.getHiddenColumns().iterator();
+ assertEquals(1, al.getHiddenColumns().getNumberOfRegions());
+ assertEquals("[4, 6]", Arrays.toString(regions.next()));
// none now selected:
assertTrue(cs.getSelected().isEmpty());
cs.addElement(5);
cs.addElement(6);
cs.hideSelectedColumns(4, al.getHiddenColumns());
- hidden = al.getHiddenColumns().getHiddenColumnsCopy();
- assertEquals(1, hidden.size());
- assertEquals("[4, 6]", Arrays.toString(hidden.get(0)));
+ regions = al.getHiddenColumns().iterator();
+ assertEquals(1, al.getHiddenColumns().getNumberOfRegions());
+ assertEquals("[4, 6]", Arrays.toString(regions.next()));
assertTrue(cs.getSelected().isEmpty());
// repeat, hiding column (4, 5 and) 6
cs.addElement(5);
cs.addElement(6);
cs.hideSelectedColumns(6, al.getHiddenColumns());
- hidden = al.getHiddenColumns().getHiddenColumnsCopy();
- assertEquals(1, hidden.size());
- assertEquals("[4, 6]", Arrays.toString(hidden.get(0)));
+ regions = al.getHiddenColumns().iterator();
+ assertEquals(1, al.getHiddenColumns().getNumberOfRegions());
+ assertEquals("[4, 6]", Arrays.toString(regions.next()));
assertTrue(cs.getSelected().isEmpty());
// repeat, with _only_ adjacent columns selected
cs.addElement(4);
cs.addElement(6);
cs.hideSelectedColumns(5, al.getHiddenColumns());
- hidden = al.getHiddenColumns().getHiddenColumnsCopy();
- assertEquals(1, hidden.size());
- assertEquals("[4, 6]", Arrays.toString(hidden.get(0)));
+ regions = al.getHiddenColumns().iterator();
+ assertEquals(1, al.getHiddenColumns().getNumberOfRegions());
+ assertEquals("[4, 6]", Arrays.toString(regions.next()));
assertTrue(cs.getSelected().isEmpty());
}
cs.hideSelectedColumns(al);
assertTrue(cs.getSelected().isEmpty());
- List<int[]> hidden = cols.getHiddenColumnsCopy();
- assertEquals(4, hidden.size());
- assertEquals("[2, 4]", Arrays.toString(hidden.get(0)));
- assertEquals("[7, 9]", Arrays.toString(hidden.get(1)));
- assertEquals("[15, 18]", Arrays.toString(hidden.get(2)));
- assertEquals("[20, 22]", Arrays.toString(hidden.get(3)));
+ Iterator<int[]> regions = cols.iterator();
+ assertEquals(4, cols.getNumberOfRegions());
+ assertEquals("[2, 4]", Arrays.toString(regions.next()));
+ assertEquals("[7, 9]", Arrays.toString(regions.next()));
+ assertEquals("[15, 18]", Arrays.toString(regions.next()));
+ assertEquals("[20, 22]", Arrays.toString(regions.next()));
}
/**
--- /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.assertNull;
+import static org.testng.AssertJUnit.assertEquals;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.testng.annotations.Test;
+
+public class HiddenColumnsCursorTest
+{
+
+ @Test(groups = { "Functional" })
+ public void testConstructor()
+ {
+ HiddenColumnsCursor cursor = new HiddenColumnsCursor();
+ assertNull(cursor.findRegionForColumn(0, false));
+
+ List<int[]> hlist = new ArrayList<>();
+ cursor = new HiddenColumnsCursor(hlist);
+ assertNull(cursor.findRegionForColumn(0, false));
+
+ cursor = new HiddenColumnsCursor(hlist, 3, 12);
+ assertNull(cursor.findRegionForColumn(0, false));
+
+ hlist.add(new int[] { 3, 7 });
+ hlist.add(new int[] { 15, 25 });
+ cursor = new HiddenColumnsCursor(hlist);
+ HiddenCursorPosition p = cursor.findRegionForColumn(8, false);
+ assertEquals(1, p.getRegionIndex());
+
+ cursor = new HiddenColumnsCursor(hlist, 1, 5);
+ p = cursor.findRegionForColumn(8, false);
+ assertEquals(1, p.getRegionIndex());
+ }
+
+ /**
+ * Test the method which finds the corresponding region given a column
+ */
+ @Test(groups = { "Functional" })
+ public void testFindRegionForColumn()
+ {
+ HiddenColumnsCursor cursor = new HiddenColumnsCursor();
+
+ HiddenCursorPosition pos = cursor.findRegionForColumn(20, false);
+ assertNull(pos);
+
+ List<int[]> hidden = new ArrayList<>();
+ hidden.add(new int[] { 53, 76 });
+ hidden.add(new int[] { 104, 125 });
+
+ cursor = new HiddenColumnsCursor(hidden);
+
+ int regionIndex = cursor.findRegionForColumn(126, false).getRegionIndex();
+ assertEquals(2, regionIndex);
+
+ regionIndex = cursor.findRegionForColumn(125, false).getRegionIndex();
+ assertEquals(1, regionIndex);
+
+ regionIndex = cursor.findRegionForColumn(108, false).getRegionIndex();
+ assertEquals(1, regionIndex);
+
+ regionIndex = cursor.findRegionForColumn(104, false).getRegionIndex();
+ assertEquals(1, regionIndex);
+
+ regionIndex = cursor.findRegionForColumn(103, false).getRegionIndex();
+ assertEquals(1, regionIndex);
+
+ regionIndex = cursor.findRegionForColumn(77, false).getRegionIndex();
+ assertEquals(1, regionIndex);
+
+ regionIndex = cursor.findRegionForColumn(76, false).getRegionIndex();
+ assertEquals(0, regionIndex);
+
+ regionIndex = cursor.findRegionForColumn(53, false).getRegionIndex();
+ assertEquals(0, regionIndex);
+
+ regionIndex = cursor.findRegionForColumn(52, false).getRegionIndex();
+ assertEquals(0, regionIndex);
+
+ regionIndex = cursor.findRegionForColumn(0, false).getRegionIndex();
+ assertEquals(0, regionIndex);
+
+ hidden.add(new int[] { 138, 155 });
+
+ cursor = new HiddenColumnsCursor(hidden);
+
+ regionIndex = cursor.findRegionForColumn(160, false).getRegionIndex();
+ assertEquals(3, regionIndex);
+
+ regionIndex = cursor.findRegionForColumn(100, false).getRegionIndex();
+ assertEquals(1, regionIndex);
+ }
+
+ /**
+ * Test the method which counts the number of hidden columns before a column
+ */
+ @Test(groups = { "Functional" })
+ public void testFindRegionForColumn_Visible()
+ {
+ HiddenColumnsCursor cursor = new HiddenColumnsCursor();
+
+ HiddenCursorPosition pos = cursor.findRegionForColumn(20, true);
+ assertNull(pos);
+
+ List<int[]> hidden = new ArrayList<>();
+ hidden.add(new int[] { 53, 76 });
+ hidden.add(new int[] { 104, 125 });
+
+ cursor = new HiddenColumnsCursor(hidden);
+
+ int offset = cursor.findRegionForColumn(80, true).getHiddenSoFar();
+ assertEquals(46, offset);
+
+ offset = cursor.findRegionForColumn(79, true).getHiddenSoFar();
+ assertEquals(24, offset);
+
+ offset = cursor.findRegionForColumn(53, true).getHiddenSoFar();
+ assertEquals(24, offset);
+
+ offset = cursor.findRegionForColumn(52, true).getHiddenSoFar();
+ assertEquals(0, offset);
+
+ offset = cursor.findRegionForColumn(10, true).getHiddenSoFar();
+ assertEquals(0, offset);
+
+ offset = cursor.findRegionForColumn(0, true).getHiddenSoFar();
+ assertEquals(0, offset);
+
+ offset = cursor.findRegionForColumn(79, true).getHiddenSoFar();
+ assertEquals(24, offset);
+
+ offset = cursor.findRegionForColumn(80, true).getHiddenSoFar();
+ assertEquals(46, offset);
+ }
+}
import static org.testng.AssertJUnit.assertTrue;
import jalview.analysis.AlignmentGenerator;
-import jalview.gui.JvOptionPane;
import java.util.Arrays;
import java.util.BitSet;
-import java.util.List;
-import java.util.Random;
+import java.util.Iterator;
-import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
public class HiddenColumnsTest
{
-
- @BeforeClass(alwaysRun = true)
- public void setUpJvOptionPane()
- {
- JvOptionPane.setInteractiveMode(false);
- JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
- }
-
/**
* Test the method which counts the number of hidden columns
*/
public void testFindColumnPosition()
{
HiddenColumns cs = new HiddenColumns();
- assertEquals(5, cs.findColumnPosition(5));
+ assertEquals(5, cs.absoluteToVisibleColumn(5));
// hiding column 6 makes no difference
cs.hideColumns(6, 6);
- assertEquals(5, cs.findColumnPosition(5));
+ assertEquals(5, cs.absoluteToVisibleColumn(5));
// hiding column 4 moves column 5 to column 4
cs.hideColumns(4, 4);
- assertEquals(4, cs.findColumnPosition(5));
+ assertEquals(4, cs.absoluteToVisibleColumn(5));
// hiding column 4 moves column 4 to position 3
- assertEquals(3, cs.findColumnPosition(4));
+ assertEquals(3, cs.absoluteToVisibleColumn(4));
// hiding columns 1 and 2 moves column 5 to column 2
cs.hideColumns(1, 2);
- assertEquals(2, cs.findColumnPosition(5));
+ assertEquals(2, cs.absoluteToVisibleColumn(5));
// check with > 1 hidden column regions
// where some columns are in the hidden regions
cs2.hideColumns(40, 44);
// hiding columns 5-10 and 20-27 moves column 8 to column 4
- assertEquals(4, cs2.findColumnPosition(8));
+ assertEquals(4, cs2.absoluteToVisibleColumn(8));
// and moves column 24 to 13
- assertEquals(13, cs2.findColumnPosition(24));
+ assertEquals(13, cs2.absoluteToVisibleColumn(24));
// and moves column 28 to 14
- assertEquals(14, cs2.findColumnPosition(28));
+ assertEquals(14, cs2.absoluteToVisibleColumn(28));
// and moves column 40 to 25
- assertEquals(25, cs2.findColumnPosition(40));
+ assertEquals(25, cs2.absoluteToVisibleColumn(40));
// check when hidden columns start at 0 that the visible column
// is returned as 0
HiddenColumns cs3 = new HiddenColumns();
cs3.hideColumns(0, 4);
- assertEquals(0, cs3.findColumnPosition(2));
+ assertEquals(0, cs3.absoluteToVisibleColumn(2));
+ // check that column after the last hidden region doesn't crash
+ assertEquals(46, cs2.absoluteToVisibleColumn(65));
}
- /**
- * Test the method that finds the visible column position a given distance
- * before another column
- */
@Test(groups = { "Functional" })
- public void testFindColumnNToLeft()
+ public void testVisibleContigsIterator()
{
HiddenColumns cs = new HiddenColumns();
- // test that without hidden columns, findColumnNToLeft returns
- // position n to left of provided position
- int pos = cs.subtractVisibleColumns(3, 10);
- assertEquals(7, pos);
-
- // 0 returns same position
- pos = cs.subtractVisibleColumns(0, 10);
- assertEquals(10, pos);
-
- // overflow to left returns negative number
- pos = cs.subtractVisibleColumns(3, 0);
- assertEquals(-3, pos);
-
- // test that with hidden columns to left of result column
- // behaviour is the same as above
- cs.hideColumns(1, 3);
-
- // position n to left of provided position
- pos = cs.subtractVisibleColumns(3, 10);
- assertEquals(7, pos);
-
- // 0 returns same position
- pos = cs.subtractVisibleColumns(0, 10);
- assertEquals(10, pos);
-
- // test with one set of hidden columns between start and required position
- cs.hideColumns(12, 15);
- pos = cs.subtractVisibleColumns(8, 17);
- assertEquals(5, pos);
-
- // test with two sets of hidden columns between start and required position
- cs.hideColumns(20, 21);
- pos = cs.subtractVisibleColumns(8, 23);
- assertEquals(9, pos);
-
- // repeat last 2 tests with no hidden columns to left of required position
- ColumnSelection colsel = new ColumnSelection();
- cs.revealAllHiddenColumns(colsel);
-
- // test with one set of hidden columns between start and required position
- cs.hideColumns(12, 15);
- pos = cs.subtractVisibleColumns(8, 17);
- assertEquals(5, pos);
-
- // test with two sets of hidden columns between start and required position
- cs.hideColumns(20, 21);
- pos = cs.subtractVisibleColumns(8, 23);
- assertEquals(9, pos);
-
- }
+ Iterator<int[]> visible = cs.getVisContigsIterator(3, 10, false);
+ int[] region = visible.next();
+ assertEquals("[3, 9]", Arrays.toString(region));
+ assertFalse(visible.hasNext());
- @Test(groups = { "Functional" })
- public void testGetVisibleContigs()
- {
- HiddenColumns cs = new HiddenColumns();
cs.hideColumns(3, 6);
cs.hideColumns(8, 9);
cs.hideColumns(12, 12);
- // start position is inclusive, end position exclusive:
- int[] visible = cs.getVisibleContigs(1, 13);
- assertEquals("[1, 2, 7, 7, 10, 11]", Arrays.toString(visible));
-
- visible = cs.getVisibleContigs(4, 14);
- assertEquals("[7, 7, 10, 11, 13, 13]", Arrays.toString(visible));
-
- visible = cs.getVisibleContigs(3, 10);
- assertEquals("[7, 7]", Arrays.toString(visible));
-
- visible = cs.getVisibleContigs(4, 6);
- assertEquals("[]", Arrays.toString(visible));
+ // Test both ends visible region
+
+ // start position is inclusive, end position exclusive
+ visible = cs.getVisContigsIterator(1, 13, false);
+ region = visible.next();
+ assertEquals("[1, 2]", Arrays.toString(region));
+ region = visible.next();
+ assertEquals("[7, 7]", Arrays.toString(region));
+ region = visible.next();
+ assertEquals("[10, 11]", Arrays.toString(region));
+ assertFalse(visible.hasNext());
+
+ // Test start hidden, end visible
+ visible = cs.getVisContigsIterator(4, 14, false);
+ region = visible.next();
+ assertEquals("[7, 7]", Arrays.toString(region));
+ region = visible.next();
+ assertEquals("[10, 11]", Arrays.toString(region));
+ region = visible.next();
+ assertEquals("[13, 13]", Arrays.toString(region));
+ assertFalse(visible.hasNext());
+
+ // Test start hidden, end hidden
+ visible = cs.getVisContigsIterator(3, 10, false);
+ region = visible.next();
+ assertEquals("[7, 7]", Arrays.toString(region));
+ assertFalse(visible.hasNext());
+
+ // Test start visible, end hidden
+ visible = cs.getVisContigsIterator(0, 13, false);
+ region = visible.next();
+ assertEquals("[0, 2]", Arrays.toString(region));
+ region = visible.next();
+ assertEquals("[7, 7]", Arrays.toString(region));
+ region = visible.next();
+ assertEquals("[10, 11]", Arrays.toString(region));
+ assertFalse(visible.hasNext());
+
+ // Test empty result
+ visible = cs.getVisContigsIterator(4, 6, false);
+ assertFalse(visible.hasNext());
}
@Test(groups = { "Functional" })
assertFalse(cs.equals(cs2));
assertFalse(cs2.equals(cs));
+ // with the wrong kind of object
+ assertFalse(cs.equals(new HiddenColumnsCursor()));
+
+ // with a different hiddenColumns object - by size
+ HiddenColumns cs3 = new HiddenColumns();
+ cs3.hideColumns(2, 3);
+ assertFalse(cs.equals(cs3));
+
// with hidden columns added in a different order
cs2.hideColumns(6, 9);
+ assertFalse(cs.equals(cs2));
+ assertFalse(cs2.equals(cs));
+
cs2.hideColumns(5, 8);
assertTrue(cs.equals(cs2));
assertTrue(cs.equals(cs));
assertTrue(cs2.equals(cs));
assertTrue(cs2.equals(cs2));
+
+ // different ranges, same size
+ cs.hideColumns(10, 12);
+ cs2.hideColumns(10, 15);
+ assertFalse(cs.equals(cs2));
+
}
@Test(groups = "Functional")
HiddenColumns cs = new HiddenColumns();
cs.hideColumns(10, 11);
cs.hideColumns(5, 7);
+ Iterator<int[]> regions = cs.iterator();
assertEquals("[5, 7]",
- Arrays.toString(cs.getHiddenColumnsCopy().get(0)));
+ Arrays.toString(regions.next()));
HiddenColumns cs2 = new HiddenColumns(cs);
+ regions = cs2.iterator();
assertTrue(cs2.hasHiddenColumns());
- assertEquals(2, cs2.getHiddenColumnsCopy().size());
+ assertEquals(2, cs2.getNumberOfRegions());
// hidden columns are held in column order
assertEquals("[5, 7]",
- Arrays.toString(cs2.getHiddenColumnsCopy().get(0)));
+ Arrays.toString(regions.next()));
assertEquals("[10, 11]",
- Arrays.toString(cs2.getHiddenColumnsCopy().get(1)));
+ Arrays.toString(regions.next()));
}
- /**
- * Test the code used to locate the reference sequence ruler origin
- */
- @Test(groups = { "Functional" })
- public void testLocateVisibleBoundsofSequence()
+ @Test(groups = "Functional")
+ public void testCopyConstructor2()
{
- // create random alignment
- AlignmentGenerator gen = new AlignmentGenerator(false);
- AlignmentI al = gen.generate(50, 20, 123, 5, 5);
+ HiddenColumns cs = new HiddenColumns();
+ cs.hideColumns(10, 11);
+ cs.hideColumns(5, 7);
- HiddenColumns cs = al.getHiddenColumns();
- ColumnSelection colsel = new ColumnSelection();
+ HiddenColumns cs2 = new HiddenColumns(cs, 3, 9, 1);
+ assertTrue(cs2.hasHiddenColumns());
+ Iterator<int[]> regions = cs2.iterator();
- SequenceI seq = new Sequence("RefSeq", "-A-SD-ASD--E---");
- assertEquals(2, seq.findIndex(seq.getStart()));
-
- // no hidden columns
- assertEquals(
- Arrays.toString(new int[] { seq.findIndex(seq.getStart()) - 1,
- seq.findIndex(seq.getEnd()) - 1, seq.getStart(),
- seq.getEnd(), seq.findIndex(seq.getStart()) - 1,
- seq.findIndex(seq.getEnd()) - 1 }),
- Arrays.toString(cs.locateVisibleBoundsOfSequence(seq)));
-
- // hidden column on gap after end of sequence - should not affect bounds
- colsel.hideSelectedColumns(13, al.getHiddenColumns());
- assertEquals(
- Arrays.toString(new int[] { seq.findIndex(seq.getStart()) - 1,
- seq.findIndex(seq.getEnd()) - 1, seq.getStart(),
- seq.getEnd(), seq.findIndex(seq.getStart()) - 1,
- seq.findIndex(seq.getEnd()) - 1 }),
- Arrays.toString(cs.locateVisibleBoundsOfSequence(seq)));
+ // only [5,7] returned, offset by 1
+ assertEquals("[4, 6]",
+ Arrays.toString(regions.next()));
+ assertEquals(3, cs2.getSize());
- cs.revealAllHiddenColumns(colsel);
- // hidden column on gap before beginning of sequence - should vis bounds by
- // one
- colsel.hideSelectedColumns(0, al.getHiddenColumns());
- assertEquals(
- Arrays.toString(new int[] { seq.findIndex(seq.getStart()) - 2,
- seq.findIndex(seq.getEnd()) - 2, seq.getStart(),
- seq.getEnd(), seq.findIndex(seq.getStart()) - 1,
- seq.findIndex(seq.getEnd()) - 1 }),
- Arrays.toString(cs.locateVisibleBoundsOfSequence(seq)));
-
- cs.revealAllHiddenColumns(colsel);
- // hide columns around most of sequence - leave one residue remaining
- cs.hideColumns(1, 3);
- cs.hideColumns(6, 11);
- assertEquals("-D",
- cs.getVisibleSequenceStrings(0, 5, new SequenceI[] { seq })[0]);
- assertEquals(
- Arrays.toString(new int[] { 1, 1, 3, 3,
- seq.findIndex(seq.getStart()) - 1,
- seq.findIndex(seq.getEnd()) - 1 }),
- Arrays.toString(cs.locateVisibleBoundsOfSequence(seq)));
- cs.revealAllHiddenColumns(colsel);
+ cs2 = new HiddenColumns(cs, 8, 15, 4);
+ regions = cs2.iterator();
+ assertTrue(cs2.hasHiddenColumns());
- // hide whole sequence - should just get location of hidden region
- // containing sequence
- cs.hideColumns(1, 11);
- assertEquals(
- Arrays.toString(new int[] { 0, 1, 0, 0,
- seq.findIndex(seq.getStart()) - 1,
- seq.findIndex(seq.getEnd()) - 1 }),
- Arrays.toString(cs.locateVisibleBoundsOfSequence(seq)));
+ // only [10,11] returned, offset by 4
+ assertEquals("[6, 7]",
+ Arrays.toString(regions.next()));
+ assertEquals(2, cs2.getSize());
+ cs2 = new HiddenColumns(cs, 6, 10, 4);
+ assertFalse(cs2.hasHiddenColumns());
}
- @Test(groups = { "Functional" })
- public void testLocateVisibleBoundsPathologicals()
- {
- // test some pathological cases we missed
- AlignmentI al = new Alignment(new SequenceI[] { new Sequence(
- "refseqGaptest", "KTDVTI----------NFI-----G----L") });
- HiddenColumns cs = new HiddenColumns();
- cs.hideInsertionsFor(al.getSequenceAt(0));
- assertEquals(
- "G",
- ""
- + al.getSequenceAt(0).getCharAt(
- cs.adjustForHiddenColumns(9)));
-
- }
@Test(groups = { "Functional" })
public void testHideColumns()
ColumnSelection colsel = new ColumnSelection();
HiddenColumns cs = al.getHiddenColumns();
colsel.hideSelectedColumns(5, al.getHiddenColumns());
- List<int[]> hidden = cs.getHiddenColumnsCopy();
- assertEquals(1, hidden.size());
- assertEquals("[5, 5]", Arrays.toString(hidden.get(0)));
+ Iterator<int[]> regions = cs.iterator();
+ assertEquals(1, cs.getNumberOfRegions());
+ assertEquals("[5, 5]", Arrays.toString(regions.next()));
+ assertEquals(cs.getSize(), 1);
colsel.hideSelectedColumns(3, al.getHiddenColumns());
- hidden = cs.getHiddenColumnsCopy();
- assertEquals(2, hidden.size());
+ regions = cs.iterator();
+ assertEquals(2, cs.getNumberOfRegions());
// two hidden ranges, in order:
- assertEquals(hidden.size(), cs.getHiddenColumnsCopy().size());
- assertEquals("[3, 3]", Arrays.toString(hidden.get(0)));
- assertEquals("[5, 5]", Arrays.toString(hidden.get(1)));
+ assertEquals("[3, 3]", Arrays.toString(regions.next()));
+ assertEquals("[5, 5]", Arrays.toString(regions.next()));
+ assertEquals(cs.getSize(), 2);
// hiding column 4 expands [3, 3] to [3, 4]
// and merges to [5, 5] to make [3, 5]
colsel.hideSelectedColumns(4, al.getHiddenColumns());
- hidden = cs.getHiddenColumnsCopy();
- assertEquals(1, hidden.size());
- assertEquals("[3, 5]", Arrays.toString(hidden.get(0)));
+ regions = cs.iterator();
+ assertEquals(1, cs.getNumberOfRegions());
+ assertEquals("[3, 5]", Arrays.toString(regions.next()));
+ assertEquals(cs.getSize(), 3);
// clear hidden columns (note they are added to selected)
cs.revealAllHiddenColumns(colsel);
// it is now actually null but getter returns an empty list
- assertTrue(cs.getHiddenColumnsCopy().isEmpty());
+ assertEquals(0, cs.getNumberOfRegions());
+ assertEquals(cs.getSize(), 0);
cs.hideColumns(3, 6);
- hidden = cs.getHiddenColumnsCopy();
- int[] firstHiddenRange = hidden.get(0);
+ regions = cs.iterator();
+ int[] firstHiddenRange = regions.next();
assertEquals("[3, 6]", Arrays.toString(firstHiddenRange));
+ assertEquals(cs.getSize(), 4);
// adding a subrange of already hidden should do nothing
cs.hideColumns(4, 5);
- hidden = cs.getHiddenColumnsCopy();
- assertEquals(1, hidden.size());
+ regions = cs.iterator();
+ assertEquals(1, cs.getNumberOfRegions());
assertEquals("[3, 6]",
- Arrays.toString(cs.getHiddenColumnsCopy().get(0)));
+ Arrays.toString(regions.next()));
+ assertEquals(cs.getSize(), 4);
cs.hideColumns(3, 5);
- hidden = cs.getHiddenColumnsCopy();
- assertEquals(1, hidden.size());
+ regions = cs.iterator();
+ assertEquals(1, cs.getNumberOfRegions());
assertEquals("[3, 6]",
- Arrays.toString(cs.getHiddenColumnsCopy().get(0)));
+ Arrays.toString(regions.next()));
+ assertEquals(cs.getSize(), 4);
cs.hideColumns(4, 6);
- hidden = cs.getHiddenColumnsCopy();
- assertEquals(1, hidden.size());
+ regions = cs.iterator();
+ assertEquals(1, cs.getNumberOfRegions());
assertEquals("[3, 6]",
- Arrays.toString(cs.getHiddenColumnsCopy().get(0)));
+ Arrays.toString(regions.next()));
+ assertEquals(cs.getSize(), 4);
cs.hideColumns(3, 6);
- hidden = cs.getHiddenColumnsCopy();
- assertEquals(1, hidden.size());
+ regions = cs.iterator();
+ assertEquals(1, cs.getNumberOfRegions());
assertEquals("[3, 6]",
- Arrays.toString(cs.getHiddenColumnsCopy().get(0)));
+ Arrays.toString(regions.next()));
+ assertEquals(cs.getSize(), 4);
cs.revealAllHiddenColumns(colsel);
cs.hideColumns(2, 4);
- hidden = cs.getHiddenColumnsCopy();
- assertEquals(1, hidden.size());
- assertEquals("[2, 4]", Arrays.toString(hidden.get(0)));
+ regions = cs.iterator();
+ assertEquals(1, cs.getNumberOfRegions());
+ assertEquals("[2, 4]", Arrays.toString(regions.next()));
+ assertEquals(cs.getSize(), 3);
// extend contiguous with 2 positions overlap
cs.hideColumns(3, 5);
- hidden = cs.getHiddenColumnsCopy();
- assertEquals(1, hidden.size());
- assertEquals("[2, 5]", Arrays.toString(hidden.get(0)));
+ regions = cs.iterator();
+ assertEquals(1, cs.getNumberOfRegions());
+ assertEquals("[2, 5]", Arrays.toString(regions.next()));
+ assertEquals(cs.getSize(), 4);
// extend contiguous with 1 position overlap
cs.hideColumns(5, 6);
- hidden = cs.getHiddenColumnsCopy();
- assertEquals(1, hidden.size());
- assertEquals("[2, 6]", Arrays.toString(hidden.get(0)));
+ regions = cs.iterator();
+ assertEquals(1, cs.getNumberOfRegions());
+ assertEquals("[2, 6]", Arrays.toString(regions.next()));
+ assertEquals(cs.getSize(), 5);
// extend contiguous with overlap both ends:
cs.hideColumns(1, 7);
- hidden = cs.getHiddenColumnsCopy();
- assertEquals(1, hidden.size());
- assertEquals("[1, 7]", Arrays.toString(hidden.get(0)));
+ regions = cs.iterator();
+ assertEquals(1, cs.getNumberOfRegions());
+ assertEquals("[1, 7]", Arrays.toString(regions.next()));
+ assertEquals(cs.getSize(), 7);
+
+ cs.revealAllHiddenColumns(colsel);
+ cs.hideColumns(15, 18);
+ cs.hideColumns(2, 4);
+ cs.hideColumns(7, 9);
+ regions = cs.iterator();
+ assertEquals(3, cs.getNumberOfRegions());
+ assertEquals("[2, 4]", Arrays.toString(regions.next()));
+ assertEquals("[7, 9]", Arrays.toString(regions.next()));
+ assertEquals("[15, 18]", Arrays.toString(regions.next()));
+ assertEquals(cs.getSize(), 10);
}
/**
{
ColumnSelection colsel = new ColumnSelection();
HiddenColumns cs = new HiddenColumns();
+
+ // test with null hidden columns
+ cs.revealHiddenColumns(5, colsel);
+ assertTrue(colsel.getSelected().isEmpty());
+
cs.hideColumns(5, 8);
colsel.addElement(10);
cs.revealHiddenColumns(5, colsel);
- // hidden columns list now null but getter returns empty list:
- assertTrue(cs.getHiddenColumnsCopy().isEmpty());
+
+ // hiddenColumns now empty
+ assertEquals(0, cs.getSize());
+
// revealed columns are marked as selected (added to selection):
assertEquals("[10, 5, 6, 7, 8]", colsel.getSelected().toString());
colsel = new ColumnSelection();
cs = new HiddenColumns();
cs.hideColumns(5, 8);
- List<int[]> hidden = cs.getHiddenColumnsCopy();
+
+ int prevSize = cs.getSize();
cs.revealHiddenColumns(6, colsel);
- assertEquals(hidden.size(), cs.getHiddenColumnsCopy().size());
+ assertEquals(prevSize, cs.getSize());
+ assertTrue(colsel.getSelected().isEmpty());
+
+ // reveal hidden columns when there is more than one region
+ cs.hideColumns(20, 23);
+ // now there are 2 hidden regions
+ assertEquals(2, cs.getNumberOfRegions());
+
+ cs.revealHiddenColumns(20, colsel);
+
+ // hiddenColumns now has one region
+ assertEquals(1, cs.getNumberOfRegions());
+
+ // revealed columns are marked as selected (added to selection):
+ assertEquals("[20, 21, 22, 23]", colsel.getSelected().toString());
+
+ // call with a column past the end of the hidden column ranges
+ colsel.clear();
+ cs.revealHiddenColumns(20, colsel);
+ // hiddenColumns still has 1 region
+ assertEquals(1, cs.getNumberOfRegions());
assertTrue(colsel.getSelected().isEmpty());
}
@Test(groups = { "Functional" })
public void testRevealAllHiddenColumns()
{
- HiddenColumns cs = new HiddenColumns();
+ HiddenColumns hidden = new HiddenColumns();
ColumnSelection colsel = new ColumnSelection();
- cs.hideColumns(5, 8);
- cs.hideColumns(2, 3);
+
+ // test with null hidden columns
+ hidden.revealAllHiddenColumns(colsel);
+ assertTrue(colsel.getSelected().isEmpty());
+
+ hidden.hideColumns(5, 8);
+ hidden.hideColumns(2, 3);
colsel.addElement(11);
colsel.addElement(1);
- cs.revealAllHiddenColumns(colsel);
+ hidden.revealAllHiddenColumns(colsel);
/*
* revealing hidden columns adds them (in order) to the (unordered)
* selection list
*/
- assertTrue(cs.getHiddenColumnsCopy().isEmpty());
- assertEquals("[11, 1, 2, 3, 5, 6, 7, 8]", colsel.getSelected()
- .toString());
+
+ // hiddenColumns now empty
+ assertEquals(0, hidden.getSize());
+
+ assertEquals("[11, 1, 2, 3, 5, 6, 7, 8]",
+ colsel.getSelected().toString());
}
@Test(groups = { "Functional" })
public void testIsVisible()
{
HiddenColumns cs = new HiddenColumns();
+ assertTrue(cs.isVisible(5));
+
cs.hideColumns(2, 4);
cs.hideColumns(6, 7);
assertTrue(cs.isVisible(0));
assertTrue(cs.isVisible(5));
assertFalse(cs.isVisible(6));
assertFalse(cs.isVisible(7));
+ assertTrue(cs.isVisible(8));
}
/**
HiddenColumns cs = new HiddenColumns();
cs.hideColumns(49, 59);
cs.hideColumns(69, 79);
- List<int[]> hidden = cs.getHiddenColumnsCopy();
- assertEquals(2, hidden.size());
- assertEquals("[49, 59]", Arrays.toString(hidden.get(0)));
- assertEquals("[69, 79]", Arrays.toString(hidden.get(1)));
+ Iterator<int[]> regions = cs.iterator();
+ assertEquals(2, cs.getNumberOfRegions());
+ assertEquals("[49, 59]", Arrays.toString(regions.next()));
+ assertEquals("[69, 79]", Arrays.toString(regions.next()));
+ assertEquals(22, cs.getSize());
cs.hideColumns(48, 80);
- hidden = cs.getHiddenColumnsCopy();
- assertEquals(1, hidden.size());
- assertEquals("[48, 80]", Arrays.toString(hidden.get(0)));
+ regions = cs.iterator();
+ assertEquals(1, cs.getNumberOfRegions());
+ assertEquals("[48, 80]", Arrays.toString(regions.next()));
+ assertEquals(33, cs.getSize());
/*
* another...joining hidden ranges
cs.hideColumns(50, 60);
// hiding 21-49 should merge to one range
cs.hideColumns(21, 49);
- hidden = cs.getHiddenColumnsCopy();
- assertEquals(1, hidden.size());
- assertEquals("[10, 60]", Arrays.toString(hidden.get(0)));
+ regions = cs.iterator();
+ assertEquals(1, cs.getNumberOfRegions());
+ assertEquals("[10, 60]", Arrays.toString(regions.next()));
+ assertEquals(51, cs.getSize());
/*
* another...left overlap, subsumption, right overlap,
cs.hideColumns(60, 70);
cs.hideColumns(15, 45);
- hidden = cs.getHiddenColumnsCopy();
- assertEquals(2, hidden.size());
- assertEquals("[10, 50]", Arrays.toString(hidden.get(0)));
- assertEquals("[60, 70]", Arrays.toString(hidden.get(1)));
+ regions = cs.iterator();
+ assertEquals(2, cs.getNumberOfRegions());
+ assertEquals("[10, 50]", Arrays.toString(regions.next()));
+ assertEquals("[60, 70]", Arrays.toString(regions.next()));
+ assertEquals(52, cs.getSize());
}
@Test(groups = { "Functional" })
- public void testHideBitset()
+ public void testHideColumns_BitSet()
{
HiddenColumns cs;
// one hidden range
one.set(1);
cs = new HiddenColumns();
- cs.hideMarkedBits(one);
- assertEquals(1, cs.getHiddenColumnsCopy().size());
+ cs.hideColumns(one);
+ assertEquals(1, cs.getNumberOfRegions());
+ assertEquals(1, cs.getSize());
one.set(2);
cs = new HiddenColumns();
- cs.hideMarkedBits(one);
- assertEquals(1, cs.getHiddenColumnsCopy().size());
+ cs.hideColumns(one);
+ assertEquals(1, cs.getNumberOfRegions());
+ assertEquals(2, cs.getSize());
one.set(3);
cs = new HiddenColumns();
- cs.hideMarkedBits(one);
- assertEquals(1, cs.getHiddenColumnsCopy().size());
+ cs.hideColumns(one);
+ assertEquals(1, cs.getNumberOfRegions());
+ assertEquals(3, cs.getSize());
// split
one.clear(2);
cs = new HiddenColumns();
- cs.hideMarkedBits(one);
- assertEquals(2, cs.getHiddenColumnsCopy().size());
+ cs.hideColumns(one);
+ assertEquals(2, cs.getNumberOfRegions());
+ assertEquals(2, cs.getSize());
- assertEquals(0, cs.adjustForHiddenColumns(0));
- assertEquals(2, cs.adjustForHiddenColumns(1));
- assertEquals(4, cs.adjustForHiddenColumns(2));
+ assertEquals(0, cs.visibleToAbsoluteColumn(0));
+ assertEquals(2, cs.visibleToAbsoluteColumn(1));
+ assertEquals(4, cs.visibleToAbsoluteColumn(2));
// one again
one.clear(1);
cs = new HiddenColumns();
- cs.hideMarkedBits(one);
+ cs.hideColumns(one);
+ assertEquals(1, cs.getSize());
- assertEquals(1, cs.getHiddenColumnsCopy().size());
+ assertEquals(1, cs.getNumberOfRegions());
- assertEquals(0, cs.adjustForHiddenColumns(0));
- assertEquals(1, cs.adjustForHiddenColumns(1));
- assertEquals(2, cs.adjustForHiddenColumns(2));
- assertEquals(4, cs.adjustForHiddenColumns(3));
- }
-
- @Test(groups = { "Functional" })
- public void testGetBitset()
- {
- BitSet toMark, fromMark;
- long seed = -3241532;
- Random number = new Random(seed);
- for (int n = 0; n < 1000; n++)
- {
- // create a random bitfield
- toMark = BitSet.valueOf(new long[] { number.nextLong(),
- number.nextLong(), number.nextLong() });
- toMark.set(n * number.nextInt(10), n * (25 + number.nextInt(25)));
- HiddenColumns hc = new HiddenColumns();
- hc.hideMarkedBits(toMark);
-
- // see if we can recover bitfield
- hc.markHiddenRegions(fromMark = new BitSet());
- assertEquals(toMark, fromMark);
- }
- }
-
- @Test(groups = { "Functional" })
- public void testFindHiddenRegionPositions()
- {
- HiddenColumns hc = new HiddenColumns();
-
- List<Integer> positions = hc.findHiddenRegionPositions();
- assertTrue(positions.isEmpty());
-
- hc.hideColumns(3, 7);
- hc.hideColumns(10, 10);
- hc.hideColumns(14, 15);
-
- positions = hc.findHiddenRegionPositions();
- assertEquals(3, positions.size());
- assertEquals(3, positions.get(0).intValue());
- assertEquals(5, positions.get(1).intValue());
- assertEquals(8, positions.get(2).intValue());
+ assertEquals(0, cs.visibleToAbsoluteColumn(0));
+ assertEquals(1, cs.visibleToAbsoluteColumn(1));
+ assertEquals(2, cs.visibleToAbsoluteColumn(2));
+ assertEquals(4, cs.visibleToAbsoluteColumn(3));
}
@Test(groups = { "Functional" })
}
@Test(groups = "Functional")
- public void getVisibleStartAndEndIndexTest()
+ public void testGetVisibleStartAndEndIndex()
{
Sequence seq = new Sequence("testSeq", "ABCDEFGHIJKLMNOPQRSTUVWXYZ");
AlignmentI align = new Alignment(new SequenceI[] { seq });
System.out.println(startEnd[0] + " : " + startEnd[1]);
assertEquals(1, startEnd[0]);
assertEquals(23, startEnd[1]);
+
+ // force lowest range to start of alignment
+ hc = new HiddenColumns();
+ hc.hideColumns(3, 4);
+ startEnd = hc.getVisibleStartAndEndIndex(align.getWidth());
+ assertEquals(0, startEnd[0]);
+ assertEquals(25, startEnd[1]);
}
@Test(groups = "Functional")
hc.hideColumns(10, 10);
hc.hideColumns(14, 15);
- result = hc.getRegionWithEdgeAtRes(3);
+ result = hc.getRegionWithEdgeAtRes(2);
assertEquals(3, result[0]);
assertEquals(7, result[1]);
+ result = hc.getRegionWithEdgeAtRes(4);
+ assertEquals(10, result[0]);
+ assertEquals(10, result[1]);
+
result = hc.getRegionWithEdgeAtRes(5);
assertEquals(10, result[0]);
assertEquals(10, result[1]);
result = hc.getRegionWithEdgeAtRes(6);
assertNull(result);
+
+ result = hc.getRegionWithEdgeAtRes(0);
+ assertNull(result);
+
+ result = hc.getRegionWithEdgeAtRes(7);
+ assertEquals(14, result[0]);
+ assertEquals(15, result[1]);
+
+ result = hc.getRegionWithEdgeAtRes(8);
+ assertEquals(14, result[0]);
+ assertEquals(15, result[1]);
+
+ result = hc.getRegionWithEdgeAtRes(16);
+ assertNull(result);
}
@Test(groups = "Functional")
- public void testPropagateInsertions()
+ public void testHasHiddenColumns()
{
- // create an alignment with no gaps - this will be the profile seq and other
- // JPRED seqs
- AlignmentGenerator gen = new AlignmentGenerator(false);
- AlignmentI al = gen.generate(20, 10, 1234, 0, 0);
-
- // get the profileseq
- SequenceI profileseq = al.getSequenceAt(0);
- SequenceI gappedseq = new Sequence(profileseq);
- gappedseq.insertCharAt(5, al.getGapCharacter());
- gappedseq.insertCharAt(6, al.getGapCharacter());
- gappedseq.insertCharAt(7, al.getGapCharacter());
- gappedseq.insertCharAt(8, al.getGapCharacter());
-
- // create an alignment view with the gapped sequence
- SequenceI[] seqs = new SequenceI[1];
- seqs[0] = gappedseq;
- AlignmentI newal = new Alignment(seqs);
- HiddenColumns hidden = new HiddenColumns();
- hidden.hideColumns(15, 17);
-
- AlignmentView view = new AlignmentView(newal, hidden, null, true, false,
- false);
-
- // confirm that original contigs are as expected
- int[] oldcontigs = hidden.getVisibleContigs(0, 20);
- int[] testcontigs = { 0, 14, 18, 19 };
- assertTrue(Arrays.equals(oldcontigs, testcontigs));
-
- // propagate insertions
- HiddenColumns result = HiddenColumns.propagateInsertions(profileseq, al,
- view);
-
- // confirm that the contigs have changed to account for the gaps
- int[] newcontigs = result.getVisibleContigs(0, 20);
- testcontigs[1] = 10;
- testcontigs[2] = 14;
- assertTrue(Arrays.equals(newcontigs, testcontigs));
-
+ HiddenColumns h = new HiddenColumns();
+
+ // new HiddenColumns2 has no hidden cols
+ assertFalse(h.hasHiddenColumns());
+
+ // some columns hidden, returns true
+ h.hideColumns(5, 10);
+ assertTrue(h.hasHiddenColumns());
+
+ // reveal columns, no hidden cols again
+ ColumnSelection sel = new ColumnSelection();
+ h.revealAllHiddenColumns(sel);
+ assertFalse(h.hasHiddenColumns());
+ }
+
+ @Test(groups = "Functional")
+ public void testHasManyHiddenColumns()
+ {
+ HiddenColumns h = new HiddenColumns();
+
+ // h has no hidden cols
+ assertFalse(h.hasMultiHiddenColumnRegions());
+
+ // one set of columns hidden, returns false
+ h.hideColumns(5, 10);
+ assertFalse(h.hasMultiHiddenColumnRegions());
+
+ // two sets hidden, returns true
+ h.hideColumns(15, 17);
+ assertTrue(h.hasMultiHiddenColumnRegions());
+
+ // back to one block, asserts false
+ h.hideColumns(11, 14);
+ assertFalse(h.hasMultiHiddenColumnRegions());
+ }
+
+ @Test(groups = "Functional")
+ public void testAdjustForHiddenColumns()
+ {
+ HiddenColumns h = new HiddenColumns();
+ // returns input value when there are no hidden columns
+ assertEquals(10, h.visibleToAbsoluteColumn(10));
+
+ h.hideColumns(20, 30);
+ assertEquals(10, h.visibleToAbsoluteColumn(10));
+ assertEquals(20 + 11, h.visibleToAbsoluteColumn(20));
+ assertEquals(35 + 11, h.visibleToAbsoluteColumn(35));
+
+ h.hideColumns(5, 7);
+ assertEquals(10 + 3, h.visibleToAbsoluteColumn(10));
+ assertEquals(20 + 14, h.visibleToAbsoluteColumn(20));
+ assertEquals(35 + 14, h.visibleToAbsoluteColumn(35));
+
+ ColumnSelection sel = new ColumnSelection();
+ h.revealAllHiddenColumns(sel);
+ h.hideColumns(0, 1);
+ assertEquals(4, h.visibleToAbsoluteColumn(2));
+ }
+
+ @Test(groups = "Functional")
+ public void testGetNextHiddenBoundary_Left()
+ {
+ HiddenColumns h = new HiddenColumns();
+
+ // returns same value if no hidden cols
+ assertEquals(3, h.getNextHiddenBoundary(true, 3));
+
+ h.hideColumns(5, 10);
+ assertEquals(10, h.getNextHiddenBoundary(true, 15));
+ assertEquals(3, h.getNextHiddenBoundary(true, 3));
+ assertEquals(7, h.getNextHiddenBoundary(true, 7));
+
+ h.hideColumns(15, 20);
+ assertEquals(10, h.getNextHiddenBoundary(true, 15));
+ assertEquals(20, h.getNextHiddenBoundary(true, 21));
+ }
+
+ @Test(groups = "Functional")
+ public void testGetNextHiddenBoundary_Right()
+ {
+ HiddenColumns h = new HiddenColumns();
+
+ // returns same value if no hidden cols
+ assertEquals(3, h.getNextHiddenBoundary(false, 3));
+
+ h.hideColumns(5, 10);
+ assertEquals(5, h.getNextHiddenBoundary(false, 3));
+ assertEquals(15, h.getNextHiddenBoundary(false, 15));
+ assertEquals(7, h.getNextHiddenBoundary(false, 7));
+
+ h.hideColumns(15, 20);
+ assertEquals(15, h.getNextHiddenBoundary(false, 7));
+ assertEquals(15, h.getNextHiddenBoundary(false, 14));
+
+ // returns same value if there is no next hidden column
+ assertEquals(22, h.getNextHiddenBoundary(false, 22));
+ }
+
+ @Test(groups = "Functional")
+ public void testIterator()
+ {
+ HiddenColumns h = new HiddenColumns();
+ Iterator<int[]> result = h.iterator();
+ assertFalse(result.hasNext());
+
+ h.hideColumns(5, 10);
+ result = h.iterator();
+ int[] next = result.next();
+ assertEquals(5, next[0]);
+ assertEquals(10, next[1]);
+ assertFalse(result.hasNext());
+
+ h.hideColumns(22, 23);
+ result = h.iterator();
+ next = result.next();
+ assertEquals(5, next[0]);
+ assertEquals(10, next[1]);
+ next = result.next();
+ assertEquals(22, next[0]);
+ assertEquals(23, next[1]);
+ assertFalse(result.hasNext());
+
+ // test for only one hidden region at start of alignment
+ ColumnSelection sel = new ColumnSelection();
+ h.revealAllHiddenColumns(sel);
+ h.hideColumns(0, 1);
+ result = h.iterator();
+ next = result.next();
+ assertEquals(0, next[0]);
+ assertEquals(1, next[1]);
+ assertFalse(result.hasNext());
+ }
+
+ /* @Test(groups = "Functional")
+ public void testGetVisibleSequenceStrings()
+ {
+ HiddenColumns h = new HiddenColumns();
+ SequenceI seq1 = new Sequence("TEST1", "GALMFWKQESPVICYHRNDT");
+ SequenceI seq2 = new Sequence("TEST2", "VICYHRNDTGA");
+ SequenceI[] seqs = new SequenceI[2];
+ seqs[0] = seq1;
+ seqs[1] = seq2;
+ String[] result = h.getVisibleSequenceStrings(5, 10, seqs);
+ assertEquals(2, result.length);
+ assertEquals("WKQES", result[0]);
+ assertEquals("RNDTG", result[1]);
+
+ h.hideColumns(6, 8);
+ result = h.getVisibleSequenceStrings(5, 10, seqs);
+ assertEquals(2, result.length);
+ assertEquals("WS", result[0]);
+ assertEquals("RG", result[1]);
+
+ SequenceI seq = new Sequence("RefSeq", "-A-SD-ASD--E---");
+ ColumnSelection sel = new ColumnSelection();
+ h.revealAllHiddenColumns(sel);
+ h.hideColumns(1, 3);
+ h.hideColumns(6, 11);
+ assertEquals("-D",
+ h.getVisibleSequenceStrings(0, 5, new SequenceI[]
+ { seq })[0]);
+ }*/
+
+ @Test(groups = "Functional")
+ public void testHideInsertionsFor()
+ {
+ HiddenColumns h = new HiddenColumns();
+ HiddenColumns h2 = new HiddenColumns();
+ SequenceI seq1 = new Sequence("TEST1", "GAL---MFW-KQESPVICY--HRNDT");
+ SequenceI seq2 = new Sequence("TEST1", "GALMFWKQESPVICYHRNDT");
+
+ h.hideList(seq2.getInsertions());
+ assertTrue(h.equals(h2));
+ assertEquals(0, h.getSize());
+
+ h.hideList(seq1.getInsertions());
+ h2.hideColumns(3, 5);
+ h2.hideColumns(9, 9);
+ h2.hideColumns(19, 20);
+ assertTrue(h.equals(h2));
+ assertEquals(6, h.getSize());
+ }
+
+ @Test(groups = "Functional")
+ public void testHideColumns_BitSet_range()
+ {
+ HiddenColumns h = new HiddenColumns();
+ HiddenColumns h2 = new HiddenColumns();
+
+ BitSet tohide = new BitSet(25);
+ h.hideColumns(tohide);
+ assertTrue(h.equals(h2));
+
+ // when setting bitset, first param is inclusive, second exclusive
+ tohide.set(3, 6);
+ tohide.set(9);
+ tohide.set(15, 21);
+ h.clearAndHideColumns(tohide, 5, 23);
+
+ h2.hideColumns(5, 5);
+ h2.hideColumns(9, 9);
+ h2.hideColumns(15, 20);
+ assertTrue(h.equals(h2));
+ assertEquals(h.getSize(), h2.getSize());
+
+ tohide.clear();
+ tohide.set(41);
+ h.clearAndHideColumns(tohide, 23, 30);
+ assertTrue(h.equals(h2));
+ assertEquals(h.getSize(), h2.getSize());
+
+ tohide.set(41);
+ h.clearAndHideColumns(tohide, 30, 45);
+ h2.hideColumns(41, 41);
+ assertTrue(h.equals(h2));
+ assertEquals(h.getSize(), h2.getSize());
+
+ tohide.clear();
+ tohide.set(25, 28);
+ h.clearAndHideColumns(tohide, 17, 50);
+ h2 = new HiddenColumns();
+ h2.hideColumns(5, 5);
+ h2.hideColumns(9, 9);
+ h2.hideColumns(15, 16);
+ h2.hideColumns(25, 27);
+ assertTrue(h.equals(h2));
+ assertEquals(h.getSize(), h2.getSize());
+
+ HiddenColumns hc = new HiddenColumns();
+ hc.hideColumns(3, 5);
+ hc.hideColumns(15, 20);
+ hc.hideColumns(45, 60);
+
+ tohide = new BitSet();
+
+ // all unhidden if tohide is empty and range covers hidden
+ hc.clearAndHideColumns(tohide, 1, 70);
+ assertTrue(!hc.hasHiddenColumns());
+ assertEquals(0, hc.getSize());
+
+ hc.hideColumns(3, 5);
+ hc.hideColumns(15, 20);
+ hc.hideColumns(45, 60);
+ assertEquals(25, hc.getSize());
+
+ // but not if range does not cover hidden
+ hc.clearAndHideColumns(tohide, 23, 40);
+ assertTrue(hc.hasHiddenColumns());
+ assertEquals(25, hc.getSize());
+
+ // and partial unhide if range partially covers
+ hc.clearAndHideColumns(tohide, 1, 17);
+ Iterator<int[]> it = hc.iterator();
+ assertTrue(it.hasNext());
+ int[] region = it.next();
+
+ assertEquals(18, region[0]);
+ assertEquals(20, region[1]);
+
+ assertTrue(it.hasNext());
+ region = it.next();
+
+ assertEquals(45, region[0]);
+ assertEquals(60, region[1]);
+
+ assertFalse(it.hasNext());
+ assertEquals(19, hc.getSize());
+ }
+
+ @Test(groups = "Functional")
+ public void testOffsetByVisibleColumns()
+ {
+ HiddenColumns h = new HiddenColumns();
+ int result = h.offsetByVisibleColumns(-1, 10);
+ assertEquals(9, result);
+
+ h.hideColumns(7, 9);
+ result = h.offsetByVisibleColumns(-4, 10);
+ assertEquals(3, result);
+
+ h.hideColumns(14, 15);
+ result = h.offsetByVisibleColumns(-4, 10);
+ assertEquals(3, result);
+
+ result = h.offsetByVisibleColumns(-10, 17);
+ assertEquals(2, result);
+
+ result = h.offsetByVisibleColumns(-1, 7);
+ assertEquals(5, result);
+
+ result = h.offsetByVisibleColumns(-1, 8);
+ assertEquals(5, result);
+
+ result = h.offsetByVisibleColumns(-3, 15);
+ assertEquals(10, result);
+
+ ColumnSelection sel = new ColumnSelection();
+ h.revealAllHiddenColumns(sel);
+ h.hideColumns(0, 30);
+ result = h.offsetByVisibleColumns(-31, 0);
+ assertEquals(-31, result);
+
+ HiddenColumns cs = new HiddenColumns();
+
+ // test that without hidden columns, offsetByVisibleColumns returns
+ // position n to left of provided position
+ long pos = cs.offsetByVisibleColumns(-3, 10);
+ assertEquals(7, pos);
+
+ // 0 returns same position
+ pos = cs.offsetByVisibleColumns(0, 10);
+ assertEquals(10, pos);
+
+ // overflow to left returns negative number
+ pos = cs.offsetByVisibleColumns(-3, 0);
+ assertEquals(-3, pos);
+
+ // test that with hidden columns to left of result column
+ // behaviour is the same as above
+ cs.hideColumns(1, 3);
+
+ // position n to left of provided position
+ pos = cs.offsetByVisibleColumns(-3, 10);
+ assertEquals(7, pos);
+
+ // 0 returns same position
+ pos = cs.offsetByVisibleColumns(0, 10);
+ assertEquals(10, pos);
+
+ // test with one set of hidden columns between start and required position
+ cs.hideColumns(12, 15);
+ pos = cs.offsetByVisibleColumns(-8, 17);
+ assertEquals(5, pos);
+
+ // test with two sets of hidden columns between start and required position
+ cs.hideColumns(20, 21);
+ pos = cs.offsetByVisibleColumns(-8, 23);
+ assertEquals(9, pos);
+
+ // repeat last 2 tests with no hidden columns to left of required position
+ ColumnSelection colsel = new ColumnSelection();
+ cs.revealAllHiddenColumns(colsel);
+
+ // test with one set of hidden columns between start and required position
+ cs.hideColumns(12, 15);
+ pos = cs.offsetByVisibleColumns(-8, 17);
+ assertEquals(5, pos);
+
+ // test with two sets of hidden columns between start and required position
+ cs.hideColumns(20, 21);
+ pos = cs.offsetByVisibleColumns(-8, 23);
+ assertEquals(9, pos);
+
+ // test with right (positive) offsets
+
+ // test that without hidden columns, offsetByVisibleColumns returns
+ // position n to right of provided position
+ pos = cs.offsetByVisibleColumns(3, 7);
+ assertEquals(10, pos);
+
+ // test that with hidden columns to left of result column
+ // behaviour is the same as above
+ cs.hideColumns(1, 3);
+
+ // test with one set of hidden columns between start and required position
+ cs.hideColumns(12, 15);
+ pos = cs.offsetByVisibleColumns(8, 5);
+ assertEquals(17, pos);
+
+ // test with two sets of hidden columns between start and required position
+ cs.hideColumns(20, 21);
+ pos = cs.offsetByVisibleColumns(8, 9);
+ assertEquals(23, pos);
+
+ // repeat last 2 tests with no hidden columns to left of required position
+ colsel = new ColumnSelection();
+ cs.revealAllHiddenColumns(colsel);
+
+ // test with one set of hidden columns between start and required position
+ cs.hideColumns(12, 15);
+ pos = cs.offsetByVisibleColumns(8, 5);
+ assertEquals(17, pos);
+
+ // test with two sets of hidden columns between start and required position
+ cs.hideColumns(20, 21);
+ pos = cs.offsetByVisibleColumns(8, 9);
+ assertEquals(23, pos);
+ }
+
+ @Test(groups = "Functional")
+ public void testBoundedIterator()
+ {
+ HiddenColumns h = new HiddenColumns();
+ Iterator<int[]> it = h.getBoundedIterator(0, 10);
+
+ // no hidden columns = nothing to iterate over
+ assertFalse(it.hasNext());
+
+ // [start,end] contains all hidden columns
+ // all regions are returned
+ h.hideColumns(3, 10);
+ h.hideColumns(14, 16);
+ it = h.getBoundedIterator(0, 20);
+ assertTrue(it.hasNext());
+ int[] next = it.next();
+ assertEquals(3, next[0]);
+ assertEquals(10, next[1]);
+ next = it.next();
+ assertEquals(14, next[0]);
+ assertEquals(16, next[1]);
+ assertFalse(it.hasNext());
+
+ // [start,end] overlaps a region
+ // 1 region returned
+ it = h.getBoundedIterator(5, 7);
+ assertTrue(it.hasNext());
+ next = it.next();
+ assertEquals(3, next[0]);
+ assertEquals(10, next[1]);
+ assertFalse(it.hasNext());
+
+ // [start,end] fully contains 1 region and start of last
+ // - 2 regions returned
+ it = h.getBoundedIterator(3, 15);
+ assertTrue(it.hasNext());
+ next = it.next();
+ assertEquals(3, next[0]);
+ assertEquals(10, next[1]);
+ next = it.next();
+ assertEquals(14, next[0]);
+ assertEquals(16, next[1]);
+ assertFalse(it.hasNext());
+
+ // [start,end] contains end of first region and whole of last region
+ // - 2 regions returned
+ it = h.getBoundedIterator(4, 20);
+ assertTrue(it.hasNext());
+ next = it.next();
+ assertEquals(3, next[0]);
+ assertEquals(10, next[1]);
+ next = it.next();
+ assertEquals(14, next[0]);
+ assertEquals(16, next[1]);
+ assertFalse(it.hasNext());
+ }
+
+ @Test(groups = "Functional")
+ public void testBoundedStartIterator()
+ {
+ HiddenColumns h = new HiddenColumns();
+ Iterator<Integer> it = h.getStartRegionIterator(0, 10);
+
+ // no hidden columns = nothing to iterate over
+ assertFalse(it.hasNext());
+
+ // [start,end] contains all hidden columns
+ // all regions are returned
+ h.hideColumns(3, 10);
+ h.hideColumns(14, 16);
+ it = h.getStartRegionIterator(0, 20);
+ assertTrue(it.hasNext());
+ int next = it.next();
+ assertEquals(3, next);
+ next = it.next();
+ assertEquals(6, next);
+ assertFalse(it.hasNext());
+
+ // [start,end] does not contain a start of a region
+ // no regions to iterate over
+ it = h.getStartRegionIterator(4, 5);
+ assertFalse(it.hasNext());
+
+ // [start,end] fully contains 1 region and start of last
+ // - 2 regions returned
+ it = h.getStartRegionIterator(3, 7);
+ assertTrue(it.hasNext());
+ next = it.next();
+ assertEquals(3, next);
+ next = it.next();
+ assertEquals(6, next);
+ assertFalse(it.hasNext());
+
+ // [start,end] contains whole of last region
+ // - 1 region returned
+ it = h.getStartRegionIterator(4, 20);
+ assertTrue(it.hasNext());
+ next = it.next();
+ assertEquals(6, next);
+ assertFalse(it.hasNext());
+ }
+
+ @Test(groups = "Functional")
+ public void testVisibleBlocksVisBoundsIterator()
+ {
+ HiddenColumns h = new HiddenColumns();
+ Iterator<int[]> regions = h.getVisContigsIterator(0, 31, true);
+
+ // only 1 visible region spanning 0-30 if nothing is hidden
+ assertTrue(regions.hasNext());
+ int[] region = regions.next();
+ assertEquals(0, region[0]);
+ assertEquals(30, region[1]);
+ assertFalse(regions.hasNext());
+
+ // hide 1 region in middle
+ // 2 regions one on either side
+ // second region boundary accounts for hidden columns
+ h.hideColumns(10, 15);
+ regions = h.getVisContigsIterator(0, 31, true);
+
+ assertTrue(regions.hasNext());
+ region = regions.next();
+ assertEquals(0, region[0]);
+ assertEquals(9, region[1]);
+ region = regions.next();
+ assertEquals(16, region[0]);
+ assertEquals(36, region[1]);
+ assertFalse(regions.hasNext());
+
+ // single hidden region at left
+ h = new HiddenColumns();
+ h.hideColumns(0, 5);
+ regions = h.getVisContigsIterator(0, 31, true);
+
+ assertTrue(regions.hasNext());
+ region = regions.next();
+ assertEquals(6, region[0]);
+ assertEquals(36, region[1]);
+ assertFalse(regions.hasNext());
+
+ // single hidden region at right
+ h = new HiddenColumns();
+ h.hideColumns(27, 30);
+ regions = h.getVisContigsIterator(0, 31, true);
+
+ assertTrue(regions.hasNext());
+ region = regions.next();
+ assertEquals(0, region[0]);
+ assertEquals(26, region[1]);
+ region = regions.next();
+ assertEquals(31, region[0]);
+ assertEquals(34, region[1]);
+ assertFalse(regions.hasNext());
+
+ // hidden region at left + hidden region in middle
+ h = new HiddenColumns();
+ h.hideColumns(0, 5);
+ h.hideColumns(23, 25);
+ regions = h.getVisContigsIterator(0, 31, true);
+
+ assertTrue(regions.hasNext());
+ region = regions.next();
+ assertEquals(6, region[0]);
+ assertEquals(22, region[1]);
+ region = regions.next();
+ assertEquals(26, region[0]);
+ assertEquals(39, region[1]);
+ assertFalse(regions.hasNext());
+
+ // hidden region at right + hidden region in middle
+ h = new HiddenColumns();
+ h.hideColumns(27, 30);
+ h.hideColumns(11, 14);
+ regions = h.getVisContigsIterator(0, 31, true);
+
+ assertTrue(regions.hasNext());
+ region = regions.next();
+ assertEquals(0, region[0]);
+ assertEquals(10, region[1]);
+ region = regions.next();
+ assertEquals(15, region[0]);
+ assertEquals(26, region[1]);
+ region = regions.next();
+ assertEquals(31, region[0]);
+ assertEquals(38, region[1]);
+ assertFalse(regions.hasNext());
+
+ // hidden region at left and right
+ h = new HiddenColumns();
+ h.hideColumns(27, 35);
+ h.hideColumns(0, 4);
+ regions = h.getVisContigsIterator(0, 31, true);
+
+ assertTrue(regions.hasNext());
+ region = regions.next();
+ assertEquals(5, region[0]);
+ assertEquals(26, region[1]);
+ region = regions.next();
+ assertEquals(36, region[0]);
+ assertEquals(44, region[1]);
+ assertFalse(regions.hasNext());
+
+ // multiple hidden regions
+ h = new HiddenColumns();
+ h.hideColumns(1, 1);
+ h.hideColumns(3, 5);
+ h.hideColumns(9, 11);
+ h.hideColumns(22, 26);
+
+ regions = h.getVisContigsIterator(0, 31, true);
+
+ assertTrue(regions.hasNext());
+ region = regions.next();
+ assertEquals(0, region[0]);
+ assertEquals(0, region[1]);
+ region = regions.next();
+ assertEquals(2, region[0]);
+ assertEquals(2, region[1]);
+ region = regions.next();
+ assertEquals(6, region[0]);
+ assertEquals(8, region[1]);
+ region = regions.next();
+ assertEquals(12, region[0]);
+ assertEquals(21, region[1]);
+ region = regions.next();
+ assertEquals(27, region[0]);
+ assertEquals(42, region[1]);
+ assertFalse(regions.hasNext());
+ }
+
+ /*
+ * the VisibleColsIterator is tested elsewhere, this just tests that
+ * it can be retrieved from HiddenColumns
+ */
+ @Test(groups = "Functional")
+ public void testGetVisibleColsIterator()
+ {
+ HiddenColumns h = new HiddenColumns();
+ Iterator<Integer> it = h.getVisibleColsIterator(0, 10);
+
+ assertTrue(it instanceof RangeElementsIterator);
+ }
+
+ @Test(groups = "Functional")
+ public void testHashCode()
+ {
+ HiddenColumns h = new HiddenColumns();
+ h.hideColumns(0, 25);
+
+ int result = h.hashCode();
+ assertTrue(result > 0);
+
+ h.hideColumns(30, 50);
+ assertTrue(h.hashCode() > 0);
+ assertTrue(result != h.hashCode());
}
}
import static org.testng.Assert.assertTrue;
+import java.util.Iterator;
import java.util.NoSuchElementException;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
-public class VisibleColsIteratorTest
+public class RangeElementsIteratorTest
{
HiddenColumns hiddenCols;
@Test(groups = { "Functional" })
public void testHasNextAndNextWithHidden()
{
- VisibleColsIterator it = new VisibleColsIterator(0, 6, hiddenCols);
+ Iterator<Integer> it = hiddenCols.getVisibleColsIterator(0, 6);
int count = 0;
while (it.hasNext())
{
- it.next();
+ int result = it.next();
+ System.out.println(result);
count++;
}
assertTrue(count == 4, "hasNext() is false after 4 iterations");
@Test(groups = { "Functional" })
public void testHasNextAndNextNoHidden()
{
- VisibleColsIterator it2 = new VisibleColsIterator(0, 3,
- new HiddenColumns());
+ HiddenColumns test = new HiddenColumns();
+ Iterator<Integer> it2 = test.getVisibleColsIterator(0, 3);
int count = 0;
while (it2.hasNext())
{
@Test(groups = { "Functional" })
public void testHasNextAndNextStartHidden()
{
- VisibleColsIterator it3 = new VisibleColsIterator(0, 6,
- hiddenColsAtStart);
+ Iterator<Integer> it3 = hiddenColsAtStart.getVisibleColsIterator(0, 6);
int count = 0;
while (it3.hasNext())
{
@Test(groups = { "Functional" })
public void testHasNextAndNextEndHidden()
{
- VisibleColsIterator it4 = new VisibleColsIterator(0, 4, hiddenCols);
+ Iterator<Integer> it4 = hiddenCols.getVisibleColsIterator(0, 4);
int count = 0;
while (it4.hasNext())
{
expectedExceptions = { NoSuchElementException.class })
public void testLastNextWithHidden() throws NoSuchElementException
{
- VisibleColsIterator it = new VisibleColsIterator(0, 3, hiddenCols);
+ Iterator<Integer> it = hiddenCols.getVisibleColsIterator(0, 3);
while (it.hasNext())
{
it.next();
expectedExceptions = { NoSuchElementException.class })
public void testLastNextNoHidden() throws NoSuchElementException
{
- VisibleColsIterator it2 = new VisibleColsIterator(0, 3,
- new HiddenColumns());
+ HiddenColumns test = new HiddenColumns();
+ Iterator<Integer> it2 = test.getVisibleColsIterator(0, 3);
while (it2.hasNext())
{
it2.next();
expectedExceptions = { NoSuchElementException.class })
public void testLastNextStartHidden() throws NoSuchElementException
{
- VisibleColsIterator it3 = new VisibleColsIterator(0, 6,
- hiddenColsAtStart);
+ Iterator<Integer> it3 = hiddenColsAtStart.getVisibleColsIterator(0, 6);
while (it3.hasNext())
{
it3.next();
expectedExceptions = { NoSuchElementException.class })
public void testLastNextEndHidden() throws NoSuchElementException
{
- VisibleColsIterator it4 = new VisibleColsIterator(0, 4, hiddenCols);
+ Iterator<Integer> it4 = hiddenCols.getVisibleColsIterator(0, 4);
while (it4.hasNext())
{
it4.next();
expectedExceptions = { UnsupportedOperationException.class })
public void testRemove() throws UnsupportedOperationException
{
- VisibleColsIterator it = new VisibleColsIterator(0, 3, hiddenCols);
+ Iterator<Integer> it = hiddenCols.getVisibleColsIterator(0, 3);
it.remove();
}
}
import static org.testng.AssertJUnit.assertSame;
import static org.testng.AssertJUnit.assertTrue;
+import jalview.analysis.AlignmentGenerator;
import jalview.commands.EditCommand;
import jalview.commands.EditCommand.Action;
import jalview.datamodel.PDBEntry.Type;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.BitSet;
+import java.util.Iterator;
import java.util.List;
import java.util.Vector;
-import junit.extensions.PA;
-
import org.testng.Assert;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
+import junit.extensions.PA;
+
public class SequenceTest
{
Assert.assertEquals(pdbe1a,
sq.getDatasetSequence().getPDBEntry("1PDB"),
"PDB Entry '1PDB' not found on dataset sequence via getPDBEntry.");
- ArrayList<Annotation> annotsList = new ArrayList<Annotation>();
+ ArrayList<Annotation> annotsList = new ArrayList<>();
System.out.println(">>>>>> " + sq.getSequenceAsString().length());
annotsList.add(new Annotation("A", "A", 'X', 0.1f));
annotsList.add(new Annotation("A", "A", 'X', 0.1f));
}
@Test(groups = { "Functional" })
+ public void testGapBitset()
+ {
+ SequenceI sq = new Sequence("test/8-13", "-ABC---DE-F--");
+ BitSet bs = sq.gapBitset();
+ BitSet expected = new BitSet();
+ expected.set(0);
+ expected.set(4, 7);
+ expected.set(9);
+ expected.set(11, 13);
+
+ assertTrue(bs.equals(expected));
+
+ }
+
public void testFindFeatures_largeEndPos()
{
/*
assertEquals(8, sq.getDatasetSequence().getStart());
assertEquals(9, sq.getDatasetSequence().getEnd());
}
+
+ /**
+ * Test the code used to locate the reference sequence ruler origin
+ */
+ @Test(groups = { "Functional" })
+ public void testLocateVisibleStartofSequence()
+ {
+ // create random alignment
+ AlignmentGenerator gen = new AlignmentGenerator(false);
+ AlignmentI al = gen.generate(50, 20, 123, 5, 5);
+
+ HiddenColumns cs = al.getHiddenColumns();
+ ColumnSelection colsel = new ColumnSelection();
+
+ SequenceI seq = new Sequence("RefSeq", "-A-SD-ASD--E---");
+ assertEquals(2, seq.findIndex(seq.getStart()));
+
+ // no hidden columns
+ assertEquals(seq.findIndex(seq.getStart()) - 1,
+ seq.firstResidueOutsideIterator(cs.iterator()));
+
+ // hidden column on gap after end of sequence - should not affect bounds
+ colsel.hideSelectedColumns(13, al.getHiddenColumns());
+ assertEquals(seq.findIndex(seq.getStart()) - 1,
+ seq.firstResidueOutsideIterator(cs.iterator()));
+
+ cs.revealAllHiddenColumns(colsel);
+ // hidden column on gap before beginning of sequence - should vis bounds by
+ // one
+ colsel.hideSelectedColumns(0, al.getHiddenColumns());
+ assertEquals(seq.findIndex(seq.getStart()) - 2,
+ cs.absoluteToVisibleColumn(
+ seq.firstResidueOutsideIterator(cs.iterator())));
+
+ cs.revealAllHiddenColumns(colsel);
+ // hide columns around most of sequence - leave one residue remaining
+ cs.hideColumns(1, 3);
+ cs.hideColumns(6, 11);
+
+ Iterator<int[]> it = cs.getVisContigsIterator(0, 6, false);
+
+ assertEquals("-D", seq.getSequenceStringFromIterator(it));
+ // cs.getVisibleSequenceStrings(0, 5, new SequenceI[]
+ // { seq })[0]);
+
+ assertEquals(4, seq.firstResidueOutsideIterator(cs.iterator()));
+ cs.revealAllHiddenColumns(colsel);
+
+ // hide whole sequence - should just get location of hidden region
+ // containing sequence
+ cs.hideColumns(1, 11);
+ assertEquals(0, seq.firstResidueOutsideIterator(cs.iterator()));
+
+ cs.revealAllHiddenColumns(colsel);
+ cs.hideColumns(0, 15);
+ assertEquals(0, seq.firstResidueOutsideIterator(cs.iterator()));
+
+ SequenceI seq2 = new Sequence("RefSeq2", "-------A-SD-ASD--E---");
+
+ cs.revealAllHiddenColumns(colsel);
+ cs.hideColumns(7, 17);
+ assertEquals(0, seq2.firstResidueOutsideIterator(cs.iterator()));
+
+ cs.revealAllHiddenColumns(colsel);
+ cs.hideColumns(3, 17);
+ assertEquals(0, seq2.firstResidueOutsideIterator(cs.iterator()));
+
+ cs.revealAllHiddenColumns(colsel);
+ cs.hideColumns(3, 19);
+ assertEquals(0, seq2.firstResidueOutsideIterator(cs.iterator()));
+
+ cs.revealAllHiddenColumns(colsel);
+ cs.hideColumns(0, 0);
+ assertEquals(1, seq.firstResidueOutsideIterator(cs.iterator()));
+
+ cs.revealAllHiddenColumns(colsel);
+ cs.hideColumns(0, 1);
+ assertEquals(3, seq.firstResidueOutsideIterator(cs.iterator()));
+
+ cs.revealAllHiddenColumns(colsel);
+ cs.hideColumns(0, 2);
+ assertEquals(3, seq.firstResidueOutsideIterator(cs.iterator()));
+
+ cs.revealAllHiddenColumns(colsel);
+ cs.hideColumns(1, 1);
+ assertEquals(3, seq.firstResidueOutsideIterator(cs.iterator()));
+
+ cs.revealAllHiddenColumns(colsel);
+ cs.hideColumns(1, 2);
+ assertEquals(3, seq.firstResidueOutsideIterator(cs.iterator()));
+
+ cs.revealAllHiddenColumns(colsel);
+ cs.hideColumns(1, 3);
+ assertEquals(4, seq.firstResidueOutsideIterator(cs.iterator()));
+
+ cs.revealAllHiddenColumns(colsel);
+ cs.hideColumns(0, 2);
+ cs.hideColumns(5, 6);
+ assertEquals(3, seq.firstResidueOutsideIterator(cs.iterator()));
+
+ cs.revealAllHiddenColumns(colsel);
+ cs.hideColumns(0, 2);
+ cs.hideColumns(5, 6);
+ cs.hideColumns(9, 10);
+ assertEquals(3, seq.firstResidueOutsideIterator(cs.iterator()));
+
+ cs.revealAllHiddenColumns(colsel);
+ cs.hideColumns(0, 2);
+ cs.hideColumns(7, 11);
+ assertEquals(3, seq.firstResidueOutsideIterator(cs.iterator()));
+
+ cs.revealAllHiddenColumns(colsel);
+ cs.hideColumns(2, 4);
+ cs.hideColumns(7, 11);
+ assertEquals(1, seq.firstResidueOutsideIterator(cs.iterator()));
+
+ cs.revealAllHiddenColumns(colsel);
+ cs.hideColumns(2, 4);
+ cs.hideColumns(7, 12);
+ assertEquals(1, seq.firstResidueOutsideIterator(cs.iterator()));
+
+ cs.revealAllHiddenColumns(colsel);
+ cs.hideColumns(1, 11);
+ assertEquals(0, seq.firstResidueOutsideIterator(cs.iterator()));
+
+ cs.revealAllHiddenColumns(colsel);
+ cs.hideColumns(0, 12);
+ assertEquals(0, seq.firstResidueOutsideIterator(cs.iterator()));
+
+ cs.revealAllHiddenColumns(colsel);
+ cs.hideColumns(0, 4);
+ cs.hideColumns(6, 12);
+ assertEquals(0, seq.firstResidueOutsideIterator(cs.iterator()));
+
+ cs.revealAllHiddenColumns(colsel);
+ cs.hideColumns(0, 1);
+ cs.hideColumns(3, 12);
+ assertEquals(0, seq.firstResidueOutsideIterator(cs.iterator()));
+
+ cs.revealAllHiddenColumns(colsel);
+ cs.hideColumns(3, 14);
+ cs.hideColumns(17, 19);
+ assertEquals(0, seq2.firstResidueOutsideIterator(cs.iterator()));
+
+ cs.revealAllHiddenColumns(colsel);
+ cs.hideColumns(3, 7);
+ cs.hideColumns(9, 14);
+ cs.hideColumns(17, 19);
+ assertEquals(0, seq2.firstResidueOutsideIterator(cs.iterator()));
+
+ cs.revealAllHiddenColumns(colsel);
+ cs.hideColumns(0, 1);
+ cs.hideColumns(3, 4);
+ cs.hideColumns(6, 8);
+ cs.hideColumns(10, 12);
+ assertEquals(0, seq.firstResidueOutsideIterator(cs.iterator()));
+
+ }
}
--- /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 static org.testng.AssertJUnit.assertFalse;
+import static org.testng.AssertJUnit.assertTrue;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.testng.annotations.Test;
+
+public class StartRegionIteratorTest
+{
+ /**
+ * Test the start region iterator
+ */
+ @Test(groups = { "Functional" })
+ public void testBasicBoundsIterator()
+ {
+ List<int[]> hiddenColumns = null;
+
+ // null hidden columns
+ Iterator<Integer> it = new StartRegionIterator(3, 10,
+ hiddenColumns);
+ assertFalse(it.hasNext());
+
+ hiddenColumns = new ArrayList<>();
+
+ // no hidden columns
+ it = new StartRegionIterator(3, 10, hiddenColumns);
+ assertFalse(it.hasNext());
+
+ // add some hidden columns
+ hiddenColumns.add(new int[] { 5, 10 });
+ hiddenColumns.add(new int[] { 25, 40 });
+
+ it = new StartRegionIterator(3, 10, hiddenColumns);
+ assertTrue(it.hasNext());
+ Integer result = it.next();
+ assertEquals(5, (int) result);
+ assertFalse(it.hasNext());
+
+ it = new StartRegionIterator(3, 15, hiddenColumns);
+ assertTrue(it.hasNext());
+ result = it.next();
+ assertEquals(5, (int) result);
+ assertFalse(it.hasNext());
+
+ it = new StartRegionIterator(3, 18, hiddenColumns);
+ assertTrue(it.hasNext());
+ result = it.next();
+ assertEquals(5, (int) result);
+ assertFalse(it.hasNext());
+
+ it = new StartRegionIterator(3, 19, hiddenColumns);
+ assertTrue(it.hasNext());
+ result = it.next();
+ assertEquals(5, (int) result);
+ assertTrue(it.hasNext());
+ result = it.next();
+ assertEquals(19, (int) result);
+ assertFalse(it.hasNext());
+
+ hiddenColumns.add(new int[] { 47, 50 });
+
+ it = new StartRegionIterator(15, 60, hiddenColumns);
+ assertTrue(it.hasNext());
+ result = it.next();
+ assertEquals(19, (int) result);
+ assertTrue(it.hasNext());
+ result = it.next();
+ assertEquals(25, (int) result);
+ assertFalse(it.hasNext());
+ }
+
+ /**
+ * Test the start region iterator with null cursor
+ */
+ @Test(groups = { "Functional" })
+ public void testBoundsIteratorUsingNullCursor()
+ {
+ List<int[]> hiddenColumns = null;
+ HiddenCursorPosition pos = null;
+
+ // null hidden columns
+ Iterator<Integer> it = new StartRegionIterator(pos, 3, 10,
+ hiddenColumns);
+ assertFalse(it.hasNext());
+
+ hiddenColumns = new ArrayList<>();
+
+ // no hidden columns
+ it = new StartRegionIterator(pos, 3, 10, hiddenColumns);
+ assertFalse(it.hasNext());
+
+ // add some hidden columns
+ hiddenColumns.add(new int[] { 5, 10 });
+ hiddenColumns.add(new int[] { 25, 40 });
+
+ it = new StartRegionIterator(pos, 3, 10, hiddenColumns);
+ assertTrue(it.hasNext());
+ Integer result = it.next();
+ assertEquals(5, (int) result);
+ assertFalse(it.hasNext());
+
+ it = new StartRegionIterator(pos, 3, 15, hiddenColumns);
+ assertTrue(it.hasNext());
+ result = it.next();
+ assertEquals(5, (int) result);
+ assertFalse(it.hasNext());
+
+ it = new StartRegionIterator(pos, 3, 18, hiddenColumns);
+ assertTrue(it.hasNext());
+ result = it.next();
+ assertEquals(5, (int) result);
+ assertFalse(it.hasNext());
+
+ it = new StartRegionIterator(pos, 3, 19, hiddenColumns);
+ assertTrue(it.hasNext());
+ result = it.next();
+ assertEquals(5, (int) result);
+ assertTrue(it.hasNext());
+ result = it.next();
+ assertEquals(19, (int) result);
+ assertFalse(it.hasNext());
+
+ hiddenColumns.add(new int[] { 47, 50 });
+
+ it = new StartRegionIterator(pos, 15, 60, hiddenColumns);
+ assertTrue(it.hasNext());
+ result = it.next();
+ assertEquals(19, (int) result);
+ assertTrue(it.hasNext());
+ result = it.next();
+ assertEquals(25, (int) result);
+ assertFalse(it.hasNext());
+ }
+
+ /**
+ * Test the start region iterator with nonnull cursor
+ */
+ @Test(groups = { "Functional" })
+ public void testBoundsIteratorUsingCursor()
+ {
+ List<int[]> hiddenColumns = new ArrayList<>();
+
+ // add some hidden columns
+ hiddenColumns.add(new int[] { 5, 10 });
+ hiddenColumns.add(new int[] { 25, 40 });
+
+ HiddenCursorPosition pos = new HiddenCursorPosition(0, 0);
+
+ Iterator<Integer> it = new StartRegionIterator(pos, 3, 10,
+ hiddenColumns);
+ assertTrue(it.hasNext());
+ Integer result = it.next();
+ assertEquals(5, (int) result);
+ assertFalse(it.hasNext());
+
+ it = new StartRegionIterator(pos, 3, 15, hiddenColumns);
+ assertTrue(it.hasNext());
+ result = it.next();
+ assertEquals(5, (int) result);
+ assertFalse(it.hasNext());
+
+ it = new StartRegionIterator(pos, 3, 18, hiddenColumns);
+ assertTrue(it.hasNext());
+ result = it.next();
+ assertEquals(5, (int) result);
+ assertFalse(it.hasNext());
+
+ it = new StartRegionIterator(pos, 3, 19, hiddenColumns);
+ assertTrue(it.hasNext());
+ result = it.next();
+ assertEquals(5, (int) result);
+ assertTrue(it.hasNext());
+ result = it.next();
+ assertEquals(19, (int) result);
+ assertFalse(it.hasNext());
+
+ pos = new HiddenCursorPosition(1, 6);
+ hiddenColumns.add(new int[] { 47, 50 });
+
+ it = new StartRegionIterator(pos, 15, 60, hiddenColumns);
+ assertTrue(it.hasNext());
+ result = it.next();
+ assertEquals(19, (int) result);
+ assertTrue(it.hasNext());
+ result = it.next();
+ assertEquals(25, (int) result);
+ assertFalse(it.hasNext());
+ }
+}
--- /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 static org.testng.AssertJUnit.assertFalse;
+import static org.testng.AssertJUnit.assertTrue;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.testng.annotations.Test;
+
+public class VisibleContigsIteratorTest
+{
+ /**
+ * Test the iterator with single visible regions
+ */
+ @Test(groups = { "Functional" })
+ public void testSimpleVisibleRegions()
+ {
+ List<int[]> hiddenColumns = null;
+
+ // null hidden columns
+ VisibleContigsIterator it = new VisibleContigsIterator(3, 10,
+ hiddenColumns);
+ assertTrue(it.hasNext());
+ assertFalse(it.endsAtHidden());
+ int[] result = it.next();
+ assertEquals(3, result[0]);
+ assertEquals(9, result[1]);
+ assertFalse(it.hasNext());
+ assertFalse(it.endsAtHidden());
+
+ hiddenColumns = new ArrayList<>();
+
+ // no hidden columns
+ it = new VisibleContigsIterator(3, 10,
+ hiddenColumns);
+ assertTrue(it.hasNext());
+ assertFalse(it.endsAtHidden());
+ result = it.next();
+ assertEquals(3, result[0]);
+ assertEquals(9, result[1]);
+ assertFalse(it.hasNext());
+ assertFalse(it.endsAtHidden());
+
+ // hidden columns, but not where we are looking
+ hiddenColumns.add(new int[] { 5, 10 });
+ hiddenColumns.add(new int[] { 25, 40 });
+
+ it = new VisibleContigsIterator(2, 3, hiddenColumns);
+ assertTrue(it.hasNext());
+ assertFalse(it.endsAtHidden());
+ result = it.next();
+ assertEquals(2, result[0]);
+ assertEquals(2, result[1]);
+ assertFalse(it.hasNext());
+ assertFalse(it.endsAtHidden());
+
+ it = new VisibleContigsIterator(5, 7, hiddenColumns);
+ assertFalse(it.hasNext());
+ assertFalse(it.endsAtHidden());
+
+ it = new VisibleContigsIterator(11, 15, hiddenColumns);
+ assertTrue(it.hasNext());
+ assertFalse(it.endsAtHidden());
+ result = it.next();
+ assertEquals(11, result[0]);
+ assertEquals(14, result[1]);
+ assertFalse(it.hasNext());
+ assertFalse(it.endsAtHidden());
+
+ it = new VisibleContigsIterator(50, 60, hiddenColumns);
+ assertTrue(it.hasNext());
+ assertFalse(it.endsAtHidden());
+ result = it.next();
+ assertEquals(50, result[0]);
+ assertEquals(59, result[1]);
+ assertFalse(it.hasNext());
+ assertFalse(it.endsAtHidden());
+ }
+
+ /**
+ * Test the iterator with multiple visible regions
+ */
+ @Test(groups = { "Functional" })
+ public void testMultipleVisibleRegions()
+ {
+ List<int[]> hiddenColumns = new ArrayList<>();
+ hiddenColumns.add(new int[] { 5, 10 });
+ hiddenColumns.add(new int[] { 25, 40 });
+
+ // all hidden columns covered
+ VisibleContigsIterator it = new VisibleContigsIterator(3, 50,
+ hiddenColumns);
+ assertTrue(it.hasNext());
+ assertFalse(it.endsAtHidden());
+ int[] result = it.next();
+ assertEquals(3, result[0]);
+ assertEquals(4, result[1]);
+
+ assertTrue(it.hasNext());
+ assertFalse(it.endsAtHidden());
+ result = it.next();
+ assertEquals(11, result[0]);
+ assertEquals(24, result[1]);
+
+ assertTrue(it.hasNext());
+ assertFalse(it.endsAtHidden());
+ result = it.next();
+ assertEquals(41, result[0]);
+ assertEquals(49, result[1]);
+
+ assertFalse(it.hasNext());
+ assertFalse(it.endsAtHidden());
+ }
+
+ /**
+ * Test the iterator with regions which start/end at hidden region edges
+ */
+ @Test(groups = { "Functional" })
+ public void testVisibleRegionsAtHiddenEdges()
+ {
+ List<int[]> hiddenColumns = new ArrayList<>();
+ hiddenColumns.add(new int[] { 5, 10 });
+ hiddenColumns.add(new int[] { 25, 40 });
+
+ VisibleContigsIterator it = new VisibleContigsIterator(0, 10,
+ hiddenColumns);
+ assertTrue(it.hasNext());
+ assertTrue(it.endsAtHidden());
+ int[] result = it.next();
+ assertEquals(0, result[0]);
+ assertEquals(4, result[1]);
+ assertFalse(it.hasNext());
+ assertTrue(it.endsAtHidden());
+
+ it = new VisibleContigsIterator(2, 11, hiddenColumns);
+ assertTrue(it.hasNext());
+ assertTrue(it.endsAtHidden());
+ result = it.next();
+ assertEquals(2, result[0]);
+ assertEquals(4, result[1]);
+ assertFalse(it.hasNext());
+ assertTrue(it.endsAtHidden());
+
+ it = new VisibleContigsIterator(2, 12, hiddenColumns);
+ assertTrue(it.hasNext());
+ assertFalse(it.endsAtHidden());
+ result = it.next();
+ assertEquals(2, result[0]);
+ assertEquals(4, result[1]);
+ assertTrue(it.hasNext());
+ assertFalse(it.endsAtHidden());
+ result = it.next();
+ assertEquals(11, result[0]);
+ assertEquals(11, result[1]);
+ assertFalse(it.hasNext());
+ assertFalse(it.endsAtHidden());
+
+ it = new VisibleContigsIterator(13, 25, hiddenColumns);
+ assertTrue(it.hasNext());
+ assertFalse(it.endsAtHidden());
+ result = it.next();
+ assertEquals(13, result[0]);
+ assertEquals(24, result[1]);
+ assertFalse(it.hasNext());
+
+ it = new VisibleContigsIterator(13, 26, hiddenColumns);
+ assertTrue(it.hasNext());
+ assertTrue(it.endsAtHidden());
+ result = it.next();
+ assertEquals(13, result[0]);
+ assertEquals(24, result[1]);
+ assertFalse(it.hasNext());
+
+ it = new VisibleContigsIterator(13, 27, hiddenColumns);
+ assertTrue(it.hasNext());
+ assertTrue(it.endsAtHidden());
+ result = it.next();
+ assertEquals(13, result[0]);
+ assertEquals(24, result[1]);
+ assertFalse(it.hasNext());
+
+ it = new VisibleContigsIterator(13, 41, hiddenColumns);
+ assertTrue(it.hasNext());
+ assertTrue(it.endsAtHidden());
+ result = it.next();
+ assertEquals(13, result[0]);
+ assertEquals(24, result[1]);
+ assertFalse(it.hasNext());
+
+ it = new VisibleContigsIterator(13, 42, hiddenColumns);
+ assertTrue(it.hasNext());
+ assertFalse(it.endsAtHidden());
+ result = it.next();
+ assertEquals(13, result[0]);
+ assertEquals(24, result[1]);
+ assertTrue(it.hasNext());
+ result = it.next();
+ assertEquals(41, result[0]);
+ assertEquals(41, result[1]);
+ }
+}
import static org.testng.AssertJUnit.assertTrue;
import jalview.api.FeatureSettingsModelI;
+import jalview.bin.Cache;
import jalview.datamodel.SequenceDummy;
import jalview.datamodel.SequenceFeature;
import jalview.datamodel.SequenceI;
@BeforeClass(alwaysRun = true)
public void setUp()
{
+ Cache.loadProperties("test/jalview/io/testProps.jvprops");
SequenceOntologyFactory.setInstance(new SequenceOntologyLite());
}
String chainACommand = commands[0].commands[0];
// M colour is #82827d == (130, 130, 125) (see strand.html help page)
assertTrue(chainACommand
- .contains(";select 21:A/1.1;color[130,130,125]"));
+ .contains("select 21:A/1.1;color[130,130,125]")); // first one
// H colour is #60609f == (96, 96, 159)
assertTrue(chainACommand.contains(";select 22:A/1.1;color[96,96,159]"));
// hidden columns are Gray (128, 128, 128)
String chainBCommand = commands[1].commands[0];
// M colour is #82827d == (130, 130, 125)
assertTrue(chainBCommand
- .contains(";select 21:B/2.1;color[130,130,125]"));
+ .contains("select 21:B/2.1;color[130,130,125]"));
// V colour is #ffff00 == (255, 255, 0)
assertTrue(chainBCommand
.contains(";select 22:B/2.1;color[255,255,0]"));
import jalview.bin.Jalview;
import jalview.datamodel.Alignment;
import jalview.datamodel.AlignmentI;
+import jalview.datamodel.HiddenColumns;
import jalview.datamodel.Sequence;
import jalview.datamodel.SequenceFeature;
import jalview.datamodel.SequenceGroup;
import jalview.util.MessageManager;
import java.awt.Color;
-import java.util.List;
+import java.util.Iterator;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeClass;
*/
assertFalse(alignFrame.hideFeatureColumns("exon", true));
assertTrue(alignFrame.getViewport().getColumnSelection().isEmpty());
- assertTrue(alignFrame.getViewport().getAlignment().getHiddenColumns()
- .getHiddenColumnsCopy().isEmpty());
+
+ assertEquals(alignFrame.getViewport().getAlignment().getHiddenColumns()
+ .getNumberOfRegions(), 0);
+
assertFalse(alignFrame.hideFeatureColumns("exon", false));
assertTrue(alignFrame.getViewport().getColumnSelection().isEmpty());
- assertTrue(alignFrame.getViewport().getAlignment().getHiddenColumns()
- .getHiddenColumnsCopy().isEmpty());
+
+ assertEquals(alignFrame.getViewport().getAlignment().getHiddenColumns()
+ .getNumberOfRegions(), 0);
/*
* hiding a feature in all columns does nothing
*/
assertFalse(alignFrame.hideFeatureColumns("Metal", true));
assertTrue(alignFrame.getViewport().getColumnSelection().isEmpty());
- List<int[]> hidden = alignFrame.getViewport().getAlignment()
- .getHiddenColumns().getHiddenColumnsCopy();
- assertTrue(hidden.isEmpty());
+
+ assertEquals(alignFrame.getViewport().getAlignment().getHiddenColumns()
+ .getNumberOfRegions(), 0);
+
/*
* threshold Metal to hide features where score < 5
fc.setThreshold(5f);
alignFrame.getFeatureRenderer().setColour("Metal", fc);
assertTrue(alignFrame.hideFeatureColumns("Metal", true));
- hidden = alignFrame.getViewport().getAlignment().getHiddenColumns()
- .getHiddenColumnsCopy();
- assertEquals(hidden.size(), 1);
- assertEquals(hidden.get(0)[0], 5);
- assertEquals(hidden.get(0)[1], 9);
+ HiddenColumns hidden = alignFrame.getViewport().getAlignment().getHiddenColumns();
+ assertEquals(hidden.getNumberOfRegions(), 1);
+ Iterator<int[]> regions = hidden.iterator();
+ int[] next = regions.next();
+ assertEquals(next[0], 5);
+ assertEquals(next[1], 9);
/*
* hide a feature present in some columns
*/
alignFrame.getViewport().showAllHiddenColumns();
assertTrue(alignFrame.hideFeatureColumns("Turn", true));
- hidden = alignFrame.getViewport().getAlignment().getHiddenColumns()
- .getHiddenColumnsCopy();
- assertEquals(hidden.size(), 2);
- assertEquals(hidden.get(0)[0], 1);
- assertEquals(hidden.get(0)[1], 3);
- assertEquals(hidden.get(1)[0], 6);
- assertEquals(hidden.get(1)[1], 8);
+ regions = alignFrame.getViewport().getAlignment()
+ .getHiddenColumns().iterator();
+ assertEquals(alignFrame.getViewport().getAlignment().getHiddenColumns()
+ .getNumberOfRegions(), 2);
+ next = regions.next();
+ assertEquals(next[0], 1);
+ assertEquals(next[1], 3);
+ next = regions.next();
+ assertEquals(next[0], 6);
+ assertEquals(next[1], 8);
}
@BeforeClass(alwaysRun = true)
import jalview.io.FormatAdapter;
import java.io.IOException;
-import java.util.List;
+import java.util.Iterator;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.BeforeMethod;
HiddenColumns currentHidden = af.getViewport().getAlignment()
.getHiddenColumns();
- List<int[]> regions = currentHidden.getHiddenColumnsCopy();
- assertEquals(regions.get(0)[0], 0);
- assertEquals(regions.get(0)[1], 3);
- assertEquals(regions.get(1)[0], 22);
- assertEquals(regions.get(1)[1], 25);
+ Iterator<int[]> regions = currentHidden.iterator();
+ int[] next = regions.next();
+ assertEquals(0, next[0]);
+ assertEquals(3, next[1]);
+ next = regions.next();
+ assertEquals(22, next[0]);
+ assertEquals(25, next[1]);
// now reset hidden columns
acc.reset();
currentHidden = af.getViewport().getAlignment().getHiddenColumns();
- regions = currentHidden.getHiddenColumnsCopy();
- assertEquals(regions.get(0)[0], 10);
- assertEquals(regions.get(0)[1], 20);
+ regions = currentHidden.iterator();
+ next = regions.next();
+ assertEquals(10, next[0]);
+ assertEquals(20, next[1]);
// check works with empty hidden columns as old columns
oldhidden = new HiddenColumns();
acc.reset();
currentHidden = af.getViewport().getAlignment().getHiddenColumns();
- regions = currentHidden.getHiddenColumnsCopy();
- assertEquals(regions.get(0)[0], 10);
- assertEquals(regions.get(0)[1], 20);
+ regions = currentHidden.iterator();
+ next = regions.next();
+ assertEquals(10, next[0]);
+ assertEquals(20, next[1]);
}
}
import jalview.datamodel.AlignmentAnnotation;
import jalview.datamodel.AlignmentI;
import jalview.datamodel.Annotation;
+import jalview.datamodel.ColumnSelection;
import jalview.datamodel.DBRefEntry;
import jalview.datamodel.DBRefSource;
+import jalview.datamodel.HiddenColumns;
+import jalview.datamodel.Sequence;
import jalview.datamodel.SequenceFeature;
+import jalview.datamodel.SequenceGroup;
import jalview.datamodel.SequenceI;
import jalview.io.DataSourceType;
import jalview.io.FileFormat;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
+import java.util.Iterator;
import java.util.List;
import javax.swing.JMenu;
public void testConfigureReferenceAnnotationsMenu_noSequenceSelected()
{
JMenuItem menu = new JMenuItem();
- List<SequenceI> seqs = new ArrayList<SequenceI>();
+ List<SequenceI> seqs = new ArrayList<>();
testee.configureReferenceAnnotationsMenu(menu, seqs);
assertFalse(menu.isEnabled());
// now try null list
List<SequenceI> seqs = parentPanel.getAlignment().getSequences();
// create list of links and list of DBRefs
- List<String> links = new ArrayList<String>();
- List<DBRefEntry> refs = new ArrayList<DBRefEntry>();
+ List<String> links = new ArrayList<>();
+ List<DBRefEntry> refs = new ArrayList<>();
// links as might be added into Preferences | Connections dialog
links.add("EMBL-EBI Search | http://www.ebi.ac.uk/ebisearch/search.ebi?db=allebi&query=$"
}
// if there are no valid links the Links submenu is disabled
- List<String> nomatchlinks = new ArrayList<String>();
+ List<String> nomatchlinks = new ArrayList<>();
nomatchlinks.add("NOMATCH | http://www.uniprot.org/uniprot/$"
+ DB_ACCESSION + "$");
assertFalse(linkMenu.isEnabled());
}
+
+ /**
+ * Test for adding feature links
+ */
+ @Test(groups = { "Functional" })
+ public void testHideInsertions()
+ {
+ // get sequences from the alignment
+ List<SequenceI> seqs = parentPanel.getAlignment().getSequences();
+
+ // add our own seqs to avoid problems with changes to existing sequences
+ // (gap at end of sequences varies depending on how tests are run!)
+ Sequence seqGap1 = new Sequence("GappySeq",
+ "AAAA----AA-AAAAAAA---AAA-----------AAAAAAAAAA--");
+ seqGap1.createDatasetSequence();
+ seqs.add(seqGap1);
+ Sequence seqGap2 = new Sequence("LessGappySeq",
+ "AAAAAA-AAAAA---AAA--AAAAA--AAAAAAA-AAAAAA");
+ seqGap2.createDatasetSequence();
+ seqs.add(seqGap2);
+ Sequence seqGap3 = new Sequence("AnotherGapSeq",
+ "AAAAAA-AAAAAA--AAAAAA-AAAAAAAAAAA---AAAAAAAA");
+ seqGap3.createDatasetSequence();
+ seqs.add(seqGap3);
+ Sequence seqGap4 = new Sequence("NoGaps",
+ "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA");
+ seqGap4.createDatasetSequence();
+ seqs.add(seqGap4);
+
+ ColumnSelection sel = new ColumnSelection();
+ parentPanel.av.getAlignment().getHiddenColumns()
+ .revealAllHiddenColumns(sel);
+
+ // get the Popup Menu for 7th sequence - no insertions
+ testee = new PopupMenu(parentPanel, seqs.get(7), null);
+ testee.hideInsertions_actionPerformed(null);
+
+ HiddenColumns hidden = parentPanel.av.getAlignment().getHiddenColumns();
+ Iterator<int[]> it = hidden.iterator();
+ assertFalse(it.hasNext());
+
+ // get the Popup Menu for GappySeq - this time we have insertions
+ testee = new PopupMenu(parentPanel, seqs.get(4), null);
+ testee.hideInsertions_actionPerformed(null);
+ hidden = parentPanel.av.getAlignment().getHiddenColumns();
+ it = hidden.iterator();
+
+ assertTrue(it.hasNext());
+ int[] region = it.next();
+ assertEquals(region[0], 4);
+ assertEquals(region[1], 7);
+
+ assertTrue(it.hasNext());
+ region = it.next();
+ assertEquals(region[0], 10);
+ assertEquals(region[1], 10);
+
+ assertTrue(it.hasNext());
+ region = it.next();
+ assertEquals(region[0], 18);
+ assertEquals(region[1], 20);
+
+ assertTrue(it.hasNext());
+ region = it.next();
+ assertEquals(region[0], 24);
+ assertEquals(region[1], 34);
+
+ assertTrue(it.hasNext());
+ region = it.next();
+ assertEquals(region[0], 45);
+ assertEquals(region[1], 46);
+
+ assertFalse(it.hasNext());
+
+ sel = new ColumnSelection();
+ hidden.revealAllHiddenColumns(sel);
+
+ // make a sequence group and hide insertions within the group
+ SequenceGroup sg = new SequenceGroup();
+ sg.setStartRes(8);
+ sg.setEndRes(42);
+ sg.addSequence(seqGap2, false);
+ sg.addSequence(seqGap3, false);
+ parentPanel.av.setSelectionGroup(sg);
+
+ // hide columns outside and within selection
+ // only hidden columns outside the collection will be retained (unless also
+ // gaps in the selection)
+ hidden.hideColumns(1, 10);
+ hidden.hideColumns(31, 40);
+
+ // get the Popup Menu for LessGappySeq in the sequence group
+ testee = new PopupMenu(parentPanel, seqs.get(5), null);
+ testee.hideInsertions_actionPerformed(null);
+ hidden = parentPanel.av.getAlignment().getHiddenColumns();
+ it = hidden.iterator();
+
+ assertTrue(it.hasNext());
+ region = it.next();
+ assertEquals(region[0], 1);
+ assertEquals(region[1], 7);
+
+ assertTrue(it.hasNext());
+ region = it.next();
+ assertEquals(region[0], 13);
+ assertEquals(region[1], 14);
+
+ assertTrue(it.hasNext());
+ region = it.next();
+ assertEquals(region[0], 34);
+ assertEquals(region[1], 34);
+ }
+
}
import java.io.File;
import java.util.List;
+import org.junit.Assert;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.BeforeMethod;
}
}
- @Test(groups = { "Functional" })
+ @Test(groups = { "Functional" }, enabled = false)
public void checkPDBannotationSource()
{
-
+ Assert.fail(
+ "This test is incorrect - does not verify that JmolParser's annotation rows can be recognised as generated by the Jmol parser.");
for (SequenceI asq : al.getSequences())
{
for (AlignmentAnnotation aa : asq.getAnnotation())
{
System.out.println("CalcId: " + aa.getCalcId());
- if (StructureImportSettings.getDefaultPDBFileParser().equals(
- StructureParser.JALVIEW_PARSER))
+ if (StructureImportSettings.getDefaultPDBFileParser()
+ .equals(StructureParser.JALVIEW_PARSER))
{
assertTrue(MCview.PDBfile.isCalcIdForFile(aa, pdbId));
}
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
+import java.util.Iterator;
import java.util.List;
import java.util.Map;
TEST_SEQ_HEIGHT = expectedSeqs.size();
TEST_GRP_HEIGHT = expectedGrps.size();
TEST_ANOT_HEIGHT = expectedAnnots.size();
- TEST_CS_HEIGHT = expectedColSel.getHiddenColumnsCopy().size();
+ TEST_CS_HEIGHT = expectedColSel.getNumberOfRegions();
exportSettings = new AlignExportSettingI()
{
{
HiddenColumns cs = testJsonFile.getHiddenColumns();
Assert.assertNotNull(cs);
- Assert.assertNotNull(cs.getHiddenColumnsCopy());
- List<int[]> hiddenCols = cs.getHiddenColumnsCopy();
- Assert.assertEquals(hiddenCols.size(), TEST_CS_HEIGHT);
- Assert.assertEquals(hiddenCols.get(0), expectedColSel
- .getHiddenColumnsCopy().get(0),
+
+ Iterator<int[]> it = cs.iterator();
+ Iterator<int[]> colselit = expectedColSel.iterator();
+ Assert.assertTrue(it.hasNext());
+ Assert.assertEquals(cs.getNumberOfRegions(), TEST_CS_HEIGHT);
+ Assert.assertEquals(it.next(), colselit.next(),
"Mismatched hidden columns!");
}
@BeforeTest(alwaysRun = true)
public static void clearDesktop()
{
- if (Desktop.instance != null && Desktop.getAlignFrames() != null)
+ if (Desktop.instance != null && Desktop.getFrames() != null
+ && Desktop.getFrames().length > 0)
{
Desktop.instance.closeAll_actionPerformed(null);
}
260 2.99670 4.36610 4.95290 4.33956 1.72799 3.71830 4.50360 1.92619 4.12878 1.69258 2.79907 4.33234 4.52551 4.25179 4.13733 3.48573 3.22794 1.98896 4.25850 3.81122 476 l -
2.68618 4.42225 2.77519 2.73123 3.46354 2.40513 3.72494 3.29354 2.67741 2.69355 4.24690 2.90347 2.73739 3.18146 2.89801 2.37887 2.77519 2.98518 4.58477 3.61503
0.00667 5.01308 * 0.61958 0.77255 0.00000 *
-//
\ No newline at end of file
+//
*/
package jalview.structure;
+import static org.junit.Assert.assertArrayEquals;
+import static org.testng.Assert.assertNotNull;
import static org.testng.AssertJUnit.assertEquals;
import static org.testng.AssertJUnit.assertTrue;
+import jalview.analysis.AlignmentUtils;
+import jalview.api.structures.JalviewStructureDisplayI;
+import jalview.bin.Cache;
import jalview.datamodel.AlignedCodonFrame;
+import jalview.datamodel.AlignmentAnnotation;
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.Annotation;
+import jalview.datamodel.PDBEntry;
import jalview.datamodel.Sequence;
import jalview.datamodel.SequenceFeature;
import jalview.datamodel.SequenceI;
+import jalview.ext.jmol.JmolCommands;
+import jalview.gui.AlignFrame;
+import jalview.gui.Desktop;
import jalview.gui.JvOptionPane;
+import jalview.gui.SequenceRenderer;
+import jalview.gui.StructureChooser;
import jalview.io.DataSourceType;
+import jalview.io.FileLoader;
+import jalview.io.Jalview2xmlBase;
import jalview.io.StructureFile;
import jalview.util.MapList;
+import jalview.ws.DBRefFetcher;
+import jalview.ws.sifts.SiftsSettings;
import java.util.ArrayList;
+import java.util.LinkedHashMap;
import java.util.List;
+import java.util.Map;
+import java.util.SortedMap;
+import java.util.TreeMap;
+import org.testng.Assert;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
-public class StructureSelectionManagerTest
+@Test(singleThreaded = true)
+public class StructureSelectionManagerTest extends Jalview2xmlBase
{
+ @Override
@BeforeClass(alwaysRun = true)
public void setUpJvOptionPane()
{
assertEquals("1gaq", sf.getFeatureGroup());
assertEquals("ALA: 1 1gaqB", sf.getDescription());
}
+
+ /**
+ * Verify that RESNUM sequence features are present after creating a PDB
+ * mapping from a local file, then that everything stays in the same place
+ * when the file is viewed. The corner case is that 4IM2 is a fragment of a
+ * PDB file, which still includes the 'ID' field - a bug in Jalview 2.10.3
+ * causes features, annotation and positions to be remapped to the wrong place
+ * on viewing the structure
+ */
+ @Test(groups = { "Network" })
+ public void testMapping_EqualsFeatures()
+ {
+ // for some reason 'BeforeMethod' (which should be inherited from
+ // Jalview2XmlBase isn't always called)...
+ Desktop.instance.closeAll_actionPerformed(null);
+ try {
+ Thread.sleep(200);
+ } catch (Exception foo) {};
+ SequenceI seq = new Sequence("4IM2|A",
+ "LDFCIRNIEKTVMGEISDIHTKLLRLSSSQGTIE");
+ String P4IM2_MISSING = "examples/testdata/4IM2_missing.pdb";
+ StructureSelectionManager sm = new StructureSelectionManager();
+ sm.setProcessSecondaryStructure(true);
+ sm.setAddTempFacAnnot(true);
+ StructureFile pmap = sm.setMapping(true, new SequenceI[] { seq },
+ new String[]
+ { null }, P4IM2_MISSING,
+ DataSourceType.FILE);
+ assertTrue(pmap != null);
+
+ assertEquals(1, pmap.getSeqs().size());
+ assertEquals("4IM2|A", pmap.getSeqs().get(0).getName());
+
+ List<int[]> structuremap1 = new ArrayList(
+ sm.getMapping(P4IM2_MISSING)[0]
+ .getPDBResNumRanges(seq.getStart(), seq.getEnd()));
+
+ /*
+ * Verify a RESNUM sequence feature in the PDBfile sequence
+ * LEU468 - start+0
+ * VAL479 - start+11
+ * MET486 - start+12
+ * GLY496 - start+13
+ * GLU516 - start+33 (last)
+ *
+ * Expect features and mapping to resolve to same residues.
+ * Also try creating a view and test again
+ *
+ */
+ String[] feats = new String[] { "LEU", "468", "VAL", "479", "MET",
+ "486", "GLY", "496", "GLU", "516" };
+ int[] offset = new int[] { 0, 11, 12, 13, 33 };
+
+ List<String> fdesc = new ArrayList<>();
+ for (int f = 0; f < feats.length; f += 2)
+ {
+ fdesc.add(feats[f] + ": " + feats[f + 1] + " 4im2A");
+ }
+ SequenceI pdbseq = pmap.getSeqs().get(0);
+ verifySeqFeats(pdbseq, offset, fdesc);
+
+ /// Now load as a view
+
+ AlignFrame alf = new FileLoader(false).LoadFileWaitTillLoaded(
+ "examples/testdata/4IM2_missing.pdb", DataSourceType.FILE);
+ Desktop.addInternalFrame(alf, "examples/testdata/4IM2_missing.pdb", 800,
+ 400);
+ AlignmentI pdbal = alf.getViewport().getAlignment();
+ SequenceI pdb_viewseq = pdbal.getSequenceAt(0);
+ assertEquals(pdb_viewseq.getSequenceAsString(),
+ seq.getSequenceAsString());
+ // verify the feature location on the sequence when pdb imported as an
+ // alignment
+ verifySeqFeats(pdb_viewseq, offset, fdesc);
+
+
+ JalviewStructureDisplayI viewr = openStructureViaChooser(alf,
+ pdb_viewseq, "4IM2");
+
+ // and check all is good with feature location still
+ verifySeqFeats(pdb_viewseq, offset, fdesc);
+
+ // finally check positional mapping for sequence and structure
+ PDBEntry pdbe = seq.getPDBEntry("4IM2");
+ StructureSelectionManager apssm = alf.alignPanel
+ .getStructureSelectionManager();
+ StructureMapping[] smap = apssm
+ .getMapping(pdbe.getFile());
+ assertNotNull(smap);
+ assertNotNull(smap[0]);
+ // find the last position in the alignment sequence - this is not
+ // 'SequenceI.getEnd()' - which gets the last PDBRESNUM rather than
+ // SequenceI.getStart() + number of residues in file...
+ int realSeqEnd = pdb_viewseq.findPosition(pdb_viewseq.getLength());
+ List<int[]> ranges = smap[0].getPDBResNumRanges(pdb_viewseq.getStart(),
+ realSeqEnd);
+ assertEquals(structuremap1.size(), ranges.size());
+ int tot_mapped = 0;
+ for (int p = 0; p < ranges.size(); p++)
+ {
+ assertArrayEquals(structuremap1.get(p), ranges.get(p));
+ tot_mapped += 1 + (structuremap1.get(p)[1] - structuremap1.get(p)[0]);
+ }
+
+ assertEquals(pdb_viewseq.getLength(), tot_mapped);
+
+ int lastmappedp = StructureMapping.UNASSIGNED_VALUE;
+ for (int rp = pdb_viewseq.getStart(), rpEnd = pdb_viewseq
+ .findPosition(pdb_viewseq.getLength() - 1); rp <= rpEnd; rp++)
+ {
+ int mappedp = smap[0].getPDBResNum(rp);
+ if (mappedp != StructureMapping.UNASSIGNED_VALUE)
+ {
+ tot_mapped--;
+ if (lastmappedp == mappedp)
+ {
+ Assert.fail("Duplicate mapped position at " + rp + " (dupe = "
+ + mappedp + ")");
+ }
+ }
+ }
+
+ Assert.assertEquals(tot_mapped, 0,
+ "Different number of mapped residues compared to ranges of mapped residues");
+
+ // positional mapping to atoms for color by structure is still wrong, even
+ // though panel looks correct.
+
+ StructureMappingcommandSet smcr[] = JmolCommands
+ .getColourBySequenceCommand(apssm,
+ new String[]
+ { pdbe.getFile() },
+ new SequenceI[][]
+ { new SequenceI[] { pdb_viewseq } },
+ new SequenceRenderer(alf.alignPanel.getAlignViewport()),
+ alf.alignPanel);
+ // Expected - all residues are white
+ for (StructureMappingcommandSet smm : smcr)
+ {
+ for (String c : smm.commands)
+ {
+ System.out.println(c);
+ }
+ }
+ }
+
+ private void verifySeqFeats(SequenceI pdbseq, int[] offset,
+ List<String> fdesc)
+ {
+ for (int o = 0; o < offset.length; o++)
+ {
+ int res = pdbseq.findPosition(offset[o]);
+ List<SequenceFeature> sf = pdbseq.getFeatures().findFeatures(res, res,
+ "RESNUM");
+ assertEquals("Expected sequence feature at position " + res + "("
+ + offset[o] + ")", 1, sf.size());
+ assertEquals("Wrong description at " + res + "(" + offset[o] + ")",
+ fdesc.get(o), sf.get(0).getDescription());
+ }
+
+ }
+
+ @Test(groups = { "Network" })
+ public void testAssociatedMappingToSubSeq() throws Exception
+ {
+
+ // currently this test fails if trimming is enabled
+ Cache.setProperty(DBRefFetcher.TRIM_RETRIEVED_SEQUENCES,
+ Boolean.FALSE.toString());
+ String TEMP_FACTOR_AA="Temperature Factor";
+ String PDBID = "4IM2";
+ String FullLengthSeq = ">TBK1_HUMAN Serine/threonine-protein kinase TBK1\n" +
+ "MQSTSNHLWLLSDILGQGATANVFRGRHKKTGDLFAIKVFNNISFLRPVDVQMREFEVLKKLNHKNIVKLFA\n" +
+ "IEEETTTRHKVLIMEFCPCGSLYTVLEEPSNAYGLPESEFLIVLRDVVGGMNHLRENGIVHRDIKPGNIMRV\n" +
+ "IGEDGQSVYKLTDFGAARELEDDEQFVSLYGTEEYLHPDMYERAVLRKDHQKKYGATVDLWSIGVTFYHAAT\n" +
+ "GSLPFRPFEGPRRNKEVMYKIITGKPSGAISGVQKAENGPIDWSGDMPVSCSLSRGLQVLLTPVLANILEAD\n" +
+ "QEKCWGFDQFFAETSDILHRMVIHVFSLQQMTAHKIYIHSYNTATIFHELVYKQTKIISSNQELIYEGRRLV\n" +
+ "LEPGRLAQHFPKTTEENPIFVVSREPLNTIGLIYEKISLPKVHPRYDLDGDASMAKAITGVVCYACRIASTL\n" +
+ "LLYQELMRKGIRWLIELIKDDYNETVHKKTEVVITLDFCIRNIEKTVKVYEKLMKINLEAAELGEISDIHTK\n" +
+ "LLRLSSSQGTIETSLQDIDSRLSPGGSLADAWAHQEGTHPKDRNVEKLQVLLNCMTEIYYQFKKDKAERRLA\n" +
+ "YNEEQIHKFDKQKLYYHATKAMTHFTDECVKKYEAFLNKSEEWIRKMLHLRKQLLSLTNQCFDIEEEVSKYQ\n" +
+ "EYTNELQETLPQKMFTASSGIKHTMTPIYPSSNTLVEMTLGMKKLKEEMEGVVKELAENNHILERFGSLTMD\n" +
+ "GGLRNVDCL";
+ /*
+ * annotation exported after importing full length sequence to desktop, opening 4IM2 and selecting 'Add Reference Annotation'.
+ *
+ * Note - tabs must be replaced with \t - Eclipse expands them to spaces otherwise.
+ */
+ String FullLengthAnnot = "JALVIEW_ANNOTATION\n" +
+ "# Created: Mon Feb 05 15:30:20 GMT 2018\n" +
+ "# Updated: Fri Feb 09 17:05:17 GMT 2018\n" +
+ "\n" +
+ "\n" +
+ "SEQUENCE_REF\tTBK1_HUMAN\n"
+ + "LINE_GRAPH\tTemperature Factor\tTemperature Factor for 4im2A\t125.22|128.51|120.35|113.12|122.6|114.44|91.49|102.53|98.22|111.41|111.32|116.64|103.55|100.53|95.07|105.55|114.76|128.29|133.55|142.14|121.12|110.36|95.79|95.39|87.14|99.56|93.55|94.21|100.33|110.68|97.85|82.37|75.87|76.53|77.85|82.49|80.92|96.88|122.58|133.31|160.15|180.51|||||242.88|258.97|247.01|227.12|223.24|211.62|184.65|183.51|168.96|160.04|150.88|131.68|130.43|139.87|148.59|136.57|125.7|96.51|74.49|74.08|85.87|70.93|86.47|101.59|97.51|97.39|117.19|114.27|129.5|112.98|147.52|170.26|154.98|168.18|157.51|131.95|105.85|97.78|97.35|76.51|76.31|72.55|71.43|78.82|79.94|75.04|79.54|77.95|83.56|88.5|71.51|71.73|75.96|82.36|81.75|66.51|67.23|69.35|67.92|54.75|71.19|61.85|65.34|67.97|64.51|67.41|62.28|72.85|72.76|70.64|65.23|71.07|67.73|87.72|64.93|75.92|94.02|99.35|93.71|103.59|106.29|115.46|118.69|147.18|130.62|171.64|158.95|164.11||107.42|88.53|83.52|88.06|94.06|80.82|59.01|59.73|78.89|69.21|70.34|81.95|74.53|60.92|64.65|55.79|75.71|68.86|70.95|75.08|87.76|85.43|105.84|||||||||||||||||137.46|151.33|145.17|122.79|111.56|126.72|124.06|161.75|176.84|180.51|198.49|196.75|187.41||195.23|202.27|203.16|226.55|221.75|193.83||||||172.33|177.97|151.47|132.65|99.22|93.7|91.15|88.24|72.35|70.05|70.0|74.92|66.51|68.37|65.76|70.12|74.97|76.89|80.83|70.21|69.48|79.54|82.65|96.54|114.31|140.46|168.51|176.99|205.08|209.27|155.83|139.41|151.3|129.33|111.31|119.62|121.37|102.26|115.39|129.97|128.65|110.38|110.66|116.1|82.53|84.02|82.17|87.63|86.42|77.23|91.23|95.53|102.21|120.73|133.26|109.67|108.49|93.25|92.85|86.39|95.66|94.92|85.82|80.13|76.17|86.61|78.9|77.97|105.6|70.66|69.35|78.94|66.68|63.03|69.91|79.05|75.43|70.73|70.02|80.57|81.74|77.99|84.1|91.66|92.42|94.03|116.47|132.01|154.55|163.99|161.37|155.23|132.78|109.3|90.38|101.83|99.61|91.68|82.77|86.12|82.73|90.13|85.14|79.54|74.27|74.06|72.88|86.34|72.0|69.32|60.9|68.15|52.99|63.53|61.3|66.01|68.28|77.41|71.52|67.18|66.17|71.51|65.47|52.63|65.08|66.37|73.76|77.79|67.58|79.53|84.75|87.42|78.9|79.19|85.57|73.67|80.56|86.19|72.17|66.27|72.8|86.28|78.89|74.5|90.6|80.42|92.5|92.84|96.18|92.08|88.5|87.25|64.6|68.95|65.56|67.55|71.62|78.24|84.95|71.35|86.41|84.73|94.41|95.09|84.74|87.64|88.85|75.1|86.42|79.28|73.14|78.54|80.81|60.66|67.93|71.64|59.85|64.7|61.22|63.84|65.9|62.18|74.95|72.92|93.37|90.47|96.0|93.8|88.46|79.78|83.4|66.55|68.7|73.2|78.76|85.67|84.8|89.59|96.52|79.53|103.51|134.72|126.7|145.31|156.17|149.35|128.48|117.29|118.98|131.59|109.36|90.39|87.68|91.81|78.77|80.11|91.39|75.57|78.98|71.53|76.85|70.9|64.71|73.55|73.45|60.0|69.92|57.89|69.07|66.45|62.85|57.83|57.89|66.4|61.61|60.85|66.47|63.53|63.84|65.96|73.06|70.82|64.51|63.66|73.37|73.59|68.09|78.93|76.99|75.05|71.32|88.4|78.88|93.08|110.61|94.32|99.24|128.99|129.49|132.74|124.21|120.32|142.06|166.41|149.87|153.29|172.19|165.89|181.6|223.11|237.73|176.41|171.09|189.65|188.61|154.84|142.72|154.25|170.99|175.65|||||||110.61||||||||||158.07|170.73|167.93|198.47|212.36|181.71|157.69|163.31|138.96|120.29|131.63|152.26|125.06|136.66|148.97|129.68|120.52|135.31|136.05|119.39|124.18|128.94|123.02|103.37|128.44|134.12|118.88|120.94|130.38|124.67|112.21|113.69|123.65|132.06|114.97|110.75|92.38|101.2|103.25|94.84|85.3|82.19|89.81|98.81|83.03|68.91|65.24|70.31|63.49|86.38|71.07|62.65|63.95|66.98|58.06|68.28|62.11|63.86|67.4|68.69|69.57|68.03|74.23|75.66|70.67|81.08|81.31|82.49|88.15|95.99|92.97|100.01|113.18|122.37|110.99|122.19|159.27|147.74|133.96|111.2|115.64|126.55|107.15|102.85|117.06|116.56|109.55|96.82|98.92|96.53|86.0|88.11|92.76|85.77|79.41|93.06|86.96|76.35|72.37|74.19|68.6|67.46|74.47|76.25|66.73|73.18|75.2|88.21|84.93|75.04|71.09|82.6|80.03|76.22|75.76|83.72|75.85|79.36|90.35|86.9|78.24|95.64|97.38|86.41|85.02|91.87|87.36|77.56|81.25|91.66|83.65|77.67|85.07|89.21|92.66|92.46|89.0|100.83|96.71|94.81|101.37|111.28|124.48|119.73|127.81|134.41|132.4|140.32|140.86|166.52|160.16|168.39|176.74|174.63|172.86|168.55|155.9|132.71|113.44|113.49|123.9|151.11|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||\n"
+ +
+ "\n" +
+ "";
+ AlignFrame alf_full=new
+ FileLoader(false).LoadFileWaitTillLoaded(FullLengthSeq,DataSourceType.PASTE);
+ alf_full.loadJalviewDataFile(FullLengthAnnot, DataSourceType.PASTE, null, null);
+ AlignmentI al_full = alf_full.getViewport().getAlignment();
+ AlignmentAnnotation fullseq_tf = al_full.findAnnotations(al_full.getSequences().get(0), null, TEMP_FACTOR_AA).iterator()
+ .next();
+ assertNotNull(fullseq_tf);
+
+ // getMappingFor
+ // AlignmentI al_full=alf_full.getViewport().getAlignment();
+ //
+ // // load 4IM2 (full length, SIFTS onto full alingnment)
+ // SiftsSettings.setMapWithSifts(true);
+ // StructureChooser schoose = new StructureChooser(selectedSeqs_full,
+ // seq_full,
+ // alf_full.getViewport().getAlignPanel());
+ // schoose.selectStructure(PDBID);
+ // schoose.ok_ActionPerformed();
+
+ AlignFrame alf = new FileLoader(false).LoadFileWaitTillLoaded(
+ ">TBK1_HUMAN/470-502 Serine/threonine-protein kinase TBK1\nFCIRNIEKTVKVYEKLMKINLEAAELGEISDIH",
+ DataSourceType.PASTE);
+ Desktop.addInternalFrame(alf, "Foo", 800, 600);
+ ;
+ AlignmentI al = alf.getViewport().getAlignment();
+ SequenceI seq = al.getSequenceAt(0);
+ assertEquals(470, seq.getStart());
+ // load 4IM2 (full length, SIFTS)
+ SiftsSettings.setMapWithSifts(true);
+ StructureImportSettings.setProcessSecondaryStructure(true);
+ StructureImportSettings.setVisibleChainAnnotation(true);
+ JalviewStructureDisplayI sview = openStructureViaChooser(alf, seq,
+ PDBID);
+
+ AlignmentAnnotation subseq_tf=null;
+ assertTrue(seq.getDBRefs() != null && seq.getDBRefs().length > 0);
+
+ if (!al.findAnnotations(seq, null, TEMP_FACTOR_AA).iterator().hasNext())
+ {
+ // FIXME JAL-2321 - don't see reference annotation on alignment the first
+ // time
+ // around
+ SortedMap<String, String> tipEntries = new TreeMap<>();
+ final Map<SequenceI, List<AlignmentAnnotation>> candidates = new LinkedHashMap<>();
+
+ AlignmentUtils.findAddableReferenceAnnotations(al.getSequences(),
+ tipEntries, candidates, al);
+ AlignmentUtils.addReferenceAnnotations(candidates, al, null);
+
+ if (!al.findAnnotations(seq, null, TEMP_FACTOR_AA).iterator()
+ .hasNext())
+ {
+ Assert.fail(
+ "JAL-2321 or worse has occured. No secondary structure added to alignment.");
+ }
+ }
+ subseq_tf = al.findAnnotations(seq, null, TEMP_FACTOR_AA).iterator()
+ .next();
+ // verify against annotation after loading 4IM2 to full length TBK1_HUMAN
+ // verify location of mapped residues
+ // verify location of secondary structure annotation
+ // Specific positions: LYS477 (h),THR478 (no helix), ... GLY496(no helix),
+ // GLU497 (helix),
+
+ // check there is or is not a tempfactor for each mapped position, and that
+ // values are equal for those positions.
+ for (int p=seq.getStart();p<=seq.getEnd();p++)
+ {
+ Annotation orig,subseq;
+ orig = fullseq_tf.getAnnotationForPosition(p);
+ subseq = subseq_tf.getAnnotationForPosition(p);
+ if (orig == null)
+ {
+ Assert.assertNull(subseq,
+ "Expected no annotation transferred at position " + p);
+ }
+ ;
+ if (orig != null)
+ {
+ Assert.assertNotNull(subseq,
+ "Expected annotation transfer at position " + p);
+ assertEquals(orig.value, subseq.value);
+ }
+ ;
+
+ }
+ }
+
+ private JalviewStructureDisplayI openStructureViaChooser(AlignFrame alf,
+ SequenceI seq,
+ String pDBID)
+ {
+
+ SequenceI[] selectedSeqs = new SequenceI[] { seq };
+
+ StructureChooser schoose = new StructureChooser(selectedSeqs, seq,
+ alf.getViewport().getAlignPanel());
+
+ try
+ {
+ Thread.sleep(5000);
+ } catch (InterruptedException q)
+ {
+ }
+ ;
+ Assert.assertTrue(schoose.selectStructure(pDBID),
+ "Couldn't select structure via structure chooser: " + pDBID);
+ schoose.showStructures(true);
+ return schoose.getOpenedStructureViewer();
+ }
+
}
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Iterator;
import java.util.List;
import org.testng.annotations.BeforeClass;
MappingUtils.mapColumnSelection(proteinSelection, hiddenCols,
proteinView, dnaView, dnaSelection, dnaHidden);
assertEquals("[]", dnaSelection.getSelected().toString());
- List<int[]> hidden = dnaHidden.getHiddenColumnsCopy();
- assertEquals(1, hidden.size());
- assertEquals("[0, 4]", Arrays.toString(hidden.get(0)));
+ Iterator<int[]> regions = dnaHidden.iterator();
+ assertEquals(1, dnaHidden.getNumberOfRegions());
+ assertEquals("[0, 4]", Arrays.toString(regions.next()));
/*
* Column 1 in protein picks up Seq1/K which maps to cols 0-3 in dna
proteinSelection.hideSelectedColumns(1, hiddenCols);
MappingUtils.mapColumnSelection(proteinSelection, hiddenCols,
proteinView, dnaView, dnaSelection, dnaHidden);
- hidden = dnaHidden.getHiddenColumnsCopy();
- assertEquals(1, hidden.size());
- assertEquals("[0, 3]", Arrays.toString(hidden.get(0)));
+ regions = dnaHidden.iterator();
+ assertEquals(1, dnaHidden.getNumberOfRegions());
+ assertEquals("[0, 3]", Arrays.toString(regions.next()));
/*
* Column 2 in protein picks up gaps only - no mapping
proteinSelection.hideSelectedColumns(2, hiddenCols);
MappingUtils.mapColumnSelection(proteinSelection, hiddenCols,
proteinView, dnaView, dnaSelection, dnaHidden);
- assertTrue(dnaHidden.getHiddenColumnsCopy().isEmpty());
+ assertEquals(0, dnaHidden.getNumberOfRegions());
/*
* Column 3 in protein picks up Seq1/P, Seq2/Q, Seq3/S which map to columns
MappingUtils.mapColumnSelection(proteinSelection, hiddenCols,
proteinView, dnaView, dnaSelection, dnaHidden);
assertEquals("[0, 1, 2, 3]", dnaSelection.getSelected().toString());
- hidden = dnaHidden.getHiddenColumnsCopy();
- assertEquals(1, hidden.size());
- assertEquals("[5, 10]", Arrays.toString(hidden.get(0)));
+ regions = dnaHidden.iterator();
+ assertEquals(1, dnaHidden.getNumberOfRegions());
+ assertEquals("[5, 10]", Arrays.toString(regions.next()));
/*
* Combine hiding columns 1 and 3 to get discontiguous hidden columns
proteinSelection.hideSelectedColumns(3, hiddenCols);
MappingUtils.mapColumnSelection(proteinSelection, hiddenCols,
proteinView, dnaView, dnaSelection, dnaHidden);
- hidden = dnaHidden.getHiddenColumnsCopy();
- assertEquals(2, hidden.size());
- assertEquals("[0, 3]", Arrays.toString(hidden.get(0)));
- assertEquals("[5, 10]", Arrays.toString(hidden.get(1)));
+ regions = dnaHidden.iterator();
+ assertEquals(2, dnaHidden.getNumberOfRegions());
+ assertEquals("[0, 3]", Arrays.toString(regions.next()));
+ assertEquals("[5, 10]", Arrays.toString(regions.next()));
}
@Test(groups = { "Functional" })
*/
package jalview.ws;
+import static org.testng.Assert.assertEquals;
import static org.testng.AssertJUnit.assertTrue;
import jalview.bin.Cache;
import jalview.datamodel.AlignmentI;
+import jalview.datamodel.SequenceFeature;
import jalview.datamodel.SequenceI;
import jalview.gui.JvOptionPane;
import jalview.structure.StructureImportSettings;
import jalview.structure.StructureImportSettings.StructureParser;
import jalview.ws.seqfetcher.DbSourceProxy;
+import java.util.Arrays;
import java.util.List;
+import org.testng.Assert;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
testRetrieveProteinSeqFromPDB();
}
+ private class TestRetrieveObject
+ {
+ String id;
+
+ int expectedHeight;
+
+ public TestRetrieveObject(String id, int expectedHeight)
+ {
+ super();
+ this.id = id;
+ this.expectedHeight = expectedHeight;
+ }
+
+ }
+
+ private List<TestRetrieveObject> toRetrieve = Arrays.asList(
+ new TestRetrieveObject("1QIP", 4),
+ new TestRetrieveObject("4IM2", 1));
+
private void testRetrieveProteinSeqFromPDB() throws Exception
{
List<DbSourceProxy> sps = sf.getSourceProxy("PDB");
- AlignmentI response = sps.get(0).getSequenceRecords("1QIP");
- assertTrue(response != null);
- assertTrue(response.getHeight() == 4);
- for (SequenceI sq : response.getSequences())
+ StringBuilder errors = new StringBuilder();
+ for (TestRetrieveObject str : toRetrieve)
{
- assertTrue("No annotation transfered to sequence.",
- sq.getAnnotation().length > 0);
- assertTrue("No PDBEntry on sequence.",
- sq.getAllPDBEntries().size() > 0);
- org.testng.Assert
- .assertEquals(sq.getEnd() - sq.getStart() + 1,
- sq.getLength(),
- "Sequence start/end doesn't match number of residues in sequence");
+ AlignmentI response = sps.get(0).getSequenceRecords(str.id);
+ assertTrue("No aligment for " + str.id, response != null);
+ assertEquals(response.getHeight(), str.expectedHeight,
+ "Number of chains for " + str.id);
+ for (SequenceI sq : response.getSequences())
+ {
+ assertTrue("No annotation transfered to sequence " + sq.getName(),
+ sq.getAnnotation().length > 0);
+ assertTrue("No PDBEntry on sequence " + sq.getName(),
+ sq.getAllPDBEntries().size() > 0);
+ // FIXME: should test that all residues extracted as sequences from
+ // chains in structure have a mapping to data in the structure
+ List<SequenceFeature> prev = null;
+ int lastp = -1;
+ for (int col = 1; col <= sq.getLength(); col++)
+ {
+ List<SequenceFeature> sf = sq.findFeatures(col, col, "RESNUM");
+ if (sf.size() != 1)
+ {
+ errors.append(
+ str.id + ": " +
+ "Expected one feature at column (position): "
+ + (col - 1)
+ + " (" + sq.findPosition(col - 1) + ")"
+ + ": saw "
+ + sf.size());
+ errors.append("\n");
+ if (prev != null)
+ {
+ errors.append("Last Feature was at position " + lastp + ": "
+ + prev.get(0).toString());
+ errors.append("\n");
+ }
+ }
+ else
+ {
+ prev = sf;
+ lastp = sq.findPosition(col - 1);
+ }
+ }
+ }
+ }
+ if (errors.length() > 0)
+ {
+ Assert.fail(errors.toString());
}
}
-
}
--- /dev/null
+package jalview.ws.dbsources;
+
+import static org.testng.Assert.assertEquals;
+
+import jalview.bin.Cache;
+
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+public class PfamFullTest
+{
+ @BeforeClass(alwaysRun = true)
+ public void setUp()
+ {
+ Cache.loadProperties("test/jalview/io/testProps.jvprops");
+ }
+
+ @Test(groups = "Functional")
+ public void testGetURL()
+ {
+ String path = "pfam.xfam.org/family/ABC/alignment/full";
+
+ // with default value for domain
+ String url = new PfamFull().getURL(" abc ");
+ assertEquals(url, "https://" + path);
+
+ // with override in properties
+ Cache.setProperty(Pfam.PFAM_BASEURL_KEY, "http://pfam.xfam.org");
+ url = new PfamFull().getURL(" abc ");
+ assertEquals(url, "http://" + path);
+ }
+}
--- /dev/null
+package jalview.ws.dbsources;
+
+import static org.testng.Assert.assertEquals;
+
+import jalview.bin.Cache;
+
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+public class PfamSeedTest
+{
+ @BeforeClass(alwaysRun = true)
+ public void setUp()
+ {
+ Cache.loadProperties("test/jalview/io/testProps.jvprops");
+ }
+
+ @Test(groups = "Functional")
+ public void testGetURL()
+ {
+ String path = "pfam.xfam.org/family/ABC/alignment/seed";
+
+ // with default value for domain
+ String url = new PfamSeed().getURL(" abc ");
+ assertEquals(url, "https://" + path);
+
+ // with override in properties
+ Cache.setProperty(Pfam.PFAM_BASEURL_KEY, "http://pfam.xfam.org");
+ url = new PfamSeed().getURL(" abc ");
+ assertEquals(url, "http://" + path);
+ }
+}
--- /dev/null
+package jalview.ws.dbsources;
+
+import static org.testng.Assert.assertEquals;
+
+import jalview.bin.Cache;
+
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+public class RfamFullTest
+{
+ @BeforeClass(alwaysRun = true)
+ public void setUp()
+ {
+ Cache.loadProperties("test/jalview/io/testProps.jvprops");
+ }
+
+ @Test(groups = "Functional")
+ public void testGetURL()
+ {
+ String path = "rfam.xfam.org/family/ABC/alignment/full";
+
+ // with default value for domain
+ String url = new RfamFull().getURL(" abc ");
+ assertEquals(url, "https://" + path);
+
+ // with override in properties
+ Cache.setProperty(Rfam.RFAM_BASEURL_KEY, "http://rfam.xfam.org");
+ url = new RfamFull().getURL(" abc ");
+ assertEquals(url, "http://" + path);
+ }
+}
--- /dev/null
+package jalview.ws.dbsources;
+
+import static org.testng.Assert.assertEquals;
+
+import jalview.bin.Cache;
+
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+public class RfamSeedTest
+{
+ @BeforeClass(alwaysRun = true)
+ public void setUp()
+ {
+ Cache.loadProperties("test/jalview/io/testProps.jvprops");
+ }
+
+ @Test(groups = "Functional")
+ public void testGetURL()
+ {
+ String path = "rfam.xfam.org/family/ABC/alignment/stockholm";
+
+ // with default value for domain
+ String url = new RfamSeed().getURL(" abc ");
+ assertEquals(url, "https://" + path);
+
+ // with override in properties
+ Cache.setProperty(Rfam.RFAM_BASEURL_KEY, "http://rfam.xfam.org");
+ url = new RfamSeed().getURL(" abc ");
+ assertEquals(url, "http://" + path);
+ }
+}
@Test(groups = { "External" })
public void testPfamFullAndSeed() throws Exception
{
- PfamFull pff = new PfamFull();
+ Pfam pff = new PfamFull();
PfamSeed pfseed = new PfamSeed();
AlignmentI fullpf = pff.getSequenceRecords(pff.getTestQuery());
@BeforeTest(alwaysRun = true)
public void populateExpectedMapping() throws SiftsException
{
- expectedMapping.put(51, new int[] { 1, 2 });
- expectedMapping.put(52, new int[] { 2, 7 });
- expectedMapping.put(53, new int[] { 3, 12 });
- expectedMapping.put(54, new int[] { 4, 24 });
- expectedMapping.put(55, new int[] { 5, 33 });
- expectedMapping.put(56, new int[] { 6, 40 });
- expectedMapping.put(57, new int[] { 7, 47 });
- expectedMapping.put(58, new int[] { 8, 55 });
- expectedMapping.put(59, new int[] { 9, 62 });
- expectedMapping.put(60, new int[] { 10, 69 });
- expectedMapping.put(61, new int[] { 11, 76 });
- expectedMapping.put(62, new int[] { 12, 83 });
- expectedMapping.put(63, new int[] { 13, 87 });
- expectedMapping.put(64, new int[] { 14, 95 });
- expectedMapping.put(65, new int[] { 15, 102 });
- expectedMapping.put(66, new int[] { 16, 111 });
- expectedMapping.put(67, new int[] { 17, 122 });
- expectedMapping.put(68, new int[] { 18, 131 });
- expectedMapping.put(69, new int[] { 19, 137 });
- expectedMapping.put(70, new int[] { 20, 144 });
- expectedMapping.put(71, new int[] { 21, 152 });
- expectedMapping.put(72, new int[] { 22, 160 });
- expectedMapping.put(73, new int[] { 23, 167 });
- expectedMapping.put(74, new int[] { 24, 179 });
- expectedMapping.put(75, new int[] { 25, 187 });
- expectedMapping.put(76, new int[] { 26, 195 });
- expectedMapping.put(77, new int[] { 27, 203 });
- expectedMapping.put(78, new int[] { 28, 208 });
- expectedMapping.put(79, new int[] { 29, 213 });
- expectedMapping.put(80, new int[] { 30, 222 });
- expectedMapping.put(81, new int[] { 31, 231 });
- expectedMapping.put(82, new int[] { 32, 240 });
- expectedMapping.put(83, new int[] { 33, 244 });
- expectedMapping.put(84, new int[] { 34, 252 });
- expectedMapping.put(85, new int[] { 35, 260 });
- expectedMapping.put(86, new int[] { 36, 268 });
- expectedMapping.put(87, new int[] { 37, 275 });
- expectedMapping.put(88, new int[] { 38, 287 });
- expectedMapping.put(89, new int[] { 39, 293 });
- expectedMapping.put(90, new int[] { 40, 299 });
- expectedMapping.put(91, new int[] { 41, 310 });
- expectedMapping.put(92, new int[] { 42, 315 });
- expectedMapping.put(93, new int[] { 43, 319 });
- expectedMapping.put(94, new int[] { 44, 325 });
- expectedMapping.put(95, new int[] { 45, 331 });
- expectedMapping.put(96, new int[] { 46, 337 });
- expectedMapping.put(97, new int[] { 47, 343 });
- expectedMapping.put(98, new int[] { 48, 349 });
- expectedMapping.put(99, new int[] { 49, 354 });
- expectedMapping.put(100, new int[] { 50, 358 });
- expectedMapping.put(101, new int[] { 51, 367 });
- expectedMapping.put(102, new int[] { 52, 375 });
- expectedMapping.put(103, new int[] { 53, 384 });
- expectedMapping.put(104, new int[] { 54, 391 });
- expectedMapping.put(105, new int[] { 55, 395 });
- expectedMapping.put(106, new int[] { 56, 401 });
- expectedMapping.put(107, new int[] { 57, 409 });
- expectedMapping.put(108, new int[] { 58, 417 });
- expectedMapping.put(109, new int[] { 59, 426 });
- expectedMapping.put(110, new int[] { 60, 434 });
- expectedMapping.put(111, new int[] { 61, 442 });
- expectedMapping.put(112, new int[] { 62, 451 });
- expectedMapping.put(113, new int[] { 63, 457 });
- expectedMapping.put(114, new int[] { 64, 468 });
- expectedMapping.put(115, new int[] { 65, 476 });
- expectedMapping.put(116, new int[] { 66, 484 });
- expectedMapping.put(117, new int[] { 67, 492 });
- expectedMapping.put(118, new int[] { 68, 500 });
- expectedMapping.put(119, new int[] { 69, 509 });
- expectedMapping.put(120, new int[] { 70, 517 });
- expectedMapping.put(121, new int[] { 71, 525 });
- expectedMapping.put(122, new int[] { 72, 534 });
- expectedMapping.put(123, new int[] { 73, 538 });
- expectedMapping.put(124, new int[] { 74, 552 });
- expectedMapping.put(125, new int[] { 75, 559 });
- expectedMapping.put(126, new int[] { 76, 567 });
- expectedMapping.put(127, new int[] { 77, 574 });
- expectedMapping.put(128, new int[] { 78, 580 });
- expectedMapping.put(129, new int[] { 79, 585 });
- expectedMapping.put(130, new int[] { 80, 590 });
- expectedMapping.put(131, new int[] { 81, 602 });
- expectedMapping.put(132, new int[] { 82, 609 });
- expectedMapping.put(133, new int[] { 83, 616 });
- expectedMapping.put(134, new int[] { 84, 622 });
- expectedMapping.put(135, new int[] { 85, 630 });
- expectedMapping.put(136, new int[] { 86, 637 });
- expectedMapping.put(137, new int[] { 87, 644 });
- expectedMapping.put(138, new int[] { 88, 652 });
- expectedMapping.put(139, new int[] { 89, 661 });
- expectedMapping.put(140, new int[] { 90, 668 });
- expectedMapping.put(141, new int[] { 91, 678 });
- expectedMapping.put(142, new int[] { 92, 687 });
- expectedMapping.put(143, new int[] { 93, 696 });
- expectedMapping.put(144, new int[] { 94, 705 });
- expectedMapping.put(145, new int[] { 95, 714 });
- expectedMapping.put(146, new int[] { 96, 722 });
- expectedMapping.put(147, new int[] { 97, 729 });
+ expectedMapping.put(51, new int[] { 1, 2, 1 });
+ expectedMapping.put(52, new int[] { 2, 7, 2 });
+ expectedMapping.put(53, new int[] { 3, 12, 3 });
+ expectedMapping.put(54, new int[] { 4, 24, 4 });
+ expectedMapping.put(55, new int[] { 5, 33, 5 });
+ expectedMapping.put(56, new int[] { 6, 40, 6 });
+ expectedMapping.put(57, new int[] { 7, 47, 7 });
+ expectedMapping.put(58, new int[] { 8, 55, 8 });
+ expectedMapping.put(59, new int[] { 9, 62, 9 });
+ expectedMapping.put(60, new int[] { 10, 69, 10 });
+ expectedMapping.put(61, new int[] { 11, 76, 11 });
+ expectedMapping.put(62, new int[] { 12, 83, 12 });
+ expectedMapping.put(63, new int[] { 13, 87, 13 });
+ expectedMapping.put(64, new int[] { 14, 95, 14 });
+ expectedMapping.put(65, new int[] { 15, 102, 15 });
+ expectedMapping.put(66, new int[] { 16, 111, 16 });
+ expectedMapping.put(67, new int[] { 17, 122, 17 });
+ expectedMapping.put(68, new int[] { 18, 131, 18 });
+ expectedMapping.put(69, new int[] { 19, 137, 19 });
+ expectedMapping.put(70, new int[] { 20, 144, 20 });
+ expectedMapping.put(71, new int[] { 21, 152, 21 });
+ expectedMapping.put(72, new int[] { 22, 160, 22 });
+ expectedMapping.put(73, new int[] { 23, 167, 23 });
+ expectedMapping.put(74, new int[] { 24, 179, 24 });
+ expectedMapping.put(75, new int[] { 25, 187, 25 });
+ expectedMapping.put(76, new int[] { 26, 195, 26 });
+ expectedMapping.put(77, new int[] { 27, 203, 27 });
+ expectedMapping.put(78, new int[] { 28, 208, 28 });
+ expectedMapping.put(79, new int[] { 29, 213, 29 });
+ expectedMapping.put(80, new int[] { 30, 222, 30 });
+ expectedMapping.put(81, new int[] { 31, 231, 31 });
+ expectedMapping.put(82, new int[] { 32, 240, 32 });
+ expectedMapping.put(83, new int[] { 33, 244, 33 });
+ expectedMapping.put(84, new int[] { 34, 252, 34 });
+ expectedMapping.put(85, new int[] { 35, 260, 35 });
+ expectedMapping.put(86, new int[] { 36, 268, 36 });
+ expectedMapping.put(87, new int[] { 37, 275, 37 });
+ expectedMapping.put(88, new int[] { 38, 287, 38 });
+ expectedMapping.put(89, new int[] { 39, 293, 39 });
+ expectedMapping.put(90, new int[] { 40, 299, 40 });
+ expectedMapping.put(91, new int[] { 41, 310, 41 });
+ expectedMapping.put(92, new int[] { 42, 315, 42 });
+ expectedMapping.put(93, new int[] { 43, 319, 43 });
+ expectedMapping.put(94, new int[] { 44, 325, 44 });
+ expectedMapping.put(95, new int[] { 45, 331, 45 });
+ expectedMapping.put(96, new int[] { 46, 337, 46 });
+ expectedMapping.put(97, new int[] { 47, 343, 47 });
+ expectedMapping.put(98, new int[] { 48, 349, 48 });
+ expectedMapping.put(99, new int[] { 49, 354, 49 });
+ expectedMapping.put(100, new int[] { 50, 358, 50 });
+ expectedMapping.put(101, new int[] { 51, 367, 51 });
+ expectedMapping.put(102, new int[] { 52, 375, 52 });
+ expectedMapping.put(103, new int[] { 53, 384, 53 });
+ expectedMapping.put(104, new int[] { 54, 391, 54 });
+ expectedMapping.put(105, new int[] { 55, 395, 55 });
+ expectedMapping.put(106, new int[] { 56, 401, 56 });
+ expectedMapping.put(107, new int[] { 57, 409, 57 });
+ expectedMapping.put(108, new int[] { 58, 417, 58 });
+ expectedMapping.put(109, new int[] { 59, 426, 59 });
+ expectedMapping.put(110, new int[] { 60, 434, 60 });
+ expectedMapping.put(111, new int[] { 61, 442, 61 });
+ expectedMapping.put(112, new int[] { 62, 451, 62 });
+ expectedMapping.put(113, new int[] { 63, 457, 63 });
+ expectedMapping.put(114, new int[] { 64, 468, 64 });
+ expectedMapping.put(115, new int[] { 65, 476, 65 });
+ expectedMapping.put(116, new int[] { 66, 484, 66 });
+ expectedMapping.put(117, new int[] { 67, 492, 67 });
+ expectedMapping.put(118, new int[] { 68, 500, 68 });
+ expectedMapping.put(119, new int[] { 69, 509, 69 });
+ expectedMapping.put(120, new int[] { 70, 517, 70 });
+ expectedMapping.put(121, new int[] { 71, 525, 71 });
+ expectedMapping.put(122, new int[] { 72, 534, 72 });
+ expectedMapping.put(123, new int[] { 73, 538, 73 });
+ expectedMapping.put(124, new int[] { 74, 552, 74 });
+ expectedMapping.put(125, new int[] { 75, 559, 75 });
+ expectedMapping.put(126, new int[] { 76, 567, 76 });
+ expectedMapping.put(127, new int[] { 77, 574, 77 });
+ expectedMapping.put(128, new int[] { 78, 580, 78 });
+ expectedMapping.put(129, new int[] { 79, 585, 79 });
+ expectedMapping.put(130, new int[] { 80, 590, 80 });
+ expectedMapping.put(131, new int[] { 81, 602, 81 });
+ expectedMapping.put(132, new int[] { 82, 609, 82 });
+ expectedMapping.put(133, new int[] { 83, 616, 83 });
+ expectedMapping.put(134, new int[] { 84, 622, 84 });
+ expectedMapping.put(135, new int[] { 85, 630, 85 });
+ expectedMapping.put(136, new int[] { 86, 637, 86 });
+ expectedMapping.put(137, new int[] { 87, 644, 87 });
+ expectedMapping.put(138, new int[] { 88, 652, 88 });
+ expectedMapping.put(139, new int[] { 89, 661, 89 });
+ expectedMapping.put(140, new int[] { 90, 668, 90 });
+ expectedMapping.put(141, new int[] { 91, 678, 91 });
+ expectedMapping.put(142, new int[] { 92, 687, 92 });
+ expectedMapping.put(143, new int[] { 93, 696, 93 });
+ expectedMapping.put(144, new int[] { 94, 705, 94 });
+ expectedMapping.put(145, new int[] { 95, 714, 95 });
+ expectedMapping.put(146, new int[] { 96, 722, 96 });
+ expectedMapping.put(147, new int[] { 97, 729, 97 });
}
@BeforeTest(alwaysRun = true)
atom.atomIndex = 7;
atoms.add(atom);
int actualAtomIndex = siftsClient.getAtomIndex(1, atoms);
- Assert.assertEquals(actualAtomIndex, -1);
+ Assert.assertEquals(actualAtomIndex, siftsClient.UNASSIGNED);
actualAtomIndex = siftsClient.getAtomIndex(43, atoms);
Assert.assertEquals(actualAtomIndex, 7);
}