From ec24991b1786e17158a43f713c8ae9c4f8647393 Mon Sep 17 00:00:00 2001 From: Ben Soares Date: Thu, 11 May 2023 20:38:04 +0100 Subject: [PATCH] JAL-629 Fix --tempfac. Hide non-working --notempfac. Add --scale, --width, --height to PNG output. Tidy usage. Add --version. More quietness for --quiet. More consistently formatted stdout info, --- src/jalview/bin/Cache.java | 54 ++++++++++------- src/jalview/bin/Commands.java | 64 ++++++++++++++++++-- src/jalview/bin/Jalview.java | 18 ++++-- src/jalview/bin/argparser/Arg.java | 17 +++++- src/jalview/bin/argparser/ArgParser.java | 6 +- .../annotations/AnnotationRowBuilder.java | 10 +-- src/jalview/gui/AlignFrame.java | 8 ++- src/jalview/gui/AlignmentPanel.java | 13 +++- src/jalview/gui/ImageExporter.java | 15 +++-- src/jalview/io/StructureFile.java | 8 +-- src/jalview/util/ImageMaker.java | 52 ++++++++++++++-- 11 files changed, 203 insertions(+), 62 deletions(-) diff --git a/src/jalview/bin/Cache.java b/src/jalview/bin/Cache.java index 769c868..f4c8854 100755 --- a/src/jalview/bin/Cache.java +++ b/src/jalview/bin/Cache.java @@ -383,10 +383,13 @@ public class Cache { // props file provided as URL fis = new URL(propertiesFile).openStream(); - System.out.println( - "Loading jalview properties from : " + propertiesFile); - System.out.println( - "Disabling Jalview writing to user's local properties file."); + if (!Jalview.quiet()) + { + System.out.println( + "Loading jalview properties from : " + propertiesFile); + System.out.println( + "Disabling Jalview writing to user's local properties file."); + } propsAreReadOnly = true; } catch (Exception ex) { @@ -414,7 +417,8 @@ public class Cache fis.close(); } catch (Exception ex) { - System.out.println("Error reading properties file: " + ex); + if (!Jalview.quiet()) + System.out.println("Error reading properties file: " + ex); } } @@ -470,7 +474,8 @@ public class Cache } } catch (Exception ex) { - System.out.println("Error reading author details: " + ex); + if (!Jalview.quiet()) + System.out.println("Error reading author details: " + ex); authorDetails = null; } if (authorDetails == null) @@ -554,10 +559,13 @@ public class Cache remoteVersion = remoteBuildProperties.getProperty("VERSION"); } catch (Exception ex) { - System.out.println( - "Non-fatal exception when checking version at " - + remoteBuildPropertiesUrl + ":"); - System.out.println(ex); + if (!Jalview.quiet()) + { + System.out.println( + "Non-fatal exception when checking version at " + + remoteBuildPropertiesUrl + ":"); + System.out.println(ex); + } remoteVersion = getProperty("VERSION"); } } @@ -656,7 +664,8 @@ public class Cache } } catch (Exception ex) { - System.out.println("Error reading build details: " + ex); + if (!Jalview.quiet()) + System.out.println("Error reading build details: " + ex); applicationProperties.remove("VERSION"); } String codeVersion = getProperty("VERSION"); @@ -676,11 +685,8 @@ public class Cache new BuildDetails(codeVersion, null, codeInstallation); if (printVersion && reportVersion) { - if (!Jalview.quiet()) - { - System.out.println(ChannelProperties.getProperty("app_name") - + " Version: " + codeVersion + codeInstallation); - } + System.out.println(ChannelProperties.getProperty("app_name") + + " version: " + codeVersion + codeInstallation); } } @@ -741,8 +747,9 @@ public class Cache def = Integer.parseInt(string); } catch (NumberFormatException e) { - System.out.println("Error parsing int property '" + property - + "' with value '" + string + "'"); + if (!Jalview.quiet()) + System.out.println("Error parsing int property '" + property + + "' with value '" + string + "'"); } } @@ -783,8 +790,9 @@ public class Cache } } catch (Exception ex) { - System.out.println( - "Error setting property: " + key + " " + obj + "\n" + ex); + if (!Jalview.quiet()) + System.out.println( + "Error setting property: " + key + " " + obj + "\n" + ex); } return oldValue; } @@ -814,7 +822,8 @@ public class Cache out.close(); } catch (Exception ex) { - System.out.println("Error saving properties: " + ex); + if (!Jalview.quiet()) + System.out.println("Error saving properties: " + ex); } } } @@ -1152,7 +1161,8 @@ public class Cache } } catch (Exception ex) { - System.out.println("Error loading User ColourFile\n" + ex); + if (!Jalview.quiet()) + System.out.println("Error loading User ColourFile\n" + ex); } } if (!files.equals(coloursFound.toString())) diff --git a/src/jalview/bin/Commands.java b/src/jalview/bin/Commands.java index 3608295..679fbf4 100644 --- a/src/jalview/bin/Commands.java +++ b/src/jalview/bin/Commands.java @@ -492,16 +492,23 @@ public class Commands // 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.getBoolFromSubValOrArg(avm, + Arg.NOTEMPFAC, subVals); + TFType tft = notempfac ? null : TFType.DEFAULT; + /* String tftString = subVals.get("tempfac"); - TFType tft = avm.getBoolean(Arg.NOTEMPFAC) ? null - : TFType.DEFAULT; ArgValue tftAv = getArgAssociatedWithStructure(Arg.TEMPFAC, avm, af, structureFilepath); if (tftString == null && tftAv != null) { tftString = tftAv.getSubVals().getContent(); } - if (tftString != null) + */ + if (tftString != null && !notempfac) { // get kind of temperature factor annotation try @@ -546,8 +553,9 @@ public class Commands } } - boolean addTempFac = tft != null - || Cache.getDefault("ADD_TEMPFACT_ANN", false); + boolean addTempFac = notempfac ? false + : ((tft != null) + || Cache.getDefault("ADD_TEMPFACT_ANN", false)); // TODO use ssFromStructure StructureChooser.openStructureFileForSequence(null, null, ap, seq, @@ -626,6 +634,50 @@ public class Commands if (renderer == null) renderer = "text"; String type = "png"; // default + + float bitmapscale = 0.0f; + int bitmapwidth = 0; + int bitmapheight = 0; + String scale = ArgParser.getValueFromSubValOrArg(avm, av, Arg.SCALE, + subVal); + if (scale != null) + { + try + { + bitmapscale = Float.parseFloat(scale); + } catch (NumberFormatException e) + { + Console.warn("Did not understand scale '" + scale + + "', won't be used."); + } + } + String width = ArgParser.getValueFromSubValOrArg(avm, av, Arg.WIDTH, + subVal); + if (width != null) + { + try + { + bitmapwidth = Integer.parseInt(width); + } catch (NumberFormatException e) + { + Console.warn("Did not understand width '" + width + + "', won't be used."); + } + } + String height = ArgParser.getValueFromSubValOrArg(avm, av, + Arg.HEIGHT, subVal); + if (height != null) + { + try + { + bitmapheight = Integer.parseInt(height); + } catch (NumberFormatException e) + { + Console.warn("Did not understand height '" + height + + "', won't be used."); + } + } + type = ArgParser.getValueFromSubValOrArg(avm, av, Arg.TYPE, subVal); if (type == null && fileName != null) { @@ -651,7 +703,7 @@ public class Commands case "png": Console.debug("Outputting type '" + type + "' to " + fileName); - af.createPNG(file); + af.createPNG(file, null, bitmapscale, bitmapwidth, bitmapheight); break; case "html": diff --git a/src/jalview/bin/Jalview.java b/src/jalview/bin/Jalview.java index 1021a69..cf73c81 100755 --- a/src/jalview/bin/Jalview.java +++ b/src/jalview/bin/Jalview.java @@ -329,7 +329,8 @@ public class Jalview } } - if (bootstrapArgs.contains(Arg.HELP)) + if (bootstrapArgs.contains(Arg.HELP) + || bootstrapArgs.contains(Arg.VERSION)) { QUIET = true; } @@ -354,12 +355,12 @@ public class Jalview }.start(); } - if (!quiet()) + if (!quiet() || bootstrapArgs.contains(Arg.VERSION)) { System.out.println( "Java version: " + System.getProperty("java.version")); - System.out.println("Java Home: " + System.getProperty("java.home")); - System.out.println(System.getProperty("os.arch") + " " + System.out.println("Java home: " + System.getProperty("java.home")); + System.out.println("Java arch: " + System.getProperty("os.arch") + " " + System.getProperty("os.name") + " " + System.getProperty("os.version")); @@ -390,7 +391,14 @@ public class Jalview .bootstrapProperties(bootstrapArgs.get(Arg.PROPS)); // report Jalview version - Cache.loadBuildProperties(true); + Cache.loadBuildProperties( + !quiet() || bootstrapArgs.contains(Arg.VERSION)); + + // stop now if only after --version + if (bootstrapArgs.contains(Arg.VERSION)) + { + Jalview.exit(null, 0); + } // old ArgsParser ArgsParser aparser = new ArgsParser(args); diff --git a/src/jalview/bin/argparser/Arg.java b/src/jalview/bin/argparser/Arg.java index 95b6b43..6fcc011 100644 --- a/src/jalview/bin/argparser/Arg.java +++ b/src/jalview/bin/argparser/Arg.java @@ -16,6 +16,9 @@ public enum Arg // Initialising arguments (BOOTSTRAP) HELP("Display this help statement", Opt.UNARY, Opt.BOOTSTRAP), + VERSION("Display the version of " + + ChannelProperties.getProperty("app_name"), Opt.UNARY, + Opt.BOOTSTRAP), HEADLESS( "Run Jalview in headless mode. No GUI interface will be created and Jalview will quit after all arguments have been processed.", Opt.UNARY, Opt.BOOTSTRAP), @@ -99,7 +102,8 @@ public enum Arg Opt.STRING, Opt.LINKED, Opt.MULTI), NOTEMPFAC( "Do not show the temperature factor annotation for the preceding --structure.", - Opt.UNARY, Opt.LINKED), + Opt.UNARY, Opt.LINKED, Opt.SECRET), // keep this secret until it + // works! SHOWSSANNOTATIONS(null, Opt.BOOLEAN, Opt.LINKED), // Outputting files @@ -114,6 +118,12 @@ public enum Arg "Sets whether text in a vector image format (SVG, HTML, EPS) should be rendered as text or vector line-art. Possible values for name are:\n" + "text,\n" + "lineart.", Opt.STRING, Opt.LINKED, Opt.ALLOWALL), + SCALE("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), + WIDTH("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), + HEIGHT("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), 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" + "fasta (fa, fasta, mfa, fastq),\n" + "pfam (pfam),\n" + "stockholm (sto, stk),\n" + "pir (pir),\n" + "blc (blc),\n" @@ -459,6 +469,11 @@ public enum Arg options.add("allows substitutions"); } + if (a.hasOption(Opt.ALLOWALL)) + { + options.add("can be applied to all linked arguments"); + } + if (a.hasOption(Opt.PRIVATE)) { options.add("for internal use only"); diff --git a/src/jalview/bin/argparser/ArgParser.java b/src/jalview/bin/argparser/ArgParser.java index 38cb2d4..223cc53 100644 --- a/src/jalview/bin/argparser/ArgParser.java +++ b/src/jalview/bin/argparser/ArgParser.java @@ -270,8 +270,10 @@ public class ArgParser { // arg not found Console.error("Argument '" + arg + "' not recognised. Exiting."); - Jalview.exit("Unrecognised command line argument '" + arg + "'", - 13); + Jalview.exit("Invalid argument used." + System.lineSeparator() + + "Use" + System.lineSeparator() + "jalview " + + Arg.HELP.argString() + System.lineSeparator() + + "for a usage statement.", 13); continue; } if (a.hasOption(Opt.PRIVATE) && !allowPrivate) diff --git a/src/jalview/datamodel/annotations/AnnotationRowBuilder.java b/src/jalview/datamodel/annotations/AnnotationRowBuilder.java index b3d567a..c7e4549 100644 --- a/src/jalview/datamodel/annotations/AnnotationRowBuilder.java +++ b/src/jalview/datamodel/annotations/AnnotationRowBuilder.java @@ -1,7 +1,6 @@ package jalview.datamodel.annotations; import jalview.datamodel.Annotation; -import jalview.structure.StructureImportSettings; import jalview.structure.StructureImportSettings.TFType; public class AnnotationRowBuilder @@ -18,14 +17,15 @@ public class AnnotationRowBuilder /** * the type of temperature factor plot (if it is one) */ - private StructureImportSettings.TFType tfType = StructureImportSettings.TFType.DEFAULT; + // private TFType tfType = TFType.DEFAULT; + private TFType tfType = null; - public void setTFType(StructureImportSettings.TFType t) + public void setTFType(TFType t) { tfType = t; } - public StructureImportSettings.TFType getTFType() + public TFType getTFType() { return tfType; } @@ -97,7 +97,7 @@ public class AnnotationRowBuilder name = string; } - public AnnotationRowBuilder(String name, float min, float max, StructureImportSettings.TFType tft) + public AnnotationRowBuilder(String name, float min, float max, TFType tft) { this(name, min, max); setTFType(tft); diff --git a/src/jalview/gui/AlignFrame.java b/src/jalview/gui/AlignFrame.java index 6b46041..71905c1 100644 --- a/src/jalview/gui/AlignFrame.java +++ b/src/jalview/gui/AlignFrame.java @@ -1480,12 +1480,14 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, @Override public void createPNG(File f) { - createPNG(f, null); + createPNG(f, null, 0.0f, 0, 0); } - public void createPNG(File f, String renderer) + public void createPNG(File f, String renderer, float bitmapscale, + int bitmapwidth, int bitmapheight) { - alignPanel.makeAlignmentImage(TYPE.PNG, f, renderer); + alignPanel.makeAlignmentImage(TYPE.PNG, f, renderer, bitmapscale, + bitmapwidth, bitmapheight); } /** diff --git a/src/jalview/gui/AlignmentPanel.java b/src/jalview/gui/AlignmentPanel.java index 3b0597a..a5a1aff 100644 --- a/src/jalview/gui/AlignmentPanel.java +++ b/src/jalview/gui/AlignmentPanel.java @@ -1173,14 +1173,22 @@ public class AlignmentPanel extends GAlignmentPanel implements return (w > 0 ? w : calculateIdWidth().width); } + void makeAlignmentImage(ImageMaker.TYPE type, File file, String renderer) + { + makeAlignmentImage(type, file, renderer, 0.0f, 0, 0); + } + /** * Builds an image of the alignment of the specified type (EPS/PNG/SVG) and * writes it to the specified file * * @param type * @param file + * @param textrenderer + * @param bitmapscale */ - void makeAlignmentImage(ImageMaker.TYPE type, File file, String renderer) + void makeAlignmentImage(ImageMaker.TYPE type, File file, String renderer, + float bitmapscale, int bitmapwidth, int bitmapheight) { final int borderBottomOffset = 5; @@ -1210,7 +1218,8 @@ public class AlignmentPanel extends GAlignmentPanel implements int imageWidth = aDimension.getWidth(); int imageHeight = aDimension.getHeight() + borderBottomOffset; String of = MessageManager.getString("label.alignment"); - exporter.doExport(file, this, imageWidth, imageHeight, of, renderer); + exporter.doExport(file, this, imageWidth, imageHeight, of, renderer, + bitmapscale, bitmapwidth, bitmapheight); } /** diff --git a/src/jalview/gui/ImageExporter.java b/src/jalview/gui/ImageExporter.java index 657601e..785d206 100644 --- a/src/jalview/gui/ImageExporter.java +++ b/src/jalview/gui/ImageExporter.java @@ -105,11 +105,12 @@ public class ImageExporter public void doExport(File file, Component parent, int width, int height, String imageSource) { - doExport(file, parent, width, height, imageSource, null); + doExport(file, parent, width, height, imageSource, null, 0.0f, 0, 0); } public void doExport(File file, Component parent, int width, int height, - String imageSource, String renderer) + String imageSource, String renderer, float bitmapscale, + int bitmapwidth, int bitmapheight) { final long messageId = System.currentTimeMillis(); setStatus( @@ -165,7 +166,7 @@ public class ImageExporter final File chosenFile = file; Callable okAction = () -> { exportImage(chosenFile, !textSelected.get(), width, height, - messageId); + messageId, bitmapscale, bitmapwidth, bitmapheight); return null; }; LineartOptions epsOption = new LineartOptions(TYPE.EPS.getName(), @@ -191,7 +192,8 @@ public class ImageExporter * character rendering not required, or preference already set * - just do the export */ - exportImage(file, !textSelected.get(), width, height, messageId); + exportImage(file, !textSelected.get(), width, height, messageId, + bitmapscale, bitmapwidth, bitmapheight); } } @@ -207,7 +209,8 @@ public class ImageExporter * @param messageId */ protected void exportImage(File chosenFile, boolean asLineart, int width, - int height, long messageId) + int height, long messageId, float bitmapscale, int bitmapwidth, + int bitmapheight) { String type = imageType.getName(); try @@ -217,7 +220,7 @@ public class ImageExporter // "status.exporting_alignment_as_x_file", type), // messageId); ImageMaker im = new ImageMaker(imageType, width, height, chosenFile, - title, asLineart); + title, asLineart, bitmapscale, bitmapwidth, bitmapheight); imageWriter.exportImage(im.getGraphics()); im.writeImage(); setStatus( diff --git a/src/jalview/io/StructureFile.java b/src/jalview/io/StructureFile.java index fb416db..61b3d1d 100644 --- a/src/jalview/io/StructureFile.java +++ b/src/jalview/io/StructureFile.java @@ -70,7 +70,7 @@ public abstract class StructureFile extends AlignFile private boolean pdbIdAvailable; - private StructureImportSettings.TFType temperatureFactorType = TFType.DEFAULT; + private TFType temperatureFactorType = TFType.DEFAULT; private String paeMatrix = null; @@ -91,12 +91,12 @@ public abstract class StructureFile extends AlignFile return paeMatrix != null; } - public void setTemperatureFactorType(StructureImportSettings.TFType t) + public void setTemperatureFactorType(TFType t) { this.temperatureFactorType = t; } - public StructureImportSettings.TFType getTemperatureFactorType() + public TFType getTemperatureFactorType() { return temperatureFactorType; } @@ -118,7 +118,7 @@ public abstract class StructureFile extends AlignFile } public StructureFile(Object inFile, DataSourceType sourceType, - StructureImportSettings.TFType tempfacType) throws IOException + TFType tempfacType) throws IOException { super(false, inFile, sourceType); this.setTemperatureFactorType(tempfacType); diff --git a/src/jalview/util/ImageMaker.java b/src/jalview/util/ImageMaker.java index 0cd017f..016feee 100755 --- a/src/jalview/util/ImageMaker.java +++ b/src/jalview/util/ImageMaker.java @@ -20,8 +20,6 @@ */ package jalview.util; -import jalview.io.JalviewFileChooser; - import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.RenderingHints; @@ -36,6 +34,8 @@ import org.jfree.graphics2d.svg.SVGGraphics2D; import org.jfree.graphics2d.svg.SVGHints; import org.jibble.epsgraphics.EpsGraphics2D; +import jalview.io.JalviewFileChooser; + public class ImageMaker { public static final String SVG_DESCRIPTION = "Scalable Vector Graphics"; @@ -110,10 +110,12 @@ public class ImageMaker * @param file * @param fileTitle * @param useLineart + * @param bitmapscale * @throws IOException */ public ImageMaker(TYPE imageType, int width, int height, File file, - String fileTitle, boolean useLineart) throws IOException + String fileTitle, boolean useLineart, float bitmapscale, + int bitmapwidth, int bitmapheight) throws IOException { this.type = imageType; @@ -127,7 +129,7 @@ public class ImageMaker setupEPS(width, height, fileTitle, useLineart); break; case PNG: - setupPNG(width, height); + setupPNG(width, height, bitmapscale, bitmapwidth, bitmapheight); break; default: } @@ -176,14 +178,52 @@ public class ImageMaker * * @param width * @param height + * @param scale */ - protected void setupPNG(int width, int height) + protected void setupPNG(int width, int height, float scale, + int bitmapwidth, int bitmapheight) { - bi = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); + if (width == 0 || height == 0) + return; + + float usescale = 0.0f; + int usewidth = width; + int useheight = height; + + // use the smallest positive scale (i.e. fit in the box) + if (scale > 0.0f) + { + usescale = scale; + usewidth = Math.round(scale * width); + useheight = Math.round(scale * height); + } + if (bitmapwidth > 0) + { + float wscale = (float) bitmapwidth / width; + if (wscale > 0.0f && (usescale == 0.0f || wscale < usescale)) + { + usescale = wscale; + usewidth = bitmapwidth; + useheight = Math.round(usescale * height); + } + } + if (bitmapheight > 0) + { + float hscale = (float) bitmapheight / height; + if (hscale > 0.0f && (usescale == 0.0f || hscale < usescale)) + { + usescale = hscale; + usewidth = Math.round(usescale * width); + useheight = bitmapheight; + } + } + bi = new BufferedImage(usewidth, useheight, BufferedImage.TYPE_INT_RGB); graphics = bi.getGraphics(); Graphics2D ig2 = (Graphics2D) graphics; ig2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + if (usescale > 0.0f) + ig2.scale(usescale, usescale); } /** -- 1.7.10.2