001/* 002 * BioJava development code 003 * 004 * This code may be freely distributed and modified under the 005 * terms of the GNU Lesser General Public Licence. This should 006 * be distributed with the code. If you do not have a copy, 007 * see: 008 * 009 * http://www.gnu.org/copyleft/lesser.html 010 * 011 * Copyright for this code is held jointly by the individual 012 * authors. These should be listed in @author doc comments. 013 * 014 * For more information on the BioJava project and its aims, 015 * or to join the biojava-l mailing list, visit the home page 016 * at: 017 * 018 * http://www.biojava.org/ 019 * 020 */ 021package org.biojava.nbio.structure.secstruc; 022 023import java.io.BufferedReader; 024import java.io.File; 025import java.io.FileReader; 026import java.io.IOException; 027import java.io.InputStream; 028import java.io.InputStreamReader; 029import java.io.Reader; 030import java.io.StringReader; 031import java.net.URL; 032import java.util.ArrayList; 033import java.util.List; 034import java.util.zip.GZIPInputStream; 035 036import org.biojava.nbio.structure.Group; 037import org.biojava.nbio.structure.ResidueNumber; 038import org.biojava.nbio.structure.Structure; 039import org.biojava.nbio.structure.StructureException; 040import org.slf4j.Logger; 041import org.slf4j.LoggerFactory; 042 043/** 044 * Class to parse a DSSP file (output of the DSSP program), 045 * that contains the secondary structure assignment of a structure. 046 * <p> 047 * This class has been ported from the OWL Java library for 048 * Structural Bioinformatics (https://github.com/eppic-team/owl). 049 * <p> 050 * As of September 2015, the DSSP source code and executables can 051 * be downloaded from http://swift.cmbi.ru.nl/gv/dssp/. 052 * 053 * @author Aleix Lafita 054 * @since 4.1.1 055 * 056 */ 057public class DSSPParser { 058 059 private static final Logger logger = 060 LoggerFactory.getLogger(DSSPParser.class); 061 062 /** 063 * Parse a DSSP output file and return the secondary structure 064 * annotation as a List of {@link SecStrucState} objects. 065 * 066 * @param dsspIs an InputStream to a DSSP file 067 * @param structure Structure object associated to the dssp 068 * @param assign assigns the SS to the structure if true 069 * @return a List of SS annotation objects 070 * @throws StructureException 071 * @throws IOException 072 */ 073 public static List<SecStrucState> parseInputStream(InputStream dsspIs, 074 Structure structure, boolean assign) 075 throws IOException, StructureException { 076 077 BufferedReader reader = new BufferedReader(new InputStreamReader(dsspIs)); 078 return generalParse(reader, structure, assign); 079 } 080 081 /** 082 * Parse a DSSP output file and return the secondary structure 083 * annotation as a List of {@link SecStrucState} objects. 084 * 085 * @param dsspPath path to the DSSP file to parse 086 * @param structure Structure object associated to the dssp 087 * @param assign assigns the SS to the structure if true 088 * @return a List of SS annotation objects 089 * @throws StructureException 090 * @throws IOException 091 */ 092 public static List<SecStrucState> parseFile(String dsspPath, 093 Structure structure, boolean assign) 094 throws IOException, StructureException { 095 096 File file = new File(dsspPath); 097 Reader read = new FileReader(file); 098 BufferedReader reader = new BufferedReader(read); 099 return generalParse(reader, structure, assign); 100 } 101 102 /** 103 * Fetch and parse the DSSP file of the specified pdb code 104 * from the PDB web server and return the secondary structure 105 * annotation as a List of {@link SecStrucState} objects. 106 * 107 * @param pdb path to the DSSP file to parse 108 * @param structure Structure object associated to the dssp 109 * @param assign assigns the SS to the structure if true 110 * @return a List of SS annotation objects 111 * @throws StructureException 112 * @throws IOException 113 */ 114 public static List<SecStrucState> fetch(String pdb, 115 Structure structure, boolean assign) 116 throws IOException, StructureException { 117 118 URL url = new URL("http://files.rcsb.org/dssp/" + 119 pdb.toLowerCase().substring(1, 3) + "/" + 120 pdb.toLowerCase() + "/" + 121 pdb.toLowerCase() + ".dssp.gz"); 122 InputStream in = new GZIPInputStream(url.openStream()); 123 Reader read = new InputStreamReader(in); 124 BufferedReader reader = new BufferedReader(read); 125 return generalParse(reader, structure, assign); 126 } 127 128 /** 129 * Parse a DSSP format String and return the secondary structure 130 * annotation as a List of {@link SecStrucState} objects. 131 * 132 * @param dsspOut String with the DSSP output to parse 133 * @param structure Structure object associated to the dssp 134 * @param assign assigns the SS to the structure if true 135 * @return a List of SS annotation objects 136 * @throws StructureException 137 * @throws IOException 138 */ 139 public static List<SecStrucState> parseString(String dsspOut, 140 Structure structure, boolean assign) 141 throws IOException, StructureException { 142 143 Reader read = new StringReader(dsspOut); 144 BufferedReader reader = new BufferedReader(read); 145 return generalParse(reader, structure, assign); 146 } 147 148 private static List<SecStrucState> generalParse(BufferedReader reader, 149 Structure structure, boolean assign) 150 throws IOException, StructureException { 151 152 String startLine = " # RESIDUE AA STRUCTURE BP1 BP2 ACC"; 153 String line; 154 155 List<SecStrucState> secstruc = new ArrayList<SecStrucState>(); 156 157 //Find the first line of the DSSP output 158 while((line = reader.readLine()) != null) { 159 if(line.startsWith(startLine)) break; 160 } 161 162 while((line = reader.readLine()) != null) { 163 164 String indexStr = line.substring(0,5).trim(); 165 String resNumStr = line.substring(5,10).trim(); 166 167 //Only happens if dssp inserts a line indicating a chain break 168 if(!resNumStr.equals("")) { 169 170 int index = Integer.parseInt(indexStr); 171 //Get the group of the structure corresponding to the residue 172 int resNum = Integer.parseInt(resNumStr); 173 char insCode = line.charAt(10); 174 String chainId = line.substring(11,13).trim(); 175 ResidueNumber r = new ResidueNumber(chainId, resNum, insCode); 176 Group parent = structure.getPolyChainByPDB(chainId) 177 .getGroupByPDB(r); 178 SecStrucType ssType = 179 SecStrucType.fromCharacter(line.charAt(16)); 180 181 SecStrucState ss = new SecStrucState(parent, 182 SecStrucInfo.DSSP_ASSIGNMENT, ssType); 183 184 //Parse the Bridge partners - TODO parallel or antiparallel? 185 String bp = line.substring(25,29).trim(); 186 if (bp != "") { 187 BetaBridge bb = new BetaBridge( 188 index, Integer.valueOf(bp), BridgeType.parallel); 189 ss.addBridge(bb); 190 } else logger.warn("Unable to parse beta Bridge for resn "+index); 191 192 bp = line.substring(29,33).trim(); 193 if (bp != "") { 194 BetaBridge bb = new BetaBridge( 195 index, Integer.valueOf(bp), BridgeType.parallel); 196 ss.addBridge(bb); 197 } else logger.warn("Unable to parse beta Bridge for resn "+index); 198 199 //Parse the energy terms of donor and acceptor 200 for (int i=0; i<4; i++){ 201 202 int a = 42 + i*11; 203 int b = a + 8; 204 205 String val = line.substring(a,b).trim(); 206 if (val == "") { 207 logger.warn("Unable to parse energy for resn "+index); 208 continue; 209 } 210 211 String[] p = val.split(","); 212 213 int partner = Integer.parseInt(p[0]); 214 if (partner != 0) partner += index; 215 double energy = Double.valueOf(p[1]) * 1000.0; 216 217 switch(i){ 218 case 0: 219 ss.getAccept1().setPartner(partner); 220 ss.getAccept1().setEnergy(energy); 221 break; 222 case 1: 223 ss.getDonor1().setPartner(partner); 224 ss.getDonor1().setEnergy(energy); 225 break; 226 case 2: 227 ss.getAccept2().setPartner(partner); 228 ss.getAccept2().setEnergy(energy); 229 break; 230 case 3: 231 ss.getDonor2().setPartner(partner); 232 ss.getDonor1().setEnergy(energy); 233 break; 234 } 235 } 236 237 //Angle properties 238 String val = line.substring(91,97).trim(); 239 if (val != "") ss.setKappa(Float.valueOf(val)); 240 else logger.warn("Unable to parse kappa for resn "+index); 241 242 val = line.substring(103,109).trim(); 243 if (val != "") ss.setPhi(Float.valueOf(val)); 244 else logger.warn("Unable to parse phi for resn "+index); 245 246 val = line.substring(109,116).trim(); 247 if (val != "") ss.setPsi(Float.valueOf(val)); 248 else logger.warn("Unable to parse psi for resn "+index); 249 250 if (assign) parent.setProperty(Group.SEC_STRUC, ss); 251 secstruc.add(ss); 252 } 253 } 254 255 reader.close(); 256 return secstruc; 257 } 258 259}