From: Ben Soares Date: Mon, 28 Mar 2022 12:22:21 +0000 (+0100) Subject: Merge branch 'feature/JAL-3982_mouseover_highlighting_viaJAL-3860' into feature/JAL... X-Git-Url: http://source.jalview.org/gitweb/?a=commitdiff_plain;h=13f1c3ad1826ce7b2c278e8183ff6fad109b5a7e;hp=26fed5571fff958eadcc96d14f9d952bac1598e8;p=jalview.git Merge branch 'feature/JAL-3982_mouseover_highlighting_viaJAL-3860' into feature/JAL-3851_rest_api_for_genome_browser_updated_with_develop --- diff --git a/j11lib/jersey-json-1.19.4.jar b/j11lib/jersey-json-1.19.4.jar deleted file mode 100644 index c79271b..0000000 Binary files a/j11lib/jersey-json-1.19.4.jar and /dev/null differ diff --git a/resources/lang/Messages.properties b/resources/lang/Messages.properties index 9ce5a63..5921107 100644 --- a/resources/lang/Messages.properties +++ b/resources/lang/Messages.properties @@ -204,6 +204,11 @@ label.colourScheme_nucleotide = Nucleotide label.colourScheme_t-coffeescores = T-Coffee Scores label.colourScheme_rnahelices = By RNA Helices label.colourScheme_sequenceid = Sequence ID Colour +label.colourScheme_gecos-flower = Gecos: flower +label.colourScheme_gecos-blossom = Gecos: blossom +label.colourScheme_gecos-sunset = Gecos: sunset +label.colourScheme_gecos-ocean = Gecos: ocean +label.colourScheme_igv = IGV Nucleotide label.blc = BLC label.fasta = Fasta label.msf = MSF diff --git a/resources/lang/Messages_es.properties b/resources/lang/Messages_es.properties index fb87f7d..7fb0b58 100644 --- a/resources/lang/Messages_es.properties +++ b/resources/lang/Messages_es.properties @@ -197,6 +197,11 @@ label.colourScheme_nucleotide = Nucle label.colourScheme_t-coffeescores = Puntuación del T-Coffee label.colourScheme_rnahelices = Por hélices de RNA label.colourScheme_sequenceid = Color de ID de secuencia +label.colourScheme_gecos-flower = Gecos: flower +label.colourScheme_gecos-blossom = Gecos: blossom +label.colourScheme_gecos-sunset = Gecos: sunset +label.colourScheme_gecos-ocean = Gecos: ocean +label.colourScheme_igv = IGV Nucleótido label.blc = BLC label.fasta = Fasta label.msf = MSF diff --git a/src/jalview/gui/AlignFrame.java b/src/jalview/gui/AlignFrame.java index 168f6c5..237e0c6 100644 --- a/src/jalview/gui/AlignFrame.java +++ b/src/jalview/gui/AlignFrame.java @@ -20,8 +20,6 @@ */ package jalview.gui; -import java.util.Locale; - import java.awt.BorderLayout; import java.awt.Color; import java.awt.Component; @@ -60,6 +58,7 @@ import java.util.Enumeration; import java.util.HashMap; import java.util.Hashtable; import java.util.List; +import java.util.Locale; import java.util.Map; import java.util.Vector; import java.util.concurrent.CompletableFuture; @@ -3076,11 +3075,17 @@ 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()); + wrapMenuItem_actionPerformed(e, wrapMenuItem.isSelected()); + } + + public void wrapMenuItem_actionPerformed(ActionEvent e, boolean select) + { + scaleAbove.setVisible(select); + scaleLeft.setVisible(select); + scaleRight.setVisible(select); + viewport.setWrapAlignment(select); alignPanel.updateLayout(); + wrapMenuItem.setSelected(select); } @Override @@ -3372,12 +3377,19 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, @Override public void annotationPanelMenuItem_actionPerformed(ActionEvent e) { - final boolean setVisible = annotationPanelMenuItem.isSelected(); + annotationPanelMenuItem_actionPerformed(e, + annotationPanelMenuItem.isSelected()); + } + + public void annotationPanelMenuItem_actionPerformed(ActionEvent e, + boolean setVisible) + { viewport.setShowAnnotation(setVisible); this.showAllSeqAnnotations.setEnabled(setVisible); this.hideAllSeqAnnotations.setEnabled(setVisible); this.showAllAlAnnotations.setEnabled(setVisible); this.hideAllAlAnnotations.setEnabled(setVisible); + annotationPanelMenuItem.setSelected(setVisible); alignPanel.updateLayout(); } diff --git a/src/jalview/gui/CutAndPasteTransfer.java b/src/jalview/gui/CutAndPasteTransfer.java index 112d502..091b7dd 100644 --- a/src/jalview/gui/CutAndPasteTransfer.java +++ b/src/jalview/gui/CutAndPasteTransfer.java @@ -20,13 +20,31 @@ */ package jalview.gui; -import jalview.bin.Cache; +import java.awt.Toolkit; +import java.awt.datatransfer.Clipboard; +import java.awt.datatransfer.DataFlavor; +import java.awt.datatransfer.StringSelection; +import java.awt.datatransfer.Transferable; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.MouseEvent; +import java.io.FileWriter; +import java.io.IOException; +import java.io.PrintWriter; +import java.util.HashMap; +import java.util.Map; + +import javax.swing.JMenuItem; +import javax.swing.JPopupMenu; +import javax.swing.SwingUtilities; + import jalview.api.AlignViewportI; import jalview.api.AlignmentViewPanel; import jalview.api.ComplexAlignFile; import jalview.api.FeatureSettingsModelI; import jalview.api.FeaturesDisplayedI; import jalview.api.FeaturesSourceI; +import jalview.bin.Cache; import jalview.bin.Jalview; import jalview.datamodel.AlignmentI; import jalview.datamodel.HiddenColumns; @@ -45,22 +63,6 @@ import jalview.json.binding.biojson.v1.ColourSchemeMapper; import jalview.schemes.ColourSchemeI; import jalview.util.MessageManager; -import java.awt.Toolkit; -import java.awt.datatransfer.Clipboard; -import java.awt.datatransfer.DataFlavor; -import java.awt.datatransfer.StringSelection; -import java.awt.datatransfer.Transferable; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.awt.event.MouseEvent; -import java.io.FileWriter; -import java.io.IOException; -import java.io.PrintWriter; - -import javax.swing.JMenuItem; -import javax.swing.JPopupMenu; -import javax.swing.SwingUtilities; - /** * Cut'n'paste files into the desktop See JAL-1105 * @@ -215,6 +217,11 @@ public class CutAndPasteTransfer extends GCutAndPasteTransfer @Override public void ok_actionPerformed(ActionEvent e) { + ok_actionPerformed(e, new HashMap()); + } + + public void ok_actionPerformed(ActionEvent e, Map options) + { String text = getText(); if (text.trim().length() < 1) { @@ -251,7 +258,6 @@ public class CutAndPasteTransfer extends GCutAndPasteTransfer FormatAdapter fa = new FormatAdapter(alignpanel); al = fa.readFile(getText(), DataSourceType.PASTE, format); source = fa.getAlignFile(); - } catch (IOException ex) { JvOptionPane.showInternalMessageDialog(Desktop.desktop, MessageManager @@ -263,9 +269,10 @@ public class CutAndPasteTransfer extends GCutAndPasteTransfer if (al != null && al.hasValidSequence()) { - String title = MessageManager - .formatMessage("label.input_cut_paste_params", new String[] - { format.getName() }); + String title = options.containsKey("title") ? options.get("title") + : MessageManager.formatMessage("label.input_cut_paste_params", + new String[] + { format.getName() }); FeatureSettingsModelI proxyColourScheme = source .getFeatureColourScheme(); @@ -320,6 +327,20 @@ public class CutAndPasteTransfer extends GCutAndPasteTransfer af.getViewport().applyFeaturesStyle(proxyColourScheme); } af.currentFileFormat = format; + if (options.containsKey("wrap")) + { + af.wrapMenuItem_actionPerformed(e, + Boolean.parseBoolean(options.get("wrap"))); + } + if (options.containsKey("showannotations")) + { + af.annotationPanelMenuItem_actionPerformed(e, + Boolean.parseBoolean(options.get("showannotations"))); + } + if (options.containsKey("colourscheme")) + { + af.changeColour_actionPerformed(options.get("colourscheme")); + } Desktop.addInternalFrame(af, title, AlignFrame.DEFAULT_WIDTH, AlignFrame.DEFAULT_HEIGHT); af.setStatus(MessageManager diff --git a/src/jalview/rest/AbstractEndpoint.java b/src/jalview/rest/AbstractEndpoint.java index c84b7b7..ae9a938 100644 --- a/src/jalview/rest/AbstractEndpoint.java +++ b/src/jalview/rest/AbstractEndpoint.java @@ -2,6 +2,9 @@ package jalview.rest; import java.io.IOException; import java.io.PrintWriter; +import java.util.HashMap; +import java.util.Map; +import java.util.Map.Entry; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @@ -23,6 +26,16 @@ public abstract class AbstractEndpoint implements EndpointI private final String description; + private String[] pathParameters = null; + + private Map queryParameters = null; + + private Map options = null; + + private String id = null; + + private String fromId = null; + public AbstractEndpoint(API api, String path, String name, String parameters, String description) { @@ -65,12 +78,89 @@ public abstract class AbstractEndpoint implements EndpointI * Shared methods below here */ + protected String getId(HttpServletRequest request) + { + if (id != null) + return id; + id = getQueryParameter(request, "id"); + return id; + } + + protected String getFromId(HttpServletRequest request) + { + if (fromId != null) + return fromId; + fromId = getQueryParameter(request, "fromId"); + return fromId; + } + + protected Map getQueryParameters( + HttpServletRequest request) + { + if (queryParameters != null) + return queryParameters; + queryParameters = request.getParameterMap(); + return queryParameters; + } + + protected String getQueryParameter(HttpServletRequest request, + String param) + { + String[] vals = getQueryParameters(request).get(param); + return (vals == null || vals.length < 1) ? null : vals[0]; + } + protected String[] getEndpointPathParameters(HttpServletRequest request) { + if (pathParameters != null) + return pathParameters; String pathInfo = request.getPathInfo(); int slashpos = pathInfo.indexOf('/', 1); - return slashpos < 1 ? null - : pathInfo.substring(slashpos + 1).split("/"); + if (slashpos < 1) + return null; + + pathParameters = pathInfo.substring(slashpos + 1).split("/"); + return pathParameters; + } + + protected Map getOptions(HttpServletRequest request) + { + if (this.options != null) + return this.options; + Map opts = new HashMap<>(); + for (Entry e : getQueryParameters(null).entrySet()) + { + if (e.getKey().startsWith("option:")) + { + for (int i = 0; i < e.getValue().length; i++) + { + opts.put(e.getKey().substring(7), e.getValue()[i]); + } + } + } + + String[] params = getEndpointPathParameters(request); + if (params != null) + { + for (int i = 0; i < params.length; i++) + { + String param = params[i]; + if (param.startsWith("option:")) + { + int ePos = param.indexOf("="); + if (ePos == -1) + { + opts.put(param.substring(7), null); + } + else + { + opts.put(param.substring(7, ePos), param.substring(ePos + 1)); + } + } + } + } + this.options = opts; + return opts; } protected void returnError(HttpServletRequest request, @@ -161,7 +251,7 @@ public abstract class AbstractEndpoint implements EndpointI protected AlignFrame[] getAlignFrames(HttpServletRequest request, String idParam, boolean all) { - String fromIdString = request.getParameter(idParam); + String fromIdString = this.getQueryParameter(request, idParam); if (fromIdString != null) { @@ -187,8 +277,7 @@ public abstract class AbstractEndpoint implements EndpointI String idParam) { AlignFrame[] afs = getAlignFrames(request, idParam, false); - return (afs == null || afs.length < 1 || afs[0] == null) ? null - : afs[0]; + return (afs == null || afs.length < 1) ? null : afs[0]; } protected boolean deleteFromCache() diff --git a/src/jalview/rest/AbstractEndpointAsync.java b/src/jalview/rest/AbstractEndpointAsync.java index cb1ff34..989bd27 100644 --- a/src/jalview/rest/AbstractEndpointAsync.java +++ b/src/jalview/rest/AbstractEndpointAsync.java @@ -71,8 +71,19 @@ public abstract class AbstractEndpointAsync extends AbstractEndpoint HttpServletResponse response) { // should be overridden - // must setId(request, extension) - setId(request, null); + // MUST setId(request, extension) + this.setId(request, null); + // and do this + this.saveParameters(request); + } + + protected void saveParameters(HttpServletRequest request) + { + this.getId(request); + this.getFromId(request); + this.getEndpointPathParameters(request); + this.getQueryParameters(request); + this.getOptions(request); } protected abstract void processAsync(HttpServletRequest request, @@ -143,7 +154,8 @@ public abstract class AbstractEndpointAsync extends AbstractEndpoint protected String setId(HttpServletRequest request, String extension) { - String idString = request.getParameter("id"); + String idString = getId(request); + Console.debug("GOT ID '" + idString + "'"); if (idString == null) { setIdExtension(extension); diff --git a/src/jalview/rest/HighlightSequenceEndpoint.java b/src/jalview/rest/HighlightSequenceEndpoint.java index f228473..4e2b072 100644 --- a/src/jalview/rest/HighlightSequenceEndpoint.java +++ b/src/jalview/rest/HighlightSequenceEndpoint.java @@ -8,6 +8,7 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import jalview.api.AlignmentViewPanel; +import jalview.bin.Console; import jalview.datamodel.AlignmentI; import jalview.datamodel.SequenceI; import jalview.gui.AlignFrame; @@ -48,7 +49,21 @@ public class HighlightSequenceEndpoint extends AbstractEndpoint "Could not parse postition integer " + posString); } - String sequenceNames = parameters[0]; + String sequenceNames = parameters[0] == null ? "#0" : parameters[0]; + Console.debug("Looking for sequence '" + sequenceNames + "'"); + + int sequenceNum = -1; + if (sequenceNames.startsWith("*")) + { + try + { + sequenceNum = Integer.parseInt(sequenceNames.substring(1)); + } catch (NumberFormatException e) + { + Console.debug("Could not parse sequence number '" + sequenceNames + + "'. Will use as identifier.", e); + } + } Map ssmMap = new HashMap<>(); AlignFrame[] alignFrames = getAlignFrames(request, true); @@ -67,11 +82,28 @@ public class HighlightSequenceEndpoint extends AbstractEndpoint StructureSelectionManager ssm = ap.getStructureSelectionManager(); AlignmentI al = ap.getAlignment(); List seqs = (List) al.getSequences(); - for (SequenceI seq : seqs) + if (sequenceNum >= 0) + { + try + { + SequenceI seqN = seqs.get(sequenceNum); + ssmMap.put(seqN, ssm); + } catch (IndexOutOfBoundsException e) + { + Console.debug("Sequence index number too large: " + sequenceNum, + e); + } + } + else { - if (sequenceNames.equals(seq.getName())) + // search for sequence names + for (SequenceI seq : seqs) { - ssmMap.put(seq, ssm); + if (sequenceNames.equals(seq.getName())) + { + ssmMap.put(seq, ssm); + Console.debug("Found sequence '" + seq.getName()); + } } } } @@ -84,6 +116,8 @@ public class HighlightSequenceEndpoint extends AbstractEndpoint { continue; } + Console.debug("Highlighting sequence '" + seq.getName() + + "' at position " + pos); ssm.mouseOverSequence(seq, pos, -1, null); } diff --git a/src/jalview/rest/InputAlignmentEndpoint.java b/src/jalview/rest/InputAlignmentEndpoint.java index caad39f..246f511 100644 --- a/src/jalview/rest/InputAlignmentEndpoint.java +++ b/src/jalview/rest/InputAlignmentEndpoint.java @@ -62,13 +62,14 @@ public class InputAlignmentEndpoint extends AbstractEndpointAsync isPost = method.equalsIgnoreCase("post"); hasData = data != null; + this.saveParameters(request); + if (isPost) { access = "post"; try { body = RestHandler.getInstance().getRequestBody(request, response); - Console.debug("BODY='" + body + "'"); } catch (IOException e) { returnError(request, response, "could not read POST body"); @@ -143,7 +144,10 @@ public class InputAlignmentEndpoint extends AbstractEndpointAsync // use File -> Input Alignment -> from Textbox CutAndPasteTransfer cap = new CutAndPasteTransfer(); cap.setText(content); - cap.ok_actionPerformed(null); + + Map options = getOptions(request); + + cap.ok_actionPerformed(null, options); cap.cancel_actionPerformed(null); } else if (fileString != null) diff --git a/src/jalview/rest/RestHandler.java b/src/jalview/rest/RestHandler.java index c4ada0e..c967d3e 100644 --- a/src/jalview/rest/RestHandler.java +++ b/src/jalview/rest/RestHandler.java @@ -24,6 +24,7 @@ import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; +import java.lang.reflect.InvocationTargetException; import java.net.BindException; import java.util.HashMap; import java.util.Map; @@ -73,13 +74,32 @@ public class RestHandler extends AbstractRequestHandler private boolean init = false; // map of method names and method handlers - private Map endpoints = null; + private Map endpoints = null; - protected Map getEndpoints() + protected Map getEndpoints() { return endpoints; } + protected AbstractEndpoint getNewEndpoint(String name) + { + if (getEndpoints() == null) + { + return null; + } + try + { + return getEndpoints().get(name).getClass() + .getDeclaredConstructor(API.class).newInstance(this); + } catch (InstantiationException | IllegalAccessException + | IllegalArgumentException | InvocationTargetException + | NoSuchMethodException | SecurityException e) + { + Console.debug("Could not instantiate new endpoint '" + name + "'", e); + } + return null; + } + /** * Singleton instance of this class */ @@ -135,13 +155,21 @@ public class RestHandler extends AbstractRequestHandler // This "pointless" call to request.getInputStream() seems to preserve the // InputStream for use later in getRequestBody. request.getInputStream(); - if (endpoints == null) + + String remoteAddr = request.getRemoteAddr(); + if (!("127.0.0.1".equals(remoteAddr) || "localhost".equals(remoteAddr))) + { + returnError(request, response, "Not authorised: " + remoteAddr, + HttpServletResponse.SC_UNAUTHORIZED); + return; + } + if (getEndpoints() == null) { final String queryString = request.getQueryString(); final String reply = "REST not yet implemented; received " + request.getMethod() + ": " + request.getRequestURL() + (queryString == null ? "" : "?" + queryString); - System.out.println(reply); + Console.error(reply); response.setHeader("Cache-Control", "no-cache/no-store"); response.setHeader("Content-type", "text/plain"); @@ -151,10 +179,13 @@ public class RestHandler extends AbstractRequestHandler } String endpointName = getRequestedEndpointName(request); + Console.debug(endpointName); - if (!endpoints.containsKey(endpointName) - || endpoints.get(endpointName) == null) + if (!getEndpoints().containsKey(endpointName) + || getEndpoints().get(endpointName) == null) { + Console.debug( + "RestHandler did not find endpoint '" + endpointName + "'"); response.setHeader("Cache-Control", "no-cache/no-store"); response.setHeader("Content-type", "text/plain"); @@ -167,7 +198,7 @@ public class RestHandler extends AbstractRequestHandler ContextHandler ch = HttpServer.getInstance().getContextHandler(this); String base = HttpServer.getInstance().getUri().toString(); String contextPath = ch == null ? "" : ch.getContextPath(); - for (String key : endpoints.keySet()) + for (String key : getEndpoints().keySet()) { writer.write(base + contextPath + "/" + key + "\n"); } @@ -177,7 +208,7 @@ public class RestHandler extends AbstractRequestHandler response.setHeader("Cache-Control", "no-cache/no-store"); response.setHeader("Content-type", "text/plain"); - EndpointI ep = endpoints.get(endpointName); + EndpointI ep = getNewEndpoint(endpointName); ep.processEndpoint(request, response); return; @@ -209,15 +240,14 @@ public class RestHandler extends AbstractRequestHandler // e.g. registerHandler and addEndpoints } - protected boolean addEndpoint(EndpointI ep) + protected void addEndpoint(AbstractEndpoint ep) { - if (endpoints == null) + if (getEndpoints() == null) { endpoints = new HashMap<>(); } - AbstractEndpoint e = (AbstractEndpoint) ep; endpoints.put(ep.getPath(), ep); - return true; + Console.debug("REST API, added endpoint '" + ep.getPath() + "'"); } protected String getRequestedEndpointName(HttpServletRequest request) @@ -228,18 +258,17 @@ public class RestHandler extends AbstractRequestHandler : pathInfo.substring(1); } - protected String[] getEndpointPathParameters(HttpServletRequest request) + protected void returnError(HttpServletRequest request, + HttpServletResponse response, String message) { - String pathInfo = request.getPathInfo(); - int slashpos = pathInfo.indexOf('/', 1); - return slashpos < 1 ? null - : pathInfo.substring(slashpos + 1).split("/"); + returnError(request, response, message, + HttpServletResponse.SC_INTERNAL_SERVER_ERROR); } protected void returnError(HttpServletRequest request, - HttpServletResponse response, String message) + HttpServletResponse response, String message, int statusCode) { - response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); + response.setStatus(statusCode); String endpointName = getRequestedEndpointName(request); Console.error(getName() + " error: endpoint " + endpointName + " failed: '" + message + "'"); @@ -277,7 +306,7 @@ public class RestHandler extends AbstractRequestHandler StringBuilder sb = new StringBuilder(); BufferedReader reader = null; Console.debug("REQUEST=" + request.toString()); - Console.debug("REQUEST.Content-Lenggth=" + request.getContentLength()); + Console.debug("REQUEST.Content-Length=" + request.getContentLength()); try { reader = request.getReader(); @@ -285,8 +314,6 @@ public class RestHandler extends AbstractRequestHandler } catch (IllegalStateException e) { ServletInputStream is = request.getInputStream(); - Console.debug("INPUTSTREAM " - + (is.isFinished() ? "FINISHED" : "NOT FINISHED")); reader = new BufferedReader(new InputStreamReader(is)); Console.debug("Using getInputStream()"); } diff --git a/src/jalview/schemes/BlossomColourScheme.java b/src/jalview/schemes/BlossomColourScheme.java new file mode 100755 index 0000000..9b92405 --- /dev/null +++ b/src/jalview/schemes/BlossomColourScheme.java @@ -0,0 +1,64 @@ +/* + * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$) + * Copyright (C) $$Year-Rel$$ The Jalview Authors + * + * This file is part of Jalview. + * + * Jalview is free software: you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, either version 3 + * of the License, or (at your option) any later version. + * + * Jalview is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Jalview. If not, see . + * The Jalview Authors are detailed in the 'AUTHORS' file. + */ +package jalview.schemes; + +import jalview.api.AlignViewportI; +import jalview.datamodel.AnnotatedCollectionI; + +/** + * DOCUMENT ME! + * + * @author $author$ + * @version $Revision$ + */ +public class BlossomColourScheme extends ResidueColourScheme +{ + /** + * Creates a new BlossomColourScheme object. + */ + public BlossomColourScheme() + { + super(ResidueProperties.aaIndex, ResidueProperties.blossom); + } + + @Override + public boolean isPeptideSpecific() + { + return true; + } + + @Override + public String getSchemeName() + { + return JalviewColourScheme.Blossom.toString(); + } + + /** + * Returns a new instance of this colour scheme with which the given data may + * be coloured + */ + @Override + public ColourSchemeI getInstance(AlignViewportI view, + AnnotatedCollectionI coll) + { + return new BlossomColourScheme(); + } +} diff --git a/src/jalview/schemes/FlowerColourScheme.java b/src/jalview/schemes/FlowerColourScheme.java new file mode 100755 index 0000000..040e6e4 --- /dev/null +++ b/src/jalview/schemes/FlowerColourScheme.java @@ -0,0 +1,64 @@ +/* + * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$) + * Copyright (C) $$Year-Rel$$ The Jalview Authors + * + * This file is part of Jalview. + * + * Jalview is free software: you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, either version 3 + * of the License, or (at your option) any later version. + * + * Jalview is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Jalview. If not, see . + * The Jalview Authors are detailed in the 'AUTHORS' file. + */ +package jalview.schemes; + +import jalview.api.AlignViewportI; +import jalview.datamodel.AnnotatedCollectionI; + +/** + * DOCUMENT ME! + * + * @author $author$ + * @version $Revision$ + */ +public class FlowerColourScheme extends ResidueColourScheme +{ + /** + * Creates a new FlowerColourScheme object. + */ + public FlowerColourScheme() + { + super(ResidueProperties.aaIndex, ResidueProperties.flower); + } + + @Override + public boolean isPeptideSpecific() + { + return true; + } + + @Override + public String getSchemeName() + { + return JalviewColourScheme.Flower.toString(); + } + + /** + * Returns a new instance of this colour scheme with which the given data may + * be coloured + */ + @Override + public ColourSchemeI getInstance(AlignViewportI view, + AnnotatedCollectionI coll) + { + return new FlowerColourScheme(); + } +} diff --git a/src/jalview/schemes/IGVColourScheme.java b/src/jalview/schemes/IGVColourScheme.java new file mode 100755 index 0000000..58ba3ba --- /dev/null +++ b/src/jalview/schemes/IGVColourScheme.java @@ -0,0 +1,64 @@ +/* + * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$) + * Copyright (C) $$Year-Rel$$ The Jalview Authors + * + * This file is part of Jalview. + * + * Jalview is free software: you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, either version 3 + * of the License, or (at your option) any later version. + * + * Jalview is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Jalview. If not, see . + * The Jalview Authors are detailed in the 'AUTHORS' file. + */ +package jalview.schemes; + +import jalview.api.AlignViewportI; +import jalview.datamodel.AnnotatedCollectionI; + +/** + * DOCUMENT ME! + * + * @author $author$ + * @version $Revision$ + */ +public class IGVColourScheme extends ResidueColourScheme +{ + /** + * Creates a new NucleotideColourScheme object. + */ + public IGVColourScheme() + { + super(ResidueProperties.nucleotideIndex, ResidueProperties.igv); + } + + @Override + public boolean isNucleotideSpecific() + { + return true; + } + + @Override + public String getSchemeName() + { + return JalviewColourScheme.IGV.toString(); + } + + /** + * Returns a new instance of this colour scheme with which the given data may + * be coloured + */ + @Override + public ColourSchemeI getInstance(AlignViewportI view, + AnnotatedCollectionI coll) + { + return new IGVColourScheme(); + } +} diff --git a/src/jalview/schemes/JalviewColourScheme.java b/src/jalview/schemes/JalviewColourScheme.java index 456397e..d1817fe 100644 --- a/src/jalview/schemes/JalviewColourScheme.java +++ b/src/jalview/schemes/JalviewColourScheme.java @@ -34,12 +34,17 @@ public enum JalviewColourScheme PID("% Identity", PIDColourScheme.class), Zappo("Zappo", ZappoColourScheme.class), Taylor("Taylor", TaylorColourScheme.class), + Flower("gecos-flower", FlowerColourScheme.class), + Blossom("gecos-blossom", BlossomColourScheme.class), + Sunset("gecos-sunset", SunsetColourScheme.class), + Ocean("gecos-ocean", OceanColourScheme.class), Hydrophobic("Hydrophobic", HydrophobicColourScheme.class), Helix("Helix Propensity", HelixColourScheme.class), Strand("Strand Propensity", StrandColourScheme.class), Turn("Turn Propensity", TurnColourScheme.class), Buried("Buried Index", BuriedColourScheme.class), Nucleotide("Nucleotide", NucleotideColourScheme.class), + IGV("IGV", IGVColourScheme.class), PurinePyrimidine("Purine/Pyrimidine", PurinePyrimidineColourScheme.class), RNAHelices("RNA Helices", RNAHelicesColour.class), TCoffee("T-Coffee Scores", TCoffeeColourScheme.class), diff --git a/src/jalview/schemes/OceanColourScheme.java b/src/jalview/schemes/OceanColourScheme.java new file mode 100755 index 0000000..23834a6 --- /dev/null +++ b/src/jalview/schemes/OceanColourScheme.java @@ -0,0 +1,64 @@ +/* + * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$) + * Copyright (C) $$Year-Rel$$ The Jalview Authors + * + * This file is part of Jalview. + * + * Jalview is free software: you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, either version 3 + * of the License, or (at your option) any later version. + * + * Jalview is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Jalview. If not, see . + * The Jalview Authors are detailed in the 'AUTHORS' file. + */ +package jalview.schemes; + +import jalview.api.AlignViewportI; +import jalview.datamodel.AnnotatedCollectionI; + +/** + * DOCUMENT ME! + * + * @author $author$ + * @version $Revision$ + */ +public class OceanColourScheme extends ResidueColourScheme +{ + /** + * Creates a new OceanColourScheme object. + */ + public OceanColourScheme() + { + super(ResidueProperties.aaIndex, ResidueProperties.ocean); + } + + @Override + public boolean isPeptideSpecific() + { + return true; + } + + @Override + public String getSchemeName() + { + return JalviewColourScheme.Ocean.toString(); + } + + /** + * Returns a new instance of this colour scheme with which the given data may + * be coloured + */ + @Override + public ColourSchemeI getInstance(AlignViewportI view, + AnnotatedCollectionI coll) + { + return new OceanColourScheme(); + } +} diff --git a/src/jalview/schemes/ResidueProperties.java b/src/jalview/schemes/ResidueProperties.java index ab86400..75fa083 100755 --- a/src/jalview/schemes/ResidueProperties.java +++ b/src/jalview/schemes/ResidueProperties.java @@ -21,9 +21,6 @@ package jalview.schemes; import java.util.Locale; - -import jalview.analysis.GeneticCodes; - import java.awt.Color; import java.util.ArrayList; import java.util.Arrays; @@ -34,6 +31,8 @@ import java.util.List; import java.util.Map; import java.util.Vector; +import jalview.analysis.GeneticCodes; + public class ResidueProperties { // Stores residue codes/names and colours and other things @@ -366,6 +365,20 @@ public class ResidueProperties Color.white, // Gap }; + public static final Color[] igv = { + new Color(0, 150, 0), // A + Color.blue, // C + new Color(209, 113, 5), // G + Color.red, // T + Color.red, // U + Color.white, // I (inosine) + Color.white, // X (xanthine) + Color.white, // R + Color.white, // Y + Color.white, // N + Color.white, // Gap + }; + // Added for PurinePyrimidineColourScheme public static final Color[] purinepyrimidine = { new Color(255, 131, 250), // A, // G, @@ -407,6 +420,125 @@ public class ResidueProperties Color.white // ' ' }; + /* + * flower, blossom, sunset, ocean colour schemes from geocos. + * See https://gecos.biotite-python.org/ + * https://raw.githubusercontent.com/biotite-dev/biotite/master/src/biotite/sequence/graphics/color_schemes/flower.json + * and https://bmcbioinformatics.biomedcentral.com/articles/10.1186/s12859-020-3526-6 + * (https://doi.org/10.1186/s12859-020-3526-6) + */ + public static final Color[] flower = { new Color(177, 138, 81), // A + new Color(131, 191, 241), // R + new Color(11, 206, 198), // N + new Color(1, 165, 120), // D + new Color(255, 87, 1), // C + new Color(114, 149, 174), // Q + new Color(45, 160, 161), // E + new Color(177, 194, 60), // G + new Color(1, 148, 249), // H + new Color(242, 118, 99), // I + new Color(223, 110, 117), // L + new Color(127, 195, 215), // K + new Color(254, 157, 175), // M + new Color(250, 85, 157), // F + new Color(79, 163, 42), // P + new Color(180, 189, 155), // S + new Color(210, 181, 118), // T + new Color(255, 45, 237), // W + new Color(201, 110, 207), // Y + new Color(253, 153, 123), // V + Color.white, // B + Color.white, // Z + Color.white, // X + Color.white, // - + Color.white, // * + Color.white // . + }; + + public static final Color[] blossom = { new Color(139, 196, 180), // A + new Color(252, 149, 2), // R + new Color(181, 194, 6), // N + new Color(95, 165, 5), // D + new Color(8, 147, 254), // C + new Color(191, 133, 39), // Q + new Color(219, 181, 1), // E + new Color(0, 211, 130), // G + new Color(255, 87, 1), // H + new Color(154, 186, 243), // I + new Color(205, 165, 220), // L + new Color(254, 165, 39), // K + new Color(245, 161, 184), // M + new Color(247, 79, 168), // F + new Color(16, 214, 49), // P + new Color(126, 157, 89), // S + new Color(0, 162, 156), // T + new Color(254, 8, 251), // W + new Color(255, 78, 122), // Y + new Color(135, 192, 228), // V + Color.white, // B + Color.white, // Z + Color.white, // X + Color.white, // - + Color.white, // * + Color.white // . + }; + + public static final Color[] sunset = { new Color(254, 160, 253), // A + new Color(133, 116, 106), // R + new Color(171, 200, 245), // N + new Color(46, 123, 190), // D + new Color(252, 12, 254), // C + new Color(140, 110, 129), // Q + new Color(103, 120, 146), // E + new Color(39, 153, 255), // G + new Color(219, 197, 142), // H + new Color(250, 33, 161), // I + new Color(224, 30, 130), // L + new Color(222, 190, 204), // K + new Color(209, 62, 123), // M + new Color(255, 56, 93), // F + new Color(87, 102, 249), // P + new Color(231, 180, 253), // S + new Color(166, 88, 183), // T + new Color(255, 55, 1), // W + new Color(203, 83, 57), // Y + new Color(254, 81, 184), // V + Color.white, // B + Color.white, // Z + Color.white, // X + Color.white, // - + Color.white, // * + Color.white // . + }; + + public static final Color[] ocean = { new Color(198, 202, 155), // A + new Color(12, 160, 168), // R + new Color(10, 223, 195), // N + new Color(76, 223, 161), // D + new Color(198, 129, 54), // C + new Color(139, 211, 209), // Q + new Color(96, 218, 201), // E + new Color(51, 165, 81), // G + new Color(0, 207, 254), // H + new Color(242, 186, 170), // I + new Color(187, 138, 131), // L + new Color(64, 160, 144), // K + new Color(164, 139, 136), // M + new Color(171, 136, 174), // F + new Color(175, 211, 101), // P + new Color(109, 155, 116), // S + new Color(141, 149, 102), // T + new Color(117, 138, 238), // W + new Color(186, 195, 252), // Y + new Color(233, 190, 164), // V + Color.white, // B + Color.white, // Z + Color.white, // X + Color.white, // - + Color.white, // * + Color.white // . + }; + // Dunno where I got these numbers from public static final double[] hyd2 = { 0.62, // A 0.29, // R diff --git a/src/jalview/schemes/SunsetColourScheme.java b/src/jalview/schemes/SunsetColourScheme.java new file mode 100755 index 0000000..4af7566 --- /dev/null +++ b/src/jalview/schemes/SunsetColourScheme.java @@ -0,0 +1,64 @@ +/* + * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$) + * Copyright (C) $$Year-Rel$$ The Jalview Authors + * + * This file is part of Jalview. + * + * Jalview is free software: you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, either version 3 + * of the License, or (at your option) any later version. + * + * Jalview is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Jalview. If not, see . + * The Jalview Authors are detailed in the 'AUTHORS' file. + */ +package jalview.schemes; + +import jalview.api.AlignViewportI; +import jalview.datamodel.AnnotatedCollectionI; + +/** + * DOCUMENT ME! + * + * @author $author$ + * @version $Revision$ + */ +public class SunsetColourScheme extends ResidueColourScheme +{ + /** + * Creates a new SunsetColourScheme object. + */ + public SunsetColourScheme() + { + super(ResidueProperties.aaIndex, ResidueProperties.sunset); + } + + @Override + public boolean isPeptideSpecific() + { + return true; + } + + @Override + public String getSchemeName() + { + return JalviewColourScheme.Sunset.toString(); + } + + /** + * Returns a new instance of this colour scheme with which the given data may + * be coloured + */ + @Override + public ColourSchemeI getInstance(AlignViewportI view, + AnnotatedCollectionI coll) + { + return new SunsetColourScheme(); + } +}