X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fjalview%2Fstructures%2Fmodels%2FAAStructureBindingModel.java;h=1afa15e7673a9a992a60d268311aef9e7d533b84;hb=7c41e0253551a494219c4f1133a1aa2fe591b97a;hp=05cfd5ad168d3535874e992c2641189ce935c8ab;hpb=2fb924ec0d110eb3ca6c3fb06efa27acd34b2750;p=jalview.git diff --git a/src/jalview/structures/models/AAStructureBindingModel.java b/src/jalview/structures/models/AAStructureBindingModel.java index 05cfd5a..1afa15e 100644 --- a/src/jalview/structures/models/AAStructureBindingModel.java +++ b/src/jalview/structures/models/AAStructureBindingModel.java @@ -47,6 +47,7 @@ import jalview.datamodel.PDBEntry; import jalview.datamodel.SequenceFeature; import jalview.datamodel.SequenceI; import jalview.ext.rbvi.chimera.JalviewChimeraBinding; +import jalview.gui.AlignmentPanel; import jalview.gui.Desktop; import jalview.gui.StructureViewer.ViewerType; import jalview.io.DataSourceType; @@ -56,6 +57,7 @@ import jalview.schemes.ColourSchemeI; import jalview.schemes.ResidueProperties; import jalview.structure.AtomSpec; import jalview.structure.AtomSpecModel; +import jalview.structure.StructureCommand; import jalview.structure.StructureCommandI; import jalview.structure.StructureCommandsI; import jalview.structure.StructureListener; @@ -83,20 +85,20 @@ public abstract class AAStructureBindingModel public static class SuperposeData { public String filename; - + public String pdbId; - + public String chain = ""; - + public boolean isRna; - + /* * The pdb residue number (if any) mapped to columns of the alignment */ public int[] pdbResNo; // or use SparseIntArray? - + public String modelId; - + /** * Constructor * @@ -262,6 +264,7 @@ public abstract class AAStructureBindingModel chains = newchains; return chainmaps > 0; } + public StructureSelectionManager getSsm() { return ssm; @@ -659,7 +662,8 @@ public abstract class AAStructureBindingModel * @return */ protected int findSuperposableResidues(AlignmentI alignment, - BitSet matched, AAStructureBindingModel.SuperposeData[] structures) + BitSet matched, + AAStructureBindingModel.SuperposeData[] structures) { int refStructure = -1; String[] files = getStructureFiles(); @@ -885,8 +889,8 @@ public abstract class AAStructureBindingModel * Calculate the superposable alignment columns ('matched'), and the * corresponding structure residue positions (structures.pdbResNo) */ - int refStructure = findSuperposableResidues(alignment, - matched, structures); + int refStructure = findSuperposableResidues(alignment, matched, + structures); /* * require at least 4 positions to be able to execute superposition @@ -894,8 +898,8 @@ public abstract class AAStructureBindingModel int nmatched = matched.cardinality(); if (nmatched < MIN_POS_TO_SUPERPOSE) { - String msg = MessageManager.formatMessage("label.insufficient_residues", - nmatched); + String msg = MessageManager + .formatMessage("label.insufficient_residues", nmatched); error += view.getViewName() + ": " + msg + "; "; continue; } @@ -939,7 +943,8 @@ public abstract class AAStructureBindingModel return error; } - private AtomSpecModel getAtomSpec(AAStructureBindingModel.SuperposeData superposeData, + private AtomSpecModel getAtomSpec( + AAStructureBindingModel.SuperposeData superposeData, BitSet matched) { AtomSpecModel model = new AtomSpecModel(); @@ -1008,7 +1013,7 @@ public abstract class AAStructureBindingModel { return; } - + /* * build a map of {Residue3LetterCode, Color} */ @@ -1053,16 +1058,16 @@ public abstract class AAStructureBindingModel private List executeCommand(StructureCommandI cmd, boolean getReply, String msg) { + final JalviewStructureDisplayI theViewer = getViewer(); + final long handle = msg == null ? 0 : theViewer.startProgressBar(msg); if (getReply) { /* * synchronous (same thread) execution so reply can be returned */ - final JalviewStructureDisplayI theViewer = getViewer(); - final long handle = msg == null ? 0 : theViewer.startProgressBar(msg); try { - return executeCommand(cmd, getReply); + return executeCommand(cmd, true); } finally { if (msg != null) @@ -1076,9 +1081,6 @@ public abstract class AAStructureBindingModel /* * asynchronous (new thread) execution if no reply needed */ - final JalviewStructureDisplayI theViewer = getViewer(); - final long handle = msg == null ? 0 : theViewer.startProgressBar(msg); - SwingUtilities.invokeLater(new Runnable() { @Override @@ -1111,8 +1113,7 @@ public abstract class AAStructureBindingModel boolean getReply); /** - * Executes one or more structure viewer commands. If a progress message is - * provided, it is shown first, and removed after all commands have been run. + * Executes one or more structure viewer commands * * @param commands * @param getReply @@ -1121,31 +1122,16 @@ public abstract class AAStructureBindingModel protected List executeCommands(List commands, boolean getReply, String msg) { - /* - * show progress message if specified - */ - final JalviewStructureDisplayI theViewer = getViewer(); - final long handle = msg == null ? 0 : theViewer.startProgressBar(msg); - List response = getReply ? new ArrayList<>() : null; - try - { - for (StructureCommandI cmd : commands) - { - List replies = executeCommand(cmd, getReply, null); - if (getReply && replies != null) - { - response.addAll(replies); - } - } - return response; - } finally + for (StructureCommandI cmd : commands) { - if (msg != null) + List replies = executeCommand(cmd, getReply, msg); + if (replies != null) { - theViewer.stopProgressBar(null, handle); + response.addAll(replies); } } + return response; } /** @@ -1163,7 +1149,7 @@ public abstract class AAStructureBindingModel List colourBySequenceCommands = commandGenerator .colourBySequence(colourMap); - executeCommands(colourBySequenceCommands, false, null); + executeCommands(colourBySequenceCommands, false, COLOURING_STRUCTURES); } /** @@ -1356,17 +1342,17 @@ public abstract class AAStructureBindingModel AlignmentI al = viewport.getAlignment(); Map colourMap = new LinkedHashMap<>(); Color lastColour = null; - + for (int pdbfnum = 0; pdbfnum < files.length; pdbfnum++) { final String modelId = getModelIdForFile(files[pdbfnum]); StructureMapping[] mapping = ssm.getMapping(files[pdbfnum]); - + if (mapping == null || mapping.length < 1) { continue; } - + int startPos = -1, lastPos = -1; String lastChain = ""; for (int s = 0; s < sequence[pdbfnum].length; s++) @@ -1386,14 +1372,14 @@ public abstract class AAStructureBindingModel continue; } int pos = mapping[m].getPDBResNum(asp.findPosition(r)); - + if (pos < 1 || pos == lastPos) { continue; } - + Color colour = sr.getResidueColour(seq, r, finder); - + /* * darker colour for hidden regions */ @@ -1401,9 +1387,9 @@ public abstract class AAStructureBindingModel { colour = Color.GRAY; } - + final String chain = mapping[m].getChain(); - + /* * Just keep incrementing the end position for this colour range * _unless_ colour, PDB model or chain has changed, or there is a @@ -1416,8 +1402,8 @@ public abstract class AAStructureBindingModel { if (startPos != -1) { - addAtomSpecRange(colourMap, lastColour, modelId, - startPos, lastPos, lastChain); + addAtomSpecRange(colourMap, lastColour, modelId, startPos, + lastPos, lastChain); } startPos = pos; } @@ -1469,8 +1455,9 @@ public abstract class AAStructureBindingModel } /** - * Helper method to add one contiguous range to the AtomSpec model for the given - * value (creating the model if necessary). As used by Jalview, {@code value} is + * Helper method to add one contiguous range to the AtomSpec model for the + * given value (creating the model if necessary). As used by Jalview, + * {@code value} is *
    *
  • a colour, when building a 'colour structure by sequence' command
  • *
  • a feature value, when building a 'set Chimera attributes from features' @@ -1485,8 +1472,8 @@ public abstract class AAStructureBindingModel * @param chain */ public static final void addAtomSpecRange(Map map, - Object value, - String model, int startPos, int endPos, String chain) + Object value, String model, int startPos, int endPos, + String chain) { /* * Get/initialize map of data for the colour @@ -1497,7 +1484,7 @@ public abstract class AAStructureBindingModel atomSpec = new AtomSpecModel(); map.put(value, atomSpec); } - + atomSpec.addRange(model, startPos, endPos, chain); } @@ -1530,8 +1517,8 @@ public abstract class AAStructureBindingModel saveSession(f); } catch (IOException e) { - Cache.log.error(String.format("Error saving %s session: %s", - prefix, e.toString())); + Cache.log.error(String.format("Error saving %s session: %s", prefix, + e.toString())); } return f; @@ -1544,8 +1531,7 @@ public abstract class AAStructureBindingModel */ protected void saveSession(File f) { - StructureCommandI cmd = commandGenerator - .saveSession(f.getPath()); + StructureCommandI cmd = commandGenerator.saveSession(f.getPath()); if (cmd != null) { executeCommand(cmd, false); @@ -1585,6 +1571,8 @@ public abstract class AAStructureBindingModel externalViewerMonitor = null; } + stopListening(); + if (forceClose) { StructureCommandI cmd = getCommandGenerator().closeViewer(); @@ -1630,10 +1618,10 @@ public abstract class AAStructureBindingModel { return theMap; } - + AlignViewportI viewport = viewPanel.getAlignViewport(); List visibleFeatures = fr.getDisplayedFeatureTypes(); - + /* * if alignment is showing features from complement, we also transfer * these features to the corresponding mapped structure residues @@ -1655,7 +1643,7 @@ public abstract class AAStructureBindingModel { return theMap; } - + AlignmentI alignment = viewPanel.getAlignment(); SequenceI[][] seqs = getSequence(); @@ -1663,12 +1651,12 @@ public abstract class AAStructureBindingModel { String modelId = getModelIdForFile(files[pdbfnum]); StructureMapping[] mapping = ssm.getMapping(files[pdbfnum]); - + if (mapping == null || mapping.length < 1) { continue; } - + for (int seqNo = 0; seqNo < seqs[pdbfnum].length; seqNo++) { for (int m = 0; m < mapping.length; m++) @@ -1719,8 +1707,8 @@ public abstract class AAStructureBindingModel } /** - * Scans visible features in mapped positions of the CDS/peptide complement, and - * adds any found to the map of attribute values/structure positions + * Scans visible features in mapped positions of the CDS/peptide complement, + * and adds any found to the map of attribute values/structure positions * * @param complementRenderer * @param structureMapping @@ -1749,7 +1737,7 @@ public abstract class AAStructureBindingModel for (SequenceFeature sf : mf.features) { String type = sf.getType(); - + /* * Don't copy features which originated from Chimera */ @@ -1758,14 +1746,14 @@ public abstract class AAStructureBindingModel { continue; } - + /* * record feature 'value' (score/description/type) as at the * corresponding structure position */ List mappedRanges = structureMapping .getPDBResNumRanges(seqPos, seqPos); - + if (!mappedRanges.isEmpty()) { String value = sf.getDescription(); @@ -1815,7 +1803,7 @@ public abstract class AAStructureBindingModel for (SequenceFeature sf : sfs) { String type = sf.getType(); - + /* * Don't copy features which originated from Chimera */ @@ -1824,10 +1812,10 @@ public abstract class AAStructureBindingModel { continue; } - + List mappedRanges = mapping.getPDBResNumRanges(sf.getBegin(), sf.getEnd()); - + if (!mappedRanges.isEmpty()) { String value = sf.getDescription(); @@ -1880,7 +1868,7 @@ public abstract class AAStructureBindingModel { externalViewerMonitor = new Thread(new Runnable() { - + @Override public void run() { @@ -1900,4 +1888,82 @@ public abstract class AAStructureBindingModel }); externalViewerMonitor.start(); } + + /** + * If supported by the external structure viewer, sends it commands to notify + * model or selection changes to the specified URL (where Jalview has started + * a listener) + * + * @param uri + */ + protected void startListening(String uri) + { + List commands = getCommandGenerator() + .startNotifications(uri); + if (commands != null) + { + executeCommands(commands, false, null); + } + } + + /** + * If supported by the external structure viewer, sends it commands to stop + * notifying model or selection changes + */ + protected void stopListening() + { + List commands = getCommandGenerator() + .stopNotifications(); + if (commands != null) + { + executeCommands(commands, false, null); + } + } + + /** + * If supported by the structure viewer, queries it for all residue attributes + * with the given attribute name, and creates features on corresponding + * residues of the alignment. Returns the number of features added. + * + * @param attName + * @param alignmentPanel + * @return + */ + public int copyStructureAttributesToFeatures(String attName, + AlignmentPanel alignmentPanel) + { + StructureCommandI cmd = getCommandGenerator() + .getResidueAttributes(attName); + if (cmd == null) + { + return 0; + } + List residueAttributes = executeCommand(cmd, true); + + int featuresAdded = createFeaturesForAttributes(attName, + residueAttributes); + if (featuresAdded > 0) + { + alignmentPanel.getFeatureRenderer().featuresAdded(); + } + return featuresAdded; + } + + /** + * Parses {@code residueAttributes} and creates sequence features on any + * mapped alignment residues. Returns the number of features created. + *

    + * {@code residueAttributes} is the reply from the structure viewer to a + * command to list any residue attributes for the given attribute name. Syntax + * and parsing of this is viewer-specific. + * + * @param attName + * @param residueAttributes + * @return + */ + protected int createFeaturesForAttributes(String attName, + List residueAttributes) + { + return 0; + } }