JAL-2089 patch broken merge to master for Release 2.10.0b1
[jalview.git] / test / MCview / PDBChainTest.java
1 /*
2  * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3  * Copyright (C) $$Year-Rel$$ 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 MCview;
22
23 import static org.testng.AssertJUnit.assertEquals;
24 import static org.testng.AssertJUnit.assertFalse;
25 import static org.testng.AssertJUnit.assertSame;
26 import static org.testng.AssertJUnit.assertTrue;
27
28 import jalview.analysis.AlignSeq;
29 import jalview.datamodel.AlignmentAnnotation;
30 import jalview.datamodel.Sequence;
31 import jalview.datamodel.SequenceFeature;
32 import jalview.datamodel.SequenceI;
33 import jalview.schemes.ColourSchemeI;
34 import jalview.schemes.TaylorColourScheme;
35 import jalview.structure.StructureImportSettings;
36
37 import java.awt.Color;
38 import java.util.Vector;
39
40 import org.testng.annotations.BeforeMethod;
41 import org.testng.annotations.Test;
42
43 public class PDBChainTest
44 {
45   PDBChain c;
46
47   final Atom a1 = new Atom(1f, 2f, 3f);
48
49   final Atom a2 = new Atom(5f, 6f, 4f);
50
51   final Atom a3 = new Atom(2f, 5f, 6f);
52
53   final Atom a4 = new Atom(2f, 1f, 7f);
54
55   @BeforeMethod(alwaysRun = true)
56   public void setUp()
57   {
58     System.out.println("setup");
59     StructureImportSettings.setShowSeqFeatures(true);
60     c = new PDBChain("1GAQ", "A");
61   }
62
63   @Test(groups = { "Functional" })
64   public void testGetNewlineString()
65   {
66     assertEquals(System.lineSeparator(), c.getNewlineString());
67     c.setNewlineString("gaga");
68     assertEquals("gaga", c.getNewlineString());
69   }
70
71   @Test(groups = { "Functional" })
72   public void testPrint()
73   {
74     c.offset = 7;
75
76     a1.resName = "GLY";
77     a1.resNumber = 23;
78     a2.resName = "GLU";
79     a2.resNumber = 34;
80     a3.resName = "ASP";
81     a3.resNumber = 41;
82
83     Vector<Bond> v = new Vector<Bond>();
84     v.add(new Bond(a1, a2));
85     v.add(new Bond(a2, a3));
86     v.add(new Bond(a3, a1));
87     c.bonds = v;
88
89     String printed = c.print();
90     String nl = System.lineSeparator();
91     assertEquals("GLY 23 7" + nl + "GLU 34 7" + nl + "ASP 41 7" + nl,
92             printed);
93   }
94
95   /**
96    * Test the method that constructs a Bond between two atoms and adds it to the
97    * chain's list of bonds
98    */
99   @Test(groups = { "Functional" })
100   public void testMakeBond()
101   {
102     /*
103      * Add a bond from a1 to a2
104      */
105     c.makeBond(a1, a2);
106     assertEquals(1, c.bonds.size());
107     Bond b1 = c.bonds.get(0);
108     assertSame(a1, b1.at1);
109     assertSame(a2, b1.at2);
110     assertEquals(1f, b1.start[0], 0.0001f);
111     assertEquals(2f, b1.start[1], 0.0001f);
112     assertEquals(3f, b1.start[2], 0.0001f);
113     assertEquals(5f, b1.end[0], 0.0001f);
114     assertEquals(6f, b1.end[1], 0.0001f);
115     assertEquals(4f, b1.end[2], 0.0001f);
116
117     /*
118      * Add another bond from a2 to a1
119      */
120     c.makeBond(a2, a1);
121     assertEquals(2, c.bonds.size());
122     assertSame(b1, c.bonds.get(0));
123     Bond b2 = c.bonds.get(1);
124     assertSame(a2, b2.at1);
125     assertSame(a1, b2.at2);
126     assertEquals(5f, b2.start[0], 0.0001f);
127     assertEquals(6f, b2.start[1], 0.0001f);
128     assertEquals(4f, b2.start[2], 0.0001f);
129     assertEquals(1f, b2.end[0], 0.0001f);
130     assertEquals(2f, b2.end[1], 0.0001f);
131     assertEquals(3f, b2.end[2], 0.0001f);
132   }
133
134   @Test(groups = { "Functional" })
135   public void testSetChainColours_colour()
136   {
137     c.makeBond(a1, a2);
138     c.makeBond(a2, a3);
139     c.setChainColours(Color.PINK);
140     assertEquals(2, c.bonds.size());
141     assertEquals(Color.PINK, c.bonds.get(0).startCol);
142     assertEquals(Color.PINK, c.bonds.get(0).endCol);
143     assertEquals(Color.PINK, c.bonds.get(1).startCol);
144     assertEquals(Color.PINK, c.bonds.get(1).endCol);
145   }
146
147   /**
148    * Test setting bond start/end colours based on a colour scheme i.e. colour by
149    * residue
150    */
151   @Test(groups = { "Functional" })
152   public void testSetChainColours_colourScheme()
153   {
154     Color alaColour = new Color(204, 255, 0);
155     Color glyColour = new Color(255, 153, 0);
156     a1.resName = "ALA";
157     a2.resName = "GLY";
158     a3.resName = "XXX"; // no colour defined
159     c.makeBond(a1, a2);
160     c.makeBond(a2, a1);
161     c.makeBond(a2, a3);
162     ColourSchemeI cs = new TaylorColourScheme();
163     c.setChainColours(cs);
164     // bond a1 to a2
165     Bond b = c.bonds.get(0);
166     assertEquals(alaColour, b.startCol);
167     assertEquals(glyColour, b.endCol);
168     // bond a2 to a1
169     b = c.bonds.get(1);
170     assertEquals(glyColour, b.startCol);
171     assertEquals(alaColour, b.endCol);
172     // bond a2 to a3 - no colour found for a3
173     // exception handling defaults to gray
174     b = c.bonds.get(2);
175     assertEquals(Color.gray, b.startCol);
176     assertEquals(Color.gray, b.endCol);
177   }
178
179   @Test(groups = { "Functional" })
180   public void testGetChargeColour()
181   {
182     assertEquals(Color.red, PDBChain.getChargeColour("ASP"));
183     assertEquals(Color.red, PDBChain.getChargeColour("GLU"));
184     assertEquals(Color.blue, PDBChain.getChargeColour("LYS"));
185     assertEquals(Color.blue, PDBChain.getChargeColour("ARG"));
186     assertEquals(Color.yellow, PDBChain.getChargeColour("CYS"));
187     assertEquals(Color.lightGray, PDBChain.getChargeColour("ALA"));
188     assertEquals(Color.lightGray, PDBChain.getChargeColour(null));
189   }
190
191   /**
192    * Test the method that sets bond start/end colours by residue charge property
193    */
194   @Test(groups = { "Functional" })
195   public void testSetChargeColours()
196   {
197     a1.resName = "ASP"; // red
198     a2.resName = "LYS"; // blue
199     a3.resName = "CYS"; // yellow
200     a4.resName = "ALA"; // no colour (light gray)
201     c.makeBond(a1, a2);
202     c.makeBond(a2, a3);
203     c.makeBond(a3, a4);
204     c.setChargeColours();
205     assertEquals(3, c.bonds.size());
206     // bond a1 to a2
207     Bond b = c.bonds.get(0);
208     assertEquals(Color.red, b.startCol);
209     assertEquals(Color.blue, b.endCol);
210     // bond a2 to a3
211     b = c.bonds.get(1);
212     assertEquals(Color.blue, b.startCol);
213     assertEquals(Color.yellow, b.endCol);
214     // bond a3 to a4
215     b = c.bonds.get(2);
216     assertEquals(Color.yellow, b.startCol);
217     assertEquals(Color.lightGray, b.endCol);
218   }
219
220   /**
221    * Test the method that converts the raw list of atoms to a list of residues
222    */
223   @Test(groups = { "Functional" })
224   public void testMakeResidueList_noAnnotation()
225   {
226     Vector<Atom> atoms = new Vector<Atom>();
227     c.atoms = atoms;
228     c.isNa = true;
229     atoms.add(makeAtom(4, "N", "MET"));
230     atoms.add(makeAtom(4, "CA", "MET"));
231     atoms.add(makeAtom(4, "C", "MET"));
232     atoms.add(makeAtom(5, "O", "LYS"));
233     atoms.add(makeAtom(5, "N", "LYS"));
234     atoms.add(makeAtom(5, "CA", "LYS"));
235     atoms.add(makeAtom(6, "O", "LEU"));
236     atoms.add(makeAtom(6, "N", "LEU"));
237     atoms.add(makeAtom(6, "CA", "LEU"));
238
239     c.makeResidueList(false);
240
241     /*
242      * check sequence constructed
243      */
244     assertEquals("MKL", c.sequence.getSequenceAsString());
245     assertFalse(c.isNa);
246     assertEquals(3, c.residues.size());
247
248     /*
249      * check sequence features
250      */
251     SequenceFeature[] sfs = c.sequence.getSequenceFeatures();
252     assertEquals(3, sfs.length);
253     assertEquals("RESNUM", sfs[0].type);
254     assertEquals("MET:4 1gaqA", sfs[0].description);
255     assertEquals(4, sfs[0].begin);
256     assertEquals(4, sfs[0].end);
257     assertEquals("RESNUM", sfs[0].type);
258     assertEquals("LYS:5 1gaqA", sfs[1].description);
259     assertEquals(5, sfs[1].begin);
260     assertEquals(5, sfs[1].end);
261     assertEquals("LEU:6 1gaqA", sfs[2].description);
262     assertEquals(6, sfs[2].begin);
263     assertEquals(6, sfs[2].end);
264   }
265
266   private Atom makeAtom(int resnum, String name, String resname)
267   {
268     Atom a = new Atom(1f, 2f, 3f);
269     a.resNumber = resnum;
270     a.resNumIns = String.valueOf(resnum);
271     a.name = name;
272     a.resName = resname;
273     a.chain = "A";
274     return a;
275   }
276
277   /**
278    * Test the method that converts the raw list of atoms to a list of residues,
279    * including parsing of tempFactor to an alignment annotation
280    */
281   @Test(groups = { "Functional" })
282   public void testMakeResidueList_withTempFactor()
283   {
284     Vector<Atom> atoms = new Vector<Atom>();
285     c.atoms = atoms;
286     atoms.add(makeAtom(4, "N", "MET"));
287     atoms.get(atoms.size() - 1).tfactor = 1f;
288     atoms.add(makeAtom(4, "CA", "MET"));
289     atoms.get(atoms.size() - 1).tfactor = 2f;
290     atoms.add(makeAtom(4, "C", "MET"));
291     atoms.get(atoms.size() - 1).tfactor = 3f;
292     atoms.add(makeAtom(5, "O", "LYS"));
293     atoms.get(atoms.size() - 1).tfactor = 7f;
294     atoms.add(makeAtom(5, "N", "LYS"));
295     atoms.get(atoms.size() - 1).tfactor = 8f;
296     atoms.add(makeAtom(5, "CA", "LYS"));
297     atoms.get(atoms.size() - 1).tfactor = 9f;
298     atoms.add(makeAtom(6, "O", "LEU"));
299     atoms.get(atoms.size() - 1).tfactor = 4f;
300     atoms.add(makeAtom(6, "N", "LEU"));
301     atoms.get(atoms.size() - 1).tfactor = 5f;
302     atoms.add(makeAtom(6, "CA", "LEU"));
303     atoms.get(atoms.size() - 1).tfactor = 6f;
304
305     /*
306      * make residues including temp factor annotation
307      */
308     c.makeResidueList(true);
309
310     /*
311      * Verify annotations; note the tempFactor is read from the first atom in
312      * each residue i.e. we expect values 1, 7, 4 for the residues
313      */
314     AlignmentAnnotation[] ann = c.sequence.getAnnotation();
315     assertEquals(1, ann.length);
316     assertEquals("Temperature Factor", ann[0].label);
317     assertEquals("Temperature Factor for 1gaqA", ann[0].description);
318     assertSame(c.sequence, ann[0].sequenceRef);
319     assertEquals(AlignmentAnnotation.LINE_GRAPH, ann[0].graph);
320     assertEquals(0f, ann[0].graphMin, 0.001f);
321     assertEquals(7f, ann[0].graphMax, 0.001f);
322     assertEquals(3, ann[0].annotations.length);
323     assertEquals(1f, ann[0].annotations[0].value, 0.001f);
324     assertEquals(7f, ann[0].annotations[1].value, 0.001f);
325     assertEquals(4f, ann[0].annotations[2].value, 0.001f);
326   }
327
328   /**
329    * Test the method that constructs bonds between successive residues' CA or P
330    * atoms
331    */
332   @Test(groups = { "Functional" })
333   public void testMakeCaBondList()
334   {
335     c.isNa = true;
336     Vector<Atom> atoms = new Vector<Atom>();
337     c.atoms = atoms;
338     atoms.add(makeAtom(4, "N", "MET"));
339     atoms.add(makeAtom(4, "CA", "MET"));
340     atoms.add(makeAtom(5, "CA", "ASP"));
341     atoms.add(makeAtom(5, "O", "ASP"));
342     atoms.add(makeAtom(6, "CA", "GLY"));
343     atoms.add(makeAtom(6, "N", "GLY"));
344
345     // have to make residue list first!
346     c.makeResidueList(false);
347     assertFalse(c.isNa);
348     c.isNa = true;
349
350     c.makeCaBondList();
351     assertEquals(2, c.bonds.size());
352     Bond b = c.bonds.get(0);
353     assertSame(c.atoms.get(1), b.at1);
354     assertSame(c.atoms.get(2), b.at2);
355     b = c.bonds.get(1);
356     assertSame(c.atoms.get(2), b.at1);
357     assertSame(c.atoms.get(4), b.at2);
358
359     // isNa flag is _not_ reset by this method!
360     assertTrue(c.isNa);
361   }
362
363   @Test(groups = { "Functional" })
364   public void testMakeCaBondList_nucleotide()
365   {
366     c.isNa = false;
367     Vector<Atom> atoms = new Vector<Atom>();
368     c.atoms = atoms;
369     atoms.add(makeAtom(4, "N", "G"));
370     atoms.add(makeAtom(4, "P", "G"));
371     atoms.add(makeAtom(5, "P", "C"));
372     atoms.add(makeAtom(5, "O", "C"));
373     atoms.add(makeAtom(6, "P", "T"));
374     atoms.add(makeAtom(6, "N", "T"));
375
376     // have to make residue list first!
377     c.makeResidueList(false);
378     assertEquals("GCT", c.sequence.getSequenceAsString());
379
380     c.makeCaBondList();
381     assertEquals(2, c.bonds.size());
382     Bond b = c.bonds.get(0);
383     assertSame(c.atoms.get(1), b.at1);
384     assertSame(c.atoms.get(2), b.at2);
385     b = c.bonds.get(1);
386     assertSame(c.atoms.get(2), b.at1);
387     assertSame(c.atoms.get(4), b.at2);
388
389     assertTrue(c.isNa);
390   }
391
392   /**
393    * Test the method that updates atoms with their alignment positions
394    */
395   @Test(groups = { "Functional" })
396   public void testMakeExactMapping()
397   {
398     Vector<Atom> atoms = new Vector<Atom>();
399     c.atoms = atoms;
400     atoms.add(makeAtom(4, "N", "MET"));
401     atoms.add(makeAtom(4, "CA", "MET"));
402     atoms.add(makeAtom(5, "CA", "ASP"));
403     atoms.add(makeAtom(5, "O", "ASP"));
404     atoms.add(makeAtom(6, "CA", "GLY"));
405     atoms.add(makeAtom(6, "N", "GLY"));
406     c.makeResidueList(false);
407     assertEquals("MDG", c.sequence.getSequenceAsString());
408     SequenceI s1 = new Sequence("Seq1", "MDG");
409     SequenceI s2 = new Sequence("Seq2", "MDG");
410     AlignSeq alignSeq = AlignSeq.doGlobalNWAlignment(s1, s2, AlignSeq.PEP);
411     SequenceI seq3 = new Sequence("Seq3", "--M-DG");
412     c.makeExactMapping(alignSeq, seq3);
413
414     int pos = 0;
415     for (Residue res : c.residues)
416     {
417       for (Atom a : res.atoms)
418       {
419         assertEquals(pos, a.alignmentMapping);
420       }
421       pos++;
422     }
423   }
424 }