X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fjalview%2Fext%2Frbvi%2Fchimera%2FChimeraCommands.java;h=3caaac3532367e30f3f2d11003cbdb23c9560437;hb=6200addf078b7f7ace90597dc056dafc7fc602c1;hp=dad85117fb15622f90656836a1bc7fffcc0f31e4;hpb=4b1c969e87feaefd4fb9c49ba3d6b828b3ce1a9c;p=jalview.git diff --git a/src/jalview/ext/rbvi/chimera/ChimeraCommands.java b/src/jalview/ext/rbvi/chimera/ChimeraCommands.java index dad8511..3caaac3 100644 --- a/src/jalview/ext/rbvi/chimera/ChimeraCommands.java +++ b/src/jalview/ext/rbvi/chimera/ChimeraCommands.java @@ -26,8 +26,10 @@ import jalview.api.FeatureRenderer; import jalview.api.SequenceRenderer; import jalview.datamodel.AlignmentI; import jalview.datamodel.HiddenColumns; +import jalview.datamodel.MappedFeatures; import jalview.datamodel.SequenceFeature; import jalview.datamodel.SequenceI; +import jalview.gui.Desktop; import jalview.renderer.seqfeatures.FeatureColourFinder; import jalview.structure.StructureMapping; import jalview.structure.StructureMappingcommandSet; @@ -104,7 +106,7 @@ public class ChimeraCommands * delimited). If length limit issues arise, refactor to return one color * command per colour. */ - List commands = new ArrayList(); + List commands = new ArrayList<>(); StringBuilder sb = new StringBuilder(256); boolean firstColour = true; for (Object key : colourMap.keySet()) @@ -196,7 +198,7 @@ public class ChimeraCommands AlignViewportI viewport = viewPanel.getAlignViewport(); HiddenColumns cs = viewport.getAlignment().getHiddenColumns(); AlignmentI al = viewport.getAlignment(); - Map colourMap = new LinkedHashMap(); + Map colourMap = new LinkedHashMap<>(); Color lastColour = null; for (int pdbfnum = 0; pdbfnum < files.length; pdbfnum++) @@ -257,7 +259,7 @@ public class ChimeraCommands { if (startPos != -1) { - addColourRange(colourMap, lastColour, pdbfnum, startPos, + addAtomSpecRange(colourMap, lastColour, pdbfnum, startPos, lastPos, lastChain); } startPos = pos; @@ -269,7 +271,7 @@ public class ChimeraCommands // final colour range if (lastColour != null) { - addColourRange(colourMap, lastColour, pdbfnum, startPos, + addAtomSpecRange(colourMap, lastColour, pdbfnum, startPos, lastPos, lastChain); } // break; @@ -281,26 +283,32 @@ public class ChimeraCommands } /** - * Helper method to add one contiguous colour range to the colour map. + * 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' + * command
  • + *
* * @param map - * @param key + * @param value * @param model * @param startPos * @param endPos * @param chain */ - protected static void addColourRange(Map map, - Object key, int model, int startPos, int endPos, String chain) + protected static void addAtomSpecRange(Map map, + Object value, int model, int startPos, int endPos, String chain) { /* * Get/initialize map of data for the colour */ - AtomSpecModel atomSpec = map.get(key); + AtomSpecModel atomSpec = map.get(value); if (atomSpec == null) { atomSpec = new AtomSpecModel(); - map.put(key, atomSpec); + map.put(value, atomSpec); } atomSpec.addRange(model, startPos, endPos, chain); @@ -349,7 +357,7 @@ public class ChimeraCommands StructureSelectionManager ssm, String[] files, SequenceI[][] seqs, AlignmentViewPanel viewPanel) { - Map> theMap = new LinkedHashMap>(); + Map> theMap = new LinkedHashMap<>(); FeatureRenderer fr = viewPanel.getFeatureRenderer(); if (fr == null) @@ -357,8 +365,27 @@ public class ChimeraCommands return theMap; } + AlignViewportI viewport = viewPanel.getAlignViewport(); List visibleFeatures = fr.getDisplayedFeatureTypes(); - if (visibleFeatures.isEmpty()) + + /* + * if alignment is showing features from complement, we also transfer + * these features to the corresponding mapped structure residues + */ + boolean showLinkedFeatures = viewport.isShowComplementFeatures(); + List complementFeatures = new ArrayList<>(); + FeatureRenderer complementRenderer = null; + if (showLinkedFeatures) + { + AlignViewportI comp = fr.getViewport().getCodingComplement(); + if (comp != null) + { + complementRenderer = Desktop.getAlignFrameFor(comp) + .getFeatureRenderer(); + complementFeatures = complementRenderer.getDisplayedFeatureTypes(); + } + } + if (visibleFeatures.isEmpty() && complementFeatures.isEmpty()) { return theMap; } @@ -379,16 +406,23 @@ public class ChimeraCommands { final SequenceI seq = seqs[pdbfnum][seqNo]; int sp = alignment.findIndex(seq); - if (mapping[m].getSequence() == seq && sp > -1) + StructureMapping structureMapping = mapping[m]; + if (structureMapping.getSequence() == seq && sp > -1) { /* * found a sequence with a mapping to a structure; * now scan its features */ - SequenceI asp = alignment.getSequenceAt(sp); - - scanSequenceFeatures(visibleFeatures, mapping[m], asp, theMap, - pdbfnum); + if (!visibleFeatures.isEmpty()) + { + scanSequenceFeatures(visibleFeatures, structureMapping, seq, + theMap, pdbfnum); + } + if (showLinkedFeatures) + { + scanComplementFeatures(complementRenderer, structureMapping, + seq, theMap, pdbfnum); + } } } } @@ -397,9 +431,85 @@ public class ChimeraCommands } /** - * Inspect features on the sequence; for each feature that is visible, - * determine its mapped ranges in the structure (if any) according to the - * given mapping, and add them to the map + * 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 + * @param seq + * @param theMap + * @param modelNumber + */ + protected static void scanComplementFeatures( + FeatureRenderer complementRenderer, + StructureMapping structureMapping, SequenceI seq, + Map> theMap, int modelNumber) + { + /* + * for each sequence residue mapped to a structure position... + */ + for (int seqPos : structureMapping.getMapping().keySet()) + { + /* + * find visible complementary features at mapped position(s) + */ + MappedFeatures mf = complementRenderer + .findComplementFeaturesAtResidue(seq, seqPos); + if (mf != null) + { + for (SequenceFeature sf : mf.features) + { + String type = sf.getType(); + + /* + * Don't copy features which originated from Chimera + */ + if (JalviewChimeraBinding.CHIMERA_FEATURE_GROUP + .equals(sf.getFeatureGroup())) + { + 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(); + if (value == null || value.length() == 0) + { + value = type; + } + float score = sf.getScore(); + if (score != 0f && !Float.isNaN(score)) + { + value = Float.toString(score); + } + Map featureValues = theMap.get(type); + if (featureValues == null) + { + featureValues = new HashMap<>(); + theMap.put(type, featureValues); + } + for (int[] range : mappedRanges) + { + addAtomSpecRange(featureValues, value, modelNumber, range[0], + range[1], structureMapping.getChain()); + } + } + } + } + } + } + + /** + * Inspect features on the sequence; for each feature that is visible, determine + * its mapped ranges in the structure (if any) according to the given mapping, + * and add them to the map. * * @param visibleFeatures * @param mapping @@ -418,15 +528,14 @@ public class ChimeraCommands String type = sf.getType(); /* - * Only copy visible features, don't copy any which originated - * from Chimera, and suppress uninteresting ones (e.g. RESNUM) + * Don't copy features which originated from Chimera */ - boolean isFromViewer = JalviewChimeraBinding.CHIMERA_FEATURE_GROUP - .equals(sf.getFeatureGroup()); - if (isFromViewer) + if (JalviewChimeraBinding.CHIMERA_FEATURE_GROUP + .equals(sf.getFeatureGroup())) { continue; } + List mappedRanges = mapping.getPDBResNumRanges(sf.getBegin(), sf.getEnd()); @@ -445,12 +554,12 @@ public class ChimeraCommands Map featureValues = theMap.get(type); if (featureValues == null) { - featureValues = new HashMap(); + featureValues = new HashMap<>(); theMap.put(type, featureValues); } for (int[] range : mappedRanges) { - addColourRange(featureValues, value, modelNumber, range[0], + addAtomSpecRange(featureValues, value, modelNumber, range[0], range[1], mapping.getChain()); } } @@ -475,7 +584,7 @@ public class ChimeraCommands protected static List buildSetAttributeCommands( Map> featureMap) { - List commands = new ArrayList(); + List commands = new ArrayList<>(); for (String featureType : featureMap.keySet()) { String attributeName = makeAttributeName(featureType);