2 * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3 * Copyright (C) $$Year-Rel$$ The Jalview Authors
5 * This file is part of Jalview.
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.
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.
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.
21 package jalview.ext.rbvi.chimera;
23 import static org.testng.Assert.assertEquals;
24 import static org.testng.Assert.assertTrue;
26 import jalview.structure.AtomSpecModel;
27 import jalview.structure.StructureCommandsI;
29 import java.awt.Color;
30 import java.util.HashMap;
31 import java.util.LinkedHashMap;
34 import org.testng.annotations.Test;
36 public class ChimeraXCommandsTest
38 @Test(groups = { "Functional" })
39 public void testColourByCharge()
41 String cmd = new ChimeraXCommands().colourByCharge();
43 "color white;color :ASP,GLU red;color :LYS,ARG blue;color :CYS yellow");
46 @Test(groups = { "Functional" })
47 public void testColourByChain()
49 String cmd = new ChimeraXCommands().colourByChain();
50 assertEquals(cmd, "rainbow chain");
53 @Test(groups = { "Functional" })
54 public void testFocusView()
56 String cmd = new ChimeraXCommands().focusView();
57 assertEquals(cmd, "view");
60 @Test(groups = { "Functional" })
61 public void testColourBySequence()
63 Map<Object, AtomSpecModel> map = new LinkedHashMap<>();
64 ChimeraCommands.addAtomSpecRange(map, Color.blue, 1, 2, 5, "A");
65 ChimeraCommands.addAtomSpecRange(map, Color.blue, 1, 7, 7, "B");
66 ChimeraCommands.addAtomSpecRange(map, Color.blue, 1, 9, 23, "A");
67 ChimeraCommands.addAtomSpecRange(map, Color.blue, 2, 1, 1, "A");
68 ChimeraCommands.addAtomSpecRange(map, Color.blue, 2, 4, 7, "B");
69 ChimeraCommands.addAtomSpecRange(map, Color.yellow, 2, 8, 8, "A");
70 ChimeraCommands.addAtomSpecRange(map, Color.yellow, 2, 3, 5, "A");
71 ChimeraCommands.addAtomSpecRange(map, Color.red, 1, 3, 5, "A");
72 ChimeraCommands.addAtomSpecRange(map, Color.red, 1, 6, 9, "A");
74 // Colours should appear in the Chimera command in the order in which
75 // they were added; within colour, by model, by chain, ranges in start order
76 String[] commands = new ChimeraXCommands().colourBySequence(map);
77 assertEquals(commands.length, 1);
80 "color #1/A:2-5,9-23/B:7|#2/A:1/B:4-7 #0000ff; color #2/A:3-5,8 #ffff00; color #1/A:3-9 #ff0000");
83 @Test(groups = { "Functional" })
84 public void testSetAttributes()
87 * make a map of { featureType, {featureValue, {residue range specification } } }
89 Map<String, Map<Object, AtomSpecModel>> featuresMap = new LinkedHashMap<>();
90 Map<Object, AtomSpecModel> featureValues = new HashMap<>();
93 * start with just one feature/value...
95 featuresMap.put("chain", featureValues);
96 ChimeraCommands.addAtomSpecRange(featureValues, "X", 0, 8, 20, "A");
98 ChimeraXCommands commandGenerator = new ChimeraXCommands();
99 String[] commands = commandGenerator.setAttributes(featuresMap);
100 assertEquals(commands.length, 1);
103 * feature name gets a jv_ namespace prefix
104 * feature value is quoted in case it contains spaces
106 assertEquals(commands[0],
107 "setattr #0/A:8-20 res jv_chain 'X' create true");
109 // add same feature value, overlapping range
110 ChimeraCommands.addAtomSpecRange(featureValues, "X", 0, 3, 9, "A");
111 // same feature value, contiguous range
112 ChimeraCommands.addAtomSpecRange(featureValues, "X", 0, 21, 25, "A");
113 commands = commandGenerator.setAttributes(featuresMap);
114 assertEquals(commands.length, 1);
115 assertEquals(commands[0],
116 "setattr #0/A:3-25 res jv_chain 'X' create true");
118 // same feature value and model, different chain
119 ChimeraCommands.addAtomSpecRange(featureValues, "X", 0, 21, 25, "B");
120 // same feature value and chain, different model
121 ChimeraCommands.addAtomSpecRange(featureValues, "X", 1, 26, 30, "A");
122 commands = commandGenerator.setAttributes(featuresMap);
123 assertEquals(commands.length, 1);
124 String expected1 = "setattr #0/A:3-25/B:21-25|#1/A:26-30 res jv_chain 'X' create true";
125 assertEquals(commands[0], expected1);
127 // same feature, different value
128 ChimeraCommands.addAtomSpecRange(featureValues, "Y", 0, 40, 50, "A");
129 commands = commandGenerator.setAttributes(featuresMap);
130 assertEquals(2, commands.length);
131 // commands are ordered by feature type but not by value
132 // so test for the expected command in either order
134 commands[0].equals(expected1) || commands[1].equals(expected1));
135 String expected2 = "setattr #0/A:40-50 res jv_chain 'Y' create true";
137 commands[0].equals(expected2) || commands[1].equals(expected2));
140 featureValues.clear();
141 featuresMap.put("side-chain binding!", featureValues);
142 ChimeraCommands.addAtomSpecRange(featureValues,
143 "<html>metal <a href=\"http:a.b.c/x\"> 'ion!", 0, 7, 15,
145 // feature names are sanitised to change non-alphanumeric to underscore
146 // feature values are sanitised to encode single quote characters
147 commands = commandGenerator.setAttributes(featuresMap);
148 String expected3 = "setattr #0/A:7-15 res jv_side_chain_binding_ '<html>metal <a href=\"http:a.b.c/x\"> 'ion!' create true";
150 commands[0].equals(expected3) || commands[1].equals(expected3));
153 @Test(groups = { "Functional" })
154 public void testSuperposeStructures()
156 StructureCommandsI testee = new ChimeraXCommands();
157 AtomSpecModel ref = new AtomSpecModel();
158 ref.addRange(1, 12, 14, "A");
159 ref.addRange(1, 18, 18, "B");
160 ref.addRange(1, 22, 23, "B");
161 AtomSpecModel toAlign = new AtomSpecModel();
162 toAlign.addRange(2, 15, 17, "B");
163 toAlign.addRange(2, 20, 21, "B");
164 toAlign.addRange(2, 22, 22, "C");
165 String command = testee.superposeStructures(ref, toAlign);
166 String refSpec = "#1/A:12-14/B:18,22-23";
167 String toAlignSpec = "#2/B:15-17,20-21/C:22";
170 * superposition arguments include AlphaCarbon restriction,
171 * ribbon command does not
173 String expected = String.format(
174 "align %s@CA|P toAtoms %s@CA|P; ribbon %s|%s; view",
175 refSpec, toAlignSpec, refSpec, toAlignSpec);
176 assertEquals(command, expected);
179 @Test(groups = "Functional")
180 public void testGetAtomSpec()
182 StructureCommandsI testee = new ChimeraXCommands();
183 AtomSpecModel model = new AtomSpecModel();
184 assertEquals(testee.getAtomSpec(model, false), "");
185 model.addRange(1, 2, 4, "A");
186 assertEquals(testee.getAtomSpec(model, false), "#1/A:2-4");
187 model.addRange(1, 8, 8, "A");
188 assertEquals(testee.getAtomSpec(model, false), "#1/A:2-4,8");
189 model.addRange(1, 5, 7, "B");
190 assertEquals(testee.getAtomSpec(model, false), "#1/A:2-4,8/B:5-7");
191 model.addRange(1, 3, 5, "A");
192 assertEquals(testee.getAtomSpec(model, false), "#1/A:2-5,8/B:5-7");
193 model.addRange(0, 1, 4, "B");
194 assertEquals(testee.getAtomSpec(model, false),
195 "#0/B:1-4|#1/A:2-5,8/B:5-7");
196 model.addRange(0, 5, 9, "C");
197 assertEquals(testee.getAtomSpec(model, false),
198 "#0/B:1-4/C:5-9|#1/A:2-5,8/B:5-7");
199 model.addRange(1, 8, 10, "B");
200 assertEquals(testee.getAtomSpec(model, false),
201 "#0/B:1-4/C:5-9|#1/A:2-5,8/B:5-10");
202 model.addRange(1, 8, 9, "B");
203 assertEquals(testee.getAtomSpec(model, false),
204 "#0/B:1-4/C:5-9|#1/A:2-5,8/B:5-10");
205 model.addRange(0, 3, 10, "C"); // subsumes 5-9
206 assertEquals(testee.getAtomSpec(model, false),
207 "#0/B:1-4/C:3-10|#1/A:2-5,8/B:5-10");
208 model.addRange(5, 25, 35, " ");
209 assertEquals(testee.getAtomSpec(model, false),
210 "#0/B:1-4/C:3-10|#1/A:2-5,8/B:5-10|#5/:25-35");
213 @Test(groups = "Functional")
214 public void testGetAtomSpec_alphaOnly()
216 StructureCommandsI testee = new ChimeraXCommands();
217 AtomSpecModel model = new AtomSpecModel();
218 assertEquals(testee.getAtomSpec(model, true), "");
219 model.addRange(1, 2, 4, "A");
220 assertEquals(testee.getAtomSpec(model, true), "#1/A:2-4@CA|P");
221 model.addRange(1, 8, 8, "A");
222 assertEquals(testee.getAtomSpec(model, true), "#1/A:2-4,8@CA|P");
223 model.addRange(1, 5, 7, "B");
224 assertEquals(testee.getAtomSpec(model, true), "#1/A:2-4,8/B:5-7@CA|P");
225 model.addRange(1, 3, 5, "A");
226 assertEquals(testee.getAtomSpec(model, true), "#1/A:2-5,8/B:5-7@CA|P");
227 model.addRange(0, 1, 4, "B");
228 assertEquals(testee.getAtomSpec(model, true),
229 "#0/B:1-4@CA|P|#1/A:2-5,8/B:5-7@CA|P");
230 model.addRange(0, 5, 9, "C");
231 assertEquals(testee.getAtomSpec(model, true),
232 "#0/B:1-4/C:5-9@CA|P|#1/A:2-5,8/B:5-7@CA|P");
233 model.addRange(1, 8, 10, "B");
234 assertEquals(testee.getAtomSpec(model, true),
235 "#0/B:1-4/C:5-9@CA|P|#1/A:2-5,8/B:5-10@CA|P");
236 model.addRange(1, 8, 9, "B");
237 assertEquals(testee.getAtomSpec(model, true),
238 "#0/B:1-4/C:5-9@CA|P|#1/A:2-5,8/B:5-10@CA|P");
239 model.addRange(0, 3, 10, "C"); // subsumes 5-9
240 assertEquals(testee.getAtomSpec(model, true),
241 "#0/B:1-4/C:3-10@CA|P|#1/A:2-5,8/B:5-10@CA|P");
242 model.addRange(5, 25, 35, " "); // empty chain code
243 assertEquals(testee.getAtomSpec(model, true),
244 "#0/B:1-4/C:3-10@CA|P|#1/A:2-5,8/B:5-10@CA|P|#5/:25-35@CA|P");
247 @Test(groups = "Functional")
248 public void testGetModelStartNo()
250 StructureCommandsI testee = new ChimeraXCommands();
251 assertEquals(testee.getModelStartNo(), 1);
254 @Test(groups = "Functional")
255 public void testGetResidueSpec()
257 ChimeraCommands testee = new ChimeraXCommands();
258 assertEquals(testee.getResidueSpec("ALA"), ":ALA");
261 @Test(groups = "Functional")
262 public void testShowBackbone()
264 ChimeraCommands testee = new ChimeraXCommands();
265 assertEquals(testee.showBackbone(), "~display all;show @CA|P pbonds");
268 @Test(groups = "Functional")
269 public void testOpenCommandFile()
271 ChimeraCommands testee = new ChimeraXCommands();
272 assertEquals(testee.openCommandFile("nowhere"), "open nowhere");
275 @Test(groups = "Functional")
276 public void testSaveSession()
278 ChimeraCommands testee = new ChimeraXCommands();
279 assertEquals(testee.saveSession("somewhere"), "save session somewhere");
282 @Test(groups = "Functional")
283 public void testGetColourCommand()
285 ChimeraCommands testee = new ChimeraXCommands();
286 assertEquals(testee.getColourCommand("something", Color.MAGENTA),
287 "color something #ff00ff");
290 @Test(groups = "Functional")
291 public void testSetAttribute()
293 ChimeraCommands testee = new ChimeraXCommands();
294 AtomSpecModel model = new AtomSpecModel();
295 model.addRange(1, 89, 92, "A");
296 model.addRange(2, 12, 20, "B");
297 model.addRange(2, 8, 9, "B");
298 assertEquals(testee.setAttribute("phi", "27.3", model),
299 "setattr #1/A:89-92|#2/B:8-9,12-20 res phi '27.3' create true");