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