JAL-1620 version bump and release notes
[jalview.git] / src / jalview / ext / rbvi / chimera / ChimeraCommands.java
1 /*
2  * Jalview - A Sequence Alignment Editor and Viewer (Version 2.8.2b1)
3  * Copyright (C) 2014 The Jalview Authors
4  * 
5  * This file is part of Jalview.
6  * 
7  * Jalview is free software: you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License 
9  * as published by the Free Software Foundation, either version 3
10  * of the License, or (at your option) any later version.
11  *  
12  * Jalview is distributed in the hope that it will be useful, but 
13  * WITHOUT ANY WARRANTY; without even the implied warranty 
14  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
15  * PURPOSE.  See the GNU General Public License for more details.
16  * 
17  * You should have received a copy of the GNU General Public License
18  * along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
19  * The Jalview Authors are detailed in the 'AUTHORS' file.
20  */
21 package jalview.ext.rbvi.chimera;
22
23 import jalview.api.FeatureRenderer;
24 import jalview.api.SequenceRenderer;
25 import jalview.api.structures.JalviewStructureDisplayI;
26 import jalview.datamodel.AlignmentI;
27 import jalview.datamodel.SequenceI;
28 import jalview.structure.StructureMapping;
29 import jalview.structure.StructureMappingcommandSet;
30 import jalview.structure.StructureSelectionManager;
31 import jalview.util.Format;
32
33 import java.awt.Color;
34 import java.util.ArrayList;
35 import java.util.Hashtable;
36
37 /**
38  * Routines for generating Chimera commands for Jalview/Chimera binding
39  * 
40  * @author JimP
41  * 
42  */
43 public class ChimeraCommands
44 {
45
46   /**
47    * utility to construct the commands to colour chains by the given alignment
48    * for passing to Chimera
49    * 
50    * @returns Object[] { Object[] { <model being coloured>,
51    * 
52    */
53   public static StructureMappingcommandSet[] getColourBySequenceCommand(
54           StructureSelectionManager ssm, String[] files,
55           SequenceI[][] sequence, SequenceRenderer sr, FeatureRenderer fr,
56           AlignmentI alignment)
57   {
58
59     ArrayList<StructureMappingcommandSet> cset = new ArrayList<StructureMappingcommandSet>();
60     Hashtable<String,StringBuffer> colranges=new Hashtable<String,StringBuffer>();
61     for (int pdbfnum = 0; pdbfnum < files.length; pdbfnum++)
62     {
63       float cols[] = new float[4];
64       StructureMapping[] mapping = ssm.getMapping(files[pdbfnum]);
65       StringBuffer command = new StringBuffer();
66       StructureMappingcommandSet smc;
67       ArrayList<String> str = new ArrayList<String>();
68
69       if (mapping == null || mapping.length < 1)
70         continue;
71
72       int startPos = -1, lastPos = -1, startModel = -1, lastModel = -1;
73       String startChain = "", lastChain = "";
74       Color lastCol = null;
75       for (int s = 0; s < sequence[pdbfnum].length; s++)
76       {
77         for (int sp, m = 0; m < mapping.length; m++)
78         {
79           if (mapping[m].getSequence() == sequence[pdbfnum][s]
80                   && (sp = alignment.findIndex(sequence[pdbfnum][s])) > -1)
81           {
82             SequenceI asp = alignment.getSequenceAt(sp);
83             for (int r = 0; r < asp.getLength(); r++)
84             {
85               // no mapping to gaps in sequence
86               if (jalview.util.Comparison.isGap(asp.getCharAt(r)))
87               {
88                 continue;
89               }
90               int pos = mapping[m].getPDBResNum(asp.findPosition(r));
91
92               if (pos < 1 || pos == lastPos)
93                 continue;
94
95               Color col = sr.getResidueBoxColour(sequence[pdbfnum][s], r);
96
97               if (fr != null)
98                 col = fr.findFeatureColour(col, sequence[pdbfnum][s], r);
99               if (lastCol != col || lastPos + 1 != pos
100                       || pdbfnum != lastModel
101                       || !mapping[m].getChain().equals(lastChain))
102               {
103                 if (lastCol != null)
104                 {
105                   addColourRange(colranges, lastCol,startModel,startPos,lastPos,lastChain); 
106                 }
107                 lastCol = null;
108                 startPos = pos;
109                 startModel = pdbfnum;
110                 startChain = mapping[m].getChain();
111               }
112               lastCol = col;
113               lastPos = pos;
114               lastModel = pdbfnum;
115               lastChain = mapping[m].getChain();
116             }
117             // final colour range
118             if (lastCol != null)
119             {
120               addColourRange(colranges, lastCol,startModel,startPos,lastPos,lastChain); 
121             }
122             break;
123           }
124         }
125       }
126       // Finally, add the command set ready to be returned.
127       StringBuffer coms=new StringBuffer();
128       for (String cr:colranges.keySet())
129       {
130         coms.append("color #"+cr+" "+colranges.get(cr)+";");
131       }
132       cset.add(new StructureMappingcommandSet(ChimeraCommands.class,
133               files[pdbfnum], new String[] { coms.toString() }));
134     }
135     return cset.toArray(new StructureMappingcommandSet[cset.size()]);
136   }
137
138   private static void addColourRange(Hashtable<String, StringBuffer> colranges, Color lastCol, int startModel,
139           int startPos, int lastPos, String lastChain)
140   {
141     
142     String colstring = ((lastCol.getRed()< 16) ? "0":"")+Integer.toHexString(lastCol.getRed())
143             + ((lastCol.getGreen()< 16) ? "0":"")+Integer.toHexString(lastCol.getGreen())
144             + ((lastCol.getBlue()< 16) ? "0":"")+Integer.toHexString(lastCol.getBlue());
145     StringBuffer currange = colranges.get(colstring);
146     if (currange==null)
147     {
148       colranges.put(colstring,currange = new StringBuffer());
149     }
150     if (currange.length()>0)
151     {
152       currange.append("|");
153     }
154     currange.append("#" + startModel + ":" + ((startPos==lastPos) ? startPos : startPos + "-"
155             + lastPos) + "." + lastChain);
156   }
157
158 }