Skip to content

Commit 6fc9a32

Browse files
sblivenElinow
authored andcommitted
Fix parsing of SCOP 1.71 (#115)
- Accept some poorly-formatted comment definitions - Use the first chain found for '_' domains (#115) - Add tests for 1.71
1 parent 6e778ba commit 6fc9a32

5 files changed

Lines changed: 72 additions & 41 deletions

File tree

biojava3-structure/src/main/java/org/biojava/bio/structure/StructureTools.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -819,9 +819,15 @@ public static final Structure getSubRanges(Structure s, String ranges )
819819
String chainId = matcher.group(1);
820820
Chain chain;
821821

822-
if(chainId.equals("_") && struc.size() == 1) {
822+
if(chainId.equals("_") ) {
823823
// Handle special case of "_" chain for single-chain proteins
824824
chain = struc.getChain(0);
825+
826+
if(struc.size() != 1) {
827+
// SCOP 1.71 uses this for some proteins with multiple chains
828+
// Print a warning in this ambiguous case
829+
System.err.format("WARNING multiple possible chains match '_'. Using chain %s.%n",chain.getChainID());
830+
}
825831
} else {
826832
// Explicit chain
827833
chain = struc.getChainByPDB(chainId);

biojava3-structure/src/main/java/org/biojava/bio/structure/scop/ScopInstallation.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -531,10 +531,10 @@ private void parseComments(BufferedReader buffer) throws IOException {
531531
String line = null;
532532
while ((line = buffer.readLine ()) != null) {
533533
if (line.startsWith("#")) continue;
534-
String[] parts = line.split(" ! ");
534+
String[] parts = line.split("!");
535535
int sunId = -1;
536536
try {
537-
sunId = Integer.parseInt(parts[0]);
537+
sunId = Integer.parseInt(parts[0].trim());
538538
} catch (RuntimeException e) {
539539
e.printStackTrace();
540540
continue;
@@ -545,7 +545,10 @@ private void parseComments(BufferedReader buffer) throws IOException {
545545
}
546546
List<String> comments = new ArrayList<String>(parts.length - 1);
547547
for (int i = 1; i < parts.length; i++) {
548-
comments.add(parts[i]);
548+
String trimmed = parts[i].trim();
549+
if( !trimmed.isEmpty() ) {
550+
comments.add(trimmed);
551+
}
549552
}
550553
commentsMap.put(sunId, comments);
551554
}

biojava3-structure/src/test/java/org/biojava/bio/structure/align/util/AtomCacheTest.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
import org.biojava.bio.structure.Structure;
3333
import org.biojava.bio.structure.StructureException;
3434
import org.biojava.bio.structure.StructureTools;
35+
import org.biojava.bio.structure.scop.ScopDatabase;
3536
import org.biojava.bio.structure.scop.ScopFactory;
3637
import org.junit.Before;
3738
import org.junit.Test;
@@ -118,4 +119,22 @@ public void testGetStructureForDomain3() throws IOException, StructureException
118119
assertEquals(1, ligandsE.size());
119120
}
120121

122+
/**
123+
* Test parsing of chain-less ranges (present in SCOP < 1.73)
124+
* @throws IOException
125+
* @throws StructureException
126+
*/
127+
@Test
128+
public void testGetStructureForChainlessDomains() throws IOException, StructureException {
129+
ScopDatabase scop = ScopFactory.getSCOP(ScopFactory.VERSION_1_71); // Uses the range '1-135' without a chain
130+
Structure structure = cache.getStructureForDomain("d1hcy_1",scop);
131+
assertEquals(1, structure.getChains().size());
132+
Chain a = structure.getChainByPDB("A");
133+
int expectedLengthA = 135+4;
134+
assertEquals(expectedLengthA, a.getAtomGroups().size());
135+
List<Group> ligandsE = StructureTools.filterLigands(a.getAtomGroups());
136+
assertEquals(4, ligandsE.size());
137+
138+
}
139+
121140
}

integrationtest/src/test/java/org/biojava/structure/test/scop/ScopDatabaseTest.java

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,10 @@
2424

2525
package org.biojava.structure.test.scop;
2626

27-
import static org.junit.Assert.assertEquals;
28-
import static org.junit.Assert.assertFalse;
29-
import static org.junit.Assert.assertNotNull;
30-
import static org.junit.Assert.assertNull;
31-
import static org.junit.Assert.assertTrue;
27+
import static org.junit.Assert.*;
3228

3329
import java.util.List;
30+
import java.util.regex.Pattern;
3431

3532
import org.biojava.bio.structure.scop.ScopCategory;
3633
import org.biojava.bio.structure.scop.ScopDatabase;
@@ -102,7 +99,7 @@ public void traverseHierarchy()
10299
desc = scop.getScopDescriptionBySunid(node.getSunid());
103100
assertEquals(tag,46487,node.getSunid());
104101
assertEquals(tag,"-",desc.getName());
105-
assertEquals(tag,"Human (Homo sapiens) [TaxId: 9606]",desc.getDescription());
102+
assertTrue(tag,Pattern.matches("Human \\(Homo sapiens\\)( \\[TaxId: 9606\\])?",desc.getDescription()));
106103
assertEquals(tag,"a.1.1.2",desc.getClassificationId());
107104

108105
node = scop.getScopNode(node.getParentSunid());
@@ -206,13 +203,18 @@ public void testComments() {
206203

207204
//TODO add additional version checks, since comments change a lot
208205

209-
if(scop.getScopVersion().compareToIgnoreCase( ScopFactory.VERSION_1_75) <= 0 ) {
206+
if(scop.getScopVersion().compareToIgnoreCase( ScopFactory.VERSION_1_71) >= 0 ) {
207+
comments = scop.getComments(15016);
208+
assertEquals(tag+"Wrong number of comments", 1, comments.size());
209+
assertEquals(tag+"Wrong comment", "complexed with cmo, hem", comments.get(0).trim());
210+
}
211+
if(scop.getScopVersion().compareToIgnoreCase( ScopFactory.VERSION_1_75) >= 0 ) {
210212
// Note: only tested so far with 1.75, so may need some modification for earlier versions
211213

212214
comments = scop.getComments(127355);
213215
assertEquals(tag+"Wrong number of comments", 2, comments.size());
214216
assertEquals(tag+"Wrong comment", "automatically matched to d2hbia_", comments.get(0).trim());
215-
assertEquals(tag+"Wrong comment", "complexed with hem; mutant", comments.get(1).trim());
217+
assertTrue(tag+"Wrong comment", Pattern.matches("complexed with hem(; mutant)?", comments.get(1).trim()));
216218
}
217219
if(scop.getScopVersion().compareToIgnoreCase( ScopFactory.VERSION_1_75) == 0 ) {
218220
comments = scop.getComments(160555);

integrationtest/src/test/java/org/biojava/structure/test/scop/ScopInstallationTest.java

Lines changed: 30 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -40,36 +40,37 @@
4040
@RunWith(Parameterized.class)
4141
public class ScopInstallationTest extends ScopDatabaseTest {
4242

43-
public ScopInstallationTest(String tag,ScopDatabase scop) {
44-
super(tag,scop);
45-
}
43+
public ScopInstallationTest(String tag,ScopDatabase scop) {
44+
super(tag,scop);
45+
}
4646

47-
//@Parameters
48-
@Parameters(name="{0}")
49-
public static Collection<Object[]> availableDatabases() {
50-
ArrayList<Object[]> databases = new ArrayList<Object[]>();
51-
ScopInstallation scop;
47+
//@Parameters
48+
@Parameters(name="{0}")
49+
public static Collection<Object[]> availableDatabases() {
50+
ArrayList<Object[]> databases = new ArrayList<Object[]>();
51+
ScopInstallation scop;
5252

53-
for(String version : new String[] {
54-
ScopFactory.VERSION_1_75,
55-
ScopFactory.VERSION_1_73,
56-
}) {
57-
scop = new ScopInstallation();
58-
scop.setScopVersion(version);
59-
60-
// Don't fail if the server is down
61-
boolean reachable = false;
62-
for(ScopMirror mirror: scop.getMirrors()) {
63-
if(mirror.isReachable()) {
64-
reachable = true;
65-
break;
66-
}
67-
}
68-
Assume.assumeTrue("SCOP server is currently unreachable.",reachable);
69-
70-
databases.add(new Object[] {version, scop});
71-
}
72-
return databases;
73-
}
53+
for(String version : new String[] {
54+
ScopFactory.VERSION_1_75,
55+
ScopFactory.VERSION_1_73,
56+
ScopFactory.VERSION_1_71,
57+
}) {
58+
scop = new ScopInstallation();
59+
scop.setScopVersion(version);
60+
61+
// Don't fail if the server is down
62+
boolean reachable = false;
63+
for(ScopMirror mirror: scop.getMirrors()) {
64+
if(mirror.isReachable()) {
65+
reachable = true;
66+
break;
67+
}
68+
}
69+
Assume.assumeTrue("SCOP server is currently unreachable.",reachable);
70+
71+
databases.add(new Object[] {version, scop});
72+
}
73+
return databases;
74+
}
7475

7576
}

0 commit comments

Comments
 (0)