From 03968fce3d428957aced82b7f051527fa66e762f Mon Sep 17 00:00:00 2001 From: Ben Soares Date: Fri, 14 Apr 2023 18:14:23 +0100 Subject: [PATCH] JAL-629 Adding PAE and TFType at structure loading time. Display PAE automatically --- src/jalview/bin/Commands.java | 239 ++++++++++++++--------------- src/jalview/bin/argparser/ArgParser.java | 4 +- src/jalview/bin/argparser/SubVals.java | 5 + src/jalview/gui/StructureChooser.java | 53 ++++++- src/jalview/ws/dbsources/EBIAlfaFold.java | 9 +- 5 files changed, 174 insertions(+), 136 deletions(-) diff --git a/src/jalview/bin/Commands.java b/src/jalview/bin/Commands.java index 4a70bd9..5341874 100644 --- a/src/jalview/bin/Commands.java +++ b/src/jalview/bin/Commands.java @@ -14,7 +14,6 @@ import java.util.Map; import java.util.Map.Entry; import jalview.analysis.AlignmentUtils; -import jalview.api.AlignmentViewPanel; import jalview.bin.argparser.Arg; import jalview.bin.argparser.ArgParser; import jalview.bin.argparser.ArgValue; @@ -42,13 +41,11 @@ import jalview.io.FileLoader; import jalview.io.HtmlSvgOutput; import jalview.io.IdentifyFile; import jalview.schemes.AnnotationColourGradient; -import jalview.structure.StructureImportSettings; import jalview.structure.StructureImportSettings.TFType; import jalview.structure.StructureSelectionManager; import jalview.util.HttpUtils; import jalview.util.MessageManager; import jalview.util.Platform; -import jalview.ws.dbsources.EBIAlfaFold; import mc_view.PDBChain; public class Commands @@ -245,44 +242,10 @@ public class Commands * ssm.setProcessSecondaryStructure(showSecondaryStructure); } */ - // get kind of temperature factor annotation - StructureImportSettings.TFType tempfacType = TFType.DEFAULT; - if ((!avm.getBoolean(Arg.NOTEMPFAC)) - && avm.containsArg(Arg.TEMPFAC)) - { - try - { - tempfacType = StructureImportSettings.TFType - .valueOf(avm.getArgValue(Arg.TEMPFAC).getValue() - .toUpperCase(Locale.ROOT)); - Console.debug("Obtained Temperature Factor type of '" - + tempfacType + "'"); - } catch (IllegalArgumentException e) - { - // Just an error message! - StringBuilder sb = new StringBuilder().append("Cannot set ") - .append(Arg.TEMPFAC.argString()).append(" to '") - .append(tempfacType) - .append("', ignoring. Valid values are: "); - Iterator it = Arrays - .stream(StructureImportSettings.TFType.values()) - .iterator(); - while (it.hasNext()) - { - sb.append(it.next().toString().toLowerCase(Locale.ROOT)); - if (it.hasNext()) - sb.append(", "); - } - Console.warn(sb.toString()); - } - } - Console.debug( "Opening '" + openFile + "' in new alignment frame"); FileLoader fileLoader = new FileLoader(!headless); - StructureImportSettings.setTemperatureFactorType(tempfacType); - af = fileLoader.LoadFileWaitTillLoaded(openFile, protocol, format); @@ -399,8 +362,8 @@ public class Commands for (ArgValue av : avm.getArgValueList(Arg.STRUCTURE)) { String val = av.getValue(); - SubVals subId = av.getSubVals(); - SequenceI seq = getSpecifiedSequence(af, subId); + SubVals subVals = av.getSubVals(); + SequenceI seq = getSpecifiedSequence(af, subVals); if (seq == null) { // Could not find sequence from subId, let's assume the first @@ -418,10 +381,10 @@ public class Commands continue; } File structureFile = null; - if (subId.getContent() != null - && subId.getContent().length() != 0) + if (subVals.getContent() != null + && subVals.getContent().length() != 0) { - structureFile = new File(subId.getContent()); + structureFile = new File(subVals.getContent()); Console.debug("Using structure file (from argument) '" + structureFile.getAbsolutePath() + "'"); } @@ -473,102 +436,71 @@ public class Commands StructureViewer.ViewerType.JMOL.toString()); } - // get tft, paeFilename, label? - /* - * ArgValue tftAv = avm.getArgValuesReferringTo("structid", structId, - * Arg.TEMPFAC); - */ - StructureChooser.openStructureFileForSequence(null, null, ap, seq, - false, structureFile.getAbsolutePath(), null, null); // tft, - // paeFilename); - } - } - } + String structureFilepath = structureFile.getAbsolutePath(); - // load a PAE file if given - if (avm.containsArg(Arg.PAEMATRIX)) - { - AlignFrame af = afMap.get(id); - if (af != null) - { - for (ArgValue av : avm.getArgValueList(Arg.PAEMATRIX)) - { - String val = av.getValue(); - SubVals subVals = av.getSubVals(); - String paeLabel = subVals.get("label"); - File paeFile = new File(subVals.getContent()); - String paePath = null; - try + // get PAEMATRIX file and label from subvals or Arg.PAEMATRIX + String paeFilepath = subVals.getWithSubstitutions(argParser, id, + "paematrix"); + String paeLabel = subVals.get("paelabel"); + ArgValue paeAv = getArgAssociatedWithStructure(Arg.PAEMATRIX, avm, + af, structureFilepath); + if (paeFilepath == null && paeAv != null) { - paePath = paeFile.getCanonicalPath(); - } catch (IOException e) + SubVals sv = paeAv.getSubVals(); + File paeFile = new File(sv.getContent()); + + paeLabel = sv.get("label"); + try + { + paeFilepath = paeFile.getCanonicalPath(); + } catch (IOException e) + { + paeFilepath = paeFile.getAbsolutePath(); + Console.warn("Problem with the PAE file path: '" + + paeFile.getPath() + "'"); + } + } + + // get TEMPFAC type from subvals or Arg.TEMPFAC + 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) { - paePath = paeFile.getAbsolutePath(); - Console.warn( - "Problem with the PAE file path: '" + paePath + "'"); + tftString = tftAv.getSubVals().getContent(); } - String structid = subVals.get("structid"); - String structfile = subVals.get("structfile"); - String seqid = subVals.get("seqid"); - int seqindex = subVals.getIndex(); - - // let's find a structure - if (structfile == null && structid == null && seqid == null - && seqindex == SubVals.NOTSET) + if (tftString != null) { - ArgValue likelyStructure = avm - .getClosestPreviousArgValueOfArg(av, Arg.STRUCTURE); - if (likelyStructure != null) + // get kind of temperature factor annotation + try { - SubVals sv = likelyStructure.getSubVals(); - if (sv != null && sv.has(ArgValues.ID)) - { - structid = sv.get(ArgValues.ID); - } - else + tft = TFType.valueOf(tftString.toUpperCase(Locale.ROOT)); + Console.debug("Obtained Temperature Factor type of '" + tft + + "' for structure '" + structureFilepath + "'"); + } catch (IllegalArgumentException e) + { + // Just an error message! + StringBuilder sb = new StringBuilder().append("Cannot set ") + .append(Arg.TEMPFAC.argString()).append(" to '") + .append(tft) + .append("', ignoring. Valid values are: "); + Iterator it = Arrays.stream(TFType.values()) + .iterator(); + while (it.hasNext()) { - structfile = likelyStructure.getValue(); - Console.debug( - "##### Using closest previous structure argument '" - + structfile + "'"); + sb.append(it.next().toString().toLowerCase(Locale.ROOT)); + if (it.hasNext()) + sb.append(", "); } + Console.warn(sb.toString()); } } - if (structfile != null) - { - Console.debug("##### Attaching paeFile '" + paePath + "' to " - + "structfile=" + structfile); - EBIAlfaFold.addAlphaFoldPAE(af.getCurrentView().getAlignment(), - paeFile, seqindex, structfile, true, false, paeLabel); - } - else if (structid != null) - { - Console.debug("##### Attaching paeFile '" + paePath + "' to " - + "structid=" + structid); - EBIAlfaFold.addAlphaFoldPAE(af.getCurrentView().getAlignment(), - paeFile, seqindex, structid, true, true, paeLabel); - } - else if (seqid != null) - { - Console.debug("##### Attaching paeFile '" + paePath + "' to " - + "seqid=" + seqid); - EBIAlfaFold.addAlphaFoldPAE(af.getCurrentView().getAlignment(), - paeFile, seqindex, seqid, false, false, paeLabel); - } - else if (seqindex >= 0) - { - Console.debug("##### Attaching paeFile '" + paePath - + "' to sequence index " + seqindex); - EBIAlfaFold.addAlphaFoldPAE(af.getCurrentView().getAlignment(), - paeFile, seqindex, null, false, false, paeLabel); - } - for (AlignmentViewPanel ap : af.getAlignPanels()) - { - // required to readjust the height and position of the PAE - // annotation - ap.adjustAnnotationHeight(); - } + // TODO pass PAE label + StructureChooser.openStructureFileForSequence(null, null, ap, seq, + false, structureFilepath, tft, paeFilepath); } } } @@ -670,4 +602,57 @@ public class Commands } return null; } + + // returns the first Arg value intended for the structure structFilename + // (in the given AlignFrame from the ArgValuesMap) + private ArgValue getArgAssociatedWithStructure(Arg arg, ArgValuesMap avm, + AlignFrame af, String structFilename) + { + if (af != null) + { + for (ArgValue av : avm.getArgValueList(arg)) + { + SubVals subVals = av.getSubVals(); + String structid = subVals.get("structid"); + String structfile = subVals.get("structfile"); + + // let's find a structure + if (structfile == null && structid == null) + { + ArgValue likelyStructure = avm.getClosestPreviousArgValueOfArg(av, + Arg.STRUCTURE); + if (likelyStructure != null) + { + SubVals sv = likelyStructure.getSubVals(); + if (sv != null && sv.has(ArgValues.ID)) + { + structid = sv.get(ArgValues.ID); + } + else + { + structfile = likelyStructure.getValue(); + Console.debug( + "##### Comparing closest previous structure argument '" + + structfile + "'"); + } + } + } + + if (structfile == null && structid != null) + { + StructureSelectionManager ssm = StructureSelectionManager + .getStructureSelectionManager(Desktop.instance); + if (ssm != null) + { + structfile = ssm.findFileForPDBId(structid); + } + } + if (structfile != null && structfile.equals(structFilename)) + { + return av; + } + } + } + return null; + } } diff --git a/src/jalview/bin/argparser/ArgParser.java b/src/jalview/bin/argparser/ArgParser.java index 5f0cad6..0ff1845 100644 --- a/src/jalview/bin/argparser/ArgParser.java +++ b/src/jalview/bin/argparser/ArgParser.java @@ -480,9 +480,9 @@ public class ArgParser } } - private String makeSubstitutions(String val, String linkedId) + public String makeSubstitutions(String val, String linkedId) { - if (!this.substitutions) + if (!this.substitutions || val == null) return val; String subvals; diff --git a/src/jalview/bin/argparser/SubVals.java b/src/jalview/bin/argparser/SubVals.java index 6708cf9..196cd24 100644 --- a/src/jalview/bin/argparser/SubVals.java +++ b/src/jalview/bin/argparser/SubVals.java @@ -104,6 +104,11 @@ public class SubVals return index == NOTSET && (subValMap == null || subValMap.size() == 0); } + public String getWithSubstitutions(ArgParser ap, String id, String key) + { + return ap.makeSubstitutions(subValMap.get(key), id); + } + public String get(String key) { return subValMap.get(key); diff --git a/src/jalview/gui/StructureChooser.java b/src/jalview/gui/StructureChooser.java index 3fce931..fc73c27 100644 --- a/src/jalview/gui/StructureChooser.java +++ b/src/jalview/gui/StructureChooser.java @@ -28,9 +28,11 @@ import java.io.File; import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; +import java.util.LinkedHashMap; import java.util.LinkedHashSet; import java.util.List; import java.util.Locale; +import java.util.Map; import java.util.concurrent.Callable; import java.util.concurrent.Executors; @@ -45,11 +47,16 @@ import javax.swing.table.AbstractTableModel; import com.stevesoft.pat.Regex; +import jalview.analysis.AlignmentUtils; +import jalview.api.AlignmentViewPanel; import jalview.api.structures.JalviewStructureDisplayI; import jalview.bin.Cache; import jalview.bin.Console; import jalview.bin.Jalview; +import jalview.datamodel.AlignmentAnnotation; +import jalview.datamodel.AlignmentI; import jalview.datamodel.PDBEntry; +import jalview.datamodel.SequenceGroup; import jalview.datamodel.SequenceI; import jalview.ext.jmol.JmolParser; import jalview.fts.api.FTSData; @@ -1711,10 +1718,21 @@ public class StructureChooser extends GStructureChooser AlignmentPanel ap, SequenceI seq, boolean prompt, String sFilename, TFType tft, String paeFilename) { - boolean headless = false; + openStructureFileForSequence(ssm, sc, ap, seq, prompt, sFilename, tft, + paeFilename, false, true); + } + + public static void openStructureFileForSequence( + StructureSelectionManager ssm, StructureChooser sc, + AlignmentPanel ap, SequenceI seq, boolean prompt, + String sFilename, TFType tft, String paeFilename, + boolean forceHeadless, boolean showAnnotations) + { + boolean headless = forceHeadless; if (sc == null) { headless = true; + prompt = false; sc = new StructureChooser(new SequenceI[] { seq }, seq, ap, false); } if (ssm == null) @@ -1724,11 +1742,38 @@ public class StructureChooser extends GStructureChooser sFilename, DataSourceType.FILE, seq, prompt, Desktop.instance, tft, paeFilename); - StructureViewer sViewer = sc.launchStructureViewer(ssm, - new PDBEntry[] - { fileEntry }, ap, new SequenceI[] { seq }); + // if headless, "false" in the sc constructor above will avoid GUI behaviour + // in sc.launchStructureViewer() + sc.launchStructureViewer(ssm, new PDBEntry[] { fileEntry }, ap, + new SequenceI[] + { seq }); if (headless) sc.mainFrame.dispose(); + + if (showAnnotations) + showReferenceAnnotationsForSequence(ap.alignFrame, seq); + } + + public static void showReferenceAnnotationsForSequence(AlignFrame af, + SequenceI sequence) + { + AlignViewport av = af.getCurrentView(); + AlignmentI al = av.getAlignment(); + + List forSequences = new ArrayList<>(); + forSequences.add(sequence); + final Map> candidates = new LinkedHashMap<>(); + AlignmentUtils.findAddableReferenceAnnotations(forSequences, null, + candidates, al); + final SequenceGroup selectionGroup = av.getSelectionGroup(); + AlignmentUtils.addReferenceAnnotations(candidates, al, selectionGroup); + for (AlignmentViewPanel ap : af.getAlignPanels()) + { + // required to readjust the height and position of the PAE + // annotation + ap.adjustAnnotationHeight(); + } + } } diff --git a/src/jalview/ws/dbsources/EBIAlfaFold.java b/src/jalview/ws/dbsources/EBIAlfaFold.java index d0538c1..8044717 100644 --- a/src/jalview/ws/dbsources/EBIAlfaFold.java +++ b/src/jalview/ws/dbsources/EBIAlfaFold.java @@ -314,6 +314,8 @@ public class EBIAlfaFold extends EbiFileRetrievedProxy if (isStruct) { + // ###### WRITE A TEST for this bit of the logic addAlphaFoldPAE with + // different params. StructureSelectionManager ssm = StructureSelectionManager .getStructureSelectionManager(Desktop.instance); if (ssm != null) @@ -474,6 +476,7 @@ public class EBIAlfaFold extends EbiFileRetrievedProxy return paeDict; } + // ###### TEST THIS public static boolean importPaeJSONAsContactMatrixToStructure( StructureMapping[] smArray, InputStream paeInput, String label) throws IOException, ParseException @@ -505,9 +508,9 @@ public class EBIAlfaFold extends EbiFileRetrievedProxy (Map) pae_obj); ((PAEContactMatrix) matrix).makeGroups(5f, true); AlignmentAnnotation cmannot = seq.addContactList(matrix); - seq.addAlignmentAnnotation(cmannot); - // seq.addAlignmentAnnotation(cmannot); - + /* this already happens in Sequence.addContactList() + seq.addAlignmentAnnotation(cmannot); + */ return true; } -- 1.7.10.2