Merge branch 'develop' into features/JAL-2295setChimeraAttributes
authorgmungoc <g.m.carstairs@dundee.ac.uk>
Mon, 7 Nov 2016 15:58:24 +0000 (15:58 +0000)
committergmungoc <g.m.carstairs@dundee.ac.uk>
Mon, 7 Nov 2016 15:58:24 +0000 (15:58 +0000)
resources/lang/Messages.properties
src/jalview/ext/rbvi/chimera/ChimeraCommands.java
src/jalview/ext/rbvi/chimera/JalviewChimeraBinding.java
src/jalview/gui/ChimeraViewFrame.java
src/jalview/gui/JalviewChimeraBindingModel.java

index 49a0456..1262536 100644 (file)
@@ -714,6 +714,8 @@ label.colour_with_chimera = Colour with Chimera
 label.align_structures = Align Structures
 label.jmol = Jmol
 label.chimera = Chimera
+label.create_chimera_attributes = Write Jalview features
+label.create_chimera_attributes_tip = Set Chimera residue attributes for visible features
 label.sort_alignment_by_tree = Sort Alignment By Tree
 label.mark_unlinked_leaves = Mark Unlinked Leaves
 label.associate_leaves_with = Associate Leaves With
index a551ca2..bece4eb 100644 (file)
@@ -75,15 +75,17 @@ public class ChimeraCommands
    * 'color' commands (one per distinct colour used). The format of each command
    * is
    * 
+   * <pre>
    * <blockquote> color colorname #modelnumber:range.chain e.g. color #00ff00
    * #0:2.B,4.B,9-12.B|#1:1.A,2-6.A,...
-   * 
-   * @see http 
-   *      ://www.cgl.ucsf.edu/chimera/current/docs/UsersGuide/midas/frameatom_spec
-   *      .html </pre>
+   * </blockquote>
+   * </pre>
    * 
    * @param colourMap
    * @return
+   * @see http
+   *      ://www.cgl.ucsf.edu/chimera/current/docs/UsersGuide/midas/frameatom_spec
+   *      .html
    */
   protected static List<String> buildColourCommands(
           Map<Color, Map<Integer, Map<String, List<int[]>>>> colourMap)
index 7ba9186..2534421 100644 (file)
@@ -27,14 +27,17 @@ import jalview.bin.Cache;
 import jalview.datamodel.AlignmentI;
 import jalview.datamodel.ColumnSelection;
 import jalview.datamodel.PDBEntry;
+import jalview.datamodel.SequenceFeature;
 import jalview.datamodel.SequenceI;
 import jalview.httpserver.AbstractRequestHandler;
 import jalview.schemes.ColourSchemeI;
 import jalview.schemes.ResidueProperties;
 import jalview.structure.AtomSpec;
+import jalview.structure.StructureMapping;
 import jalview.structure.StructureMappingcommandSet;
 import jalview.structure.StructureSelectionManager;
 import jalview.structures.models.AAStructureBindingModel;
+import jalview.util.Comparison;
 import jalview.util.MessageManager;
 
 import java.awt.Color;
@@ -1125,4 +1128,87 @@ public abstract class JalviewChimeraBinding extends AAStructureBindingModel
       sm.highlightStructure(this, seq, positions);
     }
   }
+
+  /**
+   * Constructs and send commands to Chimera to set attributes on residues for
+   * features visible in Jalview
+   * 
+   * @param avp
+   */
+  public void sendFeaturesToChimera(AlignmentViewPanel avp)
+  {
+    // TODO send a command per feature with the range of residues it applies to
+    AlignmentI alignment = avp.getAlignment();
+    FeatureRenderer fr = getFeatureRenderer(avp);
+
+    /*
+     * fr is null if feature display is turned off
+     */
+    if (fr == null)
+    {
+      return;
+    }
+
+    String[] files = getPdbFile();
+    if (files == null)
+    {
+      return;
+    }
+    for (int pdbfnum = 0; pdbfnum < files.length; pdbfnum++)
+    {
+      StructureMapping[] mapping = getSsm().getMapping(files[pdbfnum]);
+
+      if (mapping == null || mapping.length < 1)
+      {
+        continue;
+      }
+
+      int lastPos = -1;
+      for (int seqNo = 0; seqNo < getSequence()[pdbfnum].length; seqNo++)
+      {
+        for (int m = 0; m < mapping.length; m++)
+        {
+          final SequenceI seq = getSequence()[pdbfnum][seqNo];
+          int sp = alignment.findIndex(seq);
+          if (mapping[m].getSequence() == seq && sp > -1)
+          {
+            SequenceI asp = alignment.getSequenceAt(sp);
+            for (int r = 0; r < asp.getLength(); r++)
+            {
+              // no mapping to gaps in sequence
+              if (Comparison.isGap(asp.getCharAt(r)))
+              {
+                continue;
+              }
+              int residuePos = asp.findPosition(r);
+              int pos = mapping[m].getPDBResNum(residuePos);
+
+              if (pos < 1 || pos == lastPos)
+              {
+                continue;
+              }
+              final String chain = mapping[m].getChain();
+              List<SequenceFeature> features = fr.findFeaturesAtRes(asp,
+                      residuePos);
+              for (SequenceFeature feature : features)
+              {
+                String desc = feature.getDescription();
+                float score = feature.getScore();
+                if (score != 0 && score != Float.NaN)
+                {
+                  desc = Float.toString(score);
+                }
+                String attName = "jv:"
+                        + feature.getType().replace(" ", "_");
+                String cmd = "setattr r " + attName + " \""
+                        + desc + "\" #" + pdbfnum + ":" + pos + "." + chain;
+                System.out.println(cmd);
+                sendAsynchronousCommand(cmd, null);
+              }
+            }
+          }
+        }
+      }
+    }
+  }
 }
index ce719d0..ae3ff9e 100644 (file)
@@ -181,6 +181,31 @@ public class ChimeraViewFrame extends StructureViewerBase
         // TODO Auto-generated method stub
       }
     });
+    JMenuItem writeFeatures = new JMenuItem(
+            MessageManager.getString("label.create_chimera_attributes"));
+    writeFeatures.setToolTipText(MessageManager
+            .getString("label.create_chimera_attributes_tip"));
+    writeFeatures.addActionListener(new ActionListener()
+    {
+      @Override
+      public void actionPerformed(ActionEvent e)
+      {
+        sendFeaturesToChimera();
+      }
+    });
+    viewerActionMenu.add(writeFeatures);
+  }
+
+  /**
+   * Send a command to Chimera to create residue attributes for Jalview features
+   * <p>
+   * The syntax is: setattr r <attName> <attValue> <atomSpec>
+   * <p>
+   * For example: setattr r jv:chain "Ferredoxin-1, Chloroplastic" #0:94.A
+   */
+  protected void sendFeaturesToChimera()
+  {
+    jmb.sendFeaturesToChimera(getAlignmentPanel());
   }
 
   /**
@@ -1040,10 +1065,10 @@ public class ChimeraViewFrame extends StructureViewerBase
     setChainMenuItems(jmb.getChainNames());
 
     this.setTitle(jmb.getViewerTitle("Chimera", true));
-    if (jmb.getPdbFile().length > 1 && jmb.getSequence().length > 1)
-    {
+    // if (jmb.getPdbFile().length > 1 && jmb.getSequence().length > 1)
+    // {
       viewerActionMenu.setVisible(true);
-    }
+    // }
     if (!jmb.isLoadingFromArchive())
     {
       seqColour_actionPerformed(null);
index 7a54732..ec30e7f 100644 (file)
@@ -72,6 +72,7 @@ public class JalviewChimeraBindingModel extends JalviewChimeraBinding
   {
     javax.swing.SwingUtilities.invokeLater(new Runnable()
     {
+      @Override
       public void run()
       {
         cvf.updateTitleAndMenus();
@@ -80,6 +81,7 @@ public class JalviewChimeraBindingModel extends JalviewChimeraBinding
     });
   }
 
+  @Override
   public void updateColours(Object source)
   {
     AlignmentPanel ap = (AlignmentPanel) source;
@@ -113,6 +115,7 @@ public class JalviewChimeraBindingModel extends JalviewChimeraBinding
    * Send an asynchronous command to Chimera, in a new thread, optionally with
    * an 'in progress' message in a progress bar somewhere
    */
+  @Override
   protected void sendAsynchronousCommand(final String command,
           final String progressMsg)
   {
@@ -122,13 +125,20 @@ public class JalviewChimeraBindingModel extends JalviewChimeraBinding
       @Override
       public void run()
       {
-        long stm = cvf.startProgressBar(progressMsg);
+        long handle = 0;
+        if (progressMsg != null)
+        {
+          handle = cvf.startProgressBar(progressMsg);
+        }
         try
         {
           sendChimeraCommand(command, false);
         } finally
         {
-          cvf.stopProgressBar(null, stm);
+          if (progressMsg != null)
+          {
+            cvf.stopProgressBar(null, handle);
+          }
         }
       }
     });