JAL-3032 MCview package renamed mc_view in test classes
[jalview.git] / test / mc_view / PDBChainTest.java
diff --git a/test/mc_view/PDBChainTest.java b/test/mc_view/PDBChainTest.java
new file mode 100644 (file)
index 0000000..0f748ce
--- /dev/null
@@ -0,0 +1,435 @@
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ * 
+ * This file is part of Jalview.
+ * 
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License 
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *  
+ * Jalview is distributed in the hope that it will be useful, but 
+ * WITHOUT ANY WARRANTY; without even the implied warranty 
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
+ * PURPOSE.  See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
+package mc_view;
+
+import static org.testng.AssertJUnit.assertEquals;
+import static org.testng.AssertJUnit.assertFalse;
+import static org.testng.AssertJUnit.assertSame;
+import static org.testng.AssertJUnit.assertTrue;
+
+import jalview.analysis.AlignSeq;
+import jalview.datamodel.AlignmentAnnotation;
+import jalview.datamodel.Sequence;
+import jalview.datamodel.SequenceFeature;
+import jalview.datamodel.SequenceI;
+import jalview.gui.JvOptionPane;
+import jalview.schemes.ColourSchemeI;
+import jalview.schemes.TaylorColourScheme;
+import jalview.structure.StructureImportSettings;
+
+import java.awt.Color;
+import java.util.List;
+import java.util.Vector;
+
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+public class PDBChainTest
+{
+
+  @BeforeClass(alwaysRun = true)
+  public void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
+  PDBChain c;
+
+  final Atom a1 = new Atom(1f, 2f, 3f);
+
+  final Atom a2 = new Atom(5f, 6f, 4f);
+
+  final Atom a3 = new Atom(2f, 5f, 6f);
+
+  final Atom a4 = new Atom(2f, 1f, 7f);
+
+  @BeforeMethod(alwaysRun = true)
+  public void setUp()
+  {
+    System.out.println("setup");
+    StructureImportSettings.setShowSeqFeatures(true);
+    c = new PDBChain("1GAQ", "A");
+  }
+
+  @Test(groups = { "Functional" })
+  public void testGetNewlineString()
+  {
+    assertEquals(System.lineSeparator(), c.getNewlineString());
+    c.setNewlineString("gaga");
+    assertEquals("gaga", c.getNewlineString());
+  }
+
+  @Test(groups = { "Functional" })
+  public void testPrint()
+  {
+    c.offset = 7;
+
+    a1.resName = "GLY";
+    a1.resNumber = 23;
+    a2.resName = "GLU";
+    a2.resNumber = 34;
+    a3.resName = "ASP";
+    a3.resNumber = 41;
+
+    Vector<Bond> v = new Vector<>();
+    v.add(new Bond(a1, a2));
+    v.add(new Bond(a2, a3));
+    v.add(new Bond(a3, a1));
+    c.bonds = v;
+
+    String printed = c.print();
+    String nl = System.lineSeparator();
+    assertEquals("GLY 23 7" + nl + "GLU 34 7" + nl + "ASP 41 7" + nl,
+            printed);
+  }
+
+  /**
+   * Test the method that constructs a Bond between two atoms and adds it to the
+   * chain's list of bonds
+   */
+  @Test(groups = { "Functional" })
+  public void testMakeBond()
+  {
+    /*
+     * Add a bond from a1 to a2
+     */
+    c.makeBond(a1, a2);
+    assertEquals(1, c.bonds.size());
+    Bond b1 = c.bonds.get(0);
+    assertSame(a1, b1.at1);
+    assertSame(a2, b1.at2);
+    assertEquals(1f, b1.start[0], 0.0001f);
+    assertEquals(2f, b1.start[1], 0.0001f);
+    assertEquals(3f, b1.start[2], 0.0001f);
+    assertEquals(5f, b1.end[0], 0.0001f);
+    assertEquals(6f, b1.end[1], 0.0001f);
+    assertEquals(4f, b1.end[2], 0.0001f);
+
+    /*
+     * Add another bond from a2 to a1
+     */
+    c.makeBond(a2, a1);
+    assertEquals(2, c.bonds.size());
+    assertSame(b1, c.bonds.get(0));
+    Bond b2 = c.bonds.get(1);
+    assertSame(a2, b2.at1);
+    assertSame(a1, b2.at2);
+    assertEquals(5f, b2.start[0], 0.0001f);
+    assertEquals(6f, b2.start[1], 0.0001f);
+    assertEquals(4f, b2.start[2], 0.0001f);
+    assertEquals(1f, b2.end[0], 0.0001f);
+    assertEquals(2f, b2.end[1], 0.0001f);
+    assertEquals(3f, b2.end[2], 0.0001f);
+  }
+
+  @Test(groups = { "Functional" })
+  public void testSetChainColours_colour()
+  {
+    c.makeBond(a1, a2);
+    c.makeBond(a2, a3);
+    c.setChainColours(Color.PINK);
+    assertEquals(2, c.bonds.size());
+    assertEquals(Color.PINK, c.bonds.get(0).startCol);
+    assertEquals(Color.PINK, c.bonds.get(0).endCol);
+    assertEquals(Color.PINK, c.bonds.get(1).startCol);
+    assertEquals(Color.PINK, c.bonds.get(1).endCol);
+  }
+
+  /**
+   * Test setting bond start/end colours based on a colour scheme i.e. colour by
+   * residue
+   */
+  @Test(groups = { "Functional" })
+  public void testSetChainColours_colourScheme()
+  {
+    Color alaColour = new Color(204, 255, 0);
+    Color glyColour = new Color(255, 153, 0);
+    a1.resName = "ALA";
+    a2.resName = "GLY";
+    a3.resName = "XXX"; // no colour defined
+    c.makeBond(a1, a2);
+    c.makeBond(a2, a1);
+    c.makeBond(a2, a3);
+    ColourSchemeI cs = new TaylorColourScheme();
+    c.setChainColours(cs);
+    // bond a1 to a2
+    Bond b = c.bonds.get(0);
+    assertEquals(alaColour, b.startCol);
+    assertEquals(glyColour, b.endCol);
+    // bond a2 to a1
+    b = c.bonds.get(1);
+    assertEquals(glyColour, b.startCol);
+    assertEquals(alaColour, b.endCol);
+    // bond a2 to a3 - no colour found for a3
+    // exception handling defaults to gray
+    b = c.bonds.get(2);
+    assertEquals(Color.gray, b.startCol);
+    assertEquals(Color.gray, b.endCol);
+  }
+
+  @Test(groups = { "Functional" })
+  public void testGetChargeColour()
+  {
+    assertEquals(Color.red, PDBChain.getChargeColour("ASP"));
+    assertEquals(Color.red, PDBChain.getChargeColour("GLU"));
+    assertEquals(Color.blue, PDBChain.getChargeColour("LYS"));
+    assertEquals(Color.blue, PDBChain.getChargeColour("ARG"));
+    assertEquals(Color.yellow, PDBChain.getChargeColour("CYS"));
+    assertEquals(Color.lightGray, PDBChain.getChargeColour("ALA"));
+    assertEquals(Color.lightGray, PDBChain.getChargeColour(null));
+  }
+
+  /**
+   * Test the method that sets bond start/end colours by residue charge property
+   */
+  @Test(groups = { "Functional" })
+  public void testSetChargeColours()
+  {
+    a1.resName = "ASP"; // red
+    a2.resName = "LYS"; // blue
+    a3.resName = "CYS"; // yellow
+    a4.resName = "ALA"; // no colour (light gray)
+    c.makeBond(a1, a2);
+    c.makeBond(a2, a3);
+    c.makeBond(a3, a4);
+    c.setChargeColours();
+    assertEquals(3, c.bonds.size());
+    // bond a1 to a2
+    Bond b = c.bonds.get(0);
+    assertEquals(Color.red, b.startCol);
+    assertEquals(Color.blue, b.endCol);
+    // bond a2 to a3
+    b = c.bonds.get(1);
+    assertEquals(Color.blue, b.startCol);
+    assertEquals(Color.yellow, b.endCol);
+    // bond a3 to a4
+    b = c.bonds.get(2);
+    assertEquals(Color.yellow, b.startCol);
+    assertEquals(Color.lightGray, b.endCol);
+  }
+
+  /**
+   * Test the method that converts the raw list of atoms to a list of residues
+   */
+  @Test(groups = { "Functional" })
+  public void testMakeResidueList_noAnnotation()
+  {
+    Vector<Atom> atoms = new Vector<>();
+    c.atoms = atoms;
+    c.isNa = true;
+    atoms.add(makeAtom(4, "N", "MET"));
+    atoms.add(makeAtom(4, "CA", "MET"));
+    atoms.add(makeAtom(4, "C", "MET"));
+    atoms.add(makeAtom(5, "O", "LYS"));
+    atoms.add(makeAtom(5, "N", "LYS"));
+    atoms.add(makeAtom(5, "CA", "LYS"));
+    atoms.add(makeAtom(6, "O", "LEU"));
+    atoms.add(makeAtom(6, "N", "LEU"));
+    atoms.add(makeAtom(6, "CA", "LEU"));
+
+    c.makeResidueList(false);
+
+    /*
+     * check sequence constructed
+     */
+    assertEquals("MKL", c.sequence.getSequenceAsString());
+    assertFalse(c.isNa);
+    assertEquals(3, c.residues.size());
+
+    /*
+     * check sequence features
+     */
+    List<SequenceFeature> sfs = c.sequence.getSequenceFeatures();
+    assertEquals(3, sfs.size());
+    assertEquals("RESNUM", sfs.get(0).type);
+    assertEquals("MET:4 1gaqA", sfs.get(0).description);
+    assertEquals(4, sfs.get(0).begin);
+    assertEquals(4, sfs.get(0).end);
+    assertEquals("RESNUM", sfs.get(0).type);
+    assertEquals("LYS:5 1gaqA", sfs.get(1).description);
+    assertEquals(5, sfs.get(1).begin);
+    assertEquals(5, sfs.get(1).end);
+    assertEquals("LEU:6 1gaqA", sfs.get(2).description);
+    assertEquals(6, sfs.get(2).begin);
+    assertEquals(6, sfs.get(2).end);
+  }
+
+  private Atom makeAtom(int resnum, String name, String resname)
+  {
+    Atom a = new Atom(1f, 2f, 3f);
+    a.resNumber = resnum;
+    a.resNumIns = String.valueOf(resnum);
+    a.name = name;
+    a.resName = resname;
+    a.chain = "A";
+    return a;
+  }
+
+  /**
+   * Test the method that converts the raw list of atoms to a list of residues,
+   * including parsing of tempFactor to an alignment annotation
+   */
+  @Test(groups = { "Functional" })
+  public void testMakeResidueList_withTempFactor()
+  {
+    Vector<Atom> atoms = new Vector<>();
+    c.atoms = atoms;
+    atoms.add(makeAtom(4, "N", "MET"));
+    atoms.get(atoms.size() - 1).tfactor = 1f;
+    atoms.add(makeAtom(4, "CA", "MET"));
+    atoms.get(atoms.size() - 1).tfactor = 2f;
+    atoms.add(makeAtom(4, "C", "MET"));
+    atoms.get(atoms.size() - 1).tfactor = 3f;
+    atoms.add(makeAtom(5, "O", "LYS"));
+    atoms.get(atoms.size() - 1).tfactor = 7f;
+    atoms.add(makeAtom(5, "N", "LYS"));
+    atoms.get(atoms.size() - 1).tfactor = 8f;
+    atoms.add(makeAtom(5, "CA", "LYS"));
+    atoms.get(atoms.size() - 1).tfactor = 9f;
+    atoms.add(makeAtom(6, "O", "LEU"));
+    atoms.get(atoms.size() - 1).tfactor = -4f;
+    atoms.add(makeAtom(6, "N", "LEU"));
+    atoms.get(atoms.size() - 1).tfactor = 5f;
+    atoms.add(makeAtom(6, "CA", "LEU"));
+    atoms.get(atoms.size() - 1).tfactor = 6f;
+
+    /*
+     * make residues including temp factor annotation
+     */
+    c.makeResidueList(true);
+
+    /*
+     * Verify annotations; note the tempFactor is read from the first atom in
+     * each residue i.e. we expect values 1, 7, -4 for the residues
+     */
+    AlignmentAnnotation[] ann = c.sequence.getAnnotation();
+    assertEquals(1, ann.length);
+    assertEquals("Temperature Factor", ann[0].label);
+    assertEquals("Temperature Factor for 1gaqA", ann[0].description);
+    assertSame(c.sequence, ann[0].sequenceRef);
+    assertEquals(AlignmentAnnotation.LINE_GRAPH, ann[0].graph);
+    assertEquals(-4f, ann[0].graphMin, 0.001f);
+    assertEquals(7f, ann[0].graphMax, 0.001f);
+    assertEquals(3, ann[0].annotations.length);
+    assertEquals(1f, ann[0].annotations[0].value, 0.001f);
+    assertEquals(7f, ann[0].annotations[1].value, 0.001f);
+    assertEquals(-4f, ann[0].annotations[2].value, 0.001f);
+  }
+
+  /**
+   * Test the method that constructs bonds between successive residues' CA or P
+   * atoms
+   */
+  @Test(groups = { "Functional" })
+  public void testMakeCaBondList()
+  {
+    c.isNa = true;
+    Vector<Atom> atoms = new Vector<>();
+    c.atoms = atoms;
+    atoms.add(makeAtom(4, "N", "MET"));
+    atoms.add(makeAtom(4, "CA", "MET"));
+    atoms.add(makeAtom(5, "CA", "ASP"));
+    atoms.add(makeAtom(5, "O", "ASP"));
+    atoms.add(makeAtom(6, "CA", "GLY"));
+    atoms.add(makeAtom(6, "N", "GLY"));
+
+    // have to make residue list first!
+    c.makeResidueList(false);
+    assertFalse(c.isNa);
+    c.isNa = true;
+
+    c.makeCaBondList();
+    assertEquals(2, c.bonds.size());
+    Bond b = c.bonds.get(0);
+    assertSame(c.atoms.get(1), b.at1);
+    assertSame(c.atoms.get(2), b.at2);
+    b = c.bonds.get(1);
+    assertSame(c.atoms.get(2), b.at1);
+    assertSame(c.atoms.get(4), b.at2);
+
+    // isNa flag is _not_ reset by this method!
+    assertTrue(c.isNa);
+  }
+
+  @Test(groups = { "Functional" })
+  public void testMakeCaBondList_nucleotide()
+  {
+    c.isNa = false;
+    Vector<Atom> atoms = new Vector<>();
+    c.atoms = atoms;
+    atoms.add(makeAtom(4, "N", "G"));
+    atoms.add(makeAtom(4, "P", "G"));
+    atoms.add(makeAtom(5, "P", "C"));
+    atoms.add(makeAtom(5, "O", "C"));
+    atoms.add(makeAtom(6, "P", "T"));
+    atoms.add(makeAtom(6, "N", "T"));
+
+    // have to make residue list first!
+    c.makeResidueList(false);
+    assertEquals("GCT", c.sequence.getSequenceAsString());
+
+    c.makeCaBondList();
+    assertEquals(2, c.bonds.size());
+    Bond b = c.bonds.get(0);
+    assertSame(c.atoms.get(1), b.at1);
+    assertSame(c.atoms.get(2), b.at2);
+    b = c.bonds.get(1);
+    assertSame(c.atoms.get(2), b.at1);
+    assertSame(c.atoms.get(4), b.at2);
+
+    assertTrue(c.isNa);
+  }
+
+  /**
+   * Test the method that updates atoms with their alignment positions
+   */
+  @Test(groups = { "Functional" })
+  public void testMakeExactMapping()
+  {
+    Vector<Atom> atoms = new Vector<>();
+    c.atoms = atoms;
+    atoms.add(makeAtom(4, "N", "MET"));
+    atoms.add(makeAtom(4, "CA", "MET"));
+    atoms.add(makeAtom(5, "CA", "ASP"));
+    atoms.add(makeAtom(5, "O", "ASP"));
+    atoms.add(makeAtom(6, "CA", "GLY"));
+    atoms.add(makeAtom(6, "N", "GLY"));
+    c.makeResidueList(false);
+    assertEquals("MDG", c.sequence.getSequenceAsString());
+    SequenceI s1 = new Sequence("Seq1", "MDG");
+    SequenceI s2 = new Sequence("Seq2", "MDG");
+    AlignSeq alignSeq = AlignSeq.doGlobalNWAlignment(s1, s2, AlignSeq.PEP);
+    SequenceI seq3 = new Sequence("Seq3", "--M-DG");
+    c.makeExactMapping(alignSeq, seq3);
+
+    int pos = 0;
+    for (Residue res : c.residues)
+    {
+      for (Atom a : res.atoms)
+      {
+        assertEquals(pos, a.alignmentMapping);
+      }
+      pos++;
+    }
+  }
+}