From c0e43acd458a2e19a5ab3be56a53bc88932657c4 Mon Sep 17 00:00:00 2001 From: Ben Soares Date: Thu, 8 Dec 2022 14:19:23 +0000 Subject: [PATCH] JAL-629 Allow attachment of pAE file to a particular sequence --- src/jalview/bin/ArgParser.java | 2 +- src/jalview/bin/Commands.java | 106 +++++++++++++++++++++++++---- src/jalview/ws/dbsources/EBIAlfaFold.java | 59 ++++++++++++++-- 3 files changed, 146 insertions(+), 21 deletions(-) diff --git a/src/jalview/bin/ArgParser.java b/src/jalview/bin/ArgParser.java index bcd4498..0f9ac2e 100644 --- a/src/jalview/bin/ArgParser.java +++ b/src/jalview/bin/ArgParser.java @@ -104,7 +104,7 @@ public class ArgParser TEMPFAC_DESC.setOptions(Opt.STRING, Opt.LINKED); TEMPFAC_SHADING.setOptions(Opt.STRING, Opt.LINKED); TITLE.setOptions(Opt.STRING, Opt.LINKED); - PAEMATRIX.setOptions(Opt.STRING, Opt.LINKED); + PAEMATRIX.setOptions(Opt.STRING, Opt.LINKED, Opt.MULTI); WRAP.setOptions(Opt.BOOLEAN, Opt.LINKED); } diff --git a/src/jalview/bin/Commands.java b/src/jalview/bin/Commands.java index 4ff82aa..f01b2b3 100644 --- a/src/jalview/bin/Commands.java +++ b/src/jalview/bin/Commands.java @@ -11,10 +11,12 @@ import java.util.Locale; import java.util.Map; import jalview.analysis.AlignmentUtils; +import jalview.api.AlignmentViewPanel; import jalview.bin.ArgParser.Arg; import jalview.bin.ArgParser.ArgValues; import jalview.datamodel.AlignmentAnnotation; import jalview.gui.AlignFrame; +import jalview.gui.AlignViewport; import jalview.gui.Desktop; import jalview.io.AppletFormatAdapter; import jalview.io.DataSourceType; @@ -221,9 +223,6 @@ public class Commands .getFirstSequenceAnnotationOfType( af.getCurrentView().getAlignment(), AlignmentAnnotation.LINE_GRAPH); - Console.debug("***** Trying to change label from '" - + (aa == null ? aa : aa.label) + "' to '" - + m.get(Arg.TEMPFAC_LABEL).getValue() + "'"); if (aa != null) { aa.label = m.get(Arg.TEMPFAC_LABEL).getValue(); @@ -231,16 +230,6 @@ public class Commands } } - // - - // load a pAE file? - if (m.get(Arg.PAEMATRIX) != null) - { - File paeFile = new File(m.get(Arg.PAEMATRIX).getValue()); - EBIAlfaFold.addAlphaFoldPAE(af.getCurrentView().getAlignment(), - paeFile); - } - // store the AlignFrame for this id afMap.put(id, af); } @@ -271,6 +260,97 @@ public class Commands } } + + // load a pAE file if given + if (m.get(Arg.PAEMATRIX) != null) + { + AlignFrame af = afMap.get(id); + if (af != null) + { + for (String val : m.get(Arg.PAEMATRIX).getValues()) + { + SubId subId = new SubId(val); + File paeFile = new File(subId.content); + EBIAlfaFold.addAlphaFoldPAE(af.getCurrentView().getAlignment(), + paeFile, subId.index, + "id".equals(subId.keyName) ? subId.keyValue : null); + // required to readjust the height and position of the pAE + // annotation + for (AlignmentViewPanel ap : af.getAlignPanels()) + { + ap.adjustAnnotationHeight(); + } + } + } + } } + /** + * A helper class to parse a string of the possible forms "content" + * "[index]content", "[keyName=keyValue]content" and return the integer index, + * the strings keyName and keyValue, and the content after the square brackets + * (if present). Values not set will be -1 or null. + */ + protected class SubId + { + protected int index = 0; + + protected String keyName = null; + + protected String keyValue = null; + + protected String content = null; + + protected SubId(String item) + { + if (item.indexOf('[') == 0 && item.indexOf(']') > 1) + { + int openBracket = item.indexOf('['); + int closeBracket = item.indexOf(']'); + String indexString = item.substring(openBracket + 1, closeBracket); + this.content = item.substring(closeBracket + 1); + int equals = indexString.indexOf('='); + if (equals > -1) + { + this.keyName = indexString.substring(0, equals); + this.keyValue = indexString.substring(equals + 1); + this.index = -1; + } + else + { + try + { + this.index = Integer.parseInt(indexString); + } catch (NumberFormatException e) + { + Console.warn("Failed to obtain sequenced id or index from '" + + item + "'. Setting index=0 and using content='" + + content + "'."); + } + } + } + else + { + this.content = item; + } + } + } + + private void testMethod() + { + Desktop Jalview = Desktop.instance; + jalview.bin.Cache.setProperty("SVG_RENDERING", "Text"); + for (AlignFrame af : Jalview.getAlignFrames()) + { + String title = af.getTitle(); + System.out.println("Title: " + af.getTitle()); + AlignViewport view = af.getCurrentView(); + view.setShowText(false); + view.setShowAnnotation(false); + af.deselectAllSequenceMenuItem_actionPerformed(null); + af.repaint(); + af.createPNG(new File(title + ".png")); + af.createSVG(new File(title + ".svg")); + } + } } diff --git a/src/jalview/ws/dbsources/EBIAlfaFold.java b/src/jalview/ws/dbsources/EBIAlfaFold.java index 5314207..5575cb8 100644 --- a/src/jalview/ws/dbsources/EBIAlfaFold.java +++ b/src/jalview/ws/dbsources/EBIAlfaFold.java @@ -249,10 +249,11 @@ public class EBIAlfaFold extends EbiFileRetrievedProxy Console.debug("Downloading pae from " + paeURL + " to " + pae.toString() + ""); UrlDownloadClient.download(paeURL, pae); - addAlphaFoldPAE(pdbAlignment, pae); + addAlphaFoldPAE(pdbAlignment, pae, 0, null); } - public static void addAlphaFoldPAE(AlignmentI pdbAlignment, File pae) + public static void addAlphaFoldPAE(AlignmentI pdbAlignment, File pae, + int index, String seqId) { FileInputStream pae_input = null; try @@ -266,7 +267,8 @@ public class EBIAlfaFold extends EbiFileRetrievedProxy try { - if (!importPaeJSONAsContactMatrix(pdbAlignment, pae_input)) + if (!importPaeJSONAsContactMatrix(pdbAlignment, pae_input, index, + seqId)) { Console.warn("Could not import contact matrix from '" + pae.getAbsolutePath() + "'"); @@ -299,18 +301,61 @@ public class EBIAlfaFold extends EbiFileRetrievedProxy AlignmentI pdbAlignment, InputStream pae_input) throws IOException, ParseException { + return importPaeJSONAsContactMatrix(pdbAlignment, pae_input, 0, null); + } + + public static boolean importPaeJSONAsContactMatrix( + AlignmentI pdbAlignment, InputStream pae_input, int index, + String seqId) throws IOException, ParseException + { List pae_obj = (List) Platform.parseJSON(pae_input); if (pae_obj == null) { + Console.debug("JSON file did not parse properly."); return false; } - ContactMatrixI matrix = new PAEContactMatrix( - pdbAlignment.getSequenceAt(0), + SequenceI sequence = null; + /* debugging */ + SequenceI[] seqs = pdbAlignment.getSequencesArray(); + if (seqs == null) + Console.debug("******* sequences is null"); + else + { + for (int i = 0; i < seqs.length; i++) + { + SequenceI s = seqs[i]; + Console.debug("******* sequences[" + i + "]='" + s.getName() + "'"); + } + } + /* end debug */ + if (seqId == null) + { + int seqToGet = index > 0 ? index : 0; + sequence = pdbAlignment.getSequenceAt(seqToGet); + Console.debug("***** Got sequence at index " + seqToGet + ": " + + (sequence == null ? null : sequence.getName())); + } + else + { + Console.debug("***** Looking for sequence with id '" + seqId + "'"); + + SequenceI[] sequences = pdbAlignment.findSequenceMatch(seqId); + if (sequences == null || sequences.length < 1) + { + Console.warn("Could not find sequence with id '" + seqId + + "' to attach pAE matrix to. Ignoring matrix."); + return false; + } + else + { + sequence = sequences[0]; // just use the first sequence with this seqId + } + } + ContactMatrixI matrix = new PAEContactMatrix(sequence, (Map) pae_obj.get(0)); - AlignmentAnnotation cmannot = pdbAlignment.getSequenceAt(0) - .addContactList(matrix); + AlignmentAnnotation cmannot = sequence.addContactList(matrix); pdbAlignment.addAnnotation(cmannot); return true; } -- 1.7.10.2