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.structures.models;
23 import static org.testng.Assert.assertFalse;
24 import static org.testng.AssertJUnit.assertEquals;
25 import static org.testng.AssertJUnit.assertTrue;
27 import jalview.api.AlignmentViewPanel;
28 import jalview.api.FeatureRenderer;
29 import jalview.api.SequenceRenderer;
30 import jalview.datamodel.Alignment;
31 import jalview.datamodel.AlignmentI;
32 import jalview.datamodel.HiddenColumns;
33 import jalview.datamodel.PDBEntry;
34 import jalview.datamodel.PDBEntry.Type;
35 import jalview.datamodel.Sequence;
36 import jalview.datamodel.SequenceI;
37 import jalview.gui.JvOptionPane;
38 import jalview.io.DataSourceType;
39 import jalview.io.FileFormats;
40 import jalview.schemes.ColourSchemeI;
41 import jalview.structure.AtomSpec;
42 import jalview.structure.StructureSelectionManager;
43 import jalview.structures.models.AAStructureBindingModel.SuperposeData;
45 import java.awt.Color;
46 import java.io.IOException;
47 import java.util.Arrays;
48 import java.util.BitSet;
49 import java.util.List;
51 import org.testng.annotations.BeforeClass;
52 import org.testng.annotations.BeforeMethod;
53 import org.testng.annotations.Test;
56 * Unit tests for non-abstract methods of abstract base class
61 public class AAStructureBindingModelTest
64 @BeforeClass(alwaysRun = true)
65 public void setUpJvOptionPane()
67 JvOptionPane.setInteractiveMode(false);
68 JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
72 * Scenario: Jalview has 4 sequences, corresponding to 1YCS (chains A and B), 3A6S|B, 1OOT|A
74 private static final String PDB_1 = "HEADER COMPLEX (ANTI-ONCOGENE/ANKYRIN REPEATS) 30-SEP-96 1YCS \n"
75 + "ATOM 2 CA VAL A 97 24.134 4.926 45.821 1.00 47.43 C \n"
76 + "ATOM 9 CA PRO A 98 25.135 8.584 46.217 1.00 41.60 C \n"
77 + "ATOM 16 CA SER A 99 28.243 9.596 44.271 1.00 39.63 C \n"
78 + "ATOM 22 CA GLN A 100 31.488 10.133 46.156 1.00 35.60 C \n"
79 // artificial jump in residue numbering to prove it is correctly
81 + "ATOM 31 CA LYS A 102 33.323 11.587 43.115 1.00 41.69 C \n"
82 + "ATOM 1857 CA GLU B 374 9.193 -16.005 95.870 1.00 54.22 C \n"
83 + "ATOM 1866 CA ILE B 375 7.101 -14.921 92.847 1.00 46.82 C \n"
84 + "ATOM 1874 CA VAL B 376 10.251 -13.625 91.155 1.00 47.80 C \n"
85 + "ATOM 1881 CA LYS B 377 11.767 -17.068 91.763 1.00 50.21 C \n"
86 + "ATOM 1890 CA PHE B 378 8.665 -18.948 90.632 1.00 44.85 C \n";
88 private static final String PDB_2 = "HEADER HYDROLASE 09-SEP-09 3A6S \n"
89 + "ATOM 2 CA MET B 1 15.366 -11.648 24.854 1.00 32.05 C \n"
90 + "ATOM 10 CA LYS B 2 16.846 -9.215 22.340 1.00 25.68 C \n"
91 + "ATOM 19 CA LYS B 3 15.412 -6.335 20.343 1.00 19.42 C \n"
92 + "ATOM 28 CA LEU B 4 15.629 -5.719 16.616 1.00 15.49 C \n"
93 + "ATOM 36 CA GLN B 5 14.412 -2.295 15.567 1.00 12.19 C \n";
95 private static final String PDB_3 = "HEADER STRUCTURAL GENOMICS 04-MAR-03 1OOT \n"
96 + "ATOM 2 CA SER A 7 29.427 3.330 -6.578 1.00 32.50 C \n"
97 + "ATOM 8 CA PRO A 8 29.975 3.340 -2.797 1.00 17.62 C \n"
98 + "ATOM 16 CA ALYS A 9 26.958 3.024 -0.410 0.50 8.78 C \n"
99 + "ATOM 33 CA ALA A 10 26.790 4.320 3.172 1.00 11.98 C \n"
100 + "ATOM 39 CA AVAL A 12 24.424 3.853 6.106 0.50 13.83 C \n";
103 * Multichain PDB with identical sequences imported - Binding should correctly
104 * recover chain mappings for each derived sequence
106 private static final String PDB_4_MC = "HEADER HYDROLASE 09-SEP-09 3A6S \n"
107 + "ATOM 2 CA MET A 1 15.366 -11.648 24.854 1.00 32.05 C \n"
108 + "ATOM 10 CA LYS A 2 16.846 -9.215 22.340 1.00 25.68 C \n"
109 + "ATOM 19 CA LYS A 3 15.412 -6.335 20.343 1.00 19.42 C \n"
110 + "ATOM 28 CA LEU A 4 15.629 -5.719 16.616 1.00 15.49 C \n"
111 + "ATOM 36 CA GLN A 5 14.412 -2.295 15.567 1.00 12.19 C \n"
112 + "ATOM 1030 CA MET B 1 18.869 -7.572 3.432 1.00 31.52 C \n"
113 + "ATOM 1038 CA LYS B 2 19.182 -10.025 6.313 1.00 26.41 C \n"
114 + "ATOM 1047 CA LYS B 3 17.107 -12.963 7.534 1.00 19.71 C \n"
115 + "ATOM 1056 CA LEU B 4 16.142 -13.579 11.164 1.00 14.81 C \n"
116 + "ATOM 1064 CA GLN B 5 14.648 -17.005 11.785 1.00 13.38 C \n";
118 // TODO: JAL-2227 - import mmCIF PISA assembly & identify master/copy chains
120 @Test(groups= {"Functional"})
121 public void testImportPDBPreservesChainMappings() throws IOException
123 AlignmentI importedAl = new jalview.io.FormatAdapter().readFile(
124 PDB_4_MC, DataSourceType.PASTE, FileFormats.getInstance()
125 .forName(jalview.io.FileFormat.PDB.toString()));
126 // ideally, we would match on the actual data for the 'File' handle for
128 // see JAL-623 - pasting is still not correctly handled...
129 PDBEntry importedPDB = new PDBEntry("3A6S", "", Type.PDB,
131 AAStructureBindingModel binder = new AAStructureBindingModel(
132 new StructureSelectionManager(), new PDBEntry[]
135 { importedAl.getSequencesArray() }, null)
139 public void updateColours(Object source)
144 public void releaseReferences(Object svl)
149 public String[] getStructureFiles()
155 public String superposeStructures(AlignmentI[] alignments,
156 int[] structureIndices, HiddenColumns[] hiddenCols)
162 public void setJalviewColourScheme(ColourSchemeI cs)
167 public void setBackgroundColour(Color col)
172 public void highlightAtoms(List<AtomSpec> atoms)
177 public SequenceRenderer getSequenceRenderer(AlignmentViewPanel alignment)
183 public FeatureRenderer getFeatureRenderer(AlignmentViewPanel alignment)
189 protected void colourBySequence(AlignmentViewPanel avp)
194 public void colourByCharge()
199 public void colourByChain()
203 String[][] chains = binder.getChains();
204 assertFalse(chains == null || chains[0] == null,
205 "No chains discovered by binding");
206 assertEquals(2, chains[0].length);
207 assertEquals("A", chains[0][0]);
208 assertEquals("B", chains[0][1]);
210 AAStructureBindingModel testee;
212 AlignmentI al = null;
215 * Set up test conditions with three aligned sequences,
217 @BeforeMethod(alwaysRun = true)
220 SequenceI seq1a = new Sequence("1YCS|A", "-VPSQK");
221 SequenceI seq1b = new Sequence("1YCS|B", "EIVKF-");
222 SequenceI seq2 = new Sequence("3A6S", "MK-KLQ");
223 SequenceI seq3 = new Sequence("1OOT", "SPK-AV");
224 al = new Alignment(new SequenceI[] { seq1a, seq1b, seq2, seq3 });
228 * give pdb files the name generated by Jalview for PASTE source
230 PDBEntry[] pdbFiles = new PDBEntry[3];
231 pdbFiles[0] = new PDBEntry("1YCS", "A", Type.PDB, "INLINE1YCS");
232 pdbFiles[1] = new PDBEntry("3A6S", "B", Type.PDB, "INLINE3A6S");
233 pdbFiles[2] = new PDBEntry("1OOT", "A", Type.PDB, "INLINE1OOT");
234 SequenceI[][] seqs = new SequenceI[3][];
235 seqs[0] = new SequenceI[] { seq1a, seq1b };
236 seqs[1] = new SequenceI[] { seq2 };
237 seqs[2] = new SequenceI[] { seq3 };
238 StructureSelectionManager ssm = new StructureSelectionManager();
240 ssm.setMapping(new SequenceI[] { seq1a, seq1b }, null, PDB_1,
241 DataSourceType.PASTE, null);
242 ssm.setMapping(new SequenceI[] { seq2 }, null, PDB_2,
243 DataSourceType.PASTE, null);
244 ssm.setMapping(new SequenceI[] { seq3 }, null, PDB_3,
245 DataSourceType.PASTE, null);
247 testee = new AAStructureBindingModel(ssm, pdbFiles, seqs, null)
250 public String[] getStructureFiles()
252 return new String[] { "INLINE1YCS", "INLINE3A6S", "INLINE1OOT" };
256 public void updateColours(Object source)
261 public void releaseReferences(Object svl)
266 public void highlightAtoms(List<AtomSpec> atoms)
271 public void setJalviewColourScheme(ColourSchemeI cs)
276 public String superposeStructures(AlignmentI[] als, int[] alm,
283 public void setBackgroundColour(Color col)
288 public SequenceRenderer getSequenceRenderer(
289 AlignmentViewPanel alignment)
295 protected void colourBySequence(AlignmentViewPanel avp)
300 public void colourByChain()
305 public void colourByCharge()
310 public FeatureRenderer getFeatureRenderer(
311 AlignmentViewPanel alignment)
319 * Verify that the method determines that columns 2, 5 and 6 of the alignment
320 * are alignable in structure
322 @Test(groups = { "Functional" })
323 public void testFindSuperposableResidues()
326 * create a data bean to hold data per structure file
328 SuperposeData[] structs = new SuperposeData[testee.getStructureFiles().length];
329 for (int i = 0; i < structs.length; i++)
331 structs[i] = testee.new SuperposeData(al.getWidth());
334 * initialise BitSet of 'superposable columns' to true (would be false for
337 BitSet matched = new BitSet();
338 for (int i = 0; i < al.getWidth(); i++)
343 int refStructure = testee
344 .findSuperposableResidues(al, matched, structs);
346 assertEquals(0, refStructure);
349 * only ungapped, structure-mapped columns are superposable
351 assertFalse(matched.get(0)); // gap in first sequence
352 assertTrue(matched.get(1));
353 assertFalse(matched.get(2)); // gap in third sequence
354 assertFalse(matched.get(3)); // gap in fourth sequence
355 assertTrue(matched.get(4));
356 assertTrue(matched.get(5)); // gap in second sequence
358 assertEquals("1YCS", structs[0].pdbId);
359 assertEquals("3A6S", structs[1].pdbId);
360 assertEquals("1OOT", structs[2].pdbId);
361 assertEquals("A", structs[0].chain); // ? struct has chains A _and_ B
362 assertEquals("B", structs[1].chain);
363 assertEquals("A", structs[2].chain);
364 // the 0's for unsuperposable positions propagate down the columns:
365 assertEquals("[0, 97, 98, 99, 100, 102]",
366 Arrays.toString(structs[0].pdbResNo));
367 assertEquals("[0, 2, 0, 3, 4, 5]", Arrays.toString(structs[1].pdbResNo));
368 assertEquals("[0, 8, 0, 0, 10, 12]",
369 Arrays.toString(structs[2].pdbResNo));
372 @Test(groups = { "Functional" })
373 public void testFindSuperposableResidues_hiddenColumn()
375 SuperposeData[] structs = new SuperposeData[al.getHeight()];
376 for (int i = 0; i < structs.length; i++)
378 structs[i] = testee.new SuperposeData(al.getWidth());
381 * initialise BitSet of 'superposable columns' to true (would be false for
384 BitSet matched = new BitSet();
385 for (int i = 0; i < al.getWidth(); i++)
390 // treat column 5 of the alignment as hidden
393 int refStructure = testee
394 .findSuperposableResidues(al, matched, structs);
396 assertEquals(0, refStructure);
398 // only ungapped, structure-mapped columns are not superposable
399 assertFalse(matched.get(0));
400 assertTrue(matched.get(1));
401 assertFalse(matched.get(2));
402 assertFalse(matched.get(3));
403 assertFalse(matched.get(4)); // superposable, but hidden, column
404 assertTrue(matched.get(5));