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