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