JAL-1333 more abstraction and refactoring and working demo of Jalview talking to...
[jalview.git] / src / jalview / ext / rbvi / chimera / ChimeraCommands.java
1 /*
2  * Jalview - A Sequence Alignment Editor and Viewer (Version 2.8.2)
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
36 /**
37  * Routines for generating Chimera commands for Jalview/Chimera binding
38  * 
39  * @author JimP
40  * 
41  */
42 public class ChimeraCommands
43 {
44
45   /**
46    * utility to construct the commands to colour chains by the given alignment
47    * for passing to Chimera
48    * 
49    * @returns Object[] { Object[] { <model being coloured>,
50    * 
51    */
52   public static StructureMappingcommandSet[] getColourBySequenceCommand(
53           StructureSelectionManager ssm, String[] files,
54           SequenceI[][] sequence, SequenceRenderer sr, FeatureRenderer fr,
55           AlignmentI alignment)
56   {
57
58     ArrayList<StructureMappingcommandSet> cset = new ArrayList<StructureMappingcommandSet>();
59
60     for (int pdbfnum = 0; pdbfnum < files.length; pdbfnum++)
61     {
62       float cols[] = new float[4];
63       StructureMapping[] mapping = ssm.getMapping(files[pdbfnum]);
64       StringBuffer command = new StringBuffer();
65       StructureMappingcommandSet smc;
66       ArrayList<String> str = new ArrayList<String>();
67
68       if (mapping == null || mapping.length < 1)
69         continue;
70
71       int startPos = -1, lastPos = -1, startModel = -1, lastModel = -1;
72       String startChain = "", lastChain = "";
73       Color lastCol = null;
74       for (int s = 0; s < sequence[pdbfnum].length; s++)
75       {
76         for (int sp, m = 0; m < mapping.length; m++)
77         {
78           if (mapping[m].getSequence() == sequence[pdbfnum][s]
79                   && (sp = alignment.findIndex(sequence[pdbfnum][s])) > -1)
80           {
81             SequenceI asp = alignment.getSequenceAt(sp);
82             for (int r = 0; r < asp.getLength(); r++)
83             {
84               // no mapping to gaps in sequence
85               if (jalview.util.Comparison.isGap(asp.getCharAt(r)))
86               {
87                 continue;
88               }
89               int pos = mapping[m].getPDBResNum(asp.findPosition(r));
90
91               if (pos < 1 || pos == lastPos)
92                 continue;
93
94               Color col = sr.getResidueBoxColour(sequence[pdbfnum][s], r);
95
96               if (fr != null)
97                 col = fr.findFeatureColour(col, sequence[pdbfnum][s], r);
98               if (lastCol != col || lastPos + 1 != pos
99                       || pdbfnum != lastModel
100                       || !mapping[m].getChain().equals(lastChain))
101               {
102                 if (lastCol != null)
103                 {
104
105                   lastCol.getRGBComponents(cols);
106                   String newSelcom = "color " + cols[0] + "," + cols[1]
107                           + "," + cols[2] + " #" + startModel + ":"
108                           + startPos + "-" + lastPos + "." + lastChain;
109                   if (str.size() > 0
110                           && (str.get(str.size() - 1).length() + newSelcom
111                                   .length()) < 4096)
112                   {
113                     str.set(str.size() - 1, str.get(str.size() - 1) + ";"
114                             + newSelcom);
115                   }
116                   else
117                   {
118                     str.add(newSelcom);
119                   }
120                 }
121                 lastCol = null;
122                 startPos = pos;
123                 startModel = pdbfnum;
124                 startChain = mapping[m].getChain();
125               }
126               lastCol = col;
127               lastPos = pos;
128               lastModel = pdbfnum;
129               lastChain = mapping[m].getChain();
130             }
131             // final colour range
132             if (lastCol != null)
133             {
134
135               lastCol.getRGBComponents(cols);
136               String newSelcom = "color " + cols[0] + "," + cols[1] + ","
137                       + cols[2] + " #" + startModel + ":" + startPos + "-"
138                       + lastPos + "." + lastChain;
139               if (str.size() > 0
140                       && (str.get(str.size() - 1).length() + newSelcom
141                               .length()) < 4096)
142               {
143                 str.set(str.size() - 1, str.get(str.size() - 1) + ";"
144                         + newSelcom);
145               }
146               else
147               {
148                 str.add(newSelcom);
149               }
150             }
151             break;
152           }
153         }
154       }
155       // Finally, add the command set ready to be returned.
156       cset.add(new StructureMappingcommandSet(ChimeraCommands.class,
157               files[pdbfnum], str.toArray(new String[str.size()])));
158     }
159     return cset.toArray(new StructureMappingcommandSet[cset.size()]);
160   }
161
162 }