Merge branch 'features/JAL-1333' into Release_2_8_2_Branch
[jalview.git] / src / jalview / ext / rbvi / chimera / ChimeraCommands.java
diff --git a/src/jalview/ext/rbvi/chimera/ChimeraCommands.java b/src/jalview/ext/rbvi/chimera/ChimeraCommands.java
new file mode 100644 (file)
index 0000000..d3c8c09
--- /dev/null
@@ -0,0 +1,158 @@
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer (Version 2.8.2)
+ * Copyright (C) 2014 The Jalview Authors
+ * 
+ * This file is part of Jalview.
+ * 
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License 
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *  
+ * Jalview is distributed in the hope that it will be useful, but 
+ * WITHOUT ANY WARRANTY; without even the implied warranty 
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
+ * PURPOSE.  See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
+package jalview.ext.rbvi.chimera;
+
+import jalview.api.FeatureRenderer;
+import jalview.api.SequenceRenderer;
+import jalview.api.structures.JalviewStructureDisplayI;
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.SequenceI;
+import jalview.structure.StructureMapping;
+import jalview.structure.StructureMappingcommandSet;
+import jalview.structure.StructureSelectionManager;
+import jalview.util.Format;
+
+import java.awt.Color;
+import java.util.ArrayList;
+import java.util.Hashtable;
+
+/**
+ * Routines for generating Chimera commands for Jalview/Chimera binding
+ * 
+ * @author JimP
+ * 
+ */
+public class ChimeraCommands
+{
+
+  /**
+   * utility to construct the commands to colour chains by the given alignment
+   * for passing to Chimera
+   * 
+   * @returns Object[] { Object[] { <model being coloured>,
+   * 
+   */
+  public static StructureMappingcommandSet[] getColourBySequenceCommand(
+          StructureSelectionManager ssm, String[] files,
+          SequenceI[][] sequence, SequenceRenderer sr, FeatureRenderer fr,
+          AlignmentI alignment)
+  {
+
+    ArrayList<StructureMappingcommandSet> cset = new ArrayList<StructureMappingcommandSet>();
+    Hashtable<String,StringBuffer> colranges=new Hashtable<String,StringBuffer>();
+    for (int pdbfnum = 0; pdbfnum < files.length; pdbfnum++)
+    {
+      float cols[] = new float[4];
+      StructureMapping[] mapping = ssm.getMapping(files[pdbfnum]);
+      StringBuffer command = new StringBuffer();
+      StructureMappingcommandSet smc;
+      ArrayList<String> str = new ArrayList<String>();
+
+      if (mapping == null || mapping.length < 1)
+        continue;
+
+      int startPos = -1, lastPos = -1, startModel = -1, lastModel = -1;
+      String startChain = "", lastChain = "";
+      Color lastCol = null;
+      for (int s = 0; s < sequence[pdbfnum].length; s++)
+      {
+        for (int sp, m = 0; m < mapping.length; m++)
+        {
+          if (mapping[m].getSequence() == sequence[pdbfnum][s]
+                  && (sp = alignment.findIndex(sequence[pdbfnum][s])) > -1)
+          {
+            SequenceI asp = alignment.getSequenceAt(sp);
+            for (int r = 0; r < asp.getLength(); r++)
+            {
+              // no mapping to gaps in sequence
+              if (jalview.util.Comparison.isGap(asp.getCharAt(r)))
+              {
+                continue;
+              }
+              int pos = mapping[m].getPDBResNum(asp.findPosition(r));
+
+              if (pos < 1 || pos == lastPos)
+                continue;
+
+              Color col = sr.getResidueBoxColour(sequence[pdbfnum][s], r);
+
+              if (fr != null)
+                col = fr.findFeatureColour(col, sequence[pdbfnum][s], r);
+              if (lastCol != col || lastPos + 1 != pos
+                      || pdbfnum != lastModel
+                      || !mapping[m].getChain().equals(lastChain))
+              {
+                if (lastCol != null)
+                {
+                  addColourRange(colranges, lastCol,startModel,startPos,lastPos,lastChain); 
+                }
+                lastCol = null;
+                startPos = pos;
+                startModel = pdbfnum;
+                startChain = mapping[m].getChain();
+              }
+              lastCol = col;
+              lastPos = pos;
+              lastModel = pdbfnum;
+              lastChain = mapping[m].getChain();
+            }
+            // final colour range
+            if (lastCol != null)
+            {
+              addColourRange(colranges, lastCol,startModel,startPos,lastPos,lastChain); 
+            }
+            break;
+          }
+        }
+      }
+      // Finally, add the command set ready to be returned.
+      StringBuffer coms=new StringBuffer();
+      for (String cr:colranges.keySet())
+      {
+        coms.append("color #"+cr+" "+colranges.get(cr)+";");
+      }
+      cset.add(new StructureMappingcommandSet(ChimeraCommands.class,
+              files[pdbfnum], new String[] { coms.toString() }));
+    }
+    return cset.toArray(new StructureMappingcommandSet[cset.size()]);
+  }
+
+  private static void addColourRange(Hashtable<String, StringBuffer> colranges, Color lastCol, int startModel,
+          int startPos, int lastPos, String lastChain)
+  {
+    
+    String colstring = ((lastCol.getRed()< 16) ? "0":"")+Integer.toHexString(lastCol.getRed())
+            + ((lastCol.getGreen()< 16) ? "0":"")+Integer.toHexString(lastCol.getGreen())
+            + ((lastCol.getBlue()< 16) ? "0":"")+Integer.toHexString(lastCol.getBlue());
+    StringBuffer currange = colranges.get(colstring);
+    if (currange==null)
+    {
+      colranges.put(colstring,currange = new StringBuffer());
+    }
+    if (currange.length()>0)
+    {
+      currange.append("|");
+    }
+    currange.append("#" + startModel + ":" + ((startPos==lastPos) ? startPos : startPos + "-"
+            + lastPos) + "." + lastChain);
+  }
+
+}