/*
* BioJava development code
*
* This code may be freely distributed and modified under the
* terms of the GNU Lesser General Public Licence. This should
* be distributed with the code. If you do not have a copy,
* see:
*
* http://www.gnu.org/copyleft/lesser.html
*
* Copyright for this code is held jointly by the individual
* authors. These should be listed in @author doc comments.
*
* For more information on the BioJava project and its aims,
* or to join the biojava-l mailing list, visit the home page
* at:
*
* http://www.biojava.org/
*
*/
package org.biojava.nbio.structure.io;
import org.biojava.nbio.structure.*;
import org.biojava.nbio.structure.align.util.AtomCache;
import org.biojava.nbio.structure.quaternary.BioAssemblyInfo;
import org.biojava.nbio.structure.quaternary.BiologicalAssemblyTransformation;
import org.junit.Test;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
public class TestQuaternaryStructureProviders {
@Test
public void test1STP() throws IOException, StructureException{
comparePdbVsMmcif("1stp",1, 4);
}
@Test
public void test3FAD() throws IOException, StructureException{
comparePdbVsMmcif("3fad",1, 1);
comparePdbVsMmcif("3fad",2, 2);
}
@Test
public void test5LDH() throws IOException, StructureException{
comparePdbVsMmcif("5LDH",1, 4);
// the pdb file of 5ldh contains only 1 bioassembly, whilst the mmcif contains 2,
// thus we can't test here the comparison between the 2
//testID("5LDH",2, 2);
// in 5ldh there's also PAU and XAU but those are ignored, see github issue #230
boolean gotException = false;
try {
AtomCache cache = new AtomCache();
cache.setUseMmCif(true);
StructureIO.setAtomCache(cache);
StructureIO.getBiologicalAssembly("5LDH",3);
} catch (StructureException e) {
gotException = true;
}
assertTrue("Bioassembly 3 for PDB id 5LDH should fail with a StructureException!", gotException);
// bioassembly 2 does exist in mmcif file, let's check that
gotException = false;
try {
AtomCache cache = new AtomCache();
cache.setUseMmCif(true);
StructureIO.setAtomCache(cache);
StructureIO.getBiologicalAssembly("5LDH",2);
} catch (StructureException e) {
gotException = true;
}
assertTrue("Bioassembly 2 for PDB id 5LDH should not fail with a StructureException!", !gotException);
}
@Test
public void test3NTU() throws IOException, StructureException{
comparePdbVsMmcif("3NTU",1, 6);
}
@Test
public void test1A29() throws IOException, StructureException{
comparePdbVsMmcif("1A29",1, 1);
}
@Test
public void test1EI7() throws IOException, StructureException {
comparePdbVsMmcif("1ei7",1, 68);
}
@Test
public void testGetNrBioAssemblies5LDH() throws IOException, StructureException {
assertEquals("There should be only 2 bioassemblies for 5LDH, see github issue #230", 2, StructureIO.getBiologicalAssemblies("5LDH").size());
}
/**
* Bioassembly tests for a single PDB entry
* @param pdbId
* @param bioMolecule the bio assembly identifier to test
* @param mmSize the expected mmSize of given bioMolecule number
* @throws IOException
* @throws StructureException
*/
private void comparePdbVsMmcif(String pdbId, int bioMolecule, int mmSize) throws IOException, StructureException{
Structure pdbS = getPdbBioAssembly(pdbId, bioMolecule, true);
Structure mmcifS = getMmcifBioAssembly(pdbId, bioMolecule, true);
PDBHeader pHeader = pdbS.getPDBHeader();
PDBHeader mHeader = mmcifS.getPDBHeader();
assertTrue("not correct nr of bioassemblies " + pHeader.getNrBioAssemblies() + " " , pHeader.getNrBioAssemblies() >= bioMolecule);
assertTrue("not correct nr of bioassemblies " + mHeader.getNrBioAssemblies() + " " , mHeader.getNrBioAssemblies() >= bioMolecule);
// mmcif files contain sometimes partial virus assemblies, so they can contain more info than pdb
assertTrue(pHeader.getNrBioAssemblies() <= mHeader.getNrBioAssemblies());
Map<Integer, BioAssemblyInfo> pMap = pHeader.getBioAssemblies();
Map<Integer, BioAssemblyInfo> mMap = mHeader.getBioAssemblies();
assertTrue(pMap.keySet().size()<= mMap.keySet().size());
assertEquals(mmSize, mMap.get(bioMolecule).getMacromolecularSize());
for ( int k : pMap.keySet()) {
assertTrue(mMap.containsKey(k));
BioAssemblyInfo pBioAssemb = pMap.get(k);
BioAssemblyInfo mBioAssemb = mMap.get(k);
assertEquals("Macromolecular sizes don't coincide!",pBioAssemb.getMacromolecularSize(), mBioAssemb.getMacromolecularSize());
List<BiologicalAssemblyTransformation> pL = pBioAssemb.getTransforms();
// mmcif list can be longer due to the use of internal chain IDs
List<BiologicalAssemblyTransformation> mL = mBioAssemb.getTransforms();
//assertEquals(pL.size(), mL.size());
for (BiologicalAssemblyTransformation m1 : pL){
boolean found = false;
for ( BiologicalAssemblyTransformation m2 : mL){
if (! m1.getChainId().equals(m2.getChainId()))
continue;
if ( ! m1.getTransformationMatrix().epsilonEquals(m2.getTransformationMatrix(), 0.0001))
continue;
found = true;
}
if ( ! found ){
System.err.println("did not find matching matrix " + m1);
System.err.println(mL);
}
assertTrue(found);
}
}
assertEquals("Not the same number of chains!" , pdbS.size(),mmcifS.size());
Atom[] pdbA = StructureTools.getAllAtomArray(pdbS);
Atom[] mmcifA = StructureTools.getAllAtomArray(mmcifS);
assertEquals(pdbA.length, mmcifA.length);
assertEquals(pdbA[0].toPDB(), mmcifA[0].toPDB());
}
private Structure getPdbBioAssembly(String pdbId, int bioMolecule, boolean multiModel) throws IOException, StructureException {
// get bio assembly from PDB file
AtomCache cache = new AtomCache();
cache.setUseMmCif(false);
StructureIO.setAtomCache(cache);
Structure pdbS = StructureIO.getBiologicalAssembly(pdbId, bioMolecule, multiModel);
return pdbS;
}
private Structure getMmcifBioAssembly(String pdbId, int bioMolecule, boolean multiModel) throws IOException, StructureException {
// get bio assembly from mmcif file
AtomCache cache = new AtomCache();
cache.setUseMmCif(true);
StructureIO.setAtomCache(cache);
Structure mmcifS = StructureIO.getBiologicalAssembly(pdbId, bioMolecule, multiModel);
return mmcifS;
}
}