From: Jim Procter Date: Fri, 23 Feb 2018 16:01:42 +0000 (+0000) Subject: Merge branch 'features/JAL-2885UniprotHttps' into releases/Release_2_10_4_Branch X-Git-Tag: Release_2_10_4~58 X-Git-Url: http://source.jalview.org/gitweb/?p=jalview.git;a=commitdiff_plain;h=d7e95f458ebcbbdcc13f8b07357542ab2d7e4547;hp=b4ebd059827a953d3d54b14ff08eefc99825be5d Merge branch 'features/JAL-2885UniprotHttps' into releases/Release_2_10_4_Branch --- diff --git a/RELEASE b/RELEASE index f1faf34..5ad87c8 100644 --- a/RELEASE +++ b/RELEASE @@ -1,2 +1,2 @@ -jalview.release=releases/Release_2_10_3_Branch -jalview.version=2.10.3 +jalview.release=releases/Release_2_10_4_Branch +jalview.version=2.10.4 diff --git a/benchmarking/src/main/java/org/jalview/SeqWidthBenchmark.java b/benchmarking/src/main/java/org/jalview/SeqWidthBenchmark.java new file mode 100644 index 0000000..a92d4f0 --- /dev/null +++ b/benchmarking/src/main/java/org/jalview/SeqWidthBenchmark.java @@ -0,0 +1,96 @@ +/* + * 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 . + * 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. * The Jalview Authors are detailed in the 'AUTHORS' file. --> - + @@ -96,6 +98,10 @@ + + + + @@ -298,6 +304,8 @@ + + @@ -431,13 +439,14 @@ - + - + + diff --git a/examples/testdata/4IM2_missing.pdb b/examples/testdata/4IM2_missing.pdb new file mode 100644 index 0000000..35f94b2 --- /dev/null +++ b/examples/testdata/4IM2_missing.pdb @@ -0,0 +1,525 @@ +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 diff --git a/examples/testdata/4IM2_missing_noid.pdb b/examples/testdata/4IM2_missing_noid.pdb new file mode 100644 index 0000000..5a5ef94 --- /dev/null +++ b/examples/testdata/4IM2_missing_noid.pdb @@ -0,0 +1,524 @@ +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 diff --git a/examples/testdata/4IM2_nterm.pdb b/examples/testdata/4IM2_nterm.pdb new file mode 100644 index 0000000..48f7803 --- /dev/null +++ b/examples/testdata/4IM2_nterm.pdb @@ -0,0 +1,139 @@ +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 diff --git a/help/help.jhm b/help/help.jhm index 010bca8..f129193 100755 --- a/help/help.jhm +++ b/help/help.jhm @@ -22,7 +22,7 @@ - + diff --git a/help/html/features/splitView.html b/help/html/features/splitView.html index be1bd66..e1c07c1 100644 --- a/help/html/features/splitView.html +++ b/help/html/features/splitView.html @@ -76,7 +76,7 @@ or "View→Nucleotide" (in the protein panel) allows you to show or hide one or other of the linked alignment panels. -
  • Panel heights are adjusted dragging the divider between +
  • Panel heights are adjusted by dragging the divider between them using the mouse
  • "View→New View / Expand Views / Gather Views" behave as for a normal diff --git a/help/html/releases.html b/help/html/releases.html index a36e31a..bef7c41 100755 --- a/help/html/releases.html +++ b/help/html/releases.html @@ -68,22 +68,52 @@ li:before { - +
    - 2.10.3b1
    5/12/2017
    + 2.10.4
    27/02/2018
    +
      +
    • + Mouse cursor changes to indicate Sequence ID and annotation area margins can be click-dragged to adjust them.
    • +
    +
    + +
    +
      +
    • + Slow redraw when Overview panel shown overlapping alignment panel +
    • +
    • + Linked scrolling via protein horizontal scroll bar doesn't work for some CDS/Protein views +
    • +
    +
    + + + +
    + 2.10.3b1
    24/1/2018
    +
    + +
    +
    • Updated Certum Codesigning Certificate + (Valid till 30th November 2018)
    + Desktop
        +
      • Only one structure is loaded when several sequences and structures are selected for viewing/superposing
      • Alignment doesn't appear to scroll vertically via trackpad and scrollwheel
      • Jalview hangs if up/down arrows pressed in cursor mode when cursor lies in hidden region at start of alignment
      • Helix annotation has 'notches' when scrolled into view if columns are hidden
      • Annotation column filter can be slow to reset (ie after hitting cancel) for large numbers of hidden columns
      • -
      • User preference for disabling inclusion of sequence limits when exporting as flat file has no effect
      • -
          +
        • User preference for disabling inclusion of sequence limits when exporting as flat file has no effect
        • +
        • Reproducible cross-reference relationships when retrieving sequences from EnsemblGenomes
        • +
        +
    diff --git a/help/html/whatsNew.html b/help/html/whatsNew.html index 4bf1cec..d3972f5 100755 --- a/help/html/whatsNew.html +++ b/help/html/whatsNew.html @@ -24,27 +24,15 @@

    - What's new in Jalview 2.10.3 ? + What's new in Jalview 2.10.4 ?

    - Version 2.10.3 was released in November 2017. The major focus was to - improve Jalview's sequence features datamodel and the scalability of - the alignment rendering system. The full list of bug fixes and new - features can be found in the 2.10.3 - Release Notes. Key improvements include: + This is the February 2018 release of Jalview, with several minor bug fixes and enhanvements. + The full list bugs fixed in this release can be found in the 2.10.4 + Release Notes. In addition, Jalview 2.10.4 provides:

      -
    • Faster and more responsive UI when importing and working - with wide alignments and handling hundreds and thousands of - sequence features
    • -
    • Improved usability with PDB and UniProt Free Text - Search dialog, and new tab for retrieval of sequences for lists of - IDs. -
    • -
    • Short names assigned to sequences retrieved from UniProt
    • -
    • Groovy console upgraded to 2.4.12 (improved support for Java 9)
    • +

    Experimental Features diff --git a/resources/images/idwidth.gif b/resources/images/idwidth.gif deleted file mode 100755 index c1bd8cb..0000000 Binary files a/resources/images/idwidth.gif and /dev/null differ diff --git a/resources/lang/Messages.properties b/resources/lang/Messages.properties index 94f7eff..f526699 100644 --- a/resources/lang/Messages.properties +++ b/resources/lang/Messages.properties @@ -673,7 +673,8 @@ label.2d_rna_structure_line = 2D RNA {0} (alignment) label.2d_rna_sequence_name = 2D RNA - {0} label.edit_name_and_description_current_group = Edit name and description of current group label.from_file = From File -label.enter_pdb_id = Enter PDB Id (or pdbid:chaincode) +label.enter_pdb_id = Enter PDB Id +label.enter_pdb_id_tip = Enter PDB Id (or pdbid:chaincode) label.text_colour = Text Colour... label.structure = Structure label.show_pdbstruct_dialog = 3D Structure Data... @@ -1319,6 +1320,13 @@ label.select_hidden_colour = Select hidden colour label.overview = Overview label.reset_to_defaults = Reset to defaults label.oview_calc = Recalculating overview... -option.enable_disable_autosearch = When ticked, search is performed automatically. +option.enable_disable_autosearch = When ticked, search is performed automatically option.autosearch = Autosearch -label.retrieve_ids = Retrieve IDs \ No newline at end of file +label.retrieve_ids = Retrieve IDs +label.best_quality = Best Quality +label.best_resolution = Best Resolution +label.most_protein_chain = Most Protein Chain +label.most_bound_molecules = Most Bound Molecules +label.most_polymer_residues = Most Polymer Residues +label.cached_structures = Cached Structures +label.free_text_search = Free Text Search diff --git a/resources/lang/Messages_es.properties b/resources/lang/Messages_es.properties index e8fd411..77f053e 100644 --- a/resources/lang/Messages_es.properties +++ b/resources/lang/Messages_es.properties @@ -626,6 +626,7 @@ label.2d_rna_sequence_name = 2D RNA - {0} label.edit_name_and_description_current_group = Editar el nombre y la descripción del grupo actual label.from_file = desde fichero label.enter_pdb_id = Introducir PDB Id +label.enter_pdb_id_tip = Introducir PDB Id (o pdbid:chaincode) label.text_colour = Color de texto... label.structure = Estructura label.create_sequence_details_report_annotation_for = Anotación para {0} @@ -1319,3 +1320,13 @@ label.select_hidden_colour = Seleccionar color de las regiones ocultas label.overview = Resumen label.reset_to_defaults = Restablecen a los predeterminados label.oview_calc = Recalculando resumen +option.enable_disable_autosearch = Marcar para buscar automáticamente +option.autosearch = Auto búsqueda +label.retrieve_ids = Recuperar IDs +label.best_quality = Mejor Calidad +label.best_resolution = Mejor Resolución +label.most_protein_chain = Más Cadena de Proteína +label.most_bound_molecules = Más Moléculas Ligadas +label.most_polymer_residues = Más Residuos de Polímeros +label.cached_structures = Estructuras en Caché +label.free_text_search = Búsqueda de texto libre diff --git a/src/MCview/PDBChain.java b/src/MCview/PDBChain.java index f4bd31c..29b994e 100755 --- a/src/MCview/PDBChain.java +++ b/src/MCview/PDBChain.java @@ -162,6 +162,50 @@ public class PDBChain } /** + * 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 * @@ -550,6 +594,12 @@ public class PDBChain { 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) diff --git a/src/jalview/analysis/AlignmentUtils.java b/src/jalview/analysis/AlignmentUtils.java index 90d9197..343ebc7 100644 --- a/src/jalview/analysis/AlignmentUtils.java +++ b/src/jalview/analysis/AlignmentUtils.java @@ -117,7 +117,7 @@ public class AlignmentUtils */ public static AlignmentI expandContext(AlignmentI core, int flankSize) { - List sq = new ArrayList(); + List sq = new ArrayList<>(); int maxoffset = 0; for (SequenceI s : core.getSequences()) { @@ -247,7 +247,7 @@ public class AlignmentUtils public static Map> getSequencesByName( AlignmentI al) { - Map> theMap = new LinkedHashMap>(); + Map> theMap = new LinkedHashMap<>(); for (SequenceI seq : al.getSequences()) { String name = seq.getName(); @@ -256,7 +256,7 @@ public class AlignmentUtils List seqs = theMap.get(name); if (seqs == null) { - seqs = new ArrayList(); + seqs = new ArrayList<>(); theMap.put(name, seqs); } seqs.add(seq); @@ -283,8 +283,8 @@ public class AlignmentUtils return false; } - Set mappedDna = new HashSet(); - Set mappedProtein = new HashSet(); + Set mappedDna = new HashSet<>(); + Set mappedProtein = new HashSet<>(); /* * First pass - map sequences where cross-references exist. This include @@ -870,7 +870,7 @@ public class AlignmentUtils System.err.println("Wrong alignment type in alignProteinAsDna"); return 0; } - List unmappedProtein = new ArrayList(); + List unmappedProtein = new ArrayList<>(); Map> alignedCodons = buildCodonColumnsMap( protein, dna, unmappedProtein); return alignProteinAs(protein, alignedCodons, unmappedProtein); @@ -1081,7 +1081,7 @@ public class AlignmentUtils * {dnaSequence, {proteinSequence, codonProduct}} at that position. The * comparator keeps the codon positions ordered. */ - Map> alignedCodons = new TreeMap>( + Map> alignedCodons = new TreeMap<>( new CodonComparator()); for (SequenceI dnaSeq : dna.getSequences()) @@ -1127,9 +1127,9 @@ public class AlignmentUtils // TODO delete this ugly hack once JAL-2022 is resolved // i.e. we can model startPhase > 0 (incomplete start codon) - List sequencesChecked = new ArrayList(); + List sequencesChecked = new ArrayList<>(); AlignedCodon lastCodon = null; - Map toAdd = new HashMap(); + Map toAdd = new HashMap<>(); for (Entry> entry : alignedCodons .entrySet()) @@ -1308,7 +1308,7 @@ public class AlignmentUtils Map seqProduct = alignedCodons.get(codon); if (seqProduct == null) { - seqProduct = new HashMap(); + seqProduct = new HashMap<>(); alignedCodons.put(codon, seqProduct); } seqProduct.put(protein, codon); @@ -1445,7 +1445,7 @@ public class AlignmentUtils { continue; } - final List result = new ArrayList(); + final List result = new ArrayList<>(); for (AlignmentAnnotation dsann : datasetAnnotations) { /* @@ -1627,13 +1627,13 @@ public class AlignmentUtils throw new IllegalArgumentException( "IMPLEMENTATION ERROR: dataset.getDataset() must be null!"); } - List foundSeqs = new ArrayList(); - List cdsSeqs = new ArrayList(); + List foundSeqs = new ArrayList<>(); + List cdsSeqs = new ArrayList<>(); List mappings = dataset.getCodonFrames(); HashSet productSeqs = null; if (products != null) { - productSeqs = new HashSet(); + productSeqs = new HashSet<>(); for (SequenceI seq : products) { productSeqs.add(seq.getDatasetSequence() == null ? seq @@ -1833,7 +1833,7 @@ public class AlignmentUtils * @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 mappings, @@ -1858,7 +1858,15 @@ public class AlignmentUtils 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; + } } /* @@ -1883,10 +1891,12 @@ public class AlignmentUtils { /* * 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 dnaToCdsMaps = MappingUtils .findMappingsForSequence(cdsSeq, seqMappings); if (!dnaToCdsMaps.isEmpty()) @@ -2002,8 +2012,8 @@ public class AlignmentUtils { // gather direct refs from contig congrent with mapping - List direct = new ArrayList(); - HashSet directSources = new HashSet(); + List direct = new ArrayList<>(); + HashSet directSources = new HashSet<>(); if (contig.getDBRefs() != null) { for (DBRefEntry dbr : contig.getDBRefs()) @@ -2023,7 +2033,7 @@ public class AlignmentUtils DBRefEntry[] onSource = DBRefUtils.selectRefs( proteinProduct.getDBRefs(), directSources.toArray(new String[0])); - List propagated = new ArrayList(); + List propagated = new ArrayList<>(); // and generate appropriate mappings for (DBRefEntry cdsref : direct) @@ -2180,12 +2190,13 @@ public class AlignmentUtils 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(); @@ -2202,7 +2213,7 @@ public class AlignmentUtils proteinStart++; proteinLength--; } - List proteinRange = new ArrayList(); + List proteinRange = new ArrayList<>(); /* * dna length should map to protein (or protein plus stop codon) @@ -2237,7 +2248,7 @@ public class AlignmentUtils */ public static List findCdsPositions(SequenceI dnaSeq) { - List result = new ArrayList(); + List result = new ArrayList<>(); List sfs = dnaSeq.getFeatures().getFeaturesByOntology( SequenceOntologyI.CDS); @@ -2523,7 +2534,7 @@ public class AlignmentUtils * map from peptide position to all variants of the codon which codes for it * LinkedHashMap ensures we keep the peptide features in sequence order */ - LinkedHashMap[]> variants = new LinkedHashMap[]>(); + LinkedHashMap[]> variants = new LinkedHashMap<>(); List dnaFeatures = dnaSeq.getFeatures() .getFeaturesByOntology(SequenceOntologyI.SEQUENCE_VARIANT); @@ -2558,9 +2569,9 @@ public class AlignmentUtils if (codonVariants == null) { codonVariants = new ArrayList[CODON_LENGTH]; - codonVariants[0] = new ArrayList(); - codonVariants[1] = new ArrayList(); - codonVariants[2] = new ArrayList(); + codonVariants[0] = new ArrayList<>(); + codonVariants[1] = new ArrayList<>(); + codonVariants[2] = new ArrayList<>(); variants.put(peptidePosition, codonVariants); } @@ -2699,7 +2710,7 @@ public class AlignmentUtils /* * fancy case - aligning via mappings between sequences */ - List unmapped = new ArrayList(); + List unmapped = new ArrayList<>(); Map> columnMap = buildMappedColumnsMap( unaligned, aligned, unmapped); int width = columnMap.size(); @@ -2774,7 +2785,7 @@ public class AlignmentUtils } // map from dataset sequence to alignment sequence(s) - Map> alignedDatasets = new HashMap>(); + Map> alignedDatasets = new HashMap<>(); for (SequenceI seq : aligned.getSequences()) { SequenceI ds = seq.getDatasetSequence(); @@ -2837,7 +2848,7 @@ public class AlignmentUtils * {unalignedSequence, characterPerSequence} at that position. * TreeMap keeps the entries in ascending column order. */ - SortedMap> map = new TreeMap>(); + SortedMap> map = new TreeMap<>(); /* * record any sequences that have no mapping so can't be realigned @@ -2942,7 +2953,7 @@ public class AlignmentUtils Map seqsMap = map.get(fromCol); if (seqsMap == null) { - seqsMap = new HashMap(); + seqsMap = new HashMap<>(); map.put(fromCol, seqsMap); } seqsMap.put(seq, seq.getCharAt(mappedCharPos - toStart)); diff --git a/src/jalview/api/structures/JalviewStructureDisplayI.java b/src/jalview/api/structures/JalviewStructureDisplayI.java index fd66388..b4612cf 100644 --- a/src/jalview/api/structures/JalviewStructureDisplayI.java +++ b/src/jalview/api/structures/JalviewStructureDisplayI.java @@ -62,4 +62,11 @@ public interface JalviewStructureDisplayI */ void setJalviewColourScheme(ColourSchemeI colourScheme); + /** + * + * @return true if all background sequence/structure binding threads have + * completed for this viewer instance + */ + boolean hasMapping(); + } diff --git a/src/jalview/appletgui/AnnotationLabels.java b/src/jalview/appletgui/AnnotationLabels.java index d8f65a5..d8e7007 100755 --- a/src/jalview/appletgui/AnnotationLabels.java +++ b/src/jalview/appletgui/AnnotationLabels.java @@ -31,6 +31,7 @@ import jalview.util.ParseHtmlBodyAndLinks; import java.awt.Checkbox; import java.awt.CheckboxMenuItem; import java.awt.Color; +import java.awt.Cursor; import java.awt.Dimension; import java.awt.FlowLayout; import java.awt.FontMetrics; @@ -57,6 +58,16 @@ public class AnnotationLabels extends Panel { 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; @@ -92,23 +103,6 @@ public class AnnotationLabels extends Panel 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); } @@ -268,7 +262,10 @@ public class AnnotationLabels extends Panel @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); if (row > -1) @@ -406,6 +403,7 @@ public class AnnotationLabels extends Panel resizePanel = false; dragEvent = null; dragCancelled = false; + setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); repaint(); ap.annotationPanel.repaint(); } @@ -418,6 +416,8 @@ public class AnnotationLabels extends Panel resizePanel = true; repaint(); } + setCursor(Cursor.getPredefinedCursor( + resizePanel ? Cursor.S_RESIZE_CURSOR : Cursor.DEFAULT_CURSOR)); } @Override @@ -903,14 +903,8 @@ public class AnnotationLabels extends Panel } } 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(), diff --git a/src/jalview/appletgui/IdwidthAdjuster.java b/src/jalview/appletgui/IdwidthAdjuster.java index 75e3243..2602268 100755 --- a/src/jalview/appletgui/IdwidthAdjuster.java +++ b/src/jalview/appletgui/IdwidthAdjuster.java @@ -21,9 +21,8 @@ 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; @@ -36,29 +35,24 @@ public class IdwidthAdjuster extends Panel 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); } + @Override public void mousePressed(MouseEvent evt) { oldX = evt.getX(); } + @Override public void mouseReleased(MouseEvent evt) { active = false; @@ -85,18 +79,24 @@ public class IdwidthAdjuster extends Panel // } } + @Override public void mouseEntered(MouseEvent evt) { active = true; + setCursor(Cursor.getPredefinedCursor(Cursor.W_RESIZE_CURSOR)); + repaint(); } + @Override public void mouseExited(MouseEvent evt) { active = false; + setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); repaint(); } + @Override public void mouseDragged(MouseEvent evt) { active = true; @@ -112,25 +112,13 @@ public class IdwidthAdjuster extends Panel } } + @Override public void mouseMoved(MouseEvent evt) { } + @Override public void mouseClicked(MouseEvent evt) { } - - 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); - } - } - } - } diff --git a/src/jalview/appletgui/OverviewPanel.java b/src/jalview/appletgui/OverviewPanel.java index 8ce597d..3bbbe95 100755 --- a/src/jalview/appletgui/OverviewPanel.java +++ b/src/jalview/appletgui/OverviewPanel.java @@ -155,6 +155,10 @@ public class OverviewPanel extends Panel implements Runnable, 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()); @@ -172,6 +176,7 @@ public class OverviewPanel extends Panel implements Runnable, @Override public void mouseReleased(MouseEvent evt) { + draggingBox = false; } @Override diff --git a/src/jalview/datamodel/Alignment.java b/src/jalview/datamodel/Alignment.java index f268d37..a3b3ff6 100755 --- a/src/jalview/datamodel/Alignment.java +++ b/src/jalview/datamodel/Alignment.java @@ -49,7 +49,7 @@ public class Alignment implements AlignmentI { private Alignment dataset; - protected List sequences; + private List sequences; protected List groups; @@ -198,6 +198,7 @@ public class Alignment implements AlignmentI return sequences.get(i); } } + return null; } @@ -706,7 +707,7 @@ public class Alignment implements AlignmentI public int getWidth() { int maxLength = -1; - + for (int i = 0; i < sequences.size(); i++) { if (getSequenceAt(i).getLength() > maxLength) @@ -714,9 +715,34 @@ public class Alignment implements AlignmentI maxLength = getSequenceAt(i).getLength(); } } - + return maxLength; } + /* + @Override + public int getWidth() + { + final Wrapper temp = new Wrapper(); + + forEachSequence(new Consumer() + { + @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! @@ -1603,7 +1629,10 @@ public class Alignment implements AlignmentI 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) { diff --git a/src/jalview/ext/ensembl/EnsemblCdna.java b/src/jalview/ext/ensembl/EnsemblCdna.java index 6d031b7..952f01e 100644 --- a/src/jalview/ext/ensembl/EnsemblCdna.java +++ b/src/jalview/ext/ensembl/EnsemblCdna.java @@ -24,9 +24,6 @@ import jalview.datamodel.SequenceFeature; import jalview.io.gff.SequenceOntologyFactory; import jalview.io.gff.SequenceOntologyI; -import java.util.HashMap; -import java.util.Map; - import com.stevesoft.pat.Regex; /** @@ -47,13 +44,6 @@ public class EnsemblCdna extends EnsemblSeqProxy private static final Regex ACCESSION_REGEX = new Regex( "(ENS([A-Z]{3}|)[TG][0-9]{11}$)" + "|" + "(CCDS[0-9.]{3,}$)"); - private static Map params = new HashMap(); - - static - { - params.put("object_type", "transcript"); - } - /* * fetch exon features on genomic sequence (to identify the cdna regions) * and cds and variation features (to retain) @@ -139,13 +129,13 @@ public class EnsemblCdna extends EnsemblSeqProxy } /** - * Parameter object_type=cdna added to ensure cdna and not peptide is returned - * (JAL-2529) + * Parameter object_type=Transcaript added to ensure cdna and not peptide is + * returned (JAL-2529) */ @Override - protected Map getAdditionalParameters() + protected String getObjectType() { - return params; + return OBJECT_TYPE_TRANSCRIPT; } } diff --git a/src/jalview/ext/ensembl/EnsemblFeatures.java b/src/jalview/ext/ensembl/EnsemblFeatures.java index 7570822..cb6f548 100644 --- a/src/jalview/ext/ensembl/EnsemblFeatures.java +++ b/src/jalview/ext/ensembl/EnsemblFeatures.java @@ -82,7 +82,7 @@ class EnsemblFeatures extends EnsemblRestClient public AlignmentI getSequenceRecords(String query) throws IOException { // TODO: use a vararg String... for getSequenceRecords instead? - List queries = new ArrayList(); + List queries = new ArrayList<>(); queries.add(query); FileParse fp = getSequenceReader(queries); if (fp == null || !fp.isValid()) @@ -109,9 +109,17 @@ class EnsemblFeatures extends EnsemblRestClient urlstring.append("?content-type=text/x-gff3"); /* + * specify object_type=gene in case is shared by transcript and/or protein; + * currently only fetching features for gene sequences; + * refactor in future if needed to fetch for transcripts + */ + urlstring.append("&").append(OBJECT_TYPE).append("=") + .append(OBJECT_TYPE_GENE); + + /* * specify features to retrieve * @see http://rest.ensembl.org/documentation/info/overlap_id - * could make the list a configurable entry in jalview.properties + * could make the list a configurable entry in .jalview_properties */ for (EnsemblFeatureType feature : featuresWanted) { diff --git a/src/jalview/ext/ensembl/EnsemblGene.java b/src/jalview/ext/ensembl/EnsemblGene.java index 50dfa90..0d5fc26 100644 --- a/src/jalview/ext/ensembl/EnsemblGene.java +++ b/src/jalview/ext/ensembl/EnsemblGene.java @@ -98,6 +98,12 @@ public class EnsemblGene extends EnsemblSeqProxy return EnsemblSeqType.GENOMIC; } + @Override + protected String getObjectType() + { + return OBJECT_TYPE_GENE; + } + /** * Returns an alignment containing the gene(s) for the given gene or * transcript identifier, or external identifier (e.g. Uniprot id). If given a @@ -146,6 +152,8 @@ public class EnsemblGene extends EnsemblSeqProxy } if (geneAlignment.getHeight() == 1) { + // ensure id has 'correct' case for the Ensembl identifier + geneId = geneAlignment.getSequenceAt(0).getName(); getTranscripts(geneAlignment, geneId); } if (al == null) @@ -170,7 +178,7 @@ public class EnsemblGene extends EnsemblSeqProxy */ List getGeneIds(String accessions) { - List geneIds = new ArrayList(); + List geneIds = new ArrayList<>(); for (String acc : accessions.split(getAccessionSeparator())) { @@ -305,7 +313,7 @@ public class EnsemblGene extends EnsemblSeqProxy int transcriptLength = 0; final char[] geneChars = gene.getSequence(); int offset = gene.getStart(); // to convert to 0-based positions - List mappedFrom = new ArrayList(); + List mappedFrom = new ArrayList<>(); for (SequenceFeature sf : splices) { @@ -347,7 +355,7 @@ public class EnsemblGene extends EnsemblSeqProxy * transfer features to the new sequence; we use EnsemblCdna to do this, * to filter out unwanted features types (see method retainFeature) */ - List mapTo = new ArrayList(); + List mapTo = new ArrayList<>(); mapTo.add(new int[] { 1, transcriptLength }); MapList mapping = new MapList(mappedFrom, mapTo, 1, 1); EnsemblCdna cdna = new EnsemblCdna(getDomain()); @@ -395,7 +403,7 @@ public class EnsemblGene extends EnsemblSeqProxy protected List getTranscriptFeatures(String accId, SequenceI geneSequence) { - List transcriptFeatures = new ArrayList(); + List transcriptFeatures = new ArrayList<>(); String parentIdentifier = GENE_PREFIX + accId; @@ -407,7 +415,7 @@ public class EnsemblGene extends EnsemblSeqProxy for (SequenceFeature sf : sfs) { String parent = (String) sf.getValue(PARENT); - if (parentIdentifier.equals(parent)) + if (parentIdentifier.equalsIgnoreCase(parent)) { transcriptFeatures.add(sf); } @@ -444,8 +452,9 @@ public class EnsemblGene extends EnsemblSeqProxy if (SequenceOntologyFactory.getInstance().isA(sf.getType(), SequenceOntologyI.GENE)) { - String id = (String) sf.getValue(ID); - if ((GENE_PREFIX + accId).equals(id)) + // NB features as gff use 'ID'; rest services return as 'id' + String id = (String) sf.getValue("ID"); + if ((GENE_PREFIX + accId).equalsIgnoreCase(id)) { return true; } @@ -472,7 +481,7 @@ public class EnsemblGene extends EnsemblSeqProxy if (isTranscript(type)) { String parent = (String) sf.getValue(PARENT); - if (!(GENE_PREFIX + accessionId).equals(parent)) + if (!(GENE_PREFIX + accessionId).equalsIgnoreCase(parent)) { return false; } diff --git a/src/jalview/ext/ensembl/EnsemblGenome.java b/src/jalview/ext/ensembl/EnsemblGenome.java index 458a233..bde3c0f 100644 --- a/src/jalview/ext/ensembl/EnsemblGenome.java +++ b/src/jalview/ext/ensembl/EnsemblGenome.java @@ -103,7 +103,7 @@ public class EnsemblGenome extends EnsemblSeqProxy { if (isTranscript(sf.getType())) { - String id = (String) sf.getValue(ID); + String id = (String) sf.getValue("ID"); if (("transcript:" + accId).equals(id)) { return true; diff --git a/src/jalview/ext/ensembl/EnsemblLookup.java b/src/jalview/ext/ensembl/EnsemblLookup.java index f31a3f0..0ddef2b 100644 --- a/src/jalview/ext/ensembl/EnsemblLookup.java +++ b/src/jalview/ext/ensembl/EnsemblLookup.java @@ -34,11 +34,10 @@ import org.json.simple.parser.JSONParser; import org.json.simple.parser.ParseException; /** - * A client for the Ensembl lookup REST endpoint; used to find the Parent gene - * identifier given a transcript identifier. + * A client for the Ensembl lookup REST endpoint, used to find the gene + * identifier given a gene, transcript or protein identifier. * * @author gmcarstairs - * */ public class EnsemblLookup extends EnsemblRestClient { @@ -50,6 +49,9 @@ public class EnsemblLookup extends EnsemblRestClient private static final String OBJECT_TYPE_GENE = "Gene"; private static final String OBJECT_TYPE = "object_type"; + /** + * keep track of last identifier retrieved to break loops + */ private String lastId; /** @@ -86,17 +88,26 @@ public class EnsemblLookup extends EnsemblRestClient protected URL getUrl(List ids) throws MalformedURLException { String identifier = ids.get(0); - return getUrl(identifier); + return getUrl(identifier, null); } /** + * Gets the url for lookup of the given identifier, optionally with objectType + * also specified in the request + * * @param identifier + * @param objectType * @return */ - protected URL getUrl(String identifier) + protected URL getUrl(String identifier, String objectType) { String url = getDomain() + "/lookup/id/" + identifier + CONTENT_TYPE_JSON; + if (objectType != null) + { + url += "&" + OBJECT_TYPE + "=" + objectType; + } + try { return new URL(url); @@ -125,27 +136,45 @@ public class EnsemblLookup extends EnsemblRestClient } /** + * Returns the gene id related to the given identifier, which may be for a + * gene, transcript or protein + * + * @param identifier + * @return + */ + public String getGeneId(String identifier) + { + return getGeneId(identifier, null); + } + + /** * Calls the Ensembl lookup REST endpoint and retrieves the 'Parent' for the * given identifier, or null if not found * * @param identifier + * @param objectType + * (optional) * @return */ - public String getGeneId(String identifier) + public String getGeneId(String identifier, String objectType) { List ids = Arrays.asList(new String[] { identifier }); BufferedReader br = null; try { - URL url = getUrl(identifier); + + 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); @@ -190,28 +219,19 @@ public class EnsemblLookup extends EnsemblRestClient String type = val.get(OBJECT_TYPE).toString(); if (OBJECT_TYPE_GENE.equalsIgnoreCase(type)) { + // got the gene - just returns its id geneId = val.get(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(); - try - { - geneId = getGeneId(transcriptId); - } catch (StackOverflowError e) - { - /* - * unlikely data condition error! - */ - System.err - .println("** Ensembl lookup " - + getUrl(transcriptId).toString() - + " looping on Parent!"); - } + geneId = getGeneId(transcriptId, OBJECT_TYPE_TRANSCRIPT); } } catch (ParseException e) { diff --git a/src/jalview/ext/ensembl/EnsemblSeqProxy.java b/src/jalview/ext/ensembl/EnsemblSeqProxy.java index 577111e..b2ebb1a 100644 --- a/src/jalview/ext/ensembl/EnsemblSeqProxy.java +++ b/src/jalview/ext/ensembl/EnsemblSeqProxy.java @@ -48,8 +48,6 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; -import java.util.Map; -import java.util.Map.Entry; /** * Base class for Ensembl sequence fetchers @@ -61,10 +59,6 @@ public abstract class EnsemblSeqProxy extends EnsemblRestClient { private static final String ALLELES = "alleles"; - protected static final String PARENT = "Parent"; - - protected static final String ID = "ID"; - protected static final String NAME = "Name"; protected static final String DESCRIPTION = "description"; @@ -209,7 +203,8 @@ public abstract class EnsemblSeqProxy extends EnsemblRestClient try { /* - * get 'dummy' genomic sequence with exon, cds and variation features + * get 'dummy' genomic sequence with gene, transcript, + * exon, cds and variation features */ SequenceI genomicSequence = null; EnsemblFeatures gffFetcher = new EnsemblFeatures(getDomain()); @@ -225,7 +220,7 @@ public abstract class EnsemblSeqProxy extends EnsemblRestClient /* * transfer features to the query sequence */ - SequenceI querySeq = alignment.findName(accId); + SequenceI querySeq = alignment.findName(accId, true); if (transferFeatures(accId, genomicSequence, querySeq)) { @@ -472,14 +467,11 @@ public abstract class EnsemblSeqProxy extends EnsemblRestClient urlstring.append("?type=").append(getSourceEnsemblType().getType()); urlstring.append(("&Accept=text/x-fasta")); - Map params = getAdditionalParameters(); - if (params != null) + String objectType = getObjectType(); + if (objectType != null) { - for (Entry entry : params.entrySet()) - { - urlstring.append("&").append(entry.getKey()).append("=") - .append(entry.getValue()); - } + urlstring.append("&").append(OBJECT_TYPE).append("=") + .append(objectType); } URL url = new URL(urlstring.toString()); @@ -487,11 +479,11 @@ public abstract class EnsemblSeqProxy extends EnsemblRestClient } /** - * Override this method to add any additional x=y URL parameters needed + * Override this method to specify object_type request parameter * * @return */ - protected Map getAdditionalParameters() + protected String getObjectType() { return null; } @@ -560,7 +552,6 @@ public abstract class EnsemblSeqProxy extends EnsemblRestClient protected MapList getGenomicRangesFromFeatures(SequenceI sourceSequence, String accId, int start) { - // SequenceFeature[] sfs = sourceSequence.getSequenceFeatures(); List sfs = sourceSequence.getFeatures() .getPositionalFeatures(); if (sfs.isEmpty()) @@ -572,7 +563,7 @@ public abstract class EnsemblSeqProxy extends EnsemblRestClient * generously initial size for number of cds regions * (worst case titin Q8WZ42 has c. 313 exons) */ - List regions = new ArrayList(100); + List regions = new ArrayList<>(100); int mappedLength = 0; int direction = 1; // forward boolean directionSet = false; @@ -871,7 +862,8 @@ public abstract class EnsemblSeqProxy extends EnsemblRestClient { String parent = (String) sf.getValue(PARENT); // using contains to allow for prefix "gene:", "transcript:" etc - if (parent != null && !parent.contains(identifier)) + if (parent != null + && !parent.toUpperCase().contains(identifier.toUpperCase())) { // this genomic feature belongs to a different transcript return false; @@ -899,14 +891,14 @@ public abstract class EnsemblSeqProxy extends EnsemblRestClient protected List findFeatures(SequenceI sequence, String term, String parentId) { - List result = new ArrayList(); + List result = new ArrayList<>(); List sfs = sequence.getFeatures() .getFeaturesByOntology(term); for (SequenceFeature sf : sfs) { String parent = (String) sf.getValue(PARENT); - if (parent != null && parent.equals(parentId)) + if (parent != null && parent.equalsIgnoreCase(parentId)) { result.add(sf); } diff --git a/src/jalview/ext/ensembl/EnsemblSequenceFetcher.java b/src/jalview/ext/ensembl/EnsemblSequenceFetcher.java index eb1d399..0aaaf93 100644 --- a/src/jalview/ext/ensembl/EnsemblSequenceFetcher.java +++ b/src/jalview/ext/ensembl/EnsemblSequenceFetcher.java @@ -56,6 +56,18 @@ abstract class EnsemblSequenceFetcher extends DbSourceProxyImpl protected final String ensemblDomain; + protected static final String OBJECT_TYPE_TRANSLATION = "Translation"; + + protected static final String OBJECT_TYPE_TRANSCRIPT = "Transcript"; + + protected static final String OBJECT_TYPE_GENE = "Gene"; + + protected static final String PARENT = "Parent"; + + protected static final String ID = "id"; + + protected static final String OBJECT_TYPE = "object_type"; + /* * possible values for the 'feature' parameter of the /overlap REST service * @see http://rest.ensembl.org/documentation/info/overlap_id diff --git a/src/jalview/ext/ensembl/EnsemblSymbol.java b/src/jalview/ext/ensembl/EnsemblSymbol.java index 75598a0..e3b6c93 100644 --- a/src/jalview/ext/ensembl/EnsemblSymbol.java +++ b/src/jalview/ext/ensembl/EnsemblSymbol.java @@ -44,8 +44,6 @@ public class EnsemblSymbol extends EnsemblXref { private static final String GENE = "gene"; private static final String TYPE = "type"; - private static final String ID = "id"; - /** * Constructor given the target domain to fetch data from * diff --git a/src/jalview/ext/jmol/JmolCommands.java b/src/jalview/ext/jmol/JmolCommands.java index 6bf7010..8fb0de6 100644 --- a/src/jalview/ext/jmol/JmolCommands.java +++ b/src/jalview/ext/jmol/JmolCommands.java @@ -77,7 +77,6 @@ public class JmolCommands continue; } - int lastPos = -1; for (int s = 0; s < sequence[pdbfnum].length; s++) { for (int sp, m = 0; m < mapping.length; m++) @@ -85,6 +84,7 @@ public class JmolCommands 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++) { @@ -95,10 +95,22 @@ public class JmolCommands } 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; @@ -128,7 +140,12 @@ public class JmolCommands // 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 diff --git a/src/jalview/fts/core/GFTSPanel.java b/src/jalview/fts/core/GFTSPanel.java index 9802d4b..86710e1 100644 --- a/src/jalview/fts/core/GFTSPanel.java +++ b/src/jalview/fts/core/GFTSPanel.java @@ -92,7 +92,7 @@ public abstract class GFTSPanel extends JPanel implements GFTSPanelI protected JTabbedPane tabs = new JTabbedPane(); protected IProgressIndicator progressIndicator; - protected JComboBox cmb_searchTarget = new JComboBox(); + protected JComboBox cmb_searchTarget = new JComboBox<>(); protected JButton btn_ok = new JButton(); @@ -151,7 +151,7 @@ public abstract class GFTSPanel extends JPanel implements GFTSPanelI protected int pageLimit; - protected HashSet paginatorCart = new HashSet(); + protected HashSet paginatorCart = new HashSet<>(); private static final int MIN_WIDTH = 670; @@ -293,7 +293,7 @@ public abstract class GFTSPanel extends JPanel implements GFTSPanelI private void jbInit() throws Exception { - txt_search = new JvCacheableInputBox(getCacheKey()); + txt_search = new JvCacheableInputBox<>(getCacheKey()); populateCmbSearchTargetOptions(); Integer width = getTempUserPrefs().get("FTSPanel.width") == null ? 800 : getTempUserPrefs().get("FTSPanel.width"); @@ -681,7 +681,8 @@ public abstract class GFTSPanel extends JPanel implements GFTSPanelI if (tabs != null) { tabs.setOpaque(true); - tabs.insertTab("Free Text Search", null, this, "", 0); + tabs.insertTab(MessageManager.getString("label.free_text_search"), + null, this, "", 0); mainFrame.setContentPane(tabs); tabs.setVisible(true); } @@ -871,7 +872,7 @@ public abstract class GFTSPanel extends JPanel implements GFTSPanelI */ public void populateCmbSearchTargetOptions() { - List searchableTargets = new ArrayList(); + List searchableTargets = new ArrayList<>(); try { Collection foundFTSTargets = getFTSRestClient() diff --git a/src/jalview/gui/AlignFrame.java b/src/jalview/gui/AlignFrame.java index 298688b..e10ff4a 100644 --- a/src/jalview/gui/AlignFrame.java +++ b/src/jalview/gui/AlignFrame.java @@ -4865,14 +4865,15 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, 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()); }; }); diff --git a/src/jalview/gui/AlignmentPanel.java b/src/jalview/gui/AlignmentPanel.java index 3a1dbe8..68b1998 100644 --- a/src/jalview/gui/AlignmentPanel.java +++ b/src/jalview/gui/AlignmentPanel.java @@ -874,15 +874,17 @@ public class AlignmentPanel extends GAlignmentPanel implements @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()); @@ -1813,35 +1815,6 @@ public class AlignmentPanel extends GAlignmentPanel implements */ 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 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); } diff --git a/src/jalview/gui/AnnotationLabels.java b/src/jalview/gui/AnnotationLabels.java index b94a615..15f1fe0 100755 --- a/src/jalview/gui/AnnotationLabels.java +++ b/src/jalview/gui/AnnotationLabels.java @@ -20,6 +20,7 @@ */ package jalview.gui; +import jalview.analysis.AlignSeq; import jalview.analysis.AlignmentUtils; import jalview.datamodel.Alignment; import jalview.datamodel.AlignmentAnnotation; @@ -29,16 +30,17 @@ import jalview.datamodel.SequenceGroup; import jalview.datamodel.SequenceI; import jalview.io.FileFormat; import jalview.io.FormatAdapter; +import jalview.util.Comparison; import jalview.util.MessageManager; +import jalview.util.Platform; import java.awt.Color; +import java.awt.Cursor; import java.awt.Dimension; import java.awt.Font; 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; @@ -48,7 +50,6 @@ import java.awt.event.MouseEvent; 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; @@ -62,63 +63,74 @@ import javax.swing.SwingUtilities; import javax.swing.ToolTipManager; /** - * DOCUMENT ME! - * - * @author $author$ - * @version $Revision$ + * The panel that holds the labels for alignment annotations, providing + * tooltips, context menus, drag to reorder rows, and drag to adjust panel + * height */ public class AnnotationLabels extends JPanel implements MouseListener, MouseMotionListener, ActionListener { + /** + * 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("<"); - String TOGGLE_LABELSCALE = MessageManager + private static final Font font = new Font("Arial", Font.PLAIN, 11); + + private static final String TOGGLE_LABELSCALE = MessageManager .getString("label.scale_label_to_column"); - String ADDNEW = MessageManager.getString("label.add_new_row"); + private static final String ADDNEW = MessageManager + .getString("label.add_new_row"); - String EDITNAME = MessageManager + private static final String EDITNAME = MessageManager .getString("label.edit_label_description"); - String HIDE = MessageManager.getString("label.hide_row"); + private static final String HIDE = MessageManager + .getString("label.hide_row"); - String DELETE = MessageManager.getString("label.delete_row"); + private static final String DELETE = MessageManager + .getString("label.delete_row"); - String SHOWALL = MessageManager.getString("label.show_all_hidden_rows"); + private static final String SHOWALL = MessageManager + .getString("label.show_all_hidden_rows"); - String OUTPUT_TEXT = MessageManager.getString("label.export_annotation"); + private static final String OUTPUT_TEXT = MessageManager + .getString("label.export_annotation"); - String COPYCONS_SEQ = MessageManager + private static final String COPYCONS_SEQ = MessageManager .getString("label.copy_consensus_sequence"); - boolean resizePanel = false; - - Image image; + private final boolean debugRedraw = false; - AlignmentPanel ap; + private AlignmentPanel ap; AlignViewport av; - boolean resizing = false; - - MouseEvent dragEvent; + private MouseEvent dragEvent; - int oldY; + private int oldY; - int selectedRow; + private int selectedRow; private int scrollOffset = 0; - Font font = new Font("Arial", Font.PLAIN, 11); - private boolean hasHiddenRows; + private boolean resizePanel = false; + /** - * Creates a new AnnotationLabels object. + * Creates a new AnnotationLabels object * * @param ap - * DOCUMENT ME! */ public AnnotationLabels(AlignmentPanel ap) { @@ -126,30 +138,6 @@ public class AnnotationLabels extends JPanel av = ap.av; ToolTipManager.sharedInstance().registerComponent(this); - 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 = bi; - addMouseListener(this); addMouseMotionListener(this); addMouseWheelListener(ap.getAnnotationPanel()); @@ -607,10 +595,9 @@ public class AnnotationLabels extends JPanel } /** - * DOCUMENT ME! + * Reorders annotation rows after a drag of a label * * @param evt - * DOCUMENT ME! */ @Override public void mouseReleased(MouseEvent evt) @@ -625,6 +612,9 @@ public class AnnotationLabels extends JPanel getSelectedRow(evt.getY() - getScrollOffset()); int end = selectedRow; + /* + * if dragging to resize instead, start == end + */ if (start != end) { // Swap these annotations @@ -648,31 +638,13 @@ public class AnnotationLabels extends JPanel } /** - * DOCUMENT ME! - * - * @param evt - * DOCUMENT ME! - */ - @Override - public void mouseEntered(MouseEvent evt) - { - if (evt.getY() < 10) - { - resizePanel = true; - repaint(); - } - } - - /** - * DOCUMENT ME! - * - * @param evt - * DOCUMENT ME! + * Removes the height adjuster image on leaving the panel, unless currently + * dragging it */ @Override public void mouseExited(MouseEvent evt) { - if (dragEvent == null) + if (resizePanel && dragEvent == null) { resizePanel = false; repaint(); @@ -680,10 +652,11 @@ public class AnnotationLabels extends JPanel } /** - * DOCUMENT ME! + * A mouse drag may be either an adjustment of the panel height (if flag + * resizePanel is set on), or a reordering of the annotation rows. The former + * is dealt with by this method, the latter in mouseReleased. * * @param evt - * DOCUMENT ME! */ @Override public void mouseDragged(MouseEvent evt) @@ -717,15 +690,14 @@ public class AnnotationLabels extends JPanel } /** - * DOCUMENT ME! + * Updates the tooltip as the mouse moves over the labels * * @param evt - * DOCUMENT ME! */ @Override public void mouseMoved(MouseEvent evt) { - resizePanel = evt.getY() < 10; + showOrHideAdjuster(evt); getSelectedRow(evt.getY() - getScrollOffset()); @@ -801,6 +773,26 @@ public class AnnotationLabels extends JPanel } } + /** + * Shows the height adjuster image if the mouse moves into the top left + * region, or hides it if the mouse leaves the regio + * + * @param evt + */ + protected void showOrHideAdjuster(MouseEvent evt) + { + boolean was = resizePanel; + resizePanel = evt.getY() < HEIGHT_ADJUSTER_HEIGHT && evt.getX() < HEIGHT_ADJUSTER_WIDTH; + + if (resizePanel != was) + { + setCursor(Cursor.getPredefinedCursor( + resizePanel ? Cursor.S_RESIZE_CURSOR + : Cursor.DEFAULT_CURSOR)); + repaint(); + } + } + @Override public void mouseClicked(MouseEvent evt) { @@ -820,11 +812,9 @@ public class AnnotationLabels extends JPanel // process modifiers SequenceGroup sg = ap.av.getSelectionGroup(); if (sg == null || sg == aa[selectedRow].groupRef - || !(jalview.util.Platform.isControlDown(evt) - || evt.isShiftDown())) + || !(Platform.isControlDown(evt) || evt.isShiftDown())) { - if (jalview.util.Platform.isControlDown(evt) - || evt.isShiftDown()) + if (Platform.isControlDown(evt) || evt.isShiftDown()) { // clone a new selection group from the associated group ap.av.setSelectionGroup( @@ -883,8 +873,7 @@ public class AnnotationLabels extends JPanel // we make a copy rather than edit the current selection if no // modifiers pressed // see Enhancement JAL-1557 - if (!(jalview.util.Platform.isControlDown(evt) - || evt.isShiftDown())) + if (!(Platform.isControlDown(evt) || evt.isShiftDown())) { sg = new SequenceGroup(sg); sg.clear(); @@ -892,7 +881,7 @@ public class AnnotationLabels extends JPanel } else { - if (jalview.util.Platform.isControlDown(evt)) + if (Platform.isControlDown(evt)) { sg.addOrRemove(aa[selectedRow].sequenceRef, true); } @@ -937,8 +926,8 @@ public class AnnotationLabels extends JPanel if (dseqs[0] == null) { dseqs[0] = new Sequence(sq); - dseqs[0].setSequence(jalview.analysis.AlignSeq.extractGaps( - jalview.util.Comparison.GapChars, sq.getSequenceAsString())); + dseqs[0].setSequence(AlignSeq.extractGaps(Comparison.GapChars, + sq.getSequenceAsString())); sq.setDatasetSequence(dseqs[0]); } @@ -1020,8 +1009,6 @@ public class AnnotationLabels extends JPanel drawComponent(g, false, width); } - private final boolean debugRedraw = false; - /** * Draw the full set of annotation Labels for the alignment at the given * cursor @@ -1204,11 +1191,7 @@ public class AnnotationLabels extends JPanel } } - if (resizePanel) - { - g.drawImage(image, 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(), @@ -1227,4 +1210,9 @@ public class AnnotationLabels extends JPanel { return scrollOffset; } + + @Override + public void mouseEntered(MouseEvent e) + { + } } diff --git a/src/jalview/gui/AnnotationPanel.java b/src/jalview/gui/AnnotationPanel.java index 438e81b..c39a87d 100755 --- a/src/jalview/gui/AnnotationPanel.java +++ b/src/jalview/gui/AnnotationPanel.java @@ -904,6 +904,8 @@ public class AnnotationPanel extends JPanel implements AwtRenderPanelI, @Override public void paintComponent(Graphics g) { + super.paintComponent(g); + g.setColor(Color.white); g.fillRect(0, 0, getWidth(), getHeight()); @@ -959,7 +961,7 @@ public class AnnotationPanel extends JPanel implements AwtRenderPanelI, gg.fillRect(0, 0, imgWidth, image.getHeight()); imageFresh = true; } - + drawComponent(gg, av.getRanges().getStartRes(), av.getRanges().getEndRes() + 1); imageFresh = false; @@ -992,10 +994,8 @@ public class AnnotationPanel extends JPanel implements AwtRenderPanelI, 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 { @@ -1012,17 +1012,13 @@ public class AnnotationPanel extends JPanel implements AwtRenderPanelI, 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; diff --git a/src/jalview/gui/Desktop.java b/src/jalview/gui/Desktop.java index 128481c..5ee9150 100644 --- a/src/jalview/gui/Desktop.java +++ b/src/jalview/gui/Desktop.java @@ -849,6 +849,7 @@ public class Desktop extends jalview.jbgui.GDesktop frame.setResizable(resizable); frame.setMaximizable(resizable); frame.setIconifiable(resizable); + frame.setOpaque(false); if (frame.getX() < 1 && frame.getY() < 1) { diff --git a/src/jalview/gui/IdCanvas.java b/src/jalview/gui/IdCanvas.java index 085b259..8f13eca 100755 --- a/src/jalview/gui/IdCanvas.java +++ b/src/jalview/gui/IdCanvas.java @@ -83,7 +83,7 @@ public class IdCanvas extends JPanel implements ViewportListenerI this.av = av; PaintRefresher.Register(this, av.getSequenceSetId()); av.getRanges().addPropertyChangeListener(this); - } + } /** * DOCUMENT ME! @@ -204,7 +204,11 @@ public class IdCanvas extends JPanel implements ViewportListenerI 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(); } /** @@ -216,41 +220,43 @@ public class IdCanvas extends JPanel implements ViewportListenerI @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); } diff --git a/src/jalview/gui/IdwidthAdjuster.java b/src/jalview/gui/IdwidthAdjuster.java index 8400543..0cffc3b 100755 --- a/src/jalview/gui/IdwidthAdjuster.java +++ b/src/jalview/gui/IdwidthAdjuster.java @@ -23,8 +23,8 @@ package jalview.gui; import jalview.api.AlignViewportI; 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; @@ -44,8 +44,6 @@ public class IdwidthAdjuster extends JPanel int oldX = 0; - Image image; - AlignmentPanel ap; /** @@ -57,14 +55,7 @@ public class IdwidthAdjuster extends JPanel 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); } @@ -196,10 +187,7 @@ public class IdwidthAdjuster extends JPanel if (active) { - if (image != null) - { - g.drawImage(image, getWidth() - 20, 2, this); - } + setCursor(Cursor.getPredefinedCursor(Cursor.W_RESIZE_CURSOR)); } } } diff --git a/src/jalview/gui/OverviewCanvas.java b/src/jalview/gui/OverviewCanvas.java index 2991889..9df0d82 100644 --- a/src/jalview/gui/OverviewCanvas.java +++ b/src/jalview/gui/OverviewCanvas.java @@ -183,7 +183,7 @@ public class OverviewCanvas extends JComponent @Override public void paintComponent(Graphics g) { - // super.paintComponent(g); + super.paintComponent(g); if (restart) { diff --git a/src/jalview/gui/OverviewPanel.java b/src/jalview/gui/OverviewPanel.java index 43b4310..02d54a8 100755 --- a/src/jalview/gui/OverviewPanel.java +++ b/src/jalview/gui/OverviewPanel.java @@ -170,15 +170,20 @@ public class OverviewPanel extends JPanel @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)); + } } } }); @@ -203,6 +208,10 @@ public class OverviewPanel extends JPanel 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()); @@ -225,6 +234,13 @@ public class OverviewPanel extends JPanel showPopupMenu(evt); } } + + @Override + public void mouseReleased(MouseEvent evt) + { + draggingBox = false; + } + }); } diff --git a/src/jalview/gui/ScalePanel.java b/src/jalview/gui/ScalePanel.java index 798c833..cb7f0da 100755 --- a/src/jalview/gui/ScalePanel.java +++ b/src/jalview/gui/ScalePanel.java @@ -409,6 +409,8 @@ public class ScalePanel extends JPanel @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 @@ -554,7 +556,11 @@ public class ScalePanel extends JPanel || 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(); } } diff --git a/src/jalview/gui/SeqCanvas.java b/src/jalview/gui/SeqCanvas.java index 1e1105f..7d182b2 100755 --- a/src/jalview/gui/SeqCanvas.java +++ b/src/jalview/gui/SeqCanvas.java @@ -295,7 +295,7 @@ public class SeqCanvas extends JComponent implements ViewportListenerI int endSeq = ranges.getEndSeq(); int transX = 0; int transY = 0; - + gg.copyArea(horizontal * charWidth, vertical * charHeight, img.getWidth(), img.getHeight(), -horizontal * charWidth, -vertical * charHeight); @@ -337,7 +337,10 @@ public class SeqCanvas extends JComponent implements ViewportListenerI 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; @@ -351,20 +354,20 @@ public class SeqCanvas extends JComponent implements ViewportListenerI 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))) @@ -388,16 +391,16 @@ public class SeqCanvas extends JComponent implements ViewportListenerI 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()); @@ -407,7 +410,7 @@ public class SeqCanvas extends JComponent implements ViewportListenerI 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); @@ -504,8 +507,11 @@ public class SeqCanvas extends JComponent implements ViewportListenerI 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); @@ -545,8 +551,8 @@ public class SeqCanvas extends JComponent implements ViewportListenerI 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(); @@ -1137,16 +1143,16 @@ public class SeqCanvas extends JComponent implements ViewportListenerI 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)); } } } @@ -1835,9 +1841,7 @@ public class SeqCanvas extends JComponent implements ViewportListenerI { 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 diff --git a/src/jalview/gui/StructureChooser.java b/src/jalview/gui/StructureChooser.java index 7c386f1..198aa62 100644 --- a/src/jalview/gui/StructureChooser.java +++ b/src/jalview/gui/StructureChooser.java @@ -21,6 +21,7 @@ package jalview.gui; +import jalview.api.structures.JalviewStructureDisplayI; import jalview.bin.Jalview; import jalview.datamodel.DBRefEntry; import jalview.datamodel.DBRefSource; @@ -53,6 +54,8 @@ import java.util.Vector; 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; /** @@ -525,7 +528,7 @@ public class StructureChooser extends GStructureChooser * structures */ protected void populateFilterComboBox(boolean haveData, - boolean cachedPDBExists) + boolean cachedPDBExist) { /* * temporarily suspend the change listener behaviour @@ -535,25 +538,33 @@ public class StructureChooser extends GStructureChooser cmb_filterOption.removeAllItems(); if (haveData) { - cmb_filterOption.addItem(new FilterOption("Best Quality", + cmb_filterOption.addItem(new FilterOption( + MessageManager.getString("label.best_quality"), "overall_quality", VIEWS_FILTER, false)); - cmb_filterOption.addItem(new FilterOption("Best Resolution", + cmb_filterOption.addItem(new FilterOption( + MessageManager.getString("label.best_resolution"), "resolution", VIEWS_FILTER, false)); - cmb_filterOption.addItem(new FilterOption("Most Protein Chain", + cmb_filterOption.addItem(new FilterOption( + MessageManager.getString("label.most_protein_chain"), "number_of_protein_chains", VIEWS_FILTER, false)); - cmb_filterOption.addItem(new FilterOption("Most Bound Molecules", + cmb_filterOption.addItem(new FilterOption( + MessageManager.getString("label.most_bound_molecules"), "number_of_bound_molecules", VIEWS_FILTER, false)); - cmb_filterOption.addItem(new FilterOption("Most Polymer Residues", + cmb_filterOption.addItem(new FilterOption( + MessageManager.getString("label.most_polymer_residues"), "number_of_polymer_residues", VIEWS_FILTER, true)); } cmb_filterOption.addItem( - new FilterOption("Enter PDB Id", "-", VIEWS_ENTER_ID, false)); + new FilterOption(MessageManager.getString("label.enter_pdb_id"), + "-", VIEWS_ENTER_ID, false)); cmb_filterOption.addItem( - new FilterOption("From File", "-", VIEWS_FROM_FILE, false)); + new FilterOption(MessageManager.getString("label.from_file"), + "-", VIEWS_FROM_FILE, false)); - if (cachedPDBExists) + if (cachedPDBExist) { - FilterOption cachedOption = new FilterOption("Cached Structures", + FilterOption cachedOption = new FilterOption( + MessageManager.getString("label.cached_structures"), "-", VIEWS_LOCAL_PDB, false); cmb_filterOption.addItem(cachedOption); cmb_filterOption.setSelectedItem(cachedOption); @@ -720,16 +731,65 @@ public class StructureChooser extends GStructureChooser } /** + * 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() @@ -737,21 +797,24 @@ public class StructureChooser extends GStructureChooser 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 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); @@ -772,7 +835,8 @@ public class StructureChooser extends GStructureChooser } 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) { @@ -795,7 +859,8 @@ public class StructureChooser extends GStructureChooser } 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) { @@ -824,7 +889,7 @@ public class StructureChooser extends GStructureChooser } PDBEntry[] pdbEntriesToView = new PDBEntry[] { pdbEntry }; - launchStructureViewer(ssm, pdbEntriesToView, ap, + sViewer = launchStructureViewer(ssm, pdbEntriesToView, ap, new SequenceI[] { selectedSequence }); } @@ -841,14 +906,40 @@ public class StructureChooser extends GStructureChooser 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 pdbEntries) @@ -866,7 +957,8 @@ public class StructureChooser extends GStructureChooser return foundEntry; } - private void launchStructureViewer(StructureSelectionManager ssm, + private StructureViewer launchStructureViewer( + StructureSelectionManager ssm, final PDBEntry[] pdbEntriesToView, final AlignmentPanel alignPanel, SequenceI[] sequences) { @@ -940,6 +1032,7 @@ public class StructureChooser extends GStructureChooser sViewer.viewStructures(pdbEntriesToView[0], sequences, alignPanel); } setProgressBar(null, progressId); + return sViewer; } /** @@ -1170,4 +1263,9 @@ public class StructureChooser extends GStructureChooser { return progressBar.operationInProgress(); } + + public JalviewStructureDisplayI getOpenedStructureViewer() + { + return sViewer == null ? null : sViewer.sview; + } } diff --git a/src/jalview/gui/StructureViewer.java b/src/jalview/gui/StructureViewer.java index fb37b77..f37df71 100644 --- a/src/jalview/gui/StructureViewer.java +++ b/src/jalview/gui/StructureViewer.java @@ -104,7 +104,7 @@ public class StructureViewer 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); @@ -203,7 +203,7 @@ public class StructureViewer private JalviewStructureDisplayI onlyOnePdb(PDBEntry[] pdbs, SequenceI[] seqsForPdbs, AlignmentPanel ap) { - List seqs = new ArrayList(); + List seqs = new ArrayList<>(); if (pdbs == null || pdbs.length == 0) { return null; @@ -227,11 +227,12 @@ public class StructureViewer 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); @@ -270,7 +271,6 @@ public class StructureViewer final boolean usetoColourbyseq = viewerData.isColourWithAlignPanel(); final boolean viewerColouring = viewerData.isColourByViewer(); - JalviewStructureDisplayI sview = null; switch (type) { case JMOL: @@ -287,4 +287,16 @@ public class StructureViewer return sview; } + public boolean isBusy() + { + if (sview != null) + { + if (!sview.hasMapping()) + { + return true; + } + } + return false; + } + } diff --git a/src/jalview/gui/StructureViewerBase.java b/src/jalview/gui/StructureViewerBase.java index 31c20ed..93d675a 100644 --- a/src/jalview/gui/StructureViewerBase.java +++ b/src/jalview/gui/StructureViewerBase.java @@ -34,6 +34,7 @@ import jalview.io.JalviewFileView; 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; @@ -102,9 +103,9 @@ public abstract class StructureViewerBase extends GStructureViewer 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; @@ -113,6 +114,13 @@ public abstract class StructureViewerBase extends GStructureViewer 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() @@ -909,6 +917,7 @@ public abstract class StructureViewerBase extends GStructureViewer { binding.colourBySequence(ap); } + seqColoursApplied = true; } } @@ -1028,4 +1037,42 @@ public abstract class StructureViewerBase extends GStructureViewer 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; + } + } diff --git a/src/jalview/jbgui/GStructureChooser.java b/src/jalview/jbgui/GStructureChooser.java index 7c4672a..9bcaa5a 100644 --- a/src/jalview/jbgui/GStructureChooser.java +++ b/src/jalview/jbgui/GStructureChooser.java @@ -91,7 +91,7 @@ public abstract class GStructureChooser extends JPanel protected JInternalFrame mainFrame = new JInternalFrame(frameTitle); - protected JComboBox cmb_filterOption = new JComboBox(); + protected JComboBox cmb_filterOption = new JComboBox<>(); protected AlignmentPanel ap; @@ -182,7 +182,7 @@ public abstract class GStructureChooser extends JPanel protected FTSDataColumnI[] previousWantedFields; - protected static Map tempUserPrefs = new HashMap(); + protected static Map tempUserPrefs = new HashMap<>(); private JTable tbl_summary = new JTable() { @@ -474,7 +474,7 @@ public abstract class GStructureChooser extends JPanel chk_rememberSettings.setFont(new java.awt.Font("Verdana", 0, 12)); chk_rememberSettings.setVisible(false); txt_search.setToolTipText(JvSwingUtils.wrapTooltip(true, - MessageManager.getString("label.enter_pdb_id"))); + MessageManager.getString("label.enter_pdb_id_tip"))); cmb_filterOption.setToolTipText( MessageManager.getString("info.select_filter_option")); txt_search.getDocument().addDocumentListener(new DocumentListener() @@ -803,7 +803,7 @@ public abstract class GStructureChooser extends JPanel */ public class AssciateSeqPanel extends JPanel implements ItemListener { - private JComboBox cmb_assSeq = new JComboBox(); + private JComboBox cmb_assSeq = new JComboBox<>(); private JLabel lbl_associateSeq = new JLabel(); diff --git a/src/jalview/structure/StructureMapping.java b/src/jalview/structure/StructureMapping.java index 40789ed..fcf322d 100644 --- a/src/jalview/structure/StructureMapping.java +++ b/src/jalview/structure/StructureMapping.java @@ -21,6 +21,7 @@ package jalview.structure; import jalview.datamodel.AlignmentAnnotation; +import jalview.datamodel.Mapping; import jalview.datamodel.SequenceI; import java.util.ArrayList; @@ -39,7 +40,7 @@ public class StructureMapping 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; @@ -49,6 +50,7 @@ public class StructureMapping // and atomNo HashMap mapping; + jalview.datamodel.Mapping seqToPdbMapping = null; /** * Constructor * @@ -73,6 +75,14 @@ public class StructureMapping this.mappingDetails = mappingDetails; } + public StructureMapping(SequenceI seq, String pdbFile2, String pdbId2, + String chain, HashMap mapping2, + String mappingOutput, Mapping seqToPdbMapping) + { + this(seq, pdbFile2, pdbId2, chain, mapping2, mappingOutput); + this.seqToPdbMapping = seqToPdbMapping; + } + public SequenceI getSequence() { return sequence; @@ -109,7 +119,8 @@ public class StructureMapping /** * * @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) { @@ -247,4 +258,9 @@ public class StructureMapping { return mapping; } + + public Mapping getSeqToPdbMapping() + { + return seqToPdbMapping; + } } diff --git a/src/jalview/structure/StructureSelectionManager.java b/src/jalview/structure/StructureSelectionManager.java index 35e2536..10fe836 100644 --- a/src/jalview/structure/StructureSelectionManager.java +++ b/src/jalview/structure/StructureSelectionManager.java @@ -74,8 +74,6 @@ public class StructureSelectionManager private boolean addTempFacAnnot = false; - private SiftsClient siftsClient = null; - /* * Set of any registered mappings between (dataset) sequences. */ @@ -328,22 +326,20 @@ public class StructureSelectionManager } /** - * 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>, 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 */ @@ -355,46 +351,51 @@ public class StructureSelectionManager 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>, 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); @@ -411,7 +412,10 @@ public class StructureSelectionManager ex.printStackTrace(); return null; } - + /* + * sifts client - non null if SIFTS mappings are to be used + */ + SiftsClient siftsClient = null; try { if (isMapUsingSIFTs) @@ -422,6 +426,7 @@ public class StructureSelectionManager { isMapUsingSIFTs = false; e.printStackTrace(); + siftsClient = null; } String targetChainId; @@ -524,12 +529,12 @@ public class StructureSelectionManager 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) @@ -540,7 +545,8 @@ public class StructureSelectionManager 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)); @@ -551,11 +557,17 @@ public class StructureSelectionManager List 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()); @@ -564,11 +576,6 @@ public class StructureSelectionManager 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 @@ -608,6 +615,46 @@ public class StructureSelectionManager 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); @@ -624,13 +671,15 @@ public class StructureSelectionManager * @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); @@ -639,7 +688,7 @@ public class StructureSelectionManager PDBChain chain = pdb.findChain(targetChainId); if (chain != null) { - chain.transferResidueAnnotation(curChainMapping, sqmpping); + chain.transferResidueAnnotation(curChainMapping, null); } } catch (Exception e) { diff --git a/src/jalview/viewmodel/AlignmentViewport.java b/src/jalview/viewmodel/AlignmentViewport.java index a0cbff4..bca3c85 100644 --- a/src/jalview/viewmodel/AlignmentViewport.java +++ b/src/jalview/viewmodel/AlignmentViewport.java @@ -2781,7 +2781,7 @@ public abstract class AlignmentViewport int lastSeq = alignment.getHeight() - 1; List 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)) diff --git a/src/jalview/viewmodel/OverviewDimensions.java b/src/jalview/viewmodel/OverviewDimensions.java index 170f4e9..0235081 100644 --- a/src/jalview/viewmodel/OverviewDimensions.java +++ b/src/jalview/viewmodel/OverviewDimensions.java @@ -58,6 +58,10 @@ public abstract class OverviewDimensions protected int alheight; + protected float widthRatio; + + protected float heightRatio; + /** * Create an OverviewDimensions object * @@ -157,23 +161,25 @@ public abstract class OverviewDimensions 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; } /** @@ -273,14 +279,14 @@ public abstract class OverviewDimensions // 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); } /** diff --git a/src/jalview/viewmodel/OverviewDimensionsHideHidden.java b/src/jalview/viewmodel/OverviewDimensionsHideHidden.java index c158ce7..f58e711 100644 --- a/src/jalview/viewmodel/OverviewDimensionsHideHidden.java +++ b/src/jalview/viewmodel/OverviewDimensionsHideHidden.java @@ -50,6 +50,8 @@ public class OverviewDimensionsHideHidden extends OverviewDimensions public void updateViewportFromMouse(int mousex, int mousey, HiddenSequences hiddenSeqs, HiddenColumns hiddenCols) { + resetAlignmentDims(); + int xAsRes = getLeftXFromCentreX(mousex, hiddenCols); int yAsSeq = getTopYFromCentreY(mousey, hiddenSeqs); @@ -61,24 +63,29 @@ public class OverviewDimensionsHideHidden extends OverviewDimensions 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) { @@ -162,19 +169,30 @@ public class OverviewDimensionsHideHidden extends OverviewDimensions { 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; } @@ -182,10 +200,12 @@ public class OverviewDimensionsHideHidden extends OverviewDimensions 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; diff --git a/src/jalview/viewmodel/OverviewDimensionsShowHidden.java b/src/jalview/viewmodel/OverviewDimensionsShowHidden.java index 9dde16e..eaa3413 100644 --- a/src/jalview/viewmodel/OverviewDimensionsShowHidden.java +++ b/src/jalview/viewmodel/OverviewDimensionsShowHidden.java @@ -72,6 +72,8 @@ public class OverviewDimensionsShowHidden extends OverviewDimensions 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); @@ -93,27 +95,32 @@ public class OverviewDimensionsShowHidden extends OverviewDimensions 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 vpx = Math.round(mousex * widthRatio); int visXAsRes = hiddenCols.findColumnPosition(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) { @@ -225,20 +232,32 @@ public class OverviewDimensionsShowHidden extends OverviewDimensions { 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); + int vpx = Math.round(mousex * widthRatio); return hidden.subtractVisibleColumns(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); } @@ -246,10 +265,12 @@ public class OverviewDimensionsShowHidden extends OverviewDimensions 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); ydiff = ranges.getStartSeq() diff --git a/src/jalview/ws/DBRefFetcher.java b/src/jalview/ws/DBRefFetcher.java index fb8864d..1677eca 100644 --- a/src/jalview/ws/DBRefFetcher.java +++ b/src/jalview/ws/DBRefFetcher.java @@ -61,6 +61,8 @@ public class DBRefFetcher implements Runnable { private static final String NEWLINE = System.lineSeparator(); + public static final String TRIM_RETRIEVED_SEQUENCES = "TRIM_FETCHED_DATASET_SEQS"; + public interface FetchFinishedListenerI { void finished(); @@ -139,7 +141,7 @@ public class DBRefFetcher implements Runnable .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); diff --git a/src/jalview/ws/sifts/SiftsClient.java b/src/jalview/ws/sifts/SiftsClient.java index 68af7c3..b5f9653 100644 --- a/src/jalview/ws/sifts/SiftsClient.java +++ b/src/jalview/ws/sifts/SiftsClient.java @@ -92,14 +92,24 @@ public class SiftsClient implements SiftsClientI 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/"; @@ -413,6 +423,11 @@ public class SiftsClient implements SiftsClientI 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()); @@ -435,8 +450,9 @@ public class SiftsClient implements SiftsClientI HashMap 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; } @@ -444,8 +460,8 @@ public class SiftsClient implements SiftsClientI public HashMap getGreedyMapping(String entityId, SequenceI seq, java.io.PrintStream os) throws SiftsException { - List omitNonObserved = new ArrayList(); - int nonObservedShiftIndex = 0; + List omitNonObserved = new ArrayList<>(); + int nonObservedShiftIndex = 0,pdbeNonObserved=0; // System.out.println("Generating mappings for : " + entityId); Entity entity = null; entity = getEntityById(entityId); @@ -476,7 +492,7 @@ public class SiftsClient implements SiftsClientI TreeMap resNumMap = new TreeMap(); List segments = entity.getSegment(); SegmentHelperPojo shp = new SegmentHelperPojo(seq, mapping, resNumMap, - omitNonObserved, nonObservedShiftIndex); + omitNonObserved, nonObservedShiftIndex,pdbeNonObserved); processSegments(segments, shp); try { @@ -498,15 +514,61 @@ public class SiftsClient implements SiftsClientI { 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 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(); @@ -559,6 +621,8 @@ public class SiftsClient implements SiftsClientI TreeMap resNumMap = shp.getResNumMap(); List 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 @@ -566,6 +630,9 @@ public class SiftsClient implements SiftsClientI List residues = segment.getListResidue().getResidue(); for (Residue residue : residues) { + boolean isObserved = isResidueObserved(residue); + int pdbeIndex = getLeadingIntegerValue(residue.getDbResNum(), + UNASSIGNED); int currSeqIndex = UNASSIGNED; List cRefDbs = residue.getCrossRefDb(); CrossRefDb pdbRefDb = null; @@ -574,6 +641,19 @@ public class SiftsClient implements SiftsClientI 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())) @@ -586,11 +666,45 @@ public class SiftsClient implements SiftsClientI } } } + 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) @@ -599,22 +713,18 @@ public class SiftsClient implements SiftsClientI : 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 }); } } } @@ -904,17 +1014,36 @@ public class SiftsClient implements SiftsClientI 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 mapping, TreeMap resNumMap, - List omitNonObserved, int nonObservedShiftIndex) + List 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; @@ -964,6 +1093,7 @@ public class SiftsClient implements SiftsClientI { this.nonObservedShiftIndex = nonObservedShiftIndex; } + } @Override diff --git a/test/jalview/analysis/AlignmentUtilsTests.java b/test/jalview/analysis/AlignmentUtilsTests.java index 06b51e6..35196fa 100644 --- a/test/jalview/analysis/AlignmentUtilsTests.java +++ b/test/jalview/analysis/AlignmentUtilsTests.java @@ -47,6 +47,7 @@ import jalview.io.DataSourceType; 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; @@ -263,14 +264,14 @@ public class AlignmentUtilsTests @Test(groups = { "Functional" }) public void testMapProteinAlignmentToCdna_noXrefs() throws IOException { - List protseqs = new ArrayList(); + List protseqs = new ArrayList<>(); protseqs.add(new Sequence("UNIPROT|V12345", "EIQ")); protseqs.add(new Sequence("UNIPROT|V12346", "EIQ")); protseqs.add(new Sequence("UNIPROT|V12347", "SAR")); AlignmentI protein = new Alignment(protseqs.toArray(new SequenceI[3])); protein.setDataset(null); - List dnaseqs = new ArrayList(); + List dnaseqs = new ArrayList<>(); dnaseqs.add(new Sequence("EMBL|A11111", "TCAGCACGC")); // = SAR dnaseqs.add(new Sequence("EMBL|A22222", "GAGATACAA")); // = EIQ dnaseqs.add(new Sequence("EMBL|A33333", "GAAATCCAG")); // = EIQ @@ -507,7 +508,7 @@ public class AlignmentUtilsTests acf.addMap(dna1.getDatasetSequence(), prot1.getDatasetSequence(), map); acf.addMap(dna2.getDatasetSequence(), prot2.getDatasetSequence(), map); acf.addMap(dna3.getDatasetSequence(), prot3.getDatasetSequence(), map); - ArrayList acfs = new ArrayList(); + ArrayList acfs = new ArrayList<>(); acfs.add(acf); protein.setCodonFrames(acfs); @@ -605,14 +606,14 @@ public class AlignmentUtilsTests public void testMapProteinAlignmentToCdna_withStartAndStopCodons() throws IOException { - List protseqs = new ArrayList(); + List protseqs = new ArrayList<>(); protseqs.add(new Sequence("UNIPROT|V12345", "EIQ")); protseqs.add(new Sequence("UNIPROT|V12346", "EIQ")); protseqs.add(new Sequence("UNIPROT|V12347", "SAR")); AlignmentI protein = new Alignment(protseqs.toArray(new SequenceI[3])); protein.setDataset(null); - List dnaseqs = new ArrayList(); + List dnaseqs = new ArrayList<>(); // start + SAR: dnaseqs.add(new Sequence("EMBL|A11111", "ATGTCAGCACGC")); // = EIQ + stop @@ -697,14 +698,14 @@ public class AlignmentUtilsTests @Test(groups = { "Functional" }) public void testMapProteinAlignmentToCdna_withXrefs() throws IOException { - List protseqs = new ArrayList(); + List protseqs = new ArrayList<>(); protseqs.add(new Sequence("UNIPROT|V12345", "EIQ")); protseqs.add(new Sequence("UNIPROT|V12346", "EIQ")); protseqs.add(new Sequence("UNIPROT|V12347", "SAR")); AlignmentI protein = new Alignment(protseqs.toArray(new SequenceI[3])); protein.setDataset(null); - List dnaseqs = new ArrayList(); + List dnaseqs = new ArrayList<>(); dnaseqs.add(new Sequence("EMBL|A11111", "TCAGCACGC")); // = SAR dnaseqs.add(new Sequence("EMBL|A22222", "ATGGAGATACAA")); // = start + EIQ dnaseqs.add(new Sequence("EMBL|A33333", "GAAATCCAG")); // = EIQ @@ -774,14 +775,14 @@ public class AlignmentUtilsTests public void testMapProteinAlignmentToCdna_prioritiseXrefs() throws IOException { - List protseqs = new ArrayList(); + List protseqs = new ArrayList<>(); protseqs.add(new Sequence("UNIPROT|V12345", "EIQ")); protseqs.add(new Sequence("UNIPROT|V12346", "EIQ")); AlignmentI protein = new Alignment( protseqs.toArray(new SequenceI[protseqs.size()])); protein.setDataset(null); - List dnaseqs = new ArrayList(); + List dnaseqs = new ArrayList<>(); dnaseqs.add(new Sequence("EMBL|A11111", "GAAATCCAG")); // = EIQ dnaseqs.add(new Sequence("EMBL|A22222", "GAAATTCAG")); // = EIQ AlignmentI cdna = new Alignment(dnaseqs.toArray(new SequenceI[dnaseqs @@ -848,8 +849,8 @@ public class AlignmentUtilsTests al.addAnnotation(ann4); // Temp for seq1 al.addAnnotation(ann5); // Temp for seq2 al.addAnnotation(ann6); // Temp for no sequence - List types = new ArrayList(); - List scope = new ArrayList(); + List types = new ArrayList<>(); + List scope = new ArrayList<>(); /* * Set all sequence related Structure to hidden (ann1, ann2) @@ -1747,7 +1748,7 @@ public class AlignmentUtilsTests map = new MapList(new int[] { 9, 11 }, new int[] { 2, 2 }, 3, 1); acf.addMap(dna3.getDatasetSequence(), prot3.getDatasetSequence(), map); - ArrayList acfs = new ArrayList(); + ArrayList acfs = new ArrayList<>(); acfs.add(acf); protein.setCodonFrames(acfs); @@ -2030,9 +2031,9 @@ public class AlignmentUtilsTests sf6.setValue("ID", "var6"); sf6.setValue("clinical_significance", "Good"); - List codon1Variants = new ArrayList(); - List codon2Variants = new ArrayList(); - List codon3Variants = new ArrayList(); + List codon1Variants = new ArrayList<>(); + List codon2Variants = new ArrayList<>(); + List codon3Variants = new ArrayList<>(); List codonVariants[] = new ArrayList[3]; codonVariants[0] = codon1Variants; codonVariants[1] = codon2Variants; @@ -2272,7 +2273,7 @@ public class AlignmentUtilsTests seq1.createDatasetSequence(); Mapping mapping = new Mapping(seq1, new MapList( new int[] { 3, 6, 9, 10 }, new int[] { 1, 6 }, 1, 1)); - Map> map = new TreeMap>(); + Map> map = new TreeMap<>(); AlignmentUtils.addMappedPositions(seq1, from, mapping, map); /* @@ -2304,7 +2305,7 @@ public class AlignmentUtilsTests seq1.createDatasetSequence(); Mapping mapping = new Mapping(seq1, new MapList( new int[] { 3, 6, 9, 10 }, new int[] { 1, 6 }, 1, 1)); - Map> map = new TreeMap>(); + Map> map = new TreeMap<>(); AlignmentUtils.addMappedPositions(seq1, from, mapping, map); /* @@ -2561,7 +2562,7 @@ public class AlignmentUtilsTests * 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)); @@ -2574,17 +2575,42 @@ public class AlignmentUtilsTests 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(); @@ -2600,4 +2626,151 @@ public class AlignmentUtilsTests 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 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 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 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 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()); + } } diff --git a/test/jalview/datamodel/AlignmentTest.java b/test/jalview/datamodel/AlignmentTest.java index 4b5d096..74ac146 100644 --- a/test/jalview/datamodel/AlignmentTest.java +++ b/test/jalview/datamodel/AlignmentTest.java @@ -668,6 +668,17 @@ public class AlignmentTest // 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(); @@ -1321,4 +1332,22 @@ public class AlignmentTest // 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.calcId); + } } diff --git a/test/jalview/ext/ensembl/EnsemblCdnaTest.java b/test/jalview/ext/ensembl/EnsemblCdnaTest.java index 6611e05..779962c 100644 --- a/test/jalview/ext/ensembl/EnsemblCdnaTest.java +++ b/test/jalview/ext/ensembl/EnsemblCdnaTest.java @@ -228,6 +228,9 @@ public class EnsemblCdnaTest sf.setValue("Parent", "transcript:" + accId); assertTrue(testee.retainFeature(sf, accId)); + // test is not case-sensitive + assertTrue(testee.retainFeature(sf, accId.toLowerCase())); + // feature with wrong parent is not retained sf.setValue("Parent", "transcript:XYZ"); assertFalse(testee.retainFeature(sf, accId)); diff --git a/test/jalview/ext/ensembl/EnsemblGeneTest.java b/test/jalview/ext/ensembl/EnsemblGeneTest.java index b7ea0cb..217742d 100644 --- a/test/jalview/ext/ensembl/EnsemblGeneTest.java +++ b/test/jalview/ext/ensembl/EnsemblGeneTest.java @@ -175,7 +175,8 @@ public class EnsemblGeneTest // NMD_transcript_variant treated like transcript in Ensembl SequenceFeature sf3 = new SequenceFeature("NMD_transcript_variant", "", 22000, 22500, 0f, null); - sf3.setValue("Parent", "gene:" + geneId); + // id matching should not be case-sensitive + sf3.setValue("Parent", "gene:" + geneId.toLowerCase()); sf3.setValue("transcript_id", "transcript3"); genomic.addSequenceFeature(sf3); @@ -261,6 +262,9 @@ public class EnsemblGeneTest sf.setValue("ID", "gene:" + accId); assertTrue(testee.identifiesSequence(sf, accId)); + // test is not case-sensitive + assertTrue(testee.identifiesSequence(sf, accId.toLowerCase())); + // transcript not valid: sf = new SequenceFeature("transcript", "", 1, 2, 0f, null); sf.setValue("ID", "gene:" + accId); diff --git a/test/jalview/ext/jmol/JmolCommandsTest.java b/test/jalview/ext/jmol/JmolCommandsTest.java index 3309adf..e42b54f 100644 --- a/test/jalview/ext/jmol/JmolCommandsTest.java +++ b/test/jalview/ext/jmol/JmolCommandsTest.java @@ -115,7 +115,7 @@ public class JmolCommandsTest 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) @@ -128,7 +128,7 @@ public class JmolCommandsTest 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]")); diff --git a/test/jalview/io/AnnotatedPDBFileInputTest.java b/test/jalview/io/AnnotatedPDBFileInputTest.java index e14a478..c0038a1 100644 --- a/test/jalview/io/AnnotatedPDBFileInputTest.java +++ b/test/jalview/io/AnnotatedPDBFileInputTest.java @@ -39,6 +39,7 @@ import jalview.structure.StructureImportSettings.StructureParser; 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; @@ -101,18 +102,19 @@ public class AnnotatedPDBFileInputTest } } - @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)); } diff --git a/test/jalview/io/Jalview2xmlBase.java b/test/jalview/io/Jalview2xmlBase.java index 15e18e3..fbdd782 100644 --- a/test/jalview/io/Jalview2xmlBase.java +++ b/test/jalview/io/Jalview2xmlBase.java @@ -76,7 +76,8 @@ public class Jalview2xmlBase @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); } diff --git a/test/jalview/structure/StructureSelectionManagerTest.java b/test/jalview/structure/StructureSelectionManagerTest.java index a59fbde..286be1b 100644 --- a/test/jalview/structure/StructureSelectionManagerTest.java +++ b/test/jalview/structure/StructureSelectionManagerTest.java @@ -20,28 +20,53 @@ */ 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() { @@ -160,4 +185,313 @@ public class StructureSelectionManagerTest 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 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 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 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 fdesc) + { + for (int o = 0; o < offset.length; o++) + { + int res = pdbseq.findPosition(offset[o]); + List 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 tipEntries = new TreeMap<>(); + final Map> 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(); + } + } diff --git a/test/jalview/ws/PDBSequenceFetcherTest.java b/test/jalview/ws/PDBSequenceFetcherTest.java index 95863e7..cc3dca8 100644 --- a/test/jalview/ws/PDBSequenceFetcherTest.java +++ b/test/jalview/ws/PDBSequenceFetcherTest.java @@ -20,18 +20,22 @@ */ 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; @@ -106,23 +110,76 @@ public class PDBSequenceFetcherTest testRetrieveProteinSeqFromPDB(); } + private class TestRetrieveObject + { + String id; + + int expectedHeight; + + public TestRetrieveObject(String id, int expectedHeight) + { + super(); + this.id = id; + this.expectedHeight = expectedHeight; + } + + } + + private List toRetrieve = Arrays.asList( + new TestRetrieveObject("1QIP", 4), + new TestRetrieveObject("4IM2", 1)); + private void testRetrieveProteinSeqFromPDB() throws Exception { List 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 prev = null; + int lastp = -1; + for (int col = 1; col <= sq.getLength(); col++) + { + List 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()); } } - } diff --git a/test/jalview/ws/sifts/SiftsClientTest.java b/test/jalview/ws/sifts/SiftsClientTest.java index b92766e..75c1413 100644 --- a/test/jalview/ws/sifts/SiftsClientTest.java +++ b/test/jalview/ws/sifts/SiftsClientTest.java @@ -83,103 +83,103 @@ public class SiftsClientTest @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) @@ -311,7 +311,7 @@ public class SiftsClientTest 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); }