8494b4b345e2102c6788e4fcfcaf0343c1180db2
[jalview.git] / src / jalview / ext / jmol / JmolCommands.java
1 /*
2  * Jalview - A Sequence Alignment Editor and Viewer (Version 2.8.0b1)
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 of the License, or (at your option) any later version.
10  *  
11  * Jalview is distributed in the hope that it will be useful, but 
12  * WITHOUT ANY WARRANTY; without even the implied warranty 
13  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
14  * PURPOSE.  See the GNU General Public License for more details.
15  * 
16  * You should have received a copy of the GNU General Public License along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
17  * The Jalview Authors are detailed in the 'AUTHORS' file.
18  */
19 package jalview.ext.jmol;
20
21 import jalview.api.FeatureRenderer;
22 import jalview.api.SequenceRenderer;
23 import jalview.datamodel.AlignmentI;
24 import jalview.datamodel.SequenceI;
25 import jalview.structure.StructureMapping;
26 import jalview.structure.StructureMappingcommandSet;
27 import jalview.structure.StructureSelectionManager;
28
29 import java.awt.Color;
30 import java.util.ArrayList;
31
32 /**
33  * Routines for generating Jmol commands for Jalview/Jmol binding another
34  * cruisecontrol test.
35  * 
36  * @author JimP
37  * 
38  */
39 public class JmolCommands
40 {
41
42   /**
43    * Jmol utility which constructs the commands to colour chains by the given
44    * alignment
45    * 
46    * @returns Object[] { Object[] { <model being coloured>,
47    * 
48    */
49   public static StructureMappingcommandSet[] getColourBySequenceCommand(
50           StructureSelectionManager ssm, String[] files,
51           SequenceI[][] sequence, SequenceRenderer sr, FeatureRenderer fr,
52           AlignmentI alignment)
53   {
54
55     ArrayList<StructureMappingcommandSet> cset = new ArrayList<StructureMappingcommandSet>();
56
57     for (int pdbfnum = 0; pdbfnum < files.length; pdbfnum++)
58     {
59       StructureMapping[] mapping = ssm.getMapping(files[pdbfnum]);
60       StringBuffer command = new StringBuffer();
61       StructureMappingcommandSet smc;
62       ArrayList<String> str = new ArrayList<String>();
63
64       if (mapping == null || mapping.length < 1)
65         continue;
66
67       int lastPos = -1;
68       for (int s = 0; s < sequence[pdbfnum].length; s++)
69       {
70         for (int sp, m = 0; m < mapping.length; m++)
71         {
72           if (mapping[m].getSequence() == sequence[pdbfnum][s]
73                   && (sp = alignment.findIndex(sequence[pdbfnum][s])) > -1)
74           {
75             SequenceI asp = alignment.getSequenceAt(sp);
76             for (int r = 0; r < asp.getLength(); r++)
77             {
78               // no mapping to gaps in sequence
79               if (jalview.util.Comparison.isGap(asp.getCharAt(r)))
80               {
81                 continue;
82               }
83               int pos = mapping[m].getPDBResNum(asp.findPosition(r));
84
85               if (pos < 1 || pos == lastPos)
86                 continue;
87
88               lastPos = pos;
89
90               Color col = sr.getResidueBoxColour(sequence[pdbfnum][s], r);
91
92               if (fr != null)
93                 col = fr.findFeatureColour(col, sequence[pdbfnum][s], r);
94               String newSelcom = (mapping[m].getChain() != " " ? ":"
95                       + mapping[m].getChain() : "")
96                       + "/"
97                       + (pdbfnum + 1)
98                       + ".1"
99                       + ";color["
100                       + col.getRed()
101                       + ","
102                       + col.getGreen()
103                       + ","
104                       + col.getBlue() + "]";
105               if (command.length() > newSelcom.length()
106                       && command.substring(
107                               command.length() - newSelcom.length())
108                               .equals(newSelcom))
109               {
110                 command = JmolCommands.condenseCommand(command, pos);
111                 continue;
112               }
113               // TODO: deal with case when buffer is too large for Jmol to parse
114               // - execute command and flush
115
116               command.append(";");
117               if (command.length() > 51200)
118               {
119                 // add another chunk
120                 str.add(command.toString());
121                 command.setLength(0);
122               }
123               command.append("select " + pos);
124               command.append(newSelcom);
125             }
126             break;
127           }
128         }
129       }
130       {
131         // add final chunk
132         str.add(command.toString());
133         command.setLength(0);
134       }
135       // Finally, add the command set ready to be returned.
136       cset.add(new StructureMappingcommandSet(JmolCommands.class,
137               files[pdbfnum], str.toArray(new String[str.size()])));
138
139     }
140     return cset.toArray(new StructureMappingcommandSet[cset.size()]);
141   }
142
143   public static StringBuffer condenseCommand(StringBuffer command, int pos)
144   {
145
146     // work back to last 'select'
147     int p = command.length(), q = p;
148     do
149     {
150       p -= 6;
151       if (p < 1)
152       {
153         p = 0;
154       }
155       ;
156     } while ((q = command.indexOf("select", p)) == -1 && p > 0);
157
158     StringBuffer sb = new StringBuffer(command.substring(0, q + 7));
159
160     command = command.delete(0, q + 7);
161
162     String start;
163
164     if (command.indexOf("-") > -1)
165     {
166       start = command.substring(0, command.indexOf("-"));
167     }
168     else
169     {
170       start = command.substring(0, command.indexOf(":"));
171     }
172
173     sb.append(start + "-" + pos + command.substring(command.indexOf(":")));
174
175     return sb;
176   }
177
178 }