/*
* 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;
import static org.junit.Assert.*;
import java.io.IOException;
import java.io.InputStream;
import java.util.zip.GZIPInputStream;
import org.biojava.nbio.structure.align.util.AtomCache;
import org.biojava.nbio.structure.io.FileParsingParameters;
import org.biojava.nbio.structure.io.PDBFileParser;
import org.junit.Test;
public class TestCompoundResIndexMapping {
private static final String PATH_TO_TEST_FILES = "/org/biojava/nbio/structure/io/";
@Test
public void test1B8G() throws IOException, StructureException {
AtomCache cache = new AtomCache();
FileParsingParameters params = new FileParsingParameters();
params.setAlignSeqRes(true);
cache.setFileParsingParams(params);
StructureIO.setAtomCache(cache);
cache.setUseMmCif(false);
Structure s = StructureIO.getStructure("1B8G");
Chain chainA = s.getPolyChainByPDB("A");
int i = chainA.getEntityInfo().getAlignedResIndex(chainA.getAtomGroup(0),chainA);
assertEquals("First residue in 1b8gA "+chainA.getAtomGroup(0).toString()+" should map to 1 in SEQRES",1,i);
checkAllResidues(s);
}
@Test
public void test1SMT() throws IOException, StructureException {
AtomCache cache = new AtomCache();
FileParsingParameters params = new FileParsingParameters();
params.setAlignSeqRes(true);
cache.setFileParsingParams(params);
StructureIO.setAtomCache(cache);
cache.setUseMmCif(false);
Structure s = StructureIO.getStructure("1SMT");
Chain chainA = s.getPolyChainByPDB("A");
int i = chainA.getEntityInfo().getAlignedResIndex(chainA.getAtomGroup(0),chainA);
assertEquals("First residue in 1smtA "+chainA.getAtomGroup(0).toString()+" should map to 24 in SEQRES",24,i);
Chain chainB = s.getPolyChainByPDB("B");
i = chainB.getEntityInfo().getAlignedResIndex(chainB.getAtomGroup(0),chainB);
assertEquals("First residue in 1smtB "+chainA.getAtomGroup(0).toString()+" should map to 20 in SEQRES",20,i);
checkAllResidues(s);
}
private void checkAllResidues(Structure s) {
for (Chain c:s.getChains()) {
for (Group g:c.getAtomGroups()) {
if (g.getType() != GroupType.AMINOACID) continue;
int resIndex = c.getEntityInfo().getAlignedResIndex(g, c);
assertNotEquals("Residue "+g.getResidueNumber()+" should not map to -1 in SEQRES",-1, resIndex);
assertNotEquals("Residue "+g.getResidueNumber()+" should not map to 0 in SEQRES",0, resIndex);
assertTrue(resIndex <= c.getSeqResLength());
}
}
}
// This doesn't work yet, since for raw files without a SEQRES, the seqres groups are not populated. Instead
// in that case Compound.getAlignedResIndex() returns residue numbers as given (without insertion codes) and
// thus in general residues will not be correctly aligned between different chains of same entity. This breaks
// cases like 3ddo (with no SEQRES records) where residue numbering is different in every chain of the one entity.
// see https://github.com/eppic-team/eppic/issues/39
//@Test
public void test3ddoRawNoSeqres() throws IOException, StructureException {
// 3ddo has 6 chains in 1 entity, all of them with different residue numbering (chain A is 1000+, chain B 2000+ ...)
Structure s = getStructure("3ddo_raw_noseqres.pdb.gz", true);
assertEquals(1,s.getEntityInfos().size());
Chain chainA = s.getPolyChainByPDB("A");
Chain chainB = s.getPolyChainByPDB("B");
Chain chainC = s.getPolyChainByPDB("C");
// the last 3 residues of each chain are all the same: they should map to the same index
for (int resNum=251;resNum<=253;resNum++) {
Group groupInChainA = chainA.getGroupByPDB(new ResidueNumber("A", resNum+1000, null));
int indexInChainA = chainA.getEntityInfo().getAlignedResIndex(groupInChainA, chainA);
Group groupInChainB = chainB.getGroupByPDB(new ResidueNumber("B", resNum+2000, null));
int indexInChainB = chainB.getEntityInfo().getAlignedResIndex(groupInChainB, chainB);
Group groupInChainC = chainC.getGroupByPDB(new ResidueNumber("C", resNum+3000, null));
int indexInChainC = chainC.getEntityInfo().getAlignedResIndex(groupInChainC, chainC);
assertNotEquals(-1, indexInChainA);
assertNotEquals(-1, indexInChainB);
assertNotEquals(-1, indexInChainC);
assertEquals(indexInChainA,indexInChainB);
assertEquals(indexInChainA,indexInChainC);
}
// this should work either with or without setAlignSeqRes, since the mapping happens in CompoundFinder
s = getStructure("3ddo_raw_noseqres.pdb.gz", false);
assertEquals(1,s.getEntityInfos().size());
chainA = s.getPolyChainByPDB("A");
chainB = s.getPolyChainByPDB("B");
chainC = s.getPolyChainByPDB("C");
// the last 3 residues of each chain are all the same: they should map to the same index
for (int resNum=251;resNum<=253;resNum++) {
Group groupInChainA = chainA.getGroupByPDB(new ResidueNumber("A", resNum+1000, null));
int indexInChainA = chainA.getEntityInfo().getAlignedResIndex(groupInChainA, chainA);
Group groupInChainB = chainB.getGroupByPDB(new ResidueNumber("B", resNum+2000, null));
int indexInChainB = chainB.getEntityInfo().getAlignedResIndex(groupInChainB, chainB);
Group groupInChainC = chainC.getGroupByPDB(new ResidueNumber("C", resNum+3000, null));
int indexInChainC = chainC.getEntityInfo().getAlignedResIndex(groupInChainC, chainC);
assertNotEquals(-1, indexInChainA);
assertNotEquals(-1, indexInChainB);
assertNotEquals(-1, indexInChainC);
assertEquals(indexInChainA,indexInChainB);
assertEquals(indexInChainA,indexInChainC);
}
}
@Test
public void test3ddoRawSeqres() throws IOException, StructureException {
// 3ddo has 6 chains in 1 entity, all of them with different residue numbering (chain A is 1000+, chain B 2000+ ...)
Structure s = getStructure("3ddo_raw_trunc_seqres.pdb.gz", true);
assertEquals(1,s.getEntityInfos().size());
Chain chainA = s.getPolyChainByPDB("A");
Chain chainB = s.getPolyChainByPDB("B");
Chain chainC = s.getPolyChainByPDB("C");
// the last 3 residues of each chain are all the same: they should map to the same index
for (int resNum=28;resNum<=30;resNum++) {
Group groupInChainA = chainA.getGroupByPDB(new ResidueNumber("A", resNum+1000, null));
int indexInChainA = chainA.getEntityInfo().getAlignedResIndex(groupInChainA, chainA);
Group groupInChainB = chainB.getGroupByPDB(new ResidueNumber("B", resNum+2000, null));
int indexInChainB = chainB.getEntityInfo().getAlignedResIndex(groupInChainB, chainB);
Group groupInChainC = chainC.getGroupByPDB(new ResidueNumber("C", resNum+3000, null));
int indexInChainC = chainC.getEntityInfo().getAlignedResIndex(groupInChainC, chainC);
assertNotEquals(-1, indexInChainA);
assertNotEquals(-1, indexInChainB);
assertNotEquals(-1, indexInChainC);
assertEquals(indexInChainA,indexInChainB);
assertEquals(indexInChainA,indexInChainC);
}
// this will not work without setAlignSeqRes, since the mapping happens in SeqRes2AtomAligner
//s = getStructure("3ddo_raw_trunc_seqres.pdb.gz", false);
}
private Structure getStructure(String fileName, boolean setAlignSeqRes) throws IOException {
InputStream inStream = new GZIPInputStream(this.getClass().getResourceAsStream(PATH_TO_TEST_FILES+fileName));
PDBFileParser pdbpars = new PDBFileParser();
FileParsingParameters params = new FileParsingParameters();
params.setAlignSeqRes(setAlignSeqRes);
pdbpars.setFileParsingParameters(params);
return pdbpars.parsePDBFile(inStream) ;
}
}