From: James Procter Date: Thu, 2 Nov 2023 18:49:04 +0000 (+0000) Subject: Merge branch 'develop' into patch/JAL-3088_finalbracenotinrightplace X-Git-Tag: Release_2_11_3_0~3^2~11^2 X-Git-Url: http://source.jalview.org/gitweb/?a=commitdiff_plain;h=cd669a0e8c7b91b379bca8fe6e702cf0fcbd1ce0;hp=c956ba7ae40dd7f269aa372044ed4ed5f28fb042;p=jalview.git Merge branch 'develop' into patch/JAL-3088_finalbracenotinrightplace Conflicts: - JAL-4250 src/jalview/renderer/AnnotationRenderer.java --- diff --git a/THIRDPARTYLIBS b/THIRDPARTYLIBS index a2710f4..e52f3f6 100644 --- a/THIRDPARTYLIBS +++ b/THIRDPARTYLIBS @@ -58,7 +58,8 @@ miglayout-4.0-swing.jar BSD - http://www.migcalendar.com/miglayout/versions/4.0/ regex.jar saaj.jar servlet-api-3.1.jar -slf4j-api-1.7.32.jar MIT license - https://opensource.org/licenses/mit-license.php +slf4j-api-1.7.36.jar MIT license - https://opensource.org/licenses/mit-license.php - downloaded from https://repo1.maven.org/maven2/org/slf4j/ +slf4j-nop-1.7.36.jar MIT license - https://opensource.org/licenses/mit-license.php - downloaded from https://repo1.maven.org/maven2/org/slf4j/ vamsas-client.jar VARNAv3-93.jar GPL licenced software by K�vin Darty, Alain Denise and Yann Ponty - http://varna.lri.fr wsdl4j.jar diff --git a/build.gradle b/build.gradle index 7ad6f99..011be67 100644 --- a/build.gradle +++ b/build.gradle @@ -52,7 +52,7 @@ plugins { id 'application' id 'eclipse' id "com.diffplug.gradle.spotless" version "3.28.0" - id 'com.github.johnrengelman.shadow' version '4.0.3' + id 'com.github.johnrengelman.shadow' version '6.0.0' id 'com.install4j.gradle' version '10.0.3' id 'com.dorongold.task-tree' version '2.1.1' // only needed to display task dependency tree with gradle task1 [task2 ...] taskTree id 'com.palantir.git-version' version '0.13.0' apply false @@ -1783,6 +1783,27 @@ task testTask1(type: Test) { } } +task testTask2(type: Test) { + group = "Verification" + description = "Tests that need to be isolated from the main test run" + useTestNG() { + includeGroups name + excludeGroups testng_excluded_groups.split(",") + preserveOrder true + useDefaultListeners=true + } +} +task testTask3(type: Test) { + group = "Verification" + description = "Tests that need to be isolated from the main test run" + useTestNG() { + includeGroups name + excludeGroups testng_excluded_groups.split(",") + preserveOrder true + useDefaultListeners=true + } +} + /* insert more testTaskNs here -- change N to next digit or other string */ /* task testTaskN(type: Test) { @@ -1830,10 +1851,16 @@ tasks.withType(Test).matching {t -> t.getName().startsWith("testTask")}.all { te showExceptions true showCauses true showStackTraces true - + if (test_output) { + showStandardStreams true + } info.events = [ TestLogEvent.FAILED ] } + if (OperatingSystem.current().isMacOsX()) { + testTask.systemProperty "apple.awt.UIElement", "true" + testTask.environment "JAVA_TOOL_OPTIONS", "-Dapple.awt.UIElement=true" + } ignoreFailures = true // Always try to run all tests for all modules @@ -2129,12 +2156,33 @@ shadowJar { if (buildDist) { dependsOn makeDist } - from ("${jalviewDir}/${libDistDir}") { - include("*.jar") - } - manifest { - attributes "Implementation-Version": JALVIEW_VERSION, - "Application-Name": applicationName + + def jarFiles = fileTree(dir: "${jalviewDir}/${libDistDir}", include: "*.jar", exclude: "regex.jar").getFiles() + def groovyJars = jarFiles.findAll {it1 -> file(it1).getName().startsWith("groovy-swing")} + def otherJars = jarFiles.findAll {it2 -> !file(it2).getName().startsWith("groovy-swing")} + from groovyJars + from otherJars + + // we need to include the groovy-swing Include-Package for it to run in the shadowJar + doFirst { + def jarFileManifests = [] + groovyJars.each { jarFile -> + def mf = zipTree(jarFile).getFiles().find { it.getName().equals("MANIFEST.MF") } + if (mf != null) { + jarFileManifests += mf + } + } + + manifest { + attributes "Implementation-Version": JALVIEW_VERSION, "Application-Name": applicationName + from (jarFileManifests) { + eachEntry { details -> + if (!details.key.equals("Import-Package")) { + details.exclude() + } + } + } + } } duplicatesStrategy "INCLUDE" @@ -2996,6 +3044,7 @@ task sourceDist(type: Tar) { into project.name def EXCLUDE_FILES=[ + "dist/*", "build/*", "bin/*", "test-output/", diff --git a/doc/building.md b/doc/building.md index 34d5d67..aee827d 100644 --- a/doc/building.md +++ b/doc/building.md @@ -336,7 +336,7 @@ the `tests/` folder. A summary of results should appear in your console. You can run different defined groups of tests with ```bash -gradle test -PtestngGroups=Network +gradle test -Ptestng_groups=Network ``` Available groups include Functional (default), Network, External. @@ -348,9 +348,15 @@ Some of Jalview's Functional tests don't pass reliably in all environments. We t To exclude one or more groups of tests, add them as a comma separated list in testngExcludedGroups. ```bash -gradle test -PtestngExcludedGroups=Not-bamboo +gradle test -Ptestng_excluded_groups=Not-bamboo ``` +#### Viewing stdout and stderr for tests +By default, gradle doesn't report any of the output or error streams produced by tests. You can enable output by setting the following: + +```bash +gradle test -Ptest_output=1 +``` ### Installer packaging with *install4j* diff --git a/examples/argfiles/test_fab41.txt b/examples/argfiles/test_fab41.txt index e6f7627..b7f0d45 100644 --- a/examples/argfiles/test_fab41.txt +++ b/examples/argfiles/test_fab41.txt @@ -10,4 +10,4 @@ --paematrix=[label=pAE R4-M5]./examples/test_fab41.result/test_fab41_unrelaxed_rank_4_model_5_scores.json --structure=./examples/test_fab41.result/test_fab41_unrelaxed_rank_5_model_1.pdb --paematrix=[label=pAE R5-M1]./examples/test_fab41.result/test_fab41_unrelaxed_rank_5_model_1_scores.json ---image=output1.html +--image=[textrenderer=text]output1.html diff --git a/examples/argfiles/test_fab41_nostructureviewers.txt b/examples/argfiles/test_fab41_nostructureviewers.txt new file mode 100644 index 0000000..ab52cdf --- /dev/null +++ b/examples/argfiles/test_fab41_nostructureviewers.txt @@ -0,0 +1,14 @@ +--open=./examples/test_fab41.result/sample.a2m +--colour=gecos:flower +--gui +--structure=[structureviewer=none]./examples/test_fab41.result/test_fab41_unrelaxed_rank_1_model_3.pdb +--paematrix=[label=pAE R1-M3]./examples/test_fab41.result/test_fab41_unrelaxed_rank_1_model_3_scores.json +--structure=[structureviewer=none]./examples/test_fab41.result/test_fab41_unrelaxed_rank_2_model_4.pdb +--paematrix=[label=pAE R2-M4]./examples/test_fab41.result/test_fab41_unrelaxed_rank_2_model_4_scores.json +--structure=[structureviewer=none]./examples/test_fab41.result/test_fab41_unrelaxed_rank_3_model_2.pdb +--paematrix=[label=pAE R3-M2]./examples/test_fab41.result/test_fab41_unrelaxed_rank_3_model_2_scores.json +--structure=[structureviewer=none]./examples/test_fab41.result/test_fab41_unrelaxed_rank_4_model_5.pdb +--paematrix=[label=pAE R4-M5]./examples/test_fab41.result/test_fab41_unrelaxed_rank_4_model_5_scores.json +--structure=[structureviewer=none]./examples/test_fab41.result/test_fab41_unrelaxed_rank_5_model_1.pdb +--paematrix=[label=pAE R5-M1]./examples/test_fab41.result/test_fab41_unrelaxed_rank_5_model_1_scores.json +--image=[textrenderer=text]output1.html diff --git a/examples/groovy/ComputePeptideVariants.groovy b/examples/groovy/ComputePeptideVariants.groovy index 6caa69c..e5ece51 100644 --- a/examples/groovy/ComputePeptideVariants.groovy +++ b/examples/groovy/ComputePeptideVariants.groovy @@ -1,6 +1,6 @@ import jalview.datamodel.SequenceFeature import jalview.gui.Desktop -def af = jalview.bin.Jalview.currentAlignFrame +def af = Jalview.getCurrentAlignFrame() def av = af.viewport def fr = Desktop.getAlignFrameFor(av.codingComplement).getFeatureRenderer() def counts = 0 @@ -29,4 +29,4 @@ for (seq in av.alignment.sequences) } af.getFeatureRenderer().featuresAdded() af.alignPanel.paintAlignment(true, true) -println "Added " + countm + " missense and " + counts + " synonymous variants" \ No newline at end of file +println "Added " + countm + " missense and " + counts + " synonymous variants" diff --git a/examples/groovy/JvLoadTester.groovy b/examples/groovy/JvLoadTester.groovy index d844d62..cc92e40 100644 --- a/examples/groovy/JvLoadTester.groovy +++ b/examples/groovy/JvLoadTester.groovy @@ -21,7 +21,7 @@ import jalview.gui.*; import jalview.io.*; -def class JvLoadTest { +class JvLoadTest { FileLoader fl = null; def String safename = null; JvLoadTest(String sname) { @@ -155,4 +155,4 @@ def JvLoadTest newJvLoadTest(String tempFile) { System.gc(); jalview.gui.Desktop.instance.desktop.showMemoryUsage(true); return new JvLoadTest(tempFile) -} \ No newline at end of file +} diff --git a/examples/groovy/PIDmatrix.groovy b/examples/groovy/PIDmatrix.groovy index b97abcc..76b9de7 100644 --- a/examples/groovy/PIDmatrix.groovy +++ b/examples/groovy/PIDmatrix.groovy @@ -56,7 +56,7 @@ printSimilarityMatrix(true,true,SimilarityParams.Jalview) void printSimilarityMatrix(boolean selview=false, boolean includeids=true, SimilarityParams pidMethod) { - def currentAlignFrame = jalview.bin.Jalview.getCurrentAlignFrame() + def currentAlignFrame = Jalview.getCurrentAlignFrame() jalview.gui.AlignViewport av = currentAlignFrame.getCurrentView() @@ -96,4 +96,4 @@ void printSimilarityMatrix(boolean selview=false, boolean includeids=true, Simil print "\n" } -} \ No newline at end of file +} diff --git a/examples/groovy/alignLoadedFile.groovy b/examples/groovy/alignLoadedFile.groovy index 764fdae..df68e2b 100644 --- a/examples/groovy/alignLoadedFile.groovy +++ b/examples/groovy/alignLoadedFile.groovy @@ -20,6 +20,7 @@ */ // run an alignment on the current alignFrame import jalview.ws.jws2.*; +import jalview.ws.jws2.jabaws2.Jws2Instance; import jalview.datamodel.*; // First get the JABA service discoverer and see if there are any services. @@ -33,7 +34,7 @@ if (!disc.isRunning() && !disc.hasServices()) disc.run(); } -for (jalview.ws.jws2.Jws2Discoverer.Jws2Instance service: disc.getServices()) { +for (jalview.ws.jws2.jabaws2.Jws2Instance service: disc.getServices()) { if (service.serviceType.indexOf("uscle")>-1) { // now - go through the services if any, and find a Muscle service diff --git a/examples/groovy/annotationForSelectedSequence.groovy b/examples/groovy/annotationForSelectedSequence.groovy index abfad35..7cb3082 100644 --- a/examples/groovy/annotationForSelectedSequence.groovy +++ b/examples/groovy/annotationForSelectedSequence.groovy @@ -31,7 +31,7 @@ import java.awt.datatransfer.StringSelection import static java.awt.Toolkit.* -def curviewport = Jalview.getAlignFrames()[Jalview.getAlignFrames().length-1].getViewport(); +def curviewport = Jalview.getCurrentAlignFrame().getViewport(); // TSV output by default. // change "\t" to "," to output CSV file diff --git a/examples/groovy/parseproperties.groovy b/examples/groovy/parseproperties.groovy index 879bd49..ceec6d2 100644 --- a/examples/groovy/parseproperties.groovy +++ b/examples/groovy/parseproperties.groovy @@ -1,19 +1,19 @@ /* * 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 + * 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 + * + * 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. @@ -23,10 +23,9 @@ import jalview.datamodel.*; import jalview.gui.AlignFrame; import jalview.gui.AlignViewport; -def af = Jalview.getAlignFrames(); -def al = af[0].viewport.alignment; +def al = Jalview.getCurrentAlignFrame().viewport.alignment; ParseProperties pp = new ParseProperties(al); -pp.getScoresFromDescription("Score", "ScanPS Raw Score", "([-0-9.+]+)"); +pp.getScoresFromDescription("Score", "ScanPS Raw Score", "([-0-9.+]+)", true); def sqs = al.getSequenceAt(0); def annots = sqs.getAnnotation(); diff --git a/examples/groovy/printtitle.groovy b/examples/groovy/printtitle.groovy index b3387ea..a048d65 100644 --- a/examples/groovy/printtitle.groovy +++ b/examples/groovy/printtitle.groovy @@ -1,35 +1,35 @@ /* * 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 + * 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 + * + * 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. */ // do something groovy in jalview println "Hello World.\n" -println "First sequence is " + currentAlFrame.viewport.alignment.getSequenceAt(0).getDisplayId(true) +println "First sequence is " + Jalview.getCurrentAlignFrame().viewport.alignment.getSequenceAt(0).getDisplayId(true) def alf = Jalview.getAlignFrames() for (ala in alf) { - // ala is an jalview.gui.AlignFrame object + // ala is an jalview.gui.AlignFrame object println ala.getTitle() // get the parent jalview.datamodel.Alignment from the alignment viewport def alignment = ala.viewport.alignment // get the first sequence from the jalview.datamodel.Alignment object - def seq = alignment.getSequenceAt(0) + def seq = alignment.getSequenceAt(0) } Jalview.quit() diff --git a/examples/groovy/removeFeaturesByGroup.groovy b/examples/groovy/removeFeaturesByGroup.groovy index 341e06f..c947a5b 100644 --- a/examples/groovy/removeFeaturesByGroup.groovy +++ b/examples/groovy/removeFeaturesByGroup.groovy @@ -46,6 +46,7 @@ for (ala in af) } } } + ala.repaint(); } diff --git a/examples/groovy/selectColumnsByFeatureAndGroup.groovy b/examples/groovy/selectColumnsByFeatureAndGroup.groovy index b8edaa7..aaa3405 100644 --- a/examples/groovy/selectColumnsByFeatureAndGroup.groovy +++ b/examples/groovy/selectColumnsByFeatureAndGroup.groovy @@ -23,7 +23,7 @@ import jalview.datamodel.*; import jalview.gui.AlignFrame; import jalview.gui.AlignViewport; import java.util.BitSet; -import javax.swing.JOptionPane; +import jalview.gui.JvOptionPane; import groovy.swing.SwingBuilder; def toselect = getFeatureInput(); // change this to select the desired feature type @@ -81,7 +81,7 @@ for (ala in Jalview.getAlignFrames()) { cs.addElement(i); } ala.viewport.setColumnSelection(cs); - ala.alignPanel.paintAlignment(true); + ala.alignPanel.paintAlignment(true, true); ala.statusBar.setText("Marked "+bs.cardinality()+" columns containing features of type "+toselect) } else { ala.statusBar.setText("No features of type "+toselect+" found."); @@ -96,4 +96,4 @@ String getFeatureInput(){ null, 'Select columns by feature by type','Enter type of feature', JvOptionPane.OK_OPTION) return response - } \ No newline at end of file + } diff --git a/examples/groovy/sitesForSelectedColumns.groovy b/examples/groovy/sitesForSelectedColumns.groovy index 8165373..f775f18 100644 --- a/examples/groovy/sitesForSelectedColumns.groovy +++ b/examples/groovy/sitesForSelectedColumns.groovy @@ -29,7 +29,7 @@ import java.awt.datatransfer.StringSelection import static java.awt.Toolkit.* -def curviewport = Jalview.getAlignFrames()[Jalview.getAlignFrames().length-1].getViewport() +def curviewport = Jalview.getCurrentAlignFrame().getViewport() def debug = false diff --git a/examples/groovy/stripUniprotPrefixes.groovy b/examples/groovy/stripUniprotPrefixes.groovy index 71b3a9f..5a01da4 100644 --- a/examples/groovy/stripUniprotPrefixes.groovy +++ b/examples/groovy/stripUniprotPrefixes.groovy @@ -29,7 +29,7 @@ def af = Jalview.getAlignFrames(); for (ala in af) { - def al = ala.viewport.alignment; + def al = ala.getViewport().getAlignment(); if (al!=null) { SequenceI[] seqs = al.getSequencesArray(); @@ -47,5 +47,6 @@ for (ala in af) } } } + ala.repaint(); } - \ No newline at end of file + diff --git a/examples/groovy/visibleFeaturesCounter.groovy b/examples/groovy/visibleFeaturesCounter.groovy index b3180f8..510f600 100644 --- a/examples/groovy/visibleFeaturesCounter.groovy +++ b/examples/groovy/visibleFeaturesCounter.groovy @@ -1,38 +1,37 @@ /* * 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 + * 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 + * + * 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. */ -import jalview.bin.Jalview import jalview.workers.FeatureSetCounterI import jalview.workers.AlignmentAnnotationFactory /* * Demonstration of FeatureSetCounterI - * compute annotation tracks counting number of displayed + * compute annotation tracks counting number of displayed * features of each type in each column */ /* * discover features on the current view */ - -def featuresDisp=Jalview.currentAlignFrame.currentView.featuresDisplayed + +def featuresDisp=Jalview.getCurrentAlignFrame().currentView.featuresDisplayed if (featuresDisp == null) { print 'Need at least one feature visible on alignment' } @@ -40,12 +39,12 @@ def visibleFeatures=featuresDisp.visibleFeatures.toList() assert 'java.util.ArrayList' == visibleFeatures.class.name /* - * A closure that returns an array of features present + * A closure that returns an array of features present * for each feature type in visibleFeatures - * Argument 'features' will be a list of SequenceFeature + * Argument 'features' will be a list of SequenceFeature */ -def getCounts = - { features -> +def getCounts = + { features -> int[] obs = new int[visibleFeatures.size] for (sf in features) { @@ -56,9 +55,9 @@ def getCounts = * or sf.getValue(attributeName) for GFF 'column 9' properties */ int pos = 0 - for (type in visibleFeatures) + for (type in visibleFeatures) { - if (type.equals(sf.type)) + if (type.equals(sf.type)) { obs[pos]++ } @@ -67,19 +66,19 @@ def getCounts = } obs } - + /* * Define something that counts each visible feature type */ def columnSetCounter = [ - getNames: { visibleFeatures as String[] }, + getNames: { visibleFeatures as String[] }, getDescriptions: { visibleFeatures as String[] }, getMinColour: { [0, 255, 255] as int[] }, // cyan getMaxColour: { [0, 0, 255] as int[] }, // blue - count: - { res, feats -> - getCounts.call(feats) + count: + { res, feats -> + getCounts.call(feats) } ] as FeatureSetCounterI diff --git a/getdown/lib/FJVL_VERSION b/getdown/lib/FJVL_VERSION index 35bd812..2d83e61 100644 --- a/getdown/lib/FJVL_VERSION +++ b/getdown/lib/FJVL_VERSION @@ -1 +1 @@ -1.8.3-1.2.14_FJVL +1.8.3-1.3.1_FJVL diff --git a/getdown/lib/JVL_VERSION b/getdown/lib/JVL_VERSION index 0a14c3b..7d618e2 100644 --- a/getdown/lib/JVL_VERSION +++ b/getdown/lib/JVL_VERSION @@ -1 +1 @@ -1.8.3-1.2.14_JVL +1.8.3-1.3.1_JVL diff --git a/getdown/lib/getdown-core.jar b/getdown/lib/getdown-core.jar index 7c99c93..3fc97b5 100644 Binary files a/getdown/lib/getdown-core.jar and b/getdown/lib/getdown-core.jar differ diff --git a/getdown/lib/getdown-launcher-local.jar b/getdown/lib/getdown-launcher-local.jar index c6901ae..6ba0a6d 100644 Binary files a/getdown/lib/getdown-launcher-local.jar and b/getdown/lib/getdown-launcher-local.jar differ diff --git a/getdown/lib/getdown-launcher.jar b/getdown/lib/getdown-launcher.jar index 24e3eb2..7c75a34 100644 Binary files a/getdown/lib/getdown-launcher.jar and b/getdown/lib/getdown-launcher.jar differ diff --git a/getdown/src/getdown/ant/pom.xml b/getdown/src/getdown/ant/pom.xml index b0c54e2..4c91f74 100644 --- a/getdown/src/getdown/ant/pom.xml +++ b/getdown/src/getdown/ant/pom.xml @@ -4,7 +4,7 @@ com.threerings.getdown getdown - 1.8.3-1.2.14_FJVL + 1.8.3-1.3.1_FJVL getdown-ant diff --git a/getdown/src/getdown/core/pom.xml b/getdown/src/getdown/core/pom.xml index 5dd429d..2e43522 100644 --- a/getdown/src/getdown/core/pom.xml +++ b/getdown/src/getdown/core/pom.xml @@ -4,7 +4,7 @@ com.threerings.getdown getdown - 1.8.3-1.2.14_FJVL + 1.8.3-1.3.1_FJVL getdown-core diff --git a/getdown/src/getdown/core/src/main/java/com/threerings/getdown/data/Application.java b/getdown/src/getdown/core/src/main/java/com/threerings/getdown/data/Application.java index 9d9fe14..435ebbd 100644 --- a/getdown/src/getdown/core/src/main/java/com/threerings/getdown/data/Application.java +++ b/getdown/src/getdown/core/src/main/java/com/threerings/getdown/data/Application.java @@ -1137,7 +1137,6 @@ public class Application String query = jalviewUri.getQuery(); _appargs.clear(); - _appargs.add("-open"); if (host != null && host.length() > 0) { URL newUrl = new URL( (https?"https":"http") @@ -1253,8 +1252,6 @@ public class Application } if (ext != null && LOCATOR_FILE_EXTENSION.equals(ext.toLowerCase(Locale.ROOT))) { // this file extension should have been dealt with in Getdown class - } else { - _appargs.add(0, "-open"); } } diff --git a/getdown/src/getdown/core/src/main/java/com/threerings/getdown/util/LaunchUtil.java b/getdown/src/getdown/core/src/main/java/com/threerings/getdown/util/LaunchUtil.java index 0781a11..1faaa28 100644 --- a/getdown/src/getdown/core/src/main/java/com/threerings/getdown/util/LaunchUtil.java +++ b/getdown/src/getdown/core/src/main/java/com/threerings/getdown/util/LaunchUtil.java @@ -17,6 +17,8 @@ import javax.xml.bind.DatatypeConverter; import java.security.MessageDigest; +import jalview.util.LaunchUtils; + import static com.threerings.getdown.Log.log; /** @@ -88,6 +90,7 @@ public class LaunchUtil return getJVMPath(appdir, false); } + private static String jvmPath = null; /** * Reconstructs the path to the JVM used to launch this process. * @@ -95,22 +98,27 @@ public class LaunchUtil */ public static String getJVMPath (File appdir, boolean windebug) { - // first look in our application directory for an installed VM - String vmpath = checkJVMPath(new File(appdir, LOCAL_JAVA_DIR).getAbsolutePath(), windebug); - if (vmpath == null && isMacOS()) { - vmpath = checkJVMPath(new File(appdir, LOCAL_JAVA_DIR + "/Contents/Home").getAbsolutePath(), windebug); + if (jvmPath != null) { + return jvmPath; } + + // first look in our application directory for an installed VM + final String appDir = isMacOS() ? + (new File(appdir, LOCAL_JAVA_DIR).getAbsolutePath()) + "/Contents/Home" + : new File(appdir, LOCAL_JAVA_DIR).getAbsolutePath(); + + String javaBin = LaunchUtils.findJavaBin(appDir, windebug, false); // then fall back to the VM in which we're already running - if (vmpath == null) { - vmpath = checkJVMPath(System.getProperty("java.home"), windebug); + if (javaBin == null) { + javaBin = LaunchUtils.findJavaBin(System.getProperty("java.home"), windebug, false); } // then throw up our hands and hope for the best - if (vmpath == null) { + if (javaBin == null) { + javaBin = LaunchUtils.findJavaBin(null, windebug, true); log.warning("Unable to find java [appdir=" + appdir + ", java.home=" + System.getProperty("java.home") + "]!"); - vmpath = "java"; } // Oddly, the Mac OS X specific java flag -Xdock:name will only work if java is launched @@ -120,15 +128,16 @@ public class LaunchUtil if (isMacOS()) { try { File localVM = new File("/usr/bin/java").getCanonicalFile(); - if (localVM.equals(new File(vmpath).getCanonicalFile())) { - vmpath = "/usr/bin/java"; + if (localVM.equals(new File(javaBin).getCanonicalFile())) { + javaBin = "/usr/bin/java"; } } catch (IOException ioe) { log.warning("Failed to check Mac OS canonical VM path.", ioe); } } - return vmpath; + jvmPath = javaBin; + return jvmPath; } private static String _getMD5FileChecksum (File file) { diff --git a/getdown/src/getdown/core/src/main/java/jalview/util/LaunchUtils.java b/getdown/src/getdown/core/src/main/java/jalview/util/LaunchUtils.java index ee3b2c6..784eb5a 100644 --- a/getdown/src/getdown/core/src/main/java/jalview/util/LaunchUtils.java +++ b/getdown/src/getdown/core/src/main/java/jalview/util/LaunchUtils.java @@ -32,6 +32,16 @@ import java.util.Properties; public class LaunchUtils { + // setting these is LaunchUtils so don't need to import Platform + public final static boolean isMac = System.getProperty("os.name") + .indexOf("Mac") > -1; + + public final static boolean isWindows = System.getProperty("os.name") + .indexOf("Win") > -1; + + private static boolean isJS = /** @j2sNative true || */ + false; + public static void loadChannelProps(File dir) { ChannelProperties.loadProps(dir); @@ -81,7 +91,11 @@ public class LaunchUtils public static int getJavaCompileVersion() { - if (JAVA_COMPILE_VERSION > 0) + if (LaunchUtils.isJS) + { + return -1; + } + else if (JAVA_COMPILE_VERSION > 0) { return JAVA_COMPILE_VERSION; } @@ -125,7 +139,11 @@ public class LaunchUtils public static int getJavaVersion() { - if (JAVA_VERSION > 0) + if (LaunchUtils.isJS) + { + return -1; + } + else if (JAVA_VERSION > 0) { return JAVA_VERSION; } @@ -153,6 +171,10 @@ public class LaunchUtils public static boolean checkJavaVersion() { + if (LaunchUtils.isJS) + { + return true; + } String buildDetails = "jar:".concat(LaunchUtils.class .getProtectionDomain().getCodeSource().getLocation().toString() .concat("!" + "/.build_properties")); @@ -174,4 +196,88 @@ public class LaunchUtils return true; } + + public static String findJavaBin(boolean winConsole) + { + return findJavaBin(System.getProperty("java.home"), winConsole, true); + } + + /* + * Returns a string path to the most likely java binary wanted to run this + * installation of Jalview. + * + * @param winConsole whether to use java.exe (console) in preference to javaw.exe + * (only affects Windows). + * @param javaHome Try this javaHome dir (defaults to the running java.home). + * @param generic Return a generic java command if not found. + */ + public static String findJavaBin(String javaHome, boolean winConsole, + boolean generic) + { + String javaBin = null; + final String javaExe = winConsole ? "java.exe" : "javaw.exe"; + final String java = "java"; + + if (javaHome != null) + { + // property "channel.app_name" is set by install4j when launching getdown + String propertyAppName = System.getProperty("channel.app_name"); + final String appName = (propertyAppName != null + && propertyAppName.length() > 0) ? propertyAppName + : ChannelProperties.getProperty("app_name"); + + final String javaBinDir = javaHome + File.separator + "bin" + + File.separator; + + // appName and "Jalview" will not point to javaw.exe or java.exe but in + // this case that's okay because the taskbar display name problem doesn't + // manifest in Windows. See JAL-3820, JAL-4189. + for (String name : new String[] { appName, "Jalview", java, javaExe }) + { + if (LaunchUtils.checkJVMSymlink(javaBinDir + name, winConsole)) + { + javaBin = javaBinDir + name; + break; + } + } + } + + if (javaBin == null && generic) + { + javaBin = LaunchUtils.isWindows ? javaExe : java; + } + + return javaBin; + } + + /* + * checkJVMSymlink returns true if the path in testBin *is* a java binary, or + * points to a java binary. + * @param testBin The binary or symbolic link to check + * @param winConsole whether we are in/want a Windows console (only relevant for Windows, + * determines whether we use java.exe or javaw.exe) + */ + private static boolean checkJVMSymlink(String testBin, boolean winConsole) + { + File testBinFile = new File(testBin); + if (!testBinFile.exists()) + { + return false; + } + File targetFile = null; + try + { + targetFile = testBinFile.getCanonicalFile(); + } catch (IOException e) + { + return false; + } + final String javaExe = winConsole ? "java.exe" : "javaw.exe"; + if (targetFile != null && ("java".equals(targetFile.getName()) + || javaExe.equals(targetFile.getName()))) + { + return true; + } + return false; + } } diff --git a/getdown/src/getdown/launcher/pom.xml b/getdown/src/getdown/launcher/pom.xml index ea3b6ef..c6b9ff3 100644 --- a/getdown/src/getdown/launcher/pom.xml +++ b/getdown/src/getdown/launcher/pom.xml @@ -4,7 +4,7 @@ com.threerings.getdown getdown - 1.8.3-1.2.14_FJVL + 1.8.3-1.3.1_FJVL getdown-launcher diff --git a/getdown/src/getdown/mvn_cmd b/getdown/src/getdown/mvn_cmd index b30194f..10942f8 100755 --- a/getdown/src/getdown/mvn_cmd +++ b/getdown/src/getdown/mvn_cmd @@ -3,7 +3,7 @@ if [ x$JVLVERSION != x ]; then export VERSION=$JVLVERSION else - export VERSION=1.8.3-1.2.14_JVL + export VERSION=1.8.3-1.3.1_JVL fi if [ x${VERSION%_JVL} = x$VERSION ]; then diff --git a/getdown/src/getdown/pom.xml b/getdown/src/getdown/pom.xml index ef8c811..cf32333 100644 --- a/getdown/src/getdown/pom.xml +++ b/getdown/src/getdown/pom.xml @@ -10,7 +10,7 @@ com.threerings.getdown getdown pom - 1.8.3-1.2.14_FJVL + 1.8.3-1.3.1_FJVL getdown An application installer and updater. diff --git a/gradle.properties b/gradle.properties index 547304f..79fb11d 100644 --- a/gradle.properties +++ b/gradle.properties @@ -28,6 +28,8 @@ jalview_keydig = SHA1 testng_groups = Functional testng_excluded_groups = +test_output = + j8libDir = j8lib j11libDir = j11lib @@ -177,7 +179,7 @@ imagemagick_convert = ~/buildtools/imagemagick/bin/convert bamboo_channelbase = https://builds.jalview.org/browse bamboo_planKey = -bamboo_getdown_channel_suffix = /latest/artifact/shared/getdown-channel +bamboo_getdown_channel_suffix = /latest/artifact/shared/getdown-build-for-website/default eclipse_codestyle_file = utils/eclipse/JalviewCodeStyle.xml eclipse_extra_jdt_prefs_file = utils/eclipse/org.eclipse.jdt.core.jalview.prefs diff --git a/help/help/help.jhm b/help/help/help.jhm index a2094f7..5fb7901 100755 --- a/help/help/help.jhm +++ b/help/help/help.jhm @@ -161,7 +161,10 @@ + + + diff --git a/help/help/helpTOC.xml b/help/help/helpTOC.xml index d7ff3d4..6d7c948 100755 --- a/help/help/helpTOC.xml +++ b/help/help/helpTOC.xml @@ -23,13 +23,10 @@ - - - - - - - + + + + diff --git a/help/help/html/colourSchemes/annotationColouring.html b/help/help/html/colourSchemes/annotationColouring.html index 2272503..c9221a1 100755 --- a/help/help/html/colourSchemes/annotationColouring.html +++ b/help/help/html/colourSchemes/annotationColouring.html @@ -30,9 +30,17 @@

Jalview allows the columns of an alignment to be coloured using any numerical annotation rows added to that alignment.

Select "Colour" - ".. by Annotation" to bring up the + "by Annotation..." to bring up the Colour by Annotation settings window.
+
You can also apply Colour by annotation for a particular annotation + (or per-sequence set) by right-clicking an annotation row's label and selecting "Colour by Annotation..." or "Colour by Annotation (per Sequence)..." from the + Annotation label popup menu. (Since Jalview 2.11.3) +
+
+ +
+

The Colour by Annotation Settings Window


diff --git a/help/help/html/features/annotation.html b/help/help/html/features/annotation.html index b63d20b..76b23eb 100755 --- a/help/help/html/features/annotation.html +++ b/help/help/html/features/annotation.html @@ -29,7 +29,7 @@

In addition to the definition of groups and sequence features, - Jalview can display symbols and graphs under the columns of an + Jalview can display symbols, line graphs, histograms and heatmaps under the columns of an alignment. These annotation tracks are displayed in the annotation area below the alignment. The annotation area's visibility is controlled with the View→Show Annotation @@ -40,15 +40,14 @@

  • Sequence associated annotation.
    Data displayed on sequence - annotation rows are associated with the positions of a sequence. + associated annotation rows are associated with the positions of a sequence. Often this is 'Reference annotation' such as secondary structure information derived from 3D structure data, or from the results of sequence based prediction of secondary structure and disorder. - If reference annotation is available for a the currently selected - sequences, it can be shown by selecting the Add + If reference annotations are available for a particular sequence or the current selections, they can be shown by selecting the Add Reference Annotation option in the sequence or selection popup - menu.
  • + menu.
    Jalview currently supports the following sources of sequence associated annotation:
    • Protein and RNA Secondary Structure
      These can be obtained from JPred and RNAAliFold secondary structure prediction services, and also for imported 3D Structure data.
    • Temperature factor, Model Quality or AlphaFold Reliability
      Jalview extracts and displays values from the 'Temperature Factor' column of PDB and mmCIF files, interpreted in various ways. For regular PDB files, these are imported directly as 'Temperature Factor', but for structures from computational methods such as EBI-AlphaFold, these values are interpreted and shown as 'AlphaFold Reliability' or 'Model Quality' according to the source.
    • Predicted Alignment Error heatmaps
      These are displayed for models retrieved from EBI-AlphaFold or when a supported JSON format PAE file is provided when importing a local 3D structure file.
  • Group associated annotation.
    Data can be associated with groups defined on the alignment. If sequence groups are defined, Conservation @@ -86,9 +85,11 @@ alignment. Annotations can also be used to select or hide columns via the dialog opened from the Selection - menu. + menu. You can also colour, select or hide columns of the alignment using any displayed annotation row by right-clicking its label and selecting the option from the displayed pop-up menu.

    + Adjusting the height of histograms, line graphs and heatmaps
    The height of line graphs, bar charts and predicted alignment error (PAE) matrix heatmaps can be adjusted simply by click-dragging them up or down to increase or decrease the height. Hold down SHIFT to adjust the height of all instances of a particular type of annotation row.

    +

    Sequence Highlighting and Selection from Annotation

    @@ -101,6 +102,15 @@ (Mac CMD) double-click will toggle inclusion of associated sequences in the selection.

    + Selecting, analysing and exploring heatmap annotation +

    Mouseovers on heap annotation tracks result in a tooltip displaying information about the range of values under the mouse, and their associated row and column in the heatmap.
    For Predicted Alignment Error (PAE) matrices, the only form of heatmap annotation currently supported by Jalview, both the vertical and horizontal positions in the heatmap correspond to positions in linked 3D structures and the associated sequence in the alignment - so clicking any position in a heatmap will select columns in the alignment corresponding to the selected row(s) and column under the mouse. +

      +
    • Rows and columns in the heatmap corresponding to currently selected columns in the alignment are shown as red horizontal and vertical bands.
    • +
    • Rectangular Selections can be created by pressing CMD (or Window/Meta key) whilst click-dragging across an area of the annotation.
    • +
    • Data driven selections - e.g. selecting regions of low values of Predicted Alignment Error in a heatmap can be dome by pressing CTRL whilst clicking a region of an alignment.
    • +
    + Heatmap annotations can also be clustered, enabling columns of the alignment to be grouped based on similarity of the sets of values in the heatmap. Double clicking a region of a clustered heatmap annotation will select both the row and columns of the alignment grouped by the clustering. See clustering PAE matrices for more information. +

    Interactive Alignment Annotation

    @@ -144,6 +154,13 @@ in 2.5)
    Selecting this toggles whether column labels will be shrunk to fit within each column, or displayed using the view's standard font size.

  • +
  • (introduced in 2.11.3)
  • +
  • (introduced in 2.11.3)
  • +
  • (introduced in 2.11.3)
  • +
  • (introduced in 2.11.3)
  • +
  • (introduced in 2.11.3)
  • +
  • (introduced in 2.11.3)
  • +

Editing labels and secondary structure annotation diff --git a/help/help/html/features/annotationsubmenucolbyannot.png b/help/help/html/features/annotationsubmenucolbyannot.png new file mode 100644 index 0000000..22f69d9 Binary files /dev/null and b/help/help/html/features/annotationsubmenucolbyannot.png differ diff --git a/help/help/html/features/clarguments-advanced.html b/help/help/html/features/clarguments-advanced.html index a235727..8e4012c 100644 --- a/help/help/html/features/clarguments-advanced.html +++ b/help/help/html/features/clarguments-advanced.html @@ -49,11 +49,11 @@

Alignment linked IDs

- Jalview's alignment related arguments are linked together using a linked ID. In all of the basic usage examples this linked ID is assigned using a default formula of JALVIEW:n where n starts at 0 and increments every time there is an --opened file (or a first use of --append) or the --new argument is used. + Jalview's alignment related arguments are linked together using a linked ID. In all of the basic usage examples this linked ID is assigned using a default formula of JALVIEW:n where n starts at 0 and increments every time there is an ‑‑opened file (or a first use of ‑‑append) or the ‑‑new argument is used.

- When another alignment related argument is used (without a specified linked ID), it is assigned this default linked ID. When the --all argument is used, following alignment related arguments are applied to all of the linked IDs (made so far). + When another alignment related argument is used (without a specified linked ID), it is assigned this default linked ID. When the ‑‑all argument is used, following alignment related arguments are applied to all of the linked IDs (made so far).

@@ -67,7 +67,7 @@

- A specified linked ID will also take precedence over a wildcard or --all set linked ID. e.g. + A specified linked ID will also take precedence over a wildcard or ‑‑all set linked ID. e.g.

   jalview --open[myID] examples/uniref50.fa --all --colour taylor --colour[myID] gecos-blossom
   
@@ -75,18 +75,18 @@

-

More substitutions ({n}, {++n}, [*])

+

More substitutions ({n}, {++n}, [*], {m}, {++m})

In the basic usage document we have a list of special strings that get replaced in output filename values with parts of input filename values.

- There is also an incrementor integer value {n} that can be put into both linked IDs and filenames and works across different linked IDs. Whenever you use {n} in a linked ID or filename value it is replaced with the current value of n. The initial value is 0, and it can be incremented by using the argument --npp or --n++, or using a another special substitution {++n} in either a linked ID or filename value which increments the value and is replaced with the new incremented value of n. + There is also an incrementor integer value {n} that can be put into both linked IDs and filenames and works across different linked IDs. Whenever you use {n} in a linked ID or filename value it is replaced with the current value of n. The initial value is 0, and it can be incremented by using the argument ‑‑npp or ‑‑n++, or using a another special substitution {++n} in either a linked ID or filename value which increments the value and is replaced with the new incremented value of n.

- In the same way that the --all argument enables (some) following arguments to apply to all opened alignments so far, the special linked ID * will also apply an individual argument to all opened linked IDs (in fact when you use the --all argument it simply changes the default linked ID to *). + In the same way that the ‑‑all argument enables (some) following arguments to apply to all opened alignments so far, the special linked ID * will also apply an individual argument to all opened linked IDs (in fact when you use the ‑‑all argument it simply changes the default linked ID to *).

   jalview --open[myId1] fileA.fa --open[myId2] fileB.fa --open[myId3] fileC.fa --colour[*] taylor --all --image tmp/image-{++n}.png --headless
   
@@ -97,8 +97,10 @@ because all of the command line arguments are read and sorted into their linked IDs before starting to be processed, and the [myId3] specified linked ID takes precedence over the [*] wildcard linked ID.

-

+

+ All of the substitutions talked about so far are evaluated in the argument parsing process. If in some cases (almost certainly involving structure images!) you find {n} is not incrementing when you think it should, when specifying ‑‑structureimage filenames you can also use {m} and {++m}, along with {structuredirname}, {structurebasename} and {structureextension} which are substituted at the point of use. {m} is just a plain counter starting at 0. +

Equals separator and Java file globs

@@ -118,7 +120,7 @@

- One benefit of this is seen above in the --image argument, the special "alloutput" wildcard filename *.png will not be expanded by the shell, so does not need to be escaped or surrounded with quotation marks. + One benefit of this is seen above in the ‑‑image argument, the special "alloutput" wildcard filename *.png will not be expanded by the shell, so does not need to be escaped or surrounded with quotation marks.

@@ -150,7 +152,7 @@

- Some arguments (such as --scale=n) are used to modify the behaviour of other "primary" arguments (such as --image=filename). These arguments can alternatively be specifed as sub-value modifiers of the values given to the primary argument. If specified as a sub-value modifier, this modifier takes precedence over any following linked argument if given. e.g + Some arguments (such as ‑‑scale=n) are used to modify the behaviour of other "primary" arguments (such as ‑‑image=filename). These arguments can alternatively be specifed as sub-value modifiers of the values given to the primary argument. If specified as a sub-value modifier, this modifier takes precedence over any following linked argument if given. e.g

   jalview --open=[colour=zappo]examples/*.fa
   
@@ -166,7 +168,7 @@

- You can specify multiple sub-value modifiers separating them with a comma (','). If you wish to specify a "boolean" argument, such as --wrap or --nowrap then simply use the argument name without a value, like this: + You can specify multiple sub-value modifiers separating them with a comma (','). If you wish to specify a "boolean" argument, such as ‑‑wrap or ‑‑nowrap then simply use the argument name without a value, like this:

   jalview --open=[colour=gecos-flower,wrap,noannotations,features=examples/plantfdx.features]examples/plantfdx.fa
   
diff --git a/help/help/html/features/clarguments-argfiles.html b/help/help/html/features/clarguments-argfiles.html index 5c71d16..ad27751 100644 --- a/help/help/html/features/clarguments-argfiles.html +++ b/help/help/html/features/clarguments-argfiles.html @@ -86,7 +86,7 @@

- Because --argfiles takes a filename argument, and multiple --argfiles can be read on the command line, you can also use file globs to specify multiple --argfile values. If you produce an argument file for each set of alignment files that you wish to associate then you can act on all of them with, e.g. + Because ‑‑argfiles takes a filename argument, and multiple ‑‑argfiles can be read on the command line, you can also use file globs to specify multiple ‑‑argfile values. If you produce an argument file for each set of alignment files that you wish to associate then you can act on all of them with, e.g.

   jalview --argfile=*/argfile.txt --headless
   
@@ -124,7 +124,7 @@

Only argument files

- When you use an --argfile argument, all other non-initialising arguments on the command line will be ignored. Only the initialising arguments and any and all --argfiles arguments on the command line will be used. You can also set initialising arguments in argument files. + When you use an ‑‑argfile argument, all other non-initialising arguments on the command line will be ignored. Only the initialising arguments and any and all ‑‑argfiles arguments on the command line will be used. You can also set initialising arguments in argument files.

diff --git a/help/help/html/features/clarguments-basic.html b/help/help/html/features/clarguments-basic.html index 7a87602..238366c 100644 --- a/help/help/html/features/clarguments-basic.html +++ b/help/help/html/features/clarguments-basic.html @@ -47,10 +47,10 @@
  • The all output wildcard
  • -

    Opening alignments (--open, --append, --new)

    +

    Opening alignments (‑‑open, ‑‑append, ‑‑new)

    - To simply open one or more alignment files in different windows just put the filenames as the first arguments: + To simply open one or more alignment files in different alignment windows just put the filenames as the first arguments:

       jalview filename1 filename2 ...
       
    @@ -68,14 +68,14 @@

    - (Using initial filenames is the same as using the --open argument, and further arguments can be used + (Using initial filenames is the same as using the ‑‑open argument, and further arguments can be used after the initial filenames.)

    -

    --open

    +

    ‑‑open

    - Use the --open argument to open alignment files each in their own window. + Use the ‑‑open argument to open alignment files each in their own window.

    @@ -98,14 +98,14 @@

    -

    --append

    +

    ‑‑append

    To append several alignment files together use:

       jalview --open filename1.fa --append filename2.fa filename3.fa
       
    - or, if you haven't previously used --open then you can use --append to open one new window and keep appending each set of alignments: + or, if you haven't previously used ‑‑open then you can use --append to open one new window and keep appending each set of alignments:
       jalview --append these/filename*.fa --append more/filename*.fa
     
    @@ -114,29 +114,34 @@
       

    - Note that whilst you can include a Jalview Project File (.jvp) as an --append value, the items in the file will always open in their original windows and not append to another. + Note that whilst you can include a Jalview Project File (.jvp) as an ‑‑append value, the items in the file will always open in their original windows and not append to another.

    -

    --new

    +

    ‑‑new

    - To append different sets of alignment files in different windows, use --new to move on to a new alignment window: + To append different sets of alignment files in different windows, use ‑‑new to move on to a new alignment window:

       jalview --append these/filename*.fa --new --append other/filename*.fa
       

    - --open is like using --new --append applied to every filename/URL given to --open + ‑‑open is like using ‑‑new --append applied to every filename/URL given to ‑‑open

    -

    Alignment options (--colour, --wrap, --showannotations, --title)

    +

    Alignment options (‑‑colour, ‑‑wrap, ‑‑showannotations, ‑‑title)

    -

    --colour

    +

    + An opened alignment window (or set of opened alignment windows) can be modified in its appearance using the following arguments before the next ‑‑open argument. These modifying arguments apply to the one or more files that were opened with the preceding ‑‑open argument. E.g. ‑‑open file.fa --colour gecos-flower will colour the one alignment window with file.fa. However, ‑‑open *.fa --colour gecos-flower will colour every alignment window matching file*.fa, and --open file1.fa file2.fa --colour gecos-flower + will colour both opened alignment windows. +

    + +

    ‑‑colour

    - You can specify a residue/base colouring for the alignment using the --colour option (note spelling -- Jalview is made in Scotland!): + You can specify a residue/base colouring for the alignment using the ‑‑colour option (note spelling -- Jalview is made in Scotland!):

       jalview --open examples/uniref50.fa --colour gecos-flower
       
    @@ -185,31 +190,31 @@ sequence-id

    -

    --wrap

    +

    ‑‑wrap

    - An alignment should open with your usual preferences stored in the .jalview_properties file. To open an alignment with the sequences (definitely) wrapped, following your --open (or first --append) argument use the argument --wrap: + An alignment should open with your usual preferences stored in the .jalview_properties file. To open an alignment with the sequences (definitely) wrapped, following your ‑‑open (or first ‑‑append) argument use the argument ‑‑wrap:

       jalview --open examples/uniref50.fa --wrap
       
    - To ensure an alignment is not wrapped use --nowrap: + To ensure an alignment is not wrapped use ‑‑nowrap:
       jalview --open examples/uniref50.fa --nowrap
       

    -

    --showannotations / --noshowannotations

    +

    ‑‑showannotations / ‑‑noshowannotations

    - You can specify whether the currently opened alignment window should show alignment annotations (e.g. Conservation, Quality, Consensus...) or not with either --showannotations or --noshowannotations. If you don't specify then your saved preference will be used. + You can specify whether the currently opened alignment window should show alignment annotations (e.g. Conservation, Quality, Consensus...) or not with either ‑‑showannotations or ‑‑noshowannotations. If you don't specify then your saved preference will be used.

       jalview --open examples/uniref50.fa --noshowannotations
       

    -

    --title

    +

    ‑‑title

    - If you would like to give the alignment window a specific title you can do so with the --title option: + If you would like to give the alignment window a specific title you can do so with the ‑‑title option:

       jalview --open examples/uniref50.fa --title "My example alignment"
       
    @@ -218,28 +223,28 @@ -

    Adding 3D structures (--structure, --seqid, --structureviewer, --paematrix, --tempfac, --showssannotations)

    +

    Adding 3D structures (‑‑structure, ‑‑seqid, ‑‑structureviewer, ‑‑paematrix, ‑‑tempfac, ‑‑showssannotations)

    -

    --structure

    +

    ‑‑structure

    - You can add a 3D structure file to a sequence in the current alignment window with the --structure option: + You can add a 3D structure file to a sequence in the current alignment window with the ‑‑structure option:

       jalview --open examples/uniref50.fa --structure examples/AlphaFold/AF-P00221-F1-model_v4.pdb
       
    By default this attaches to the first sequence in the alignment but most likely you will want to attach it to a specific sequence.

    -

    --seqid

    +

    ‑‑seqid

    - The easiest way to specify a sequence ID for your structure is to follow the --structure argument with a --seqid argument with a value of a sequence ID in the alignment. This does of course require some knowledge of the sequences in the alignment files + The easiest way to specify a sequence ID for your structure is to follow the ‑‑structure argument with a ‑‑seqid argument with a value of a sequence ID in the alignment. This does of course require some knowledge of the sequences in the alignment files that have been opened.
    - Alternatively you can specify a sub-value with the --structure argument value. You do this by preceding the value with square brackets and seqid=SequenceId, + Alternatively you can specify a sub-value with the ‑‑structure argument value. You do this by preceding the value with square brackets and seqid=SequenceId, like this:

       jalview --open examples/uniref50.fa --structure [seqid=FER1_SPIOL]examples/AlphaFold/AF-P00221-F1-model_v4.pdb
    @@ -251,7 +256,7 @@
       

    - The sub-value seqid=FER1_SPIOL takes precedence over the following argument --seqid FER1_SPIOL if you accidentally specify both (in which case the argument will probably be completely unused). + The sub-value seqid=FER1_SPIOL takes precedence over the following argument ‑‑seqid FER1_SPIOL if you accidentally specify both (in which case the argument will probably be completely unused).

    @@ -265,10 +270,10 @@ Remember that you might need to escape any spaces in the sequence ID or enclose the ID in quotation marks.

    -

    --structureviewer

    +

    ‑‑structureviewer

    - You can specify which structure viewer (or none) to use to open the structure using either the --structureviewer argument or the structureviewer sub-value. Multiple sub-values can be specified together, separated by a comma ','. Possible values for the structureviewer are: + You can specify which structure viewer (or none) to use to open the structure using either the ‑‑structureviewer argument or the structureviewer sub-value. Multiple sub-values can be specified together, separated by a comma ','. Possible values for the structureviewer are:
    none,
    @@ -291,30 +296,30 @@

    -

    --paematrix

    +

    ‑‑paematrix

    - If you are opening a structure file that has a PAE matrix (provided as a JSON file), such as from an AlphaFold model or an nf-core pipeline, you can add the PAE matrix as an annotation by following the --structure argument with a --paematrix argument with the filename. You can also specify a paematrix=filename sub-value. + If you are opening a structure file that has a PAE matrix (provided as a JSON file), such as from an AlphaFold model or an nf-core pipeline, you can add the PAE matrix as an annotation by following the ‑‑structure argument with a ‑‑paematrix argument with the filename. You can also specify a paematrix=filename sub-value.

       jalview --open examples/uniref50.fa --structure [seqid=FER1+SPIOL,structureviewer=pymol]examples/AlphaFold/AF-P00221-F1-model_v4.pdb --paematrix examples/AlphaFold/AF-P00221-F1-predicted_aligned_error_v4.json
       

    -

    --tempfac

    +

    ‑‑tempfac

    - Structure files may have a temperature factor associated with the structure component positions. If the temperature factor is a pLDDT confidence score, such as with an AlphaFold model, you can specify this by using a following argument of --tempfac with a value of plddt. This will enable standard pLDDT colouring of the temperature factor annotation. Valid values are: + Structure files may have a temperature factor associated with the structure component positions. If the temperature factor is a pLDDT confidence score, such as with an AlphaFold model, you can specify this by using a following argument of ‑‑tempfac with a value of plddt. This will enable standard pLDDT colouring of the temperature factor annotation. Valid values are: default, plddt. More types of temperature factor may be added in future releases of Jalview.
    The value can also be specified as a sub-value:

    -  jalview --open examples/uniref50.fa --structure [seqid=FER1+SPIOL,structureviewer=jmol,tempfac=plddt]examples/AlphaFold/AF-P00221-F1-model_v4.pdb
    +  jalview --open examples/uniref50.fa --structure [seqid=FER1_SPIOL,structureviewer=jmol,tempfac=plddt]examples/AlphaFold/AF-P00221-F1-model_v4.pdb
       
    which is equivalent to
    -  jalview --open examples/uniref50.fa --structure examples/AlphaFold/AF-P00221-F1-model_v4.pdb --tempfac plddt --seqid FER1+SPIOL
    +  jalview --open examples/uniref50.fa --structure examples/AlphaFold/AF-P00221-F1-model_v4.pdb --tempfac plddt --seqid FER1_SPIOL
        --structureviewer jmol
       
    @@ -322,10 +327,10 @@ -

    --showssannotations / --noshowssannotations

    +

    ‑‑showssannotations / ‑‑noshowssannotations

    - You can specify whether the currently opened alignment window should show secondary structure annotations or not with either --showssannotations or --noshowssannotations. If you don't specify then your saved preference will be used. + You can specify whether the currently opened alignment window should show secondary structure annotations or not with either ‑‑showssannotations or ‑‑noshowssannotations. If you don't specify then your saved preference will be used.

       jalview --open examples/uniref50.fa --structure examples/AlphaFold/AF-P00221-F1-model_v4.pdb --noshowssannotations
       
    @@ -335,7 +340,7 @@

    -

    Outputting/converting alignment files and images (--output, --format, --image, --type, --textrenderer, --scale, --backups, --overwrite)

    +

    Outputting/converting alignment files and images (‑‑output, ‑‑format, ‑‑image, ‑‑structureimage, ‑‑type, ‑‑scale, ‑‑width, ‑‑height, ‑‑imagecolour, ‑‑bgcolour, ‑‑textrenderer, ‑‑overwrite, ‑‑backups, ‑‑mkdirs)

    You can save an alignment as an alignment file, or exported as an image, in different formats. Jalview's alignment output formats are: @@ -362,10 +367,10 @@ In bitmap formats (currently only PNG, but what else would you want?!) you can specify a scaling factor to improve the resolution of the output image.

    -

    --output

    +

    ‑‑output

    - To save the open alignment in a new alignment file use --output filename. The format for the file can be found from the extension of filename, or if you are using a non-standard extension you can use a following --format argument, or specify it as a sub-value modifier. + To save the open alignment in a new alignment file use ‑‑output filename. The format for the file can be found from the extension of filename, or if you are using a non-standard extension you can use a following ‑‑format argument, or specify it as a sub-value modifier.

    Recognised formats and their recognised extensions are: @@ -393,6 +398,7 @@ phylip (phy),
    jalview (jvp, jar). +

    For example, to open a FASTA file, append another FASTA file and then save the concatenation as a Stockholm file, do

    @@ -409,17 +415,43 @@
       

    - Important! If you use --output or any other argument that outputs a file, then it will be assumed you want to run Jalview in headless mode (as if you had specified --headless). To use Jalview with --output and not assume headless mode, use the --gui or --noheadless argument (the order doesn't matter). + Important! If you use ‑‑output or any other argument that outputs a file, then it will be assumed you want to run Jalview in headless mode (as if you had specified ‑‑headless). To use Jalview with ‑‑output and not assume headless mode, use the ‑‑gui argument (the order doesn't matter).

    -

    --format

    +

    + If you would like to output an alignment file directly to standard output (often referred to as STDOUT), then use the filename - (a single hyphen). In this case any messages that would normally appear on STDOUT will be diverted to STDERR to avoid invalidating the output file. +

    +

    + For example, to open a Stockholm file and pipe it to another command as a Block file, do +

    +  jalview --open alignment1.stk --output - --format blc | another_command
    +  
    + or equivalently +
    +  jalview alignment1.stk --output=[format=blc]- | another_command
    +  
    +

    + +

    ‑‑format

    - To specify the format of the output file (if using an unrecognised file extension) use the --format argument to specify a value (see above). A sub-value modifier on the --output value can also be used. + To specify the format of the output file (if using an unrecognised file extension) use the ‑‑format argument to specify a value (see above). A sub-value modifier on the ‑‑output value can also be used. +

    + +

    ‑‑image

    +

    + To export the open alignment window as an image, use the ‑‑image argument, which will give an image of the alignment and annotations as it appears (or would appear if not in ‑‑headless mode) in the alignment window if it was large enough for the whole alignment, including colour scheme and features. +

    +

    +

    +  jalview --open examples/plantfdx.fa --colour gecos-blossom --features examples/plantfdx.features --annotations examples/plantfdx.annotations --image plantfdx.png --headless
    +  

    -

    --image

    - To export the open alignment window as an image, use the --image argument, which will give an image of the alignment and annotations as it appears (or would appear if not in --headless mode) in the alignment window if it was large enough for the whole alignment, including colour choice and features. +

    ‑‑structureimage

    +

    + To export an open structure as an image, use the ‑‑structureimage argument, which will give an image of the structure as it appears (or would appear if not in ‑‑headless mode) in a Jmol window including colour scheme. ‑‑structureimage can currently only be used with structures opened with the jmol structureviewer (the default viewer). +

       jalview --open examples/plantfdx.fa --colour gecos-blossom --features examples/plantfdx.features --annotations examples/plantfdx.annotations --image plantfdx.png --headless
    @@ -427,9 +459,25 @@
       

    - This by default produces a PNG image of screen or webpage resolution, which you may want to improve upon. There are two ways of doing this with Jalview: increasing the scale of the PNG image, or using a vector based image format (EPS, SVG, HTML). + These by default produce a PNG image of screen or webpage resolution, which you will probably want to improve upon. There are two ways of doing this with Jalview: increasing the scale of the PNG image, or using a vector based image format (EPS, SVG, HTML).

    +

    ‑‑type

    + +

    + To specify the type of image file to write (if using an unrecognised file extension) use the ‑‑type argument to specify a value (see above). A sub-value modifier on the ‑‑image and ‑‑structureimage value can also be used. Valid values are: +
    + png - A Portable Network Graphics image (bitmap, default), +
    + svg - A Scalable Vector Graphics image (vector), +
    + eps - An Encapsulated PostScript file (vector), +
    + html - An HTML rendition of the alignment with embedded source data (vector/web browser), +
    + biojs - An HTML rendition of the alignment with interactive MSA viewer BioJS-MSA (vector). +

    +

    Bitmap image types (png)

    @@ -442,67 +490,89 @@ Let's increase the resolution of the PNG image:

    -

    --scale

    +

    ‑‑scale

    - We can increase the size of the PNG image by a factor of S by following the --image argument with a --scale S argument and value. The value doesn't have to be an integer and should be given as an integer or floating point formatted number, e.g. + We can increase the size of the PNG image by a factor of S by following the ‑‑image or ‑‑structureimage argument with a ‑‑scale S argument and value. The value doesn't have to be an integer and should be given as an integer or floating point formatted number, e.g.

       jalview --open examples/uniref50.fa --colour gecos-ocean --image mypic.png --scale 5.5 --headless
       
    - which will produce a PNG image 5.5 times larger (and more detailed) than without the --scale argument. + which will produce a PNG image 5.5 times larger (and more detailed) than without the ‑‑scale argument.

    However, since you won't necessarily already know the size of an alignment's exported image you can specify either an exact width or height (in pixels) with either one of the - --width and --height arguments: + ‑‑width and ‑‑height arguments: -

    --width

    +

    ‑‑width

    - Specify an exact width of an exported PNG image with --width: + Specify an exact width of an exported PNG image with ‑‑width:

       jalview --headless --open https://www.ebi.ac.uk/interpro/api/entry/pfam/PF03760/?annotation=alignment%3Aseed --noshowannotations --colour gecos-sunset --image wallpaper.png --width 3840
       

    -

    --height

    +

    ‑‑height

    - Alternatively specify an exact height with the --height argument: + Alternatively specify an exact height with the ‑‑height argument:

       jalview --headless --open https://www.ebi.ac.uk/interpro/api/entry/pfam/PF03760/?annotation=alignment%3Aseed --noshowannotations --colour gecos-ocean --image wallpaper.png --height 2160
       

    - You can specify two or all of --scale, --width and --height as limits to the size of the image (think of one or two bounding boxes) and the one which produces the smallest scale of image is used. You can also specify each of these as sub-value modifiers to the --image value: + You can specify two or all of ‑‑scale, ‑‑width and ‑‑height as limits to the size of the image (think of one or two bounding boxes) and the one which produces the smallest scale of image is used. You can also specify each of these as sub-value modifiers to the ‑‑image or ‑‑structureimage value:

       jalview --headless --open https://www.ebi.ac.uk/interpro/api/entry/pfam/PF03760/?annotation=alignment%3Aseed --noshowannotations --colour gecos-flower --image [scale=0.25,width=320,height=240]thumbnail.png
       

    +

    ‑‑imagecolour

    + +

    + Specify a colour scheme to use just for this image using the ‑‑imagecolour argument: +

    +  jalview --open examples/uniref50.fa --colour gecos-flower --image uniref50-residues.png --height 2160 --image uniref50-helix.png --imagecolour helix-propensity --width 800 --image uniref50-turn.png --imagecolour turn-propensity --width 800
    +  
    +

    + +

    ‑‑bgcolour

    + +

    + Only applies to ‑‑structureimage. Specify a background colour for a structure image. The colour can be specified as a named colour recognised by Java (e.g. "white", "cyan") or as a RRGGBB 6 digit hex string (e.g. ffffff, 00ffff). +

    +

    + E.g. +

    +  jalview --open examples/uniref50.fa --colour gecos-sunset --structure examples/AF-P00221-F1-model_v4.pdb --seqid FER1_SPIOL --structureimage temp.png  --bgcolour magenta
    +  
    +

    +

    Next we look at vector image formats, which maintain detail at all resolutions.

    -

    Vector image export

    +

    Vector image export (svg, eps, html, biojs)

    - Jalview can export an alignment in Encapsulated PostScript (eps), Scalable Vector Graphics (svg), HTML (html) or BioJSON -- another HTML format (biojs), by using, e.g. + Jalview can export an alignment in Encapsulated PostScript (eps), Scalable Vector Graphics (svg), HTML (html) or BioJSON -- another HTML format with an interactive MSA viewer (biojs), by using, e.g.

       jalview --open examples/uniref50.fa --colour gecos-flower --image printable.eps
       
    - The image format can be specified with the --type argument or as a sub-value modifier on the --image value. If neither is used the type will be guessed from the image file extension. The following three examples should produce the same contents: + The image format can be specified with the ‑‑type argument or as a sub-value modifier on the ‑‑image value. If neither is used the type will be guessed from the image file extension. The following three examples should produce the same contents:
       jalview --open examples/uniref50.fa --colour gecos-flower --image printable.eps
       jalview --open examples/uniref50.fa --colour gecos-flower --image printable.postscript --type eps
       jalview --open examples/uniref50.fa --colour gecos-flower --image [type=eps]printable.postscript
    +  jalview --open examples/uniref50.fa --colour gecos-flower --image [type=biojs]printable.html
       

    -

    --textrenderer

    +

    ‑‑textrenderer

    - In a vector format any text that appears on the page (including residue/base labels) can be saved in the image file either as text or as lineart using the --textrenderer argument. This is only available for eps, svg and html formats. + In a vector format any text that appears on the page (including residue/base labels) can be saved in the image file either as text or as lineart using the ‑‑textrenderer argument. This is only available for eps, svg and html formats.

    @@ -513,15 +583,34 @@

    - The type of --textrenderer can be specified with an argument following --image or as a sub-value modifier: + The type of ‑‑textrenderer can be specified with an argument following ‑‑image or as a sub-value modifier:

       jalview --open examples/uniref50.fa --colour gecos-flower --image printable.html --type biojs
       jalview --open examples/uniref50.fa --colour gecos-flower --image [type=eps,textrenderer=lineart]printable.ps
       

    +

    Output behaviour

    -

    Filename substitutions and batch processing (--substitutions, --close, --all)

    +

    ‑‑overwrite

    + +

    + By default, Jalview will refuse to overwrite an output file (alignment or image) unless backups are in operation (alignment files only). To force overwriting files, use the ‑‑overwrite argument. +

    + +

    ‑‑backups / --nobackups

    + +

    + Jalview should honour your preferences for backup files of output alignment files. Using ‑‑backups or ‑‑nobackups forces the behaviour. With no backups set, you will need to use ‑‑overwrite to overwrite an existing file. Note that Jalview does not make backup files of exported images. +

    + +

    ‑‑mkdirs

    + +

    + If you want to output a file into a folder that doesn't yet exist (this might happen particularly when using {dirname} substitutions -- see below), then Jalview will fail to write the file since the parent directory doesn't exist. You can use ‑‑mkdirs to tell Jalview to make the new directory (or directories, it will create several nested directories if necessary) before writing the file. ‑‑mkdirs is cautious and will generally refuse to make a new directory using a relative path with .. in. +

    + +

    Filename substitutions and batch processing (‑‑substitutions, ‑‑close, ‑‑all)

    One of the more powerful aspects of Jalview's command line operations is that stores all of the different opened alignment arguments (before opening them) and can apply some arguments to all of the alignments as they are opened. This includes display and output arguments. @@ -542,10 +631,19 @@

    + Specifically for ‑‑structureimage output, you can also use substitutions using parts of the structure filename: +

      +
    • {structuredirname} -- is replaced by the directory path to the opened structure file.
    • +
    • {structurebasename} -- is replaced by the base of the filename of the opened structure file. This is without the path or file extension (if there is one).
    • +
    • {structureextension} -- is replaced by the extension of the filename of the opened structure file.
    • +
    +

    + +

    These filename substitutions are on by default, but if for whatever reason you wish to disable the substitutions, they can be turned off (or back on again) through the list of arguments with:

    -

    --substitutions / --nosubstitutions

    +

    ‑‑substitutions / --nosubstitutions

    Enable (or disable) filename substitutions in the following argument values and sub-value modifier values. @@ -555,54 +653,54 @@

    - For opening single files this is less useful, since you could obviously just type the output filename, but for multiple opened alignments you can also use these substituted values and they will be replaced by the relevant part of the filename given for each opened alignment window. Normally an --output or --image argument will only be applied to the latest opened alignment window, but you can tell Jalview to apply some arguments to all alignments that have been opened (so far) by using the --all argument. + For opening single files this is less useful, since you could obviously just type the output filename, but for multiple opened alignments you can also use these substituted values and they will be replaced by the relevant part of the filename given for each opened alignment window. Normally an ‑‑output or ‑‑image argument will only be applied to the latest opened alignment window, but you can tell Jalview to apply some arguments to all alignments that have been opened (so far) by using the ‑‑all argument.

    -

    --all / -noall

    +

    ‑‑all / -noall

    - When using the --all argument, following arguments will apply to all of the previously opened alignment windows. You can turn this behaviour off again for following arguments using the --noall argument. The arguments that can apply to all previously opened alignments are: + When using the ‑‑all argument, following arguments will apply to all of the previously opened alignment windows. You can turn this behaviour off again for following arguments using the ‑‑noall argument. The arguments that can apply to all previously opened alignments are:
    - --colour + ‑‑colour
    - --sortbytree + ‑‑sortbytree
    - --showannotations + ‑‑showannotations
    - --wrap + ‑‑wrap
    - --nostructure + ‑‑nostructure
    - --notempfac + ‑‑notempfac
    - --showssannotations + ‑‑showssannotations
    - --image + ‑‑image
    - --type + ‑‑type
    - --textrenderer + ‑‑textrenderer
    - --scale + ‑‑scale
    - --width + ‑‑width
    - --height + ‑‑height
    - --output + ‑‑output
    - --format + ‑‑format
    - --groovy + ‑‑groovy
    - --backups + ‑‑backups
    - --overwrite + ‑‑overwrite
    - --close + ‑‑close

    - In particular, for our example above, we can use -all and --output like this (--close will be explained in a moment): + In particular, for our example above, we can use -all and ‑‑output like this (‑‑close will be explained in a moment):

       jalview --open all_my_fasta_files/*.fa --all --output all_my_converted_stockholm_files/{basename}.stk --close --headless
       
    @@ -619,23 +717,39 @@

    -

    --close

    +

    ‑‑close

    - The --close tag is used to close an alignment window after all output files or image exports are performed. This reduces memory use, especially if an --open value is set to open many files. These will be opened, formatted and output sequentially so since they are closed before the next one is opened memory use will not build up over a large number of alignments. + The ‑‑close tag is used to close an alignment window after all output files or image exports are performed. This reduces memory use, especially if an ‑‑open value is set to open many files. These will be opened, formatted and output sequentially so since they are closed before the next one is opened memory use will not build up over a large number of alignments.

       

    -

    The all output wildcard: --output "*.ext", --image "*.ext"

    +

    The all output wildcard: ‑‑output "*/*.ext", ‑‑image "*/*.ext"

    + +

    + Purely as an intuitive syntactic sweetener, you can use the ‑‑output wildcard * in two places as part of an output path and filename. +

    + +

    + Using an asterisk (*) as a filename before an extension, e.g. ‑‑image "tmp/*.png" will result in that asterisk being treated as a {basename} substitution. +

    + +

    + Using an asterisk (*) before a file separator (usually /), e.g. ‑‑image "tmp/*/file1.png" will result in that asterisk being treated as a {dirname} substitution. +

    + +

    + You can combine these, using an asterisk (*) before and after the last file separator, e.g. ‑‑image "tmp/*/*.png" will result in being substituted like tmp/{dirname}/{basename}.png. +

    - Purely as an intuitive syntactic sweetener, you can use the --output wildcard * at the beginning of the output filename as shorthand for --all --output {dirname}/{basename} followed by whatever you put after the '*'. For example, to achieve the same as the thumbnails example above, you could use + For example, to achieve the same as the thumbnails example above, you could use

    -  jalview --open */*.fa --image "*.png" --colour gecos-flower --width 256 --height 256 --close --headless
    +  jalview --open */*.fa --image "*/*.png" --colour gecos-flower --width 256 --height 256 --close --headless
       
    - Here we move the --colour argument after the --output argument (it will still be applied before the image export or file output) so that it is included after the implied --all argument. The thumbnails will be placed in the same directory as the alignment file with the same filename except for a different extension of .png. + Here we move the ‑‑colour argument after the ‑‑output argument (it will still be applied before the image export or file output) so that it is included after the implied ‑‑all argument. The thumbnails will be placed in the same directory as the alignment file with the same filename except for a different extension of .png.

    @@ -650,7 +764,7 @@

    - An alternative is to use an equals sign ('=') with no spaces between the argument and the value, --output=*.ext, which Jalview will interpret the same, but the shell will not automatically expand before it is sent to Jalview, e.g. + An alternative is to use an equals sign ('=') with no spaces between the argument and the value, ‑‑output=*.ext, which Jalview will interpret the same, but the shell will not automatically expand before it is sent to Jalview, e.g.

       jalview --open all_my_fasta_files/*.fa --output=*.stk --close --headless
       
    diff --git a/help/help/html/features/clarguments-reference.html b/help/help/html/features/clarguments-reference.html index dd0bd52..b1588e5 100644 --- a/help/help/html/features/clarguments-reference.html +++ b/help/help/html/features/clarguments-reference.html @@ -35,7 +35,6 @@
  • Processing alignments
  • Outputting alignment files
  • Exporting image files
  • -
  • Exporting 3D structure image files
  • Controlling flow of arguments
  • @@ -65,16 +64,16 @@ ‑‑help‑allHelp for all arguments - ‑‑headless / ‑‑noheadless - Run Jalview in headless (/ or not in headless) mode. In headless mode, no GUI interface will be created and Jalview will quit after all arguments have been processed. + ‑‑headless + Run Jalview in headless mode. In headless mode, no GUI interface will be created and Jalview will quit after all arguments have been processed.
    - If you use a command line argument to specify an output file of some kind (--output, --image or --structureimage) then headless mode will be assumed. If you don't want this behaviour use --noheadless or --gui. + If you use a command line argument to specify an output file of some kind (‑‑output, ‑‑image or ‑‑structureimage) then headless mode will be assumed. If you don't want this behaviour use ‑‑gui. ‑‑gui - Force Jalview to run in graphical mode. This can be used to counter the assumption of headless mode when an argument that creates an output file is used. --gui takes precedence over --headless. + Force Jalview to run in graphical mode. This can be used to counter the assumption of headless mode when an argument that creates an output file is used. ‑‑gui takes precedence over ‑‑headless. @@ -93,6 +92,11 @@ + ‑‑javaconsole / ‑‑nojavaconsole + Show (/ or don't show) the Java Console. Using one of these overrides any saved Preference. + + + ‑‑questionnaire / ‑‑noquestionnaire Show (/ or don't show) the questionnaire if one is available. @@ -521,6 +525,8 @@ phylip (phy),
    jalview (jvp, jar). +
    + To output directly to STDOUT (console output) use the filename - (a single hyphen). In this case all STDOUT messages will instead go to STDERR. If no format is supplied then Fasta will be assumed. format=name ✓ @@ -572,6 +578,16 @@ ✓ + + ‑‑mkdirs + Enable automatic creation of new directories and parent directories for filenames given, or created through substitutions, in ‑‑output, ‑‑image or ‑‑structureimage arguments. + + ✓ + + + + +Automatically create directories when outputting a file to a new directory @@ -600,18 +616,56 @@ biojs. - type=name, - textrenderer=name, - scale=number, - width=number, - height=number + + type=name, +
    + textrenderer=name, +
    + scale=number, +
    + width=number, +
    + height=number, +
    + imagecolour=name +
    + + ✓ + + + + ‑‑structureimage filename + Export an image of a 3D structure opened in JMOL (currently jmol only). Each ‑‑structureimage filename will output a file for each ‑‑structureimage that has been applied to the open alignment window. In this situation, to avoid overwriting the same file with each structure, additional substitutions {structuredirname}, {structurebasename} and {structureextname} are available being substituted with the directory path, file basename and file extension of each structure file. Image formats can be: +
    + svg, +
    + png, +
    + eps. + + + + type=name, +
    + textrenderer=name, +
    + scale=number, +
    + width=number, +
    + height=number, +
    + imagecolour=name +
    + bgcolour=name +
    ‑‑type name - Set the image format for the preceding ‑‑image to name. Valid values for name are: + Set the image format for the preceding ‑‑image or ‑‑structureimage to name. Valid values for name are:
    svg,
    @@ -629,7 +683,7 @@ ‑‑textrenderer name - Sets whether text in a vector image format (SVG, HTML, EPS) should be rendered as text or vector line-art. Valid values for name are: + Sets whether text in a vector image format (SVG, HTML, EPS) should be rendered as text or vector line-art. Applies to the preceding ‑‑image or ‑‑structureimage. Valid values for name are:
    text,
    @@ -641,7 +695,7 @@ ‑‑scale number - Sets a scaling for bitmap image format (PNG). Should be given as a floating point number. This can also be set as a sub-value modifier to the --image value. If used in conjunction with --width and --height then the smallest scaling will be used (scale, width and height provide bounds for the image). + Sets a scaling for bitmap image format (PNG). Should be given as a floating point number. Applies to the preceding ‑‑image or ‑‑structureimage. This can also be set as a sub-value modifier to the ‑‑image or ‑‑structureimage value. If used in conjunction with ‑‑width and ‑‑height then the smallest size will be used (scale, width and height provide bounds for the image). ✓ @@ -649,7 +703,7 @@ ‑‑width number - Sets a width for bitmap image format (PNG) with the height maintaining the aspect ratio. Should be given as a positive integer. This can also be set as a sub-value modifier to the --image value. If used in conjunction with --scale and --height then the smallest scaling will be used (scale, width and height provide bounds for the image). + Sets a width for bitmap image format (PNG) with the height maintaining the aspect ratio. Applies to the preceding ‑‑image or ‑‑structureimage. Should be given as a positive integer. This can also be set as a sub-value modifier to the ‑‑image or ‑‑structureimage value. If used in conjunction with ‑‑scale and ‑‑height then the smallest size will be used (scale, width and height provide bounds for the image). ✓ @@ -657,97 +711,21 @@ ‑‑height number - Sets a height for bitmap image format (PNG) with the width maintaining the aspect ratio. Should be given as a positive integer. This can also be set as a sub-value modifier to the --image value. If used in conjunction with --scale and --width then the smallest scaling will be used (scale, width and height provide bounds for the image). + Sets a height for bitmap image format (PNG) with the width maintaining the aspect ratio. Applies to the preceding ‑‑image or ‑‑structureimage. Should be given as a positive integer. This can also be set as a sub-value modifier to the ‑‑image or ‑‑structureimage value. If used in conjunction with ‑‑scale and ‑‑width then the smallest size will be used (scale, width and height provide bounds for the image). ✓ - ‑‑groovy filename - Process a groovy script in the file for the open alignment. + ‑‑bgcolour name + Only applies to structure images (opened with jmol structure viewer). Sets the background colour of the preceding ‑‑structureimage. name should be either a named colour (e.g. white, cyan) known to Jmol, or can be given as a six digit RGB hex string (e.g. ffffff, 00ffff). This can also be set as a sub-value modifier to the ‑‑structureimage value. ✓ - - - -

    Exporting 3D structure image files (jmol only)

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + @@ -768,24 +746,36 @@ @@ -815,7 +805,7 @@ diff --git a/help/help/html/features/clarguments.html b/help/help/html/features/clarguments.html index b763a81..6df40b5 100644 --- a/help/help/html/features/clarguments.html +++ b/help/help/html/features/clarguments.html @@ -44,7 +44,7 @@

    - These new arguments are all accessed with a --doubledash form of + These new arguments are all accessed with a ‑‑doubledash form of command line argument (with the one exception where simply opening one or more files can be performed without any arguments other than the filenames).

    @@ -60,7 +60,7 @@

    However, you cannot mix old and new style arguments, so if you use any -singledash arguments (with the exception of -help or -h), they will all be interpreted as - old style arguments with the new --doubledash + old style arguments with the new ‑‑doubledash arguments being ignored. If you have a script that uses the old arguments without any dashes, and uses the bare-word open then these will also be interpreted as old style arguments. @@ -97,52 +97,52 @@

  • For arguments that require a value, the value can be given after an equals-sign ('=') or a space (' ').
    - --arg value + ‑‑arg value
    - --arg=value + ‑‑arg=value
  • For arguments that can take multiple values (these will be filenames), the multiple filenames should appear after a space. If you use a filename wildcard you can put this after a space (which will be expanded by the shell unto multiple filenames before they reach Jalview), or you can put it after an equals-sign, which will be used by Jalview to find a list of files. You cannot use an equals-sign and value followed by further values.
    - --arg file1.fa otherfile.stk + ‑‑arg file1.fa otherfile.stk
    - --arg filename*.fa (filenames expanded by shell) + ‑‑arg filename*.fa (filenames expanded by shell)
    - --arg=filename*.fa (filenames expanded by Jalview) + ‑‑arg=filename*.fa (filenames expanded by Jalview)
  • For arguments that act as a switch, most can be negated by preceding the argument name with no.
    - --switch + ‑‑switch
    - --noswitch + ‑‑noswitch
  • - Some values can be modified, or may need additional information (for instance an --image output can be modified with a --scale=number factor, or a --structure can refer to a sequence with a --seqid=ID). This additional information can be added in a number of different ways. + Some values can be modified, or may need additional information (for instance an ‑‑image output can be modified with a ‑‑scale=number factor, or a ‑‑structure can refer to a sequence with a ‑‑seqid=ID). This additional information can be added in a number of different ways.
    • An argument immediately following the main argument.
      - --image output.png --scale 2.5 + ‑‑image output.png --scale 2.5
    • A sub-value modifier, which is where one or more (comma-separated) values are added to the start of the main value, placed in square brackets.
      - --open=[nowrap,colour=gecos-blossom]uniref50.fa + ‑‑open=[nowrap,colour=gecos-blossom]uniref50.fa
      Sub-value modifiers with a value must use an equals-sign separator, and those that act as a switch can simply be included without an equals-sign or value, and can be preceded with no to negate the value, as with the argument name.
    • Another argument with the same linked ID. A linked ID is an optional identifier for a particular open alignment, placed in square brackets immediately following the argument name (before the equals-sign or space). If linked IDs are specified they do not need to be near to each other.
      - --image[MYID]=output.png --other --args --scale[MYID]=2.5 + ‑‑image[MYID]=output.png --other --args --scale[MYID]=2.5
    • An argument that is designated as applying to all linked IDs
      - --image=output.png --other --args --all --scale=2.5 + ‑‑image=output.png --other --args --all --scale=2.5
      - --image=output.png --other --args --scale[*]=2.5 + ‑‑image=output.png --other --args --scale[*]=2.5
  • @@ -157,13 +157,13 @@

    Headless mode

    - Jalview can be run in headless mode, i.e. without the usual graphical user interface (GUI), by specifying the --headless argument. With command line arguments you can specify operations for Jalview to perform on one or more files and then stop running. Most likely you will want to output another file, either an alignment for image file. + Jalview can be run in headless mode, i.e. without the usual graphical user interface (GUI), by specifying the ‑‑headless argument. With command line arguments you can specify operations for Jalview to perform on one or more files and then stop running. Most likely you will want to output another file, either an alignment for image file.

    - If you specify an argument for an output file (one or more of --output, --image or --structureimage) then it will be assumed that you wish to run in headless mode. + If you specify an argument for an output file (one or more of ‑‑output, ‑‑image or ‑‑structureimage) then it will be assumed that you wish to run in headless mode.

    - You can force Jalview to run in graphical mode using the --gui or --noheadless arguments. + You can force Jalview to run in graphical mode using the ‑‑gui argument.

    diff --git a/help/help/html/features/groovy.html b/help/help/html/features/groovy.html index cb0b10c..6b5c4c0 100644 --- a/help/help/html/features/groovy.html +++ b/help/help/html/features/groovy.html @@ -20,11 +20,11 @@ * The Jalview Authors are detailed in the 'AUTHORS' file. --> -Groovy Shell +Groovy Console

    - The Groovy Shell + The Groovy Console

    Groovy (www.groovy-lang.org) @@ -41,8 +41,8 @@ short pause, you should then see the Groovy Console appear. This allows you to interactively execute Groovy - scripts whilst Jalview is running. We've also provided a Calculations→Execute - Groovy Script button so you can execute the currently loaded + scripts whilst Jalview is running. We've also provided a Calculations→Run + Groovy Console Script button so you can execute the currently loaded groovy script whilst viewing an alignment.

    @@ -63,31 +63,36 @@ we recommend you also take a look at Jalview's source, since all the public methods of the jalview class hierarchy can be called from Groovy scripts. In addition, the following objects are also defined: +

    - -
      -
    • Jalview - this is bound to jalview.bin.Jalview.
      Useful - methods include: +
    • Jalview - this is bound to jalview.bin.groovy.JalviewObject providing access to the following useful + methods:
      • Jalview.getAlignFrames() - returns a list of jalview.gui.AlignFrame objects
      • Jalview.getCurrentAlignFrame() - returns the alignment - window which is currently being looked at by the user
      • + window which has most recently been in focus. If you change focus to another alignment window then re-running Jalview.getCurrentAlignFrame() will return the new AlignFrame.
    • -
    • currentAlFrame - this is only defined when - running a Groovy script via the --groovy command line argument. It - returns the first alignment window created after acting on the - other arguments passed on the command line.
    • +
    • currentAlFrame When used on the command line this refers to the current opened alignment. +
      + When used from the Groovy Console, it refers to the alignment that was in focus when the Groovy Console was opened. +
      + When a Groovy Console script is run from Calculate->Run Groovy Console Script, currentAlFrame us updated to that alignment.

    + If you specify a --groovy argument before an --open argument + then you should ensure your script doesn't refer to currentAlFrame. +

    + +

    A simple script

    • Getting the title, alignment and first sequence from the current alignFrame
      -def alf = Jalview.getAlignFrames();
      -print alf[0].getTitle();
      -def alignment = alf[0].viewport.alignment;
      +def al = Jalview.getCurrentAlignFrame();
      +print al.getTitle();
      +def alignment = al.viewport.alignment;
       def seq = alignment.getSequenceAt(0);
       
    • diff --git a/help/help/html/features/jmol.html b/help/help/html/features/jmol.html index ac2489b..491a03f 100644 --- a/help/help/html/features/jmol.html +++ b/help/help/html/features/jmol.html @@ -160,7 +160,11 @@
    • Show Chains
      Select which of the PDB file's chains are to be displayed.
    • -
    • Colour by ..
      Submenu +
    • Ligands
      +
      When available, allows the display of all, none or specific + ligands (also known as HETATM groups) in the Jmol view, using CPK + spacefilling.
    • +
    • Colour by ..
      Submenu allowing specific alignment views to be selected for colouring associated chains in the structure display. This menu contains all the alignment views associated with the diff --git a/help/help/html/features/local-pdb-import.png b/help/help/html/features/local-pdb-import.png new file mode 100644 index 0000000..561a10f Binary files /dev/null and b/help/help/html/features/local-pdb-import.png differ diff --git a/help/help/html/features/paematrices.html b/help/help/html/features/paematrices.html new file mode 100644 index 0000000..2f00e19 --- /dev/null +++ b/help/help/html/features/paematrices.html @@ -0,0 +1,188 @@ + + + +Working with PAE Matrices in Jalview + + + +

      + Working with Predicted Alignment Error Matrices in + Jalview +

      + +

      Predicted Alignment Error (PAE) matrices are produced by + deep-learning based 3D-structure prediction pipelines such as + AlphaFold. They reflect how reliably two parts of a model have been + positioned in space, by giving for each residue the likely error (in + Ångstroms) between that residue and every other modelled + position the pair of residues' real relative position, if the model + and real 3D structure were superimposed at that residue.

      +

      + Jalview visualises PAE matrices as an alignment annotation track, + shaded from dark green to white, similar to the encoding used on the + EBI-AlphaFold website (see O04090 3D model + at EBI-AlphaFoldDB). +

      +
      +
      + +
      + Alignment of EPAS1 homologs from Human, Rat and Cow
      with + predicted alignment error shown for Human +
      +
      +
      + +
      + Predicted Alignment Error for Human EPAS1
      from https://alphafold.ebi.ac.uk/entry/Q99814 +
      +
      +
      +

      + Importing PAE Matrices +

      +

      + Jalview retrieves PAE matrices when importing predicted 3D structures + from the EBI-AlphaFold database via Jalview's structure + chooser GUI. If you have produced your own models and accompanying + PAE matrices using a pipeline such as ColabFold, then you can load + them both together via the Load PDB + File dropdown menu in the 3D structure chooser, providing it is in a + supported PAE format. +

      +

      + The Command Line + Interface also provides a options for importing PAE matrices along + side models, enabling the automated production of alignment figures + annotated with PAE matrices and PLDDT scores. +

      +

      + Showing PAE Matrix Annotations +

      +

      + When viewing 3D structures from the EBI-AlphaFold database or local 3D + structures with an associated PAE file, the PAE is imported as Reference + Annotation, which is not always automatically added to the alignment + view. +

      +

      To show the PAE, right click the sequence and locate the 'Add + Reference Annotation' entry in the Sequence ID submenu, or select all + sequences and locate the option in the Selection submenu. You can do + this in any alignment window (or view) where a sequence with + associated PAE data appears.

      +

      + Adjusting the height of PAE matrix annotations +

      +

      + PAE annotations behave in the same way as Jalview's line graph and + histogram tracks. Click+dragging up and down with the left (select) + mouse button held down will increase or decrease the height of the + annotation. You can also hold down SHIFT + whilst doing this to adjust the height of all PAE rows at once. +

      +

      PAE matrix annotation rows behave like any other sequence + associated annotation, with the following additional features:

      +
        +
      • The vertical axis of the PAE heatmap is mapped to positions + on the linked 3D structure. +
          +
        • Mousing over the matrix shows a tooltip giving information + on the range of values under the mouse.
          Positions in the + associated 3D structure are also highlighted in any linked views. +
        • +
        • Clicking on positions in the matrix selects columns of the + alignment corresponding to the row and column in the matrix.
        • +
        +
      • +
      • Rectangular selections (created by Cmd (or Alt)+Click + dragging on the matrix) can be created to select multiple ranges of + columns at once.
      • +
      • Columns corresponding to adjacent regions with similarly low + levels of predicted alignment error can be selected by Ctrl+Clicking + on a region in the matrix.
      • +
      • Columns of an alignment showing a PAE matrix can be grouped + and selected by clustering the matrix.
      • +
      +

      + Clustering PAE Matrices +

      +

      PAE matrices are useful for identifying regions of 3D structure + predictions that are likely to be positioned in space in the same or + similar way as shown in the predicted structure data. Regions of low + PAE often correlate with high alphafold reliability (PLDDT) scores, + but also complement them since they highlight well-folded regions such + as domains, and how well those regions have been predicted to be + positioned relative to eachother, which is important when evaluating + whether domain-domain interactions or other contacts can be trusted.

      +

      To make it more easy to identify regions of low PAE, Jalview can + cluster the PAE matrix, allowing columns of the matrix to be grouped + according to their similarity, using an Average Distance (UPGMA) tree + algorithm and the sum of differences between each column's PAE values.

      +

      + distij = ∥ pi-pj + ∥ +

      +

      + To create a PAE matrix tree, right click on a PAE annotation's label + to open the annotation popup menu, and select Cluster + Matrix. Once the calculation has finished, a tree viewer will open, + and columns of the matrix are then partitioned into groups such that + the third left-most node from the root is placed in its own group. + Colours are randomly assigned to each group, and by default these will + also be overlaid on the matrix annotation row. +

      +

        +
      • The PAE matrix tree viewer behaves like other tree views in + Jalview, except selecting nodes or groups of nodes in the tree select + columns in the alignment rather than sequences, and clicking adjust + the matrix's partition.
      • +
      • Only one tree and clustering can be defined for a PAE matrix, + regardless of whether it is displayed in different views or + alignments.
      • +
      • Double clicking on a position in the PAE annotation where a + clustering has been defined will select both the row and column + clusters for the clicked position. This makes it easy to select + clusters corresponding to pairs of interacting regions.
      • +
      • Cluster colours for a PAE matrix can be used to colour + sequences or columns of the alignment via the Colour by + Annotation.. dialog + (opened by right-clicking the annotation label + and selecting from the popup menu). +
      • +
      +

      + PAE matrices and Jalview Projects +

      +

      Any PAE matrices imported to Jalview are saved along side any + trees and clustering defined on them in Jalview Projects.

      +

      + Support for visualision and analysis of predicted alignment + error matrices was added in Jalview 2.11.3. +

      + + diff --git a/help/help/html/features/search.html b/help/help/html/features/search.html index d559db8..6889d84 100755 --- a/help/help/html/features/search.html +++ b/help/help/html/features/search.html @@ -36,7 +36,7 @@ td {

      The search box is displayed by pressing Control and F or selecting "Find..." from the "Search" menu.

      - +

      "Find next" will find the next occurrence of the query and adjust the alignment window view to show it, and "Find all" highlights all matches for a query. The @@ -46,18 +46,24 @@ td {

      • The search uses regular expressions. (understands a mixture of posix and perl style regex - see below for a summary)
      • -
      • Gaps are ignored when matching the query to the sequences - in the alignment.
      • -
      • Hidden columns can optionally be ignored (since Jalview 2.11)
      • -
      • The search is applied to both sequences and their IDs. It can - optionally also be applied to the description string (since Jalview - 2.10), and sequence feature descriptions (since Jalview 2.11.2.5). -
      • -
      • If a region is selected, then search will only +
      • If a region is selected, then search will only be performed on that region.
        Tip: to quickly clear the current selection, click the alignment view you wish to search, then press 'Escape'.
      • +
      • Gaps are ignored when matching the query to the sequences + in the alignment.
      • +
      • Hidden columns can optionally be ignored (since Jalview 2.11)
      • +
      • The search is applied to both sequences and their IDs.
        + Check boxes also enable searching of: +
          +
        • Sequence description (since Jalview 2.10) +
        • +
        • Sequence Feature type and description for currently displayed features (since Jalview + 2.11.3.0) +
        • +
        +
      • Tick the "Match Case" box to perform a case sensitive search.
      • To access a previously used @@ -87,9 +93,11 @@ td { Copying highlighted regions to a new alignment

        - You can copy the currently highlighted matching regions of sequences to the clipboard with alt-Command-C. + Press Copy button or type Ctrl (Cmd on OSX) + Shift + + C to copy highlighted search results to the clipboard, enabling them + to be pasted to a new alignment (via Shift+Ctrl (or Cmd) + V).

        -

        +

        A quick Regular Expression Guide

        diff --git a/help/help/html/features/search.png b/help/help/html/features/search.png index 47c18f4..9178b9a 100644 Binary files a/help/help/html/features/search.png and b/help/help/html/features/search.png differ diff --git a/help/help/html/features/structurechooser.html b/help/help/html/features/structurechooser.html index 2c77049..f91b1dd 100644 --- a/help/help/html/features/structurechooser.html +++ b/help/help/html/features/structurechooser.html @@ -176,21 +176,47 @@ style="width: 464px; height: 173px;">
        Manual selection/association of PDB files with Sequences

        -

        To manually associate PDB files with a sequence, select 'From - File', or 'Enter PDB Id' from the drop-down menu: -

        - -

        - The Structure Chooser interface was introduced in Jalview - 2.9. -

        +

        + Manual Association of PDBe accessions with sequences +

        +

        If for some reason the PDBe and 3D beacons search fail to + automatically the PDB structure or model you wish to import, you can + select 'Enter PDB Id' from the drop-down menu to manually specify PDB + identifiers for one or more selected sequences. The PDB Rest API, + provided by EMBL-EBI, is used to validate accessions exist, and fetch + structure data.

        +

        + Import structure models + and metadata from file +

        +

        + Selecting the From File option from the drop down + menu allows 3D structure data to be imported from your own computer. + PDB or mmCIF files associated in this way are also saved in Jalview Projects.

        + The 'From File' dialog provides a drop down menu which allows you to + specify how the Temperature Factor metadata for each residue in the 3D + structure data file is interpreted: + +

          +
        • Default - Jalview will try to automatically determine whether + to show as 'Temperature Factor', 'AlphaFold Reliability' or 'Model + Quality'
        • +
        • PLDDT - Model has PLDDT scores in the temperature factor + column.
        • +
        +

        + An additional Predicted Alignment Error file can also be + provided when importing 3D structure data. Jalview supports import of + PAE Matrices provided as AlphaFold + format JSON files - which are also produced by ColabFold. See Working with PAE Matrices for details on + what Jalview allows you to do with associated PAE matrix data. +

        +

        + The Structure Chooser interface was introduced in Jalview + 2.9. +

        diff --git a/help/help/html/features/viewingpdbs.html b/help/help/html/features/viewingpdbs.html index 947b96b..df76f89 100755 --- a/help/help/html/features/viewingpdbs.html +++ b/help/help/html/features/viewingpdbs.html @@ -87,7 +87,7 @@ Structure Viewers in the Jalview Desktop
        The Jmol viewer has been included since Jalview 2.3. Jalview 2.8.2 included support for Chimera, - provided it is installed and can be launched by Jalview. ChimeraX and PyMOL + provided it is installed and can be launched by Jalview. ChimeraX and PyMOL support is included from Jalview 2.11.2. The default viewer can be configured in the Structure tab in the Tools→Preferences dialog box. @@ -114,19 +114,23 @@ un-tick the Superpose Structures checkbox.

        -

        - Superposing structures
        Jalview superposes structures using - the visible portions of any associated sequence alignments. A - message in the structure viewer's status bar will be shown if not - enough aligned columns were available to perform a superposition. -

        -

        - See the Jmol - and Chimera help pages for - more information about their capabilities.

        - - -

        +

        + Superposing structures
        Jalview superposes structures + using the currently selected columns (if more than 3 columns are + selected), or the visible portions of any associated sequence + alignments. Depending on the viewer, Root Mean Squared Deviation (RMS + or RMSD) for each pair of superpositions may be output in the + structure viewer's console. +

        +

        A message in the structure viewer's status bar will be shown if + not enough aligned columns were available to perform a superposition. +

        +

        + See the Jmol, Chimera/X + and Pymol help pages for more information + about their individual capabilities. +

        +

        Retrieving sequences from the PDB
        You can retrieve sequences from the PDB using the Sequence Fetcher. The sequences diff --git a/help/help/html/features/xsspannotation.html b/help/help/html/features/xsspannotation.html index 870b005..5f33dfe 100644 --- a/help/help/html/features/xsspannotation.html +++ b/help/help/html/features/xsspannotation.html @@ -29,8 +29,9 @@

        Jalview can process PDB data associated with sequences to display values extracted from the Temperature Factor column for - corresponding sites, and secondary structure from DSSP or RNAView - (as appropriate). + corresponding sites, and secondary structure from DSSP. For computationally determined structures, jalview will show + model quality data encoded in the temperature factor column as AlphaFold Reliability (PLDDT) or Model + Quality as appropriate.

        Extracting data from PDB files
        Annotation is @@ -43,20 +44,21 @@ the Add Reference Annotation in the Selection and Sequence ID sub-menus of the Sequence ID Panel's popup menu.
        Please note:Protein structures - are analysed in situ, but Jalview employs a web service to - process RNA structures which can cause long delays if your internet - connection is slow. + are analysed in situ.

        The Annotations alignment menu provides settings useful for controlling the - display of secondary structure annotation. -

        + display of sequence-associated annotation. To compare several tracks from different structures for one or more + sequences, use 'sort by label' - which will also display PDB and Chain IDs for secondary structure and temperature + factor/quality annotation tracks for easier identification. +

        Shading sequences by associated structure annotation
        The annotation colouring dialog (opened by the Colour→By - Annotation option) allows sequences with associated secondary + Annotation option) or by right-clicking a particular annotation tracks's label allows sequences with + associated secondary structure data to be shaded according to secondary structure type. Once the dialog is opened, select the Per Sequence option and then choose Secondary structure from the dropdown menu.
        When diff --git a/help/help/html/groovy/featuresCounter.html b/help/help/html/groovy/featuresCounter.html index bd7144e..494dd3e 100644 --- a/help/help/html/groovy/featuresCounter.html +++ b/help/help/html/groovy/featuresCounter.html @@ -36,7 +36,7 @@

      • Copy and paste it into the groovy script console
      • Load the example Feredoxin project (the one that opens by default when you first launched Jalview)
      • -
      • Select Calculations→Execute Groovy +
      • Select Calculations→Run Groovy Console Script from the alignment window's menu bar to run the script on the current view.
      • diff --git a/help/help/html/io/export.html b/help/help/html/io/export.html index 04216da..c940373 100755 --- a/help/help/html/io/export.html +++ b/help/help/html/io/export.html @@ -50,8 +50,28 @@
      -

      + PNG Export Options + +

      + Since Jalview 2.11.3 it is possible to specify options when exporting + figures via the command line to increase the resolution of the + exported PNG, and configure maximum width and height settings. + +

      You can also configure default export settings by adding the + following lines to + +

      .jalview_properties
      +
      BITMAP_SCALE=<Scale factor multiplied by 10>
      +  BITMAP_WIDTH=Width of export in pixels
      +  BITMAP_HEIGHT=Height of figure export in pixels
      +  
      + When scale is not set, the figure will be scaled to fit in the smallest + specified dimension. Scale will be ignored if it results in an image + dimension greater than the smallest specified dimension. +

      +

      Exporting alignments as Web Pages

      In Jalview 2.9, new HTML exporting options were introduced. The diff --git a/help/help/html/io/paematrixformat.html b/help/help/html/io/paematrixformat.html new file mode 100644 index 0000000..9cf57d9 --- /dev/null +++ b/help/help/html/io/paematrixformat.html @@ -0,0 +1,71 @@ + + + +Supported Formats for Predicted Alignment Error Matrices + + + +

      + Supported Formats for Predicted Alignment Error + Matrices +

      +

      + Predicted Alignment Error matrices are square matrices produced as + part of deep-learning based 3D-structure prediction pipelines such as + AlphaFold. They can be imported via Jalview's structure + chooser GUI and the Command + Line Interface. See Working + with PAE Matrices for information on how they are visualised and + analysed in Jalview. +

      +

      + Supported Formats +

      +

      Jalview supports import of PAE matrix data as provided by the + EBI-AlphaFold database. This resource provides PAE matrices as a JSON + files structured in one of the following ways:

      +
      +	# Version 1 format PAE file - deprecated 28th July 2022
      +	{
      +		residue1:[1,1,... total number of residues]
      +		residue2:[1,2,... total number of residues]
      +		distance:[0.1,0.3,... list of PAE matrix elements as doubles]
      +	}
      +  
      +
      +  	# Version 2 format PAE file - see https://alphafold.ebi.ac.uk/faq
      +  	{
      +  		max_predicted_alignment_error: 4.0, # may also be max_pae
      +  		predicted_alignment_error: [[1,2,0,0,3,...],...] # may also be pae
      +  	}
      +  
      +

      + Variants of the version 2 format include using 'pae' instead of + 'predicted_alignment_error' in the names of keys. Jalview copes both.
      + Once imported, Jalview stores PAE matrices as float arrays along with + any associated tree and partition set resultant from clustering the + matrix.

      PAE Matrix import support was added in Jalview 2.11.3 + +

      + + diff --git a/help/help/html/menus/alwannotationpanel.html b/help/help/html/menus/alwannotationpanel.html index cd09693..ff53d0b 100755 --- a/help/help/html/menus/alwannotationpanel.html +++ b/help/help/html/menus/alwannotationpanel.html @@ -86,6 +86,7 @@ highly variable regions.
    • +
    • Copy Consensus Sequence
      Copies the consensus sequence to the clipboard in Fasta format, to allow the consensus sequence to be added to an diff --git a/help/help/html/structures/epas1_annotdetail.png b/help/help/html/structures/epas1_annotdetail.png new file mode 100644 index 0000000..45118a0 Binary files /dev/null and b/help/help/html/structures/epas1_annotdetail.png differ diff --git a/help/help/html/structures/epas1_pae_ebiaf.png b/help/help/html/structures/epas1_pae_ebiaf.png new file mode 100644 index 0000000..b7b4bf6 Binary files /dev/null and b/help/help/html/structures/epas1_pae_ebiaf.png differ diff --git a/help/help/icons/jalview_docs_logo.png b/help/help/icons/jalview_docs_logo.png new file mode 100644 index 0000000..21f5386 Binary files /dev/null and b/help/help/icons/jalview_docs_logo.png differ diff --git a/help/markdown/releases/release-2_11_3_0.md b/help/markdown/releases/release-2_11_3_0.md index a433bc6..e527792 100644 --- a/help/markdown/releases/release-2_11_3_0.md +++ b/help/markdown/releases/release-2_11_3_0.md @@ -1,86 +1,79 @@ --- version: 2.11.3.0 -date: 2023-07-19 +date: 2023-11-03 channel: "release" --- ## New Features - Native M1 build for macOS using Adoptium JRE 11 macos-aarch64 -- Installers built with install4j10 -- Allow log level configuration via Jalview's Java Console, and a Copy to Clipboard button -- FlatLAF default look and feel on Linux, OSX and everywhere else ? - +- Jalview now uses a standard 'look and feel' (FlatLaf) on Linux, OSX and everywhere else - Ambiguous Base Colourscheme - Find can search sequence features' type and description - Hold down Shift + CMD/CTRL C to copy highlighted regions as new sequences -- Quickly enable select and/or colour by for displayed annotation row via its popup menu +- Quickly enable select and/or colour by for displayed annotation row via annotation panel popup menu - Shift+Click+Drag to adjust height of all annotation tracks of same type - Pressing escape in tree panel clears any current selection - - Use selected columns for superposition - Highlight aligned positions on all associated structures when mousing over a column - - sequence descriptions are updated from database reference sources if not already defined +- Visible adjuster marks to grab and adjust annotation panel height and id width +- Adjustable ID margin when alignment is wrapped +- Command line options and configurable bitmap export (via preferences file) for height, width and scale factor +- Show or hide ligands in a Jmol structure view via View Ligands submenu +- Jmol's display is antialiased by default (smoother, less pixellated) - -### Improved support for working with computationally determined models - +### Improved support for working with structures and computationally determined models - Alphafold red/orange/yellow/green colourscheme for structures - Interactive picking of low pAE score regions -- contact matrix datatype in Jalview +- Predicted Alignment Error annotation tracks for structures from AlphaFold DB - Selections with visual feedback via contact matrix annotation - - Discover and import alphafold2 models and metadata from https://alphafold.ebi.ac.uk/ - - Visual indication of relationship with associated sequence to distinguish different sequence associated annotation rows - GUI and command line allows configuration of how temperature factor in imported 3D structure data should be interpreted - Import model reliability scores encoded as temperature factor annotation with their correct name and semantics - Import and display alphafold alignment uncertainty matrices from JSON - Column-wise alignment groups and selections and interactive tree viewer for PAE matrices - Store/Restore PAE data and visualisation settings from Jalview Project +- Store and restore adjustable ID margin and annotation panel height in Jalview projects - Multiple residue sidechain highlighting in structure viewers from PAE mouseovers +- Per-structure and chain shown when annotation shown sorted by label enabling secondary structure and temperature factor scores from different chains and structures for the same sequence to be visually compared. ### Jalview on the command line - -- New command line argument framework allowing flexible batch processing, figure generation, and import of structures, pae matrices and other sequence associated data +- New command line argument framework allowing flexible batch processing, import of structures, pae matrices and other sequence associated data, and alignment and structure figure generation. +- Command-line wrapper script for macOS bundle, linux and Windows installations (bash, powershell and .bat wrappers) - Assume --headless when jalview is run with a command line argument that generates output +- Automatically adjust Left margin on import to avoid cropping of annotation labels & sequence IDs +- Specify alignment title on import via --title argument +- sensible responses from the CLI when things go wrong during image export +- Add a command line option to set Jalview properties for this session only +- Add a command line option to suppress opening the startup file for this session ### Other improvements - - - Secondary structure annotation glyphs are rendered anti-aliasing when enabled - Helix and Sheet glyphs vertically centered with respect to grey coil secondary structure annotation track -- Lower line of the sequence group border does not align with vertical and background residue box +- feature should be displayed when its rendering and filtering settings are adjusted - Updated JFreeSVG (https://www.jfree.org/jfreesvg) from 2.1 to 3.4.3 - Name of alignment and view included in overview window's title - "add reference annotation" add all positions in reference annotation tracks, not just positions in the currently highlighted columns/selection range - EMBL-EBI SIFTS file downloads now use split directories - -- sensible responses from the CLI when things go wrong during image export -Add a command line option to set Jalview properties for this session only -Add a command line option to suppress opening the startup file for this session - - -JAL-4187 Powershell launcher script fails when given no arguments with the old ArgsParser - -known issue ? 'Reload' for a jalview project results in all windows being duplicated - - -- Command-line wrapper script for macOS bundle, linux and Windows installations (bash, powershell and .bat wrappers) - In Linux desktops' task-managers, the grouped Jalview windows get a generic name - -## Still in progress (delete on release) - -- Import and display sequence-associated contact predictions in CASP-RR format -- Contact prediction visualisation -- modularise annotation renderer +- Improved file chooser's 'recent files' view and added filter for 'All known alignment files' +- Relative files added to recent files list via import from command line are selected when Jalview opened from same location +- Reduce number of database crossreferences shown in tooltip +- Drag and drop feature colours file on an alignment to quickly apply feature settings +- Allow log level configuration via Jalview's Java Console, and a Copy to Clipboard button +- Upgrade bundled groovy to v4.0.15 and regularised interface for groovy scripts run from CLI, interactively and headlessly. ### Development and Deployment - +- Installers built with install4j10 - Create separate gradle test task for some tests +- Prevent gradle test on macOS continuously grabbing focus - Allow gradle build to create suffixed DEVELOP-... builds with channel appbase +- Update .jvl generation in build.gradle for jalview branch builds - Jalview bio.tools description maintained under jalview's git repo and bundled with source 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 @@ -96,17 +89,36 @@ known issue ? 'Reload' for a jalview project results in all wi - 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 - Can press 'Add' or 'New View' multiple times when manually adding and viewing a 3D structure via structure chooser +- 3D beacons sources providing models scored with PLDDT and pTM not sorted against alphaFoldDB models - Jalview project does not preserve font aspect ratio when Viewport is zoomed with mouse +- Lower line of the sequence group border does not align with vertical and background residue box - Resizing overview quickly with solid-drags enabled causes exception - Sequences copied to clipboard from within Jalview cannot be pasted via the desktop's popup menu to a new alignment window - Overview window is saved in project file, and state of 'show hidden regions' is preserved. - JvCacheableInputBoxTest flaky on build server +- SLF4J produces an error to STDERR at Jalview startup due to missing class +- macOS Dock and KDE taskbar names Jalview icon "java" when running +- HeadlessException in console in headless mode (actually fixed in 2.11.{0,1,2)) +- Groovy console does not open when Jalview launched from jalview's Java 11 executable jar (available via conda) for recent versions of groovy +- Don't offer View model page for sources that do not have model pages +- Java Console opening at startup with the exampleFile_v2_7.jvp opening (nearly always) causes Jalview to hang +- automatic positioning of ID width for imported project can fail for certain font size configured in User preferences (affects most versions of Jalview prior to 2.11.3.0) +- RNAML import missing terminal residue +- Jalview source distribution unnecessarily includes dist directory with built jalview jar and dependencies ## New Known defects +- 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. - 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 +- 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 +- Files opened via command line with a relative path are added as relative paths to Recent files list (since 2.0.x) +- 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 diff --git a/help/markdown/whatsnew/whatsnew-2_11_3_0.md b/help/markdown/whatsnew/whatsnew-2_11_3_0.md index ec82f83f..b6c1b0d 100644 --- a/help/markdown/whatsnew/whatsnew-2_11_3_0.md +++ b/help/markdown/whatsnew/whatsnew-2_11_3_0.md @@ -1,7 +1,24 @@ -The 2.11.3 series includes support for in-depth exploration of predicted alignment error matrices from AlphaFold in the context of multiple alignments, along with support for standard colourschemes for shading models according to their pLDDT. +The 2.11.3 Jalview release features a new and more powerful command line interface, support for in-depth exploration of predicted alignment error (PAE) matrices from AlphaFold in the context of multiple alignments, AlphaFold's standard Blue-Orange-Red confidence colourscheme, and a host of [minor improvements and bug fixes](releases.html#Jalview.2.11.3.0) -We're launching this release at ISMB 2023 - come find us ! +**Interactive exploration of AlphaFold Predicted Alignment Error Matrices** -It also introduces new support for native ARM-based OSX architectures, and a few other goodies! +Predicted alignment error (PAE) matrices are JSON files produced by AlphaFold and other 3D structure prediction tools, which reflect how well any two positions in a predicted structure are positioned correctly relative to each other. Jalview automatically imports PAE matrices when retrieving protein structures from the EBI-AlphaFold database. A PAE matrix file can also be provided when manually importing 3D structure data. +Once imported, PAE matrices are shown in annotation tracks as a heat map shaded pale to dark green, where darker shades indicate higher confidence in relative positioning. Right-clicking a PAE Matrix's annotation label provides the option to cluster the columns of the matrix, producing a tree where regions of well arranged structure are grouped together, allowing columns containing those regions to be selected and manipulated further. + +**Jalview's Next Generation Command Line Interface** + +Jalview 2's original command line interface (CLI) allowed alignments to be imported, annotated and overlaid with sequence features, coloured, associated with trees, and exported either as figures (EPS, PNG, SVG, HTML SVG or an interactive BioJS page) or with one of Jalview's supported alignment export file formats. The new command line interface provides all this, as well as a range of additional functionality previously only available via the GUI: + + * 3D structures can be associated with sequences in alignments and shown in Jmol or external viewers + * Secondary structure, Model Reliability and Temperature factor can be shown and used to colour alignments + * PAE Matrices can be imported and shown as annotation + * 3D structure data shown in Jmol can be exported as PNG + * Scale factors and dimensions can be specified, allowing high resolution image exports + +In addition to these new functionality, next generation CLI operations can be applied to a range of files and directories through the use of wild-cards. This allows faster and more efficient processing of large numbers of alignments. It also facilitates modularisation of operations through the use of ['command-line argument files'](features/clarguments-argfiles.html). + +All new CLI parameters are preceded by '--', as opposed to an optional single '-' which was used in Jalview's old CLI. Old style arguments can still be used, so existing scripts will still work as before, but old-style operations cannot be mixed with new operations in the same CLI call. Use of old command line operations will also raise a warning, and we plan to completely remove support in Jalview's next major release (2.12). + +As usual, please let us via [Jalview's Discussion forum](https://discourse.jalview.org) of any issues you encounter using the new CLI, and of course any requests for improvement or new functionality ! diff --git a/help/templates/whatsNew.html b/help/templates/whatsNew.html index 70deea4..301ea4b 100755 --- a/help/templates/whatsNew.html +++ b/help/templates/whatsNew.html @@ -27,69 +27,5 @@ Welcome to Jalview Version __VERSION__ (released __DISPLAY_DATE__)!!

      __WHATS_NEW__ -

      - The 2.11.2 release series provides support for two popular 3D - structure visualisation tools, new features for discovery of 3D - structures, improved platform integration and a new command line - tool allowing Jalview to be more easily called from scripts.

      - -

      - View predicted protein structures via 3D-Beacons
      - Jalview 2.11.2's Structure - Chooser includes a client for the 3D-Beacons Network. Launched in - 2021, the 3D-Beacons network (www.ebi.ac.uk/pdbe/pdbe-kb/3dbeacons/) - provides a central point for the retrieval of predicted and observed - 3D structures for sequences in Uniprot, including homology models - from Swiss-model and deep learning based predictions from the EBI's - Alphafold database (Orengo et al. 2020, doi:10.12688/f1000research.20559.1).
      -

      - -

      - Support for viewing structures with ChimeraX and - Pymol
      Jalview's 3D structure viewer system has been - re-architected to allow easier integration of external structure - viewers, and takes advantage of the strucViz2 Chimera communications - library developed by Scooter Morris (doi:10.1093/bioinformatics/btm329).

      - The Structures - Preferences tab provides new options allowing ChimeraX and - Pymol to be used for visualising external 3D structures. Views - from all structure viewers are saved in Jalview Projects, allowing - them to be shared with others using Jalview 2.11.2 or later, - providing they have the same viewer installed and configured to be - used with Jalview.

      Jalview - 2.11.2 has been tested with Pymol 2.5.0 (community) and 2.5.2 - (incentive). For ChimeraX, we recommend using v1.3 or later. -

      -

      Other highlights include:

      - - - -

      - For the full details, see the Jalview 2.11.2 series - release notes. -

      -

      - Known Issues
      The following known issues will - be addressed in a minor patch release. - -

        -
      • Display of RESNUM sequence features are not suppressed when - structures associated with a sequence are viewed with an external - viewer (Regression from 2.11.1 series)
      • -
      -

      diff --git a/j11lib/flatlaf-3.0.jar b/j11lib/flatlaf-3.0.jar deleted file mode 100644 index 75d90d3..0000000 Binary files a/j11lib/flatlaf-3.0.jar and /dev/null differ diff --git a/j11lib/flatlaf-3.1.1.jar b/j11lib/flatlaf-3.1.1.jar deleted file mode 100644 index 2b13cdd..0000000 Binary files a/j11lib/flatlaf-3.1.1.jar and /dev/null differ diff --git a/j11lib/flatlaf-3.2.jar b/j11lib/flatlaf-3.2.jar new file mode 100644 index 0000000..450c1e8 Binary files /dev/null and b/j11lib/flatlaf-3.2.jar differ diff --git a/j11lib/flatlaf-extras-3.0.jar b/j11lib/flatlaf-extras-3.0.jar deleted file mode 100644 index 1f6bbc3..0000000 Binary files a/j11lib/flatlaf-extras-3.0.jar and /dev/null differ diff --git a/j8lib/flatlaf-extras-3.1.1.jar b/j11lib/flatlaf-extras-3.2.jar similarity index 52% rename from j8lib/flatlaf-extras-3.1.1.jar rename to j11lib/flatlaf-extras-3.2.jar index 9d91bd0..ccdbf94 100644 Binary files a/j8lib/flatlaf-extras-3.1.1.jar and b/j11lib/flatlaf-extras-3.2.jar differ diff --git a/j11lib/getdown-core.jar b/j11lib/getdown-core.jar index 7c99c93..3fc97b5 100644 Binary files a/j11lib/getdown-core.jar and b/j11lib/getdown-core.jar differ diff --git a/j11lib/groovy-4.0.15.jar b/j11lib/groovy-4.0.15.jar new file mode 100644 index 0000000..8423d99 Binary files /dev/null and b/j11lib/groovy-4.0.15.jar differ diff --git a/j11lib/groovy-all-2.4.21-indy.jar b/j11lib/groovy-all-2.4.21-indy.jar deleted file mode 100644 index 15ee98d..0000000 Binary files a/j11lib/groovy-all-2.4.21-indy.jar and /dev/null differ diff --git a/j11lib/groovy-ant-4.0.15.jar b/j11lib/groovy-ant-4.0.15.jar new file mode 100644 index 0000000..b6a39ac Binary files /dev/null and b/j11lib/groovy-ant-4.0.15.jar differ diff --git a/j11lib/groovy-astbuilder-4.0.15.jar b/j11lib/groovy-astbuilder-4.0.15.jar new file mode 100644 index 0000000..f341fac Binary files /dev/null and b/j11lib/groovy-astbuilder-4.0.15.jar differ diff --git a/j11lib/groovy-cli-commons-4.0.15.jar b/j11lib/groovy-cli-commons-4.0.15.jar new file mode 100644 index 0000000..b482258 Binary files /dev/null and b/j11lib/groovy-cli-commons-4.0.15.jar differ diff --git a/j11lib/groovy-cli-picocli-4.0.15.jar b/j11lib/groovy-cli-picocli-4.0.15.jar new file mode 100644 index 0000000..3223ba9 Binary files /dev/null and b/j11lib/groovy-cli-picocli-4.0.15.jar differ diff --git a/j11lib/groovy-console-4.0.15.jar b/j11lib/groovy-console-4.0.15.jar new file mode 100644 index 0000000..04a402a Binary files /dev/null and b/j11lib/groovy-console-4.0.15.jar differ diff --git a/j11lib/groovy-contracts-4.0.15.jar b/j11lib/groovy-contracts-4.0.15.jar new file mode 100644 index 0000000..6825657 Binary files /dev/null and b/j11lib/groovy-contracts-4.0.15.jar differ diff --git a/j11lib/groovy-datetime-4.0.15.jar b/j11lib/groovy-datetime-4.0.15.jar new file mode 100644 index 0000000..312575a Binary files /dev/null and b/j11lib/groovy-datetime-4.0.15.jar differ diff --git a/j11lib/groovy-dateutil-4.0.15.jar b/j11lib/groovy-dateutil-4.0.15.jar new file mode 100644 index 0000000..5893f97 Binary files /dev/null and b/j11lib/groovy-dateutil-4.0.15.jar differ diff --git a/j11lib/groovy-docgenerator-4.0.15.jar b/j11lib/groovy-docgenerator-4.0.15.jar new file mode 100644 index 0000000..bf76564 Binary files /dev/null and b/j11lib/groovy-docgenerator-4.0.15.jar differ diff --git a/j11lib/groovy-ginq-4.0.15.jar b/j11lib/groovy-ginq-4.0.15.jar new file mode 100644 index 0000000..46f561e Binary files /dev/null and b/j11lib/groovy-ginq-4.0.15.jar differ diff --git a/j11lib/groovy-groovydoc-4.0.15.jar b/j11lib/groovy-groovydoc-4.0.15.jar new file mode 100644 index 0000000..b818919 Binary files /dev/null and b/j11lib/groovy-groovydoc-4.0.15.jar differ diff --git a/j11lib/groovy-groovysh-4.0.15.jar b/j11lib/groovy-groovysh-4.0.15.jar new file mode 100644 index 0000000..253eff6 Binary files /dev/null and b/j11lib/groovy-groovysh-4.0.15.jar differ diff --git a/j11lib/groovy-jmx-4.0.15.jar b/j11lib/groovy-jmx-4.0.15.jar new file mode 100644 index 0000000..8667ac4 Binary files /dev/null and b/j11lib/groovy-jmx-4.0.15.jar differ diff --git a/j11lib/groovy-json-4.0.15.jar b/j11lib/groovy-json-4.0.15.jar new file mode 100644 index 0000000..76b486a Binary files /dev/null and b/j11lib/groovy-json-4.0.15.jar differ diff --git a/j11lib/groovy-jsr223-4.0.15.jar b/j11lib/groovy-jsr223-4.0.15.jar new file mode 100644 index 0000000..5ae9f69 Binary files /dev/null and b/j11lib/groovy-jsr223-4.0.15.jar differ diff --git a/j11lib/groovy-macro-4.0.15.jar b/j11lib/groovy-macro-4.0.15.jar new file mode 100644 index 0000000..e5f7abb Binary files /dev/null and b/j11lib/groovy-macro-4.0.15.jar differ diff --git a/j11lib/groovy-macro-library-4.0.15.jar b/j11lib/groovy-macro-library-4.0.15.jar new file mode 100644 index 0000000..92c208f Binary files /dev/null and b/j11lib/groovy-macro-library-4.0.15.jar differ diff --git a/j11lib/groovy-nio-4.0.15.jar b/j11lib/groovy-nio-4.0.15.jar new file mode 100644 index 0000000..e6e2ad8 Binary files /dev/null and b/j11lib/groovy-nio-4.0.15.jar differ diff --git a/j11lib/groovy-servlet-4.0.15.jar b/j11lib/groovy-servlet-4.0.15.jar new file mode 100644 index 0000000..711a1e2 Binary files /dev/null and b/j11lib/groovy-servlet-4.0.15.jar differ diff --git a/j11lib/groovy-sql-4.0.15.jar b/j11lib/groovy-sql-4.0.15.jar new file mode 100644 index 0000000..058db44 Binary files /dev/null and b/j11lib/groovy-sql-4.0.15.jar differ diff --git a/j11lib/groovy-swing-4.0.15.jar b/j11lib/groovy-swing-4.0.15.jar new file mode 100644 index 0000000..848d074 Binary files /dev/null and b/j11lib/groovy-swing-4.0.15.jar differ diff --git a/j11lib/groovy-templates-4.0.15.jar b/j11lib/groovy-templates-4.0.15.jar new file mode 100644 index 0000000..3cd0245 Binary files /dev/null and b/j11lib/groovy-templates-4.0.15.jar differ diff --git a/j11lib/groovy-test-4.0.15.jar b/j11lib/groovy-test-4.0.15.jar new file mode 100644 index 0000000..e600dc7 Binary files /dev/null and b/j11lib/groovy-test-4.0.15.jar differ diff --git a/j11lib/groovy-test-junit5-4.0.15.jar b/j11lib/groovy-test-junit5-4.0.15.jar new file mode 100644 index 0000000..abcc69a Binary files /dev/null and b/j11lib/groovy-test-junit5-4.0.15.jar differ diff --git a/j11lib/groovy-testng-4.0.15.jar b/j11lib/groovy-testng-4.0.15.jar new file mode 100644 index 0000000..60c1b58 Binary files /dev/null and b/j11lib/groovy-testng-4.0.15.jar differ diff --git a/j11lib/groovy-toml-4.0.15.jar b/j11lib/groovy-toml-4.0.15.jar new file mode 100644 index 0000000..ad49634 Binary files /dev/null and b/j11lib/groovy-toml-4.0.15.jar differ diff --git a/j11lib/groovy-typecheckers-4.0.15.jar b/j11lib/groovy-typecheckers-4.0.15.jar new file mode 100644 index 0000000..dc113c3 Binary files /dev/null and b/j11lib/groovy-typecheckers-4.0.15.jar differ diff --git a/j11lib/groovy-xml-4.0.15.jar b/j11lib/groovy-xml-4.0.15.jar new file mode 100644 index 0000000..21aeea0 Binary files /dev/null and b/j11lib/groovy-xml-4.0.15.jar differ diff --git a/j11lib/groovy-yaml-4.0.15.jar b/j11lib/groovy-yaml-4.0.15.jar new file mode 100644 index 0000000..207d47d Binary files /dev/null and b/j11lib/groovy-yaml-4.0.15.jar differ diff --git a/j11lib/javaparser-core-3.25.5.jar b/j11lib/javaparser-core-3.25.5.jar new file mode 100644 index 0000000..92eed53 Binary files /dev/null and b/j11lib/javaparser-core-3.25.5.jar differ diff --git a/j11lib/slf4j-api-1.7.32.jar b/j11lib/slf4j-api-1.7.32.jar deleted file mode 100644 index b16a078..0000000 Binary files a/j11lib/slf4j-api-1.7.32.jar and /dev/null differ diff --git a/j11lib/slf4j-api-1.7.36.jar b/j11lib/slf4j-api-1.7.36.jar new file mode 100644 index 0000000..7d3ce68 Binary files /dev/null and b/j11lib/slf4j-api-1.7.36.jar differ diff --git a/j11lib/slf4j-nop-1.7.36.jar b/j11lib/slf4j-nop-1.7.36.jar new file mode 100644 index 0000000..734ad96 Binary files /dev/null and b/j11lib/slf4j-nop-1.7.36.jar differ diff --git a/j8lib/flatlaf-3.1.1.jar b/j8lib/flatlaf-3.1.1.jar deleted file mode 100644 index 2b13cdd..0000000 Binary files a/j8lib/flatlaf-3.1.1.jar and /dev/null differ diff --git a/j8lib/flatlaf-3.2.jar b/j8lib/flatlaf-3.2.jar new file mode 100644 index 0000000..450c1e8 Binary files /dev/null and b/j8lib/flatlaf-3.2.jar differ diff --git a/j11lib/flatlaf-extras-3.1.1.jar b/j8lib/flatlaf-extras-3.2.jar similarity index 52% rename from j11lib/flatlaf-extras-3.1.1.jar rename to j8lib/flatlaf-extras-3.2.jar index 9d91bd0..ccdbf94 100644 Binary files a/j11lib/flatlaf-extras-3.1.1.jar and b/j8lib/flatlaf-extras-3.2.jar differ diff --git a/j8lib/getdown-core.jar b/j8lib/getdown-core.jar index 7c99c93..3fc97b5 100644 Binary files a/j8lib/getdown-core.jar and b/j8lib/getdown-core.jar differ diff --git a/j8lib/groovy-4.0.15.jar b/j8lib/groovy-4.0.15.jar new file mode 100644 index 0000000..8423d99 Binary files /dev/null and b/j8lib/groovy-4.0.15.jar differ diff --git a/j8lib/groovy-all-2.4.21-indy.jar b/j8lib/groovy-all-2.4.21-indy.jar deleted file mode 100644 index 15ee98d..0000000 Binary files a/j8lib/groovy-all-2.4.21-indy.jar and /dev/null differ diff --git a/j8lib/groovy-ant-4.0.15.jar b/j8lib/groovy-ant-4.0.15.jar new file mode 100644 index 0000000..b6a39ac Binary files /dev/null and b/j8lib/groovy-ant-4.0.15.jar differ diff --git a/j8lib/groovy-astbuilder-4.0.15.jar b/j8lib/groovy-astbuilder-4.0.15.jar new file mode 100644 index 0000000..f341fac Binary files /dev/null and b/j8lib/groovy-astbuilder-4.0.15.jar differ diff --git a/j8lib/groovy-cli-commons-4.0.15.jar b/j8lib/groovy-cli-commons-4.0.15.jar new file mode 100644 index 0000000..b482258 Binary files /dev/null and b/j8lib/groovy-cli-commons-4.0.15.jar differ diff --git a/j8lib/groovy-cli-picocli-4.0.15.jar b/j8lib/groovy-cli-picocli-4.0.15.jar new file mode 100644 index 0000000..3223ba9 Binary files /dev/null and b/j8lib/groovy-cli-picocli-4.0.15.jar differ diff --git a/j8lib/groovy-console-4.0.15.jar b/j8lib/groovy-console-4.0.15.jar new file mode 100644 index 0000000..04a402a Binary files /dev/null and b/j8lib/groovy-console-4.0.15.jar differ diff --git a/j8lib/groovy-contracts-4.0.15.jar b/j8lib/groovy-contracts-4.0.15.jar new file mode 100644 index 0000000..6825657 Binary files /dev/null and b/j8lib/groovy-contracts-4.0.15.jar differ diff --git a/j8lib/groovy-datetime-4.0.15.jar b/j8lib/groovy-datetime-4.0.15.jar new file mode 100644 index 0000000..312575a Binary files /dev/null and b/j8lib/groovy-datetime-4.0.15.jar differ diff --git a/j8lib/groovy-dateutil-4.0.15.jar b/j8lib/groovy-dateutil-4.0.15.jar new file mode 100644 index 0000000..5893f97 Binary files /dev/null and b/j8lib/groovy-dateutil-4.0.15.jar differ diff --git a/j8lib/groovy-docgenerator-4.0.15.jar b/j8lib/groovy-docgenerator-4.0.15.jar new file mode 100644 index 0000000..bf76564 Binary files /dev/null and b/j8lib/groovy-docgenerator-4.0.15.jar differ diff --git a/j8lib/groovy-ginq-4.0.15.jar b/j8lib/groovy-ginq-4.0.15.jar new file mode 100644 index 0000000..46f561e Binary files /dev/null and b/j8lib/groovy-ginq-4.0.15.jar differ diff --git a/j8lib/groovy-groovydoc-4.0.15.jar b/j8lib/groovy-groovydoc-4.0.15.jar new file mode 100644 index 0000000..b818919 Binary files /dev/null and b/j8lib/groovy-groovydoc-4.0.15.jar differ diff --git a/j8lib/groovy-groovysh-4.0.15.jar b/j8lib/groovy-groovysh-4.0.15.jar new file mode 100644 index 0000000..253eff6 Binary files /dev/null and b/j8lib/groovy-groovysh-4.0.15.jar differ diff --git a/j8lib/groovy-jmx-4.0.15.jar b/j8lib/groovy-jmx-4.0.15.jar new file mode 100644 index 0000000..8667ac4 Binary files /dev/null and b/j8lib/groovy-jmx-4.0.15.jar differ diff --git a/j8lib/groovy-json-4.0.15.jar b/j8lib/groovy-json-4.0.15.jar new file mode 100644 index 0000000..76b486a Binary files /dev/null and b/j8lib/groovy-json-4.0.15.jar differ diff --git a/j8lib/groovy-jsr223-4.0.15.jar b/j8lib/groovy-jsr223-4.0.15.jar new file mode 100644 index 0000000..5ae9f69 Binary files /dev/null and b/j8lib/groovy-jsr223-4.0.15.jar differ diff --git a/j8lib/groovy-macro-4.0.15.jar b/j8lib/groovy-macro-4.0.15.jar new file mode 100644 index 0000000..e5f7abb Binary files /dev/null and b/j8lib/groovy-macro-4.0.15.jar differ diff --git a/j8lib/groovy-macro-library-4.0.15.jar b/j8lib/groovy-macro-library-4.0.15.jar new file mode 100644 index 0000000..92c208f Binary files /dev/null and b/j8lib/groovy-macro-library-4.0.15.jar differ diff --git a/j8lib/groovy-nio-4.0.15.jar b/j8lib/groovy-nio-4.0.15.jar new file mode 100644 index 0000000..e6e2ad8 Binary files /dev/null and b/j8lib/groovy-nio-4.0.15.jar differ diff --git a/j8lib/groovy-servlet-4.0.15.jar b/j8lib/groovy-servlet-4.0.15.jar new file mode 100644 index 0000000..711a1e2 Binary files /dev/null and b/j8lib/groovy-servlet-4.0.15.jar differ diff --git a/j8lib/groovy-sql-4.0.15.jar b/j8lib/groovy-sql-4.0.15.jar new file mode 100644 index 0000000..058db44 Binary files /dev/null and b/j8lib/groovy-sql-4.0.15.jar differ diff --git a/j8lib/groovy-swing-4.0.15.jar b/j8lib/groovy-swing-4.0.15.jar new file mode 100644 index 0000000..848d074 Binary files /dev/null and b/j8lib/groovy-swing-4.0.15.jar differ diff --git a/j8lib/groovy-templates-4.0.15.jar b/j8lib/groovy-templates-4.0.15.jar new file mode 100644 index 0000000..3cd0245 Binary files /dev/null and b/j8lib/groovy-templates-4.0.15.jar differ diff --git a/j8lib/groovy-test-4.0.15.jar b/j8lib/groovy-test-4.0.15.jar new file mode 100644 index 0000000..e600dc7 Binary files /dev/null and b/j8lib/groovy-test-4.0.15.jar differ diff --git a/j8lib/groovy-test-junit5-4.0.15.jar b/j8lib/groovy-test-junit5-4.0.15.jar new file mode 100644 index 0000000..abcc69a Binary files /dev/null and b/j8lib/groovy-test-junit5-4.0.15.jar differ diff --git a/j8lib/groovy-testng-4.0.15.jar b/j8lib/groovy-testng-4.0.15.jar new file mode 100644 index 0000000..60c1b58 Binary files /dev/null and b/j8lib/groovy-testng-4.0.15.jar differ diff --git a/j8lib/groovy-toml-4.0.15.jar b/j8lib/groovy-toml-4.0.15.jar new file mode 100644 index 0000000..ad49634 Binary files /dev/null and b/j8lib/groovy-toml-4.0.15.jar differ diff --git a/j8lib/groovy-typecheckers-4.0.15.jar b/j8lib/groovy-typecheckers-4.0.15.jar new file mode 100644 index 0000000..dc113c3 Binary files /dev/null and b/j8lib/groovy-typecheckers-4.0.15.jar differ diff --git a/j8lib/groovy-xml-4.0.15.jar b/j8lib/groovy-xml-4.0.15.jar new file mode 100644 index 0000000..21aeea0 Binary files /dev/null and b/j8lib/groovy-xml-4.0.15.jar differ diff --git a/j8lib/groovy-yaml-4.0.15.jar b/j8lib/groovy-yaml-4.0.15.jar new file mode 100644 index 0000000..207d47d Binary files /dev/null and b/j8lib/groovy-yaml-4.0.15.jar differ diff --git a/j8lib/javaparser-core-3.25.5.jar b/j8lib/javaparser-core-3.25.5.jar new file mode 100644 index 0000000..92eed53 Binary files /dev/null and b/j8lib/javaparser-core-3.25.5.jar differ diff --git a/j8lib/slf4j-api-1.7.32.jar b/j8lib/slf4j-api-1.7.32.jar deleted file mode 100644 index b16a078..0000000 Binary files a/j8lib/slf4j-api-1.7.32.jar and /dev/null differ diff --git a/j8lib/slf4j-api-1.7.36.jar b/j8lib/slf4j-api-1.7.36.jar new file mode 100644 index 0000000..7d3ce68 Binary files /dev/null and b/j8lib/slf4j-api-1.7.36.jar differ diff --git a/j8lib/slf4j-nop-1.7.36.jar b/j8lib/slf4j-nop-1.7.36.jar new file mode 100644 index 0000000..734ad96 Binary files /dev/null and b/j8lib/slf4j-nop-1.7.36.jar differ diff --git a/resources/lang/Messages.properties b/resources/lang/Messages.properties index 924b9cb..c3c8589 100644 --- a/resources/lang/Messages.properties +++ b/resources/lang/Messages.properties @@ -363,6 +363,7 @@ label.sequences_from = Sequences from {0} label.successfully_loaded_file = Successfully loaded file {0} label.successfully_loaded_matrix = Successfully loaded score matrix {0} label.successfully_saved_to_file_in_format = Successfully saved to file: {0} in {1} format. +label.successfully_printed_to_stdout_in_format = Successfully printed to STDOUT in {0} format. label.copied_sequences_to_clipboard = Copied {0} sequences to clipboard. label.check_file_matches_sequence_ids_alignment = Check that the file matches sequence IDs in the alignment. label.problem_reading_tcoffee_score_file = Problem reading T-COFFEE score file @@ -1245,8 +1246,8 @@ label.mapping_method = Sequence \u27f7 Structure mapping method status.cancelled_image_export_operation = Cancelled {0} export operation info.error_creating_file = Error creating {0} file exception.outofmemory_loading_mmcif_file = Out of memory loading mmCIF File -label.run_groovy = Run Groovy console script -label.run_groovy_tip = Run the script in the Groovy console over this alignment +label.run_groovy = Run Groovy Console Script +label.run_groovy_tip = Run the script in the Groovy Console over this alignment label.couldnt_run_groovy_script = Failed to run Groovy script label.uniprot_sequence_fetcher = UniProt Sequence Fetcher action.next_page= >> @@ -1462,4 +1463,9 @@ action.show_tree_for_matrix_tooltip = Opens a tree viewer to display the average action.cluster_matrix = Cluster matrix action.clustering_matrix_for = Calculating tree for matrix {0} and clustering at {1} action.cluster_matrix_tooltip = Computes an average distance tree for the matrix and displays it - +label.all_known_alignment_files = All known alignment files +label.command_line_arguments = Command Line Arguments +warning.using_old_command_line_arguments = It looks like you are using old command line arguments. These are now deprecated and will be removed in a future release of Jalview.\nFind out about the new command line arguments at\n +warning.using_mixed_command_line_arguments = Jalview cannot use both old (-arg) and new (--arg) command line arguments. Please check your command line arguments.\ne.g. {0} and {1} +warning.the_following_errors = The following errors and warnings occurred whilst processing files: +action.show_hetatm = Show Ligands (HETATM) diff --git a/resources/lang/Messages_es.properties b/resources/lang/Messages_es.properties index 150a407..a0b9292 100644 --- a/resources/lang/Messages_es.properties +++ b/resources/lang/Messages_es.properties @@ -326,6 +326,7 @@ label.sequences_from = Secuencias de {0} label.successfully_loaded_file = Fichero cargado exitosamente {0} label.successfully_loaded_matrix = Matriz cargada exitosamente {0} label.successfully_saved_to_file_in_format = Guardado exitosamente en el fichero: {0} en formato {1}. +label.successfully_printed_to_stdout_in_format = Impresso exitosamente al STDOUT en formato {0}. label.copied_sequences_to_clipboard = Copiadas {0} secuencias en el portapapeles. label.check_file_matches_sequence_ids_alignment = Comprobar que el fichero coincide con el ID de la secuencia en el alineamiento. label.problem_reading_tcoffee_score_file = Problema de lectura del fichero de puntuaciones T-COFFEE @@ -1436,3 +1437,8 @@ label.add_pae_matrix_file = A label.nothing_selected = Nada seleccionado prompt.analytics_title = Jalview Estadísticas de Uso prompt.analytics = ¿Quiere ayudar a mejorar Jalview habilitando la recopilación de estadísticas de uso con análisis Plausible?\nPuede habilitar o deshabilitar el seguimiento de uso en las preferencias. +label.all_known_alignment_files = Todos los archivos de alineación conocidos +label.command_line_arguments = Argumentos de línea de comando +warning.using_old_command_line_arguments = Parece que estás utilizando argumentos antiguos de línea de comando. Estos ahora están en desuso y se eliminarán en una versión futura de Jalview.\nObtenga más información sobre los nuevos argumentos de la línea de comando en\n +warning.using_mixed_command_line_arguments = Jalview no puede utilizar argumentos de línea de comando antiguos (-arg) y nuevos (--arg). Verifique los argumentos de su línea de comando.\ne.g. {0} y {1} +warning.the_following_errors = Se produjeron los siguientes errores y advertencias al procesar archivos: diff --git a/schemas/jalview.xsd b/schemas/jalview.xsd index adaa3ee..c5d35fb 100755 --- a/schemas/jalview.xsd +++ b/schemas/jalview.xsd @@ -501,6 +501,8 @@ + + diff --git a/schemas/vamsas.xsd b/schemas/vamsas.xsd index fedbae3..364bfbe 100755 --- a/schemas/vamsas.xsd +++ b/schemas/vamsas.xsd @@ -23,58 +23,83 @@ xjc schemas/jalview.xsd -d src -p jalview.xml.binding.jalview Note this also generates code for included schemas --> - + - - + + - - developed after mapRangeType from http://www.vamsas.ac.uk/schemas/1.0/vamsasTypes + + developed after mapRangeType from + http://www.vamsas.ac.uk/schemas/1.0/vamsasTypes - This effectively represents a java.util.MapList object + This effectively represents a java.util.MapList + object - + - a region from start to end inclusive + a region from start to end inclusive + - - + + - - + + - a region from start to end inclusive + a region from start to end inclusive + - - + + - + - + - number of dictionary symbol widths involved in each - mapped position on this sequence (for example, 3 for a dna sequence exon - region that is being mapped to a protein sequence). This is optional, - since the unit can be usually be inferred from the dictionary type of - each sequence involved in the mapping. + number of dictionary symbol widths involved in + each + mapped position on this sequence (for example, 3 for a dna + sequence exon + region that is being mapped to a protein sequence). + This is optional, + since the unit can be usually be inferred from the + dictionary type of + each sequence involved in the mapping. + - + - number of dictionary symbol widths involved in each - mapped position on this sequence (for example, 3 for a dna sequence exon - region that is being mapped to a protein sequence). This is optional, - since the unit can be usually be inferred from the dictionary type of - each sequence involved in the mapping. + number of dictionary symbol widths involved in + each + mapped position on this sequence (for example, 3 for a dna + sequence exon + region that is being mapped to a protein sequence). + This is optional, + since the unit can be usually be inferred from the + dictionary type of + each sequence involved in the mapping. + @@ -82,74 +107,94 @@ - Represent the jalview.datamodel.Mapping object - it also provides - a way of storing sequences that are mapped 'to' without adding them - to the sequence set (which will mean they are then added to the alignment too). + Represent the jalview.datamodel.Mapping object - + it also provides + a way of storing sequences that are mapped 'to' + without adding them + to the sequence set (which will mean they are + then added to the alignment too). - + - The sequence whose dataset sequence is to be referenced here + The sequence whose dataset sequence is to + be referenced here + - + - Biotype of the mapping e.g. CdsToPeptide + Biotype of the mapping e.g. CdsToPeptide + - + - + - specifies a series of aligned codons from an associated DNA sequence alignment that when translated correspond to columns of a peptide alignment. - Element may have either all pos1,2,3 attributes specified, or none at all (indicating a gapped column with no translated peptide). + specifies a series of aligned codons from an + associated DNA sequence alignment that when translated + correspond to columns of a peptide alignment. + Element may have + either all pos1,2,3 attributes specified, or none at all + (indicating a gapped column with no translated peptide). - - - + + + - + - + - a Mapping entry and an associated protein sequence + a Mapping entry and an associated protein + sequence - + - internal jalview id for the dnasq for this mapping. + internal jalview id for the dnasq for this + mapping. - + - + @@ -158,39 +203,49 @@ - + - - - - - - + + + + + + - true for gene locus mapping, source=species, version=assembly, accession=chromosome + true for gene locus mapping, source=species, + version=assembly, accession=chromosome - + - true for the representative accession for databases where multiple accessions map to the same entry (eg. Uniprot) + true for the representative accession for + databases where multiple accessions map to the same entry + (eg. Uniprot) - + - dataset sequence id for this sequence. Will be created as union of sequences. + dataset sequence id for this sequence. Will be + created as union of sequences. - + Biotype of the sequence (if known) @@ -216,13 +271,16 @@ - + - + - - + + - - height in pixels for the graph if this is a graph-type annotation. + + + height in pixels for the graph if this is a + graph-type annotation. + + + - + - - is an autocalculated annotation row - - - is to be shown below the alignment - introduced in Jalview 2.8 for visualizing T-COFFEE alignment scores - - Optional string identifier used to group sets of annotation produced by a particular calculation. Values are opaque strings but have semantic meaning to Jalview's renderer, data importer and calculation system. + + + is an autocalculated annotation row + + + + + + is to be shown below the alignment - introduced + in Jalview 2.8 for visualizing T-COFFEE alignment scores + + + + + + Optional string identifier used to group sets of + annotation produced by a particular calculation. Values are opaque + strings but have semantic meaning to Jalview's renderer, data + importer and calculation system. + + - + - - - + + + - - + + - + + + + Matrices referred to by this set of sequences. + + + - - + + - reference to set where jalview will gather the dataset sequences for all sequences in the set. + reference to set where jalview will gather the + dataset sequences for all sequences in the set. @@ -283,36 +379,47 @@ - - + + - + - + - - + + - - + + - - + + + + Represents matrix data imported to Jalview, and the + results of any derived calculations (independent of a particular + view + on the matrix). + + serialised representation of matrix as one or - more sets of comma separated values + more sets of comma separated values + - - - mapping from the matrix row and column positions to - associated reference frame - - @@ -349,13 +449,43 @@ use="optional" /> - + + + + Defines a mapping from the local frame to a matrix + and its associated data specified by MatrixType + + + + + + + mapping from the matrix row and column positions + to + associated reference frame + + + + + + + + + reference to the matrix type this Map refers to + + + + + - - + + diff --git a/src/jalview/analysis/AAFrequency.java b/src/jalview/analysis/AAFrequency.java index b1505d6..6967885 100755 --- a/src/jalview/analysis/AAFrequency.java +++ b/src/jalview/analysis/AAFrequency.java @@ -147,7 +147,7 @@ public class AAFrequency { if (sequences[row] == null) { - System.err.println( + jalview.bin.Console.errPrintln( "WARNING: Consensus skipping null sequence - possible race condition."); continue; } @@ -188,7 +188,7 @@ public class AAFrequency } return new Profiles(result); // long elapsed = System.currentTimeMillis() - now; - // System.out.println(elapsed); + // jalview.bin.Console.outPrintln(elapsed); } /** @@ -285,7 +285,7 @@ public class AAFrequency ' ', value); } // long elapsed = System.currentTimeMillis() - now; - // System.out.println(-elapsed); + // jalview.bin.Console.outPrintln(-elapsed); } /** diff --git a/src/jalview/analysis/AlignSeq.java b/src/jalview/analysis/AlignSeq.java index 02b3f41..e1d5669 100755 --- a/src/jalview/analysis/AlignSeq.java +++ b/src/jalview/analysis/AlignSeq.java @@ -826,7 +826,7 @@ public class AlignSeq } } - System.out.println(max + " " + min); + jalview.bin.Console.outPrintln(max + " " + min); for (int i = 0; i < n; i++) { @@ -835,12 +835,12 @@ public class AlignSeq int x = psize * i; int y = psize * j; - // System.out.println(mat[i][j]); + // jalview.bin.Console.outPrintln(mat[i][j]); float score = (float) (mat[i][j] - min) / (float) (max - min); g.setColor(new Color(score, 0, 0)); g.fillRect(x, y, psize, psize); - // System.out.println(x + " " + y + " " + score); + // jalview.bin.Console.outPrintln(x + " " + y + " " + score); } } } @@ -983,7 +983,7 @@ public class AlignSeq bestm = msq; } } - // System.out.println("Best Score for " + (matches.size() + 1) + " :" + // jalview.bin.Console.outPrintln("Best Score for " + (matches.size() + 1) + " :" // + bestscore); matches.add(bestm); aligns.add(bestaseq); diff --git a/src/jalview/analysis/AlignmentSorter.java b/src/jalview/analysis/AlignmentSorter.java index b02d49c..b037336 100755 --- a/src/jalview/analysis/AlignmentSorter.java +++ b/src/jalview/analysis/AlignmentSorter.java @@ -453,7 +453,7 @@ public class AlignmentSorter if (tmp.size() != nSeq) { - System.err.println("WARNING: tmp.size()=" + tmp.size() + " != nseq=" + jalview.bin.Console.errPrintln("WARNING: tmp.size()=" + tmp.size() + " != nseq=" + nSeq + " in getOrderByTree - tree contains sequences not in alignment"); } @@ -714,7 +714,7 @@ public class AlignmentSorter String msg = String.format( "Implementation Error - sortByFeature method must be either '%s' or '%s'", FEATURE_SCORE, FEATURE_DENSITY); - System.err.println(msg); + jalview.bin.Console.errPrintln(msg); return; } @@ -832,7 +832,7 @@ public class AlignmentSorter { // int nf = (feats[i] == null) ? 0 // : ((SequenceFeature[]) feats[i]).length; - // // System.err.println("Sorting on Score: seq " + + // // jalview.bin.Console.errPrintln("Sorting on Score: seq " + // seqs[i].getName() // + " Feats: " + nf + " Score : " + scores[i]); } @@ -847,7 +847,7 @@ public class AlignmentSorter int featureCount = feats[i] == null ? 0 : ((SequenceFeature[]) feats[i]).length; scores[i] = featureCount; - // System.err.println("Sorting on Density: seq "+seqs[i].getName()+ + // jalview.bin.Console.errPrintln("Sorting on Density: seq "+seqs[i].getName()+ // " Feats: "+featureCount+" Score : "+scores[i]); } QuickSort.sortByDouble(scores, seqs, sortByFeatureAscending); diff --git a/src/jalview/analysis/AlignmentUtils.java b/src/jalview/analysis/AlignmentUtils.java index 6ab49b2..f470dc6 100644 --- a/src/jalview/analysis/AlignmentUtils.java +++ b/src/jalview/analysis/AlignmentUtils.java @@ -547,7 +547,7 @@ public class AlignmentUtils if (translated == null || !(aaRes == translated.charAt(0))) { // debug - // System.out.println(("Mismatch at " + i + "/" + aaResidue + ": " + // jalview.bin.Console.outPrintln(("Mismatch at " + i + "/" + aaResidue + ": " // + codon + "(" + translated + ") != " + aaRes)); return false; } @@ -698,7 +698,7 @@ public class AlignmentUtils * unmapped position; treat like a gap */ sourceGapMappedLength += ratio; - // System.err.println("Can't align: no codon mapping to residue " + // jalview.bin.Console.errPrintln("Can't align: no codon mapping to residue " // + sourceDsPos + "(" + sourceChar + ")"); // return; continue; @@ -883,7 +883,7 @@ public class AlignmentUtils { if (protein.isNucleotide() || !dna.isNucleotide()) { - System.err.println("Wrong alignment type in alignProteinAsDna"); + jalview.bin.Console.errPrintln("Wrong alignment type in alignProteinAsDna"); return 0; } List unmappedProtein = new ArrayList<>(); @@ -908,7 +908,7 @@ public class AlignmentUtils { if (protein.isNucleotide() || !dna.isNucleotide()) { - System.err.println("Wrong alignment type in alignProteinAsDna"); + jalview.bin.Console.errPrintln("Wrong alignment type in alignProteinAsDna"); return 0; } // todo: implement this @@ -988,7 +988,7 @@ public class AlignmentUtils .getLength() == mappedFromLength - 1); if (cdsLength != mappedToLength && !addStopCodon) { - System.err.println(String.format( + jalview.bin.Console.errPrintln(String.format( "Can't align cds as protein (length mismatch %d/%d): %s", cdsLength, mappedToLength, cdsSeq.getName())); } @@ -1162,7 +1162,7 @@ public class AlignmentUtils AlignedCodon codon = sequenceCodon.getValue(); if (codon.peptideCol > 1) { - System.err.println( + jalview.bin.Console.errPrintln( "Problem mapping protein with >1 unmapped start positions: " + seq.getName()); } @@ -2770,7 +2770,7 @@ public class AlignmentUtils fromRange[i + 1]); if (range == null) { - System.err.println("Error in mapping " + seqMap + " from " + jalview.bin.Console.errPrintln("Error in mapping " + seqMap + " from " + fromSeq.getName()); return false; } diff --git a/src/jalview/analysis/Conservation.java b/src/jalview/analysis/Conservation.java index cbc4dca..5bb0b09 100755 --- a/src/jalview/analysis/Conservation.java +++ b/src/jalview/analysis/Conservation.java @@ -243,13 +243,13 @@ public class Conservation } else { - System.out.println("SEQUENCE HAS BEEN DELETED!!!"); + jalview.bin.Console.outPrintln("SEQUENCE HAS BEEN DELETED!!!"); } } else { // JBPNote INFO level debug - System.err.println( + jalview.bin.Console.errPrintln( "ERROR: calcSeqNum called with out of range sequence index for Alignment\n"); } } @@ -711,7 +711,7 @@ public class Conservation // tmp = ((max - tmp) * (size - cons2[j][23])) / size; tmp = ((max - tmp) * (size - cons2GapCounts[j])) / size; - // System.out.println(tmp+ " " + j); + // jalview.bin.Console.outPrintln(tmp+ " " + j); quality.setElementAt(Double.valueOf(tmp), j); if (tmp > newmax) diff --git a/src/jalview/analysis/CrossRef.java b/src/jalview/analysis/CrossRef.java index 9b90ca5..41582b4 100644 --- a/src/jalview/analysis/CrossRef.java +++ b/src/jalview/analysis/CrossRef.java @@ -293,7 +293,7 @@ public class CrossRef if (matchInDataset != null && xref.getMap().getTo() != null && matchInDataset != xref.getMap().getTo()) { - System.err.println( + jalview.bin.Console.errPrintln( "Implementation problem (reopen JAL-2154): CrossRef.findInDataset seems to have recovered a different sequence than the one explicitly mapped for xref." + "Found:" + matchInDataset + "\nExpected:" + xref.getMap().getTo() + "\nFor xref:" @@ -424,7 +424,7 @@ public class CrossRef retrieved = sftch.getSequences(sourceRefs, !fromDna); } catch (Exception e) { - System.err.println( + jalview.bin.Console.errPrintln( "Problem whilst retrieving cross references for Sequence : " + seq.getName()); e.printStackTrace(); @@ -607,7 +607,7 @@ public class CrossRef String msg = "Mapping updated from " + ms.getName() + " to retrieved crossreference " + matched.getName(); - System.out.println(msg); + jalview.bin.Console.outPrintln(msg); List toRefs = map.getTo().getDBRefs(); if (toRefs != null) @@ -662,7 +662,7 @@ public class CrossRef cf.addMap(retrievedSequence, map.getTo(), map.getMap()); } catch (Exception e) { - System.err.println( + jalview.bin.Console.errPrintln( "Exception when consolidating Mapped sequence set..."); e.printStackTrace(System.err); } @@ -1029,7 +1029,7 @@ public class CrossRef } if (dataset.getSequences() == null) { - System.err.println("Empty dataset sequence set - NO VECTOR"); + jalview.bin.Console.errPrintln("Empty dataset sequence set - NO VECTOR"); return false; } List ds = dataset.getSequences(); @@ -1041,7 +1041,7 @@ public class CrossRef { if (nxt.getDatasetSequence() != null) { - System.err.println( + jalview.bin.Console.errPrintln( "Implementation warning: CrossRef initialised with a dataset alignment with non-dataset sequences in it! (" + nxt.getDisplayId(true) + " has ds reference " + nxt.getDatasetSequence().getDisplayId(true) diff --git a/src/jalview/analysis/Dna.java b/src/jalview/analysis/Dna.java index 5dcf212..aa71eb7 100644 --- a/src/jalview/analysis/Dna.java +++ b/src/jalview/analysis/Dna.java @@ -653,7 +653,7 @@ public class Dna if (rf != 0) { final String errMsg = "trimming contigs for incomplete terminal codon."; - System.err.println(errMsg); + jalview.bin.Console.errPrintln(errMsg); // map and trim contigs to ORF region vc = scontigs.length - 1; lastnpos = vismapping.shift(lastnpos); // place npos in context of diff --git a/src/jalview/analysis/GeneticCodes.java b/src/jalview/analysis/GeneticCodes.java index 133cb3a..4c826b2 100644 --- a/src/jalview/analysis/GeneticCodes.java +++ b/src/jalview/analysis/GeneticCodes.java @@ -140,7 +140,7 @@ public final class GeneticCodes InputStream is = getClass().getResourceAsStream(fileName); if (is == null) { - System.err.println("Resource file not found: " + fileName); + jalview.bin.Console.errPrintln("Resource file not found: " + fileName); return; } BufferedReader dataIn = new BufferedReader(new InputStreamReader(is)); @@ -166,7 +166,7 @@ public final class GeneticCodes } if (codeTables.isEmpty()) { - System.err.println( + jalview.bin.Console.errPrintln( "No genetic code tables loaded, check format of file " + fileName); } @@ -190,7 +190,7 @@ public final class GeneticCodes InputStream is = getClass().getResourceAsStream(fileName); if (is == null) { - System.err.println("Resource file not found: " + fileName); + jalview.bin.Console.errPrintln("Resource file not found: " + fileName); return; } BufferedReader dataIn = new BufferedReader(new InputStreamReader(is)); @@ -208,7 +208,7 @@ public final class GeneticCodes } else { - System.err.println( + jalview.bin.Console.errPrintln( "Unexpected data in " + fileName + ": " + line); } } diff --git a/src/jalview/analysis/Grouping.java b/src/jalview/analysis/Grouping.java index 066814e..def5d5a 100644 --- a/src/jalview/analysis/Grouping.java +++ b/src/jalview/analysis/Grouping.java @@ -269,7 +269,7 @@ public class Grouping * seqs.length) { for (int i = 0; i < seqs.length; i++) { if (!hasScore[i]) * { scores[i] = (max + i); } else { int nf=(feats[i]==null) ? 0 * :((SequenceFeature[]) feats[i]).length; - * System.err.println("Sorting on Score: seq "+seqs[i].getName()+ + * jalview.bin.Console.errPrintln("Sorting on Score: seq "+seqs[i].getName()+ * " Feats: "+nf+" Score : "+scores[i]); } } } * * jalview.util.QuickSort.sort(scores, seqs); } else if @@ -280,7 +280,7 @@ public class Grouping * (int i=0;i 0) ? "_" + reps : ""), ScoreDescriptions[cols], null); an.setScore(score); - System.out.println(seqs[i].getName() + " score: '" + jalview.bin.Console.outPrintln(seqs[i].getName() + " score: '" + ScoreNames[cols] + "' = " + score); // DEBUG an.setSequenceRef(seqs[i]); seqs[i].addAlignmentAnnotation(an); diff --git a/src/jalview/analysis/Rna.java b/src/jalview/analysis/Rna.java index 9649240..911ee04 100644 --- a/src/jalview/analysis/Rna.java +++ b/src/jalview/analysis/Rna.java @@ -421,8 +421,8 @@ public class Rna final int open = basePair.getBP5(); final int close = basePair.getBP3(); - // System.out.println("open " + open + " close " + close); - // System.out.println("lastclose " + lastclose + " lastopen " + lastopen); + // jalview.bin.Console.outPrintln("open " + open + " close " + close); + // jalview.bin.Console.outPrintln("lastclose " + lastclose + " lastopen " + lastopen); // we're moving from right to left based on closing pair /* @@ -441,7 +441,7 @@ public class Rna { int popen = bps.get(j).getBP5(); - // System.out.println("j " + j + " popen " + popen + " lastopen " + // jalview.bin.Console.outPrintln("j " + j + " popen " + popen + " lastopen " // +lastopen + " open " + open); if ((popen < lastopen) && (popen > open)) { diff --git a/src/jalview/analysis/SeqsetUtils.java b/src/jalview/analysis/SeqsetUtils.java index fdca89d..837462f 100755 --- a/src/jalview/analysis/SeqsetUtils.java +++ b/src/jalview/analysis/SeqsetUtils.java @@ -129,7 +129,7 @@ public class SeqsetUtils { if (sfeatures != null) { - System.err.println( + jalview.bin.Console.errPrintln( "Implementation error: setting dataset sequence for a sequence which has sequence features.\n\tDataset sequence features will not be visible."); } sq.setDatasetSequence(seqds); @@ -244,7 +244,7 @@ public class SeqsetUtils { if (!quiet) { - System.err.println("Can't find '" + ((String) key) + jalview.bin.Console.errPrintln("Can't find '" + ((String) key) + "' in uniquified alignment"); } } @@ -252,7 +252,7 @@ public class SeqsetUtils } if (unmatched.size() > 0 && !quiet) { - System.err.println("Did not find matches for :"); + jalview.bin.Console.errPrintln("Did not find matches for :"); for (Enumeration i = unmatched.elements(); i .hasMoreElements(); System.out .println(((SequenceI) i.nextElement()).getName())) diff --git a/src/jalview/analysis/StructureFrequency.java b/src/jalview/analysis/StructureFrequency.java index c04df6c..3f5099b 100644 --- a/src/jalview/analysis/StructureFrequency.java +++ b/src/jalview/analysis/StructureFrequency.java @@ -148,7 +148,7 @@ public class StructureFrequency { if (sequences[j] == null) { - System.err.println( + jalview.bin.Console.errPrintln( "WARNING: Consensus skipping null sequence - possible race condition."); continue; } diff --git a/src/jalview/analysis/TreeEngine.java b/src/jalview/analysis/TreeEngine.java index daf7836..a7cbc25 100644 --- a/src/jalview/analysis/TreeEngine.java +++ b/src/jalview/analysis/TreeEngine.java @@ -214,7 +214,7 @@ public abstract class TreeEngine { // if (_lycount<_lylimit) // { - // System.err.println("Warning: depth of _recount greater than number of + // jalview.bin.Console.errPrintln("Warning: depth of _recount greater than number of // nodes."); // } if (nd == null) diff --git a/src/jalview/analysis/TreeModel.java b/src/jalview/analysis/TreeModel.java index 0e57a58..ce79a65 100644 --- a/src/jalview/analysis/TreeModel.java +++ b/src/jalview/analysis/TreeModel.java @@ -353,13 +353,14 @@ public class TreeModel if ((nd.left() == null) && (nd.right() == null)) { - System.out.println("Leaf = " + ((SequenceI) nd.element()).getName()); - System.out.println("Dist " + nd.dist); - System.out.println("Boot " + nd.getBootstrap()); + // TODO FIX FOR COLUMN TREES + jalview.bin.Console.outPrintln("Leaf = " + ((SequenceI) nd.element()).getName()); + jalview.bin.Console.outPrintln("Dist " + nd.dist); + jalview.bin.Console.outPrintln("Boot " + nd.getBootstrap()); } else { - System.out.println("Dist " + nd.dist); + jalview.bin.Console.outPrintln("Dist " + nd.dist); printNode((BinaryNode) nd.left()); printNode((BinaryNode) nd.right()); } @@ -430,7 +431,7 @@ public class TreeModel if ((nd.left() == null) && (nd.right() == null)) { - nd.height = ((BinaryNode) nd.parent()).height + nd.dist; + nd.height = nd.parent().height + nd.dist; if (nd.height > maxheight) { @@ -445,7 +446,7 @@ public class TreeModel { if (nd.parent() != null) { - nd.height = ((BinaryNode) nd.parent()).height + nd.dist; + nd.height = nd.parent().height + nd.dist; } else { @@ -480,10 +481,10 @@ public class TreeModel } else { - System.out.println(" name = " + ((SequenceI) nd.element()).getName()); + jalview.bin.Console.outPrintln(" name = " + ((SequenceI) nd.element()).getName()); } - System.out.println( + jalview.bin.Console.outPrintln( " dist = " + nd.dist + " " + nd.count + " " + nd.height); } @@ -513,7 +514,7 @@ public class TreeModel { // if (_lycount<_lylimit) // { - // System.err.println("Warning: depth of _recount greater than number of + // jalview.bin.Console.errPrintln("Warning: depth of _recount greater than number of // nodes."); // } if (nd == null) diff --git a/src/jalview/analysis/scoremodels/FeatureDistanceModel.java b/src/jalview/analysis/scoremodels/FeatureDistanceModel.java index 9c2f6d1..bcc0855 100644 --- a/src/jalview/analysis/scoremodels/FeatureDistanceModel.java +++ b/src/jalview/analysis/scoremodels/FeatureDistanceModel.java @@ -63,7 +63,7 @@ public class FeatureDistanceModel extends DistanceScoreModel return instance; } catch (InstantiationException | IllegalAccessException e) { - System.err.println("Error in " + getClass().getName() + jalview.bin.Console.errPrintln("Error in " + getClass().getName() + ".getInstance(): " + e.getMessage()); return null; } catch (ReflectiveOperationException roe) diff --git a/src/jalview/analysis/scoremodels/ScoreMatrix.java b/src/jalview/analysis/scoremodels/ScoreMatrix.java index b206339..aa841ac 100644 --- a/src/jalview/analysis/scoremodels/ScoreMatrix.java +++ b/src/jalview/analysis/scoremodels/ScoreMatrix.java @@ -331,12 +331,12 @@ public class ScoreMatrix extends SimilarityScoreModel { if (c >= symbolIndex.length) { - System.err.println(String.format(BAD_ASCII_ERROR, c)); + jalview.bin.Console.errPrintln(String.format(BAD_ASCII_ERROR, c)); return 0; } if (d >= symbolIndex.length) { - System.err.println(String.format(BAD_ASCII_ERROR, d)); + jalview.bin.Console.errPrintln(String.format(BAD_ASCII_ERROR, d)); return 0; } diff --git a/src/jalview/analysis/scoremodels/ScoreModels.java b/src/jalview/analysis/scoremodels/ScoreModels.java index ebc9a26..d0f21bd 100644 --- a/src/jalview/analysis/scoremodels/ScoreModels.java +++ b/src/jalview/analysis/scoremodels/ScoreModels.java @@ -105,7 +105,7 @@ public class ScoreModels return sm; } catch (IOException e) { - System.err.println( + jalview.bin.Console.errPrintln( "Error reading " + resourcePath + ": " + e.getMessage()); } return null; @@ -143,7 +143,7 @@ public class ScoreModels ScoreModelI sm2 = models.get(sm.getName()); if (sm2 != null) { - System.err.println("Warning: replacing score model " + sm2.getName()); + jalview.bin.Console.errPrintln("Warning: replacing score model " + sm2.getName()); } models.put(sm.getName(), sm); } diff --git a/src/jalview/api/SequenceRenderer.java b/src/jalview/api/SequenceRenderer.java index 54f7fb6..d5d07ef 100644 --- a/src/jalview/api/SequenceRenderer.java +++ b/src/jalview/api/SequenceRenderer.java @@ -20,10 +20,12 @@ */ package jalview.api; +import jalview.datamodel.SequenceGroup; import jalview.datamodel.SequenceI; import jalview.renderer.seqfeatures.FeatureColourFinder; import java.awt.Color; +import java.awt.Graphics; public interface SequenceRenderer { @@ -31,4 +33,19 @@ public interface SequenceRenderer Color getResidueColour(SequenceI seq, int position, FeatureColourFinder finder); + /** + * Configure the Graphics canvas and render options for the renderer + * @param g - the canvas to render to + * @param renderGaps - when true, gap characters will be included when rendered + * + */ + void prepare(Graphics g, boolean renderGaps); + + void drawSequence(SequenceI nextSeq, SequenceGroup[] findAllGroups, + int startRes, int endRes, int i); + + void drawHighlightedText(SequenceI nextSeq, int i, int j, int k, int l); + + void drawCursor(Graphics g, char s, int i, int j); + } diff --git a/src/jalview/api/structures/JalviewStructureDisplayI.java b/src/jalview/api/structures/JalviewStructureDisplayI.java index a1b92df..77f2b6d 100644 --- a/src/jalview/api/structures/JalviewStructureDisplayI.java +++ b/src/jalview/api/structures/JalviewStructureDisplayI.java @@ -20,9 +20,15 @@ */ package jalview.api.structures; +import java.io.File; +import java.util.Collections; +import java.util.List; + import jalview.api.AlignmentViewPanel; import jalview.datamodel.PDBEntry; import jalview.datamodel.SequenceI; +import jalview.gui.AlignmentPanel; +import jalview.gui.StructureViewer; import jalview.structures.models.AAStructureBindingModel; public interface JalviewStructureDisplayI @@ -172,4 +178,28 @@ public interface JalviewStructureDisplayI */ boolean hasViewerActionsMenu(); + String getViewId(); + + StructureViewer.ViewerType getViewerType(); + + boolean isUsedforaligment(AlignmentViewPanel ap); + + boolean isColouredByViewer(); + + int getHeight(); + + int getWidth(); + + int getY(); + + File saveSession(); + + /** + * + * @return heteroatoms in a form suitable for display and passing to command generator to display hetatms + */ + default List getHetatms() { + return Collections.EMPTY_LIST; + } + } diff --git a/src/jalview/appletgui/APopupMenu.java b/src/jalview/appletgui/APopupMenu.java index b860a36..413b0d4 100644 --- a/src/jalview/appletgui/APopupMenu.java +++ b/src/jalview/appletgui/APopupMenu.java @@ -393,14 +393,14 @@ public class APopupMenu extends java.awt.PopupMenu urlLink = new UrlLink(link); } catch (Exception foo) { - System.err.println("Exception for URLLink '" + link + "': " + jalview.bin.Console.errPrintln("Exception for URLLink '" + link + "': " + foo.getMessage()); continue; } if (!urlLink.isValid()) { - System.err.println(urlLink.getInvalidMessage()); + jalview.bin.Console.errPrintln(urlLink.getInvalidMessage()); continue; } diff --git a/src/jalview/appletgui/AlignFrame.java b/src/jalview/appletgui/AlignFrame.java index 0159bc7..4b858e1 100644 --- a/src/jalview/appletgui/AlignFrame.java +++ b/src/jalview/appletgui/AlignFrame.java @@ -1577,7 +1577,7 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener, /* * When we finally deprecate 1.1 compatibility, we can start to use * URLEncoder.encode(url,"UTF-8") and then we'll need this catch: catch - * (UnsupportedEncodingException ex) { System.err.println("WARNING - + * (UnsupportedEncodingException ex) { jalview.bin.Console.errPrintln("WARNING - * IMPLEMENTATION ERROR - UNSUPPORTED ENCODING EXCEPTION FOR "+url); * ex.printStackTrace(); } */ @@ -1586,7 +1586,7 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener, url = viewport.applet.getCodeBase() + url; } catch (UnsupportedEncodingException ex) { - System.err.println( + jalview.bin.Console.errPrintln( "WARNING = IMPLEMENTATION ERROR - UNSUPPORTED ENCODING EXCEPTION FOR " + url); ex.printStackTrace(); @@ -2975,7 +2975,7 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener, SequenceI[] oldOrder = viewport.getAlignment().getSequencesArray(); if (viewport.applet.debug) { - System.err.println("Sorting " + alorder.getOrder().size() + jalview.bin.Console.errPrintln("Sorting " + alorder.getOrder().size() + " in alignment '" + getTitle() + "'"); } AlignmentSorter.sortBy(viewport.getAlignment(), alorder); @@ -3061,7 +3061,7 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener, { if (viewport.applet == null) { - System.out.println("Not running as applet - no browser available."); + jalview.bin.Console.outPrintln("Not running as applet - no browser available."); } else { @@ -3977,12 +3977,12 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener, viewer = (Viewer) jmolviewer; } catch (ClassCastException ex) { - System.err.println( + jalview.bin.Console.errPrintln( "Unsupported viewer object :" + jmolviewer.getClass()); } if (viewer == null) { - System.err.println("Can't use this object as a structure viewer:" + jalview.bin.Console.errPrintln("Can't use this object as a structure viewer:" + jmolviewer.getClass()); return null; } @@ -4127,7 +4127,7 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener, chains = (String[]) sqch[1]; if (seqs == null || seqs.length == 0) { - System.err.println( + jalview.bin.Console.errPrintln( "JalviewLite.AlignFrame:newStructureView: No sequence to bind structure to."); } if (protocol == null) @@ -4142,7 +4142,7 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener, } if (protocol == null) { - System.err.println("Couldn't work out protocol to open structure: " + jalview.bin.Console.errPrintln("Couldn't work out protocol to open structure: " + pdb.getId()); return; } @@ -4154,7 +4154,7 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener, .setMapping(seqs, chains, pdb.getFile(), protocol, null) == null) { - System.err.println("Failed to map " + pdb.getFile() + " (" + jalview.bin.Console.errPrintln("Failed to map " + pdb.getFile() + " (" + protocol + ") to any sequences"); } return; @@ -4176,7 +4176,7 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener, } if (ajm != null) { - System.err.println( + jalview.bin.Console.errPrintln( "Incremental adding and aligning structure to existing Jmol view not yet implemented."); // try and add the pdb structure // ajm.addS @@ -4201,7 +4201,7 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener, SequenceI[][] seqs, String[][] chains, String[] protocols) { // TODO Auto-generated method stub - System.err.println("Aligned Structure View: Not yet implemented."); + jalview.bin.Console.errPrintln("Aligned Structure View: Not yet implemented."); } /** @@ -4258,9 +4258,9 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener, if (!file.isValid()) { // TODO: raise dialog for gui - System.err.println("Problems parsing T-Coffee scores: " + jalview.bin.Console.errPrintln("Problems parsing T-Coffee scores: " + file.getWarningMessage()); - System.err.println("Origin was:\n" + source); + jalview.bin.Console.errPrintln("Origin was:\n" + source); return false; } @@ -4273,7 +4273,7 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener, || aln.getWidth() != file.getWidth())) { // TODO: raise a dialog box here rather than bomb out. - System.err.println( + jalview.bin.Console.errPrintln( "The scores matrix does not match the alignment dimensions"); } @@ -4289,10 +4289,10 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener, } else { - System.err.println("Problems resolving T-Coffee scores:"); + jalview.bin.Console.errPrintln("Problems resolving T-Coffee scores:"); if (file.getWarningMessage() != null) { - System.err.println(file.getWarningMessage()); + jalview.bin.Console.errPrintln(file.getWarningMessage()); } } return false; diff --git a/src/jalview/appletgui/AlignViewport.java b/src/jalview/appletgui/AlignViewport.java index d64cd75..c1de259 100644 --- a/src/jalview/appletgui/AlignViewport.java +++ b/src/jalview/appletgui/AlignViewport.java @@ -77,14 +77,14 @@ public class AlignViewport extends AlignmentViewport } if (widthScale <= 1.0) { - System.err.println( + jalview.bin.Console.errPrintln( "Invalid alignment character width scaling factor (" + widthScale + "). Ignoring."); widthScale = 1; } if (JalviewLite.debug) { - System.err.println( + jalview.bin.Console.errPrintln( "Alignment character width scaling factor is now " + widthScale); } @@ -100,14 +100,14 @@ public class AlignViewport extends AlignmentViewport } if (heightScale <= 1.0) { - System.err.println( + jalview.bin.Console.errPrintln( "Invalid alignment character height scaling factor (" + heightScale + "). Ignoring."); heightScale = 1; } if (JalviewLite.debug) { - System.err.println( + jalview.bin.Console.errPrintln( "Alignment character height scaling factor is now " + heightScale); } diff --git a/src/jalview/appletgui/AlignmentPanel.java b/src/jalview/appletgui/AlignmentPanel.java index fd75296..71ddcef 100644 --- a/src/jalview/appletgui/AlignmentPanel.java +++ b/src/jalview/appletgui/AlignmentPanel.java @@ -363,7 +363,7 @@ public class AlignmentPanel extends Panel { if (JalviewLite.debug) {// DEBUG - System.out.println( + jalview.bin.Console.outPrintln( "DEBUG: scroll didn't happen - results not within alignment : " + seq.getStart() + "," + seq.getEnd()); } @@ -373,7 +373,7 @@ public class AlignmentPanel extends Panel { // DEBUG /* - * System.out.println("DEBUG: scroll: start=" + r[0] + + * jalview.bin.Console.outPrintln("DEBUG: scroll: start=" + r[0] + * " av.getStartRes()=" + av.getStartRes() + " end=" + r[1] + * " seq.end=" + seq.getEnd() + " av.getEndRes()=" + av.getEndRes() + * " hextent=" + hextent); @@ -555,7 +555,7 @@ public class AlignmentPanel extends Panel // this is called after loading new annotation onto alignment if (alignFrame.getSize().height == 0) { - System.out.println( + jalview.bin.Console.outPrintln( "adjustAnnotationHeight frame size zero NEEDS FIXING"); } fontChanged(); @@ -693,7 +693,7 @@ public class AlignmentPanel extends Panel if ((hextent + x) > width) { - System.err.println("hextent was " + hextent + " and x was " + x); + jalview.bin.Console.errPrintln("hextent was " + hextent + " and x was " + x); x = width - hextent; } @@ -710,7 +710,7 @@ public class AlignmentPanel extends Panel if (x < 0) { - System.err.println("x was " + x); + jalview.bin.Console.errPrintln("x was " + x); x = 0; } @@ -1111,7 +1111,7 @@ public class AlignmentPanel extends Panel public void raiseOOMWarning(String string, OutOfMemoryError error) { // TODO: JAL-960 - System.err.println("Out of memory whilst '" + string + "'"); + jalview.bin.Console.errPrintln("Out of memory whilst '" + string + "'"); error.printStackTrace(); } diff --git a/src/jalview/appletgui/AppletJmol.java b/src/jalview/appletgui/AppletJmol.java index b0722c0..cca9aff 100644 --- a/src/jalview/appletgui/AppletJmol.java +++ b/src/jalview/appletgui/AppletJmol.java @@ -275,7 +275,7 @@ public class AppletJmol extends EmbmenuFrame implements "-applet", scriptWindow, null); } catch (Exception e) { - System.err.println( + jalview.bin.Console.errPrintln( "Couldn't create a jmol viewer. Args to allocate viewer were:\nDocumentBase=" + ap.av.applet.getDocumentBase() + "\nCodebase=" + ap.av.applet.getCodeBase()); @@ -320,7 +320,7 @@ public class AppletJmol extends EmbmenuFrame implements { if (jalview.bin.JalviewLite.debug) { - System.err.println( + jalview.bin.Console.errPrintln( "AppletJmol:Trying to reuse existing PDBfile IO parser."); } // re-use the one we opened earlier @@ -330,7 +330,7 @@ public class AppletJmol extends EmbmenuFrame implements { if (jalview.bin.JalviewLite.debug) { - System.err.println( + jalview.bin.Console.errPrintln( "AppletJmol:Creating new PDBfile IO parser."); } FileParse fp = new FileParse(pdbentry.getFile(), protocol); @@ -355,7 +355,7 @@ public class AppletJmol extends EmbmenuFrame implements } catch (Exception e) { // give up! - System.err.println("Couldn't access pdbentry id=" + jalview.bin.Console.errPrintln("Couldn't access pdbentry id=" + pdbentry.getId() + " and file=" + pdbentry.getFile() + " using protocol=" + protocol); e.printStackTrace(); @@ -433,7 +433,7 @@ public class AppletJmol extends EmbmenuFrame implements } catch (OutOfMemoryError ex) { frame.dispose(); - System.err.println( + jalview.bin.Console.errPrintln( "Out of memory when trying to create dialog box with sequence-structure mapping."); return; } diff --git a/src/jalview/appletgui/ExtJmol.java b/src/jalview/appletgui/ExtJmol.java index 47f9df0..e2b8f23 100644 --- a/src/jalview/appletgui/ExtJmol.java +++ b/src/jalview/appletgui/ExtJmol.java @@ -154,7 +154,7 @@ public class ExtJmol extends JalviewJmolBinding { // This never gets called because we haven't overriden the associated Jmol's // console - System.err.println( + jalview.bin.Console.errPrintln( "WARNING: unexpected call to ExtJmol's showConsole method. (showConsole=" + show); } diff --git a/src/jalview/appletgui/PCAPanel.java b/src/jalview/appletgui/PCAPanel.java index 7c0dfa9..7730210 100644 --- a/src/jalview/appletgui/PCAPanel.java +++ b/src/jalview/appletgui/PCAPanel.java @@ -145,7 +145,7 @@ public class PCAPanel extends EmbmenuFrame top = pcaModel.getTop(); } catch (OutOfMemoryError x) { - System.err.println("Out of memory when calculating PCA."); + jalview.bin.Console.errPrintln("Out of memory when calculating PCA."); return; } calcSettings.setEnabled(true); diff --git a/src/jalview/appletgui/PairwiseAlignPanel.java b/src/jalview/appletgui/PairwiseAlignPanel.java index bc775c6..566aad9 100644 --- a/src/jalview/appletgui/PairwiseAlignPanel.java +++ b/src/jalview/appletgui/PairwiseAlignPanel.java @@ -102,7 +102,7 @@ public class PairwiseAlignPanel extends Panel implements ActionListener if (count > 2) { - System.out.println( + jalview.bin.Console.outPrintln( "Pairwise alignment scaled similarity score matrix\n"); for (int i = 0; i < count; i++) @@ -111,7 +111,7 @@ public class PairwiseAlignPanel extends Panel implements ActionListener ("" + i) + " " + seqs[i].getName()); } - System.out.println("\n"); + jalview.bin.Console.outPrintln("\n"); for (int i = 0; i < count; i++) { @@ -122,7 +122,7 @@ public class PairwiseAlignPanel extends Panel implements ActionListener } } - System.out.println("\n"); + jalview.bin.Console.outPrintln("\n"); } } diff --git a/src/jalview/appletgui/RedundancyPanel.java b/src/jalview/appletgui/RedundancyPanel.java index bd36b0d..a5b652f 100644 --- a/src/jalview/appletgui/RedundancyPanel.java +++ b/src/jalview/appletgui/RedundancyPanel.java @@ -148,7 +148,7 @@ public class RedundancyPanel extends SliderPanel validate(); sliderValueChanged(); - // System.out.println("blob done "+ (System.currentTimeMillis()-start)); + // jalview.bin.Console.outPrintln("blob done "+ (System.currentTimeMillis()-start)); } void sliderValueChanged() diff --git a/src/jalview/appletgui/RotatableCanvas.java b/src/jalview/appletgui/RotatableCanvas.java index a870ca4..87266b4 100755 --- a/src/jalview/appletgui/RotatableCanvas.java +++ b/src/jalview/appletgui/RotatableCanvas.java @@ -145,7 +145,7 @@ public class RotatableCanvas extends Panel implements MouseListener, scale = findScale(); - // System.out.println("Scale factor = " + scale); + // jalview.bin.Console.outPrintln("Scale factor = " + scale); addMouseListener(this); addKeyListener(this); @@ -301,7 +301,7 @@ public class RotatableCanvas extends Panel implements MouseListener, scale = findScale(); - // System.out.println("New scale = " + scale); + // jalview.bin.Console.outPrintln("New scale = " + scale); img = createImage(getSize().width, getSize().height); ig = img.getGraphics(); @@ -427,7 +427,7 @@ public class RotatableCanvas extends Panel implements MouseListener, } else if (evt.getKeyChar() == 's') { - System.err.println("DEBUG: Rectangle selection"); // log.debug + jalview.bin.Console.errPrintln("DEBUG: Rectangle selection"); // log.debug if (rectx2 != -1 && recty2 != -1) { rectSelect(rectx1, recty1, rectx2, recty2); diff --git a/src/jalview/appletgui/SeqCanvas.java b/src/jalview/appletgui/SeqCanvas.java index 3b79f12..735046e 100755 --- a/src/jalview/appletgui/SeqCanvas.java +++ b/src/jalview/appletgui/SeqCanvas.java @@ -644,7 +644,9 @@ public class SeqCanvas extends Panel implements ViewportListenerI if (av.cursorMode && cursorY == i && cursorX >= startRes && cursorX <= endRes) { - sr.drawCursor(nextSeq, cursorX, (cursorX - startRes) * avcharWidth, + char s = nextSeq.getCharAt(cursorX); + + sr.drawCursor(g,s, (cursorX - startRes) * avcharWidth, offset + ((i - startSeq) * avcharHeight)); } } diff --git a/src/jalview/appletgui/SeqPanel.java b/src/jalview/appletgui/SeqPanel.java index 70366e4..c573612 100644 --- a/src/jalview/appletgui/SeqPanel.java +++ b/src/jalview/appletgui/SeqPanel.java @@ -772,7 +772,7 @@ public class SeqPanel extends Panel implements MouseMotionListener, @Override public void updateColours(SequenceI seq, int index) { - System.out.println("update the seqPanel colours"); + jalview.bin.Console.outPrintln("update the seqPanel colours"); // repaint(); } @@ -1817,7 +1817,7 @@ public class SeqPanel extends Panel implements MouseMotionListener, { if (av.getAlignment() == null) { - System.out.println("Selection message: alignviewport av SeqSetId=" + jalview.bin.Console.outPrintln("Selection message: alignviewport av SeqSetId=" + av.getSequenceSetId() + " ViewId=" + av.getViewId() + " 's alignment is NULL! returning immediatly."); return; @@ -1869,7 +1869,7 @@ public class SeqPanel extends Panel implements MouseMotionListener, if (copycolsel && av.hasHiddenColumns() && (av.getColumnSelection() == null)) { - System.err.println("Bad things"); + jalview.bin.Console.errPrintln("Bad things"); } if (repaint) { diff --git a/src/jalview/appletgui/SequenceRenderer.java b/src/jalview/appletgui/SequenceRenderer.java index eab6e39..34ad217 100755 --- a/src/jalview/appletgui/SequenceRenderer.java +++ b/src/jalview/appletgui/SequenceRenderer.java @@ -353,7 +353,7 @@ public class SequenceRenderer implements jalview.api.SequenceRenderer } } - public void drawCursor(SequenceI seq, int res, int x1, int y1) + public void drawCursor(Graphics graphics, char s, int x1, int y1) { int pady = av.getCharHeight() / 5; int charOffset = 0; @@ -363,7 +363,6 @@ public class SequenceRenderer implements jalview.api.SequenceRenderer graphics.setColor(Color.white); - char s = seq.getCharAt(res); if (av.validCharWidth) { diff --git a/src/jalview/appletgui/TreePanel.java b/src/jalview/appletgui/TreePanel.java index 671fee1..0316e0b 100644 --- a/src/jalview/appletgui/TreePanel.java +++ b/src/jalview/appletgui/TreePanel.java @@ -166,7 +166,7 @@ public class TreePanel extends EmbmenuFrame } else { - System.out.println("Original Tree Data not available"); + jalview.bin.Console.outPrintln("Original Tree Data not available"); } } diff --git a/src/jalview/bin/Cache.java b/src/jalview/bin/Cache.java index 5741908..483b1fc 100755 --- a/src/jalview/bin/Cache.java +++ b/src/jalview/bin/Cache.java @@ -54,6 +54,8 @@ import javax.swing.LookAndFeel; import javax.swing.UIManager; import jalview.analytics.Plausible; +import jalview.bin.argparser.Arg; +import jalview.bin.argparser.ArgParser; import jalview.datamodel.PDBEntry; import jalview.gui.Preferences; import jalview.gui.UserDefinedColours; @@ -141,6 +143,10 @@ import jalview.ws.sifts.SiftsSettings; *
    • WRAP_ALIGNMENT
    • *
    • EPS_RENDERING (Prompt each time|Lineart|Text) default for EPS rendering * style check
    • + *
    • BITMAP_SCALE - scale factor for PNG export - default 0.0 - native + * resolution
    • + *
    • BITMAP_HEIGHT - height bound for PNG export or 0 for unbound
    • + *
    • BITMAP_WIDTH - width bound for PNG export or 0 for unbound
    • *
    • SORT_ALIGNMENT (No sort|Id|Pairwise Identity)
    • *
    • SEQUENCE_LINKS list of name|URL pairs for opening a url with * $SEQUENCE_ID$
    • @@ -407,9 +413,9 @@ public class Cache fis = new URL(propertiesFile).openStream(); if (!Jalview.quiet()) { - System.out.println( + jalview.bin.Console.outPrintln( "Loading jalview properties from : " + propertiesFile); - System.out.println( + jalview.bin.Console.outPrintln( "Disabling Jalview writing to user's local properties file."); } propsAreReadOnly = true; @@ -440,7 +446,8 @@ public class Cache } catch (Exception ex) { if (!Jalview.quiet()) - System.out.println("Error reading properties file: " + ex); + jalview.bin.Console + .outPrintln("Error reading properties file: " + ex); } } @@ -497,7 +504,8 @@ public class Cache } catch (Exception ex) { if (!Jalview.quiet()) - System.out.println("Error reading author details: " + ex); + jalview.bin.Console + .outPrintln("Error reading author details: " + ex); authorDetails = null; } if (authorDetails == null) @@ -583,10 +591,10 @@ public class Cache { if (!Jalview.quiet()) { - System.out.println( + jalview.bin.Console.errPrintln( "Non-fatal exception when checking version at " + remoteBuildPropertiesUrl + ":"); - System.out.println(ex); + jalview.bin.Console.printStackTrace(ex); } remoteVersion = getProperty("VERSION"); } @@ -636,8 +644,8 @@ public class Cache url = Cache.class.getResource(resourcePath).toString(); } catch (Exception ex) { - System.err.println("Failed to resolve resource " + resourcePath - + ": " + ex.getMessage()); + jalview.bin.Console.errPrintln("Failed to resolve resource " + + resourcePath + ": " + ex.getMessage()); } } else @@ -687,7 +695,8 @@ public class Cache } catch (Exception ex) { if (!Jalview.quiet()) - System.out.println("Error reading build details: " + ex); + jalview.bin.Console + .outPrintln("Error reading build details: " + ex); applicationProperties.remove("VERSION"); } String codeVersion = getProperty("VERSION"); @@ -707,8 +716,9 @@ public class Cache new BuildDetails(codeVersion, null, codeInstallation); if (printVersion && reportVersion) { - System.out.println(ChannelProperties.getProperty("app_name") - + " version: " + codeVersion + codeInstallation); + jalview.bin.Console + .outPrintln(ChannelProperties.getProperty("app_name") + + " version: " + codeVersion + codeInstallation); } } @@ -784,8 +794,27 @@ public class Cache } catch (NumberFormatException e) { if (!Jalview.quiet()) - System.out.println("Error parsing int property '" + property - + "' with value '" + string + "'"); + jalview.bin.Console.errPrintln("Error parsing int property '" + + property + "' with value '" + string + "'"); + } + } + + return def; + } + + public static float getDefault(String property, float def) + { + String string = getProperty(property); + if (string != null) + { + try + { + def = Float.parseFloat(string); + } catch (NumberFormatException e) + { + if (!Jalview.quiet()) + jalview.bin.Console.errPrintln("Error parsing float property '" + + property + "' with value '" + string + "'"); } } @@ -835,7 +864,7 @@ public class Cache } catch (Exception ex) { if (!Jalview.quiet()) - System.out.println( + jalview.bin.Console.errPrintln( "Error setting property: " + key + " " + obj + "\n" + ex); } return oldValue; @@ -867,7 +896,7 @@ public class Cache } catch (Exception ex) { if (!Jalview.quiet()) - System.out.println("Error saving properties: " + ex); + jalview.bin.Console.errPrintln("Error saving properties: " + ex); } } } @@ -1057,8 +1086,9 @@ public class Cache return date_format.parse(val); } catch (Exception ex) { - System.err.println("Invalid or corrupt date in property '" - + propertyName + "' : value was '" + val + "'"); + jalview.bin.Console + .errPrintln("Invalid or corrupt date in property '" + + propertyName + "' : value was '" + val + "'"); } } return null; @@ -1081,8 +1111,8 @@ public class Cache return Integer.valueOf(val); } catch (NumberFormatException x) { - System.err.println("Invalid integer in property '" + property - + "' (value was '" + val + "')"); + jalview.bin.Console.errPrintln("Invalid integer in property '" + + property + "' (value was '" + val + "')"); } } return null; @@ -1146,7 +1176,8 @@ public class Cache } catch (Exception ex) { if (!Jalview.quiet()) - System.out.println("Error loading User ColourFile\n" + ex); + jalview.bin.Console + .outPrintln("Error loading User ColourFile\n" + ex); } } if (!files.equals(coloursFound.toString())) @@ -1634,26 +1665,36 @@ public class Cache } if (file == null || !file.exists()) { + if (file != null) + { + jalview.bin.Console + .errPrintln("Could not load bootstrap preferences file '" + + file.getPath() + "'"); + } String channelPrefsFilename = ChannelProperties .getProperty("preferences.filename"); String propertiesFilename = System.getProperty("user.home") + File.separatorChar + channelPrefsFilename; + jalview.bin.Console.errPrintln( + "Using default properties file '" + propertiesFilename + "'"); file = new File(propertiesFilename); } if (file == null || !file.exists()) + { String releasePrefsFilename = fallbackPropertiesFile; String releasePropertiesFilename = System.getProperty("user.home") + File.separatorChar + releasePrefsFilename; + jalview.bin.Console.errPrintln("Falling back to properties file '" + + releasePropertiesFilename + "'"); file = new File(releasePropertiesFilename); } - if (filename == null) - return null; if (!file.exists()) { - System.err.println("Could not load bootstrap preferences file '" - + filename + "'"); + jalview.bin.Console + .errPrintln("Could not load bootstrap preferences file '" + + file.getPath() + "'"); return null; } @@ -1669,11 +1710,12 @@ public class Cache } } catch (FileNotFoundException e) { - System.err.println("Could not find bootstrap preferences file '" - + file.getAbsolutePath() + "'"); + jalview.bin.Console + .errPrintln("Could not find bootstrap preferences file '" + + file.getAbsolutePath() + "'"); } catch (IOException e) { - System.err.println( + jalview.bin.Console.errPrintln( "IOException when loading bootstrap preferences file '" + file.getAbsolutePath() + "'"); } @@ -1692,4 +1734,10 @@ public class Cache { return key == null ? null : sessionProperties.get(key); } + + public static boolean getArgCacheDefault(Arg a, String pref, boolean def) + { + ArgParser ap = Jalview.getInstance().getArgParser(); + return ap.isSet(a) ? ap.getBoolean(a) : getDefault(pref, def); + } } diff --git a/src/jalview/bin/Commands.java b/src/jalview/bin/Commands.java index dbc4953..a092cd6 100644 --- a/src/jalview/bin/Commands.java +++ b/src/jalview/bin/Commands.java @@ -1,23 +1,25 @@ package jalview.bin; +import java.awt.Color; import java.io.File; import java.io.IOException; import java.net.URISyntaxException; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; -import java.util.EnumSet; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Locale; import java.util.Map; +import javax.swing.SwingUtilities; + import jalview.analysis.AlignmentUtils; import jalview.api.structures.JalviewStructureDisplayI; +import jalview.bin.Jalview.ExitCode; import jalview.bin.argparser.Arg; import jalview.bin.argparser.ArgParser; -import jalview.bin.argparser.ArgParser.Position; import jalview.bin.argparser.ArgValue; import jalview.bin.argparser.ArgValuesMap; import jalview.bin.argparser.SubVals; @@ -47,14 +49,17 @@ import jalview.io.NewickFile; import jalview.io.exceptions.ImageOutputException; import jalview.schemes.ColourSchemeI; import jalview.schemes.ColourSchemeProperty; +import jalview.structure.StructureCommandI; import jalview.structure.StructureImportSettings.TFType; import jalview.structure.StructureSelectionManager; +import jalview.util.ColorUtils; import jalview.util.FileUtils; import jalview.util.HttpUtils; import jalview.util.ImageMaker; import jalview.util.ImageMaker.TYPE; import jalview.util.MessageManager; import jalview.util.Platform; +import jalview.util.StringUtils; import jalview.util.imagemaker.BitmapImageSizing; public class Commands @@ -67,10 +72,14 @@ public class Commands private Map afMap; + private Map> svMap; + private boolean commandArgsProvided = false; private boolean argsWereParsed = false; + private List errors = new ArrayList<>(); + public Commands(ArgParser argparser, boolean headless) { this(Desktop.instance, argparser, headless); @@ -82,16 +91,15 @@ public class Commands headless = h; desktop = d; afMap = new HashMap<>(); - if (argparser != null) - { - processArgs(argparser, headless); - } } - private boolean processArgs(ArgParser argparser, boolean h) + protected boolean processArgs() { - argParser = argparser; - headless = h; + if (argParser == null) + { + return true; + } + boolean theseArgsWereParsed = false; if (argParser != null && argParser.getLinkedIds() != null) @@ -100,9 +108,10 @@ public class Commands { ArgValuesMap avm = argParser.getLinkedArgs(id); theseArgsWereParsed = true; - theseArgsWereParsed &= processLinked(id); + boolean processLinkedOkay = processLinked(id); + theseArgsWereParsed &= processLinkedOkay; + processGroovyScript(id); - boolean processLinkedOkay = theseArgsWereParsed; // wait around until alignFrame isn't busy AlignFrame af = afMap.get(id); @@ -118,8 +127,11 @@ public class Commands } theseArgsWereParsed &= processImages(id); + if (processLinkedOkay) + { theseArgsWereParsed &= processOutput(id); + } // close ap if (avm.getBoolean(Arg.CLOSE)) @@ -134,9 +146,22 @@ public class Commands } } + + // report errors - if any + String errorsRaised = errorsToString(); + if (errorsRaised.trim().length() > 0) + { + Console.warn( + "The following errors and warnings occurred whilst processing files:\n" + + errorsRaised); + } + // gui errors reported in Jalview + if (argParser.getBoolean(Arg.QUIT)) { - Jalview.getInstance().quit(); + Jalview.getInstance().exit( + "Exiting due to " + Arg.QUIT.argString() + " argument.", + ExitCode.OK); return true; } // carry on with jalview.bin.Jalview @@ -154,25 +179,20 @@ public class Commands return argsWereParsed; } - protected boolean processUnlinked(String id) - { - return processLinked(id); - } - protected boolean processLinked(String id) { boolean theseArgsWereParsed = false; ArgValuesMap avm = argParser.getLinkedArgs(id); if (avm == null) + { return true; + } + + Boolean isError = Boolean.valueOf(false); + + // set wrap scope here so it can be applied after structures are opened + boolean wrap = false; - /* - * // script to execute after all loading is completed one way or another String - * groovyscript = m.get(Arg.GROOVY) == null ? null : - * m.get(Arg.GROOVY).getValue(); String file = m.get(Arg.OPEN) == null ? null : - * m.get(Arg.OPEN).getValue(); String data = null; FileFormatI format = null; - * DataSourceType protocol = null; - */ if (avm.containsArg(Arg.APPEND) || avm.containsArg(Arg.OPEN)) { commandArgsProvided = true; @@ -221,7 +241,9 @@ public class Commands { if (!(new File(openFile)).exists()) { - Console.warn("Can't find file '" + openFile + "'"); + addError("Can't find file '" + openFile + "'"); + isError = true; + continue; } } } @@ -235,7 +257,9 @@ public class Commands format = new IdentifyFile().identify(openFile, protocol); } catch (FileFormatException e1) { - Console.error("Unknown file format for '" + openFile + "'"); + addError("Unknown file format for '" + openFile + "'"); + isError = true; + continue; } af = afMap.get(id); @@ -252,39 +276,37 @@ public class Commands Console.debug( "Opening '" + openFile + "' in new alignment frame"); FileLoader fileLoader = new FileLoader(!headless); - - af = fileLoader.LoadFileWaitTillLoaded(openFile, protocol, - format); - - // wrap alignment? - boolean wrap = ArgParser.getFromSubValArgOrPref(avm, Arg.WRAP, sv, - null, "WRAP_ALIGNMENT", false); - af.getCurrentView().setWrapAlignment(wrap); - - // colour alignment? - String colour = ArgParser.getFromSubValArgOrPref(avm, av, - Arg.COLOUR, sv, null, "DEFAULT_COLOUR_PROT", ""); - if ("" != colour) + boolean xception = false; + try { - ColourSchemeI cs = ColourSchemeProperty.getColourScheme( - af.getViewport(), af.getViewport().getAlignment(), - colour); - - if (cs == null && !"None".equals(colour)) - { - Console.warn( - "Couldn't parse '" + colour + "' as a colourscheme."); - } - else + af = fileLoader.LoadFileWaitTillLoaded(openFile, protocol, + format); + } catch (Throwable thr) + { + xception = true; + addError("Couldn't open '" + openFile + "' as " + format + " " + + thr.getLocalizedMessage() + + " (Enable debug for full stack trace)"); + isError = true; + Console.debug("Exception when opening '" + openFile + "'", thr); + } finally + { + if (af == null && !xception) { - af.changeColour(cs); + addInfo("Ignoring '" + openFile + + "' - no alignment data found."); + continue; } - Jalview.testoutput(argParser, Arg.COLOUR, "zappo", colour); } + // colour alignment + String colour = avm.getFromSubValArgOrPref(av, Arg.COLOUR, sv, + null, "DEFAULT_COLOUR_PROT", ""); + this.colourAlignFrame(af, colour); + // Change alignment frame title - String title = ArgParser.getFromSubValArgOrPref(avm, av, - Arg.TITLE, sv, null, null, null); + String title = avm.getFromSubValArgOrPref(av, Arg.TITLE, sv, null, + null, null); if (title != null) { af.setTitle(title); @@ -292,7 +314,7 @@ public class Commands } // Add features - String featuresfile = ArgParser.getValueFromSubValOrArg(avm, av, + String featuresfile = avm.getValueFromSubValOrArg(av, Arg.FEATURES, sv); if (featuresfile != null) { @@ -303,8 +325,8 @@ public class Commands } // Add annotations from file - String annotationsfile = ArgParser.getValueFromSubValOrArg(avm, - av, Arg.ANNOTATIONS, sv); + String annotationsfile = avm.getValueFromSubValOrArg(av, + Arg.ANNOTATIONS, sv); if (annotationsfile != null) { af.loadJalviewDataFile(annotationsfile, null, null, null); @@ -314,8 +336,8 @@ public class Commands } // Set or clear the sortbytree flag - boolean sortbytree = ArgParser.getBoolFromSubValOrArg(avm, - Arg.SORTBYTREE, sv); + boolean sortbytree = avm.getBoolFromSubValOrArg(Arg.SORTBYTREE, + sv); if (sortbytree) { af.getViewport().setSortByTree(true); @@ -323,8 +345,7 @@ public class Commands } // Load tree from file - String treefile = ArgParser.getValueFromSubValOrArg(avm, av, - Arg.TREE, sv); + String treefile = avm.getValueFromSubValOrArg(av, Arg.TREE, sv); if (treefile != null) { try @@ -337,34 +358,64 @@ public class Commands "examples/testdata/uniref50_test_tree", treefile); } catch (IOException e) { - Console.warn("Couldn't add tree " + treefile, e); + addError("Couldn't add tree " + treefile, e); + isError = true; } } + // Show secondary structure annotations? - boolean showSSAnnotations = ArgParser.getFromSubValArgOrPref(avm, + boolean showSSAnnotations = avm.getFromSubValArgOrPref( Arg.SHOWSSANNOTATIONS, av.getSubVals(), null, "STRUCT_FROM_PDB", true); - af.setAnnotationsVisibility(showSSAnnotations, true, false); - + // Show sequence annotations? - boolean showAnnotations = ArgParser.getFromSubValArgOrPref(avm, + boolean showAnnotations = avm.getFromSubValArgOrPref( Arg.SHOWANNOTATIONS, av.getSubVals(), null, "SHOW_ANNOTATIONS", true); - af.setAnnotationsVisibility(showAnnotations, false, true); + + boolean hideTFrows = (avm.getBoolean(Arg.NOTEMPFAC)); + final AlignFrame _af = af; + // many of jalview's format/layout methods are only thread safe on the swingworker thread. + // all these methods should be on the alignViewController so it can coordinate such details + try + { + SwingUtilities.invokeAndWait(new Runnable() + { + @Override + public void run() + { + _af.setAnnotationsVisibility(showSSAnnotations, true, + false); + + _af.setAnnotationsVisibility(showAnnotations, false, true); - // show temperature factor annotations? - if (avm.getBoolean(Arg.NOTEMPFAC)) + // show temperature factor annotations? + if (hideTFrows) + { + // do this better (annotation types?) + List hideThese = new ArrayList<>(); + hideThese.add("Temperature Factor"); + hideThese.add(AlphaFoldAnnotationRowBuilder.LABEL); + AlignmentUtils.showOrHideSequenceAnnotations( + _af.getCurrentView().getAlignment(), hideThese, + null, false, false); + } + } + }); + } catch (Exception x) { - // do this better (annotation types?) - List hideThese = new ArrayList<>(); - hideThese.add("Temperature Factor"); - hideThese.add(AlphaFoldAnnotationRowBuilder.LABEL); - AlignmentUtils.showOrHideSequenceAnnotations( - af.getCurrentView().getAlignment(), hideThese, null, - false, false); + Console.warn( + "Unexpected exception adjusting annotation row visibility.", + x); } + // wrap alignment? do this last for formatting reasons + wrap = avm.getFromSubValArgOrPref(Arg.WRAP, sv, null, + "WRAP_ALIGNMENT", false); + // af.setWrapFormat(wrap) is applied after structures are opened for + // annotation reasons + // store the AlignFrame for this id afMap.put(id, af); @@ -397,11 +448,12 @@ public class Commands { if (headless) { - Jalview.exit("Could not open any files in headless mode", 1); + Jalview.exit("Could not open any files in headless mode", + ExitCode.NO_FILES); } else { - Console.warn("No more files to open"); + Console.info("No more files to open"); } } if (progressBarSet && desktop != null) @@ -418,8 +470,10 @@ public class Commands commandArgsProvided = true; for (ArgValue av : avm.getArgValueList(Arg.STRUCTURE)) { + argParser.setStructureFilename(null); String val = av.getValue(); SubVals subVals = av.getSubVals(); + int argIndex = av.getArgIndex(); SequenceI seq = getSpecifiedSequence(af, avm, av); if (seq == null) { @@ -431,56 +485,52 @@ public class Commands if (seq == null) { - Console.warn("Could not find sequence for argument " + addWarn("Could not find sequence for argument " + Arg.STRUCTURE.argString() + "=" + val); - // you probably want to continue here, not break - // break; continue; } + String structureFilename = null; File structureFile = null; if (subVals.getContent() != null && subVals.getContent().length() != 0) { - structureFile = new File(subVals.getContent()); + structureFilename = subVals.getContent(); Console.debug("Using structure file (from argument) '" - + structureFile.getAbsolutePath() + "'"); - } - // TRY THIS - /* - * PDBEntry fileEntry = new AssociatePdbFileWithSeq() - * .associatePdbWithSeq(selectedPdbFileName, DataSourceType.FILE, - * selectedSequence, true, Desktop.instance); - * - * sViewer = launchStructureViewer(ssm, new PDBEntry[] { fileEntry }, ap, new - * SequenceI[] { selectedSequence }); - * - */ + + structureFilename + "'"); + structureFile = new File(structureFilename); + } /* THIS DOESN'T WORK */ else if (seq.getAllPDBEntries() != null && seq.getAllPDBEntries().size() > 0) { structureFile = new File( seq.getAllPDBEntries().elementAt(0).getFile()); - Console.debug("Using structure file (from sequence) '" - + structureFile.getAbsolutePath() + "'"); + if (structureFile != null) + { + Console.debug("Using structure file (from sequence) '" + + structureFile.getAbsolutePath() + "'"); + } + structureFilename = structureFile.getAbsolutePath(); } - if (structureFile == null) + if (structureFilename == null || structureFile == null) { - Console.warn("Not provided structure file with '" + val + "'"); + addWarn("Not provided structure file with '" + val + "'"); continue; } if (!structureFile.exists()) { - Console.warn("Structure file '" - + structureFile.getAbsoluteFile() + "' not found."); + addWarn("Structure file '" + structureFile.getAbsoluteFile() + + "' not found."); continue; } Console.debug("Using structure file " + structureFile.getAbsolutePath()); + argParser.setStructureFilename(structureFilename); + // open structure view AlignmentPanel ap = af.alignPanel; if (headless) @@ -492,10 +542,9 @@ public class Commands String structureFilepath = structureFile.getAbsolutePath(); // get PAEMATRIX file and label from subvals or Arg.PAEMATRIX - String paeFilepath = ArgParser - .getFromSubValArgOrPrefWithSubstitutions(argParser, avm, - Arg.PAEMATRIX, Position.AFTER, av, subVals, null, - null, null); + String paeFilepath = avm.getFromSubValArgOrPrefWithSubstitutions( + argParser, Arg.PAEMATRIX, ArgValuesMap.Position.AFTER, av, + subVals, null, null, null); if (paeFilepath != null) { File paeFile = new File(paeFilepath); @@ -506,25 +555,23 @@ public class Commands } catch (IOException e) { paeFilepath = paeFile.getAbsolutePath(); - Console.warn("Problem with the PAE file path: '" + addWarn("Problem with the PAE file path: '" + paeFile.getPath() + "'"); } } // showing annotations from structure file or not - boolean ssFromStructure = ArgParser.getFromSubValArgOrPref(avm, + boolean ssFromStructure = avm.getFromSubValArgOrPref( Arg.SHOWSSANNOTATIONS, subVals, null, "STRUCT_FROM_PDB", true); // get TEMPFAC type from subvals or Arg.TEMPFAC in case user Adds // reference annotations - String tftString = ArgParser - .getFromSubValArgOrPrefWithSubstitutions(argParser, avm, - Arg.TEMPFAC, Position.AFTER, av, subVals, null, - null, null); - boolean notempfac = ArgParser.getFromSubValArgOrPref(avm, - Arg.NOTEMPFAC, subVals, null, "ADD_TEMPFACT_ANN", false, - true); + String tftString = avm.getFromSubValArgOrPrefWithSubstitutions( + argParser, Arg.TEMPFAC, ArgValuesMap.Position.AFTER, av, + subVals, null, null, null); + boolean notempfac = avm.getFromSubValArgOrPref(Arg.NOTEMPFAC, + subVals, null, "ADD_TEMPFACT_ANN", false, true); TFType tft = notempfac ? null : TFType.DEFAULT; if (tftString != null && !notempfac) { @@ -549,146 +596,252 @@ public class Commands if (it.hasNext()) sb.append(", "); } - Console.warn(sb.toString()); + addWarn(sb.toString()); } } - String sViewer = ArgParser.getFromSubValArgOrPref(avm, - Arg.STRUCTUREVIEWER, Position.AFTER, av, subVals, null, - null, "jmol"); - ViewerType viewerType = null; - if (!"none".equals(sViewer)) - { - for (ViewerType v : EnumSet.allOf(ViewerType.class)) - { - String name = v.name().toLowerCase(Locale.ROOT) - .replaceAll(" ", ""); - if (sViewer.equals(name)) - { - viewerType = v; - break; - } - } - } + String sViewerName = avm.getFromSubValArgOrPref( + Arg.STRUCTUREVIEWER, ArgValuesMap.Position.AFTER, av, + subVals, null, null, "jmol"); + ViewerType viewerType = ViewerType.getFromString(sViewerName); // TODO use ssFromStructure - StructureViewer sv = StructureChooser + StructureViewer structureViewer = StructureChooser .openStructureFileForSequence(null, null, ap, seq, false, structureFilepath, tft, paeFilepath, false, ssFromStructure, false, viewerType); - if (sv == null) + if (structureViewer == null) { - Console.error("Failed to import and open structure view."); + if (!StringUtils.equalsIgnoreCase(sViewerName, "none")) + { + addError("Failed to import and open structure view for file '" + + structureFile + "'."); + } continue; } try { long tries = 1000; - while (sv.isBusy() && tries > 0) + while (structureViewer.isBusy() && tries > 0) { Thread.sleep(25); - if (sv.isBusy()) + if (structureViewer.isBusy()) { tries--; Console.debug( "Waiting for viewer for " + structureFilepath); } } - if (tries == 0 && sv.isBusy()) + if (tries == 0 && structureViewer.isBusy()) { - Console.warn( - "Gave up waiting for structure viewer to load. Something may have gone wrong."); + addWarn("Gave up waiting for structure viewer to load file '" + + structureFile + + "'. Something may have gone wrong."); } } catch (Exception x) { - Console.warn("Exception whilst waiting for structure viewer " + addError("Exception whilst waiting for structure viewer " + structureFilepath, x); + isError = true; } + + // add StructureViewer to svMap list + if (svMap == null) + { + svMap = new HashMap<>(); + } + if (svMap.get(id) == null) + { + svMap.put(id, new ArrayList<>()); + } + svMap.get(id).add(structureViewer); + Console.debug( "Successfully opened viewer for " + structureFilepath); - String structureImageFilename = ArgParser.getValueFromSubValOrArg( - avm, av, Arg.STRUCTUREIMAGE, subVals); - if (sv != null && structureImageFilename != null) - { - ArgValue siAv = avm.getClosestNextArgValueOfArg(av, - Arg.STRUCTUREIMAGE); - SubVals sisv = null; - if (structureImageFilename.equals(siAv.getValue())) - { - sisv = siAv.getSubVals(); - } - File structureImageFile = new File(structureImageFilename); - String width = ArgParser.getValueFromSubValOrArg(avm, av, - Arg.STRUCTUREIMAGEWIDTH, sisv); - String height = ArgParser.getValueFromSubValOrArg(avm, av, - Arg.STRUCTUREIMAGEHEIGHT, sisv); - String scale = ArgParser.getValueFromSubValOrArg(avm, av, - Arg.STRUCTUREIMAGESCALE, sisv); - String renderer = ArgParser.getValueFromSubValOrArg(avm, av, - Arg.STRUCTUREIMAGETEXTRENDERER, sisv); - String typeS = ArgParser.getValueFromSubValOrArg(avm, av, - Arg.STRUCTUREIMAGETYPE, sisv); - if (typeS == null || typeS.length() == 0) - { - typeS = FileUtils.getExtension(structureImageFile); - } - TYPE imageType; - try - { - imageType = Enum.valueOf(TYPE.class, - typeS.toUpperCase(Locale.ROOT)); - } catch (IllegalArgumentException e) - { - Console.warn("Do not know image format '" + typeS - + "', using PNG"); - imageType = TYPE.PNG; - } - BitmapImageSizing userBis = ImageMaker - .parseScaleWidthHeightStrings(scale, width, height); - // TODO MAKE THIS VIEWER INDEPENDENT!! - switch (StructureViewer.getViewerType()) + + if (avm.containsArg(Arg.STRUCTUREIMAGE)) + { + for (ArgValue structureImageArgValue : avm + .getArgValueList(Arg.STRUCTUREIMAGE)) { - case JMOL: - try - { - Thread.sleep(1000); // WHY ??? - } catch (InterruptedException e) + String structureImageFilename = argParser.makeSubstitutions( + structureImageArgValue.getValue(), id, true); + if (structureViewer != null && structureImageFilename != null) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - JalviewStructureDisplayI sview = sv - .getJalviewStructureDisplay(); - if (sview instanceof AppJmol) - { - AppJmol jmol = (AppJmol) sview; + SubVals structureImageSubVals = null; + structureImageSubVals = structureImageArgValue.getSubVals(); + File structureImageFile = new File(structureImageFilename); + String width = avm.getValueFromSubValOrArg( + structureImageArgValue, Arg.WIDTH, + structureImageSubVals); + String height = avm.getValueFromSubValOrArg( + structureImageArgValue, Arg.HEIGHT, + structureImageSubVals); + String scale = avm.getValueFromSubValOrArg( + structureImageArgValue, Arg.SCALE, + structureImageSubVals); + String renderer = avm.getValueFromSubValOrArg( + structureImageArgValue, Arg.TEXTRENDERER, + structureImageSubVals); + String typeS = avm.getValueFromSubValOrArg( + structureImageArgValue, Arg.TYPE, + structureImageSubVals); + if (typeS == null || typeS.length() == 0) + { + typeS = FileUtils.getExtension(structureImageFile); + } + TYPE imageType; + try + { + imageType = Enum.valueOf(TYPE.class, + typeS.toUpperCase(Locale.ROOT)); + } catch (IllegalArgumentException e) + { + addWarn("Do not know image format '" + typeS + + "', using PNG"); + imageType = TYPE.PNG; + } + BitmapImageSizing userBis = ImageMaker + .parseScaleWidthHeightStrings(scale, width, height); + + ///// + // DON'T TRY TO EXPORT IF VIEWER IS UNSUPPORTED + if (viewerType != ViewerType.JMOL) + { + addWarn("Cannot export image for structure viewer " + + viewerType.name() + " yet"); + continue; + } + + ///// + // Apply the temporary colourscheme to the linked alignment + // TODO: enhance for multiple linked alignments. + + String imageColour = avm.getValueFromSubValOrArg( + structureImageArgValue, Arg.IMAGECOLOUR, + structureImageSubVals); + ColourSchemeI originalColourScheme = this + .getColourScheme(af); + this.colourAlignFrame(af, imageColour); + + ///// + // custom image background colour + + String bgcolourstring = avm.getValueFromSubValOrArg( + structureImageArgValue, Arg.BGCOLOUR, + structureImageSubVals); + Color bgcolour = null; + if (bgcolourstring != null && bgcolourstring.length() > 0) + { + bgcolour = ColorUtils.parseColourString(bgcolourstring); + if (bgcolour == null) + { + Console.warn( + "Background colour string '" + bgcolourstring + + "' not recognised -- using default"); + } + } + + JalviewStructureDisplayI sview = structureViewer + .getJalviewStructureDisplay(); + + File sessionToRestore = null; + + List extraCommands = new ArrayList<>(); + + if (extraCommands.size() > 0 || bgcolour != null) + { + try + { + sessionToRestore = sview.saveSession(); + } catch (Throwable t) + { + Console.warn( + "Unable to save temporary session file before custom structure view export operation."); + } + } + + //// + // Do temporary ops + + if (bgcolour != null) + { + sview.getBinding().setBackgroundColour(bgcolour); + } + + sview.getBinding().executeCommands(extraCommands, false, + "Executing Custom Commands"); + + // and export the view as an image + boolean success = this.checksBeforeWritingToFile(avm, + subVals, false, structureImageFilename, + "structure image", isError); + + if (!success) + { + continue; + } + Console.debug("Rendering image to " + structureImageFile); + // + // TODO - extend StructureViewer / Binding with makePDBImage so + // we can do this with every viewer + // + try { - Console.debug("Rendering image to " + structureImageFile); + // We don't expect class cast exception + AppJmol jmol = (AppJmol) sview; jmol.makePDBImage(structureImageFile, imageType, renderer, userBis); - Console.debug("Finished Rendering image to " + Console.info("Exported structure image to " + structureImageFile); - } catch (ImageOutputException ioexc) + // RESTORE SESSION AFTER EXPORT IF NEED BE + if (sessionToRestore != null) + { + Console.debug( + "Restoring session from " + sessionToRestore); + + sview.getBinding().restoreSession( + sessionToRestore.getAbsolutePath()); + + } + } catch (ImageOutputException ioexec) + { + addError( + "Unexpected error when restoring structure viewer session after custom view operations."); + isError = true; + continue; + } finally { - Console.warn("Unexpected error whilst exporting image to " - + structureImageFile, ioexc); + try + { + this.colourAlignFrame(af, originalColourScheme); + } catch (Exception t) + { + addError( + "Unexpected error when restoring colourscheme to alignment after temporary change for export.", + t); + } } - } - break; - default: - Console.warn("Cannot export image for structure viewer " - + sv.getViewerType() + " yet"); - break; } } + argParser.setStructureFilename(null); } } } + if (wrap) + { + AlignFrame af = afMap.get(id); + if (af != null) + { + af.setWrapFormat(wrap, true); + } + } + /* boolean doShading = avm.getBoolean(Arg.TEMPFAC_SHADING); if (doShading) @@ -706,7 +859,7 @@ public class Commands } */ - return theseArgsWereParsed; + return theseArgsWereParsed && !isError; } protected void processGroovyScript(String id) @@ -714,21 +867,29 @@ public class Commands ArgValuesMap avm = argParser.getLinkedArgs(id); AlignFrame af = afMap.get(id); - if (af == null) + if (avm != null && !avm.containsArg(Arg.GROOVY)) { - Console.warn("Did not have an alignment window for id=" + id); + // nothing to do return; } + if (af == null) + { + addWarn("Groovy script does not have an alignment window. Proceeding with caution!"); + } + if (avm.containsArg(Arg.GROOVY)) { - String groovyscript = avm.getValue(Arg.GROOVY); - if (groovyscript != null) + for (ArgValue groovyAv : avm.getArgValueList(Arg.GROOVY)) { - // Execute the groovy script after we've done all the rendering stuff - // and before any images or figures are generated. - Console.info("Executing script " + groovyscript); - Jalview.getInstance().executeGroovyScript(groovyscript, af); + String groovyscript = groovyAv.getValue(); + if (groovyscript != null) + { + // Execute the groovy script after we've done all the rendering stuff + // and before any images or figures are generated. + Console.info("Executing script " + groovyscript); + Jalview.getInstance().executeGroovyScript(groovyscript, af); + } } } } @@ -738,37 +899,45 @@ public class Commands ArgValuesMap avm = argParser.getLinkedArgs(id); AlignFrame af = afMap.get(id); + if (avm != null && !avm.containsArg(Arg.IMAGE)) + { + // nothing to do + return true; + } + if (af == null) { - Console.warn("Did not have an alignment window for id=" + id); + addWarn("Do not have an alignment window to create image from (id=" + + id + "). Not proceeding."); return false; } + Boolean isError = Boolean.valueOf(false); if (avm.containsArg(Arg.IMAGE)) { - for (ArgValue av : avm.getArgValueList(Arg.IMAGE)) + for (ArgValue imageAv : avm.getArgValueList(Arg.IMAGE)) { - String val = av.getValue(); - SubVals subVal = av.getSubVals(); - String fileName = subVal.getContent(); + String val = imageAv.getValue(); + SubVals imageSubVals = imageAv.getSubVals(); + String fileName = imageSubVals.getContent(); File file = new File(fileName); String name = af.getName(); - String renderer = ArgParser.getValueFromSubValOrArg(avm, av, - Arg.TEXTRENDERER, subVal); + String renderer = avm.getValueFromSubValOrArg(imageAv, + Arg.TEXTRENDERER, imageSubVals); if (renderer == null) renderer = "text"; String type = "png"; // default - String scale = ArgParser.getValueFromSubValOrArg(avm, av, Arg.SCALE, - subVal); - String width = ArgParser.getValueFromSubValOrArg(avm, av, Arg.WIDTH, - subVal); - String height = ArgParser.getValueFromSubValOrArg(avm, av, - Arg.HEIGHT, subVal); + String scale = avm.getValueFromSubValOrArg(imageAv, Arg.SCALE, + imageSubVals); + String width = avm.getValueFromSubValOrArg(imageAv, Arg.WIDTH, + imageSubVals); + String height = avm.getValueFromSubValOrArg(imageAv, Arg.HEIGHT, + imageSubVals); BitmapImageSizing userBis = ImageMaker .parseScaleWidthHeightStrings(scale, width, height); - type = ArgParser.getValueFromSubValOrArg(avm, av, Arg.TYPE, subVal); + type = avm.getValueFromSubValOrArg(imageAv, Arg.TYPE, imageSubVals); if (type == null && fileName != null) { for (String ext : new String[] { "svg", "png", "html", "eps" }) @@ -783,7 +952,20 @@ public class Commands Cache.setPropsAreReadOnly(true); Cache.setProperty("EXPORT_EMBBED_BIOJSON", "false"); + String imageColour = avm.getValueFromSubValOrArg(imageAv, + Arg.IMAGECOLOUR, imageSubVals); + ColourSchemeI originalColourScheme = this.getColourScheme(af); + this.colourAlignFrame(af, imageColour); + Console.info("Writing " + file); + + boolean success = checksBeforeWritingToFile(avm, imageSubVals, + false, fileName, "image", isError); + if (!success) + { + continue; + } + try { switch (type) @@ -831,17 +1013,21 @@ public class Commands break; default: - Console.warn(Arg.IMAGE.argString() + " type '" + type + addWarn(Arg.IMAGE.argString() + " type '" + type + "' not known. Ignoring"); break; } } catch (Exception ioex) { - Console.warn("Unexpected error during export", ioex); + addError("Unexpected error during export to '" + fileName + "'", + ioex); + isError = true; } + + this.colourAlignFrame(af, originalColourScheme); } } - return true; + return !isError; } protected boolean processOutput(String id) @@ -849,12 +1035,21 @@ public class Commands ArgValuesMap avm = argParser.getLinkedArgs(id); AlignFrame af = afMap.get(id); + if (avm != null && !avm.containsArg(Arg.OUTPUT)) + { + // nothing to do + return true; + } + if (af == null) { - Console.warn("Did not have an alignment window for id=" + id); + addWarn("Do not have an alignment window (id=" + id + + "). Not proceeding."); return false; } + Boolean isError = Boolean.valueOf(false); + if (avm.containsArg(Arg.OUTPUT)) { for (ArgValue av : avm.getArgValueList(Arg.OUTPUT)) @@ -862,29 +1057,12 @@ public class Commands String val = av.getValue(); SubVals subVals = av.getSubVals(); String fileName = subVals.getContent(); + boolean stdout = ArgParser.STDOUTFILENAME.equals(fileName); File file = new File(fileName); - boolean overwrite = ArgParser.getFromSubValArgOrPref(avm, - Arg.OVERWRITE, subVals, null, "OVERWRITE_OUTPUT", false); - // backups. Use the Arg.BACKUPS or subval "backups" setting first, - // otherwise if headless assume false, if not headless use the user - // preference with default true. - boolean backups = ArgParser.getFromSubValArgOrPref(avm, Arg.BACKUPS, - subVals, null, - Platform.isHeadless() ? null : BackupFiles.ENABLED, - !Platform.isHeadless()); - - // if backups is not true then --overwrite must be specified - if (file.exists() && !(overwrite || backups)) - { - Console.error("Won't overwrite file '" + fileName + "' without " - + Arg.OVERWRITE.argString() + " or " - + Arg.BACKUPS.argString() + " set"); - return false; - } String name = af.getName(); - String format = ArgParser.getValueFromSubValOrArg(avm, av, - Arg.FORMAT, subVals); + String format = avm.getValueFromSubValOrArg(av, Arg.FORMAT, + subVals); FileFormats ffs = FileFormats.getInstance(); List validFormats = ffs.getWritableFormats(false); @@ -912,59 +1090,68 @@ public class Commands } if (ff == null) { - StringBuilder validSB = new StringBuilder(); - for (String f : validFormats) - { - if (validSB.length() > 0) - validSB.append(", "); - validSB.append(f); - FileFormatI tff = ffs.forName(f); - validSB.append(" ("); - validSB.append(tff.getExtensions()); - validSB.append(")"); - } - - Jalview.exit("No valid format specified for " - + Arg.OUTPUT.argString() + ". Valid formats are " - + validSB.toString() + ".", 1); - // this return really shouldn't happen - return false; + if (stdout) + { + ff = FileFormat.Fasta; + } + else + { + StringBuilder validSB = new StringBuilder(); + for (String f : validFormats) + { + if (validSB.length() > 0) + validSB.append(", "); + validSB.append(f); + FileFormatI tff = ffs.forName(f); + validSB.append(" ("); + validSB.append(tff.getExtensions()); + validSB.append(")"); + } + + addError("No valid format specified for " + + Arg.OUTPUT.argString() + ". Valid formats are " + + validSB.toString() + "."); + continue; + } } - String savedBackupsPreference = Cache - .getDefault(BackupFiles.ENABLED, null); - Console.debug("Setting backups to " + backups); - Cache.applicationProperties.put(BackupFiles.ENABLED, - Boolean.toString(backups)); + boolean success = checksBeforeWritingToFile(avm, subVals, true, + fileName, ff.getName(), isError); + if (!success) + { + continue; + } + + boolean backups = avm.getFromSubValArgOrPref(Arg.BACKUPS, subVals, + null, Platform.isHeadless() ? null : BackupFiles.ENABLED, + !Platform.isHeadless()); Console.info("Writing " + fileName); - af.saveAlignment(fileName, ff); - Console.debug("Returning backups to " + savedBackupsPreference); - if (savedBackupsPreference != null) - Cache.applicationProperties.put(BackupFiles.ENABLED, - savedBackupsPreference); + af.saveAlignment(fileName, ff, stdout, backups); if (af.isSaveAlignmentSuccessful()) { Console.debug("Written alignment '" + name + "' in " - + ff.getName() + " format to " + file); + + ff.getName() + " format to '" + file + "'"); } else { - Console.warn("Error writing file " + file + " in " + ff.getName() + addError("Error writing file '" + file + "' in " + ff.getName() + " format!"); + isError = true; + continue; } } } - return true; + return !isError; } private SequenceI getSpecifiedSequence(AlignFrame af, ArgValuesMap avm, ArgValue av) { SubVals subVals = av.getSubVals(); - ArgValue idAv = avm.getClosestNextArgValueOfArg(av, Arg.SEQID); + ArgValue idAv = avm.getClosestNextArgValueOfArg(av, Arg.SEQID, true); SequenceI seq = null; if (subVals == null && idAv == null) return null; @@ -989,10 +1176,155 @@ public class Commands seq = al.getSequenceAt(subVals.getIndex()); } } - else if (idAv != null) + if (seq == null && idAv != null) { seq = al.findName(idAv.getValue()); } return seq; } + + public AlignFrame[] getAlignFrames() + { + AlignFrame[] afs = null; + if (afMap != null) + { + afs = (AlignFrame[]) afMap.values().toArray(); + } + + return afs; + } + + public List getStructureViewers() + { + List svs = null; + if (svMap != null) + { + for (List svList : svMap.values()) + { + if (svs == null) + { + svs = new ArrayList<>(); + } + svs.addAll(svList); + } + } + return svs; + } + + private void colourAlignFrame(AlignFrame af, String colour) + { + // use string "none" to remove colour scheme + if (colour != null && "" != colour) + { + ColourSchemeI cs = ColourSchemeProperty.getColourScheme( + af.getViewport(), af.getViewport().getAlignment(), colour); + if (cs == null && !StringUtils.equalsIgnoreCase(colour, "none")) + { + addWarn("Couldn't parse '" + colour + "' as a colourscheme."); + } + else + { + Jalview.testoutput(argParser, Arg.COLOUR, "zappo", colour); + colourAlignFrame(af, cs); + } + } + } + + private void colourAlignFrame(AlignFrame af, ColourSchemeI cs) + { + // Note that cs == null removes colour scheme from af + af.changeColour(cs); + } + + private ColourSchemeI getColourScheme(AlignFrame af) + { + return af.getViewport().getGlobalColourScheme(); + } + + private void addInfo(String errorMessage) + { + Console.info(errorMessage); + errors.add(errorMessage); + } + + private void addWarn(String errorMessage) + { + Console.warn(errorMessage); + errors.add(errorMessage); + } + + private void addError(String errorMessage) + { + addError(errorMessage, null); + } + + private void addError(String errorMessage, Exception e) + { + Console.error(errorMessage, e); + errors.add(errorMessage); + } + + private boolean checksBeforeWritingToFile(ArgValuesMap avm, + SubVals subVal, boolean includeBackups, String filename, + String adjective, Boolean isError) + { + File file = new File(filename); + + boolean overwrite = avm.getFromSubValArgOrPref(Arg.OVERWRITE, subVal, + null, "OVERWRITE_OUTPUT", false); + boolean stdout = false; + boolean backups = false; + if (includeBackups) + { + stdout = ArgParser.STDOUTFILENAME.equals(filename); + // backups. Use the Arg.BACKUPS or subval "backups" setting first, + // otherwise if headless assume false, if not headless use the user + // preference with default true. + backups = avm.getFromSubValArgOrPref(Arg.BACKUPS, subVal, null, + Platform.isHeadless() ? null : BackupFiles.ENABLED, + !Platform.isHeadless()); + } + + if (file.exists() && !(overwrite || backups || stdout)) + { + addWarn("Won't overwrite file '" + filename + "' without " + + Arg.OVERWRITE.argString() + + (includeBackups ? " or " + Arg.BACKUPS.argString() : "") + + " set"); + return false; + } + + boolean mkdirs = avm.getFromSubValArgOrPref(Arg.MKDIRS, subVal, null, + "MKDIRS_OUTPUT", false); + + if (!FileUtils.checkParentDir(file, mkdirs)) + { + addError("Directory '" + + FileUtils.getParentDir(file).getAbsolutePath() + + "' does not exist for " + adjective + " file '" + filename + + "'." + + (mkdirs ? "" : " Try using " + Arg.MKDIRS.argString())); + isError = true; + return false; + } + + return true; + } + + public List getErrors() + { + return errors; + } + + public String errorsToString() + { + StringBuilder sb = new StringBuilder(); + for (String error : errors) + { + if (sb.length() > 0) + sb.append("\n"); + sb.append("- " + error); + } + return sb.toString(); + } } diff --git a/src/jalview/bin/Console.java b/src/jalview/bin/Console.java index 30fd530..1bb8162 100644 --- a/src/jalview/bin/Console.java +++ b/src/jalview/bin/Console.java @@ -20,10 +20,9 @@ */ package jalview.bin; -import java.util.Locale; +import java.io.PrintStream; import jalview.log.JLogger; -import jalview.log.JLoggerI; import jalview.log.JLoggerI.LogLevel; import jalview.log.JLoggerLog4j; import jalview.util.ChannelProperties; @@ -43,8 +42,8 @@ public class Console } else { - System.out.println(message); - t.printStackTrace(); + outPrintln(message); + Console.printStackTrace(t); } } @@ -57,7 +56,7 @@ public class Console } else { - System.out.println(message); + outPrintln(message); } } @@ -70,8 +69,8 @@ public class Console } else { - System.out.println(message); - t.printStackTrace(); + outPrintln(message); + Console.printStackTrace(t); } } @@ -83,7 +82,7 @@ public class Console } else { - System.out.println(message); + outPrintln(message); } } @@ -96,8 +95,8 @@ public class Console } else { - System.out.println(message); - t.printStackTrace(); + outPrintln(message); + Console.printStackTrace(t); } } @@ -110,7 +109,7 @@ public class Console } else { - System.out.println(message); + outPrintln(message); } } @@ -123,7 +122,7 @@ public class Console } else { - System.out.println(message); + outPrintln(message); } } @@ -135,8 +134,8 @@ public class Console } else { - System.out.println(message); - t.printStackTrace(); + outPrintln(message); + Console.printStackTrace(t); } } @@ -149,7 +148,7 @@ public class Console } else { - System.err.println(message); + jalview.bin.Console.errPrintln(message); } } @@ -162,8 +161,8 @@ public class Console } else { - System.err.println(message); - t.printStackTrace(System.err); + jalview.bin.Console.errPrintln(message); + Console.printStackTrace(t); } } @@ -176,7 +175,7 @@ public class Console } else { - System.err.println(message); + jalview.bin.Console.errPrintln(message); } } @@ -189,8 +188,8 @@ public class Console } else { - System.err.println(message); - t.printStackTrace(System.err); + jalview.bin.Console.errPrintln(message); + Console.printStackTrace(t); } } @@ -240,7 +239,7 @@ public class Console { JLogger.LogLevel logLevel = JLogger.LogLevel.INFO; - if (JLogger.isLevel(providedLogLevel)) + if (providedLogLevel != null && JLogger.isLevel(providedLogLevel)) { logLevel = Console.getLogLevel(providedLogLevel); } @@ -253,7 +252,7 @@ public class Console { if (!Jalview.quiet()) { - System.err.println( + jalview.bin.Console.errPrintln( "Setting initial log level to " + logLevel.name()); } Log4j.init(logLevel); @@ -267,8 +266,9 @@ public class Console log = JLoggerLog4j.getLogger(Cache.JALVIEW_LOGGER_NAME, logLevel); } catch (NoClassDefFoundError e) { - System.err.println("Could not initialise the logger framework"); - e.printStackTrace(); + jalview.bin.Console + .errPrintln("Could not initialise the logger framework"); + Console.printStackTrace(e); } // Test message @@ -290,22 +290,116 @@ public class Console public static void setLogLevel(String logLevelString) { - for (LogLevel logLevel : JLoggerI.LogLevel.values()) + LogLevel l = null; + try + { + l = LogLevel.valueOf(logLevelString); + } catch (IllegalArgumentException | NullPointerException e1) + { + Console.debug("Invalid log level '" + logLevelString + "'"); + return; + } + if (l != null) { - if (logLevel.toString().toLowerCase(Locale.ROOT) - .equals(logLevelString.toLowerCase(Locale.ROOT))) + log.setLevel(l); + if (!Platform.isJS()) { - log.setLevel(logLevel); - if (!Platform.isJS()) - { - Log4j.init(logLevel); - } - JLoggerLog4j.getLogger("org.apache.axis", logLevel); - break; + Log4j.init(l); } + JLoggerLog4j.getLogger("org.apache.axis", l); + } + } + + public static void outPrint() + { + outPrint(""); + } + + public static void outPrintln() + { + outPrintln(""); + } + + public static void outPrint(Object message) + { + outPrintMessage(message, false, false); + } + + public static void outPrint(Object message, boolean forceStdout) + { + outPrintMessage(message, false, forceStdout); + } + + public static void outPrintln(Object message) + { + outPrintMessage(message, true, false); + } + + public static PrintStream outputStream(boolean forceStdout) + { + // send message to stderr if an output file to stdout is expected + if (!forceStdout && Jalview.getInstance() != null + && Jalview.getInstance().getBootstrapArgs() != null + && Jalview.getInstance().getBootstrapArgs().outputToStdout()) + { + return System.err; + } + else + { + return System.out; + } + } + + public static void outPrintMessage(Object message, boolean newline, + boolean forceStdout) + { + PrintStream ps = outputStream(forceStdout); + if (newline) + { + ps.println(message); } + else + { + ps.print(message); + } + } + + public static void errPrint() + { + errPrint(""); + } + + public static void errPrintln() + { + errPrintln(""); + } + + public static void errPrint(Object message) + { + System.err.print(message); + } + + public static void errPrintln(Object message) + { + System.err.println(message); + } + + public static void debugPrintStackTrace(Throwable t) + { + if (!isDebugEnabled()) + { + return; + } + // send message to stderr if output to stdout is expected + printStackTrace(t); + } + + public static void printStackTrace(Throwable t) + { + // send message to stderr if output to stdout is expected + t.printStackTrace(System.err); } public final static String LOGGING_TEST_MESSAGE = "Logging to STDERR"; -} +} \ No newline at end of file diff --git a/src/jalview/bin/GetMemory.java b/src/jalview/bin/GetMemory.java index b01dfb8..5332704 100644 --- a/src/jalview/bin/GetMemory.java +++ b/src/jalview/bin/GetMemory.java @@ -61,7 +61,7 @@ class GetMemory } catch (NoClassDefFoundError e) { // com.sun.management.OperatingSystemMXBean doesn't exist in this JVM - System.err.println( + jalview.bin.Console.errPrintln( "No com.sun.management.OperatingSystemMXBean: cannot get total physical memory size"); } diff --git a/src/jalview/bin/HiDPISetting.java b/src/jalview/bin/HiDPISetting.java index 2bce673..e14c032 100644 --- a/src/jalview/bin/HiDPISetting.java +++ b/src/jalview/bin/HiDPISetting.java @@ -20,9 +20,8 @@ */ package jalview.bin; -import java.util.Locale; - import java.awt.HeadlessException; +import java.util.Locale; public class HiDPISetting { @@ -117,8 +116,9 @@ public class HiDPISetting } } catch (NumberFormatException e) { - System.err.println(setHiDPIScalePropertyName + " property give (" - + setHiDPIScaleProperty + ") but not parseable as integer"); + jalview.bin.Console.errPrintln(setHiDPIScalePropertyName + + " property give (" + setHiDPIScaleProperty + + ") but not parseable as integer"); } } if (setHiDPI && setHiDPIScale > 0) @@ -135,8 +135,8 @@ public class HiDPISetting try { int existingPropertyVal = Integer.parseInt(existingProperty); - System.out.println("Existing " + scalePropertyName + " is " - + existingPropertyVal); + jalview.bin.Console.outPrintln("Existing " + scalePropertyName + + " is " + existingPropertyVal); if (existingPropertyVal > 1) { setHiDPIScale(existingPropertyVal); @@ -144,8 +144,9 @@ public class HiDPISetting } } catch (NumberFormatException e) { - System.out.println("Could not convert property " + scalePropertyName - + " vale '" + existingProperty + "' to number"); + jalview.bin.Console.outPrintln( + "Could not convert property " + scalePropertyName + + " vale '" + existingProperty + "' to number"); } } @@ -159,7 +160,11 @@ public class HiDPISetting dpi = screenInfo.getScreenResolution(); } catch (HeadlessException e) { - System.err.println("Cannot get screen resolution: " + e.getMessage()); + if (isLinux) + { + jalview.bin.Console.errPrintln( + "Cannot get screen resolution: " + e.getMessage()); + } } // try and get screen size height and width @@ -171,8 +176,12 @@ public class HiDPISetting mindimension = Math.min(height, width); } catch (HeadlessException e) { - System.err.println( - "Cannot get screen size height and width:" + e.getMessage()); + if (isLinux) + { + jalview.bin.Console + .errPrintln("Cannot get screen size height and width:" + + e.getMessage()); + } } // attempt at a formula for scaling based on screen dpi and mindimension. diff --git a/src/jalview/bin/Jalview.java b/src/jalview/bin/Jalview.java index 57f2575..e343b0f 100755 --- a/src/jalview/bin/Jalview.java +++ b/src/jalview/bin/Jalview.java @@ -73,9 +73,12 @@ import jalview.bin.argparser.Arg.Opt; import jalview.bin.argparser.Arg.Type; import jalview.bin.argparser.ArgParser; import jalview.bin.argparser.BootstrapArgs; +import jalview.bin.groovy.JalviewObject; +import jalview.bin.groovy.JalviewObjectI; import jalview.ext.so.SequenceOntology; import jalview.gui.AlignFrame; import jalview.gui.Desktop; +import jalview.gui.JvOptionPane; import jalview.gui.PromptUserConfig; import jalview.gui.QuitHandler; import jalview.gui.QuitHandler.QResponse; @@ -117,7 +120,7 @@ import jalview.ws.jws2.Jws2Discoverer; * @author $author$ * @version $Revision$ */ -public class Jalview +public class Jalview implements JalviewObjectI { static { @@ -137,11 +140,11 @@ public class Jalview protected Commands cmds; - public static AlignFrame currentAlignFrame; + public AlignFrame currentAlignFrame = null; - public ArgParser argparser = null; + private ArgParser argparser = null; - public BootstrapArgs bootstrapArgs = null; + private BootstrapArgs bootstrapArgs = null; private boolean QUIET = false; @@ -274,7 +277,7 @@ public class Jalview * */ { - System.out.println("not in js"); + Console.outPrintln("not in js"); } // BH - for event debugging in JavaScript (Java mode only) @@ -383,29 +386,30 @@ public class Jalview }.start(); } - if (!quiet() || bootstrapArgs.contains(Arg.VERSION)) + if (!quiet() || !bootstrapArgs.outputToStdout() + || bootstrapArgs.contains(Arg.VERSION)) { - System.out.println( + Console.outPrintln( "Java version: " + System.getProperty("java.version")); - System.out.println("Java home: " + System.getProperty("java.home")); - System.out.println("Java arch: " + System.getProperty("os.arch") + " " + Console.outPrintln("Java home: " + System.getProperty("java.home")); + Console.outPrintln("Java arch: " + System.getProperty("os.arch") + " " + System.getProperty("os.name") + " " + System.getProperty("os.version")); String val = System.getProperty("sys.install4jVersion"); if (val != null) { - System.out.println("Install4j version: " + val); + Console.outPrintln("Install4j version: " + val); } val = System.getProperty("installer_template_version"); if (val != null) { - System.out.println("Install4j template version: " + val); + Console.outPrintln("Install4j template version: " + val); } val = System.getProperty("launcher_version"); if (val != null) { - System.out.println("Launcher version: " + val); + Console.outPrintln("Launcher version: " + val); } } @@ -425,7 +429,7 @@ public class Jalview // stop now if only after --version if (bootstrapArgs.contains(Arg.VERSION)) { - Jalview.exit(null, 0); + Jalview.exit(null, ExitCode.OK); } // old ArgsParser @@ -445,7 +449,7 @@ public class Jalview } else if (bootstrapArgs.contains(Arg.DEBUG)) { - logLevel = "DEBUG"; + logLevel = bootstrapArgs.getBoolean(Arg.DEBUG) ? "DEBUG" : "INFO"; } if (logLevel == null && !(bootstrapProperties == null)) { @@ -457,12 +461,13 @@ public class Jalview error.printStackTrace(); String message = "\nEssential logging libraries not found." + "\nUse: java -classpath \"$PATH_TO_LIB$/*:$PATH_TO_CLASSES$\" jalview.bin.Jalview"; - Jalview.exit(message, 0); + Jalview.exit(message, ExitCode.OK); } // register SIGTERM listener Runtime.getRuntime().addShutdownHook(new Thread() { + @Override public void run() { Console.debug("Running shutdown hook"); @@ -509,7 +514,7 @@ public class Jalview Cache.loadProperties(usrPropsFile); if (usrPropsFile != null) { - System.out.println( + Console.outPrintln( "CMD [-props " + usrPropsFile + "] executed successfully!"); testoutput(bootstrapArgs, Arg.PROPS, "test/jalview/bin/testProps.jvprops", usrPropsFile); @@ -541,9 +546,9 @@ public class Jalview { List> helpArgs = bootstrapArgs .getList(Arg.HELP); - System.out.println(Arg.usage(helpArgs.stream().map(e -> e.getKey()) + Console.outPrintln(Arg.usage(helpArgs.stream().map(e -> e.getKey()) .collect(Collectors.toList()))); - Jalview.exit(null, 0); + Jalview.exit(null, ExitCode.OK); } if (aparser.contains("help") || aparser.contains("h")) { @@ -551,8 +556,8 @@ public class Jalview * Now using new usage statement. showUsage(); */ - System.out.println(Arg.usage()); - Jalview.exit(null, 0); + Console.outPrintln(Arg.usage()); + Jalview.exit(null, ExitCode.OK); } // new CLI @@ -581,13 +586,13 @@ public class Jalview try { Jws2Discoverer.getDiscoverer().setPreferredUrl(jabawsUrl); - System.out.println( + Console.outPrintln( "CMD [-jabaws " + jabawsUrl + "] executed successfully!"); testoutput(bootstrapArgs, Arg.JABAWS, "http://www.compbio.dundee.ac.uk/jabaws", jabawsUrl); } catch (MalformedURLException e) { - System.err.println( + jalview.bin.Console.errPrintln( "Invalid jabaws parameter: " + jabawsUrl + " ignored"); } } @@ -617,7 +622,8 @@ public class Jalview } else { - System.out.println("Executing setprop argument: " + setprop); + jalview.bin.Console + .errPrintln("Executing setprop argument: " + setprop); if (Platform.isJS()) { Cache.setProperty(setprop.substring(0, p), @@ -638,14 +644,12 @@ public class Jalview try { Console.initLogger(); - } catch ( - - NoClassDefFoundError error) + } catch (NoClassDefFoundError error) { error.printStackTrace(); String message = "\nEssential logging libraries not found." + "\nUse: java -classpath \"$PATH_TO_LIB$/*:$PATH_TO_CLASSES$\" jalview.bin.Jalview"; - Jalview.exit(message, 0); + Jalview.exit(message, ExitCode.NO_LOGGING); } desktop = null; @@ -670,6 +674,8 @@ public class Jalview desktop = new Desktop(); desktop.setInBatchMode(true); // indicate we are starting up + mixedCliWarning(); + try { JalviewTaskbar.setTaskbar(this); @@ -749,7 +755,7 @@ public class Jalview } else { - System.out.println("CMD [-nousagestats] executed successfully!"); + Console.outPrintln("CMD [-nousagestats] executed successfully!"); testoutput(argparser, Arg.NOUSAGESTATS); } @@ -765,7 +771,7 @@ public class Jalview // questionnaire Console.debug("Starting questionnaire url at " + url); desktop.checkForQuestionnaire(url); - System.out.println("CMD questionnaire[-" + url + Console.outPrintln("CMD questionnaire[-" + url + "] executed successfully!"); } else @@ -786,8 +792,8 @@ public class Jalview } else { - System.out - .println("CMD [-noquestionnaire] executed successfully!"); + Console.outPrintln( + "CMD [-noquestionnaire] executed successfully!"); testoutput(argparser, Arg.QUESTIONNAIRE); } @@ -806,8 +812,33 @@ public class Jalview } } } + else + { + + if (getArgParser().isMixedStyle()) + { + String warning = MessageManager.formatMessage( + "warning.using_mixed_command_line_arguments", + getArgParser().getMixedExamples()); + Console.warn(warning); + Jalview.exit( + "Exiting due to mixed old and new command line arguments", + ExitCode.INVALID_ARGUMENT); + } + if (getArgParser().isOldStyle()) + { + String warning = MessageManager + .getString("warning.using_old_command_line_arguments") + .replace("\n", " ") + + "https://www.jalview.org/help/html/features/commandline.html"; + Console.warn(warning); + } + + } + // Run Commands from cli cmds = new Commands(argparser, headlessArg); + cmds.processArgs(); boolean commandsSuccess = cmds.argsWereParsed(); if (commandsSuccess) @@ -823,7 +854,7 @@ public class Jalview else { Jalview.exit("Successfully completed commands in headless mode", - 0); + ExitCode.OK); } } Console.info("Successfully completed commands"); @@ -832,7 +863,8 @@ public class Jalview { if (headlessArg) { - Jalview.exit("Error when running Commands in headless mode", 1); + Jalview.exit("Error when running Commands in headless mode", + ExitCode.ERROR_RUNNING_COMMANDS); } Console.warn("Error when running commands"); } @@ -863,7 +895,7 @@ public class Jalview if (file == null && desktop == null && !commandsSuccess) { - Jalview.exit("No files to open!", 1); + Jalview.exit("No files to open!", ExitCode.NO_FILES); } long progress = -1; @@ -877,7 +909,7 @@ public class Jalview .getString("status.processing_commandline_args"), progress = System.currentTimeMillis()); } - System.out.println("CMD [-open " + file + "] executed successfully!"); + Console.outPrintln("CMD [-open " + file + "] executed successfully!"); if (!Platform.isJS()) /** @@ -893,7 +925,8 @@ public class Jalview if (headless) { Jalview.exit( - "Can't find file '" + file + "' in headless mode", 1); + "Can't find file '" + file + "' in headless mode", + ExitCode.FILE_NOT_FOUND); } Console.warn("Can't find file'" + file + "'"); } @@ -914,7 +947,7 @@ public class Jalview format); if (af == null) { - System.out.println("error"); + Console.outPrintln("error"); } else { @@ -929,7 +962,7 @@ public class Jalview if (cs != null) { - System.out.println( + Console.outPrintln( "CMD [-colour " + data + "] executed successfully!"); } af.changeColour(cs); @@ -941,8 +974,8 @@ public class Jalview { af.parseFeaturesFile(data, AppletFormatAdapter.checkProtocol(data)); - // System.out.println("Added " + data); - System.out.println( + // Console.outPrintln("Added " + data); + Console.outPrintln( "CMD groups[-" + data + "] executed successfully!"); } data = aparser.getValue("features", true); @@ -950,8 +983,8 @@ public class Jalview { af.parseFeaturesFile(data, AppletFormatAdapter.checkProtocol(data)); - // System.out.println("Added " + data); - System.out.println( + // Console.outPrintln("Added " + data); + Console.outPrintln( "CMD [-features " + data + "] executed successfully!"); } @@ -959,8 +992,8 @@ public class Jalview if (data != null) { af.loadJalviewDataFile(data, null, null, null); - // System.out.println("Added " + data); - System.out.println( + // Console.outPrintln("Added " + data); + Console.outPrintln( "CMD [-annotations " + data + "] executed successfully!"); } // set or clear the sortbytree flag. @@ -969,7 +1002,7 @@ public class Jalview af.getViewport().setSortByTree(true); if (af.getViewport().getSortByTree()) { - System.out.println("CMD [-sortbytree] executed successfully!"); + Console.outPrintln("CMD [-sortbytree] executed successfully!"); } } if (aparser.contains("no-annotation")) @@ -977,7 +1010,7 @@ public class Jalview af.getViewport().setShowAnnotation(false); if (!af.getViewport().isShowAnnotation()) { - System.out.println("CMD no-annotation executed successfully!"); + Console.outPrintln("CMD no-annotation executed successfully!"); } } if (aparser.contains("nosortbytree")) @@ -985,8 +1018,8 @@ public class Jalview af.getViewport().setSortByTree(false); if (!af.getViewport().getSortByTree()) { - System.out - .println("CMD [-nosortbytree] executed successfully!"); + Console.outPrintln( + "CMD [-nosortbytree] executed successfully!"); } } data = aparser.getValue("tree", true); @@ -994,7 +1027,7 @@ public class Jalview { try { - System.out.println( + Console.outPrintln( "CMD [-tree " + data + "] executed successfully!"); NewickFile nf = new NewickFile(data, AppletFormatAdapter.checkProtocol(data)); @@ -1002,7 +1035,7 @@ public class Jalview .setCurrentTree(af.showNewickTree(nf, data).getTree()); } catch (IOException ex) { - System.err.println("Couldn't add tree " + data); + jalview.bin.Console.errPrintln("Couldn't add tree " + data); ex.printStackTrace(System.err); } } @@ -1011,9 +1044,9 @@ public class Jalview { // Execute the groovy script after we've done all the rendering stuff // and before any images or figures are generated. - System.out.println("Executing script " + groovyscript); + Console.outPrintln("Executing script " + groovyscript); executeGroovyScript(groovyscript, af); - System.out.println("CMD groovy[" + groovyscript + Console.outPrintln("CMD groovy[" + groovyscript + "] executed successfully!"); groovyscript = null; } @@ -1027,14 +1060,14 @@ public class Jalview if (outputFormat.equalsIgnoreCase("png")) { - System.out.println("Creating PNG image: " + file); + Console.outPrintln("Creating PNG image: " + file); af.createPNG(new File(file)); imageName = (new File(file)).getName(); continue; } else if (outputFormat.equalsIgnoreCase("svg")) { - System.out.println("Creating SVG image: " + file); + Console.outPrintln("Creating SVG image: " + file); File imageFile = new File(file); imageName = imageFile.getName(); af.createSVG(imageFile); @@ -1046,7 +1079,7 @@ public class Jalview imageName = imageFile.getName(); HtmlSvgOutput htmlSVG = new HtmlSvgOutput(af.alignPanel); - System.out.println("Creating HTML image: " + file); + Console.outPrintln("Creating HTML image: " + file); htmlSVG.exportHTML(file); continue; } @@ -1054,7 +1087,8 @@ public class Jalview { if (file == null) { - System.err.println("The output html file must not be null"); + jalview.bin.Console.errPrintln( + "The output html file must not be null"); return; } try @@ -1066,21 +1100,21 @@ public class Jalview e.printStackTrace(); } BioJsHTMLOutput bjs = new BioJsHTMLOutput(af.alignPanel); - System.out.println( + Console.outPrintln( "Creating BioJS MSA Viwer HTML file: " + file); bjs.exportHTML(file); continue; } else if (outputFormat.equalsIgnoreCase("imgMap")) { - System.out.println("Creating image map: " + file); + Console.outPrintln("Creating image map: " + file); af.createImageMap(new File(file), imageName); continue; } else if (outputFormat.equalsIgnoreCase("eps")) { File outputFile = new File(file); - System.out.println( + Console.outPrintln( "Creating EPS file: " + outputFile.getAbsolutePath()); af.createEPS(outputFile); continue; @@ -1092,14 +1126,14 @@ public class Jalview outFormat = FileFormats.getInstance().forName(outputFormat); } catch (Exception formatP) { - System.out.println("Couldn't parse " + outFormat + Console.outPrintln("Couldn't parse " + outFormat + " as a valid Jalview format string."); } if (outFormat != null) { if (!outFormat.isWritable()) { - System.out.println( + Console.outPrintln( "This version of Jalview does not support alignment export as " + outputFormat); } @@ -1108,19 +1142,19 @@ public class Jalview af.saveAlignment(file, outFormat); if (af.isSaveAlignmentSuccessful()) { - System.out.println("Written alignment in " + Console.outPrintln("Written alignment in " + outFormat.getName() + " format to " + file); } else { - System.out.println("Error writing file " + file + " in " + Console.outPrintln("Error writing file " + file + " in " + outFormat.getName() + " format!!"); } } } } catch (ImageOutputException ioexc) { - System.out.println( + Console.outPrintln( "Unexpected error whilst exporting image to " + file); ioexc.printStackTrace(); } @@ -1129,7 +1163,7 @@ public class Jalview while (aparser.getSize() > 0) { - System.out.println("Unknown arg: " + aparser.nextValue()); + Console.outPrintln("Unknown arg: " + aparser.nextValue()); } } } @@ -1197,12 +1231,12 @@ public class Jalview { if (Cache.groovyJarsPresent()) { - System.out.println("Executing script " + groovyscript); + Console.outPrintln("Executing script " + groovyscript); executeGroovyScript(groovyscript, startUpAlframe); } else { - System.err.println( + jalview.bin.Console.errPrintln( "Sorry. Groovy Support is not available, so ignoring the provided groovy script " + groovyscript); } @@ -1216,6 +1250,8 @@ public class Jalview } desktop.setInBatchMode(false); } + + cliWarning(); } private static void setLookAndFeel() @@ -1497,7 +1533,7 @@ public class Jalview UIManager.put("TabbedPane.tabType", "card"); UIManager.put("TabbedPane.showTabSeparators", true); UIManager.put("TabbedPane.showContentSeparator", true); - UIManager.put("TabbedPane.tabSeparatorsFullHeight", true); + // UIManager.put("TabbedPane.tabSeparatorsFullHeight", true); UIManager.put("TabbedPane.tabsOverlapBorder", true); UIManager.put("TabbedPane.hasFullBorder", true); UIManager.put("TabbedPane.tabLayoutPolicy", "scroll"); @@ -1547,7 +1583,7 @@ public class Jalview /* private static void showUsage() { - System.out.println( + jalview.bin.Console.outPrintln( "Usage: jalview -open [FILE] [OUTPUT_FORMAT] [OUTPUT_FILE]\n\n" + "-nodisplay\tRun Jalview without User Interface.\n" + "-props FILE\tUse the given Jalview properties file instead of users default.\n" @@ -1596,9 +1632,8 @@ public class Jalview */ PromptUserConfig prompter = new PromptUserConfig(Desktop.desktop, "USAGESTATS", - MessageManager.getString("prompt.plausible_analytics_title"), - MessageManager.getString("prompt.plausible_analytics"), - new Runnable() + MessageManager.getString("prompt.analytics_title"), + MessageManager.getString("prompt.analytics"), new Runnable() { @Override public void run() @@ -1658,9 +1693,10 @@ public class Jalview } catch (Exception ex) { - System.err.println("Failed to read from STDIN into tempfile " - + ((tfile == null) ? "(tempfile wasn't created)" - : tfile.toString())); + jalview.bin.Console + .errPrintln("Failed to read from STDIN into tempfile " + + ((tfile == null) ? "(tempfile wasn't created)" + : tfile.toString())); ex.printStackTrace(); return; } @@ -1669,7 +1705,7 @@ public class Jalview sfile = tfile.toURI().toURL(); } catch (Exception x) { - System.err.println( + jalview.bin.Console.errPrintln( "Unexpected Malformed URL Exception for temporary file created from STDIN: " + tfile.toURI()); x.printStackTrace(); @@ -1686,17 +1722,20 @@ public class Jalview tfile = new File(groovyscript); if (!tfile.exists()) { - System.err.println("File '" + groovyscript + "' does not exist."); + jalview.bin.Console.errPrintln( + "File '" + groovyscript + "' does not exist."); return; } if (!tfile.canRead()) { - System.err.println("File '" + groovyscript + "' cannot be read."); + jalview.bin.Console.errPrintln( + "File '" + groovyscript + "' cannot be read."); return; } if (tfile.length() < 1) { - System.err.println("File '" + groovyscript + "' is empty."); + jalview.bin.Console + .errPrintln("File '" + groovyscript + "' is empty."); return; } try @@ -1704,7 +1743,7 @@ public class Jalview sfile = tfile.getAbsoluteFile().toURI().toURL(); } catch (Exception ex) { - System.err.println("Failed to create a file URL for " + jalview.bin.Console.errPrintln("Failed to create a file URL for " + tfile.getAbsoluteFile()); return; } @@ -1712,12 +1751,11 @@ public class Jalview } try { + JalviewObjectI j = new JalviewObject(this); Map vbinding = new HashMap<>(); - vbinding.put("Jalview", this); - if (af != null) - { - vbinding.put("currentAlFrame", af); - } + vbinding.put(JalviewObjectI.jalviewObjectName, j); + vbinding.put(JalviewObjectI.currentAlFrameName, + af != null ? af : getCurrentAlignFrame()); Binding gbinding = new Binding(vbinding); GroovyScriptEngine gse = new GroovyScriptEngine(new URL[] { sfile }); gse.run(sfile.toString(), gbinding); @@ -1729,10 +1767,10 @@ public class Jalview } } catch (Exception e) { - System.err.println("Exception Whilst trying to execute file " + sfile - + " as a groovy script."); + jalview.bin.Console + .errPrintln("Exception Whilst trying to execute file " + sfile + + " as a groovy script."); e.printStackTrace(System.err); - } } @@ -1746,39 +1784,42 @@ public class Jalview return false; } + @Override public AlignFrame[] getAlignFrames() { return desktop == null ? new AlignFrame[] { getCurrentAlignFrame() } - : Desktop.getAlignFrames(); - + : Desktop.getDesktopAlignFrames(); } /** * jalview.bin.Jalview.quit() will just run the non-GUI shutdownHook and exit */ + @Override public void quit() { // System.exit will run the shutdownHook first - Jalview.exit("Quitting now. Bye!", 0); + Jalview.exit("Quitting now. Bye!", ExitCode.OK); } - public static AlignFrame getCurrentAlignFrame() + @Override + public AlignFrame getCurrentAlignFrame() { - return Jalview.currentAlignFrame; + return currentAlignFrame; } - public static void setCurrentAlignFrame(AlignFrame currentAlignFrame) + public void setCurrentAlignFrame(AlignFrame af) { - Jalview.currentAlignFrame = currentAlignFrame; + this.currentAlignFrame = af; } - protected Commands getCommands() + public Commands getCommands() { return cmds; } - public static void exit(String message, int exitcode) + public static void exit(String message, ExitCode ec) { + int exitcode = ec == ExitCode.OK ? 0 : ec.ordinal() + 1; if (Console.log == null) { // Don't start the logger just to exit! @@ -1786,11 +1827,11 @@ public class Jalview { if (exitcode == 0) { - System.out.println(message); + Console.outPrintln(message); } else { - System.err.println(message); + jalview.bin.Console.errPrintln(message); } } } @@ -1815,14 +1856,35 @@ public class Jalview } } + public enum ExitCode + { + // only add new ones to the end of the list (to preserve ordinal values) + OK, FILE_NOT_FOUND, FILE_NOT_READABLE, NO_FILES, INVALID_FORMAT, + INVALID_ARGUMENT, INVALID_VALUE, MIXED_CLI_ARGUMENTS, + ERROR_RUNNING_COMMANDS, NO_LOGGING, GROOVY_ERROR; + } + /****************************** * * TEST OUTPUT METHODS * + * these operate only when Arg.TESTOUTPUT has been passed, and variously check + * if an expected value / arg was set and report it to the test framework. + * ******************************/ /** - * method for reporting string values parsed/processed during tests + * report string values parsed/processed during tests When the Bootstrap + * argument Arg.TESTOUTPUT is present - reports on debug if given s1 is not + * null and not equals s2, warns if given argument is not set, and calls + * testoutput(true,a,s1,s2) to report processing progress. * + * @param ap + * - ArgParser handling parsing + * @param a + * - Arg currently being processed + * @param s1 + * - expected + * @param s2 */ protected static void testoutput(ArgParser ap, Arg a, String s1, String s2) @@ -1847,7 +1909,9 @@ public class Jalview } /** - * method for reporting string values parsed/processed during tests + * report values passed via bootstrap arguments + * + * TODO: significant code duplication with testouput(Argparser...) - move it */ protected static void testoutput(BootstrapArgs bsa, Arg a, String s1, @@ -1875,14 +1939,15 @@ public class Jalview } /** - * report value set for string values parsed/processed during tests + * conditionally (on @param yes) report that expected value s1 was set during + * CommandsTest tests */ private static void testoutput(boolean yes, Arg a, String s1, String s2) { if (yes && ((s1 == null && s2 == null) || (s1 != null && s1.equals(s2)))) { - System.out.println("[TESTOUTPUT] arg " + a.argString() + "='" + s1 + Console.outPrintln("[TESTOUTPUT] arg " + a.argString() + "='" + s1 + "' was set"); } } @@ -1940,6 +2005,90 @@ public class Jalview { message = a.argString() + (yes ? " was set" : " was not set"); } - System.out.println("[TESTOUTPUT] arg " + message); + Console.outPrintln("[TESTOUTPUT] arg " + message); + } + + public ArgParser getArgParser() + { + return argparser; + } + + public BootstrapArgs getBootstrapArgs() + { + return bootstrapArgs; + } + + public static boolean isBatchMode() + { + return getInstance() != null && (getInstance().desktop == null + || getInstance().desktop.isInBatchMode()); + } + + /** + * Warning about old or mixed command line arguments + */ + private void mixedCliWarning() + { + Jalview j = Jalview.getInstance(); + boolean mixedStyle = j.getArgParser() != null + && j.getArgParser().isMixedStyle(); + String title = MessageManager.getString("label.command_line_arguments"); + if (mixedStyle) + { + String warning = MessageManager.formatMessage( + "warning.using_mixed_command_line_arguments", + j.getArgParser().getMixedExamples()); + String quit = MessageManager.getString("action.quit"); + + Desktop.instance.nonBlockingDialog(title, warning, null, quit, + JvOptionPane.WARNING_MESSAGE, false, false, true, 30000); + + Jalview.exit( + "Exiting due to mixed old and new command line arguments.", + ExitCode.MIXED_CLI_ARGUMENTS); + } + } + + private void cliWarning() + { + Jalview j = Jalview.getInstance(); + Commands c = j.getCommands(); + boolean oldStyle = j.getArgParser() != null + && j.getArgParser().isOldStyle(); + String title = MessageManager.getString("label.command_line_arguments"); + if (oldStyle) + { + String warning = MessageManager + .getString("warning.using_old_command_line_arguments"); + String url = "https://www.jalview.org/help/html/features/commandline.html"; + if (Desktop.instance != null) + { + String cont = MessageManager.getString("label.continue"); + + Desktop.instance.nonBlockingDialog(title, warning, url, cont, + JvOptionPane.WARNING_MESSAGE, false, true, true, 30000); + } + } + if (j.getCommands() != null && j.getCommands().getErrors().size() > 0) + { + if (Desktop.instance != null) + { + String message = MessageManager + .getString("warning.the_following_errors"); + String ok = MessageManager.getString("action.ok"); + int shortest = 60; + List errors = j.getCommands().getErrors(); + for (int i = 0; i < errors.size(); i++) + { + shortest = Math.min(shortest, errors.get(i).length()); + } + Desktop.instance.nonBlockingDialog( + Math.max(message.length(), Math.min(60, shortest)), + Math.min(errors.size(), 20), title, message, + j.getCommands().errorsToString(), ok, + JvOptionPane.WARNING_MESSAGE, true, false, true, -1); + } + } } + } diff --git a/src/jalview/bin/JalviewLite.java b/src/jalview/bin/JalviewLite.java index 7d66f6d..e8be95f 100644 --- a/src/jalview/bin/JalviewLite.java +++ b/src/jalview/bin/JalviewLite.java @@ -292,7 +292,7 @@ public class JalviewLite extends Applet { if (debug) { - System.err.println("Selecting region using separator string '" + jalview.bin.Console.errPrintln("Selecting region using separator string '" + separator + "'"); } } @@ -344,7 +344,7 @@ public class JalviewLite extends Applet from--; } catch (NumberFormatException ex) { - System.err.println( + jalview.bin.Console.errPrintln( "ERROR: Couldn't parse first integer in range element column selection string '" + cl + "' - format is 'from-to'"); return; @@ -355,7 +355,7 @@ public class JalviewLite extends Applet to--; } catch (NumberFormatException ex) { - System.err.println( + jalview.bin.Console.errPrintln( "ERROR: Couldn't parse second integer in range element column selection string '" + cl + "' - format is 'from-to'"); return; @@ -396,13 +396,13 @@ public class JalviewLite extends Applet } if (debug) { - System.err.println("Range '" + cl + "' deparsed as [" + from + jalview.bin.Console.errPrintln("Range '" + cl + "' deparsed as [" + from + "," + to + "]"); } } else { - System.err.println("ERROR: Invalid Range '" + cl + jalview.bin.Console.errPrintln("ERROR: Invalid Range '" + cl + "' deparsed as [" + from + "," + to + "]"); } } @@ -422,7 +422,7 @@ public class JalviewLite extends Applet } else { - System.err.println( + jalview.bin.Console.errPrintln( "ERROR: Couldn't parse integer from point selection element of column selection string '" + cl + "'"); return; @@ -451,13 +451,13 @@ public class JalviewLite extends Applet csel.addElement(r); if (debug) { - System.err.println("Point selection '" + cl + jalview.bin.Console.errPrintln("Point selection '" + cl + "' deparsed as [" + r + "]"); } } else { - System.err.println("ERROR: Invalid Point selection '" + cl + jalview.bin.Console.errPrintln("ERROR: Invalid Point selection '" + cl + "' deparsed as [" + r + "]"); } } @@ -940,7 +940,7 @@ public class JalviewLite extends Applet listener = listener.trim(); if (listener.length() == 0) { - System.err.println( + jalview.bin.Console.errPrintln( "jalview Javascript error: Ignoring empty function for mouseover listener."); return; } @@ -952,11 +952,11 @@ public class JalviewLite extends Applet .addStructureViewerListener(mol); if (debug) { - System.err.println("Added a mouseover listener for " + jalview.bin.Console.errPrintln("Added a mouseover listener for " + ((af == null) ? "All frames" : "Just views for " + af.getAlignViewport().getSequenceSetId())); - System.err.println("There are now " + javascriptListeners.size() + jalview.bin.Console.errPrintln("There are now " + javascriptListeners.size() + " listeners in total."); } } @@ -987,7 +987,7 @@ public class JalviewLite extends Applet listener = listener.trim(); if (listener.length() == 0) { - System.err.println( + jalview.bin.Console.errPrintln( "jalview Javascript error: Ignoring empty function for selection listener."); return; } @@ -999,11 +999,11 @@ public class JalviewLite extends Applet .addSelectionListener(mol); if (debug) { - System.err.println("Added a selection listener for " + jalview.bin.Console.errPrintln("Added a selection listener for " + ((af == null) ? "All frames" : "Just views for " + af.getAlignViewport().getSequenceSetId())); - System.err.println("There are now " + javascriptListeners.size() + jalview.bin.Console.errPrintln("There are now " + javascriptListeners.size() + " listeners in total."); } } @@ -1027,7 +1027,7 @@ public class JalviewLite extends Applet listener = listener.trim(); if (listener.length() == 0) { - System.err.println( + jalview.bin.Console.errPrintln( "jalview Javascript error: Ignoring empty function for selection listener."); return; } @@ -1039,9 +1039,9 @@ public class JalviewLite extends Applet .addStructureViewerListener(mol); if (debug) { - System.err.println("Added a javascript structure viewer listener '" + jalview.bin.Console.errPrintln("Added a javascript structure viewer listener '" + listener + "'"); - System.err.println("There are now " + javascriptListeners.size() + jalview.bin.Console.errPrintln("There are now " + javascriptListeners.size() + " listeners in total."); } } @@ -1087,7 +1087,7 @@ public class JalviewLite extends Applet rprt = debug; if (debug) { - System.err.println("Removed listener '" + listener + "'"); + jalview.bin.Console.errPrintln("Removed listener '" + listener + "'"); } } else @@ -1097,7 +1097,7 @@ public class JalviewLite extends Applet } if (rprt) { - System.err.println("There are now " + javascriptListeners.size() + jalview.bin.Console.errPrintln("There are now " + javascriptListeners.size() + " listeners in total."); } } @@ -1105,14 +1105,14 @@ public class JalviewLite extends Applet @Override public void stop() { - System.err.println("Applet " + getName() + " stop()."); + jalview.bin.Console.errPrintln("Applet " + getName() + " stop()."); tidyUp(); } @Override public void destroy() { - System.err.println("Applet " + getName() + " destroy()."); + jalview.bin.Console.errPrintln("Applet " + getName() + " destroy()."); tidyUp(); } @@ -1189,7 +1189,7 @@ public class JalviewLite extends Applet } } catch (NumberFormatException e) { - System.err.println("Ignoring invalid residue number string '" + jalview.bin.Console.errPrintln("Ignoring invalid residue number string '" + pdbResNum + "'"); } @@ -1220,7 +1220,7 @@ public class JalviewLite extends Applet } catch (Exception ex) { - System.err.println("Couldn't parse integer arguments (topRow='" + jalview.bin.Console.errPrintln("Couldn't parse integer arguments (topRow='" + topRow + "' and leftHandColumn='" + leftHandColumn + "')"); ex.printStackTrace(); @@ -1251,7 +1251,7 @@ public class JalviewLite extends Applet } catch (Exception ex) { - System.err.println("Couldn't parse integer arguments (topRow='" + jalview.bin.Console.errPrintln("Couldn't parse integer arguments (topRow='" + topRow + "')"); ex.printStackTrace(); } @@ -1283,7 +1283,7 @@ public class JalviewLite extends Applet } catch (Exception ex) { - System.err.println( + jalview.bin.Console.errPrintln( "Couldn't parse integer arguments (leftHandColumn='" + leftHandColumn + "')"); ex.printStackTrace(); @@ -1415,18 +1415,18 @@ public class JalviewLite extends Applet { if (debug) { - System.err.println("Applet context is '" + jalview.bin.Console.errPrintln("Applet context is '" + getAppletContext().getClass().toString() + "'"); } JSObject scriptObject = JSObject.getWindow(this); if (debug && scriptObject != null) { - System.err.println("Applet has Javascript callback support."); + jalview.bin.Console.errPrintln("Applet has Javascript callback support."); } } catch (Exception ex) { - System.err.println( + jalview.bin.Console.errPrintln( "Warning: No JalviewLite javascript callbacks available."); if (debug) { @@ -1436,9 +1436,9 @@ public class JalviewLite extends Applet if (debug) { - System.err.println("JalviewLite Version " + getVersion()); - System.err.println("Build Date : " + getBuildDate()); - System.err.println("Installation : " + getInstallation()); + jalview.bin.Console.errPrintln("JalviewLite Version " + getVersion()); + jalview.bin.Console.errPrintln("Build Date : " + getBuildDate()); + jalview.bin.Console.errPrintln("Installation : " + getInstallation()); } String externalsviewer = getParameter("externalstructureviewer"); if (externalsviewer != null) @@ -1465,7 +1465,7 @@ public class JalviewLite extends Applet separator = sep; if (debug) { - System.err.println("Separator set to '" + separator + "'"); + jalview.bin.Console.errPrintln("Separator set to '" + separator + "'"); } } else @@ -1573,7 +1573,7 @@ public class JalviewLite extends Applet { if (tries > 0) { - System.err.println("LiveConnect request thread going to sleep."); + jalview.bin.Console.errPrintln("LiveConnect request thread going to sleep."); } try { @@ -1584,7 +1584,7 @@ public class JalviewLite extends Applet ; if (tries++ > 0) { - System.err.println("LiveConnect request thread woken up."); + jalview.bin.Console.errPrintln("LiveConnect request thread woken up."); } try { @@ -1595,7 +1595,7 @@ public class JalviewLite extends Applet } } catch (Exception jsex) { - System.err.println("Attempt " + tries + jalview.bin.Console.errPrintln("Attempt " + tries + " to access LiveConnect javascript failed."); } } @@ -1632,14 +1632,14 @@ public class JalviewLite extends Applet "Calling oninit callback '" + initjscallback + "'."); } catch (Exception e) { - System.err.println("Exception when executing _oninit callback '" + jalview.bin.Console.errPrintln("Exception when executing _oninit callback '" + initjscallback + "'."); e.printStackTrace(); } } else { - System.err.println("Not executing _oninit callback '" + jalview.bin.Console.errPrintln("Not executing _oninit callback '" + initjscallback + "' - no scripting allowed."); } } @@ -1700,7 +1700,7 @@ public class JalviewLite extends Applet ((AlignFrame) frame).viewport.applet.currentAlignFrame = (AlignFrame) frame; if (debug) { - System.err.println("Activated window " + frame); + jalview.bin.Console.errPrintln("Activated window " + frame); } } // be good. @@ -1715,7 +1715,7 @@ public class JalviewLite extends Applet * * public void windowDeactivated(WindowEvent e) { if (currentAlignFrame == * frame) { currentAlignFrame = null; if (debug) { - * System.err.println("Deactivated window "+frame); } } + * jalview.bin.Console.errPrintln("Deactivated window "+frame); } } * super.windowDeactivated(e); } */ }); @@ -1801,7 +1801,7 @@ public class JalviewLite extends Applet } if (!jmolAvailable) { - System.out.println( + jalview.bin.Console.outPrintln( "Jmol not available - Using mc_view for structures"); } } catch (java.lang.ClassNotFoundException ex) @@ -1813,7 +1813,7 @@ public class JalviewLite extends Applet jmolAvailable = false; if (debug) { - System.err.println( + jalview.bin.Console.errPrintln( "Skipping Jmol check. Will use mc_view (probably)"); } } @@ -1844,7 +1844,7 @@ public class JalviewLite extends Applet { if (JalviewLite.debug) { - System.err.println(msg); + jalview.bin.Console.errPrintln(msg); } } @@ -1884,7 +1884,7 @@ public class JalviewLite extends Applet { if (debug) { - System.err.println("Prepended document base '" + documentBase + jalview.bin.Console.errPrintln("Prepended document base '" + documentBase + "' to make: '" + withDocBase + "'"); } protocol = DataSourceType.URL; @@ -1903,7 +1903,7 @@ public class JalviewLite extends Applet protocol = DataSourceType.URL; if (debug) { - System.err.println("Prepended codebase '" + codeBase + jalview.bin.Console.errPrintln("Prepended codebase '" + codeBase + "' to make: '" + withCodeBase + "'"); } return withCodeBase; @@ -2010,7 +2010,7 @@ public class JalviewLite extends Applet + " as " + (al1.isNucleotide() ? "protein product" : "cDNA") + " for " + af.getTitle(); - System.err.println(msg); + jalview.bin.Console.errPrintln(msg); } } @@ -2084,7 +2084,7 @@ public class JalviewLite extends Applet dbgMsg(">>>Dump finished."); } catch (Exception e) { - System.err.println( + jalview.bin.Console.errPrintln( "Exception when trying to dump the content of the file parameter."); e.printStackTrace(); } @@ -2214,7 +2214,7 @@ public class JalviewLite extends Applet { // this may not really be a problem but we give a warning // anyway - System.err.println( + jalview.bin.Console.errPrintln( "Warning: Possible input parsing error: Null sequence for attachment of PDB (sequence " + i + ")"); } @@ -2320,7 +2320,7 @@ public class JalviewLite extends Applet } else { - System.err.println( + jalview.bin.Console.errPrintln( "Annotations were not added from annotation file '" + param + "'"); } @@ -2392,13 +2392,13 @@ public class JalviewLite extends Applet { if (debug) { - System.err.println( + jalview.bin.Console.errPrintln( "Attempting to load T-COFFEE score file from the scoreFile parameter"); } result = alignFrame.loadScoreFile(sScoreFile); if (!result) { - System.err.println( + jalview.bin.Console.errPrintln( "Failed to parse T-COFFEE parameter as a valid score file ('" + sScoreFile + "')"); } @@ -2469,13 +2469,13 @@ public class JalviewLite extends Applet boolean rtn = (getClass().getResourceAsStream("/" + f) != null); if (debug) { - System.err.println("Resource '" + f + "' was " + jalview.bin.Console.errPrintln("Resource '" + f + "' was " + (rtn ? "" : "not ") + "located by classloader."); } return rtn; } catch (Exception ex) { - System.out.println("Exception checking resources: " + f + " " + ex); + jalview.bin.Console.outPrintln("Exception checking resources: " + f + " " + ex); return false; } } @@ -2496,7 +2496,7 @@ public class JalviewLite extends Applet { return initialAlignFrame; } - System.err.println( + jalview.bin.Console.errPrintln( "Implementation error: Jalview Applet API cannot work out which AlignFrame to use."); return null; } @@ -2564,18 +2564,18 @@ public class JalviewLite extends Applet jv.removeAllElements(); if (debug) { - System.err.println("Array from '" + separator + jalview.bin.Console.errPrintln("Array from '" + separator + "' separated List:\n" + v.length); for (int i = 0; i < v.length; i++) { - System.err.println("item " + i + " '" + v[i] + "'"); + jalview.bin.Console.errPrintln("item " + i + " '" + v[i] + "'"); } } return v; } if (debug) { - System.err.println( + jalview.bin.Console.errPrintln( "Empty Array from '" + separator + "' separated List"); } return null; @@ -2620,13 +2620,13 @@ public class JalviewLite extends Applet { System.err .println("Returning '" + separator + "' separated List:\n"); - System.err.println(v); + jalview.bin.Console.errPrintln(v); } return v.toString(); } if (debug) { - System.err.println( + jalview.bin.Console.errPrintln( "Returning empty '" + separator + "' separated List\n"); } return "" + separator; @@ -2745,7 +2745,7 @@ public class JalviewLite extends Applet this.separator = separator; if (debug) { - System.err.println("Default Separator now: '" + separator + "'"); + jalview.bin.Console.errPrintln("Default Separator now: '" + separator + "'"); } } @@ -2901,7 +2901,7 @@ public class JalviewLite extends Applet Color col = ColorUtils.parseColourString(colprop); if (col == null) { - System.err.println("Couldn't parse '" + colprop + "' as a colour for " + jalview.bin.Console.errPrintln("Couldn't parse '" + colprop + "' as a colour for " + colparam); } return (col == null) ? defcolour : col; @@ -2971,7 +2971,7 @@ public class JalviewLite extends Applet } if (debug) { - System.err.println( + jalview.bin.Console.errPrintln( "resolveUrlForLocalOrAbsolute returning " + resolvedPath); } return resolvedPath; @@ -3000,7 +3000,7 @@ public class JalviewLite extends Applet : getDocumentBase()); if (debug) { - System.err.println("Show url (prepended " + prepend + jalview.bin.Console.errPrintln("Show url (prepended " + prepend + " - toggle resolvetocodebase if code/docbase resolution is wrong): " + url); } @@ -3009,7 +3009,7 @@ public class JalviewLite extends Applet { if (debug) { - System.err.println("Show url: " + url); + jalview.bin.Console.errPrintln("Show url: " + url); } } if (url.indexOf("javascript:") == 0) diff --git a/src/jalview/bin/JalviewLiteURLRetrieve.java b/src/jalview/bin/JalviewLiteURLRetrieve.java index f2ffda5..d38892a 100644 --- a/src/jalview/bin/JalviewLiteURLRetrieve.java +++ b/src/jalview/bin/JalviewLiteURLRetrieve.java @@ -64,7 +64,7 @@ public class JalviewLiteURLRetrieve extends Applet DataSourceType protocol = null; try { - System.out.println("Loading thread started with:\n>>file\n" + file + jalview.bin.Console.outPrintln("Loading thread started with:\n>>file\n" + file + ">>endfile"); // This might throw a security exception in certain browsers // Netscape Communicator for instance. @@ -77,7 +77,7 @@ public class JalviewLiteURLRetrieve extends Applet rtn = true; is.close(); } - System.err.println("Resource '" + file + "' was " + jalview.bin.Console.errPrintln("Resource '" + file + "' was " + (rtn ? "" : "not") + " located by classloader."); if (rtn) { @@ -86,7 +86,7 @@ public class JalviewLiteURLRetrieve extends Applet } catch (Exception ex) { - System.out.println( + jalview.bin.Console.outPrintln( "Exception checking resources: " + file + " " + ex); } if (file.indexOf("://") > -1) @@ -99,7 +99,7 @@ public class JalviewLiteURLRetrieve extends Applet protocol = DataSourceType.FILE; } - System.out.println("Trying to get contents of resource:"); + jalview.bin.Console.outPrintln("Trying to get contents of resource:"); FileParse fp = new FileParse(file, protocol); if (fp.isValid()) { @@ -112,7 +112,7 @@ public class JalviewLiteURLRetrieve extends Applet } else { - System.out.println("Resource at " + file + jalview.bin.Console.outPrintln("Resource at " + file + " cannot be read with protocol==" + protocol); return; } @@ -121,11 +121,11 @@ public class JalviewLiteURLRetrieve extends Applet if (format == null) { format = new IdentifyFile().identify(file, protocol); - System.out.println("Format is " + format); + jalview.bin.Console.outPrintln("Format is " + format); } else { - System.out.println("User specified Format is " + format); + jalview.bin.Console.outPrintln("User specified Format is " + format); } AlignmentI al = null; try @@ -133,17 +133,17 @@ public class JalviewLiteURLRetrieve extends Applet al = new AppletFormatAdapter().readFile(file, protocol, format); } catch (java.io.IOException ex) { - System.err.println("Failed to open the file."); + jalview.bin.Console.errPrintln("Failed to open the file."); ex.printStackTrace(); } if (al != null) { - System.out.println(new AppletFormatAdapter() + jalview.bin.Console.outPrintln(new AppletFormatAdapter() .formatSequences(FileFormat.Fasta, al, false)); } } catch (Exception e) { - System.err.println("bailing out : Unexpected exception:"); + jalview.bin.Console.errPrintln("bailing out : Unexpected exception:"); e.printStackTrace(); } } diff --git a/src/jalview/bin/JalviewTaskbar.java b/src/jalview/bin/JalviewTaskbar.java index c7ababa..e04c04f 100644 --- a/src/jalview/bin/JalviewTaskbar.java +++ b/src/jalview/bin/JalviewTaskbar.java @@ -46,7 +46,7 @@ public class JalviewTaskbar } else { - System.out.println("Unable to setIconImage()"); + Console.outPrintln("Unable to setIconImage()"); } } } diff --git a/src/jalview/bin/Launcher.java b/src/jalview/bin/Launcher.java index a87d322..e1415be 100644 --- a/src/jalview/bin/Launcher.java +++ b/src/jalview/bin/Launcher.java @@ -50,28 +50,7 @@ public class Launcher { private final static String startClass = "jalview.bin.Jalview"; - private static boolean checkJVMSymlink(String testBin) - { - File testBinFile = new File(testBin); - if (!testBinFile.exists()) - { - return false; - } - File targetFile = null; - try - { - targetFile = testBinFile.getCanonicalFile(); - } catch (IOException e) - { - return false; - } - if (targetFile != null && ("java".equals(targetFile.getName()) - || "java.exe".equals(targetFile.getName()))) - { - return true; - } - return false; - } + private final static String headlessProperty = "java.awt.headless"; /** * main method for jalview.bin.Launcher. This restarts the same JRE's JVM with @@ -85,53 +64,27 @@ public class Launcher { if (!LaunchUtils.checkJavaVersion()) { - System.err.println("WARNING - The Java version being used (Java " - + LaunchUtils.getJavaVersion() - + ") may lead to problems. This installation of Jalview should be used with Java " - + LaunchUtils.getJavaCompileVersion() + "."); - } - final String appName = ChannelProperties.getProperty("app_name"); - final String javaBinDir = System.getProperty("java.home") - + File.separator + "bin" + File.separator; - String javaBin = null; - if (javaBin == null && checkJVMSymlink(javaBinDir + appName)) - { - javaBin = javaBinDir + appName; - } - if (javaBin == null && checkJVMSymlink(javaBinDir + "Jalview")) - { - javaBin = javaBinDir + "Jalview"; - } - if (javaBin == null) - { - javaBin = "java"; - } - - List command = new ArrayList<>(); - command.add(javaBin); - - String memSetting = null; - - boolean isAMac = System.getProperty("os.name").indexOf("Mac") > -1; - - for (String jvmArg : ManagementFactory.getRuntimeMXBean() - .getInputArguments()) - { - command.add(jvmArg); + jalview.bin.Console + .errPrintln("WARNING - The Java version being used (Java " + + LaunchUtils.getJavaVersion() + + ") may lead to problems. This installation of Jalview should be used with Java " + + LaunchUtils.getJavaCompileVersion() + "."); } - command.add("-cp"); - command.add(ManagementFactory.getRuntimeMXBean().getClassPath()); String jvmmempc = null; String jvmmemmax = null; boolean debug = false; boolean wait = true; boolean quiet = false; + boolean headless = false; + boolean gui = false; + boolean stdout = false; // must set --debug before --launcher... boolean launcherstop = false; boolean launcherprint = false; boolean launcherwait = false; ArrayList arguments = new ArrayList<>(); + String previousArg = null; for (String arg : args) { if (arg.equals("--debug")) @@ -142,6 +95,19 @@ public class Launcher { quiet = true; } + if (arg.equals("--headless")) + { + headless = true; + } + if (arg.equals("--gui")) + { + gui = true; + } + if (arg.equals("--output=-") + || (arg.equals("-") && "--output".equals(previousArg))) + { + stdout = true; + } if (debug && arg.equals("--launcherprint")) { launcherprint = true; @@ -159,6 +125,7 @@ public class Launcher { wait = false; } + previousArg = arg; // Don't add the --launcher... args to Jalview launch if (arg.startsWith("--launcher")) { @@ -199,6 +166,29 @@ public class Launcher arguments.add(arg); } } + if (gui) + { + // --gui takes precedence over --headless + headless = false; + } + + final String appName = ChannelProperties.getProperty("app_name"); + + // if we're using jalview.bin.Launcher we always assume a console is in use + final String javaBin = LaunchUtils.findJavaBin(true); + + List command = new ArrayList<>(); + command.add(javaBin); + + String memSetting = null; + + for (String jvmArg : ManagementFactory.getRuntimeMXBean() + .getInputArguments()) + { + command.add(jvmArg); + } + command.add("-cp"); + command.add(ManagementFactory.getRuntimeMXBean().getClassPath()); // use saved preferences if no cmdline args boolean useCustomisedSettings = LaunchUtils @@ -221,6 +211,7 @@ public class Launcher boolean memSet = false; boolean dockIcon = false; boolean dockName = false; + boolean headlessProp = false; for (int i = 0; i < command.size(); i++) { String arg = command.get(i); @@ -241,6 +232,10 @@ public class Launcher { dockName = true; } + else if (arg.startsWith("-D" + headlessProperty + "=")) + { + headlessProp = true; + } } if (!memSet) @@ -255,7 +250,7 @@ public class Launcher } } - if (isAMac) + if (LaunchUtils.isMac) { if (!dockIcon) { @@ -276,11 +271,16 @@ public class Launcher + appName); } } + if (headless && !headlessProp) + { + System.setProperty(headlessProperty, "true"); + command.add("-D" + headlessProperty + "=true"); + } String scalePropertyArg = HiDPISetting.getScalePropertyArg(); if (scalePropertyArg != null) { - sysout(debug, quiet, "Running " + startClass + " with scale setting " + syserr(debug, quiet, "Running " + startClass + " with scale setting " + scalePropertyArg); command.add(scalePropertyArg); } @@ -293,10 +293,10 @@ public class Launcher if ((Boolean.parseBoolean(System.getProperty("launcherprint", "false")) || launcherprint)) { - sysout(debug, quiet, + syserr(debug, quiet, "LAUNCHER COMMAND: " + String.join(" ", builder.command())); } - sysout(debug, quiet, + syserr(debug, quiet, "Running " + startClass + " with " + (memSetting == null ? "no memory setting" : ("memory setting " + memSetting))); @@ -304,7 +304,7 @@ public class Launcher if (Boolean.parseBoolean(System.getProperty("launcherstop", "false")) || (debug && launcherstop)) { - sysout(debug, quiet, + syserr(debug, quiet, "System property 'launcherstop' is set and not 'false'. Exiting."); System.exit(0); } @@ -314,22 +314,23 @@ public class Launcher Process process = builder.start(); if (wait || launcherwait) { - sysout(debug, quiet, "Launching application process"); + syserr(debug, quiet, "Launching application process"); process.waitFor(); } else { int waitInt = 0; - sysout(debug, quiet, + syserr(debug, quiet, "Wait time for application process is " + waitInt + "ms"); process.waitFor(waitInt, TimeUnit.MILLISECONDS); } - sysout(debug, quiet, "Launcher process ending"); + syserr(debug, quiet, "Launcher process ending"); } catch (IOException e) { if (e.getMessage().toLowerCase(Locale.ROOT).contains("memory")) { - System.err.println("Caught a memory exception: " + e.getMessage()); + jalview.bin.Console + .errPrintln("Caught a memory exception: " + e.getMessage()); // Probably the "Cannot allocate memory" error, try without the memory // setting ArrayList commandNoMem = new ArrayList<>(); @@ -342,7 +343,7 @@ public class Launcher } final ProcessBuilder builderNoMem = new ProcessBuilder( commandNoMem); - System.err.println("Command without memory setting: " + jalview.bin.Console.errPrintln("Command without memory setting: " + String.join(" ", builderNoMem.command())); try { @@ -364,11 +365,11 @@ public class Launcher } } - private static void sysout(boolean debug, boolean quiet, String message) + private static void syserr(boolean debug, boolean quiet, String message) { if (debug && !quiet) { - System.out.println("LAUNCHERDEBUG - " + message); + jalview.bin.Console.errPrintln("LAUNCHERDEBUG - " + message); } } diff --git a/src/jalview/bin/MemorySetting.java b/src/jalview/bin/MemorySetting.java index bb545cb..7458d55 100644 --- a/src/jalview/bin/MemorySetting.java +++ b/src/jalview/bin/MemorySetting.java @@ -354,7 +354,7 @@ public class MemorySetting else { // number too big for a Long. Limit to Long.MAX_VALUE - System.out.println("Memory parsing of '" + memString + jalview.bin.Console.outPrintln("Memory parsing of '" + memString + "' produces number too big. Limiting to Long.MAX_VALUE=" + Long.MAX_VALUE); return Long.MAX_VALUE; @@ -395,7 +395,7 @@ public class MemorySetting ADJUSTMENT_MESSAGE = reason; if (!quiet) { - System.out.println(reason); + jalview.bin.Console.outPrintln(reason); } } diff --git a/src/jalview/bin/argparser/Arg.java b/src/jalview/bin/argparser/Arg.java index 2f25978..93156ac 100644 --- a/src/jalview/bin/argparser/Arg.java +++ b/src/jalview/bin/argparser/Arg.java @@ -19,7 +19,7 @@ public enum Arg // Initialising arguments (BOOTSTRAP) HELP(Type.HELP, "h", "Display basic help", Opt.UNARY, Opt.BOOTSTRAP, - Opt.HASTYPE, Opt.MULTI), + Opt.HASTYPE, Opt.MULTIVALUE), /* * Other --help-type Args will be added by the static block. */ @@ -29,8 +29,8 @@ public enum Arg Opt.UNARY, Opt.BOOTSTRAP), HEADLESS(Type.CONFIG, "Run Jalview in headless mode. No GUI interface will be created and Jalview will quit after all arguments have been processed. " - + "Headless mode is assumed if an output file is to be generated, this can be overridden with --noheadless or --gui.", - Opt.BOOLEAN, Opt.BOOTSTRAP), + + "Headless mode is assumed if an output file is to be generated, this can be overridden with --gui.", + Opt.UNARY, Opt.BOOTSTRAP), GUI(Type.CONFIG, "Do not run Jalview in headless mode. This overrides the assumption of headless mode when an output file is to be generated.", Opt.UNARY, Opt.BOOTSTRAP), @@ -44,6 +44,8 @@ public enum Arg QUESTIONNAIRE(Type.CONFIG, "Show (or don't show) the questionnaire if one is available.", true, Opt.BOOLEAN, Opt.BOOTSTRAP), + JAVACONSOLE(Type.CONFIG, "Show (or don't show) the Java Console.", false, + Opt.BOOLEAN, Opt.BOOTSTRAP), NOUSAGESTATS(Type.CONFIG, "Don't send initial launch usage stats.", Opt.UNARY, Opt.BOOTSTRAP), NOSTARTUPFILE(Type.CONFIG, "Don't show the default startup file.", @@ -62,27 +64,28 @@ public enum Arg Opt.BOOTSTRAP, Opt.SECRET), QUIET(Type.CONFIG, "q", "Stop all output to STDOUT (after the Java Virtual Machine has started). Use ‑‑quiet a second time to stop all output to STDERR.", - Opt.UNARY, Opt.MULTI, Opt.BOOTSTRAP), + Opt.UNARY, Opt.MULTIVALUE, Opt.BOOTSTRAP), INITSUBSTITUTIONS(Type.CONFIG, "Set ‑‑substitutions to be initially enabled (or initially disabled).", true, Opt.BOOLEAN, Opt.BOOTSTRAP, Opt.NOACTION, Opt.SECRET), P(Type.CONFIG, "Set a Jalview preference value for this session.", Opt.PREFIXKEV, Opt.PRESERVECASE, Opt.STRING, Opt.BOOTSTRAP, - Opt.MULTI, Opt.NOACTION, Opt.SECRET), // keep this secret for now. + Opt.MULTIVALUE, Opt.NOACTION, Opt.SECRET), // keep this secret for + // now. // Opening an alignment OPEN(Type.OPENING, "Opens one or more alignment files or URLs in new alignment windows.", - Opt.STRING, Opt.LINKED, Opt.INCREMENTDEFAULTCOUNTER, Opt.MULTI, - Opt.GLOB, Opt.ALLOWSUBSTITUTIONS, Opt.INPUT, Opt.STORED, - Opt.PRIMARY), + Opt.STRING, Opt.LINKED, Opt.INCREMENTDEFAULTCOUNTER, + Opt.MULTIVALUE, Opt.GLOB, Opt.ALLOWSUBSTITUTIONS, Opt.INPUT, + Opt.STORED, Opt.PRIMARY), APPEND(Type.OPENING, "Appends one or more alignment files or URLs to the open alignment window (or opens a new alignment if none already open).", - Opt.STRING, Opt.LINKED, Opt.MULTI, Opt.GLOB, + Opt.STRING, Opt.LINKED, Opt.MULTIVALUE, Opt.GLOB, Opt.ALLOWSUBSTITUTIONS, Opt.INPUT, Opt.PRIMARY), TITLE(Type.OPENING, "Specifies the title for the open alignment window as string.", - Opt.STRING, Opt.LINKED), + Opt.STRING, Opt.LINKED, Opt.ALLOWMULTIID), COLOUR(Type.OPENING, "color", // being a bit soft on the Americans! "Applies the colour scheme to the open alignment window. Valid values include:\n" + "clustal,\n" + "blosum62,\n" + "pc-identity,\n" @@ -93,103 +96,122 @@ public enum Arg + "turn-propensity,\n" + "buried-index,\n" + "nucleotide,\n" + "nucleotide-ambiguity,\n" + "purine-pyrimidine,\n" + "rna-helices,\n" - + "t-coffee-scores,\n" + "sequence-id.\n" - +"\n" + + "t-coffee-scores,\n" + "sequence-id.\n" + "\n" + "Names of user defined colourschemes will also work,\n" - +"and jalview colourscheme specifications like\n" - +"--colour=\"D,E=red; K,R,H=0022FF; C,c=yellow\"", - Opt.STRING, Opt.LINKED, Opt.ALLOWALL), + + "and jalview colourscheme specifications like\n" + + "--colour=\"D,E=red; K,R,H=0022FF; C,c=yellow\"", + Opt.STRING, Opt.LINKED, Opt.ALLOWMULTIID), FEATURES(Type.OPENING, "Add a feature file or URL to the open alignment.", - Opt.STRING, Opt.LINKED, Opt.MULTI, Opt.ALLOWSUBSTITUTIONS), + Opt.STRING, Opt.LINKED, Opt.MULTIVALUE, Opt.ALLOWSUBSTITUTIONS, + Opt.ALLOWMULTIID), TREE(Type.OPENING, "Add a tree file or URL to the open alignment.", - Opt.STRING, Opt.LINKED, Opt.MULTI, Opt.ALLOWSUBSTITUTIONS), + Opt.STRING, Opt.LINKED, Opt.MULTIVALUE, Opt.ALLOWSUBSTITUTIONS, + Opt.ALLOWMULTIID), SORTBYTREE(Type.OPENING, "Enforces sorting (or not sorting) the open alignment in the order of an attached phylogenetic tree.", - true, Opt.LINKED, Opt.BOOLEAN, Opt.ALLOWALL), + true, Opt.LINKED, Opt.BOOLEAN, Opt.ALLOWMULTIID), ANNOTATIONS(Type.OPENING, "Add an annotations file or URL to the open alignment.", - Opt.STRING, Opt.LINKED, Opt.MULTI, Opt.ALLOWSUBSTITUTIONS), + Opt.STRING, Opt.LINKED, Opt.MULTIVALUE, Opt.ALLOWSUBSTITUTIONS, + Opt.ALLOWMULTIID), SHOWANNOTATIONS(Type.OPENING, "Enforces showing (or not showing) alignment annotations.", - Opt.BOOLEAN, Opt.LINKED, Opt.ALLOWALL), + Opt.BOOLEAN, Opt.LINKED, Opt.ALLOWMULTIID, Opt.ALLOWMULTIID), WRAP(Type.OPENING, "Enforces wrapped (or not wrapped) alignment formatting.", - Opt.BOOLEAN, Opt.LINKED, Opt.ALLOWALL), + Opt.BOOLEAN, Opt.LINKED, Opt.ALLOWMULTIID, Opt.ALLOWMULTIID), NOSTRUCTURE(Type.OPENING, "Do not open or process any 3D structure in the ‑‑open or ‑‑append files.", - Opt.UNARY, Opt.LINKED, Opt.ALLOWALL), + Opt.UNARY, Opt.LINKED, Opt.ALLOWMULTIID, Opt.ALLOWMULTIID), // Adding a 3D structure STRUCTURE(Type.STRUCTURE, "Load a structure file or URL associated with a sequence in the open alignment.\n" + "The sequence to be associated with can be specified with a following --seqid argument, or the subval modifier seqid=ID can be used. A subval INDEX can also be used to specify the INDEX-th sequence in the open alignment.", - Opt.STRING, Opt.LINKED, Opt.MULTI, Opt.ALLOWSUBSTITUTIONS, - Opt.PRIMARY), + Opt.STRING, Opt.LINKED, Opt.MULTIVALUE, Opt.ALLOWSUBSTITUTIONS, + Opt.PRIMARY, Opt.ALLOWMULTIID), SEQID(Type.STRUCTURE, "Specify the sequence name for the preceding --structure to be associated with.", - Opt.STRING, Opt.LINKED, Opt.MULTI, Opt.ALLOWSUBSTITUTIONS), + Opt.STRING, Opt.LINKED, Opt.MULTIVALUE, Opt.ALLOWSUBSTITUTIONS, + Opt.ALLOWMULTIID), PAEMATRIX(Type.STRUCTURE, "Add a PAE json matrix file to the preceding --structure.", - Opt.STRING, Opt.LINKED, Opt.MULTI, Opt.ALLOWSUBSTITUTIONS), + Opt.STRING, Opt.LINKED, Opt.MULTIVALUE, Opt.ALLOWSUBSTITUTIONS, + Opt.ALLOWMULTIID), TEMPFAC(Type.STRUCTURE, "Set the type of temperature factor. Possible values are:\n" + "default,\n" + "plddt.", - Opt.STRING, Opt.LINKED), + Opt.STRING, Opt.LINKED, Opt.MULTIVALUE, Opt.ALLOWMULTIID), STRUCTUREVIEWER(Type.STRUCTURE, "Set the structure viewer to use to open the 3D structure file specified in previous --structure to name. Possible values of name are:\n" + "none,\n" + "jmol,\n" + "chimera,\n" + "chimerax,\n" + "pymol.", - Opt.STRING, Opt.LINKED, Opt.MULTI), + Opt.STRING, Opt.LINKED, Opt.MULTIVALUE, Opt.ALLOWMULTIID), NOTEMPFAC(Type.STRUCTURE, "Do not show the temperature factor annotation for the preceding --structure.", - Opt.UNARY, Opt.LINKED, Opt.ALLOWALL, Opt.SECRET), // keep this secret - // until it works! + Opt.UNARY, Opt.LINKED, Opt.ALLOWMULTIID, Opt.SECRET), // keep this + // secret until + // it works! SHOWSSANNOTATIONS(Type.STRUCTURE, null, Opt.BOOLEAN, Opt.LINKED, - Opt.ALLOWALL), + Opt.ALLOWMULTIID), // Outputting files IMAGE(Type.IMAGE, "Output an image of the open alignment window. Format is specified by the subval modifier, a following --type argument or guessed from the file extension. Valid formats/extensions are:\n" + "svg,\n" + "png,\n" + "eps,\n" + "html,\n" + "biojs.", - Opt.STRING, Opt.LINKED, Opt.ALLOWSUBSTITUTIONS, Opt.ALLOWALL, - Opt.REQUIREINPUT, Opt.OUTPUTFILE, Opt.PRIMARY), + Opt.STRING, Opt.LINKED, Opt.ALLOWSUBSTITUTIONS, Opt.MULTIVALUE, + Opt.ALLOWMULTIID, Opt.REQUIREINPUT, Opt.OUTPUTFILE, Opt.PRIMARY), + STRUCTUREIMAGE(Type.IMAGE, + "Export an image of a 3D structure opened in JMOL", Opt.STRING, + Opt.LINKED, Opt.MULTIVALUE, Opt.OUTPUTFILE, Opt.ALLOWMULTIID, + Opt.PRIMARY), TYPE(Type.IMAGE, - "Set the image format for the preceding --image. Valid values are:\n" - + "svg,\n" + "png,\n" + "eps,\n" + "html,\n" + "biojs.", - Opt.STRING, Opt.LINKED, Opt.ALLOWALL), + "Set the image format for the preceding " + Arg.IMAGE.argString() + + " or " + Arg.STRUCTUREIMAGE.argString() + + ". Valid values are:\n" + "svg,\n" + "png,\n" + "eps,\n" + + "html,\n" + "biojs.", + Opt.STRING, Opt.LINKED, Opt.MULTIVALUE, Opt.ALLOWMULTIID), TEXTRENDERER(Type.IMAGE, "Sets whether text in a vector image format (SVG, HTML, EPS) should be rendered as text or vector line-art. Possible values are:\n" + "text,\n" + "lineart.", - Opt.STRING, Opt.LINKED, Opt.ALLOWALL), + Opt.STRING, Opt.LINKED, Opt.MULTIVALUE, Opt.ALLOWMULTIID), SCALE(Type.IMAGE, "Sets a scaling for bitmap image format (PNG). Should be given as a floating point number. If used in conjunction with --width and --height then the smallest scaling will be used (scale, width and height provide bounds for the image).", - Opt.STRING, Opt.LINKED, Opt.ALLOWALL), + Opt.STRING, Opt.LINKED, Opt.MULTIVALUE, Opt.ALLOWMULTIID), WIDTH(Type.IMAGE, "Sets a width for bitmap image format (PNG) with the height maintaining the aspect ratio. Should be given as a positive integer. If used in conjunction with --scale and --height then the smallest scaling will be used (scale, width and height provide bounds for the image).", - Opt.STRING, Opt.LINKED, Opt.ALLOWALL), + Opt.STRING, Opt.LINKED, Opt.MULTIVALUE, Opt.ALLOWMULTIID), HEIGHT(Type.IMAGE, "Sets a height for bitmap image format (PNG) with the width maintaining the aspect ratio. Should be given as a positive integer. If used in conjunction with --scale and --width then the smallest scaling will be used (scale, width and height provide bounds for the image).", - Opt.STRING, Opt.LINKED, Opt.ALLOWALL), - STRUCTUREIMAGE(Type.STRUCTUREIMAGE, - "Export an image of a 3D structure opened in JMOL", Opt.STRING, - Opt.LINKED, Opt.MULTI, Opt.OUTPUTFILE), - STRUCTUREIMAGETYPE(Type.STRUCTUREIMAGE, + Opt.STRING, Opt.LINKED, Opt.MULTIVALUE, Opt.ALLOWMULTIID), + IMAGECOLOUR(Type.IMAGE, "imagecolor", // being a bit soft on the Americans! + "Applies the colour scheme to the open alignment window for this image, otherwise the value of " + + Arg.COLOUR.argString() + + " (or none) will apply. Valid values are the same as " + + Arg.COLOUR.argString() + ".", + Opt.STRING, Opt.LINKED, Opt.MULTIVALUE, Opt.ALLOWMULTIID), + BGCOLOUR(Type.IMAGE, "bgcolor", // being a bit soft on the Americans! + "Applies a background colour to the structure image. Valid values are named colours known to Java or RRGGBB 6 digit hex-string.", + Opt.STRING, Opt.LINKED, Opt.MULTIVALUE, Opt.ALLOWMULTIID), + /* + STRUCTUREIMAGETYPE(Type.IMAGE, "Set the structure image format for the preceding --structureimage. Valid values are:\n" + "svg,\n" + "png,\n" + "eps,\n" + "html,\n" + "biojs.", - Opt.STRING, Opt.LINKED, Opt.ALLOWALL), - STRUCTUREIMAGETEXTRENDERER(Type.STRUCTUREIMAGE, + Opt.STRING, Opt.LINKED, Opt.ALLOWMULTIID), + STRUCTUREIMAGETEXTRENDERER(Type.IMAGE, "Sets whether text in a vector structure image format (SVG, EPS) should be rendered as text or vector line-art. Possible values are:\n" + "text,\n" + "lineart.", - Opt.STRING, Opt.LINKED, Opt.ALLOWALL), - STRUCTUREIMAGESCALE(Type.STRUCTUREIMAGE, + Opt.STRING, Opt.LINKED, Opt.ALLOWMULTIID), + STRUCTUREIMAGESCALE(Type.IMAGE, "Sets a scaling for bitmap structure image format (PNG). Should be given as a floating point number. If used in conjunction with --structureimagewidth and --structureimageheight then the smallest scaling will be used (structureimagescale, structureimagewidth and structureimageheight provide bounds for the structure image).", - Opt.STRING, Opt.LINKED, Opt.ALLOWALL), - STRUCTUREIMAGEWIDTH(Type.STRUCTUREIMAGE, + Opt.STRING, Opt.LINKED, Opt.ALLOWMULTIID), + STRUCTUREIMAGEWIDTH(Type.IMAGE, "Sets a width for bitmap structure image format (PNG) with the height maintaining the aspect ratio. Should be given as a positive integer. If used in conjunction with --structureimagescale and --structureimageheight then the smallest scaling will be used (structureimagescale, structureimagewidth and structureimageheight provide bounds for the structure image).", - Opt.STRING, Opt.LINKED, Opt.ALLOWALL), - STRUCTUREIMAGEHEIGHT(Type.STRUCTUREIMAGE, + Opt.STRING, Opt.LINKED, Opt.ALLOWMULTIID), + STRUCTUREIMAGEHEIGHT(Type.IMAGE, "Sets a height for bitmap structure image format (PNG) with the width maintaining the aspect ratio. Should be given as a positive integer. If used in conjunction with --structureimagescale and --structureimagewidth then the smallest scaling will be used (structureimagescale, structureimagewidth and structureimageheight provide bounds for the structure image).", - Opt.STRING, Opt.LINKED, Opt.ALLOWALL), + Opt.STRING, Opt.LINKED, Opt.ALLOWMULTIID), + */ OUTPUT(Type.OUTPUT, "Export the open alignment to file filename. The format name is specified by the subval modifier format=name, a following --format name argument or guessed from the file extension. Valid format names (and file extensions) are:\n" @@ -199,32 +221,36 @@ public enum Arg + "pileup (pileup),\n" + "msf (msf),\n" + "clustal (aln),\n" + "phylip (phy),\n" + "jalview (jvp, jar).", - Opt.STRING, Opt.LINKED, Opt.ALLOWSUBSTITUTIONS, Opt.ALLOWALL, - Opt.REQUIREINPUT, Opt.OUTPUTFILE, Opt.PRIMARY), + Opt.STRING, Opt.LINKED, Opt.ALLOWSUBSTITUTIONS, Opt.ALLOWMULTIID, + Opt.REQUIREINPUT, Opt.OUTPUTFILE, Opt.STDOUT, Opt.PRIMARY), FORMAT(Type.OUTPUT, "Sets the format for the preceding --output file. Valid formats are:\n" + "fasta,\n" + "pfam,\n" + "stockholm,\n" + "pir,\n" + "blc,\n" + "amsa,\n" + "json,\n" + "pileup,\n" + "msf,\n" + "clustal,\n" + "phylip,\n" + "jalview.", - Opt.STRING, Opt.LINKED, Opt.ALLOWALL), + Opt.STRING, Opt.LINKED, Opt.ALLOWMULTIID), GROOVY(Type.PROCESS, "Process a groovy script in the file for the open alignment.", - Opt.STRING, Opt.LINKED, Opt.MULTI, Opt.ALLOWSUBSTITUTIONS, - Opt.ALLOWALL), + Opt.STRING, Opt.LINKED, Opt.MULTIVALUE, Opt.ALLOWSUBSTITUTIONS, + Opt.ALLOWMULTIID), BACKUPS(Type.OUTPUT, "Enable (or disable) writing backup files when saving an ‑‑output file. This applies to the current open alignment. To apply to all ‑‑output and ‑‑image files, use after ‑‑all.", - true, Opt.BOOLEAN, Opt.LINKED, Opt.ALLOWALL), + true, Opt.BOOLEAN, Opt.LINKED, Opt.ALLOWMULTIID), OVERWRITE(Type.OUTPUT, "Enable (or disable) overwriting of output files without backups enabled. This applies to the current open alignment. To apply to all ‑‑output and ‑‑image files, use after ‑‑all.", - Opt.BOOLEAN, Opt.LINKED, Opt.ALLOWALL), + Opt.BOOLEAN, Opt.LINKED, Opt.ALLOWMULTIID), CLOSE(Type.OPENING, "Close the current open alignment window. This occurs after other output arguments. This applies to the current open alignment. To apply to all ‑‑output and ‑‑image files, use after ‑‑all.", - Opt.UNARY, Opt.LINKED, Opt.ALLOWALL), + Opt.UNARY, Opt.LINKED, Opt.ALLOWMULTIID), + MKDIRS(Type.OUTPUT, + "Automatically create directories when outputting a file to a new directory.", + Opt.UNARY, Opt.LINKED, Opt.ALLOWMULTIID), // controlling flow of arguments NEW(Type.FLOW, "Move on to a new alignment window. This will ensure --append will start a new alignment window and other linked arguments will apply to the new alignment window.", - Opt.UNARY, Opt.MULTI, Opt.NOACTION, Opt.INCREMENTDEFAULTCOUNTER), + Opt.UNARY, Opt.MULTIVALUE, Opt.NOACTION, + Opt.INCREMENTDEFAULTCOUNTER), SUBSTITUTIONS(Type.FLOW, "The following argument values allow (or don't allow) subsituting filename parts. This is initially true. Valid substitutions are:\n" + "{basename} - the filename-without-extension of the currently --opened file (or first --appended file),\n" @@ -234,22 +260,22 @@ public enum Arg + "{n} - the value of the index counter (starting at 0).\n" + "{++n} - increase and substitute the value of the index counter,\n" + "{} - the value of the current alignment window default index.", - true, Opt.BOOLEAN, Opt.MULTI, Opt.NOACTION), + true, Opt.BOOLEAN, Opt.MULTIVALUE, Opt.NOACTION), ARGFILE(Type.FLOW, "Open one or more files filename and read, line-by-line, as arguments to Jalview.\n" + "Values in an argfile should be given with an equals sign (\"=\") separator with no spaces.\n" + "Note that if you use one or more --argfile arguments then all other non-initialising arguments will be ignored.", - Opt.STRING, Opt.MULTI, Opt.BOOTSTRAP, Opt.GLOB, + Opt.STRING, Opt.MULTIVALUE, Opt.BOOTSTRAP, Opt.GLOB, Opt.ALLOWSUBSTITUTIONS), NPP(Type.FLOW, "n++", "Increase the index counter used in argument value substitutions.", - Opt.UNARY, Opt.MULTI, Opt.NOACTION), + Opt.UNARY, Opt.MULTIVALUE, Opt.NOACTION), ALL(Type.FLOW, "Apply the following output arguments to all sets of linked arguments.", - Opt.BOOLEAN, Opt.MULTI, Opt.NOACTION), + Opt.BOOLEAN, Opt.MULTIVALUE, Opt.NOACTION), OPENED(Type.FLOW, "Apply the following output arguments to all of the last --open'ed set of linked arguments.", - Opt.BOOLEAN, Opt.MULTI, Opt.NOACTION), + Opt.BOOLEAN, Opt.MULTIVALUE, Opt.NOACTION), QUIT(Type.FLOW, "After all files have been opened, appended and output, quit Jalview. In ‑‑headless mode this already happens.", Opt.UNARY), @@ -258,26 +284,27 @@ public enum Arg Opt.UNARY, Opt.SECRET), ALLSTRUCTURES(Type.FLOW, "Apply the following 3D structure formatting arguments to all structures within the open alignment.", - Opt.BOOLEAN, Opt.MULTI, Opt.NOACTION), + Opt.BOOLEAN, Opt.MULTIVALUE, Opt.NOACTION), // secret options TESTOUTPUT(Type.CONFIG, "Allow specific stdout information. For testing purposes only.", Opt.UNARY, Opt.BOOTSTRAP, Opt.SECRET), // do not show this to the user SETPROP(Type.CONFIG, "Set an individual Java System property.", - Opt.STRING, Opt.MULTI, Opt.BOOTSTRAP, Opt.SECRET), // not in use yet + Opt.STRING, Opt.MULTIVALUE, Opt.BOOTSTRAP, Opt.SECRET), // not in use + // yet NIL(Type.FLOW, "This argument does nothing on its own, but can be used with linkedIds.", - Opt.UNARY, Opt.LINKED, Opt.MULTI, Opt.NOACTION, Opt.SECRET), + Opt.UNARY, Opt.LINKED, Opt.MULTIVALUE, Opt.NOACTION, Opt.SECRET), // private options (inserted during arg processing) SETARGFILE(Type.FLOW, "Sets the current value of the argfilename. Inserted before argfilecontents.", - Opt.UNARY, Opt.LINKED, Opt.STRING, Opt.MULTI, Opt.PRIVATE, + Opt.UNARY, Opt.LINKED, Opt.STRING, Opt.MULTIVALUE, Opt.PRIVATE, Opt.NOACTION), UNSETARGFILE(Type.FLOW, "Unsets the current value of the argfilename. Inserted after argfile contents.", - Opt.UNARY, Opt.LINKED, Opt.MULTI, Opt.PRIVATE, Opt.NOACTION), + Opt.UNARY, Opt.LINKED, Opt.MULTIVALUE, Opt.PRIVATE, Opt.NOACTION), // these last two have no purpose in the normal Jalview application but are // used by jalview.bin.Launcher to set memory settings. They are not used by @@ -316,7 +343,7 @@ public enum Arg * A MULTI Arg can be specified multiple times. * Multiple values are stored in the ArgValuesMap (along with their positional index) for each linkedId. */ - MULTI("can be specified multiple times"), + MULTIVALUE("can be specified multiple times"), /* * A Linked Arg can be linked to others through a --arg[linkedId] or --arg[linkedId]=value. * If no linkedId is specified then the current default linkedId will be used. @@ -363,7 +390,7 @@ public enum Arg /* * An ALLOWALL Arg can use the '*' linkedId to apply to all known linkedIds */ - ALLOWALL("can be used with " + ArgParser.DOUBLEDASH + "all"), + ALLOWMULTIID("can be used with " + ArgParser.DOUBLEDASH + "all"), /* * If an Arg has the INCREMENTDEFAULTCOUNTER option and the default linkedId is used, * the defaultLinkedIdCounter is incremented *first*. @@ -384,6 +411,11 @@ public enum Arg */ OUTPUTFILE("output file --headless will be assumed unless --gui used"), /* + * A STDOUT Arg can take an output filename that can be '-' to mean print to STDOUT. + */ + STDOUT("allows the output filename '" + ArgParser.STDOUTFILENAME + + "' to mean output to STDOUT"), + /* * A STORED Arg resets and creates a new set of "opened" linkedIds */ STORED(null), @@ -447,8 +479,9 @@ public enum Arg STRUCTURE("arguments used to add and format 3D structure data"), PROCESS("arguments used to process an alignment once opened"), OUTPUT("arguments used to save data from a processed alignment"), - IMAGE("arguments used to export an image of an alignment"), - STRUCTUREIMAGE("arguments used to export an image of an structure"), + IMAGE("arguments used to export an image of an alignment or structure"), + // IMAGE("arguments used to export an image of an alignment"), + // STRUCTUREIMAGE("arguments used to export an image of an structure"), FLOW("arguments that control processing of the other arguments"), // ALL("all arguments"), // mostly just a place-holder for --help-all NONE, // mostly a place-holder for --help diff --git a/src/jalview/bin/argparser/ArgParser.java b/src/jalview/bin/argparser/ArgParser.java index 907b1fa..155f69e 100644 --- a/src/jalview/bin/argparser/ArgParser.java +++ b/src/jalview/bin/argparser/ArgParser.java @@ -31,12 +31,11 @@ import java.util.EnumSet; import java.util.Enumeration; import java.util.HashMap; import java.util.List; -import java.util.Locale; import java.util.Map; -import jalview.bin.Cache; import jalview.bin.Console; import jalview.bin.Jalview; +import jalview.bin.Jalview.ExitCode; import jalview.bin.argparser.Arg.Opt; import jalview.bin.argparser.Arg.Type; import jalview.util.FileUtils; @@ -50,6 +49,8 @@ public class ArgParser public static final char EQUALS = '='; + public static final String STDOUTFILENAME = "-"; + protected static final String NEGATESTRING = "no"; /** @@ -118,6 +119,46 @@ public class ArgParser private static final String LINKEDIDDIRNAME = "{dirname}"; /** + * On-the-fly substitution (not made at argument parsing time)! the current + * structure filename extension + */ + private static final String STRUCTUREEXTENSION = "{structureextension}"; + + /** + * On-the-fly substitution (not made at argument parsing time)! the current + * structure filename base + */ + private static final String STRUCTUREBASENAME = "{structurebasename}"; + + /** + * On-the-fly substitution (not made at argument parsing time)! the current + * structure filename dir path + */ + private static final String STRUCTUREDIRNAME = "{structuredirname}"; + + /** + * On-the-fly substitution (not made at argument parsing time)! increment the + * on-the-fly counter and substitute the incremented value + */ + private static final String INCREMENTONTHEFLYCOUNTER = "{++m}"; + + /** + * On-the-fly substitution (not made at argument parsing time)! the current + * substitute with the on-the-fly counter + */ + private static final String ONTHEFLYCOUNTER = "{m}"; + + /** + * the string used for on-the-fly structure filename substitutions + */ + private String currentStructureFilename = null; + + /** + * the counter used for on-the-fly {m} substitutions + */ + private int ontheflyCounter = 0; + + /** * the current argfile */ private String argFile = null; @@ -148,12 +189,6 @@ public class ArgParser private boolean allLinkedIds = false; /** - * flag to say whether the default linkedId is the current default linked id - * or OPENED linkedIds - */ - private boolean openedLinkedIds = false; - - /** * flag to say whether the structure arguments should be applied to all * structures with this linked id */ @@ -175,6 +210,15 @@ public class ArgParser private BootstrapArgs bootstrapArgs = null; + private boolean oldArguments = false; + + private boolean mixedArguments = false; + + /** + * saved examples of mixed arguments + */ + private String[] mixedExamples = new String[] { null, null }; + static { argMap = new HashMap<>(); @@ -209,12 +253,15 @@ public class ArgParser public ArgParser(String[] args, boolean initsubstitutions, BootstrapArgs bsa) { - // Make a mutable new ArrayList so that shell globbing parser works. - // (When shell file globbing is used, there are a sequence of non-Arg - // arguments (which are the expanded globbed filenames) that need to be - // consumed by the --append/--argfile/etc Arg which is most easily done by - // removing these filenames from the list one at a time. This can't be done - // with an ArrayList made with only Arrays.asList(String[] args). ) + /* + * Make a mutable new ArrayList so that shell globbing parser works. + * (When shell file globbing is used, there are a sequence of non-Arg + * arguments (which are the expanded globbed filenames) that need to be + * consumed by the --append/--argfile/etc Arg which is most easily done + * by removing these filenames from the list one at a time. This can't be + * done with an ArrayList made with only Arrays.asList(String[] args) as + * that is not mutable. ) + */ this(new ArrayList<>(Arrays.asList(args)), initsubstitutions, false, bsa); } @@ -236,23 +283,48 @@ public class ArgParser if (arg.startsWith(DOUBLEDASH)) { dd = true; - break; + if (mixedExamples[1] == null) + { + mixedExamples[1] = arg; + } } - else if (arg.startsWith("-") || arg.equals("open")) + else if ((arg.startsWith("-") && !arg.equals(STDOUTFILENAME)) + || arg.equals("open")) { d = true; + if (mixedExamples[0] == null) + { + mixedExamples[0] = arg; + } } } - if (d && !dd) + if (d) + { + if (dd) + { + mixedArguments = true; + } + else + { + oldArguments = true; + } + } + + if (oldArguments || mixedArguments) { // leave it to the old style -- parse an empty list parse(new ArrayList(), false, false); return; } + if (bsa != null) + { this.bootstrapArgs = bsa; + } else + { this.bootstrapArgs = BootstrapArgs.getBootstrapArgs(args); + } parse(args, initsubstitutions, allowPrivate); } @@ -260,27 +332,30 @@ public class ArgParser boolean allowPrivate) { this.substitutions = initsubstitutions; - boolean openEachInitialFilenames = true; - for (int i = 0; i < args.size(); i++) - { - String arg = args.get(i); - // If the first arguments do not start with "--" or "-" or is not "open" - // and` is a filename that exists it is probably a file/list of files to - // open so we fake an Arg.OPEN argument and when adding files only add the - // single arg[i] and increment the defaultLinkedIdCounter so that each of - // these files is opened separately. - if (openEachInitialFilenames && !arg.startsWith(DOUBLEDASH) - && !arg.startsWith("-") && !arg.equals("open") - && (new File(arg).exists() - || HttpUtils.startsWithHttpOrHttps(arg))) - { - arg = Arg.OPEN.argString(); - } - else + /* + * If the first argument does not start with "--" or "-" or is not "open", + * and is a filename that exists or a URL, it is probably a file/list of + * files to open so we insert an Arg.OPEN argument before it. This will + * mean the list of files at the start of the arguments are all opened + * separately. + */ + if (args.size() > 0) + { + String arg0 = args.get(0); + if (arg0 != null + && (!arg0.startsWith(DOUBLEDASH) && !arg0.startsWith("-") + && !arg0.equals("open") && (new File(arg0).exists() + || HttpUtils.startsWithHttpOrHttps(arg0)))) { - openEachInitialFilenames = false; + // insert "--open" at the start + args.add(0, Arg.OPEN.argString()); } + } + + for (int i = 0; i < args.size(); i++) + { + String arg = args.get(i); // look for double-dash, e.g. --arg if (arg.startsWith(DOUBLEDASH)) @@ -371,10 +446,12 @@ public class ArgParser { // arg not found Console.error("Argument '" + arg + "' not recognised. Exiting."); - Jalview.exit("Invalid argument used." + System.lineSeparator() - + "Use" + System.lineSeparator() + "jalview " - + Arg.HELP.argString() + System.lineSeparator() - + "for a usage statement.", 13); + Jalview.exit( + "Invalid argument used." + System.lineSeparator() + "Use" + + System.lineSeparator() + "jalview " + + Arg.HELP.argString() + System.lineSeparator() + + "for a usage statement.", + ExitCode.INVALID_ARGUMENT); continue; } if (a.hasOption(Opt.PRIVATE) && !allowPrivate) @@ -431,7 +508,7 @@ public class ArgParser { // There is no "=" so value is next arg or args (possibly shell // glob-expanded) - if ((openEachInitialFilenames ? i : i + 1) >= args.size()) + if (i + 1 >= args.size()) { // no value to take for arg, which wants a value Console.error("Argument '" + a.getName() @@ -446,8 +523,7 @@ public class ArgParser { // if this is the first argument with a file list at the start of // the args we add filenames from index i instead of i+1 - globVals = getShellGlobbedFilenameValues(a, args, - openEachInitialFilenames ? i : i + 1); + globVals = getShellGlobbedFilenameValues(a, args, i + 1); } else { @@ -477,12 +553,6 @@ public class ArgParser else if (a == Arg.ALL) { allLinkedIds = !negated; - openedLinkedIds = false; - } - else if (a == Arg.OPENED) - { - openedLinkedIds = !negated; - allLinkedIds = false; } else if (a == Arg.ALLSTRUCTURES) { @@ -509,35 +579,25 @@ public class ArgParser { if (linkedId == null) { - if (a.hasOption(Opt.OUTPUTFILE) && a.hasOption(Opt.ALLOWALL) - && val.startsWith(MATCHALLLINKEDIDS)) + if (a.hasOption(Opt.OUTPUTFILE) && a.hasOption(Opt.ALLOWMULTIID) + && val.contains(MATCHALLLINKEDIDS)) { - // --output=*.ext is shorthand for --all --output {basename}.ext + // --output=*.ext is shorthand for --output {basename}.ext + // --output=*/*.ext is shorthand for + // --output {dirname}/{basename}.ext // (or --image=*.ext) - allLinkedIds = true; - openedLinkedIds = false; - linkedId = MATCHALLLINKEDIDS; - val = LINKEDIDDIRNAME + File.separator + LINKEDIDBASENAME - + val.substring(MATCHALLLINKEDIDS.length()); + linkedId = allLinkedIds ? MATCHALLLINKEDIDS + : MATCHOPENEDLINKEDIDS; + val = FileUtils.convertWildcardsToPath(val, MATCHALLLINKEDIDS, + LINKEDIDDIRNAME, LINKEDIDBASENAME); } - else if (a.hasOption(Opt.OUTPUTFILE) - && a.hasOption(Opt.ALLOWALL) - && val.startsWith(MATCHOPENEDLINKEDIDS)) - { - // --output=open*.ext is shorthand for --opened --output - // {basename}.ext - // (or --image=open*.ext) - openedLinkedIds = true; - allLinkedIds = false; - linkedId = MATCHOPENEDLINKEDIDS; - val = LINKEDIDDIRNAME + File.separator + LINKEDIDBASENAME - + val.substring(MATCHOPENEDLINKEDIDS.length()); - } - else if (allLinkedIds && a.hasOption(Opt.ALLOWALL)) + else if (allLinkedIds && a.hasOption(Opt.ALLOWMULTIID)) { linkedId = MATCHALLLINKEDIDS; } - else if (openedLinkedIds && a.hasOption(Opt.ALLOWALL)) + else if (a.hasOption(Opt.ALLOWMULTIID) + && this.storedLinkedIds != null + && this.storedLinkedIds.size() > 0) { linkedId = MATCHOPENEDLINKEDIDS; } @@ -601,10 +661,9 @@ public class ArgParser // set allstructures to all non-primary structure options in this linked // id if --allstructures has been set - if (allStructures - && (a.getType() == Type.STRUCTURE - || a.getType() == Type.STRUCTUREIMAGE) - && !a.hasOption(Opt.PRIMARY)) + if (allStructures && (a.getType() == Type.STRUCTURE + // || a.getType() == Type.STRUCTUREIMAGE) + ) && !a.hasOption(Opt.PRIMARY)) { if (!subvals.has(Arg.ALLSTRUCTURES.getName())) // && !subvals.has("structureid")) @@ -661,9 +720,8 @@ public class ArgParser // remove the '*' or 'open*' linkedId that should be empty if it was // created if ((MATCHALLLINKEDIDS.equals(linkedId) + || MATCHOPENEDLINKEDIDS.equals(linkedId)) && linkedArgs.containsKey(linkedId)) - || (MATCHOPENEDLINKEDIDS.equals(linkedId) - && linkedArgs.containsKey(linkedId))) { linkedArgs.remove(linkedId); } @@ -710,6 +768,12 @@ public class ArgParser public String makeSubstitutions(String val, String linkedId) { + return makeSubstitutions(val, linkedId, false); + } + + public String makeSubstitutions(String val, String linkedId, + boolean onthefly) + { if (!this.substitutions || val == null) return val; @@ -729,14 +793,20 @@ public class ArgParser rest = val; } if (rest.contains(LINKEDIDAUTOCOUNTER)) + { rest = rest.replace(LINKEDIDAUTOCOUNTER, String.valueOf(linkedIdAutoCounter)); + } if (rest.contains(INCREMENTLINKEDIDAUTOCOUNTER)) + { rest = rest.replace(INCREMENTLINKEDIDAUTOCOUNTER, String.valueOf(++linkedIdAutoCounter)); + } if (rest.contains(DEFAULTLINKEDIDCOUNTER)) + { rest = rest.replace(DEFAULTLINKEDIDCOUNTER, String.valueOf(defaultLinkedIdCounter)); + } ArgValuesMap avm = linkedArgs.get(linkedId); if (avm != null) { @@ -766,6 +836,32 @@ public class ArgParser FileUtils.getDirname(new File(argFile))); } } + if (onthefly) + { + if (rest.contains(ONTHEFLYCOUNTER)) + { + rest = rest.replace(ONTHEFLYCOUNTER, + String.valueOf(ontheflyCounter)); + } + if (rest.contains(INCREMENTONTHEFLYCOUNTER)) + { + rest = rest.replace(INCREMENTONTHEFLYCOUNTER, + String.valueOf(++ontheflyCounter)); + } + if (currentStructureFilename != null) + { + if (rest.contains(STRUCTUREBASENAME)) + { + rest = rest.replace(STRUCTUREBASENAME, FileUtils + .getBasename(new File(currentStructureFilename))); + } + if (rest.contains(STRUCTUREDIRNAME)) + { + rest = rest.replace(STRUCTUREDIRNAME, + FileUtils.getDirname(new File(currentStructureFilename))); + } + } + } return new StringBuilder(subvals).append(rest).toString(); } @@ -908,7 +1004,7 @@ public class ArgParser { String message = Arg.ARGFILE.argString() + EQUALS + "\"" + argFile.getPath() + "\": File does not exist."; - Jalview.exit(message, 2); + Jalview.exit(message, ExitCode.FILE_NOT_FOUND); } try { @@ -922,7 +1018,7 @@ public class ArgParser { String message = Arg.ARGFILE.argString() + "=\"" + argFile.getPath() + "\": File could not be read."; - Jalview.exit(message, 3); + Jalview.exit(message, ExitCode.FILE_NOT_READABLE); } } // Third param "true" uses Opt.PRIVATE args --setargile=argfile and @@ -948,167 +1044,12 @@ public class ArgParser String message = Arg.ARGFILE.argString() + "=\"" + argFile.getPath() + "\": File could not be read."; Console.debug(message, e); - Jalview.exit(message, 3); + Jalview.exit(message, ExitCode.FILE_NOT_READABLE); } } return args; } - public static enum Position - { - FIRST, BEFORE, AFTER - } - - /** - * get from following Arg of type a or subval of same name (lowercase) - */ - public static String getValueFromSubValOrArg(ArgValuesMap avm, - ArgValue av, Arg a, SubVals sv) - { - return getFromSubValArgOrPref(avm, av, a, sv, null, null, null); - } - - /** - * get from following Arg of type a or subval key or preference pref or - * default def - */ - public static String getFromSubValArgOrPref(ArgValuesMap avm, ArgValue av, - Arg a, SubVals sv, String key, String pref, String def) - { - return getFromSubValArgOrPref(avm, a, Position.AFTER, av, sv, key, pref, - def); - } - - /** - * get from following(AFTER), first occurence of (FIRST) or previous (BEFORE) - * Arg of type a or subval key or preference pref or default def - */ - public static String getFromSubValArgOrPref(ArgValuesMap avm, Arg a, - Position pos, ArgValue av, SubVals sv, String key, String pref, - String def) - { - return getFromSubValArgOrPrefWithSubstitutions(null, avm, a, pos, av, - sv, key, pref, def); - } - - public static String getFromSubValArgOrPrefWithSubstitutions(ArgParser ap, - ArgValuesMap avm, Arg a, Position pos, ArgValue av, SubVals sv, - String key, String pref, String def) - { - if (key == null) - key = a.getName(); - String value = null; - if (sv != null && sv.has(key) && sv.get(key) != null) - { - value = ap == null ? sv.get(key) - : sv.getWithSubstitutions(ap, avm.getLinkedId(), key); - } - else if (avm != null && avm.containsArg(a)) - { - if (pos == Position.FIRST && avm.getValue(a) != null) - value = avm.getValue(a); - else if (pos == Position.BEFORE - && avm.getClosestPreviousArgValueOfArg(av, a) != null) - value = avm.getClosestPreviousArgValueOfArg(av, a).getValue(); - else if (pos == Position.AFTER - && avm.getClosestNextArgValueOfArg(av, a) != null) - value = avm.getClosestNextArgValueOfArg(av, a).getValue(); - - // look for allstructures subval for Type.STRUCTURE* - Arg arg = av.getArg(); - if (value == null && arg.hasOption(Opt.PRIMARY) - && arg.getType() == Type.STRUCTURE - && !a.hasOption(Opt.PRIMARY) && (a.getType() == Type.STRUCTURE - || a.getType() == Type.STRUCTUREIMAGE)) - { - ArgValue av2 = avm.getArgValueOfArgWithSubValKey(a, - Arg.ALLSTRUCTURES.getName()); - if (av2 != null) - { - value = av2.getValue(); - } - } - } - if (value == null) - { - value = pref != null ? Cache.getDefault(pref, def) : def; - } - return value; - } - - public static boolean getBoolFromSubValOrArg(ArgValuesMap avm, Arg a, - SubVals sv) - { - return getFromSubValArgOrPref(avm, a, sv, null, null, false); - } - - public static boolean getFromSubValArgOrPref(ArgValuesMap avm, Arg a, - SubVals sv, String key, String pref, boolean def) - { - return getFromSubValArgOrPref(avm, a, sv, key, pref, def, false); - } - - public static boolean getFromSubValArgOrPref(ArgValuesMap avm, Arg a, - SubVals sv, String key, String pref, boolean def, - boolean invertPref) - { - if ((key == null && a == null) || (sv == null && a == null)) - return false; - - boolean usingArgKey = false; - if (key == null) - { - key = a.getName(); - usingArgKey = true; - } - - String nokey = ArgParser.NEGATESTRING + key; - - // look for key or nokey in subvals first (if using Arg check options) - if (sv != null) - { - // check for true boolean - if (sv.has(key) && sv.get(key) != null) - { - if (usingArgKey) - { - if (!(a.hasOption(Opt.BOOLEAN) || a.hasOption(Opt.UNARY))) - { - Console.debug( - "Looking for boolean in subval from non-boolean/non-unary Arg " - + a.getName()); - return false; - } - } - return sv.get(key).toLowerCase(Locale.ROOT).equals("true"); - } - - // check for negative boolean (subval "no..." will be "true") - if (sv.has(nokey) && sv.get(nokey) != null) - { - if (usingArgKey) - { - if (!(a.hasOption(Opt.BOOLEAN))) - { - Console.debug( - "Looking for negative boolean in subval from non-boolean Arg " - + a.getName()); - return false; - } - } - return !sv.get(nokey).toLowerCase(Locale.ROOT).equals("true"); - } - } - - // check argvalues - if (avm != null && avm.containsArg(a)) - return avm.getBoolean(a); - - // return preference or default - boolean prefVal = pref != null ? Cache.getDefault(pref, def) : false; - return pref != null ? (invertPref ? !prefVal : prefVal) : def; - } - // the following methods look for the "*" linkedId and add the argvalue to all // linkedId ArgValues if it does. /** @@ -1121,13 +1062,6 @@ public class ArgParser argIndex, doSubs); } - private void addValue(String linkedId, Type type, ArgValues avs, String v, - int argIndex, boolean doSubs) - { - this.argValueOperation(Op.ADDVALUE, linkedId, type, avs, null, v, false, - argIndex, doSubs); - } - private void setBoolean(String linkedId, Type type, ArgValues avs, boolean b, int argIndex) { @@ -1195,7 +1129,7 @@ public class ArgParser Arg a = avs.arg(); List wildcardLinkedIds = null; - if (a.hasOption(Opt.ALLOWALL)) + if (a.hasOption(Opt.ALLOWMULTIID)) { switch (linkedId) { @@ -1226,7 +1160,9 @@ public class ArgParser // skip incorrectly stored wildcard ids! if (id == null || MATCHALLLINKEDIDS.equals(id) || MATCHOPENEDLINKEDIDS.equals(id)) + { continue; + } ArgValuesMap avm = linkedArgs.get(id); // don't set an output if there isn't an input if (a.hasOption(Opt.REQUIREINPUT) @@ -1334,4 +1270,24 @@ public class ArgParser return linkedArgs.get(linkedId); } + public boolean isOldStyle() + { + return oldArguments; + } + + public boolean isMixedStyle() + { + return mixedArguments; + } + + public String[] getMixedExamples() + { + return mixedExamples; + } + + public void setStructureFilename(String s) + { + this.currentStructureFilename = s; + } + } \ No newline at end of file diff --git a/src/jalview/bin/argparser/ArgValues.java b/src/jalview/bin/argparser/ArgValues.java index f25fc9a..2b9061c 100644 --- a/src/jalview/bin/argparser/ArgValues.java +++ b/src/jalview/bin/argparser/ArgValues.java @@ -151,9 +151,9 @@ public class ArgValues protected void addArgValue(ArgValue av, boolean beingSetByWildcard) { // allow a non-wildcard value to overwrite a wildcard set single value - boolean overwrite = !arg.hasOption(Opt.MULTI) && setByWildcard + boolean overwrite = !arg.hasOption(Opt.MULTIVALUE) && setByWildcard && !beingSetByWildcard; - if ((!arg.hasOption(Opt.MULTI) && argValueList.size() > 0) + if ((!arg.hasOption(Opt.MULTIVALUE) && argValueList.size() > 0) && !overwrite) return; if (arg.hasOption(Opt.NODUPLICATEVALUES) @@ -182,7 +182,7 @@ public class ArgValues protected ArgValue getArgValue() { - if (arg.hasOption(Opt.MULTI)) + if (arg.hasOption(Opt.MULTIVALUE)) Console.warn("Requesting single value for multi value argument"); return argValueList.size() > 0 ? argValueList.get(0) : null; } diff --git a/src/jalview/bin/argparser/ArgValuesMap.java b/src/jalview/bin/argparser/ArgValuesMap.java index ab6fcc1..99a4836 100644 --- a/src/jalview/bin/argparser/ArgValuesMap.java +++ b/src/jalview/bin/argparser/ArgValuesMap.java @@ -2,12 +2,17 @@ package jalview.bin.argparser; import java.io.File; import java.util.ArrayList; +import java.util.Collections; import java.util.HashMap; import java.util.List; +import java.util.Locale; import java.util.Map; import java.util.Set; +import jalview.bin.Cache; +import jalview.bin.Console; import jalview.bin.argparser.Arg.Opt; +import jalview.bin.argparser.Arg.Type; import jalview.util.FileUtils; /** @@ -16,6 +21,8 @@ import jalview.util.FileUtils; */ public class ArgValuesMap { + private List argInfoList = new ArrayList<>(); + protected Map m; private String linkedId; @@ -165,7 +172,8 @@ public class ArgValuesMap return closestAv; } - public ArgValue getClosestNextArgValueOfArg(ArgValue thisAv, Arg a) + public ArgValue getClosestNextArgValueOfArg(ArgValue thisAv, Arg a, + boolean withinType) { // this looks for the *next* arg that *might* be referring back to // a thisAv. Such an arg would have no subValues (if it does it should @@ -185,6 +193,35 @@ public class ArgValuesMap closestAv = av; } } + + // check if withinType this closestAv doesn't belong to the next primary arg + // of this type + if (withinType && closestAv != null) + { + int nextPrimaryArgOfSameTypeIndex = Integer.MAX_VALUE; + for (Arg tmpA : this.getArgKeys()) + { + // interested in Opt.PRIMARY args of the same type + if (tmpA.getType() == a.getType() && tmpA.hasOption(Opt.PRIMARY)) + { + for (ArgValue tmpAv : getArgValueList(tmpA)) + { + int tmpArgIndex = tmpAv.getArgIndex(); + if (tmpArgIndex > thisArgIndex + && tmpArgIndex < nextPrimaryArgOfSameTypeIndex) + { + nextPrimaryArgOfSameTypeIndex = tmpArgIndex; + } + } + } + } + if (nextPrimaryArgOfSameTypeIndex < closestAv.getArgIndex()) + { + // looks licke closestAv actually belongs to a different primary Arg + return null; + } + } + return closestAv; } @@ -226,7 +263,7 @@ public class ArgValuesMap */ public String getBasename() { - return getDirBasenameOrExtension(false, false); + return getDirBasenameOrExtension(false, false, false); } /* @@ -235,7 +272,7 @@ public class ArgValuesMap */ public String getExtension() { - return getDirBasenameOrExtension(false, true); + return getDirBasenameOrExtension(false, true, false); } /* @@ -244,11 +281,11 @@ public class ArgValuesMap */ public String getDirname() { - return getDirBasenameOrExtension(true, false); + return getDirBasenameOrExtension(true, false, false); } public String getDirBasenameOrExtension(boolean dirname, - boolean extension) + boolean extension, boolean absoluteDirname) { String filename = null; String appendVal = getValue(Arg.APPEND); @@ -281,4 +318,226 @@ public class ArgValuesMap } return false; } + + /* + * ArgInfo is a more straightforward list of arguments and their info + */ + + public void addArgInfo(Arg arg, String value, SubVals subVals, + int argIndex) + { + argInfoList.add(new ArgInfo(arg, value, subVals, argIndex)); + } + + public List getArgInfoList() + { + Collections.sort(argInfoList); + return argInfoList; + } + + /** + * get from following Arg of type a or subval of same name (lowercase) + */ + public String getValueFromSubValOrArg(ArgValue av, Arg a, SubVals sv) + { + return getFromSubValArgOrPref(av, a, sv, null, null, null); + } + + /** + * get from following Arg of type a or subval key or preference pref or + * default def + */ + public String getFromSubValArgOrPref(ArgValue av, Arg a, SubVals sv, + String key, String pref, String def) + { + return getFromSubValArgOrPref(a, ArgValuesMap.Position.AFTER, av, sv, + key, pref, def); + } + + /** + * get from following(AFTER), first occurence of (FIRST) or previous (BEFORE) + * Arg of type a or subval key or preference pref or default def + */ + public String getFromSubValArgOrPref(Arg a, ArgValuesMap.Position pos, + ArgValue av, SubVals sv, String key, String pref, String def) + { + return getFromSubValArgOrPrefWithSubstitutions(null, a, pos, av, sv, + key, pref, def); + } + + public String getFromSubValArgOrPrefWithSubstitutions(ArgParser ap, Arg a, + ArgValuesMap.Position pos, ArgValue av, SubVals sv, String key, + String pref, String def) + { + return getFromSubValArgOrPrefWithSubstitutionsWithinType(ap, a, pos, av, + sv, key, pref, def, true); + } + + public String getFromSubValArgOrPrefWithSubstitutionsWithinType( + ArgParser ap, Arg a, ArgValuesMap.Position pos, ArgValue av, + SubVals sv, String key, String pref, String def, + boolean withinType) + { + if (key == null) + key = a.getName(); + String value = null; + if (sv != null && sv.has(key) && sv.get(key) != null) + { + value = ap == null ? sv.get(key) + : sv.getWithSubstitutions(ap, getLinkedId(), key); + } + else if (containsArg(a)) + { + if (pos == ArgValuesMap.Position.FIRST && getValue(a) != null) + value = getValue(a); + else if (pos == ArgValuesMap.Position.BEFORE + && getClosestPreviousArgValueOfArg(av, a) != null) + value = getClosestPreviousArgValueOfArg(av, a).getValue(); + else if (pos == ArgValuesMap.Position.AFTER + && getClosestNextArgValueOfArg(av, a, withinType) != null) + value = getClosestNextArgValueOfArg(av, a, withinType).getValue(); + + // look for allstructures subval for Type.STRUCTURE + Arg arg = av.getArg(); + if (value == null && arg.hasOption(Opt.PRIMARY) + && arg.getType() == Type.STRUCTURE + && !a.hasOption(Opt.PRIMARY) && (a.getType() == Type.STRUCTURE + // || a.getType() == Type.STRUCTUREIMAGE)) + )) + { + ArgValue av2 = getArgValueOfArgWithSubValKey(a, + Arg.ALLSTRUCTURES.getName()); + if (av2 != null) + { + value = av2.getValue(); + } + } + } + if (value == null) + { + value = pref != null ? Cache.getDefault(pref, def) : def; + } + return value; + } + + public boolean getBoolFromSubValOrArg(Arg a, SubVals sv) + { + return getFromSubValArgOrPref(a, sv, null, null, false); + } + + public boolean getFromSubValArgOrPref(Arg a, SubVals sv, String key, + String pref, boolean def) + { + return getFromSubValArgOrPref(a, sv, key, pref, def, false); + } + + public boolean getFromSubValArgOrPref(Arg a, SubVals sv, String key, + String pref, boolean def, boolean invertPref) + { + if ((key == null && a == null) || (sv == null && a == null)) + return false; + + boolean usingArgKey = false; + if (key == null) + { + key = a.getName(); + usingArgKey = true; + } + + String nokey = ArgParser.NEGATESTRING + key; + + // look for key or nokey in subvals first (if using Arg check options) + if (sv != null) + { + // check for true boolean + if (sv.has(key) && sv.get(key) != null) + { + if (usingArgKey) + { + if (!(a.hasOption(Opt.BOOLEAN) || a.hasOption(Opt.UNARY))) + { + Console.debug( + "Looking for boolean in subval from non-boolean/non-unary Arg " + + a.getName()); + return false; + } + } + return sv.get(key).toLowerCase(Locale.ROOT).equals("true"); + } + + // check for negative boolean (subval "no..." will be "true") + if (sv.has(nokey) && sv.get(nokey) != null) + { + if (usingArgKey) + { + if (!(a.hasOption(Opt.BOOLEAN))) + { + Console.debug( + "Looking for negative boolean in subval from non-boolean Arg " + + a.getName()); + return false; + } + } + return !sv.get(nokey).toLowerCase(Locale.ROOT).equals("true"); + } + } + + // check argvalues + if (containsArg(a)) + return getBoolean(a); + + // return preference or default + boolean prefVal = pref != null ? Cache.getDefault(pref, def) : false; + return pref != null ? (invertPref ? !prefVal : prefVal) : def; + } + + public class ArgInfo implements Comparable + { + private Arg arg; + + private String value; + + private SubVals subVals; + + private int argIndex; + + public ArgInfo(Arg arg, String value, SubVals subVals, int argIndex) + { + this.arg = arg; + this.value = value; + this.subVals = subVals; + this.argIndex = argIndex; + } + + public Arg arg() + { + return arg; + } + + public String value() + { + return value; + } + + public SubVals subVals() + { + return subVals; + } + + public int argIndex() + { + return argIndex; + } + + @Override + public int compareTo(ArgInfo ai2) + { + return Integer.compare(this.argIndex(), ai2.argIndex()); + } + } + + public static enum Position + { + FIRST, BEFORE, AFTER + } } diff --git a/src/jalview/bin/argparser/BootstrapArgs.java b/src/jalview/bin/argparser/BootstrapArgs.java index 4b7b180..5c21d03 100644 --- a/src/jalview/bin/argparser/BootstrapArgs.java +++ b/src/jalview/bin/argparser/BootstrapArgs.java @@ -28,6 +28,8 @@ public class BootstrapArgs private Set argsTypes = new HashSet<>(); + private boolean outputToStdout = false; + public static BootstrapArgs getBootstrapArgs(String[] args) { List argList = new ArrayList<>(Arrays.asList(args)); @@ -53,7 +55,7 @@ public class BootstrapArgs { if (argFiles.contains(inArgFile)) { - System.err.println( + jalview.bin.Console.errPrintln( "Looped argfiles detected: '" + inArgFile.getPath() + "'"); return; } @@ -127,11 +129,6 @@ public class BootstrapArgs } } - if (ArgParser.argMap.containsKey(argName) && val == null) - { - val = "true"; - } - Arg a = ArgParser.argMap.get(argName); if (a != null) @@ -152,7 +149,27 @@ public class BootstrapArgs if (a == null || !a.hasOption(Opt.BOOTSTRAP)) { - // not a valid bootstrap arg + // not a bootstrap arg + + // make a check for an output going to stdout + if (a != null && a.hasOption(Opt.OUTPUTFILE) + && a.hasOption(Opt.STDOUT)) + { + if (val == null && i + 1 < args.size()) + { + val = args.get(i + 1); + } + if (val.startsWith("[") && val.indexOf(']') > 0) + { + val = val.substring(val.indexOf(']') + 1); + } + + if (ArgParser.STDOUTFILENAME.equals(val)) + { + this.outputToStdout = true; + } + } + continue; } @@ -188,10 +205,22 @@ public class BootstrapArgs } else { + if (val == null) + { + val = "true"; + } + add(a, type, val); } } } + + // if in an argfile, remove it from the hashset so it can be re-used in + // another argfile + if (inArgFile != null) + { + argFiles.remove(inArgFile); + } } public boolean contains(Arg a) @@ -270,7 +299,7 @@ public class BootstrapArgs private void add(Arg a, Type t, String s) { List> l = getOrCreateList(a); - if (a.hasOption(Opt.MULTI) || l.size() == 0) + if (a.hasOption(Opt.MULTIVALUE) || l.size() == 0) { l.add(entry(t, s)); } @@ -279,7 +308,7 @@ public class BootstrapArgs private void addAll(Arg a, Type t, List al) { List> l = getOrCreateList(a); - if (a.hasOption(Opt.MULTI)) + if (a.hasOption(Opt.MULTIVALUE)) { for (String s : al) { @@ -362,7 +391,7 @@ public class BootstrapArgs } else if (this.contains(Arg.HEADLESS)) { - // --headless, --noheadless specified => use value + // --headless has been specified on the command line => headless isHeadless = this.getBoolean(Arg.HEADLESS); } else if (this.argsHaveOption(Opt.OUTPUTFILE)) @@ -373,4 +402,9 @@ public class BootstrapArgs } return isHeadless; } + + public boolean outputToStdout() + { + return this.outputToStdout; + } } diff --git a/src/jalview/bin/groovy/JalviewObject.java b/src/jalview/bin/groovy/JalviewObject.java new file mode 100644 index 0000000..e271c3c --- /dev/null +++ b/src/jalview/bin/groovy/JalviewObject.java @@ -0,0 +1,42 @@ +package jalview.bin.groovy; + +import jalview.bin.Jalview.ExitCode; +import jalview.gui.AlignFrame; + +public class JalviewObject implements JalviewObjectI +{ + private JalviewObjectI object = null; + + public JalviewObject(JalviewObjectI j) + { + this.object = j; + } + + @Override + public AlignFrame[] getAlignFrames() + { + return object == null ? null : object.getAlignFrames(); + } + + @Override + public AlignFrame getCurrentAlignFrame() + { + return object == null ? null : object.getCurrentAlignFrame(); + } + + @Override + public void quit() + { + if (object != null) + { + object.quit(); + } + else + { + jalview.bin.Jalview.exit( + "Groovy console quit without Jalview object.", + ExitCode.GROOVY_ERROR); + } + } + +} diff --git a/src/jalview/bin/groovy/JalviewObjectI.java b/src/jalview/bin/groovy/JalviewObjectI.java new file mode 100644 index 0000000..f365d30 --- /dev/null +++ b/src/jalview/bin/groovy/JalviewObjectI.java @@ -0,0 +1,16 @@ +package jalview.bin.groovy; + +import jalview.gui.AlignFrame; + +public interface JalviewObjectI +{ + public AlignFrame[] getAlignFrames(); + + public AlignFrame getCurrentAlignFrame(); + + public final static String currentAlFrameName = "currentAlFrame"; + + public final static String jalviewObjectName = "Jalview"; + + public void quit(); +} diff --git a/src/jalview/commands/EditCommand.java b/src/jalview/commands/EditCommand.java index 62ef660..c15bbf8 100644 --- a/src/jalview/commands/EditCommand.java +++ b/src/jalview/commands/EditCommand.java @@ -473,7 +473,7 @@ public class EditCommand implements CommandI { command.seqs[s].insertCharAt(command.position, command.number, command.gapChar); - // System.out.println("pos: "+command.position+" number: + // jalview.bin.Console.outPrintln("pos: "+command.position+" number: // "+command.number); } @@ -486,7 +486,7 @@ public class EditCommand implements CommandI // // for (int s = 0; s < command.seqs.length; s++) // { - // System.out.println("pos: "+command.position+" number: "+command.number); + // jalview.bin.Console.outPrintln("pos: "+command.position+" number: "+command.number); // command.seqs[s].insertCharAt(command.position, command.number,'A'); // } // @@ -1433,7 +1433,7 @@ public class EditCommand implements CommandI } else { - System.err.println("Can't undo edit action " + action); + jalview.bin.Console.errPrintln("Can't undo edit action " + action); // throw new IllegalStateException("Can't undo edit action " + // action); } diff --git a/src/jalview/datamodel/AlignedCodonFrame.java b/src/jalview/datamodel/AlignedCodonFrame.java index f5154ec..cb74a66 100644 --- a/src/jalview/datamodel/AlignedCodonFrame.java +++ b/src/jalview/datamodel/AlignedCodonFrame.java @@ -707,7 +707,7 @@ public class AlignedCodonFrame ds.setSequenceFeatures(dna.getSequenceFeatures()); // dnaSeqs[i] = ds; ssm.fromSeq = ds; - System.out.println("Realised mapped sequence " + ds.getName()); + jalview.bin.Console.outPrintln("Realised mapped sequence " + ds.getName()); } } } diff --git a/src/jalview/datamodel/Alignment.java b/src/jalview/datamodel/Alignment.java index 514a326..375e6b4 100755 --- a/src/jalview/datamodel/Alignment.java +++ b/src/jalview/datamodel/Alignment.java @@ -2057,7 +2057,7 @@ public class Alignment implements AlignmentI, AutoCloseable if (cm == null && _aa.sequenceRef != null) { cm = _aa.sequenceRef.getContactMatrixFor(_aa); - if (cm == null) + if (cm == null && _aa.sequenceRef.getDatasetSequence()!=null) { // TODO fix up this logic and unify with getContactListFor cm = _aa.sequenceRef.getDatasetSequence().getContactMatrixFor(_aa); @@ -2069,6 +2069,10 @@ public class Alignment implements AlignmentI, AutoCloseable @Override public ContactListI getContactListFor(AlignmentAnnotation _aa, int column) { + if (_aa.annotations==null || column>=_aa.annotations.length || column<0) + { + return null; + } ContactListI cl = cmholder.getContactListFor(_aa, column); if (cl == null && _aa.groupRef != null) { diff --git a/src/jalview/datamodel/AlignmentAnnotation.java b/src/jalview/datamodel/AlignmentAnnotation.java index de98c64..7e6b904 100755 --- a/src/jalview/datamodel/AlignmentAnnotation.java +++ b/src/jalview/datamodel/AlignmentAnnotation.java @@ -126,7 +126,7 @@ public class AlignmentAnnotation invalidrnastruc = -1; } catch (WUSSParseException px) { - // DEBUG System.out.println(px); + // DEBUG jalview.bin.Console.outPrintln(px); invalidrnastruc = px.getProblemPos(); } if (invalidrnastruc > -1) @@ -142,7 +142,7 @@ public class AlignmentAnnotation scaleColLabel = true; _markRnaHelices(); } - // System.out.println("featuregroup " + _rnasecstr[0].getFeatureGroup()); + // jalview.bin.Console.outPrintln("featuregroup " + _rnasecstr[0].getFeatureGroup()); } @@ -156,10 +156,10 @@ public class AlignmentAnnotation { /* - * System.out.println(this.annotation._rnasecstr[x] + " Begin" + + * jalview.bin.Console.outPrintln(this.annotation._rnasecstr[x] + " Begin" + * this.annotation._rnasecstr[x].getBegin()); */ - // System.out.println(this.annotation._rnasecstr[x].getFeatureGroup()); + // jalview.bin.Console.outPrintln(this.annotation._rnasecstr[x].getFeatureGroup()); int val = 0; try { @@ -386,7 +386,7 @@ public class AlignmentAnnotation char firstChar = 0; for (int i = 0; i < annotations.length; i++) { - // DEBUG System.out.println(i + ": " + annotations[i]); + // DEBUG jalview.bin.Console.outPrintln(i + ": " + annotations[i]); if (annotations[i] == null) { continue; @@ -394,14 +394,14 @@ public class AlignmentAnnotation if (annotations[i].secondaryStructure == 'H' || annotations[i].secondaryStructure == 'E') { - // DEBUG System.out.println( "/H|E/ '" + + // DEBUG jalview.bin.Console.outPrintln( "/H|E/ '" + // annotations[i].secondaryStructure + "'"); hasIcons |= true; } else // Check for RNA secondary structure { - // DEBUG System.out.println( "/else/ '" + + // DEBUG jalview.bin.Console.outPrintln( "/else/ '" + // annotations[i].secondaryStructure + "'"); // TODO: 2.8.2 should this ss symbol validation check be a function in // RNA/ResidueProperties ? @@ -446,7 +446,7 @@ public class AlignmentAnnotation } } - // System.out.println("displaychar " + annotations[i].displayCharacter); + // jalview.bin.Console.outPrintln("displaychar " + annotations[i].displayCharacter); if (annotations[i].displayCharacter == null || annotations[i].displayCharacter.length() == 0) diff --git a/src/jalview/datamodel/AlignmentView.java b/src/jalview/datamodel/AlignmentView.java index e6604d1..6ab71c7 100644 --- a/src/jalview/datamodel/AlignmentView.java +++ b/src/jalview/datamodel/AlignmentView.java @@ -1128,11 +1128,11 @@ public class AlignmentView public static void testSelectionViews(AlignmentI alignment, HiddenColumns hidden, SequenceGroup selection) { - System.out.println("Testing standard view creation:\n"); + jalview.bin.Console.outPrintln("Testing standard view creation:\n"); AlignmentView view = null; try { - System.out.println( + jalview.bin.Console.outPrintln( "View with no hidden columns, no limit to selection, no groups to be collected:"); view = new AlignmentView(alignment, hidden, selection, false, false, false); @@ -1141,12 +1141,12 @@ public class AlignmentView } catch (Exception e) { e.printStackTrace(); - System.err.println( + jalview.bin.Console.errPrintln( "Failed to generate alignment with selection but no groups marked."); } try { - System.out.println( + jalview.bin.Console.outPrintln( "View with no hidden columns, no limit to selection, and all groups to be collected:"); view = new AlignmentView(alignment, hidden, selection, false, false, true); @@ -1154,12 +1154,12 @@ public class AlignmentView } catch (Exception e) { e.printStackTrace(); - System.err.println( + jalview.bin.Console.errPrintln( "Failed to generate alignment with selection marked but no groups marked."); } try { - System.out.println( + jalview.bin.Console.outPrintln( "View with no hidden columns, limited to selection and no groups to be collected:"); view = new AlignmentView(alignment, hidden, selection, false, true, false); @@ -1167,12 +1167,12 @@ public class AlignmentView } catch (Exception e) { e.printStackTrace(); - System.err.println( + jalview.bin.Console.errPrintln( "Failed to generate alignment with selection restricted but no groups marked."); } try { - System.out.println( + jalview.bin.Console.outPrintln( "View with no hidden columns, limited to selection, and all groups to be collected:"); view = new AlignmentView(alignment, hidden, selection, false, true, true); @@ -1180,12 +1180,12 @@ public class AlignmentView } catch (Exception e) { e.printStackTrace(); - System.err.println( + jalview.bin.Console.errPrintln( "Failed to generate alignment with selection restricted and groups marked."); } try { - System.out.println( + jalview.bin.Console.outPrintln( "View *with* hidden columns, no limit to selection, no groups to be collected:"); view = new AlignmentView(alignment, hidden, selection, true, false, false); @@ -1193,12 +1193,12 @@ public class AlignmentView } catch (Exception e) { e.printStackTrace(); - System.err.println( + jalview.bin.Console.errPrintln( "Failed to generate alignment with selection but no groups marked."); } try { - System.out.println( + jalview.bin.Console.outPrintln( "View *with* hidden columns, no limit to selection, and all groups to be collected:"); view = new AlignmentView(alignment, hidden, selection, true, false, true); @@ -1206,12 +1206,12 @@ public class AlignmentView } catch (Exception e) { e.printStackTrace(); - System.err.println( + jalview.bin.Console.errPrintln( "Failed to generate alignment with selection marked but no groups marked."); } try { - System.out.println( + jalview.bin.Console.outPrintln( "View *with* hidden columns, limited to selection and no groups to be collected:"); view = new AlignmentView(alignment, hidden, selection, true, true, false); @@ -1219,12 +1219,12 @@ public class AlignmentView } catch (Exception e) { e.printStackTrace(); - System.err.println( + jalview.bin.Console.errPrintln( "Failed to generate alignment with selection restricted but no groups marked."); } try { - System.out.println( + jalview.bin.Console.outPrintln( "View *with* hidden columns, limited to selection, and all groups to be collected:"); view = new AlignmentView(alignment, hidden, selection, true, true, true); @@ -1232,7 +1232,7 @@ public class AlignmentView } catch (Exception e) { e.printStackTrace(); - System.err.println( + jalview.bin.Console.errPrintln( "Failed to generate alignment with selection restricted and groups marked."); } diff --git a/src/jalview/datamodel/ColumnSelection.java b/src/jalview/datamodel/ColumnSelection.java index 4a38ec0..b427739 100644 --- a/src/jalview/datamodel/ColumnSelection.java +++ b/src/jalview/datamodel/ColumnSelection.java @@ -340,10 +340,12 @@ public class ColumnSelection /** * Returns a read-only view of the (possibly empty) list of selected columns + * (base 1) *

      - * The list contains no duplicates but is not necessarily ordered. It also may - * include columns hidden from the current view. To modify (for example sort) - * the list, you should first make a copy. + * The list contains no duplicates but is not necessarily ordered. Columns are + * reported in alignment coordinates (base 1), so may also include columns + * hidden from the current view. To modify (for example sort) the list, you + * should first make a copy. *

      * The list is not thread-safe: iterating over it could result in * ConcurrentModificationException if it is modified by another thread. diff --git a/src/jalview/datamodel/ContactListImpl.java b/src/jalview/datamodel/ContactListImpl.java index bb31c5d..7058ac7 100644 --- a/src/jalview/datamodel/ContactListImpl.java +++ b/src/jalview/datamodel/ContactListImpl.java @@ -88,7 +88,7 @@ public class ContactListImpl implements ContactListI } } } - if (tot > 0) + if (tot > 0 && to_column>from_column) { cr.setMean(tot / (1 + to_column - from_column)); } diff --git a/src/jalview/datamodel/ContactMapHolder.java b/src/jalview/datamodel/ContactMapHolder.java index af083dd..3a64917 100644 --- a/src/jalview/datamodel/ContactMapHolder.java +++ b/src/jalview/datamodel/ContactMapHolder.java @@ -3,6 +3,7 @@ package jalview.datamodel; import java.util.Collection; import java.util.Collections; import java.util.HashMap; +import java.util.HashSet; import java.util.Map; import jalview.ws.datamodel.MappableContactMatrixI; @@ -17,7 +18,8 @@ public class ContactMapHolder implements ContactMapHolderI { if (contactmaps != null && contactmaps.size() > 0) { - return contactmaps.values(); + // defensive copy, and return non redundant set of ContactMatrixI instances + return new HashSet(contactmaps.values()); } return Collections.EMPTY_LIST; } diff --git a/src/jalview/datamodel/ContactMatrix.java b/src/jalview/datamodel/ContactMatrix.java index 48b6e6b..2e12a91 100644 --- a/src/jalview/datamodel/ContactMatrix.java +++ b/src/jalview/datamodel/ContactMatrix.java @@ -1,17 +1,12 @@ package jalview.datamodel; -import java.awt.Color; -import java.math.BigInteger; import java.util.ArrayList; -import java.util.BitSet; -import java.util.HashMap; import java.util.List; -import java.util.Spliterator; import java.util.StringTokenizer; import jalview.bin.Console; -public abstract class ContactMatrix implements ContactMatrixI +public abstract class ContactMatrix extends GroupSetHolder implements ContactMatrixI { /** * are contacts reflexive ? @@ -107,26 +102,7 @@ public abstract class ContactMatrix implements ContactMatrixI @Override public double getContactAt(int column) { - List clist; - Float cl = null; - if (symmetric) - { - if (p < column) - { - clist = contacts.get(p); - cl = clist.get(column); - } - else - { - clist = contacts.get(column); - cl = clist.get(p); - } - } - else - { - clist = contacts.get(p); - cl = clist.get(column); - } + Float cl = getFloatElementAt(column, p); if (cl == null) { // return 0 not NaN ? @@ -136,7 +112,41 @@ public abstract class ContactMatrix implements ContactMatrixI } }); } - + private Float getFloatElementAt(int column, int p) + { + + List clist; + Float cl = null; + if (symmetric) + { + if (p < column) + { + clist = contacts.get(p); + cl = clist.get(column); + } + else + { + clist = contacts.get(column); + cl = clist.get(p); + } + } + else + { + clist = contacts.get(p); + cl = clist.get(column); + } + return cl; + } + @Override + public double getElementAt(int column, int row) + { + Float cl = getFloatElementAt(column, row); + if (cl!=null) + { + return cl; + } + throw(new RuntimeException("Out of Bounds "+column+","+row)); + } @Override public float getMin() { @@ -160,30 +170,27 @@ public abstract class ContactMatrix implements ContactMatrixI { return "Contact Matrix"; } - GroupSet grps = new GroupSet(); - @Override - public GroupSetI getGroupSet() - { - return grps; - } - @Override - public void setGroupSet(GroupSet makeGroups) - { - grps = makeGroups; - } public static String contactToFloatString(ContactMatrixI cm) { StringBuilder sb = new StringBuilder(); for (int c = 0; c < cm.getWidth(); c++) { ContactListI cl = cm.getContactList(c); + long lastsb=-1; if (cl != null) { for (int h = 0; h <= cl.getContactHeight(); h++) { if (sb.length() > 0) { - sb.append('\t'); + if (sb.length()-lastsb>320) + { + // newline + sb.append('\n'); + lastsb=sb.length(); + } else { + sb.append('\t'); + } } sb.append(cl.getContactAt(h)); } @@ -196,7 +203,7 @@ public abstract class ContactMatrix implements ContactMatrixI int rows) { float[][] vals = new float[cols][rows]; - StringTokenizer tabsep = new StringTokenizer(values, "" + '\t'); + StringTokenizer tabsep = new StringTokenizer(values, "" + '\t'+'\n'); int c = 0, r = 0; while (tabsep.hasMoreTokens()) { diff --git a/src/jalview/datamodel/ContactMatrixI.java b/src/jalview/datamodel/ContactMatrixI.java index 925025f..4261519 100644 --- a/src/jalview/datamodel/ContactMatrixI.java +++ b/src/jalview/datamodel/ContactMatrixI.java @@ -199,5 +199,17 @@ public interface ContactMatrixI } return Color.white; } + + /** + * direct access to column and row position of matrix + + * Implementations are allowed to throw + * RunTimeExceptions if _column/i are out of bounds + * + * @param column + * @param row + * @return + */ + double getElementAt(int column, int row); } diff --git a/src/jalview/datamodel/FloatContactMatrix.java b/src/jalview/datamodel/FloatContactMatrix.java new file mode 100644 index 0000000..5fb156f --- /dev/null +++ b/src/jalview/datamodel/FloatContactMatrix.java @@ -0,0 +1,133 @@ +package jalview.datamodel; + +public class FloatContactMatrix extends GroupSetHolder implements ContactMatrixI +{ + + int maxrow = 0, maxcol = 0; + + + float[][] elements; + + float maxscore; + + + public FloatContactMatrix(float[][] matrix) + { + maxcol = 0; + for (float[] row : matrix) + { + if (row.length > maxcol) + { + maxcol = row.length; + } + maxscore = row[0]; + for (float f : row) + { + if (maxscore < f) + { + maxscore = f; + } + } + } + maxrow = matrix.length; + elements = matrix; + } + + public FloatContactMatrix(float[][] elements2, GroupSet grps2) + { + this(elements2); + setGroupSet(grps2); + } + + /** + * getContactList(column) @returns the vector of predicted alignment errors + * for reference position given by column + */ + @Override + public ContactListI getContactList(final int column) + { + if (column < 0 || column >= elements.length) + { + return null; + } + + return new ContactListImpl(new ContactListProviderI() + { + @Override + public int getPosition() + { + return column; + } + + @Override + public int getContactHeight() + { + return maxcol - 1; + } + + @Override + public double getContactAt(int mcolumn) + { + if (mcolumn < 0 || mcolumn >= elements[column].length) + { + return -1; + } + return elements[column][mcolumn]; + } + }); + } + + /** + * getElementAt(column, i) @returns the predicted superposition error for the + * ith position when column is used as reference + */ + @Override + public double getElementAt(int _column, int i) + { + return elements[_column][i]; + } + + @Override + public float getMin() + { + return 0; + } + + @Override + public float getMax() + { + return maxscore; + } + + @Override + public String getAnnotDescr() + { + // TODO Auto-generated method stub + return null; + } + + @Override + public String getAnnotLabel() + { + // TODO Auto-generated method stub + return null; + } + + @Override + public String getType() + { + return null; + } + + @Override + public int getWidth() + { + return maxcol; + } + + @Override + public int getHeight() + { + return maxrow; + } +} diff --git a/src/jalview/datamodel/GroupSetHolder.java b/src/jalview/datamodel/GroupSetHolder.java new file mode 100644 index 0000000..faeb7c0 --- /dev/null +++ b/src/jalview/datamodel/GroupSetHolder.java @@ -0,0 +1,24 @@ +package jalview.datamodel; + +/** + * holds a group set and provides getters and setters for ContactMatrixI + * implementations + * + * @author jprocter + */ +public class GroupSetHolder +{ + + GroupSet grps = new GroupSet(); + + public GroupSetI getGroupSet() + { + return grps; + } + + public void setGroupSet(GroupSet makeGroups) + { + grps = makeGroups; + } + +} diff --git a/src/jalview/datamodel/HiddenSequences.java b/src/jalview/datamodel/HiddenSequences.java index b5efeb4..e2ef318 100755 --- a/src/jalview/datamodel/HiddenSequences.java +++ b/src/jalview/datamodel/HiddenSequences.java @@ -159,7 +159,7 @@ public class HiddenSequences if (alignmentIndex < 0 || hiddenSequences[alignmentIndex] != null) { - System.out.println("ERROR!!!!!!!!!!!"); + jalview.bin.Console.outPrintln("ERROR!!!!!!!!!!!"); return; } @@ -239,7 +239,7 @@ public class HiddenSequences } else { - System.out.println( + jalview.bin.Console.outPrintln( seq.getName() + " has been deleted whilst hidden"); } } diff --git a/src/jalview/datamodel/SearchResultMatchI.java b/src/jalview/datamodel/SearchResultMatchI.java index 661ad6c..dedb960 100644 --- a/src/jalview/datamodel/SearchResultMatchI.java +++ b/src/jalview/datamodel/SearchResultMatchI.java @@ -57,4 +57,13 @@ public interface SearchResultMatchI * @return */ boolean contains(SequenceI seq, int start, int end); + + /** + * + * @param seq + * @param from - first position to highlight + * @param to - last position to highlight (assumed higher than from) + * @return true iff from-to intersects or marks positions either side of start/end + */ + boolean adjacent(SequenceI seq, int from, int to); } \ No newline at end of file diff --git a/src/jalview/datamodel/SearchResults.java b/src/jalview/datamodel/SearchResults.java index 909a0fe..546dd6f 100755 --- a/src/jalview/datamodel/SearchResults.java +++ b/src/jalview/datamodel/SearchResults.java @@ -35,13 +35,13 @@ public class SearchResults implements SearchResultsI { private int count; - private List matches = new ArrayList<>(); + private ArrayList matches = new ArrayList<>(); /** * One match consists of a sequence reference, start and end positions. * Discontiguous ranges in a sequence require two or more Match objects. */ - public class Match implements SearchResultMatchI + public class Match implements SearchResultMatchI, Comparable { final SequenceI sequence; @@ -160,6 +160,39 @@ public class SearchResults implements SearchResultsI { return (sequence == seq && start <= from && end >= to); } + @Override + public boolean adjacent(SequenceI seq, int from, int to) + { + return (sequence == seq && ((start <= from && end >= to) || (from<=(end+1) && to >=(end+1)) || (from<=(start-1) && to>=(start-1)))); + } + + @Override + public int compareTo(SearchResultMatchI o) + { + if (start o.getStart()) + { + return +1; + } + if (end < o.getEnd()) + { + return -1; + } + if (end > o.getEnd()) + { + return +1; + } + if (sequence!=o.getSequence()) + { + int hashc =sequence.hashCode(),oseq=o.getSequence().hashCode(); + return (hashc < oseq) ? -1 : 1; + } + return 0; + } + } @Override @@ -191,8 +224,56 @@ public class SearchResults implements SearchResultsI count = beforeCount + 1; } } + @Override + public boolean appendResult(SequenceI sequence, int start, int end) + { + + Match m = new Match(sequence, start, end); + + boolean appending=false; + + // we dynamically maintain an interval to add as we test each range in the list + + int cstart=start,cend=end; + List toRemove=new ArrayList<>(); + for (SearchResultMatchI thatm:matches) + { + if (thatm.getSequence()==sequence) + { + if (thatm.contains(sequence,cstart,cend)) + { + // found a match containing the current range. nothing else to do except report if we operated on the list + return appending; + } + if (thatm.adjacent(sequence, cstart, cend)) + { + // update the match to add with the adjacent start/end + start = Math.min(m.start, thatm.getStart()); + end = Math.max(m.end, thatm.getEnd()); + // and check if we keep or remove the old one + if (thatm.getStart()!=start || thatm.getEnd()!=end) + { + toRemove.add(thatm); + count--; + cstart = start; + cend = end; + appending=true; + } else { + return false; + } + } + } + } + matches.removeAll(toRemove); + { + matches.add(new Match(sequence,cstart,cend)); + count++; + } + return appending; + } + @Override public boolean involvesSequence(SequenceI sequence) { final int start = sequence.getStart(); @@ -269,7 +350,7 @@ public class SearchResults implements SearchResultsI else { // debug - // System.err.println("Outwith bounds!" + matchStart+">"+end +" or " + // jalview.bin.Console.errPrintln("Outwith bounds!" + matchStart+">"+end +" or " // + matchEnd+"<"+start); } } @@ -393,4 +474,5 @@ public class SearchResults implements SearchResultsI } return seqs; } + } diff --git a/src/jalview/datamodel/SearchResultsI.java b/src/jalview/datamodel/SearchResultsI.java index 7946824..d682de1 100644 --- a/src/jalview/datamodel/SearchResultsI.java +++ b/src/jalview/datamodel/SearchResultsI.java @@ -51,6 +51,19 @@ public interface SearchResultsI */ void addResult(SequenceI seq, int[] positions); + + /** + * Adds the given start/end region to this search result. If sequence already + * has a search result and the range is adjacent to already highlighted + * positions, they will be merged + * + * @param sequence + * @param start + * @param end + * @return true if an existing range was updated with this one + */ + boolean appendResult(SequenceI sequence, int start, int end); + /** * adds all match results in the argument to this set * diff --git a/src/jalview/datamodel/SeqDistanceContactMatrix.java b/src/jalview/datamodel/SeqDistanceContactMatrix.java index f8fd750..b04ac13 100644 --- a/src/jalview/datamodel/SeqDistanceContactMatrix.java +++ b/src/jalview/datamodel/SeqDistanceContactMatrix.java @@ -114,7 +114,7 @@ public class SeqDistanceContactMatrix return width; } @Override - protected double getElementAt(int _column, int i) + public double getElementAt(int _column, int i) { return Math.abs(_column - i); } diff --git a/src/jalview/datamodel/Sequence.java b/src/jalview/datamodel/Sequence.java index 5bb55e5..7a5d5bc 100755 --- a/src/jalview/datamodel/Sequence.java +++ b/src/jalview/datamodel/Sequence.java @@ -174,7 +174,7 @@ public class Sequence extends ASequence implements SequenceI { if (name == null) { - System.err.println( + jalview.bin.Console.errPrintln( "POSSIBLE IMPLEMENTATION ERROR: null sequence name passed to constructor."); name = ""; } @@ -387,7 +387,7 @@ public class Sequence extends ASequence implements SequenceI { if (sf.getType() == null) { - System.err.println( + jalview.bin.Console.errPrintln( "SequenceFeature type may not be null: " + sf.toString()); return false; } diff --git a/src/jalview/datamodel/SequenceGroup.java b/src/jalview/datamodel/SequenceGroup.java index 326793d..9837104 100755 --- a/src/jalview/datamodel/SequenceGroup.java +++ b/src/jalview/datamodel/SequenceGroup.java @@ -644,7 +644,7 @@ public class SequenceGroup implements AnnotatedCollectionI } catch (java.lang.OutOfMemoryError err) { // TODO: catch OOM - System.out.println("Out of memory loading groups: " + err); + jalview.bin.Console.outPrintln("Out of memory loading groups: " + err); } return upd; } diff --git a/src/jalview/datamodel/features/FeatureMatcher.java b/src/jalview/datamodel/features/FeatureMatcher.java index 65cba0d..124909c 100644 --- a/src/jalview/datamodel/features/FeatureMatcher.java +++ b/src/jalview/datamodel/features/FeatureMatcher.java @@ -147,7 +147,7 @@ public class FeatureMatcher implements FeatureMatcherI int nextQuotePos = descriptor.indexOf(QUOTE, 1); if (nextQuotePos == -1) { - System.err.println(invalidFormat); + jalview.bin.Console.errPrintln(invalidFormat); return null; } firstField = descriptor.substring(1, nextQuotePos); @@ -159,7 +159,7 @@ public class FeatureMatcher implements FeatureMatcherI int nextSpacePos = descriptor.indexOf(SPACE); if (nextSpacePos == -1) { - System.err.println(invalidFormat); + jalview.bin.Console.errPrintln(invalidFormat); return null; } firstField = descriptor.substring(0, nextSpacePos); @@ -193,7 +193,7 @@ public class FeatureMatcher implements FeatureMatcherI cond = Condition.fromString(leftToParse); if (cond == null || cond.needsAPattern()) { - System.err.println(invalidFormat); + jalview.bin.Console.errPrintln(invalidFormat); return null; } } @@ -214,7 +214,7 @@ public class FeatureMatcher implements FeatureMatcherI else { // unbalanced quote - System.err.println(invalidFormat); + jalview.bin.Console.errPrintln(invalidFormat); return null; } } diff --git a/src/jalview/datamodel/features/FeatureMatcherSet.java b/src/jalview/datamodel/features/FeatureMatcherSet.java index a5efe5d..eae3664 100644 --- a/src/jalview/datamodel/features/FeatureMatcherSet.java +++ b/src/jalview/datamodel/features/FeatureMatcherSet.java @@ -93,7 +93,7 @@ public class FeatureMatcherSet implements FeatureMatcherSetI if (spacePos == -1) { // trailing junk after a match condition - System.err.println(invalid); + jalview.bin.Console.errPrintln(invalid); return null; } String conjunction = leftToParse.substring(0, spacePos); @@ -109,7 +109,7 @@ public class FeatureMatcherSet implements FeatureMatcherSetI else { // not an AND or an OR - invalid - System.err.println(invalid); + jalview.bin.Console.errPrintln(invalid); return null; } } @@ -123,7 +123,7 @@ public class FeatureMatcherSet implements FeatureMatcherSetI int closePos = leftToParse.indexOf(CLOSE_BRACKET); if (closePos == -1) { - System.err.println(invalid); + jalview.bin.Console.errPrintln(invalid); return null; } nextCondition = leftToParse.substring(1, closePos); @@ -137,7 +137,7 @@ public class FeatureMatcherSet implements FeatureMatcherSetI FeatureMatcher fm = FeatureMatcher.fromString(nextCondition); if (fm == null) { - System.err.println(invalid); + jalview.bin.Console.errPrintln(invalid); return null; } try @@ -154,7 +154,7 @@ public class FeatureMatcherSet implements FeatureMatcherSetI } catch (IllegalStateException e) { // thrown if OR and AND are mixed - System.err.println(invalid); + jalview.bin.Console.errPrintln(invalid); return null; } diff --git a/src/jalview/datamodel/features/FeatureStore.java b/src/jalview/datamodel/features/FeatureStore.java index eb5688c..c19d782 100644 --- a/src/jalview/datamodel/features/FeatureStore.java +++ b/src/jalview/datamodel/features/FeatureStore.java @@ -401,7 +401,7 @@ public class FeatureStore SequenceFeature sf = contactFeatureEnds.get(index); if (!sf.isContactFeature()) { - System.err.println("Error! non-contact feature type " + sf.getType() + jalview.bin.Console.errPrintln("Error! non-contact feature type " + sf.getType() + " in contact features list"); index++; continue; @@ -454,7 +454,7 @@ public class FeatureStore SequenceFeature sf = contactFeatureStarts.get(index); if (!sf.isContactFeature()) { - System.err.println("Error! non-contact feature " + sf.toString() + jalview.bin.Console.errPrintln("Error! non-contact feature " + sf.toString() + " in contact features list"); index++; continue; diff --git a/src/jalview/datamodel/features/SequenceFeatures.java b/src/jalview/datamodel/features/SequenceFeatures.java index 905fd8b..ed4474e 100644 --- a/src/jalview/datamodel/features/SequenceFeatures.java +++ b/src/jalview/datamodel/features/SequenceFeatures.java @@ -88,7 +88,7 @@ public class SequenceFeatures implements SequenceFeaturesI String type = sf.getType(); if (type == null) { - System.err.println("Feature type may not be null: " + sf.toString()); + jalview.bin.Console.errPrintln("Feature type may not be null: " + sf.toString()); return false; } diff --git a/src/jalview/ext/ensembl/EnsemblGene.java b/src/jalview/ext/ensembl/EnsemblGene.java index 75a7154..391fd6f 100644 --- a/src/jalview/ext/ensembl/EnsemblGene.java +++ b/src/jalview/ext/ensembl/EnsemblGene.java @@ -226,7 +226,7 @@ public class EnsemblGene extends EnsemblSeqProxy return true; } catch (NumberFormatException e) { - System.err.println("Bad integers in description " + description); + jalview.bin.Console.errPrintln("Bad integers in description " + description); } } return false; diff --git a/src/jalview/ext/ensembl/EnsemblLookup.java b/src/jalview/ext/ensembl/EnsemblLookup.java index 0813ba8..e188986 100644 --- a/src/jalview/ext/ensembl/EnsemblLookup.java +++ b/src/jalview/ext/ensembl/EnsemblLookup.java @@ -222,7 +222,7 @@ public class EnsemblLookup extends EnsemblRestClient ids, -1, MODE_MAP, null); } catch (IOException | ParseException e) { - System.err.println("Error parsing " + identifier + " lookup response " + jalview.bin.Console.errPrintln("Error parsing " + identifier + " lookup response " + e.getMessage()); return null; } diff --git a/src/jalview/ext/ensembl/EnsemblMap.java b/src/jalview/ext/ensembl/EnsemblMap.java index f2ab195..1fd9a23 100644 --- a/src/jalview/ext/ensembl/EnsemblMap.java +++ b/src/jalview/ext/ensembl/EnsemblMap.java @@ -157,7 +157,7 @@ public class EnsemblMap extends EnsemblRestClient return (parseAssemblyMappingResponse(url)); } catch (Throwable t) { - System.out.println("Error calling " + url + ": " + t.getMessage()); + jalview.bin.Console.outPrintln("Error calling " + url + ": " + t.getMessage()); return null; } } @@ -265,7 +265,7 @@ public class EnsemblMap extends EnsemblRestClient return null; } catch (Throwable t) { - System.out.println("Error calling " + url + ": " + t.getMessage()); + jalview.bin.Console.outPrintln("Error calling " + url + ": " + t.getMessage()); return null; } } @@ -342,7 +342,7 @@ public class EnsemblMap extends EnsemblRestClient String ass = mapped.get("assembly_name").toString(); if (assembly != null && !assembly.equals(ass)) { - System.err.println( + jalview.bin.Console.errPrintln( "EnsemblMap found multiple assemblies - can't resolve"); return null; } @@ -350,7 +350,7 @@ public class EnsemblMap extends EnsemblRestClient String chr = mapped.get("seq_region_name").toString(); if (chromosome != null && !chromosome.equals(chr)) { - System.err.println( + jalview.bin.Console.errPrintln( "EnsemblMap found multiple chromosomes - can't resolve"); return null; } diff --git a/src/jalview/ext/ensembl/EnsemblRestClient.java b/src/jalview/ext/ensembl/EnsemblRestClient.java index 4a5544e..540fc98 100644 --- a/src/jalview/ext/ensembl/EnsemblRestClient.java +++ b/src/jalview/ext/ensembl/EnsemblRestClient.java @@ -211,7 +211,7 @@ abstract class EnsemblRestClient extends EnsemblSequenceFetcher return pingString != null; } catch (Throwable t) { - System.err.println( + jalview.bin.Console.errPrintln( "Error connecting to " + pingUrl + ": " + t.getMessage()); } finally { @@ -313,7 +313,7 @@ abstract class EnsemblRestClient extends EnsemblSequenceFetcher * note: a GET request for an invalid id returns an error code e.g. 415 * but POST request returns 200 and an empty Fasta response */ - System.err.println("Response code " + responseCode);// + " for " + url); + jalview.bin.Console.errPrintln("Response code " + responseCode);// + " for " + url); return null; } @@ -338,7 +338,7 @@ abstract class EnsemblRestClient extends EnsemblSequenceFetcher protected HttpURLConnection tryConnection(URL url, List ids, int readTimeout) throws IOException, ProtocolException { - // System.out.println(System.currentTimeMillis() + " " + url); + // jalview.bin.Console.outPrintln(System.currentTimeMillis() + " " + url); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); @@ -387,14 +387,14 @@ abstract class EnsemblRestClient extends EnsemblSequenceFetcher int retrySecs = Integer.valueOf(retryDelay); if (retrySecs > 0 && retrySecs < 10) { - System.err.println( + jalview.bin.Console.errPrintln( "Ensembl REST service rate limit exceeded, waiting " + retryDelay + " seconds before retrying"); Thread.sleep(1000 * retrySecs); } } catch (NumberFormatException | InterruptedException e) { - System.err.println("Error handling Retry-After: " + e.getMessage()); + jalview.bin.Console.errPrintln("Error handling Retry-After: " + e.getMessage()); } } } @@ -566,7 +566,7 @@ abstract class EnsemblRestClient extends EnsemblSequenceFetcher } } catch (NumberFormatException e) { - System.err.println("Error in REST version: " + e.toString()); + jalview.bin.Console.errPrintln("Error in REST version: " + e.toString()); } /* @@ -578,14 +578,14 @@ abstract class EnsemblRestClient extends EnsemblSequenceFetcher expected) == 1; if (laterVersion) { - System.err.println(String.format( + jalview.bin.Console.errPrintln(String.format( "EnsemblRestClient expected %s REST version %s but found %s, see %s", getDbSource(), expected, version, REST_CHANGE_LOG)); } info.restVersion = version; } catch (Throwable t) { - System.err.println( + jalview.bin.Console.errPrintln( "Error checking Ensembl REST version: " + t.getMessage()); } } @@ -617,7 +617,7 @@ abstract class EnsemblRestClient extends EnsemblSequenceFetcher domainData.get(getDomain()).dataVersion = versions.get(0).toString(); } catch (Throwable e) {// could be IOException | ParseException e) { - System.err.println( + jalview.bin.Console.errPrintln( "Error checking Ensembl data version: " + e.getMessage()); } } diff --git a/src/jalview/ext/ensembl/EnsemblSeqProxy.java b/src/jalview/ext/ensembl/EnsemblSeqProxy.java index 56eda5e..949c52e 100644 --- a/src/jalview/ext/ensembl/EnsemblSeqProxy.java +++ b/src/jalview/ext/ensembl/EnsemblSeqProxy.java @@ -155,7 +155,7 @@ public abstract class EnsemblSeqProxy extends EnsemblRestClient String msg = "Aborting ID retrieval after " + v + " chunks. Unexpected problem (" + r.getLocalizedMessage() + ")"; - System.err.println(msg); + jalview.bin.Console.errPrintln(msg); r.printStackTrace(); break; } @@ -240,7 +240,7 @@ public abstract class EnsemblSeqProxy extends EnsemblRestClient } } catch (IOException e) { - System.err.println( + jalview.bin.Console.errPrintln( "Error transferring Ensembl features: " + e.getMessage()); } // Platform.timeCheck("ESP.addfeat done", Platform.TIME_MARK); @@ -265,12 +265,12 @@ public abstract class EnsemblSeqProxy extends EnsemblRestClient String accId = querySeq.getName(); try { - System.out.println("Adding protein product for " + accId); + jalview.bin.Console.outPrintln("Adding protein product for " + accId); AlignmentI protein = new EnsemblProtein(getDomain()) .getSequenceRecords(accId); if (protein == null || protein.getHeight() == 0) { - System.out.println("No protein product found for " + accId); + jalview.bin.Console.outPrintln("No protein product found for " + accId); return; } SequenceI proteinSeq = protein.getSequenceAt(0); @@ -382,7 +382,7 @@ public abstract class EnsemblSeqProxy extends EnsemblRestClient seq.addDBRef(xrefs.get(i)); } - // System.out.println("primaries are " + seq.getPrimaryDBRefs().toString()); + // jalview.bin.Console.outPrintln("primaries are " + seq.getPrimaryDBRefs().toString()); /* * and add a reference to itself */ @@ -430,7 +430,7 @@ public abstract class EnsemblSeqProxy extends EnsemblRestClient if (seqs.size() != ids.size()) { - System.out.println(String.format( + jalview.bin.Console.outPrintln(String.format( "Only retrieved %d sequences for %d query strings", seqs.size(), ids.size())); } @@ -508,7 +508,7 @@ public abstract class EnsemblSeqProxy extends EnsemblRestClient result.add(sequence); } catch (ParseException | IOException e) { - System.err.println("Error processing JSON response: " + e.toString()); + jalview.bin.Console.errPrintln("Error processing JSON response: " + e.toString()); // ignore } // Platform.timeCheck("ENS seqproxy2", Platform.TIME_MARK); @@ -659,7 +659,7 @@ public abstract class EnsemblSeqProxy extends EnsemblRestClient if (regions.isEmpty()) { - System.out.println("Failed to identify target sequence for " + accId + jalview.bin.Console.outPrintln("Failed to identify target sequence for " + accId + " from genomic features"); return null; } @@ -829,7 +829,7 @@ public abstract class EnsemblSeqProxy extends EnsemblRestClient boolean result = transferFeatures(sfs, targetSequence, mapping, accessionId); - // System.out.println("transferFeatures (" + (sfs.size()) + " --> " + // jalview.bin.Console.outPrintln("transferFeatures (" + (sfs.size()) + " --> " // + targetSequence.getFeatures().getFeatureCount(true) + ") to " // + targetSequence.getName() + " took " // + (System.currentTimeMillis() - start) + "ms"); diff --git a/src/jalview/ext/htsjdk/HtsContigDb.java b/src/jalview/ext/htsjdk/HtsContigDb.java index 9a985b6..8cce87a 100644 --- a/src/jalview/ext/htsjdk/HtsContigDb.java +++ b/src/jalview/ext/htsjdk/HtsContigDb.java @@ -261,7 +261,7 @@ public class HtsContigDb { if (!isValid() || !refFile.isIndexed()) { - System.err.println( + jalview.bin.Console.errPrintln( "Cannot read contig as file is invalid or not indexed"); return null; } diff --git a/src/jalview/ext/jmol/JalviewJmolBinding.java b/src/jalview/ext/jmol/JalviewJmolBinding.java index 21a19ae..9d49a93 100644 --- a/src/jalview/ext/jmol/JalviewJmolBinding.java +++ b/src/jalview/ext/jmol/JalviewJmolBinding.java @@ -26,6 +26,8 @@ import java.awt.event.ComponentListener; import java.io.File; import java.net.URL; import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.StringTokenizer; @@ -163,28 +165,49 @@ public abstract class JalviewJmolBinding extends AAStructureBindingModel public void createImage(String file, String type, int quality) { - System.out.println("JMOL CREATE IMAGE"); + jalview.bin.Console.outPrintln("JMOL CREATE IMAGE"); } @Override public String createImage(String fileName, String type, Object textOrBytes, int quality) { - System.out.println("JMOL CREATE IMAGE"); + jalview.bin.Console.outPrintln("JMOL CREATE IMAGE"); return null; } @Override public String eval(String strEval) { - // System.out.println(strEval); + // jalview.bin.Console.outPrintln(strEval); // "# 'eval' is implemented only for the applet."; return null; } // End StructureListener // ////////////////////////// - + + //////////////////////////// + // HETATM get + // + + @Override + public Map getHetatmNames() + { + HashMap hetlist=new HashMap(); + for (int mc=0;mc hets = jmolViewer.ms.getHeteroList(mc); + if (hets!=null) + { + hetlist.putAll(hets); + } + } + return hetlist; + } + // + //////////////////////////// + @Override public float[][] functionXY(String functionName, int x, int y) { @@ -267,16 +290,30 @@ public abstract class JalviewJmolBinding extends AAStructureBindingModel { if (atoms != null) { - boolean useScriptWait = atoms.size() > 1; if (resetLastRes.length() > 0) { - jmolScript(resetLastRes.toString(), useScriptWait); + jmolScript(resetLastRes.toString()); resetLastRes.setLength(0); } + StringBuilder highlightCommands=null; for (AtomSpec atom : atoms) { - highlightAtom(atom.getAtomIndex(), atom.getPdbResNum(), - atom.getChain(), atom.getPdbFile(), useScriptWait); + StringBuilder thisAtom = highlightAtom(atom.getAtomIndex(), atom.getPdbResNum(), + atom.getChain(), atom.getPdbFile()); + if (thisAtom!=null) { + if (highlightCommands==null) + { + highlightCommands=thisAtom; + } else { + highlightCommands.append(thisAtom); + } + } + } + if (highlightCommands!=null) + { + jmolHistory(false); + jmolScript(highlightCommands.toString()); + jmolHistory(true); } // Highlight distances between atoms with a 'measure' command - not yet // working @@ -306,17 +343,15 @@ public abstract class JalviewJmolBinding extends AAStructureBindingModel } // jmol/ssm only - public void highlightAtom(int atomIndex, int pdbResNum, String chain, - String pdbfile, boolean useScriptWait) + private StringBuilder highlightAtom(int atomIndex, int pdbResNum, String chain, + String pdbfile) { String modelId = getModelIdForFile(pdbfile); if (modelId.isEmpty()) { - return; + return null; } - jmolHistory(false, useScriptWait); - StringBuilder selection = new StringBuilder(32); StringBuilder cmd = new StringBuilder(64); selection.append("select ").append(String.valueOf(pdbResNum)); @@ -333,8 +368,7 @@ public abstract class JalviewJmolBinding extends AAStructureBindingModel resetLastRes.append(selection).append(";wireframe 0;").append(selection) .append(" and not hetero; spacefill 0;"); - jmolScript(cmd.toString(), useScriptWait); - jmolHistory(true, useScriptWait); + return cmd; } private boolean debug = true; @@ -476,7 +510,7 @@ public abstract class JalviewJmolBinding extends AAStructureBindingModel lastMessage = strInfo; if (data != null) { - System.err.println("Ignoring additional hover info: " + data + jalview.bin.Console.errPrintln("Ignoring additional hover info: " + data + " (other info: '" + strInfo + "' pos " + atomIndex + ")"); } mouseOverStructure(atomIndex, strInfo); @@ -497,7 +531,7 @@ public abstract class JalviewJmolBinding extends AAStructureBindingModel */ if (strData != null) { - System.err.println("Ignoring additional pick data string " + strData); + jalview.bin.Console.errPrintln("Ignoring additional pick data string " + strData); } int chainSeparator = strInfo.indexOf(":"); int p = 0; @@ -599,7 +633,7 @@ public abstract class JalviewJmolBinding extends AAStructureBindingModel (data == null) ? ((String) null) : (String) data[1]); break; case ERROR: - // System.err.println("Ignoring error callback."); + // jalview.bin.Console.errPrintln("Ignoring error callback."); break; case SYNC: case RESIZE: @@ -609,13 +643,13 @@ public abstract class JalviewJmolBinding extends AAStructureBindingModel case CLICK: default: - System.err.println( + jalview.bin.Console.errPrintln( "Unhandled callback " + type + " " + data[1].toString()); break; } } catch (Exception e) { - System.err.println("Squashed Jmol callback handler error:"); + jalview.bin.Console.errPrintln("Squashed Jmol callback handler error:"); e.printStackTrace(); } } @@ -864,7 +898,7 @@ public abstract class JalviewJmolBinding extends AAStructureBindingModel public void setCallbackFunction(String callbackType, String callbackFunction) { - System.err.println("Ignoring set-callback request to associate " + jalview.bin.Console.errPrintln("Ignoring set-callback request to associate " + callbackType + " with function " + callbackFunction); } @@ -938,7 +972,7 @@ public abstract class JalviewJmolBinding extends AAStructureBindingModel String buttonsToShow) { - System.err.println("Allocating Jmol Viewer: " + commandOptions); + jalview.bin.Console.errPrintln("Allocating Jmol Viewer: " + commandOptions); if (commandOptions == null) { @@ -956,7 +990,7 @@ public abstract class JalviewJmolBinding extends AAStructureBindingModel console = createJmolConsole(consolePanel, buttonsToShow); } catch (Throwable e) { - System.err.println("Could not create Jmol application console. " + jalview.bin.Console.errPrintln("Could not create Jmol application console. " + e.getMessage()); e.printStackTrace(); } diff --git a/src/jalview/ext/jmol/JmolCommands.java b/src/jalview/ext/jmol/JmolCommands.java index 19d64f0..106d458 100644 --- a/src/jalview/ext/jmol/JmolCommands.java +++ b/src/jalview/ext/jmol/JmolCommands.java @@ -316,7 +316,38 @@ public class JmolCommands extends StructureCommandsBase return new StructureCommand( "load FILES \"" + Platform.escapeBackslashes(file) + "\""); } + @Override + public StructureCommandI restoreSession(String filePath) + { + return new StructureCommand( + "restore STATE \"" + Platform.escapeBackslashes(filePath) + "\""); + } + @Override + public List showHetatms(List toShow) + { + // always clear the current hetero cpk display + + StringBuilder sb = new StringBuilder(); + sb.append("select hetero; cpk off;"); + + if (toShow != null && !toShow.isEmpty()) + { + // select what was requested + sb.append("select "); + boolean or = false; + for (String k : toShow) + { + sb.append(or ? " or " : " "); + sb.append(k); + or = true; + } + // and show as + sb.append("; cpk;"); + } + + return Arrays.asList(new StructureCommand(sb.toString())); + } /** * Obsolete method, only referenced from * jalview.javascript.MouseOverStructureListener diff --git a/src/jalview/ext/jmol/JmolParser.java b/src/jalview/ext/jmol/JmolParser.java index 57b406e..0ca2ba8 100644 --- a/src/jalview/ext/jmol/JmolParser.java +++ b/src/jalview/ext/jmol/JmolParser.java @@ -338,7 +338,7 @@ public class JmolParser extends StructureFile implements JmolStatusListener } } catch (OutOfMemoryError er) { - System.out.println( + jalview.bin.Console.outPrintln( "OUT OF MEMORY LOADING TRANSFORMING JMOL MODEL TO JALVIEW MODEL"); throw new IOException(MessageManager .getString("exception.outofmemory_loading_mmcif_file")); @@ -391,7 +391,7 @@ public class JmolParser extends StructureFile implements JmolStatusListener org.jmol.modelset.Atom prevAtom, HashMap chainTerMap) { - // System.out.println("Atom: " + curAtom.getAtomNumber() + // jalview.bin.Console.outPrintln("Atom: " + curAtom.getAtomNumber() // + " Last atom index " + curAtom.group.lastAtomIndex); if (chainTerMap == null || prevAtom == null) { diff --git a/src/jalview/ext/paradise/Annotate3D.java b/src/jalview/ext/paradise/Annotate3D.java index de1d90c..3817ee9 100644 --- a/src/jalview/ext/paradise/Annotate3D.java +++ b/src/jalview/ext/paradise/Annotate3D.java @@ -229,7 +229,7 @@ class RvalsIterator implements Iterator, AutoCloseable if (sval == null) { - System.err.println( + jalview.bin.Console.errPrintln( "DEVELOPER WARNING: Annotate3d didn't return a '2D' tag in its response. Consider checking output of server. Response was :" + val.toString()); diff --git a/src/jalview/ext/pymol/PymolManager.java b/src/jalview/ext/pymol/PymolManager.java index 7dfdb0c..ddc8d84 100644 --- a/src/jalview/ext/pymol/PymolManager.java +++ b/src/jalview/ext/pymol/PymolManager.java @@ -158,7 +158,7 @@ public class PymolManager boolean getReply) { String postBody = getPostRequest(command); - // System.out.println(postBody);// debug + // jalview.bin.Console.outPrintln(postBody);// debug String rpcUrl = "http://127.0.0.1:" + this.pymolXmlRpcPort; PrintWriter out = null; BufferedReader in = null; diff --git a/src/jalview/ext/rbvi/chimera/ChimeraListener.java b/src/jalview/ext/rbvi/chimera/ChimeraListener.java index 40b0ff0..af31b78 100644 --- a/src/jalview/ext/rbvi/chimera/ChimeraListener.java +++ b/src/jalview/ext/rbvi/chimera/ChimeraListener.java @@ -126,12 +126,12 @@ public class ChimeraListener extends AbstractRequestHandler } else if (message.startsWith(MODEL_CHANGED)) { - System.err.println(message); + jalview.bin.Console.errPrintln(message); processModelChanged(message.substring(MODEL_CHANGED.length())); } else { - System.err.println("Unexpected chimeraNotification: " + message); + jalview.bin.Console.errPrintln("Unexpected chimeraNotification: " + message); } } } @@ -143,7 +143,7 @@ public class ChimeraListener extends AbstractRequestHandler */ protected void processModelChanged(String message) { - // System.out.println(message + " (not implemented in Jalview)"); + // jalview.bin.Console.outPrintln(message + " (not implemented in Jalview)"); } /** diff --git a/src/jalview/ext/rbvi/chimera/JalviewChimeraBinding.java b/src/jalview/ext/rbvi/chimera/JalviewChimeraBinding.java index aebfede..a292e88 100644 --- a/src/jalview/ext/rbvi/chimera/JalviewChimeraBinding.java +++ b/src/jalview/ext/rbvi/chimera/JalviewChimeraBinding.java @@ -207,7 +207,7 @@ public abstract class JalviewChimeraBinding extends AAStructureBindingModel startListening(chimeraListener.getUri()); } catch (BindException e) { - System.err.println( + jalview.bin.Console.errPrintln( "Failed to start Chimera listener: " + e.getMessage()); } } @@ -568,7 +568,7 @@ public abstract class JalviewChimeraBinding extends AAStructureBindingModel private void log(String message) { - System.err.println("## Chimera log: " + message); + jalview.bin.Console.errPrintln("## Chimera log: " + message); } /** @@ -627,7 +627,7 @@ public abstract class JalviewChimeraBinding extends AAStructureBindingModel executeCommand(false, null, command); } catch (IOException e) { - System.err.println("Sending commands to Chimera via file failed with " + jalview.bin.Console.errPrintln("Sending commands to Chimera via file failed with " + e.getMessage()); } } diff --git a/src/jalview/fts/core/FTSDataColumnPreferences.java b/src/jalview/fts/core/FTSDataColumnPreferences.java index 0971235..86b8c7d 100644 --- a/src/jalview/fts/core/FTSDataColumnPreferences.java +++ b/src/jalview/fts/core/FTSDataColumnPreferences.java @@ -94,7 +94,7 @@ public class FTSDataColumnPreferences extends JScrollPane int x = 0; for (FTSDataColumnI field : allFTSDataColumns) { - // System.out.println("allFTSDataColumns==" + allFTSDataColumns); + // jalview.bin.Console.outPrintln("allFTSDataColumns==" + allFTSDataColumns); if (field.getName().equalsIgnoreCase("all")) { continue; @@ -106,7 +106,7 @@ public class FTSDataColumnPreferences extends JScrollPane data[x++] = new Object[] { ftsRestClient .getAllDefaultDisplayedFTSDataColumns().contains(field), field.getName(), field.getGroup() }; - // System.out.println(" PUIS " + field.getName() + " ET AUSSI " + + // jalview.bin.Console.outPrintln(" PUIS " + field.getName() + " ET AUSSI " + // field.getGroup() + "X = " + x); break; case STRUCTURE_CHOOSER: diff --git a/src/jalview/fts/service/alphafold/AlphafoldRestClient.java b/src/jalview/fts/service/alphafold/AlphafoldRestClient.java index 7e95dd2..a631902 100644 --- a/src/jalview/fts/service/alphafold/AlphafoldRestClient.java +++ b/src/jalview/fts/service/alphafold/AlphafoldRestClient.java @@ -118,7 +118,7 @@ public class AlphafoldRestClient } catch (Exception e) { e.printStackTrace(); - System.out.println("offending value:" + fieldData); + jalview.bin.Console.outPrintln("offending value:" + fieldData); } } } diff --git a/src/jalview/fts/service/pdb/PDBFTSRestClient.java b/src/jalview/fts/service/pdb/PDBFTSRestClient.java index 796bc0e..5619075 100644 --- a/src/jalview/fts/service/pdb/PDBFTSRestClient.java +++ b/src/jalview/fts/service/pdb/PDBFTSRestClient.java @@ -175,7 +175,7 @@ public class PDBFTSRestClient extends FTSRestClient URI uri = webResource.getURI(); - System.out.println(uri); + jalview.bin.Console.outPrintln(uri); ClientResponse clientResponse = null; int responseStatus = -1; // Get the JSON string from the response object or directly from the @@ -183,7 +183,7 @@ public class PDBFTSRestClient extends FTSRestClient Map jsonObj = null; String responseString = null; - System.out.println("query >>>>>>> " + pdbRestRequest.toString()); + jalview.bin.Console.outPrintln("query >>>>>>> " + pdbRestRequest.toString()); if (!isMocked()) { @@ -413,10 +413,10 @@ public class PDBFTSRestClient extends FTSRestClient for (FTSDataColumnI field : diplayFields) { - // System.out.println("Field " + field); + // jalview.bin.Console.outPrintln("Field " + field); String fieldData = (pdbJsonDoc.get(field.getCode()) == null) ? "" : pdbJsonDoc.get(field.getCode()).toString(); - // System.out.println("Field Data : " + fieldData); + // jalview.bin.Console.outPrintln("Field Data : " + fieldData); if (field.isPrimaryKeyColumn()) { primaryKey = fieldData; @@ -440,7 +440,7 @@ public class PDBFTSRestClient extends FTSRestClient } catch (Exception e) { e.printStackTrace(); - System.out.println("offending value:" + fieldData); + jalview.bin.Console.outPrintln("offending value:" + fieldData); } } } diff --git a/src/jalview/fts/service/threedbeacons/TDB_FTSData.java b/src/jalview/fts/service/threedbeacons/TDB_FTSData.java index 3045d3d..4e1b2b0 100644 --- a/src/jalview/fts/service/threedbeacons/TDB_FTSData.java +++ b/src/jalview/fts/service/threedbeacons/TDB_FTSData.java @@ -154,5 +154,14 @@ public class TDB_FTSData implements FTSData { return (String) getField(Model_id); } + + public String getConfidenceScoreType() + { + return (String) getField(Confidence_Score_Type); + } + public String getConfidenceScoreVersion() + { + return (String) getField(Confidence_Score_Version); + } } diff --git a/src/jalview/fts/service/threedbeacons/TDBeaconsFTSPanel.java b/src/jalview/fts/service/threedbeacons/TDBeaconsFTSPanel.java index 253de42..dfb39cb 100644 --- a/src/jalview/fts/service/threedbeacons/TDBeaconsFTSPanel.java +++ b/src/jalview/fts/service/threedbeacons/TDBeaconsFTSPanel.java @@ -277,7 +277,7 @@ public class TDBeaconsFTSPanel extends GFTSPanel @Override protected void showHelp() { - System.out.println("No help implemented yet."); + jalview.bin.Console.outPrintln("No help implemented yet."); } diff --git a/src/jalview/fts/service/threedbeacons/TDBeaconsFTSRestClient.java b/src/jalview/fts/service/threedbeacons/TDBeaconsFTSRestClient.java index d7f534e..c275bda 100644 --- a/src/jalview/fts/service/threedbeacons/TDBeaconsFTSRestClient.java +++ b/src/jalview/fts/service/threedbeacons/TDBeaconsFTSRestClient.java @@ -101,7 +101,7 @@ public class TDBeaconsFTSRestClient extends FTSRestClient webResource = client.resource(DEFAULT_THREEDBEACONS_DOMAIN + query); URI uri = webResource.getURI(); - System.out.println(uri.toString()); + jalview.bin.Console.outPrintln(uri.toString()); // Execute the REST request ClientResponse clientResponse; @@ -269,7 +269,7 @@ public class TDBeaconsFTSRestClient extends FTSRestClient String fieldData = (tdbJsonStructure.get(field.getCode()) == null) ? " " : tdbJsonStructure.get(field.getCode()).toString(); - // System.out.println("Field : " + field + " Data : " + fieldData); + // jalview.bin.Console.outPrintln("Field : " + field + " Data : " + fieldData); if (field.isPrimaryKeyColumn()) { primaryKey = fieldData; @@ -293,7 +293,7 @@ public class TDBeaconsFTSRestClient extends FTSRestClient } catch (Exception e) { // e.printStackTrace(); - System.out.println("offending value:" + fieldData + fieldData); + jalview.bin.Console.outPrintln("offending value:" + fieldData + fieldData); } } } diff --git a/src/jalview/fts/service/uniprot/UniProtFTSRestClient.java b/src/jalview/fts/service/uniprot/UniProtFTSRestClient.java index 1827293..df48c0d 100644 --- a/src/jalview/fts/service/uniprot/UniProtFTSRestClient.java +++ b/src/jalview/fts/service/uniprot/UniProtFTSRestClient.java @@ -219,7 +219,7 @@ public class UniProtFTSRestClient extends FTSRestClient .getEntity(String.class); // Make redundant objects eligible for garbage collection to conserve // memory - // System.out.println(">>>>> response : " + // jalview.bin.Console.outPrintln(">>>>> response : " // + uniProtTabDelimittedResponseString); if (clientResponse.getStatus() != 200) { @@ -307,7 +307,7 @@ public class UniProtFTSRestClient extends FTSRestClient firstRow = false; continue; } - // System.out.println(dataRow); + // jalview.bin.Console.outPrintln(dataRow); result.add(getFTSData(dataRow, uniprotRestRequest)); } searchResult.setNumberOfItemsFound(xTotalResults); @@ -389,7 +389,7 @@ public class UniProtFTSRestClient extends FTSRestClient } catch (Exception e) { e.printStackTrace(); - System.out.println("offending value:" + fieldData); + jalview.bin.Console.outPrintln("offending value:" + fieldData); } } } catch (Exception e) diff --git a/src/jalview/gui/AlignExportOptions.java b/src/jalview/gui/AlignExportOptions.java index c776d82..6ca21c7 100644 --- a/src/jalview/gui/AlignExportOptions.java +++ b/src/jalview/gui/AlignExportOptions.java @@ -32,6 +32,7 @@ import javax.swing.JPanel; import jalview.api.AlignExportSettingsI; import jalview.api.AlignViewportI; +import jalview.bin.Jalview; import jalview.io.FileFormatI; import jalview.util.MessageManager; @@ -72,12 +73,9 @@ public class AlignExportOptions extends JPanel public static boolean isNeeded(AlignViewportI viewport, FileFormatI format) { - if (viewport.hasHiddenColumns() || viewport.hasHiddenRows() - || format.isComplexAlignFile()) - { - return true; - } - return false; + return !Jalview.getInstance().isHeadlessMode() + && (viewport.hasHiddenColumns() || viewport.hasHiddenRows() + || format.isComplexAlignFile()); } /** diff --git a/src/jalview/gui/AlignFrame.java b/src/jalview/gui/AlignFrame.java index 49bd4e9..4f13a78 100644 --- a/src/jalview/gui/AlignFrame.java +++ b/src/jalview/gui/AlignFrame.java @@ -49,6 +49,7 @@ import java.beans.PropertyChangeEvent; import java.io.File; import java.io.FileWriter; import java.io.IOException; +import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.net.URL; import java.util.ArrayList; @@ -94,6 +95,7 @@ import jalview.api.analysis.SimilarityParamsI; import jalview.bin.Cache; import jalview.bin.Console; import jalview.bin.Jalview; +import jalview.bin.groovy.JalviewObjectI; import jalview.commands.CommandI; import jalview.commands.EditCommand; import jalview.commands.EditCommand.Action; @@ -157,7 +159,6 @@ import jalview.viewmodel.AlignmentViewport; import jalview.viewmodel.ViewportRanges; import jalview.ws.DBRefFetcher; import jalview.ws.DBRefFetcher.FetchFinishedListenerI; -import jalview.ws.datamodel.alphafold.PAEContactMatrix; import jalview.ws.jws1.Discoverer; import jalview.ws.jws2.Jws2Discoverer; import jalview.ws.jws2.jabaws2.Jws2Instance; @@ -503,7 +504,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, @Override public void focusGained(FocusEvent e) { - Jalview.setCurrentAlignFrame(AlignFrame.this); + Jalview.getInstance().setCurrentAlignFrame(AlignFrame.this); } }); @@ -624,12 +625,12 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, // if (viewport.cursorMode) // { // alignPanel.seqPanel.insertNucAtCursor(false,"A"); - // //System.out.println("A"); + // //jalview.bin.Console.outPrintln("A"); // } // break; /* * case KeyEvent.VK_CLOSE_BRACKET: if (viewport.cursorMode) { - * System.out.println("closing bracket"); } break; + * jalview.bin.Console.outPrintln("closing bracket"); } break; */ case KeyEvent.VK_DELETE: case KeyEvent.VK_BACK_SPACE: @@ -830,7 +831,8 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, @Override public void propertyChange(PropertyChangeEvent evt) { - // // System.out.println("Discoverer property change."); + // // jalview.bin.Console.outPrintln("Discoverer property + // change."); // if (evt.getPropertyName().equals("services")) { SwingUtilities.invokeLater(new Runnable() @@ -839,7 +841,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, @Override public void run() { - System.err.println( + jalview.bin.Console.errPrintln( "Rebuild WS Menu for service change"); BuildWebServiceMenu(); } @@ -854,7 +856,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, public void internalFrameClosed( javax.swing.event.InternalFrameEvent evt) { - // System.out.println("deregistering discoverer listener"); + // jalview.bin.Console.outPrintln("deregistering discoverer listener"); Desktop.instance.removeJalviewPropertyChangeListener("services", thisListener); closeMenuItem_actionPerformed(true); @@ -1251,8 +1253,17 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, */ public void saveAlignment(String file, FileFormatI format) { + saveAlignment(file, format, false, false); + } + + public void saveAlignment(String file, FileFormatI format, boolean stdout, + boolean forceBackup) + { lastSaveSuccessful = true; - lastFilenameSaved = file; + if (!stdout) + { + lastFilenameSaved = file; + } lastFormatSaved = format; if (FileFormat.Jalview.equals(format)) @@ -1263,6 +1274,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, shortName = shortName .substring(shortName.lastIndexOf(File.separatorChar) + 1); } + // TODO deal with stdout=true lastSaveSuccessful = new Jalview2XML().saveAlignment(this, file, shortName); @@ -1298,7 +1310,8 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, else { // create backupfiles object and get new temp filename destination - boolean doBackup = BackupFiles.getEnabled(); + boolean doBackup = forceBackup + || (BackupFiles.getEnabled() && !stdout); BackupFiles backupfiles = null; if (doBackup) { @@ -1310,7 +1323,9 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, String tempFilePath = doBackup ? backupfiles.getTempFilePath() : file; Console.trace("ALIGNFRAME setting PrintWriter"); - PrintWriter out = new PrintWriter(new FileWriter(tempFilePath)); + PrintWriter out = stdout + ? new PrintWriter(new OutputStreamWriter(System.out)) + : new PrintWriter(new FileWriter(tempFilePath)); if (backupfiles != null) { @@ -1319,13 +1334,28 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, } out.print(output); - Console.trace("ALIGNFRAME about to close file"); - out.close(); - Console.trace("ALIGNFRAME closed file"); - AlignFrame.this.setTitle(file); - statusBar.setText(MessageManager.formatMessage( - "label.successfully_saved_to_file_in_format", new Object[] - { fileName, format.getName() })); + out.flush(); + if (!stdout) + { + Console.trace("ALIGNFRAME about to close file"); + out.close(); + Console.trace("ALIGNFRAME closed file"); + } + AlignFrame.this.setTitle(stdout ? "STDOUT" : file); + if (stdout) + { + statusBar.setText(MessageManager.formatMessage( + "label.successfully_printed_to_stdout_in_format", + new Object[] + { format.getName() })); + } + else + { + statusBar.setText(MessageManager.formatMessage( + "label.successfully_saved_to_file_in_format", + new Object[] + { fileName, format.getName() })); + } lastSaveSuccessful = true; } catch (IOException e) { @@ -1456,9 +1486,11 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, protected void htmlMenuItem_actionPerformed(ActionEvent e) { HtmlSvgOutput htmlSVG = new HtmlSvgOutput(alignPanel); - try { + try + { htmlSVG.exportHTML(null); - } catch (ImageOutputException x) { + } catch (ImageOutputException x) + { // report problem to console and raise dialog } } @@ -1467,51 +1499,64 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, public void bioJSMenuItem_actionPerformed(ActionEvent e) { BioJsHTMLOutput bjs = new BioJsHTMLOutput(alignPanel); - try { - bjs.exportHTML(null); - } catch (ImageOutputException x) { - // report problem to console and raise dialog - } + try + { + bjs.exportHTML(null); + } catch (ImageOutputException x) + { + // report problem to console and raise dialog + } } public void createImageMap(File file, String image) { - try { - alignPanel.makePNGImageMap(file, image); - } catch (ImageOutputException x) { + try + { + alignPanel.makePNGImageMap(file, image); + } catch (ImageOutputException x) + { // report problem to console and raise dialog } } @Override - public void createPNG_actionPerformed(ActionEvent e) { - try{ + public void createPNG_actionPerformed(ActionEvent e) + { + try + { createPNG(null); } catch (ImageOutputException ioex) { // raise dialog, and report via console } } + @Override - public void createEPS_actionPerformed(ActionEvent e) { - try{ + public void createEPS_actionPerformed(ActionEvent e) + { + try + { createEPS(null); } catch (ImageOutputException ioex) { // raise dialog, and report via console } - + } + @Override - public void createSVG_actionPerformed(ActionEvent e) { - try{ + public void createSVG_actionPerformed(ActionEvent e) + { + try + { createSVG(null); } catch (ImageOutputException ioex) { // raise dialog, and report via console } - + } + /** * Creates a PNG image of the alignment and writes it to the given file. If * the file is null, the user is prompted to choose a file. @@ -1520,10 +1565,11 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, */ public void createPNG(File f) throws ImageOutputException { - createPNG(f, null, BitmapImageSizing.nullBitmapImageSizing()); + createPNG(f, null, BitmapImageSizing.defaultBitmapImageSizing()); } - public void createPNG(File f, String renderer, BitmapImageSizing userBis) throws ImageOutputException + public void createPNG(File f, String renderer, BitmapImageSizing userBis) + throws ImageOutputException { alignPanel.makeAlignmentImage(TYPE.PNG, f, renderer, userBis); } @@ -1534,7 +1580,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, * * @param f */ - public void createEPS(File f) throws ImageOutputException + public void createEPS(File f) throws ImageOutputException { createEPS(f, null); } @@ -1550,7 +1596,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, * * @param f */ - public void createSVG(File f) throws ImageOutputException + public void createSVG(File f) throws ImageOutputException { createSVG(f, null); } @@ -1626,6 +1672,8 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, closeAllTabs = true; } + Desktop.closeModal(this); + try { if (alignPanels != null) @@ -1655,6 +1703,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, featureSettings.close(); featureSettings = null; } + /* * this will raise an INTERNAL_FRAME_CLOSED event and this method will * be called recursively, with the frame now in 'closed' state @@ -1748,7 +1797,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, * * @return alignment objects for all views */ - AlignmentI[] getViewAlignments() + public AlignmentI[] getViewAlignments() { if (alignPanels != null) { @@ -2341,12 +2390,14 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, // annotation was duplicated earlier alignment.addAnnotation(sequences[i].getAnnotation()[a]); // take care of contact matrix too - ContactMatrixI cm=sequences[i].getContactMatrixFor(sequences[i].getAnnotation()[a]); - if (cm!=null) + ContactMatrixI cm = sequences[i] + .getContactMatrixFor(sequences[i].getAnnotation()[a]); + if (cm != null) { - alignment.addContactListFor(sequences[i].getAnnotation()[a], cm); + alignment.addContactListFor(sequences[i].getAnnotation()[a], + cm); } - + alignment.setAnnotationIndex(sequences[i].getAnnotation()[a], a); } @@ -2454,7 +2505,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, } catch (Exception ex) { ex.printStackTrace(); - System.out.println("Exception whilst pasting: " + ex); + jalview.bin.Console.outPrintln("Exception whilst pasting: " + ex); // could be anything being pasted in here } @@ -2502,7 +2553,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, } catch (Exception ex) { ex.printStackTrace(); - System.out.println("Exception whilst pasting: " + ex); + jalview.bin.Console.outPrintln("Exception whilst pasting: " + ex); // could be anything being pasted in here } catch (OutOfMemoryError oom) { @@ -3138,11 +3189,20 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, @Override public void wrapMenuItem_actionPerformed(ActionEvent e) { - scaleAbove.setVisible(wrapMenuItem.isSelected()); - scaleLeft.setVisible(wrapMenuItem.isSelected()); - scaleRight.setVisible(wrapMenuItem.isSelected()); - viewport.setWrapAlignment(wrapMenuItem.isSelected()); + setWrapFormat(wrapMenuItem.isSelected(), false); + } + + public void setWrapFormat(boolean b, boolean setMenuItem) + { + scaleAbove.setVisible(b); + scaleLeft.setVisible(b); + scaleRight.setVisible(b); + viewport.setWrapAlignment(b); alignPanel.updateLayout(); + if (setMenuItem) + { + wrapMenuItem.setSelected(b); + } } @Override @@ -3480,7 +3540,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, } JInternalFrame frame = new JInternalFrame(); - + frame.setFrameIcon(null); frame.getContentPane().add(new JScrollPane(pane)); Desktop.addInternalFrame(frame, MessageManager @@ -3508,12 +3568,12 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, return alignPanel.overviewPanel; } JInternalFrame frame = new JInternalFrame(); + frame.setFrameIcon(null); final OverviewPanel overview = new OverviewPanel(alignPanel, frame, showHidden); frame.setContentPane(overview); Desktop.addInternalFrame(frame, "", true, frame.getWidth(), frame.getHeight(), true, true); - frame.setFrameIcon(null); frame.pack(); frame.setLayer(JLayeredPane.PALETTE_LAYER); final AlignmentPanel thePanel = this.alignPanel; @@ -3787,6 +3847,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, else { JInternalFrame frame = new JInternalFrame(); + frame.setFrameIcon(null); frame.setContentPane(new PairwiseAlignPanel(viewport)); Desktop.addInternalFrame(frame, MessageManager.getString("action.pairwise_alignment"), 600, @@ -4239,8 +4300,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, return tp; } - public void showContactMapTree(AlignmentAnnotation aa, - ContactMatrixI cm) + public void showContactMapTree(AlignmentAnnotation aa, ContactMatrixI cm) { int x = 4, y = 5; int w = 400, h = 500; @@ -4249,8 +4309,8 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, { NewickFile fin = new NewickFile( new FileParse(cm.getNewick(), DataSourceType.PASTE)); - String title = aa.label + " " - + cm.getTreeMethod() + " tree" + (aa.sequenceRef != null + String title = aa.label + " " + cm.getTreeMethod() + " tree" + + (aa.sequenceRef != null ? (" for " + aa.sequenceRef.getDisplayId(false)) : ""); @@ -4303,7 +4363,8 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, { try { - System.err.println("Waiting for building menu to finish."); + jalview.bin.Console + .errPrintln("Waiting for building menu to finish."); Thread.sleep(10); } catch (Exception e) { @@ -4319,7 +4380,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, final List legacyItems = new ArrayList<>(); try { - // System.err.println("Building ws menu again " + // jalview.bin.Console.errPrintln("Building ws menu again " // + Thread.currentThread()); // TODO: add support for context dependent disabling of services based // on @@ -4757,7 +4818,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, * Object[] { String,SequenceI} */ ArrayList filesmatched = new ArrayList<>(); - ArrayList filesnotmatched = new ArrayList<>(); + ArrayList filesnotmatched = new ArrayList<>(); for (int i = 0; i < files.size(); i++) { // BH 2018 @@ -4803,9 +4864,9 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, } mtch = idm.findAllIdMatches(pdbfn); } + FileFormatI type=null; if (mtch != null) { - FileFormatI type; try { type = new IdentifyFile().identify(file, protocol); @@ -4821,7 +4882,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, } // File wasn't named like one of the sequences or wasn't a PDB // file. - filesnotmatched.add(file); + filesnotmatched.add(new Object[] { file, protocol, type}); } } int assocfiles = 0; @@ -4857,7 +4918,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, Desktop.instance); if (pe != null) { - System.err.println("Associated file : " + jalview.bin.Console.errPrintln("Associated file : " + (fm[0].toString()) + " with " + toassoc.getDisplayId(true)); assocfiles++; @@ -4875,7 +4936,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, */ for (Object[] o : filesmatched) { - filesnotmatched.add(o[0]); + filesnotmatched.add(new Object[] { o[0], o[1]}); } } } @@ -4897,9 +4958,9 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, { return; } - for (Object fn : filesnotmatched) + for (Object[] fn : filesnotmatched) { - loadJalviewDataFile(fn, null, null, null); + loadJalviewDataFile(fn[0], (DataSourceType) fn[1], (FileFormatI)fn[2], null); } } @@ -4995,7 +5056,19 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, { format = new IdentifyFile().identify(file, sourceType); } - if (FileFormat.ScoreMatrix == format) + if (FileFormat.FeatureSettings == format) + { + if (featureSettings != null) + { + featureSettings.load(file, sourceType); + } + else + { + FeatureSettings.loadFeatureSettingsFile(getFeatureRenderer(), + fileObject, sourceType); + } + } + else if (FileFormat.ScoreMatrix == format) { ScoreMatrixFile sm = new ScoreMatrixFile( new FileParse(file, sourceType)); @@ -5781,6 +5854,8 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, } } alignPanel.validateAnnotationDimensions(true); + // TODO this triggers relayout of annotation panel - otherwise annotation label height is different to panel height + alignPanel.fontChanged(); alignPanel.alignmentChanged(); } @@ -5890,7 +5965,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, viewport.getAlignment())); } catch (Exception ex) { - System.err.println(ex.getMessage()); + jalview.bin.Console.errPrintln(ex.getMessage()); return; } } @@ -5903,16 +5978,17 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, @Override protected void runGroovy_actionPerformed() { - Jalview.setCurrentAlignFrame(this); - groovy.ui.Console console = Desktop.getGroovyConsole(); + Jalview.getInstance().setCurrentAlignFrame(this); + groovy.console.ui.Console console = Desktop.getGroovyConsole(); if (console != null) { try { + console.setVariable(JalviewObjectI.currentAlFrameName, this); console.runScript(); } catch (Exception ex) { - System.err.println((ex.toString())); + jalview.bin.Console.errPrintln((ex.toString())); JvOptionPane.showInternalMessageDialog(Desktop.desktop, MessageManager.getString("label.couldnt_run_groovy_script"), MessageManager.getString("label.groovy_support_failed"), @@ -5921,7 +5997,8 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, } else { - System.err.println("Can't run Groovy script as console not found"); + jalview.bin.Console + .errPrintln("Can't run Groovy script as console not found"); } } diff --git a/src/jalview/gui/AlignViewport.java b/src/jalview/gui/AlignViewport.java index 5613f16..a8bc815 100644 --- a/src/jalview/gui/AlignViewport.java +++ b/src/jalview/gui/AlignViewport.java @@ -45,7 +45,6 @@ import jalview.bin.Console; import jalview.commands.CommandI; import jalview.datamodel.AlignedCodonFrame; import jalview.datamodel.Alignment; -import jalview.datamodel.AlignmentAnnotation; import jalview.datamodel.AlignmentI; import jalview.datamodel.ColumnSelection; import jalview.datamodel.ContactMatrixI; @@ -998,7 +997,7 @@ public class AlignViewport extends AlignmentViewport */ protected boolean noReferencesTo(AlignedCodonFrame acf) { - AlignFrame[] frames = Desktop.getAlignFrames(); + AlignFrame[] frames = Desktop.getDesktopAlignFrames(); if (frames == null) { return true; diff --git a/src/jalview/gui/AlignmentPanel.java b/src/jalview/gui/AlignmentPanel.java index aa28a8c..fe6477e 100644 --- a/src/jalview/gui/AlignmentPanel.java +++ b/src/jalview/gui/AlignmentPanel.java @@ -50,6 +50,7 @@ import jalview.api.AlignmentViewPanel; import jalview.bin.Cache; import jalview.bin.Console; import jalview.bin.Jalview; +import jalview.datamodel.AlignmentAnnotation; import jalview.datamodel.AlignmentI; import jalview.datamodel.HiddenColumns; import jalview.datamodel.SearchResultsI; @@ -255,8 +256,10 @@ public class AlignmentPanel extends GAlignmentPanel implements /** * Calculates the width of the alignment labels based on the displayed names - * and any bounds on label width set in preferences. The calculated width is - * also set as a property of the viewport. + * and any bounds on label width set in preferences. + * + * The calculated width is set as a property of the viewport and the layout is + * updated. * * @return Dimension giving the maximum width of the alignment label panel * that should be used. @@ -269,10 +272,7 @@ public class AlignmentPanel extends GAlignmentPanel implements Dimension r = null; if (av.getIdWidth() < 0) { - int afwidth = (alignFrame != null ? alignFrame.getWidth() : 300); - int idWidth = Math.min(afwidth - 200, 2 * afwidth / 3); - int maxwidth = Math.max(IdwidthAdjuster.MIN_ID_WIDTH, idWidth); - r = calculateIdWidth(maxwidth); + r = calculateDefaultAlignmentIdWidth(); av.setIdWidth(r.width); } else @@ -294,9 +294,30 @@ public class AlignmentPanel extends GAlignmentPanel implements return r; } + public Dimension calculateDefaultAlignmentIdWidth() + { + return calculateIdWidth(-1, false, false); + } + /** + * pre 2.11.3 Id width calculation - used when importing old projects only + * @return + */ + public int getLegacyIdWidth() + { + int afwidth = (alignFrame != null ? alignFrame.getWidth() : 300); + int idWidth = Math.min(afwidth - 200, 2 * afwidth / 3); + int maxwidth = Math.max(IdwidthAdjuster.MIN_ID_WIDTH, idWidth); + Dimension w = calculateIdWidthOrLegacy(true, maxwidth, false, false); + return w.width; + } + /** * Calculate the width of the alignment labels based on the displayed names - * and any bounds on label width set in preferences. + * and any bounds on label width set in preferences. Also includes annotations + * not actually visible. + * + * FIXME JAL-244 JAL-4091 - doesn't include sequence associated annotation + * label decorators and only called during tests * * @param maxwidth * -1 or maximum width allowed for IdWidth @@ -305,6 +326,36 @@ public class AlignmentPanel extends GAlignmentPanel implements */ protected Dimension calculateIdWidth(int maxwidth) { + return calculateIdWidth(maxwidth, true, false); + } + /** + * Calculate the width of the alignment labels based on the displayed names + * and any bounds on label width set in preferences. + * + * @param maxwidth + * -1 or maximum width allowed for IdWidth + * @param includeAnnotations - when true includes width of any additional marks in annotation id panel + * @param visibleOnly - when true, ignore label widths for hidden annotation rows + * @return Dimension giving the maximum width of the alignment label panel + * that should be used. + */ + public Dimension calculateIdWidth(int maxwidth, + boolean includeAnnotations, boolean visibleOnly) + { + return calculateIdWidthOrLegacy(false, maxwidth, includeAnnotations, visibleOnly); + } + + /** + * legacy mode or post 2.11.3 ID width calculation + * @param legacy - uses annotation labels, not rendered label width (excludes additional decorators) + * @param maxwidth + * @param includeAnnotations + * @param visibleOnly + * @return + */ + private Dimension calculateIdWidthOrLegacy(boolean legacy, int maxwidth, + boolean includeAnnotations, boolean visibleOnly) + { Container c = new Container(); FontMetrics fm = c.getFontMetrics( @@ -324,18 +375,30 @@ public class AlignmentPanel extends GAlignmentPanel implements } // Also check annotation label widths - i = 0; - - if (al.getAlignmentAnnotation() != null) + if (includeAnnotations && al.getAlignmentAnnotation() != null) { fm = c.getFontMetrics(getAlabels().getFont()); - while (i < al.getAlignmentAnnotation().length) + if (!legacy || Jalview.isHeadlessMode()) { - String label = al.getAlignmentAnnotation()[i].label; - int stringWidth = fm.stringWidth(label); + AnnotationLabels aal = getAlabels(); + int stringWidth = aal.drawLabels(null, false, idWidth, false, false, + fm, !visibleOnly); idWidth = Math.max(idWidth, stringWidth); - i++; + } + else + { + for (i = 0; i < al.getAlignmentAnnotation().length; i++) + { + AlignmentAnnotation aa = al.getAlignmentAnnotation()[i]; + if (visibleOnly && !aa.visible) + { + continue; + } + String label = aa.label; + int stringWidth = fm.stringWidth(label); + idWidth = Math.max(idWidth, stringWidth); + } } } @@ -543,7 +606,7 @@ public class AlignmentPanel extends GAlignmentPanel implements // this is called after loading new annotation onto alignment if (alignFrame.getHeight() == 0) { - System.out.println("NEEDS FIXING"); + jalview.bin.Console.error("adjustAnnotationHeight called with zero height alignment window"); } validateAnnotationDimensions(true); addNotify(); @@ -567,21 +630,29 @@ public class AlignmentPanel extends GAlignmentPanel implements // not be called directly by programs. // I note that addNotify() is called in several areas of Jalview. - int annotationHeight = getAnnotationPanel().adjustPanelHeight(); - annotationHeight = getAnnotationPanel() - .adjustForAlignFrame(adjustPanelHeight, annotationHeight); + AnnotationPanel ap = getAnnotationPanel(); + int annotationHeight = ap.adjustPanelHeight(); + annotationHeight = ap.adjustForAlignFrame(adjustPanelHeight, + annotationHeight); hscroll.addNotify(); - annotationScroller.setPreferredSize( - new Dimension(annotationScroller.getWidth(), annotationHeight)); - Dimension e = idPanel.getSize(); - alabels.setSize(new Dimension(e.width, annotationHeight)); + int idWidth = e.width; + boolean manuallyAdjusted = this.getIdPanel().getIdCanvas() + .isManuallyAdjusted(); + annotationScroller.setPreferredSize(new Dimension( + manuallyAdjusted ? idWidth : annotationScroller.getWidth(), + annotationHeight)); + + alabels.setPreferredSize(new Dimension(idWidth, annotationHeight)); annotationSpaceFillerHolder.setPreferredSize(new Dimension( - annotationSpaceFillerHolder.getWidth(), annotationHeight)); + manuallyAdjusted ? idWidth + : annotationSpaceFillerHolder.getWidth(), + annotationHeight)); annotationScroller.validate(); annotationScroller.addNotify(); + ap.validate(); } /** @@ -597,9 +668,10 @@ public class AlignmentPanel extends GAlignmentPanel implements boolean wrap = av.getWrapAlignment(); ViewportRanges ranges = av.getRanges(); ranges.setStartSeq(0); - scalePanelHolder.setVisible(!wrap); + // scalePanelHolder.setVisible(!wrap); hscroll.setVisible(!wrap); - idwidthAdjuster.setVisible(!wrap); + // Allow idPanel width adjustment in wrap mode + idwidthAdjuster.setVisible(true); if (wrap) { @@ -633,7 +705,7 @@ public class AlignmentPanel extends GAlignmentPanel implements } } - idSpaceFillerPanel1.setVisible(!wrap); + // idSpaceFillerPanel1.setVisible(!wrap); repaint(); } @@ -854,10 +926,27 @@ public class AlignmentPanel extends GAlignmentPanel implements public void paintComponent(Graphics g) { 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)); + int idWidth = d.width; + + // check wrapped alignment as at least 1 residue width + if (av.getWrapAlignment()) + { + SeqCanvas sc = this.getSeqPanel().seqCanvas; + if (sc != null && sc.getWidth() < sc.getMinimumWrappedCanvasWidth()) + { + // need to make some adjustments + idWidth -= (sc.getMinimumWrappedCanvasWidth() - sc.getWidth()); + av.setIdWidth(idWidth); + av.getAlignPanel().getIdPanel().getIdCanvas() + .setManuallyAdjusted(true); + + validateAnnotationDimensions(false); + } + } + + idPanelHolder.setPreferredSize(new Dimension(idWidth, d.height)); + hscrollFillerPanel.setPreferredSize(new Dimension(idWidth, 12)); validate(); // needed so that the id width adjuster works correctly @@ -948,8 +1037,16 @@ public class AlignmentPanel extends GAlignmentPanel implements Graphics idGraphics, Graphics alignmentGraphics) throws PrinterException { - final int idWidth = getVisibleIdWidth(false); - + final int idWidth, idWidthForGui; + // otherwise calculate it + idWidth = getVisibleIdWidth(false); +// if (getIdPanel()!=null && getIdPanel().getWidth()>0) +// { +// // use the current IdPanel's width, if its set and non-zero +// idWidthForGui = getIdPanel().getWidth(); +// } else { +// idWidthForGui=0; +// } /* * Get the horizontal offset to where we draw the sequences. * This is idWidth if using a single Graphics context, else zero. @@ -998,6 +1095,9 @@ public class AlignmentPanel extends GAlignmentPanel implements } final int alignmentDrawnHeight = (endSeq - startSeq) * charHeight + 3; + alignmentGraphics.setColor(Color.white); + alignmentGraphics.fillRect(0, 0, pageWidth, pageHeight+scaleHeight); + /* * draw the Scale at horizontal offset, then reset to top left (0, 0) */ @@ -1014,8 +1114,9 @@ public class AlignmentPanel extends GAlignmentPanel implements IdCanvas idCanvas = getIdPanel().getIdCanvas(); List selection = av.getSelectionGroup() == null ? null : av.getSelectionGroup().getSequences(null); + idCanvas.drawIds((Graphics2D) idGraphics, av, startSeq, endSeq - 1, - selection); + selection, false,idWidth); idGraphics.setFont(av.getFont()); idGraphics.translate(0, -scaleHeight); @@ -1039,7 +1140,7 @@ public class AlignmentPanel extends GAlignmentPanel implements int offset = getAlabels().getScrollOffset(); idGraphics.translate(0, -offset); idGraphics.translate(0, alignmentDrawnHeight); - getAlabels().drawComponent(idGraphics, idWidth); + getAlabels().drawComponentNotGUI(idGraphics, idWidth); idGraphics.translate(0, -alignmentDrawnHeight); /* @@ -1120,7 +1221,7 @@ public class AlignmentPanel extends GAlignmentPanel implements * draw sequence ids and annotation labels (if shown) */ IdCanvas idCanvas = getIdPanel().getIdCanvas(); - idCanvas.drawIdsWrapped((Graphics2D) g, av, 0, totalHeight); + idCanvas.drawIdsWrappedNoGUI((Graphics2D) g, av, 0, totalHeight); g.translate(idWidth, 0); @@ -1162,7 +1263,7 @@ public class AlignmentPanel extends GAlignmentPanel implements // see if rendering offscreen - check preferences and calc width accordingly if (!onscreen && Cache.getDefault("FIGURE_AUTOIDWIDTH", false)) { - return calculateIdWidth(-1).width; + return calculateIdWidth(-1,true,true).width; } Integer idwidth = onscreen ? null : Cache.getIntegerProperty("FIGURE_FIXEDIDWIDTH"); @@ -1172,6 +1273,7 @@ public class AlignmentPanel extends GAlignmentPanel implements } int w = getIdPanel().getWidth(); + w = calculateIdWidth(-1, true, true).width; return (w > 0 ? w : calculateIdWidth().width); } @@ -1179,7 +1281,7 @@ public class AlignmentPanel extends GAlignmentPanel implements throws ImageOutputException { makeAlignmentImage(type, file, renderer, - BitmapImageSizing.nullBitmapImageSizing()); + BitmapImageSizing.defaultBitmapImageSizing()); } /** @@ -1197,6 +1299,7 @@ public class AlignmentPanel extends GAlignmentPanel implements final int borderBottomOffset = 5; AlignmentDimension aDimension = getAlignmentDimension(); + // todo use a lambda function in place of callback here? ImageWriterI writer = new ImageWriterI() { @@ -1410,8 +1513,7 @@ public class AlignmentPanel extends GAlignmentPanel implements { int seqPanelWidth = getSeqPanel().seqCanvas.getWidth(); - if (System.getProperty("java.awt.headless") != null - && System.getProperty("java.awt.headless").equals("true")) + if (Jalview.isHeadlessMode()) { seqPanelWidth = alignFrame.getWidth() - getVisibleIdWidth() - vscroll.getPreferredSize().width @@ -1799,5 +1901,4 @@ public class AlignmentPanel extends GAlignmentPanel implements overviewPanel = null; } } - } diff --git a/src/jalview/gui/AnnotationLabels.java b/src/jalview/gui/AnnotationLabels.java index 28065c3..08a25ba 100755 --- a/src/jalview/gui/AnnotationLabels.java +++ b/src/jalview/gui/AnnotationLabels.java @@ -20,6 +20,7 @@ */ package jalview.gui; +import java.awt.Canvas; import java.awt.Color; import java.awt.Cursor; import java.awt.Dimension; @@ -50,6 +51,8 @@ import javax.swing.ToolTipManager; import jalview.analysis.AlignSeq; import jalview.analysis.AlignmentUtils; +import jalview.bin.Cache; +import jalview.bin.Jalview; import jalview.datamodel.Alignment; import jalview.datamodel.AlignmentAnnotation; import jalview.datamodel.Annotation; @@ -85,7 +88,7 @@ public class AnnotationLabels extends JPanel /** * height in pixels for allowing height adjuster to be active */ - private static int HEIGHT_ADJUSTER_HEIGHT = 10; + public static int HEIGHT_ADJUSTER_HEIGHT = 10; private static final Font font = new Font("Arial", Font.PLAIN, 11); @@ -113,6 +116,8 @@ public class AnnotationLabels extends JPanel private static final String COPYCONS_SEQ = MessageManager .getString("label.copy_consensus_sequence"); + private static final String ADJUST_ANNOTATION_LABELS_WIDTH_PREF = "ADJUST_ANNOTATION_LABELS_WIDTH"; + private final boolean debugRedraw = false; private AlignmentPanel ap; @@ -131,6 +136,10 @@ public class AnnotationLabels extends JPanel private boolean resizePanel = false; + private int annotationIdWidth = -1; + + public static final String RESIZE_MARGINS_MARK_PREF = "RESIZE_MARGINS_MARK"; + /** * Creates a new AnnotationLabels object * @@ -138,7 +147,6 @@ public class AnnotationLabels extends JPanel */ public AnnotationLabels(AlignmentPanel ap) { - this.ap = ap; av = ap.av; ToolTipManager.sharedInstance().registerComponent(this); @@ -418,65 +426,74 @@ public class AnnotationLabels extends JPanel pop.add(consclipbrd); } - addColourOrFilterByOptions(ap,aa[selectedRow],pop); - + addColourOrFilterByOptions(ap, aa[selectedRow], pop); + if (aa[selectedRow].graph == AlignmentAnnotation.CONTACT_MAP) { - addContactMatrixOptions(ap,aa[selectedRow],pop); - // Set/adjust threshold for grouping ? - // colour alignment by this [type] - // select/hide columns by this row - - } + addContactMatrixOptions(ap, aa[selectedRow], pop); + // Set/adjust threshold for grouping ? + // colour alignment by this [type] + // select/hide columns by this row + } - + } + pop.show(this, evt.getX(), evt.getY()); } static void addColourOrFilterByOptions(final AlignmentPanel ap, - final AlignmentAnnotation alignmentAnnotation, final JPopupMenu pop) + final AlignmentAnnotation alignmentAnnotation, + final JPopupMenu pop) { JMenuItem item; - item = new JMenuItem(MessageManager.getString("label.colour_by_annotation")); + item = new JMenuItem( + MessageManager.getString("label.colour_by_annotation")); item.addActionListener(new ActionListener() { - + @Override public void actionPerformed(ActionEvent e) { - AnnotationColourChooser.displayFor(ap.av, ap,alignmentAnnotation,false); + AnnotationColourChooser.displayFor(ap.av, ap, alignmentAnnotation, + false); }; }); pop.add(item); - if (alignmentAnnotation.sequenceRef!=null) + if (alignmentAnnotation.sequenceRef != null) { - item = new JMenuItem(MessageManager.getString("label.colour_by_annotation")+" ("+MessageManager.getString("label.per_seq")+")"); + item = new JMenuItem( + MessageManager.getString("label.colour_by_annotation") + " (" + + MessageManager.getString("label.per_seq") + ")"); item.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { - AnnotationColourChooser.displayFor(ap.av, ap,alignmentAnnotation,true); + AnnotationColourChooser.displayFor(ap.av, ap, alignmentAnnotation, + true); }; }); pop.add(item); } - item = new JMenuItem(MessageManager.getString("action.select_by_annotation")); + item = new JMenuItem( + MessageManager.getString("action.select_by_annotation")); item.addActionListener(new ActionListener() { - + @Override public void actionPerformed(ActionEvent e) { - AnnotationColumnChooser.displayFor(ap.av,ap,alignmentAnnotation); + AnnotationColumnChooser.displayFor(ap.av, ap, alignmentAnnotation); }; }); pop.add(item); } + static void addContactMatrixOptions(final AlignmentPanel ap, - final AlignmentAnnotation alignmentAnnotation, final JPopupMenu pop) + final AlignmentAnnotation alignmentAnnotation, + final JPopupMenu pop) { - + final ContactMatrixI cm = ap.av.getContactMatrix(alignmentAnnotation); JMenuItem item; if (cm != null) @@ -485,10 +502,13 @@ public class AnnotationLabels extends JPanel if (cm.hasGroups()) { - JCheckBoxMenuItem chitem = new JCheckBoxMenuItem(MessageManager.getString("action.show_groups_on_matrix")); - chitem.setToolTipText(MessageManager.getString("action.show_groups_on_matrix_tooltip")); - boolean showGroups = alignmentAnnotation.isShowGroupsForContactMatrix(); - final AlignmentAnnotation sel_row=alignmentAnnotation; + JCheckBoxMenuItem chitem = new JCheckBoxMenuItem( + MessageManager.getString("action.show_groups_on_matrix")); + chitem.setToolTipText(MessageManager + .getString("action.show_groups_on_matrix_tooltip")); + boolean showGroups = alignmentAnnotation + .isShowGroupsForContactMatrix(); + final AlignmentAnnotation sel_row = alignmentAnnotation; chitem.setState(showGroups); chitem.addActionListener(new ActionListener() { @@ -507,8 +527,10 @@ public class AnnotationLabels extends JPanel } if (cm.hasTree()) { - item = new JMenuItem(MessageManager.getString("action.show_tree_for_matrix")); - item.setToolTipText(MessageManager.getString("action.show_tree_for_matrix_tooltip")); + item = new JMenuItem( + MessageManager.getString("action.show_tree_for_matrix")); + item.setToolTipText(MessageManager + .getString("action.show_tree_for_matrix_tooltip")); item.addActionListener(new ActionListener() { @@ -524,8 +546,10 @@ public class AnnotationLabels extends JPanel } else { - item = new JMenuItem(MessageManager.getString("action.cluster_matrix")); - item.setToolTipText(MessageManager.getString("action.cluster_matrix_tooltip")); + item = new JMenuItem( + MessageManager.getString("action.cluster_matrix")); + item.setToolTipText( + MessageManager.getString("action.cluster_matrix_tooltip")); item.addActionListener(new ActionListener() { @Override @@ -537,7 +561,11 @@ public class AnnotationLabels extends JPanel public void run() { final long progBar; - ap.alignFrame.setProgressBar(MessageManager.formatMessage("action.clustering_matrix_for",cm.getAnnotDescr(),5f), progBar = System.currentTimeMillis()); + ap.alignFrame.setProgressBar( + MessageManager.formatMessage( + "action.clustering_matrix_for", + cm.getAnnotDescr(), 5f), + progBar = System.currentTimeMillis()); cm.setGroupSet(GroupSet.makeGroups(cm, true)); cm.randomlyReColourGroups(); cm.transferGroupColorsTo(alignmentAnnotation); @@ -1140,8 +1168,7 @@ public class AnnotationLabels extends JPanel RenderingHints.VALUE_ANTIALIAS_ON); } - drawComponent(g2, true, width); - + drawComponent(g2, true, width, true); } /** @@ -1156,7 +1183,7 @@ public class AnnotationLabels extends JPanel */ public void drawComponent(Graphics g, int width) { - drawComponent(g, false, width); + drawComponent(g, false, width, true); } /** @@ -1171,32 +1198,148 @@ public class AnnotationLabels extends JPanel * @param width * Width for scaling labels */ - public void drawComponent(Graphics g, boolean clip, int width) + public void drawComponent(Graphics g, boolean clip, int givenWidth, boolean forGUI) { - if (av.getFont().getSize() < 10) + int width = givenWidth; + IdwidthAdjuster iwa = null; + if (ap != null) { - g.setFont(font); + iwa = ap.idwidthAdjuster; + if ((Cache.getDefault(ADJUST_ANNOTATION_LABELS_WIDTH_PREF, true) + || Jalview.isHeadlessMode())) + { + Graphics2D g2d = (Graphics2D) g; + Graphics dummy = g2d.create(); + int newAnnotationIdWidth = drawLabels(dummy, clip, width, false, forGUI, + null, false); + dummy.dispose(); + Dimension d = ap.calculateDefaultAlignmentIdWidth(); + int alignmentIdWidth = d.width; + if (iwa != null && !iwa.manuallyAdjusted()) + { + // If no manual adjustment to ID column with has been made then adjust + // width match widest of alignment or annotation id widths + boolean allowShrink = Cache.getDefault("ALLOW_SHRINK_ID_WIDTH", + false); + width = Math.max(alignmentIdWidth, newAnnotationIdWidth); + if (clip && width < givenWidth && !allowShrink) + { + width = givenWidth; + } + } + else if (newAnnotationIdWidth != annotationIdWidth + && newAnnotationIdWidth > givenWidth + && newAnnotationIdWidth > alignmentIdWidth) + { + // otherwise if the annotation id width has become larger than the + // current id width, increase + width = newAnnotationIdWidth; + annotationIdWidth = newAnnotationIdWidth; + } + // set the width if it's changed + if (width != ap.av.getIdWidth()) + { + iwa.setWidth(width); + } + } } else { - g.setFont(av.getFont()); + int newAnnotationIdWidth = drawLabels(g, clip, width, false, forGUI, null, false); + width = newAnnotationIdWidth

    argumentactionsub-value modifiers (optional)linked (optional)
    ‑‑structureimage filenameExport an image of a 3D structure opened in JMOL. Image formats can be: -
    - svg, -
    - png, -
    - eps. -
    - structureimagetype=name, - structureimagetextrenderer=name, - structureimagescale=number, - structureimagewidth=number, - structureimageheight=number -
    ‑‑structureimagetype nameSet the structure image format for the preceding --structureimage. Valid values are: -
    - svg, -
    - png, -
    - eps. -
    ‑‑structureimagetextrenderer nameSets whether text in a vector structure image format (SVG, EPS) should be rendered as text or vector line-art. Possible values are: -
    - text, -
    - lineart. -
    ‑‑structureimagescale numberSets a scaling for bitmap structure image format (PNG). Should be given as a floating point number. If used in conjunction with --structureimagewidth and --structureimageheight then the smallest scaling will be used (structureimagescale, structureimagewidth and structureimageheight provide bounds for the structure image). -
    ‑‑structureimagewidth numberSets a width for bitmap structure image format (PNG) with the height maintaining the aspect ratio. Should be given as a positive integer. If used in conjunction with --structureimagescale and --structureimageheight then the smallest scaling will be used (structureimagescale, structureimagewidth and structureimageheight provide bounds for the structure image). -
    ‑‑structureimageheight numberSets a height for bitmap structure image format (PNG) with the width maintaining the aspect ratio. Should be given as a positive integer. If used in conjunction with --structureimagescale and --structureimagewidth then the smallest scaling will be used (structureimagescale, structureimagewidth and structureimageheight provide bounds for the structure image). - ‑‑groovy filenameProcess a groovy script in the file for the open alignment.
    Move on to a new alignment window. This will ensure ‑‑append will start a new alignment window and other linked arguments will apply to the new alignment window.
    - Note that --open already starts a new alignment window for each file it opens. + Note that ‑‑open already starts a new alignment window for each file it opens.
    ‑‑substitutions / ‑‑nosubstitutions The following argument values allow (or don't allow) subsituting filename parts. This is initially true. Valid substitutions are +
    {basename} - the filename-without-extension of the currently ‑‑opened file (or first ‑‑appended file),
    {dirname}, - the directory (folder) name of the currently ‑‑opened file (or first ‑‑appended file), + {extension}, - the extension of the filename of the currently ‑‑opened file (or first ‑‑appended file),
    {argfilebasename} - the filename-without-extension of the current ‑‑argfile,
    {argfiledirname} - the directory (folder) name of the current ‑‑argfile,
    + {structurebasename} - the filename-without-extension of the ‑‑structure file. Only available to ‑‑structureimage . +
    + {structuredirname}, - the directory (folder) name of the ‑‑structure file. Only available to ‑‑structureimage . +
    + {structureextension}, - the extension of the filename of the ‑‑structure file. Only available to ‑‑structureimage . +
    {n} - the value of the index counter (starting at 0).
    - {++n} - increase and substitute the value of the index counter, + {++n} - increase and substitute the value of the index counter. +
    + {m} - the value of the on-the-fly counter (starting at 0). Only available to ‑‑structureimage . +
    + {++m} - increase and substitute the (incremented) value of the on-the-fly counter. Only available to ‑‑structureimage .
    {} - the value of the current alignment window default index.
    ‑‑allstructures / ‑‑noallstructures - Apply (or stop applying) the following 3D structure formatting arguments to all structures within the current open alignment. Whilst --allstructures will continue to operate for a --new alignment, the structure formatting arguments must be set again for each new alignment. + Apply (or stop applying) the following 3D structure formatting arguments to all structures within the current open alignment. Whilst ‑‑allstructures will continue to operate for a ‑‑new alignment, the structure formatting arguments must be set again for each new alignment.