Skip to content

Commit 50c34d3

Browse files
author
Matt Larson
committed
Added exception handler for out-of-bounds errors when parsing lines, usually indicative of misformated lines.
Added line length checks within the LINK and CONECT parsing blocks to allow for short lines to be parsed.
1 parent e2cc068 commit 50c34d3

2 files changed

Lines changed: 138 additions & 51 deletions

File tree

‎biojava-structure/src/main/java/org/biojava/nbio/structure/io/PDBFileParser.java‎

Lines changed: 64 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -2017,6 +2017,8 @@ private void switchCAOnly(){
20172017

20182018
/** safes repeating a few lines ... */
20192019
private Integer conect_helper (String line,int start,int end) {
2020+
if (line.length() < end) return null;
2021+
20202022
String sbond = line.substring(start,end).trim();
20212023
int bond = -1 ;
20222024
Integer b = null ;
@@ -2343,7 +2345,15 @@ private void pdb_SSBOND_Handler(String line){
23432345
private void pdb_LINK_Handler(String line) {
23442346

23452347
if (params.isHeaderOnly()) return;
2348+
2349+
// Check for the minimal set of fields.
2350+
if (line.length()<56) {
2351+
logger.info("LINK line has length under 56. Ignoring it.");
2352+
return;
2353+
}
23462354

2355+
int len = line.length();
2356+
23472357
String name1 = line.substring(12, 16).trim();
23482358
String altLoc1 = line.substring(16, 17).trim();
23492359
String resName1 = line.substring(17, 20).trim();
@@ -2356,10 +2366,13 @@ private void pdb_LINK_Handler(String line) {
23562366
String resName2 = line.substring(47, 50).trim();
23572367
String chainID2 = line.substring(51, 52).trim();
23582368
String resSeq2 = line.substring(52, 56).trim();
2359-
String iCode2 = line.substring(56, 57).trim();
2369+
String iCode2 = null; // Might get trimmed if blank.
2370+
if (len > 56) iCode2 = line.substring(56, 57).trim();
23602371

2361-
String sym1 = line.substring(59, 65).trim();
2362-
String sym2 = line.substring(66, 72).trim();
2372+
String sym1 = null;
2373+
if (len > 64) sym1 = line.substring(59, 65).trim();
2374+
String sym2 = null;
2375+
if (len > 71) sym2 = line.substring(66, 72).trim();
23632376

23642377
// System.err.println("LINK");
23652378
// System.err.println("\tName: " + name1);
@@ -2690,54 +2703,54 @@ public Structure parsePDBFile(BufferedReader buf)
26902703

26912704
String recordName = line.substring (0, 6).trim ();
26922705

2693-
if (recordName.equals("ATOM"))
2694-
pdb_ATOM_Handler(line);
2695-
else if (recordName.equals("SEQRES"))
2696-
pdb_SEQRES_Handler(line);
2697-
else if (recordName.equals("HETATM"))
2698-
pdb_ATOM_Handler(line);
2699-
else if (recordName.equals("MODEL"))
2700-
pdb_MODEL_Handler(line);
2701-
else if (recordName.equals("HEADER"))
2702-
pdb_HEADER_Handler(line);
2703-
else if (recordName.equals("AUTHOR"))
2704-
pdb_AUTHOR_Handler(line);
2705-
else if (recordName.equals("TITLE"))
2706-
pdb_TITLE_Handler(line);
2707-
else if (recordName.equals("SOURCE"))
2708-
sourceLines.add(line); //pdb_SOURCE_Handler
2709-
else if (recordName.equals("COMPND"))
2710-
compndLines.add(line); //pdb_COMPND_Handler
2711-
else if (recordName.equals("JRNL"))
2712-
pdb_JRNL_Handler(line);
2713-
else if (recordName.equals("EXPDTA"))
2714-
pdb_EXPDTA_Handler(line);
2715-
else if (recordName.equals("CRYST1"))
2716-
pdb_CRYST1_Handler(line);
2717-
else if (recordName.startsWith("MTRIX"))
2718-
pdb_MTRIXn_Handler(line);
2719-
else if (recordName.equals("REMARK"))
2720-
pdb_REMARK_Handler(line);
2721-
else if (recordName.equals("CONECT"))
2722-
pdb_CONECT_Handler(line);
2723-
else if (recordName.equals("REVDAT"))
2724-
pdb_REVDAT_Handler(line);
2725-
else if (recordName.equals("DBREF"))
2726-
pdb_DBREF_Handler(line);
2727-
else if (recordName.equals("SITE"))
2728-
pdb_SITE_Handler(line);
2729-
else if (recordName.equals("SSBOND"))
2730-
pdb_SSBOND_Handler(line);
2731-
else if (recordName.equals("LINK"))
2732-
pdb_LINK_Handler(line);
2733-
else if ( params.isParseSecStruc()) {
2734-
if ( recordName.equals("HELIX") ) pdb_HELIX_Handler ( line ) ;
2735-
else if (recordName.equals("SHEET")) pdb_SHEET_Handler(line ) ;
2736-
else if (recordName.equals("TURN")) pdb_TURN_Handler( line ) ;
2737-
}
2738-
else {
2739-
// this line type is not supported, yet.
2740-
// we ignore it
2706+
try {
2707+
if (recordName.equals("ATOM"))
2708+
pdb_ATOM_Handler(line);
2709+
else if (recordName.equals("SEQRES"))
2710+
pdb_SEQRES_Handler(line);
2711+
else if (recordName.equals("HETATM"))
2712+
pdb_ATOM_Handler(line);
2713+
else if (recordName.equals("MODEL"))
2714+
pdb_MODEL_Handler(line);
2715+
else if (recordName.equals("HEADER"))
2716+
pdb_HEADER_Handler(line);
2717+
else if (recordName.equals("AUTHOR"))
2718+
pdb_AUTHOR_Handler(line);
2719+
else if (recordName.equals("TITLE"))
2720+
pdb_TITLE_Handler(line);
2721+
else if (recordName.equals("SOURCE"))
2722+
sourceLines.add(line); //pdb_SOURCE_Handler
2723+
else if (recordName.equals("COMPND"))
2724+
compndLines.add(line); //pdb_COMPND_Handler
2725+
else if (recordName.equals("JRNL"))
2726+
pdb_JRNL_Handler(line);
2727+
else if (recordName.equals("EXPDTA"))
2728+
pdb_EXPDTA_Handler(line);
2729+
else if (recordName.equals("CRYST1"))
2730+
pdb_CRYST1_Handler(line);
2731+
else if (recordName.startsWith("MTRIX"))
2732+
pdb_MTRIXn_Handler(line);
2733+
else if (recordName.equals("REMARK"))
2734+
pdb_REMARK_Handler(line);
2735+
else if (recordName.equals("CONECT"))
2736+
pdb_CONECT_Handler(line);
2737+
else if (recordName.equals("REVDAT"))
2738+
pdb_REVDAT_Handler(line);
2739+
else if (recordName.equals("DBREF"))
2740+
pdb_DBREF_Handler(line);
2741+
else if (recordName.equals("SITE"))
2742+
pdb_SITE_Handler(line);
2743+
else if (recordName.equals("SSBOND"))
2744+
pdb_SSBOND_Handler(line);
2745+
else if (recordName.equals("LINK"))
2746+
pdb_LINK_Handler(line);
2747+
else if ( params.isParseSecStruc()) {
2748+
if ( recordName.equals("HELIX") ) pdb_HELIX_Handler ( line ) ;
2749+
else if (recordName.equals("SHEET")) pdb_SHEET_Handler(line ) ;
2750+
else if (recordName.equals("TURN")) pdb_TURN_Handler( line ) ;
2751+
}
2752+
} catch (StringIndexOutOfBoundsException ex) {
2753+
logger.info("Unable to parse [" + line + "]");
27412754
}
27422755

27432756

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
package org.biojava.nbio.structure.io;
2+
3+
import static org.junit.Assert.assertEquals;
4+
5+
import java.io.ByteArrayInputStream;
6+
import java.io.IOException;
7+
import java.io.InputStream;
8+
9+
import org.biojava.nbio.structure.Atom;
10+
import org.biojava.nbio.structure.Chain;
11+
import org.biojava.nbio.structure.Group;
12+
import org.biojava.nbio.structure.Structure;
13+
import org.junit.Test;
14+
15+
/**
16+
* This class will test parsing short CONECT lines.
17+
* <p>(c) 2016 DNASTAR, Inc.</p>
18+
* @since Nov 30, 2016
19+
* @author larsonm
20+
*/
21+
public class TestShortLines {
22+
23+
@Test
24+
public void testConect() throws IOException {
25+
PDBFileParser pdbPars = new PDBFileParser();
26+
FileParsingParameters params = pdbPars.getFileParsingParameters();
27+
params.setCreateAtomBonds(true);
28+
29+
// CONECTS will be deprecated, but will we create bonds?
30+
// Like the LINK records, should BioJava create BondImpl when params.setCreateAtomBonds(true)?
31+
32+
StringBuilder sb = new StringBuilder();
33+
sb.append("HETATM 2398 P FAD A 500 8.398 46.448 73.490 1.00 13.51 P \n");
34+
sb.append("HETATM 2399 PA FAD A 500 6.089 45.580 75.235 1.00 15.88 P \n");
35+
sb.append("HETATM 2400 O1P FAD A 500 7.908 47.684 72.869 1.00 4.19 O \n");
36+
sb.append("CONECT 2400 2398\n");
37+
String shortLine = sb.toString();
38+
Structure s;
39+
// Parse short
40+
try(InputStream is = new ByteArrayInputStream(shortLine.getBytes())) {
41+
s = pdbPars.parsePDBFile(is);
42+
}
43+
44+
// After 4.2, CONECTS are deprecated, but there is not yet an implementation
45+
// describing how CONECTS will be replaced - will Bonds be created?
46+
assertEquals(1, s.getConnections().size());
47+
}
48+
49+
@Test
50+
public void testLINK() throws IOException {
51+
Structure s;
52+
PDBFileParser pdbPars = new PDBFileParser();
53+
FileParsingParameters params = pdbPars.getFileParsingParameters();
54+
params.setCreateAtomBonds(true);
55+
56+
StringBuilder sb = new StringBuilder();
57+
sb.append("ATOM 2412 C21 2EG A 7 0.888 44.973 72.238 1.00 29.17 C \n");
58+
sb.append("ATOM 2413 C22 2EG B 19 0.888 44.973 72.238 1.00 29.17 C \n");
59+
//sb.append("LINK C21 2EG A 7 C22 2EG B 19 1555 1555 1.56 ");
60+
sb.append("LINK C21 2EG A 7 C22 2EG B 19\n");
61+
String shortLine = sb.toString();
62+
63+
// Parse short
64+
try(InputStream is = new ByteArrayInputStream(shortLine.getBytes())) {
65+
s = pdbPars.parsePDBFile(is);
66+
}
67+
68+
// Should be a bond present in the Atoms.
69+
Chain c = s.getChain(0, 0);
70+
Group g = c.getAtomGroups().get(0);
71+
Atom a = g.getAtom(0);
72+
assertEquals(1, a.getBonds().size());
73+
}
74+
}

0 commit comments

Comments
 (0)