From a0ac724dba7d556966b546d4a0093449c397be84 Mon Sep 17 00:00:00 2001 From: Ben Soares Date: Sat, 25 Mar 2023 01:05:19 +0000 Subject: [PATCH] JAL-629 improvements to argparser toString. Improvements to cli paeFile structure selection. Allow label subval for paefile --- examples/argfiles/test_fab41.txt | 13 +++---- src/jalview/bin/Commands.java | 40 +++++++++++++++---- src/jalview/bin/argparser/Arg.java | 41 ++++++++++---------- src/jalview/bin/argparser/ArgValue.java | 5 +++ src/jalview/bin/argparser/ArgValues.java | 19 ++++----- src/jalview/bin/argparser/SubVals.java | 12 ++++++ src/jalview/datamodel/ContactMatrix.java | 41 ++++++++++---------- src/jalview/datamodel/ContactMatrixI.java | 7 +++- .../datamodel/SeqDistanceContactMatrix.java | 1 + src/jalview/ext/jmol/JmolParser.java | 2 +- src/jalview/ws/dbsources/EBIAlfaFold.java | 34 ++++++++++------ 11 files changed, 135 insertions(+), 80 deletions(-) diff --git a/examples/argfiles/test_fab41.txt b/examples/argfiles/test_fab41.txt index a1db923..e6f7627 100644 --- a/examples/argfiles/test_fab41.txt +++ b/examples/argfiles/test_fab41.txt @@ -1,14 +1,13 @@ --open=./examples/test_fab41.result/sample.a2m ---colour=clustal +--colour=gecos:flower --structure=./examples/test_fab41.result/test_fab41_unrelaxed_rank_1_model_3.pdb ---paematrix=./examples/test_fab41.result/test_fab41_unrelaxed_rank_1_model_3_scores.json +--paematrix=[label=pAE R1-M3]./examples/test_fab41.result/test_fab41_unrelaxed_rank_1_model_3_scores.json --structure=./examples/test_fab41.result/test_fab41_unrelaxed_rank_2_model_4.pdb ---paematrix=./examples/test_fab41.result/test_fab41_unrelaxed_rank_2_model_4_scores.json +--paematrix=[label=pAE R2-M4]./examples/test_fab41.result/test_fab41_unrelaxed_rank_2_model_4_scores.json --structure=./examples/test_fab41.result/test_fab41_unrelaxed_rank_3_model_2.pdb ---paematrix=./examples/test_fab41.result/test_fab41_unrelaxed_rank_3_model_2_scores.json +--paematrix=[label=pAE R3-M2]./examples/test_fab41.result/test_fab41_unrelaxed_rank_3_model_2_scores.json --structure=./examples/test_fab41.result/test_fab41_unrelaxed_rank_4_model_5.pdb ---paematrix=./examples/test_fab41.result/test_fab41_unrelaxed_rank_4_model_5_scores.json +--paematrix=[label=pAE R4-M5]./examples/test_fab41.result/test_fab41_unrelaxed_rank_4_model_5_scores.json --structure=./examples/test_fab41.result/test_fab41_unrelaxed_rank_5_model_1.pdb ---paematrix=./examples/test_fab41.result/test_fab41_unrelaxed_rank_5_model_1_scores.json +--paematrix=[label=pAE R5-M1]./examples/test_fab41.result/test_fab41_unrelaxed_rank_5_model_1_scores.json --image=output1.html ---close diff --git a/src/jalview/bin/Commands.java b/src/jalview/bin/Commands.java index 24a3c22..67c0c64 100644 --- a/src/jalview/bin/Commands.java +++ b/src/jalview/bin/Commands.java @@ -16,6 +16,7 @@ import jalview.api.AlignmentViewPanel; import jalview.bin.argparser.Arg; import jalview.bin.argparser.ArgParser; import jalview.bin.argparser.ArgValue; +import jalview.bin.argparser.ArgValues; import jalview.bin.argparser.ArgValuesMap; import jalview.bin.argparser.SubVals; import jalview.datamodel.AlignmentAnnotation; @@ -489,6 +490,7 @@ public class Commands { String val = av.getValue(); SubVals subVals = ArgParser.getSubVals(val); + String paeLabel = subVals.get("label"); File paeFile = new File(subVals.getContent()); String paePath = null; try @@ -500,33 +502,57 @@ public class Commands Console.warn( "Problem with the PAE file path: '" + paePath + "'"); } - String structId = subVals.get("structid"); + String structid = null; + String structfile = null; + String seqid = null; if (subVals.notSet()) { - // take structid from pdbfilename + 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(); + } + } } - if (subVals.has("structfile")) + else if (subVals.has("structfile")) + { + structfile = subVals.get("structfile"); + } + else if (subVals.has("structid")) + { + structid = subVals.get("structid"); + } + if (structfile != null) { Console.info("***** Attaching paeFile '" + paePath + "' to " + "structfile=" + subVals.get("structfile")); EBIAlfaFold.addAlphaFoldPAE(af.getCurrentView().getAlignment(), paeFile, subVals.getIndex(), subVals.get("structfile"), - true, false); + true, false, paeLabel); } - else if (subVals.has("structid")) + else if (structid != null) { Console.info("***** Attaching paeFile '" + paePath + "' to " + "structid=" + subVals.get("structid")); EBIAlfaFold.addAlphaFoldPAE(af.getCurrentView().getAlignment(), paeFile, subVals.getIndex(), subVals.get("structid"), - true, true); + true, true, paeLabel); } else { Console.debug("***** Attaching paeFile '" + paePath + "' to sequence index " + subVals.getIndex()); EBIAlfaFold.addAlphaFoldPAE(af.getCurrentView().getAlignment(), - paeFile, subVals.getIndex(), null, false, false); + paeFile, subVals.getIndex(), null, false, false, + paeLabel); // required to readjust the height and position of the pAE // annotation } diff --git a/src/jalview/bin/argparser/Arg.java b/src/jalview/bin/argparser/Arg.java index 6b70ab7..a13acd2 100644 --- a/src/jalview/bin/argparser/Arg.java +++ b/src/jalview/bin/argparser/Arg.java @@ -1,6 +1,9 @@ package jalview.bin.argparser; +import java.util.Arrays; +import java.util.List; import java.util.Locale; +import java.util.stream.Collectors; public enum Arg { @@ -83,10 +86,11 @@ public enum Arg NPP.setOptions(Opt.UNARY, Opt.MULTI, Opt.NOACTION); SUBSTITUTIONS.setOptions(Opt.BOOLEAN, Opt.MULTI, Opt.NOACTION); NIL.setOptions(Opt.UNARY, Opt.LINKED, Opt.MULTI, Opt.NOACTION); - // BOOTSTRAP args are parsed before a full parse of arguments and - // so are accessible at an earlier stage to (e.g.) set debug log level, - // provide a props file (that might set log level), run headlessly, read - // an argfile instead of other args. + // Opt.BOOTSTRAP args are parsed (not linked with no SubVals so using a + // simplified parser, see jalview.bin.argparser.BootstrapArgs) + // before a full parse of arguments and so can be accessible at an earlier + // stage to (e.g.) set debug log level, provide a props file (that might set + // log level), run headlessly, read an argfile instead of other args. } private final String[] argNames; @@ -114,22 +118,19 @@ public enum Arg public String toLongString() { StringBuilder sb = new StringBuilder(); - sb.append("Arg: ").append(this.name()); - for (String name : getNames()) - { - sb.append(", '").append(name).append("'"); - } - sb.append("\nOptions: "); - boolean first = true; - for (Opt o : argOptions) - { - if (!first) - { - sb.append(", "); - } - sb.append(o.toString()); - first = false; - } + sb.append(this.getClass().getName()).append('.').append(this.name()); + sb.append('('); + if (getNames().length > 0) + sb.append('"'); + sb.append(String.join("\", \"", getNames())); + if (getNames().length > 0) + sb.append('"'); + sb.append(")\n"); + sb.append("\nOpt: "); + // map List to List for the String.join + List optList = Arrays.asList(argOptions).stream() + .map(opt -> opt.name()).collect(Collectors.toList()); + sb.append(String.join(", ", optList)); sb.append("\n"); return sb.toString(); } diff --git a/src/jalview/bin/argparser/ArgValue.java b/src/jalview/bin/argparser/ArgValue.java index be6227d..019e7c7 100644 --- a/src/jalview/bin/argparser/ArgValue.java +++ b/src/jalview/bin/argparser/ArgValue.java @@ -36,4 +36,9 @@ public class ArgValue { return id; } + + public SubVals getSubVals() + { + return ArgParser.getSubVals(getValue()); + } } \ No newline at end of file diff --git a/src/jalview/bin/argparser/ArgValues.java b/src/jalview/bin/argparser/ArgValues.java index 0be7768..2c71f63 100644 --- a/src/jalview/bin/argparser/ArgValues.java +++ b/src/jalview/bin/argparser/ArgValues.java @@ -4,13 +4,14 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.stream.Collectors; import jalview.bin.Console; import jalview.bin.argparser.Arg.Opt; public class ArgValues { - protected static final String ID = "id"; + public static final String ID = "id"; private Arg arg; @@ -85,16 +86,12 @@ public class ArgValues if (arg.hasOption(Opt.STRING)) { sb.append("Values:"); - boolean first = true; - for (ArgValue av : argValueList) - { - String v = av.getValue(); - if (!first) - sb.append(","); - sb.append("\n '"); - sb.append(v).append("'"); - first = false; - } + sb.append("'") + .append(String + .join("',\n '", + argValueList.stream().map(av -> av.getValue()) + .collect(Collectors.toList()))) + .append("'"); sb.append("\n"); } sb.append("Count: ").append(argCount).append("\n"); diff --git a/src/jalview/bin/argparser/SubVals.java b/src/jalview/bin/argparser/SubVals.java index 39b48d3..796c03d 100644 --- a/src/jalview/bin/argparser/SubVals.java +++ b/src/jalview/bin/argparser/SubVals.java @@ -98,4 +98,16 @@ public class SubVals { return content; } + + public String toString() + { + StringBuilder sb = new StringBuilder(); + if (subVals == null) + return ""; + for (Map.Entry m : subVals.entrySet()) + { + sb.append(m.getKey()).append('=').append(m.getValue()).append("\n"); + } + return sb.toString(); + } } \ No newline at end of file diff --git a/src/jalview/datamodel/ContactMatrix.java b/src/jalview/datamodel/ContactMatrix.java index f2e207c..25aefd3 100644 --- a/src/jalview/datamodel/ContactMatrix.java +++ b/src/jalview/datamodel/ContactMatrix.java @@ -1,9 +1,7 @@ package jalview.datamodel; -import java.math.BigInteger; import java.util.ArrayList; import java.util.List; -import java.util.Spliterator; import java.util.StringTokenizer; import jalview.bin.Console; @@ -175,17 +173,19 @@ public abstract class ContactMatrix implements ContactMatrixI public static String contactToFloatString(ContactMatrixI cm) { StringBuilder sb = new StringBuilder(); - for (int c=0;c0) { - sb.append('\t'); + for (int h = 0; h <= cl.getContactHeight(); h++) + { + if (sb.length() > 0) + { + sb.append('\t'); + } + sb.append(cl.getContactAt(h)); } - sb.append(cl.getContactAt(h)); - } } } return sb.toString(); @@ -195,29 +195,30 @@ public abstract class ContactMatrix implements ContactMatrixI int rows) { float[][] vals = new float[cols][rows]; - StringTokenizer tabsep = new StringTokenizer(values,""+'\t'); - int c=0,r=0; - + StringTokenizer tabsep = new StringTokenizer(values, "" + '\t'); + int c = 0, r = 0; + while (tabsep.hasMoreTokens()) { double elem = Double.valueOf(tabsep.nextToken()); - vals[c][r++]=(float) elem; - if (r>=vals[c].length) + vals[c][r++] = (float) elem; + if (r >= vals[c].length) { - r=0; + r = 0; c++; } - if (c>=vals.length) + if (c >= vals.length) { - + break; } } if (tabsep.hasMoreElements()) { - Console.warn("Ignoring additional elements for Float string to contact matrix parsing."); + Console.warn( + "Ignoring additional elements for Float string to contact matrix parsing."); } - + return vals; } } diff --git a/src/jalview/datamodel/ContactMatrixI.java b/src/jalview/datamodel/ContactMatrixI.java index 2367414..bac3abf 100644 --- a/src/jalview/datamodel/ContactMatrixI.java +++ b/src/jalview/datamodel/ContactMatrixI.java @@ -18,12 +18,15 @@ public interface ContactMatrixI String getAnnotLabel(); /** - * string indicating how the contactMatrix should be rendered - stored in calcId - * @return + * string indicating how the contactMatrix should be rendered - stored in + * calcId + * + * @return */ String getType(); int getWidth(); + int getHeight(); } diff --git a/src/jalview/datamodel/SeqDistanceContactMatrix.java b/src/jalview/datamodel/SeqDistanceContactMatrix.java index 731948b..e8424ea 100644 --- a/src/jalview/datamodel/SeqDistanceContactMatrix.java +++ b/src/jalview/datamodel/SeqDistanceContactMatrix.java @@ -9,6 +9,7 @@ package jalview.datamodel; public class SeqDistanceContactMatrix implements ContactMatrixI { private static final String SEQUENCE_DISTANCE = "SEQUENCE_DISTANCE"; + private int width = 0; public SeqDistanceContactMatrix(int width) diff --git a/src/jalview/ext/jmol/JmolParser.java b/src/jalview/ext/jmol/JmolParser.java index f0e477c..a276fb6 100644 --- a/src/jalview/ext/jmol/JmolParser.java +++ b/src/jalview/ext/jmol/JmolParser.java @@ -305,7 +305,7 @@ public class JmolParser extends StructureFile implements JmolStatusListener { Alignment al = new Alignment(prot.toArray(new SequenceI[0])); EBIAlfaFold.addAlphaFoldPAE(al, new File(this.getPAEMatrix()), 0, - null, false, false); + null, false, false, null); if (al.getAlignmentAnnotation() != null) { diff --git a/src/jalview/ws/dbsources/EBIAlfaFold.java b/src/jalview/ws/dbsources/EBIAlfaFold.java index 8592bd3..5165d04 100644 --- a/src/jalview/ws/dbsources/EBIAlfaFold.java +++ b/src/jalview/ws/dbsources/EBIAlfaFold.java @@ -294,11 +294,12 @@ public class EBIAlfaFold extends EbiFileRetrievedProxy AlignmentI pdbAlignment, String retrievalUrl) throws IOException { File pae = fetchAlphaFoldPAE(id, retrievalUrl); - addAlphaFoldPAE(pdbAlignment, pae, 0, null, false, false); + addAlphaFoldPAE(pdbAlignment, pae, 0, null, false, false, null); } public static void addAlphaFoldPAE(AlignmentI pdbAlignment, File pae, - int index, String id, boolean isStruct, boolean isStructId) + int index, String id, boolean isStruct, boolean isStructId, + String label) { FileInputStream paeInput = null; try @@ -318,7 +319,7 @@ public class EBIAlfaFold extends EbiFileRetrievedProxy if (ssm != null) { String structFilename = isStructId ? ssm.findFileForPDBId(id) : id; - addPAEToStructure(ssm, structFilename, pae); + addPAEToStructure(ssm, structFilename, pae, label); } } @@ -328,7 +329,7 @@ public class EBIAlfaFold extends EbiFileRetrievedProxy try { if (!importPaeJSONAsContactMatrixToSequence(pdbAlignment, paeInput, - index, id)) + index, id, label)) { Console.warn("Could not import contact matrix from '" + pae.getAbsolutePath() + "' to sequence."); @@ -347,7 +348,7 @@ public class EBIAlfaFold extends EbiFileRetrievedProxy } public static void addPAEToStructure(StructureSelectionManager ssm, - String structFilename, File pae) + String structFilename, File pae, String label) { FileInputStream paeInput = null; try @@ -370,7 +371,8 @@ public class EBIAlfaFold extends EbiFileRetrievedProxy try { - if (!importPaeJSONAsContactMatrixToStructure(smArray, paeInput)) + if (!importPaeJSONAsContactMatrixToStructure(smArray, paeInput, + label)) { Console.warn("Could not import contact matrix from '" + pae.getAbsolutePath() + "' to structure."); @@ -400,7 +402,7 @@ public class EBIAlfaFold extends EbiFileRetrievedProxy */ public static boolean importPaeJSONAsContactMatrixToSequence( AlignmentI pdbAlignment, InputStream pae_input, int index, - String seqId) throws IOException, ParseException + String seqId, String label) throws IOException, ParseException { SequenceI sequence = null; if (seqId == null) @@ -427,12 +429,13 @@ public class EBIAlfaFold extends EbiFileRetrievedProxy return false; } return importPaeJSONAsContactMatrixToSequence(pdbAlignment, pae_input, - sequence); + sequence, label); } public static boolean importPaeJSONAsContactMatrixToSequence( AlignmentI pdbAlignment, InputStream pae_input, - SequenceI sequence) throws IOException, ParseException + SequenceI sequence, String label) + throws IOException, ParseException { JSONObject paeDict = parseJSONtoPAEContactMatrix(pae_input); if (paeDict == null) @@ -444,6 +447,8 @@ public class EBIAlfaFold extends EbiFileRetrievedProxy (Map) paeDict); AlignmentAnnotation cmannot = sequence.addContactList(matrix); + if (label != null) + cmannot.label = label; pdbAlignment.addAnnotation(cmannot); return true; @@ -469,21 +474,21 @@ public class EBIAlfaFold extends EbiFileRetrievedProxy } public static boolean importPaeJSONAsContactMatrixToStructure( - StructureMapping[] smArray, InputStream paeInput) + StructureMapping[] smArray, InputStream paeInput, String label) throws IOException, ParseException { boolean someDone = false; for (StructureMapping sm : smArray) { boolean thisDone = importPaeJSONAsContactMatrixToStructure(sm, - paeInput); + paeInput, label); someDone |= thisDone; } return someDone; } public static boolean importPaeJSONAsContactMatrixToStructure( - StructureMapping sm, InputStream paeInput) + StructureMapping sm, InputStream paeInput, String label) throws IOException, ParseException { JSONObject pae_obj = parseJSONtoPAEContactMatrix(paeInput); @@ -497,6 +502,11 @@ public class EBIAlfaFold extends EbiFileRetrievedProxy (Map) pae_obj); AlignmentAnnotation cmannot = sm.getSequence().addContactList(matrix); + if (label != null) + { + Console.debug("Setting annotation label to '" + label + "'"); + cmannot.label = label; + } sm.getSequence().addAlignmentAnnotation(cmannot); return true; -- 1.7.10.2