From: Ben Soares Date: Thu, 16 Nov 2023 11:35:05 +0000 (+0000) Subject: Merge branch 'develop' into bug/JAL-4238_PAEs_not_being_shown_in_JalviewJS X-Git-Url: http://source.jalview.org/gitweb/?a=commitdiff_plain;h=00e3cf6993daba7e310af0bf75b4a64ba900f837;hp=cd96215b471f122ef03946d5683055332fa5a5b8;p=jalview.git Merge branch 'develop' into bug/JAL-4238_PAEs_not_being_shown_in_JalviewJS --- diff --git a/build.gradle b/build.gradle index fb1a83b..bcb3d66 100644 --- a/build.gradle +++ b/build.gradle @@ -2241,9 +2241,9 @@ task getdownImages() { dependsOn getdownImagesProcess } -task getdownWebsite() { +task getdownWebsiteBuild() { group = "distribution" - description = "Create the getdown minimal app folder, and website folder for this version of jalview. Website folder also used for offline app installer" + description = "Create the getdown minimal app folder, and website folder for this version of jalview. Website folder also used for offline app installer. No digest is created." dependsOn getdownImages if (buildDist) { @@ -2355,7 +2355,7 @@ task getdownWebsite() { from s into "${getdownAppBaseDir}/${getdown_wrapper_script_dir}" } - getdownTextLines += "resource = ${getdown_wrapper_script_dir}/${script}" + getdownTextLines += "xresource = ${getdown_wrapper_script_dir}/${script}" } } @@ -2497,7 +2497,9 @@ task getdownDigestDir(type: JavaExec) { task getdownDigest(type: JavaExec) { group = "distribution" description = "Digest the getdown website folder" - dependsOn getdownWebsite + + dependsOn getdownWebsiteBuild + doFirst { classpath = files(getdownLauncher) } @@ -2530,12 +2532,19 @@ task getdown() { } } +task getdownWebsite { + group = "distribution" + description = "A task to create the whole getdown channel website dir including digest file" + + dependsOn getdownWebsiteBuild + dependsOn getdownDigest +} task getdownArchiveBuild() { group = "distribution" description = "Put files in the archive dir to go on the website" - dependsOn getdownWebsite + dependsOn getdownWebsiteBuild def v = "v${JALVIEW_VERSION_UNDERSCORES}" def vDir = "${getdownArchiveDir}/${v}" diff --git a/help/markdown/releases/release-2_11_3_0.md b/help/markdown/releases/release-2_11_3_0.md index 5299026..35ff569 100644 --- a/help/markdown/releases/release-2_11_3_0.md +++ b/help/markdown/releases/release-2_11_3_0.md @@ -78,6 +78,7 @@ channel: "release" - Output stderr and stdout when running tests via gradle - New gradle task providing runtime acceptance test for JalviewJS based on Chromium for Tests (still work in progress) + ## Issues Resolved - Jmol view not always centred on structures when multiple structures are viewed - Unsaved Alignment windows close without prompting to save, individually or at application quit. @@ -87,6 +88,7 @@ channel: "release" - Multiple overview windows can be opened for a particular alignment view when multiple views are present - Overview windows opened automatically (due to preferences settings) lack title - Show Crossrefs fails to retrieve CDS from ENA or Ensembl for sequences retrieved from Uniprot due to version numbers in cross-reference accession +- Uniprot parser fails to import sequences with features that have 'unknown' start or end - Stockholm export does not include sequence descriptions - Don't add string label version of DSSP secondary structure codes in secondary structure annotation rows - reference annotation not correctly transferred to alignment containing a sub-sequence when a selection is active @@ -110,13 +112,14 @@ channel: "release" - Jalview source distribution unnecessarily includes dist directory with built jalview jar and dependencies - Jmol sessions involving large molecules may not be fully saved in Jalview project files (known defect in 2.11.2.x) -## New Known defects + +### New Known Issues - EBI-AlphaFold PLDDT colours cannot be overlaid on alignment via 'Colour by annotation' unless the alignment's colourscheme has been set to 'None' via the Colours menu. - Tree renderer doesn't show bottom-most leaves of tree when Fit-To-Window is enabled. - PAE partition not shown in the same place when tree is closed and reopened - Cannot cancel structure view open action once it has been started via the structure chooser dialog - Example project's multiple views do not open in distinct locations when eXpand views is used to show them all separately -- 'Reload' for a jalview project results in all windows being duplicated (since 2.11.2.6, more severe in 2.11.3.0 +- 'Reload' for a jalview project results in all windows being duplicated (since 2.11.2.6, more severe in 2.11.3.0) - Overview shown and then closed when importing legacy jalview projects without overview store/restore information - Missing last letter when copying consensus sequence from alignment if first column is hidden - Last sequence ID in alignment not shown and annotation labels are misaligned in HTML export @@ -124,7 +127,7 @@ channel: "release" - Test coverage for ID width adjustment disabled pending fix for new annotation label geometry and width calculation - scripts adding new fileformats or colourschemes do not work when run via command line - Headless alignment export with structure annotations doesn't include secondary structure and temperature factor -- Copy sequences from one alignment and Pasting as new window in another alignment doesn't propagate title from original alignment's window) +- Copy sequences from one alignment and Pasting as new window in another alignment doesn't propagate title from original alignment's window - Annotation colouring dialog box doesn't remember 'use original colours' settings when opened via the Colour menu - When the Groovy console is open Jalview does not prompt to save before quitting - Jalview works with but is not fully compatible with latest Ensembl REST API (15.6) diff --git a/src/jalview/gui/AppJmol.java b/src/jalview/gui/AppJmol.java index 8689aa7..0f2a00e 100644 --- a/src/jalview/gui/AppJmol.java +++ b/src/jalview/gui/AppJmol.java @@ -507,10 +507,17 @@ public class AppJmol extends StructureViewerBase } }); runner.start(); + long time = 0; do { Thread.sleep(25); - } while (runner.isAlive()); + } while (runner.isAlive() && time++ < 4000); + if (time >= 4000) + { + runner.interrupt(); + throw new ImageOutputException( + "Jmol took too long to export. Waited for 100 seconds."); + } } catch (Throwable e) { throw new ImageOutputException( diff --git a/src/jalview/gui/Desktop.java b/src/jalview/gui/Desktop.java index 5a8c048..a185fcc 100644 --- a/src/jalview/gui/Desktop.java +++ b/src/jalview/gui/Desktop.java @@ -1535,7 +1535,21 @@ public class Desktop extends jalview.jbgui.GDesktop { // suppress a possible repeat prompt to save script groovyConsole.setDirty(false); - groovyConsole.exit(); + + // and tidy up + if (((Window) groovyConsole.getFrame()) != null + && ((Window) groovyConsole.getFrame()).isVisible()) + { + // console is visible -- FIXME JAL-4327 + groovyConsole.exit(); + } + else + { + // console is not, so just let it dispose itself when we shutdown + // we don't call groovyConsole.exit() because it calls the shutdown + // handler with invokeAndWait() causing deadlock + groovyConsole = null; + } } if (terminateJvm) diff --git a/src/jalview/gui/IdCanvas.java b/src/jalview/gui/IdCanvas.java index 3ee3316..76020c7 100755 --- a/src/jalview/gui/IdCanvas.java +++ b/src/jalview/gui/IdCanvas.java @@ -398,13 +398,13 @@ public class IdCanvas extends JPanel implements ViewportListenerI * * @param g * @param av2 - * @param i + * @param startSeq * @param totalHeight */ - public void drawIdsWrappedNoGUI(Graphics2D g, AlignViewport av2, int i, - int totalHeight) + public void drawIdsWrappedNoGUI(Graphics2D g, AlignViewport av2, + int startSeq, int totalHeight) { - drawIdsWrapped(g, av2, totalHeight, totalHeight, i, false); + drawIdsWrapped(g, av2, startSeq, totalHeight, -1, false); } public void drawIdsWrapped(Graphics2D g, AlignViewport alignViewport, diff --git a/src/jalview/ws/dbsources/Uniprot.java b/src/jalview/ws/dbsources/Uniprot.java index c9db7f2..b125ba5 100644 --- a/src/jalview/ws/dbsources/Uniprot.java +++ b/src/jalview/ws/dbsources/Uniprot.java @@ -39,6 +39,7 @@ import javax.xml.stream.XMLStreamReader; import com.stevesoft.pat.Regex; import jalview.bin.Cache; +import jalview.bin.Console; import jalview.datamodel.Alignment; import jalview.datamodel.AlignmentI; import jalview.datamodel.DBRefEntry; @@ -292,19 +293,68 @@ public class Uniprot extends DbSourceProxyImpl LocationType location = uf.getLocation(); int start = 0; int end = 0; + String uncertain_start = null, uncertain_end = null, + uncertain_pos = null; if (location.getPosition() != null) { - start = location.getPosition().getPosition().intValue(); - end = start; + if (location.getPosition().getPosition() == null + || !"unknown".equals(location.getPosition().getStatus())) + { + Console.warn( + "Ignoring single position feature with uncertain location " + + uf.getType() + ":" + getDescription(uf)); + uncertain_pos = location.getPosition().getStatus() == null + ? "unknown" + : location.getPosition().getStatus(); + } + else + { + start = location.getPosition().getPosition().intValue(); + end = start; + } } else { - start = location.getBegin().getPosition().intValue(); - end = location.getEnd().getPosition().intValue(); + if (location.getBegin().getPosition() == null) + { + Console.warn( + "Setting start position of feature with uncertain start to 1: " + + uf.getType() + ":" + getDescription(uf)); + start = sequence.getStart(); + uncertain_start = location.getBegin().getStatus(); + } + else + { + start = location.getBegin().getPosition().intValue(); + } + if (location.getEnd().getPosition() == null) + { + Console.warn( + "Setting start position of feature with uncertain start to 1: " + + uf.getType() + ":" + getDescription(uf)); + end = sequence.getEnd(); + uncertain_end = location.getEnd().getStatus(); + } + else + { + end = location.getEnd().getPosition().intValue(); + } } SequenceFeature sf = new SequenceFeature(uf.getType(), getDescription(uf), start, end, "Uniprot"); sf.setStatus(uf.getStatus()); + if (uncertain_end != null) + { + sf.setValue("end_status", uncertain_end); + } + if (uncertain_start != null) + { + sf.setValue("start_status", uncertain_start); + } + if (uncertain_pos != null) + { + sf.setValue("pos_status", uncertain_pos); + } sequence.addSequenceFeature(sf); } } diff --git a/test/jalview/ws/dbsources/UniprotTest.java b/test/jalview/ws/dbsources/UniprotTest.java index 176cddc..f2d3b66 100644 --- a/test/jalview/ws/dbsources/UniprotTest.java +++ b/test/jalview/ws/dbsources/UniprotTest.java @@ -34,10 +34,12 @@ import java.util.List; import org.testng.Assert; import org.testng.annotations.BeforeClass; +import org.testng.annotations.DataProvider; import org.testng.annotations.Test; import jalview.datamodel.DBRefEntry; import jalview.datamodel.DBRefSource; +import jalview.datamodel.SequenceFeature; import jalview.datamodel.SequenceI; import jalview.gui.JvOptionPane; import jalview.util.DBRefUtils; @@ -324,4 +326,329 @@ public class UniprotTest ft.getVariation().clear(); // variant missing - is ignored assertEquals("Hello", Uniprot.getDescription(ft)); } + + public static String Q29079 = Q29079 = new String( + "\n" + + "\n" + + "Q29079\n" + + "Q29017\n" + + "PAG2_PIG\n" + "\n" + + "\n" + + "Pregnancy-associated glycoprotein 2\n" + + "PAG 2\n" + + "3.4.23.-\n" + + "\n" + "\n" + "\n" + + "PAG2\n" + "\n" + + "\n" + + "Sus scrofa\n" + + "Pig\n" + + "\n" + + "\n" + "Eukaryota\n" + + "Metazoa\n" + "Chordata\n" + + "Craniata\n" + + "Vertebrata\n" + + "Euteleostomi\n" + + "Mammalia\n" + + "Eutheria\n" + + "Laurasiatheria\n" + + "Artiodactyla\n" + + "Suina\n" + "Suidae\n" + + "Sus\n" + "\n" + + "\n" + "\n" + + "\n" + + "Porcine pregnancy-associated glycoproteins: new members of the aspartic proteinase gene family expressed in trophectoderm.\n" + + "\n" + "\n" + + "\n" + + "\n" + + "\n" + "\n" + + "\n" + + "\n" + + "\n" + + "NUCLEOTIDE SEQUENCE [GENOMIC DNA]\n" + + "\n" + "\n" + + "\n" + + "Gene for porcine pregnancy-associated glycoprotein 2 (poPAG2): its structural organization and analysis of its promoter.\n" + + "\n" + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + "\n" + + "\n" + + "\n" + + "\n" + + "NUCLEOTIDE SEQUENCE [GENOMIC DNA]\n" + + "\n" + "Placenta\n" + + "\n" + "\n" + + "\n" + + "\n" + + "Secreted\n" + + "Extracellular space\n" + + "\n" + "\n" + + "\n" + + "Expressed throughout the chorion, with the signal localized exclusively over the trophectoderm.\n" + + "\n" + + "\n" + + "Expression was detected at day 15, coinciding with the beginning of implantation, and continued throughout gestation.\n" + + "\n" + "\n" + + "Belongs to the peptidase A1 family.\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "Aspartyl protease\n" + + "Disulfide bond\n" + + "Glycoprotein\n" + + "Hydrolase\n" + + "Protease\n" + + "Reference proteome\n" + + "Secreted\n" + + "Signal\n" + + "Zymogen\n" + + "\n" + + "\n" + "\n" + + "\n" + "\n" + + "\n" + + "\n" + + "\n" + "\n" + + "\n" + "\n" + + "\n" + + "\n" + + "\n" + "\n" + + "\n" + "\n" + + "\n" + + "\n" + + "\n" + "\n" + + "\n" + "\n" + + "\n" + + "\n" + + "\n" + "\n" + + "\n" + "\n" + + "\n" + + "\n" + "\n" + + "\n" + "\n" + + "\n" + + "\n" + "\n" + + "\n" + "\n" + + "\n" + + "\n" + "\n" + + "\n" + "\n" + + "\n" + + "\n" + "\n" + + "\n" + "\n" + + "\n" + + "\n" + + "\n" + "\n" + + "\n" + "\n" + + "\n" + + "\n" + + "\n" + "\n" + + "\n" + "\n" + + "\n" + + "\n" + + "\n" + "\n" + + "\n" + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + "\n" + + "\n" + + "MKWLVILGLVALSDCLVMIPLTKVKSVRESLREKGLLKNFLKEHPYNMIQNLLSKNSSHVQKFSYQPLRNYLDMVYVGNISIGTPPQQFSVVFDTGSSDLWVPSIYCKSKACVTHRSFNPSHSSTFHDRGKSIKLEYGSGKMSGFLGQDTVRIGQLTSTGQAFGLSKEETGKAFEHAIFDGILGLAYPSIAIKGTTTVIDNLKKQDQISEPVFAFYLSSDKEEGSVVMFGGVDKKYYKGDLKWVPLTQTSYWQIALDRITCRGRVIGCPRGCQAIVDTGTSMLHGPSKAVAKIHSLIKHFEKEYVVPCNARKALPDIVFTINNVDYPVPAQAYIRKYVVPCNARKALPDIVFTINNVDYPVPAQAYIRKNANNNRCYSTFEDIMDTLNQREIWILGDVFLRLYFTVYDEGQNRIGLAQAT\n" + + "\n" + + " Copyrighted by the UniProt Consortium, see https://www.uniprot.org/terms Distributed under the Creative Commons Attribution (CC BY 4.0) License \n" + + ""); + + @DataProvider + public Object[][] problemEntries() + { + return new Object[][] { new Object[] { Q29079 } }; + } + + @Test(groups = "Functional", dataProvider = "problemEntries") + public SequenceI testimportOfProblemEntries(String entry) + { + Uniprot u = new Uniprot(); + InputStream is = new ByteArrayInputStream(entry.getBytes()); + List entries = u.getUniprotEntries(is); + assertEquals(1, entries.size()); + SequenceI sq = u.uniprotEntryToSequence(entries.get(0)); + assertNotNull(sq); + return sq; + } + + @Test(groups = "Functional") + public void checkIndefiniteSequenceFeatures() + { + SequenceI upseq = testimportOfProblemEntries(Q29079); + List sf = upseq.getFeatures() + .getPositionalFeatures("chain"); + assertNotNull(sf); + assertTrue(sf.size() == 1); + SequenceFeature chainFeaure = sf.get(0); + assertTrue(chainFeaure.getBegin() == 1); + assertTrue(chainFeaure.getEnd() == upseq.getEnd()); + assertNotNull(chainFeaure.getValueAsString("start_status")); + assertNull(chainFeaure.getValueAsString("end_status")); + assertTrue( + "unknown".equals(chainFeaure.getValueAsString("start_status"))); + } }