From eeb526362a7945229be34c388fed0d672d03a23f Mon Sep 17 00:00:00 2001 From: David Maddison Date: Mon, 10 Apr 2023 14:54:15 -0700 Subject: [PATCH 01/15] reset MesquiteCore to prerelease --- Source/mesquite/Mesquite.java | 6 +++--- Source/mesquite/lib/MesquiteModule.java | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Source/mesquite/Mesquite.java b/Source/mesquite/Mesquite.java index ee3816663..1a1884da8 100644 --- a/Source/mesquite/Mesquite.java +++ b/Source/mesquite/Mesquite.java @@ -37,11 +37,11 @@ public class Mesquite extends MesquiteTrunk { /*.................................................................................................................*/ public String getCitation() { - return "Maddison, W.P. & D.R. Maddison. 2023. Mesquite: A modular system for evolutionary analysis. Version 3.80. http://www.mesquiteproject.org"; + return "Maddison, W.P. & D.R. Maddison. 2023. Mesquite: A modular system for evolutionary analysis. Version " + getVersion() + ". https://www.mesquiteproject.org"; } /*.................................................................................................................*/ public String getVersion() { - return "3.80"; + return "3.80+"; } /*.................................................................................................................*/ @@ -58,7 +58,7 @@ public String getDateReleased() { } /*.................................................................................................................*/ public boolean isPrerelease(){ - return false; + return true; } /*.................................................................................................................*/ diff --git a/Source/mesquite/lib/MesquiteModule.java b/Source/mesquite/lib/MesquiteModule.java index 827412924..6da281b4c 100644 --- a/Source/mesquite/lib/MesquiteModule.java +++ b/Source/mesquite/lib/MesquiteModule.java @@ -72,7 +72,7 @@ public final static String getBuildDate() { /*.................................................................................................................*/ /** returns version of the Mesquite system */ public final static String getMesquiteVersion() { - return "3.80"; + return "3.80+"; } /*.................................................................................................................*/ /** returns letter in the build number of the Mesquite system (e.g., "e" of "e58") */ @@ -85,7 +85,7 @@ public final static String getBuildLetter() { public final static int getBuildNumber() { //as of 26 Dec 08, build naming changed from letter + number to just number. Accordingly j105 became 473, based on // highest build numbers of d51+e81+g97+h66+i69+j105 + 3 for a, b, c - return 950; + return 951; } //0.95.80 14 Mar 01 - first beta release //0.96 2 April 01 beta - second beta release From a3cf7be2a75f897893906dc456ffa7aeebff25d3 Mon Sep 17 00:00:00 2001 From: David Maddison Date: Mon, 10 Apr 2023 15:02:57 -0700 Subject: [PATCH 02/15] reset FlipTaxonLocus to load --- .../FlipTaxonLocus/FlipTaxonLocus.java | 2 +- .../mesquite/lib/ExternalProcessManager.java | 28 ++++++++++++++++++- 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/Source/mesquite/dmanager/FlipTaxonLocus/FlipTaxonLocus.java b/Source/mesquite/dmanager/FlipTaxonLocus/FlipTaxonLocus.java index 145f89fe7..cb21cde95 100644 --- a/Source/mesquite/dmanager/FlipTaxonLocus/FlipTaxonLocus.java +++ b/Source/mesquite/dmanager/FlipTaxonLocus/FlipTaxonLocus.java @@ -76,7 +76,7 @@ public MesquiteProject establishProject(String arguments) { /*.................................................................................................................*/ public boolean loadModule() { - return false; + return true; } /*.................................................................................................................*/ public boolean isPrerelease() { diff --git a/Source/mesquite/lib/ExternalProcessManager.java b/Source/mesquite/lib/ExternalProcessManager.java index 9359489f8..e7dc77c15 100644 --- a/Source/mesquite/lib/ExternalProcessManager.java +++ b/Source/mesquite/lib/ExternalProcessManager.java @@ -31,6 +31,7 @@ public class ExternalProcessManager implements Commandable { static int sleepTime = 50; Process proc; String directoryPath; + String[] programCommands; String programCommand; String programOptions; String name; @@ -64,6 +65,18 @@ public ExternalProcessManager(MesquiteModule ownerModule, String directoryPath, this.watcher = watcher; this.visibleTerminal = visibleTerminal; } + public ExternalProcessManager(MesquiteModule ownerModule, String directoryPath, String[] programCommands, String name, String[] outputFilePaths, OutputFileProcessor outputFileProcessor, ShellScriptWatcher watcher, boolean visibleTerminal){ + this.directoryPath=directoryPath; + this.name = name; + this.outputFilePaths = outputFilePaths; + this.outputFileProcessor = outputFileProcessor; + this.ownerModule = ownerModule; + this.programCommands = programCommands; + stdOutFilePath = MesquiteFile.getDirectoryPathFromFilePath(directoryPath) + MesquiteFile.fileSeparator + stdOutFileName; + stdErrFilePath = MesquiteFile.getDirectoryPathFromFilePath(directoryPath) + MesquiteFile.fileSeparator + stdErrFileName; + this.watcher = watcher; + this.visibleTerminal = visibleTerminal; + } public ExternalProcessManager(MesquiteModule ownerModule){ //to be used for reconnecting } @@ -256,12 +269,25 @@ public String[] getStringArrayWithSplitting(String string1, String string2) { } /*.................................................................................................................*/ + public void setProgramCommands(String programCommand, String programOptions) { + programCommands = getStringArrayWithSplitting(programCommand, programOptions); + } + /*.................................................................................................................*/ + public void setProgramCommands() { + programCommands = getStringArrayWithSplitting(programCommand, programOptions); + } + /*.................................................................................................................*/ + public void setProgramCommands(String[] programCommands) { + this.programCommands = programCommands; + } + /*.................................................................................................................*/ /** executes a shell script at "scriptPath". If runningFilePath is not blank and not null, then Mesquite will create a file there that will * serve as a flag to Mesquite that the script is running. */ public boolean executeInShell(){ proc = null; + setProgramCommands(); // to be removed externalProcess = new MesquiteExternalProcess(); - externalProcess.start(directoryPath, stdOutFilePath, stdErrFilePath, getStringArrayWithSplitting(programCommand, programOptions)); + externalProcess.start(directoryPath, stdOutFilePath, stdErrFilePath, programCommands); proc = externalProcess.getProcess(); return proc!=null; } From c2e858277da6ff65f1a582ec1ef7eb845bbaeaea Mon Sep 17 00:00:00 2001 From: David Maddison Date: Mon, 10 Apr 2023 20:24:49 -0700 Subject: [PATCH 03/15] External processes work --- .../FlipTaxonLocus/FlipTaxonLocus.java | 25 +++-- .../mesquite/lib/ExternalProcessManager.java | 93 +++++++++++++++++-- 2 files changed, 98 insertions(+), 20 deletions(-) diff --git a/Source/mesquite/dmanager/FlipTaxonLocus/FlipTaxonLocus.java b/Source/mesquite/dmanager/FlipTaxonLocus/FlipTaxonLocus.java index cb21cde95..e9d927734 100644 --- a/Source/mesquite/dmanager/FlipTaxonLocus/FlipTaxonLocus.java +++ b/Source/mesquite/dmanager/FlipTaxonLocus/FlipTaxonLocus.java @@ -31,35 +31,40 @@ public boolean startJob(String arguments, Object condition, boolean hiredByName) /*.................................................................................................................*/ public void processDirectory(String directoryPath) { - +// String pythonVersionStOut= ExternalProcessManager.executeAndGetStandardErr(this, "/Library/Frameworks/Python.framework/Versions/2.7/Resources/Python.app/Contents/MacOS/Python", "-V"); + +// String pythonVersionStOut= ExternalProcessManager.executeAndGetStandardErr(this, "python", "-V"); +/* String raxmlng= ExternalProcessManager.executeAndGetStandardOut(this, "/usr/local/bin/raxml-ng", "-v"); + logln("\nraxml-ng version: " + raxmlng); + String iqTreeV= ExternalProcessManager.executeAndGetStandardOut(this, "/usr/local/bin/iqtree2", "-V"); + logln("\niq-tree version: " + iqTreeV); +*/ + boolean success = false; MesquiteTimer timer = new MesquiteTimer(); timer.start(); ProgressIndicator progressIndicator = new ProgressIndicator(getProject(), "Python script in progress"); progressIndicator.start(); - String pythonCodeFilePath = StringUtil.protectFilePathForCommandLine(getPath()+"flipTaxonLocustoLocusTaxon.py"); -// String pythonCodeFilePath = getPath()+"flipTaxonLocustoLocusTaxon.py"; - - String pythonProgram = "python"; - externalRunner = new ExternalProcessManager(this, directoryPath, pythonProgram, pythonCodeFilePath, getName(), null, null, null, true); + String pythonCommand = "python"; + String pythonOptions = StringUtil.protectFilePathForCommandLine(getPath()+"flipTaxonLocustoLocusTaxon.py"); + + externalRunner = new ExternalProcessManager(this, directoryPath, pythonCommand, pythonOptions, getName(), null, null, null, true, true); +// externalRunner = new ExternalProcessManager(this, directoryPath, pythonProgramCommands, getName(), null, null, null, true); externalRunner.setStdOutFileName(ShellScriptRunner.stOutFileName); - externalRunner.setRemoveQuotes(true); success = externalRunner.executeInShell(); if (success) success = externalRunner.monitorAndCleanUpShell(progressIndicator); - if (progressIndicator.isAborted()){ + if (progressIndicator.isAborted()) logln("Aborted by user\n"); - } progressIndicator.goAway(); } /*.................................................................................................................*/ public MesquiteProject establishProject(String arguments) { - boolean success= false; String directoryPath = MesquiteFile.chooseDirectory("Choose directory containing data files:", null); if (StringUtil.blank(directoryPath)) return null; diff --git a/Source/mesquite/lib/ExternalProcessManager.java b/Source/mesquite/lib/ExternalProcessManager.java index e7dc77c15..c2ebdcaaf 100644 --- a/Source/mesquite/lib/ExternalProcessManager.java +++ b/Source/mesquite/lib/ExternalProcessManager.java @@ -32,8 +32,8 @@ public class ExternalProcessManager implements Commandable { Process proc; String directoryPath; String[] programCommands; - String programCommand; - String programOptions; + //String programCommand; + //String programOptions; String name; String[] outputFilePaths; //reconnect String stdOutFilePath, stdErrFilePath; @@ -49,7 +49,7 @@ public class ExternalProcessManager implements Commandable { long stdOutLastModified = 0; long stdErrLastModified = 0; boolean badExitCode = false; - boolean removeQuotes = false; + boolean removeQuotes = true; public ExternalProcessManager(MesquiteModule ownerModule, String directoryPath, String programCommand, String programOptions, String name, String[] outputFilePaths, OutputFileProcessor outputFileProcessor, ShellScriptWatcher watcher, boolean visibleTerminal){ @@ -58,13 +58,29 @@ public ExternalProcessManager(MesquiteModule ownerModule, String directoryPath, this.outputFilePaths = outputFilePaths; this.outputFileProcessor = outputFileProcessor; this.ownerModule = ownerModule; - this.programCommand = programCommand; - this.programOptions = programOptions; + // this.programCommand = programCommand; + // this.programOptions = programOptions; + this.programCommands = getStringArrayWithSplitting(programCommand, programOptions); stdOutFilePath = MesquiteFile.getDirectoryPathFromFilePath(directoryPath) + MesquiteFile.fileSeparator + stdOutFileName; stdErrFilePath = MesquiteFile.getDirectoryPathFromFilePath(directoryPath) + MesquiteFile.fileSeparator + stdErrFileName; this.watcher = watcher; this.visibleTerminal = visibleTerminal; } + public ExternalProcessManager(MesquiteModule ownerModule, String directoryPath, String programCommand, String programOptions, String name, String[] outputFilePaths, OutputFileProcessor outputFileProcessor, ShellScriptWatcher watcher, boolean visibleTerminal, boolean removeQuotes){ + this.directoryPath=directoryPath; + this.name = name; + this.outputFilePaths = outputFilePaths; + this.outputFileProcessor = outputFileProcessor; + this.ownerModule = ownerModule; + this.removeQuotes = removeQuotes; + // this.programCommand = programCommand; + // this.programOptions = programOptions; + this.programCommands = getStringArrayWithSplitting(programCommand, programOptions); + stdOutFilePath = MesquiteFile.getDirectoryPathFromFilePath(directoryPath) + stdOutFileName; + stdErrFilePath = MesquiteFile.getDirectoryPathFromFilePath(directoryPath) + stdErrFileName; + this.watcher = watcher; + this.visibleTerminal = visibleTerminal; + } public ExternalProcessManager(MesquiteModule ownerModule, String directoryPath, String[] programCommands, String name, String[] outputFilePaths, OutputFileProcessor outputFileProcessor, ShellScriptWatcher watcher, boolean visibleTerminal){ this.directoryPath=directoryPath; this.name = name; @@ -72,8 +88,8 @@ public ExternalProcessManager(MesquiteModule ownerModule, String directoryPath, this.outputFileProcessor = outputFileProcessor; this.ownerModule = ownerModule; this.programCommands = programCommands; - stdOutFilePath = MesquiteFile.getDirectoryPathFromFilePath(directoryPath) + MesquiteFile.fileSeparator + stdOutFileName; - stdErrFilePath = MesquiteFile.getDirectoryPathFromFilePath(directoryPath) + MesquiteFile.fileSeparator + stdErrFileName; + stdOutFilePath = MesquiteFile.getDirectoryPathFromFilePath(directoryPath) + stdOutFileName; + stdErrFilePath = MesquiteFile.getDirectoryPathFromFilePath(directoryPath) + stdErrFileName; this.watcher = watcher; this.visibleTerminal = visibleTerminal; } @@ -162,6 +178,14 @@ public String getStdErr() { public String getStdOut() { return MesquiteFile.getFileContentsAsStringNoWarn(stdOutFilePath); } + /*.................................................................................................................*/ + public void emptyStdErr() { + MesquiteFile.deleteFile(stdErrFilePath); + } + /*.................................................................................................................*/ + public void emptyStdOut() { + MesquiteFile.deleteFile(stdOutFilePath); + } OutputTextListener textListener; @@ -169,6 +193,43 @@ public void setOutputTextListener(OutputTextListener textListener){ this.textListener= textListener; } + + /*.................................................................................................................*/ + public static String executeAndGetStandardOut(MesquiteModule ownerModule, String directoryPath, String programCommand, String programOptions) { + boolean success = false; + ExternalProcessManager externalRunner = new ExternalProcessManager(ownerModule, directoryPath, programCommand, programOptions, ownerModule.getName(), null, null, null, false, true); + externalRunner.emptyStdOut(); + success = externalRunner.executeInShell(); + if (success) { + success = externalRunner.monitorAndCleanUpShell(null); + return externalRunner.getStdOut(); + } + return ""; + } + /*.................................................................................................................*/ + public static String executeAndGetStandardOut(MesquiteModule ownerModule, String programCommand, String programOptions) { + String directoryPath = ownerModule.createSupportDirectory() + MesquiteFile.fileSeparator; + return executeAndGetStandardOut(ownerModule, directoryPath, programCommand, programOptions); + // ownerModule.deleteSupportDirectory(); + } + /*.................................................................................................................*/ + public static String executeAndGetStandardErr(MesquiteModule ownerModule, String directoryPath, String programCommand, String programOptions) { + boolean success = false; + ExternalProcessManager externalRunner = new ExternalProcessManager(ownerModule, directoryPath, programCommand, programOptions, ownerModule.getName(), null, null, null, false, true); + externalRunner.emptyStdErr(); + success = externalRunner.executeInShell(); + if (success) { + success = externalRunner.monitorAndCleanUpShell(null); + return externalRunner.getStdErr(); + } + return ""; + } + /*.................................................................................................................*/ + public static String executeAndGetStandardErr(MesquiteModule ownerModule, String programCommand, String programOptions) { + String directoryPath = ownerModule.createSupportDirectory() + MesquiteFile.fileSeparator; + return executeAndGetStandardErr(ownerModule, directoryPath, programCommand, programOptions); + // ownerModule.deleteSupportDirectory(); + } /*.................................................................................................................*/ public long getStdErrLastModified() { File file = new File(stdErrFilePath); @@ -215,7 +276,7 @@ public void setRemoveQuotes(boolean removeQuotes) { this.removeQuotes = removeQuotes; } - /*.................................................................................................................*/ + /*.................................................................................................................* public static String[] getStringArray(String string1, String...strings) { if (StringUtil.blank(string1)) return null; @@ -269,10 +330,21 @@ public String[] getStringArrayWithSplitting(String string1, String string2) { } /*.................................................................................................................*/ + public String programCommandsToString () { + if (programCommands==null) + return ""; + StringBuffer sb = new StringBuffer(); + for (int i=0; i Date: Mon, 10 Apr 2023 23:09:58 -0700 Subject: [PATCH 04/15] Beginnings of Python integration --- .../FlipTaxonLocus/FlipTaxonLocus.java | 28 ++++---- .../externalCommunication/lib/PythonUtil.java | 71 +++++++++++++++++++ .../mesquite/minimal/Defaults/Defaults.java | 14 ++++ 3 files changed, 97 insertions(+), 16 deletions(-) create mode 100644 Source/mesquite/externalCommunication/lib/PythonUtil.java diff --git a/Source/mesquite/dmanager/FlipTaxonLocus/FlipTaxonLocus.java b/Source/mesquite/dmanager/FlipTaxonLocus/FlipTaxonLocus.java index e9d927734..8a49c4e4b 100644 --- a/Source/mesquite/dmanager/FlipTaxonLocus/FlipTaxonLocus.java +++ b/Source/mesquite/dmanager/FlipTaxonLocus/FlipTaxonLocus.java @@ -16,6 +16,7 @@ import java.io.File; +import mesquite.externalCommunication.lib.PythonUtil; import mesquite.lib.*; import mesquite.lib.duties.GeneralFileMaker; @@ -31,32 +32,27 @@ public boolean startJob(String arguments, Object condition, boolean hiredByName) /*.................................................................................................................*/ public void processDirectory(String directoryPath) { -// String pythonVersionStOut= ExternalProcessManager.executeAndGetStandardErr(this, "/Library/Frameworks/Python.framework/Versions/2.7/Resources/Python.app/Contents/MacOS/Python", "-V"); - -// String pythonVersionStOut= ExternalProcessManager.executeAndGetStandardErr(this, "python", "-V"); -/* String raxmlng= ExternalProcessManager.executeAndGetStandardOut(this, "/usr/local/bin/raxml-ng", "-v"); - logln("\nraxml-ng version: " + raxmlng); - String iqTreeV= ExternalProcessManager.executeAndGetStandardOut(this, "/usr/local/bin/iqtree2", "-V"); - logln("\niq-tree version: " + iqTreeV); -*/ - - boolean success = false; - MesquiteTimer timer = new MesquiteTimer(); - timer.start(); + if (!PythonUtil.pythonAvailable()) + PythonUtil.pythonSettings(this); + if (!PythonUtil.pythonAvailable()) + return; + boolean success = false; ProgressIndicator progressIndicator = new ProgressIndicator(getProject(), "Python script in progress"); progressIndicator.start(); - - String pythonCommand = "python"; + String pythonCommand = PythonUtil.python3Path; String pythonOptions = StringUtil.protectFilePathForCommandLine(getPath()+"flipTaxonLocustoLocusTaxon.py"); + + if (!PythonUtil.python3Available()) { + pythonCommand = PythonUtil.python2Path; + pythonOptions = StringUtil.protectFilePathForCommandLine(getPath()+"flipTaxonLocustoLocusTaxon2.py"); + } externalRunner = new ExternalProcessManager(this, directoryPath, pythonCommand, pythonOptions, getName(), null, null, null, true, true); -// externalRunner = new ExternalProcessManager(this, directoryPath, pythonProgramCommands, getName(), null, null, null, true); externalRunner.setStdOutFileName(ShellScriptRunner.stOutFileName); success = externalRunner.executeInShell(); if (success) success = externalRunner.monitorAndCleanUpShell(progressIndicator); - if (progressIndicator.isAborted()) logln("Aborted by user\n"); progressIndicator.goAway(); diff --git a/Source/mesquite/externalCommunication/lib/PythonUtil.java b/Source/mesquite/externalCommunication/lib/PythonUtil.java new file mode 100644 index 000000000..0ec1ee0cf --- /dev/null +++ b/Source/mesquite/externalCommunication/lib/PythonUtil.java @@ -0,0 +1,71 @@ +package mesquite.externalCommunication.lib; + +import mesquite.lib.*; + +public class PythonUtil { + public static String python2Path = ""; + public static String python3Path = ""; + + public static boolean pythonSettings(MesquiteModule ownerModule) { + MesquiteInteger buttonPressed = new MesquiteInteger(ExtensibleDialog.defaultCANCEL); + ExtensibleDialog dialog = new ExtensibleDialog(ownerModule.containerOfModule(), "Python Settings",buttonPressed); //MesquiteTrunk.mesquiteTrunk.containerOfModule() + String s = "To find the path to Python 2, go in to the Terminal or Command Line, and type \"python2 -h\" and hit return. " + + "The response should include a line that begins with \"usage: \", then shows the full path to Python 2, then " + + "has \"[options]\"; the path is the text between \"usage\" and \"[options]\". Copy that text and paste it into the " + + "Python 2 path field. Then do the same for Python 3, this time using the command \"python3 -h\". "; + dialog.appendToHelpString(s); + + dialog.addHorizontalLine(1); + + SingleLineTextField python2PathField = dialog.addTextField("Python 2 path", python2Path, 50); + SingleLineTextField python3PathField = dialog.addTextField("Python 3 path", python3Path, 50); + + + dialog.completeAndShowDialog(true); + boolean success=(buttonPressed.getValue()== dialog.defaultOK); + if (success) { + python2Path = StringUtil.stripBoundingWhitespace(python2PathField.getText()); + python3Path = StringUtil.stripBoundingWhitespace(python3PathField.getText()); + MesquiteTrunk.mesquiteTrunk.storePreferences(); + } + dialog.dispose(); + return success; + + } + + public static String pythonVersion(MesquiteModule ownerModule) { +// String pythonVersionStOut= ExternalProcessManager.executeAndGetStandardErr(this, "/Library/Frameworks/Python.framework/Versions/2.7/Resources/Python.app/Contents/MacOS/Python", "-V"); + +// String pythonVersionStOut= ExternalProcessManager.executeAndGetStandardErr(this, "python", "-V"); +/* String raxmlng= ExternalProcessManager.executeAndGetStandardOut(this, "/usr/local/bin/raxml-ng", "-v"); + logln("\nraxml-ng version: " + raxmlng); + String iqTreeV= ExternalProcessManager.executeAndGetStandardOut(this, "/usr/local/bin/iqtree2", "-V"); + logln("\niq-tree version: " + iqTreeV); +*/ + + + +/* scriptRunner = new ShellScriptRunner(scriptPath, runningFilePath, null, true, getName(), outputFilePaths, this, this, true); //scriptPath, runningFilePath, null, true, name, outputFilePaths, outputFileProcessor, watcher, true + success = scriptRunner.executeInShell(); + if (success) + success = scriptRunner.monitorAndCleanUpShell(progressIndicator); +*/ + + return null; + + } + + public static boolean python2Available() { + return StringUtil.notEmpty(python2Path); +} + + + public static boolean python3Available() { + return StringUtil.notEmpty(python3Path); +} + + public static boolean pythonAvailable() { + return python2Available() || python3Available(); +} + +} diff --git a/Source/mesquite/minimal/Defaults/Defaults.java b/Source/mesquite/minimal/Defaults/Defaults.java index ed2e5698f..226635644 100644 --- a/Source/mesquite/minimal/Defaults/Defaults.java +++ b/Source/mesquite/minimal/Defaults/Defaults.java @@ -18,6 +18,8 @@ import java.net.*; import java.util.*; import java.io.*; + +import mesquite.externalCommunication.lib.PythonUtil; import mesquite.lib.*; import mesquite.lib.duties.*; import mesquite.lib.simplicity.InterfaceManager; @@ -120,6 +122,7 @@ public boolean startJob(String arguments, Object condition, boolean hiredByName) MesquiteTrunk.mesquiteTrunk.addCheckMenuItemToSubmenu(MesquiteTrunk.fileMenu, MesquiteTrunk.defaultsSubmenu, "Permit t0=taxon 1, t1=taxon 2, etc. Names in Tree Reading", makeCommand("toggleT0NamesTrees", this), taxonT0Trees); MesquiteTrunk.mesquiteTrunk.addCheckMenuItemToSubmenu(MesquiteTrunk.fileMenu, MesquiteTrunk.defaultsSubmenu, "Print Tree Names by Default", makeCommand("printTreeNameByDefault", this), printTreeNameByDefault); MesquiteTrunk.mesquiteTrunk.addItemToSubmenu(MesquiteTrunk.fileMenu, MesquiteTrunk.defaultsSubmenu, "Matrix Limits for Undo...", makeCommand("setMaxMatrixSizeUndo", this)); + MesquiteTrunk.mesquiteTrunk.addItemToSubmenu(MesquiteTrunk.fileMenu, MesquiteTrunk.defaultsSubmenu, "Python Settings...", makeCommand("pythonSettings", this)); //comment out debug mode menu item for users MesquiteTrunk.mesquiteTrunk.addCheckMenuItemToSubmenu(MesquiteTrunk.fileMenu, MesquiteTrunk.defaultsSubmenu,"Debug Mode", makeCommand("toggleDebugMode", this), debugMode); @@ -311,6 +314,12 @@ else if ("resourcesFontSize".equalsIgnoreCase(tag)) { else if ("suggestedDirectory".equalsIgnoreCase(tag)){ MesquiteTrunk.suggestedDirectory = StringUtil.cleanXMLEscapeCharacters(content); } + else if ("python2Path".equalsIgnoreCase(tag)){ + PythonUtil.python2Path = StringUtil.cleanXMLEscapeCharacters(content); + } + else if ("python3Path".equalsIgnoreCase(tag)){ + PythonUtil.python3Path = StringUtil.cleanXMLEscapeCharacters(content); + } } public String preparePreferencesForXML () { StringBuffer buffer = new StringBuffer(); @@ -322,6 +331,8 @@ public String preparePreferencesForXML () { StringUtil.appendXMLTag(buffer, 2, "maxLinesOfMatricesTreeBlocksSeparateInPanel", FileCoordinator.maxLinesOfMatricesTreeBlocksSeparateInPanel); StringUtil.appendXMLTag(buffer, 2, "useOtherChoicesInMenus", useOtherChoices); StringUtil.appendXMLTag(buffer, 2, "suggestedDirectory", MesquiteTrunk.suggestedDirectory); + StringUtil.appendXMLTag(buffer, 2, "python2Path", PythonUtil.python2Path); + StringUtil.appendXMLTag(buffer, 2, "python3Path", PythonUtil.python3Path); StringUtil.appendXMLTag(buffer, 2, "askSeed", askSeed); StringUtil.appendXMLTag(buffer, 2, "suppressXORMode", suppressXORMode); StringUtil.appendXMLTag(buffer, 2, "taxonTruncTrees", taxonTruncTrees); @@ -519,6 +530,9 @@ else if (checker.compare(getClass(), "Sets the maximum number of taxa and charac } } + else if (checker.compare(getClass(), "Allows one to adjust settings for Python", "", commandName, "pythonSettings")) { + PythonUtil.pythonSettings(this); +} else if (checker.compare(getClass(), "Sets whether to show windows of each project as tabs within a single window", null, commandName, "toggleTabbedWindows")) { tabbedWindows.toggleValue(null); MesquiteWindow.compactWindows = tabbedWindows.getValue(); From 87d4e83efa2731948654a3e989224cdbb122b891 Mon Sep 17 00:00:00 2001 From: David Maddison Date: Tue, 11 Apr 2023 08:10:26 -0700 Subject: [PATCH 05/15] getPythonPath --- .../externalCommunication/lib/PythonUtil.java | 41 ++++++++++++------- Source/mesquite/lib/MesquiteModule.java | 4 +- 2 files changed, 28 insertions(+), 17 deletions(-) diff --git a/Source/mesquite/externalCommunication/lib/PythonUtil.java b/Source/mesquite/externalCommunication/lib/PythonUtil.java index 0ec1ee0cf..16e2cc344 100644 --- a/Source/mesquite/externalCommunication/lib/PythonUtil.java +++ b/Source/mesquite/externalCommunication/lib/PythonUtil.java @@ -5,6 +5,8 @@ public class PythonUtil { public static String python2Path = ""; public static String python3Path = ""; + public static int pythonPreference = 3; + public static int NOPYTHONPREFERENCE = 0; public static boolean pythonSettings(MesquiteModule ownerModule) { MesquiteInteger buttonPressed = new MesquiteInteger(ExtensibleDialog.defaultCANCEL); @@ -34,38 +36,47 @@ public static boolean pythonSettings(MesquiteModule ownerModule) { } public static String pythonVersion(MesquiteModule ownerModule) { -// String pythonVersionStOut= ExternalProcessManager.executeAndGetStandardErr(this, "/Library/Frameworks/Python.framework/Versions/2.7/Resources/Python.app/Contents/MacOS/Python", "-V"); - -// String pythonVersionStOut= ExternalProcessManager.executeAndGetStandardErr(this, "python", "-V"); -/* String raxmlng= ExternalProcessManager.executeAndGetStandardOut(this, "/usr/local/bin/raxml-ng", "-v"); + // String pythonVersionStOut= ExternalProcessManager.executeAndGetStandardErr(this, "/Library/Frameworks/Python.framework/Versions/2.7/Resources/Python.app/Contents/MacOS/Python", "-V"); + + // String pythonVersionStOut= ExternalProcessManager.executeAndGetStandardErr(this, "python", "-V"); + /* String raxmlng= ExternalProcessManager.executeAndGetStandardOut(this, "/usr/local/bin/raxml-ng", "-v"); logln("\nraxml-ng version: " + raxmlng); String iqTreeV= ExternalProcessManager.executeAndGetStandardOut(this, "/usr/local/bin/iqtree2", "-V"); logln("\niq-tree version: " + iqTreeV); -*/ - + */ + - -/* scriptRunner = new ShellScriptRunner(scriptPath, runningFilePath, null, true, getName(), outputFilePaths, this, this, true); //scriptPath, runningFilePath, null, true, name, outputFilePaths, outputFileProcessor, watcher, true + + /* scriptRunner = new ShellScriptRunner(scriptPath, runningFilePath, null, true, getName(), outputFilePaths, this, this, true); //scriptPath, runningFilePath, null, true, name, outputFilePaths, outputFileProcessor, watcher, true success = scriptRunner.executeInShell(); if (success) success = scriptRunner.monitorAndCleanUpShell(progressIndicator); -*/ - + */ + return null; } public static boolean python2Available() { return StringUtil.notEmpty(python2Path); -} - - + } + + public static boolean python3Available() { return StringUtil.notEmpty(python3Path); -} + } public static boolean pythonAvailable() { return python2Available() || python3Available(); -} + } + + public static String getPythonPath(int version) { + if (version==3 || (version==0 && pythonPreference==3)) + return python3Path; + else if (version==2 || (version==0 && pythonPreference==2)) + return python2Path; + else + return python3Path; + } } diff --git a/Source/mesquite/lib/MesquiteModule.java b/Source/mesquite/lib/MesquiteModule.java index 6da281b4c..c4b08cb6a 100644 --- a/Source/mesquite/lib/MesquiteModule.java +++ b/Source/mesquite/lib/MesquiteModule.java @@ -67,7 +67,7 @@ public abstract class MesquiteModule extends EmployerEmployee implements Command /*.................................................................................................................*/ /** returns build date of the Mesquite system (e.g., "22 September 2003") */ public final static String getBuildDate() { - return "10 April 2023"; + return "11 April 2023"; } /*.................................................................................................................*/ /** returns version of the Mesquite system */ @@ -85,7 +85,7 @@ public final static String getBuildLetter() { public final static int getBuildNumber() { //as of 26 Dec 08, build naming changed from letter + number to just number. Accordingly j105 became 473, based on // highest build numbers of d51+e81+g97+h66+i69+j105 + 3 for a, b, c - return 951; + return 952; } //0.95.80 14 Mar 01 - first beta release //0.96 2 April 01 beta - second beta release From ebd35d76a21c439b9ee289c184b4756a77f78dc7 Mon Sep 17 00:00:00 2001 From: David Maddison Date: Mon, 17 Apr 2023 15:36:32 -0700 Subject: [PATCH 06/15] Corrected TAXSET writing for BEAST --- .../bayesian/lib/ExportForBEASTLib.java | 22 +------------------ 1 file changed, 1 insertion(+), 21 deletions(-) diff --git a/Source/mesquite/bayesian/lib/ExportForBEASTLib.java b/Source/mesquite/bayesian/lib/ExportForBEASTLib.java index 224c79392..eae77d206 100644 --- a/Source/mesquite/bayesian/lib/ExportForBEASTLib.java +++ b/Source/mesquite/bayesian/lib/ExportForBEASTLib.java @@ -119,29 +119,9 @@ String nexusStringForSpecsSet(TaxaSelectionSet taxaSet, Taxa taxa, MesquiteFile int lastWritten = -1; for (int ic=0; ic0) { - if (lastWritten != ic-1) { - sT += " " + getTaxonName(taxa,ic-1); - lastWritten = ic-1; - } - else - lastWritten = -1; - continuing = 0; - } - } - if (continuing>1) - sT += " " + getTaxonName(taxa, taxa.getNumTaxa()-1); if (!StringUtil.blank(sT)) { s+= "\tTAXSET " ; String set1 = s; From cfb9ea1f274f941a2c44c77ac58ff6b7d634b20a Mon Sep 17 00:00:00 2001 From: David Maddison Date: Mon, 17 Apr 2023 15:55:01 -0700 Subject: [PATCH 07/15] Localized getLocalNexusCommands --- Source/mesquite/bayesian/lib/ExportForBEASTLib.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Source/mesquite/bayesian/lib/ExportForBEASTLib.java b/Source/mesquite/bayesian/lib/ExportForBEASTLib.java index eae77d206..e88bb9064 100644 --- a/Source/mesquite/bayesian/lib/ExportForBEASTLib.java +++ b/Source/mesquite/bayesian/lib/ExportForBEASTLib.java @@ -136,7 +136,7 @@ String nexusStringForSpecsSet(TaxaSelectionSet taxaSet, Taxa taxa, MesquiteFile return s; } /*.................................................................................................................*/ - public String getNexusCommands(MesquiteFile file, String blockName){ + String getLocalNexusCommands(MesquiteFile file, String blockName){ String s= ""; String specSet =""; for (int ids = 0; ids Date: Mon, 17 Apr 2023 16:04:44 -0700 Subject: [PATCH 08/15] BEAST cleanup --- Source/mesquite/bayesian/lib/ExportForBEASTLib.java | 2 +- .../mesquite/externalCommunication/lib/PythonUtil.java | 10 +++++----- Source/mesquite/lib/MesquiteModule.java | 4 ++-- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Source/mesquite/bayesian/lib/ExportForBEASTLib.java b/Source/mesquite/bayesian/lib/ExportForBEASTLib.java index e88bb9064..7ce644fc6 100644 --- a/Source/mesquite/bayesian/lib/ExportForBEASTLib.java +++ b/Source/mesquite/bayesian/lib/ExportForBEASTLib.java @@ -166,7 +166,7 @@ String getLocalNexusCommands(MesquiteFile file, String blockName){ return s; } /*.................................................................................................................*/ - public String getSetsBlock(MesquiteFile file){ + String getSetsBlock(MesquiteFile file){ String contents = getLocalNexusCommands(file, "SETS"); if (StringUtil.blank(contents)) return null; diff --git a/Source/mesquite/externalCommunication/lib/PythonUtil.java b/Source/mesquite/externalCommunication/lib/PythonUtil.java index 16e2cc344..0b135783e 100644 --- a/Source/mesquite/externalCommunication/lib/PythonUtil.java +++ b/Source/mesquite/externalCommunication/lib/PythonUtil.java @@ -35,9 +35,11 @@ public static boolean pythonSettings(MesquiteModule ownerModule) { } - public static String pythonVersion(MesquiteModule ownerModule) { - // String pythonVersionStOut= ExternalProcessManager.executeAndGetStandardErr(this, "/Library/Frameworks/Python.framework/Versions/2.7/Resources/Python.app/Contents/MacOS/Python", "-V"); - + public static String pythonVersion(MesquiteModule ownerModule, int version) { + if (version==2 || (version==0 && pythonPreference==2)) + return ExternalProcessManager.executeAndGetStandardErr(ownerModule, getPythonPath(2), "-V"); + else + return ExternalProcessManager.executeAndGetStandardOut(ownerModule, getPythonPath(3), "-V"); // String pythonVersionStOut= ExternalProcessManager.executeAndGetStandardErr(this, "python", "-V"); /* String raxmlng= ExternalProcessManager.executeAndGetStandardOut(this, "/usr/local/bin/raxml-ng", "-v"); logln("\nraxml-ng version: " + raxmlng); @@ -53,8 +55,6 @@ public static String pythonVersion(MesquiteModule ownerModule) { success = scriptRunner.monitorAndCleanUpShell(progressIndicator); */ - return null; - } public static boolean python2Available() { diff --git a/Source/mesquite/lib/MesquiteModule.java b/Source/mesquite/lib/MesquiteModule.java index c4b08cb6a..b8737dc6b 100644 --- a/Source/mesquite/lib/MesquiteModule.java +++ b/Source/mesquite/lib/MesquiteModule.java @@ -67,7 +67,7 @@ public abstract class MesquiteModule extends EmployerEmployee implements Command /*.................................................................................................................*/ /** returns build date of the Mesquite system (e.g., "22 September 2003") */ public final static String getBuildDate() { - return "11 April 2023"; + return "17 April 2023"; } /*.................................................................................................................*/ /** returns version of the Mesquite system */ @@ -85,7 +85,7 @@ public final static String getBuildLetter() { public final static int getBuildNumber() { //as of 26 Dec 08, build naming changed from letter + number to just number. Accordingly j105 became 473, based on // highest build numbers of d51+e81+g97+h66+i69+j105 + 3 for a, b, c - return 952; + return 953; } //0.95.80 14 Mar 01 - first beta release //0.96 2 April 01 beta - second beta release From f6ad8ecd9819963a256a050e158dba0251df13d4 Mon Sep 17 00:00:00 2001 From: David Maddison Date: Tue, 18 Apr 2023 20:41:16 -0700 Subject: [PATCH 09/15] Added ExportTiledBaits --- .../ExportTiledBaits/ExportTiledBaits.java | 237 ++++++++++++++++++ Source/mesquite/lib/MesquiteModule.java | 4 +- docs/History of New Features.html | 11 +- 3 files changed, 249 insertions(+), 3 deletions(-) create mode 100644 Source/mesquite/genomic/ExportTiledBaits/ExportTiledBaits.java diff --git a/Source/mesquite/genomic/ExportTiledBaits/ExportTiledBaits.java b/Source/mesquite/genomic/ExportTiledBaits/ExportTiledBaits.java new file mode 100644 index 000000000..41e81c0d2 --- /dev/null +++ b/Source/mesquite/genomic/ExportTiledBaits/ExportTiledBaits.java @@ -0,0 +1,237 @@ +package mesquite.genomic.ExportTiledBaits; + +import java.awt.Checkbox; + +import mesquite.categ.lib.*; +import mesquite.lib.*; +import mesquite.lib.characters.CharacterData; +import mesquite.lib.duties.FileInterpreterI; + +public class ExportTiledBaits extends FileInterpreterI { + +//TODO: warn about uncertainty + + + public void getEmployeeNeeds(){ //This gets called on startup to harvest information; override this and inside, call registerEmployeeNeed + // EmployeeNeed e = registerEmployeeNeed(VoucherInfoCoord.class, "Voucher information is needed for FASTA export for Genbank submissions.", + // "This is activated automatically when you choose this exporter."); + } + /*.................................................................................................................*/ + public boolean startJob(String arguments, Object condition, boolean hiredByName) { + return true; + } + public void readFile(MesquiteProject mf, MesquiteFile mNF, String arguments) { + + } + + /*.................................................................................................................*/ + public boolean canImport() { + return false; + } + public boolean canImport(String arguments){ + return false; + } + /** returns whether module is able ever to export.*/ + public boolean canExportEver(){ + return true; + } + /** returns whether module has something it can export in the project. Should be overridden*/ + public boolean canExportProject(MesquiteProject project){ + return project.getNumberCharMatrices(DNAState.class) > 0; // + } + + /** returns whether module can export a character data matrix of the given type. Should be overridden*/ + public boolean canExportData(Class dataClass){ + if (dataClass==null) return false; + return ((DNAState.class).isAssignableFrom(dataClass)); + } + + protected int taxonNameLengthLimit() { + return 50; + } + + /* ============================ exporting ============================*/ + /*.................................................................................................................*/ +// String fileName = "untitled.fas"; + int baitLength = 120; + int tileAmount = 60; + boolean getEndBaitIfShiftedEnough = false; + int shiftThresholdForEndBait = 30; +// boolean arbitrarilyResolveAmbiguity = true; + boolean includeShortBaits = false; + + // protected boolean buildFileName = false; + + /*.................................................................................................................*/ + public boolean getExportOptions(boolean dataSelected, boolean taxaSelected){ + MesquiteInteger buttonPressed = new MesquiteInteger(1); + ExporterDialog exportDialog = new ExporterDialog(this,containerOfModule(), "Export Tiled Baits", buttonPressed); + exportDialog.setSuppressLineEndQuery(true); + exportDialog.setDefaultButton(null); + + IntegerField baitLengthField= exportDialog.addIntegerField("Bait length", baitLength, 8); + IntegerField tileAmountField= exportDialog.addIntegerField("Tile amount", tileAmount, 8); + Checkbox includeShortBaitsBox= exportDialog.addCheckBox("Include short baits", includeShortBaits); + + exportDialog.completeAndShowDialog(dataSelected, taxaSelected); + + boolean ok = (exportDialog.query(dataSelected, taxaSelected)==0); + + if (ok) { + baitLength = baitLengthField.getValue(); + tileAmount = tileAmountField.getValue(); + includeShortBaits = includeShortBaitsBox.getState(); + } + + exportDialog.dispose(); + return ok; + } + /*.................................................................................................................*/ + public String preferredDataFileExtension() { + return "fas"; + } + + /*.................................................................................................................*/ + public String getFileName(Taxa taxa, int it, CharacterData data, int index, String identifierString) { + String fileName = ""; + fileName=StringUtil.cleanseStringOfFancyChars(taxa.getName(it),false,true); + + fileName += ".fas"; + + return fileName; + } + + + /*.................................................................................................................*/ + public String getSequenceName(DNAData data, Taxa taxa, int it) { + String s = data.getName() + ": " + taxa.getTaxonName(it); + return s; + } + /*.................................................................................................................*/ + public String getTiledBaitAsFasta(DNAData data, Taxa taxa, int it, int icStart, int siteNumber, MesquiteInteger nextStart) { + int numTaxa = taxa.getNumTaxa(); + int numChars = data.getNumChars(); + StringBuffer outputBuffer = new StringBuffer(numTaxa*(20 + numChars)); + outputBuffer.append(">"+ getSequenceName(data,taxa, it) + " " + siteNumber + "-"); + StringBuffer dataBuffer = new StringBuffer(120); + int count = 0; + int ic =0; + boolean nextStartSet = false; + for (ic = icStart; ic=tileAmount && !nextStartSet) { + nextStart.setValue(ic); + nextStartSet = true; + } + } + } + if (!nextStartSet) // must mean we didn't actually have enough for the next tile + nextStart.setValue(numChars); + outputBuffer.append((siteNumber+count-1)); + outputBuffer.append(StringUtil.lineEnding()); + outputBuffer.append(dataBuffer); + outputBuffer.append(StringUtil.lineEnding()); + if (count>=baitLength || includeShortBaits) + return outputBuffer.toString(); + else + return ""; + } + /*.................................................................................................................*/ + public String getTiledBaitsAsFasta(DNAData data, Taxa taxa, int it) { + if (data.hasDataForTaxon(it)) { + int numTaxa = taxa.getNumTaxa(); + int numChars = data.getNumChars(); + StringBuffer outputBuffer = new StringBuffer(numTaxa*(20 + numChars)); + int numSites = data.numNotInapplicableNotUnassigned(it); + int siteCounter=1; + int count = 0; + if (numSites>=baitLength || includeShortBaits) { + int icStart = 0; + MesquiteInteger nextStart = new MesquiteInteger(0); + while (icStart < numChars) { + if (!(includeShortBaits || icStartrelease dates.

Features to come in the next release version of Mesquite are listed on this web page. These new features and bug fixes are already contained in latest source code in the development branch of the MesquiteProject/MesquiteCore repository on GitHub.

+

Next Release

+

New Features

+
    +
  • +
+

Bug Fixes, Workarounds, and Improvements

+
    +
  • Bug from version 3.80 whereby TAXSETS were inappropriately replicated has been fixed.
  • +

 

- +

Version 3.80

New Features