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 dsspPath path to the DSSP file to parse 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> parseFile(String dsspPath, 074 Structure structure, boolean assign) 075 throws IOException, StructureException { 076 077 File file = new File(dsspPath); 078 Reader read = new FileReader(file); 079 BufferedReader reader = new BufferedReader(read); 080 return generalParse(reader, structure, assign); 081 } 082 083 /** 084 * Fetch and parse the DSSP file of the specified pdb code 085 * from the PDB web server and return the secondary structure 086 * annotation as a List of {@link SecStrucState} objects. 087 * 088 * @param pdb path to the DSSP file to parse 089 * @param structure Structure object associated to the dssp 090 * @param assign assigns the SS to the structure if true 091 * @return a List of SS annotation objects 092 * @throws StructureException 093 * @throws IOException 094 */ 095 public static List<SecStrucState> fetch(String pdb, 096 Structure structure, boolean assign) 097 throws IOException, StructureException { 098 099 URL url = new URL("http://files.rcsb.org/dssp/" + 100 pdb.toLowerCase().substring(1, 3) + "/" + 101 pdb.toLowerCase() + "/" + 102 pdb + ".dssp.gz"); 103 InputStream in = new GZIPInputStream(url.openStream()); 104 Reader read = new InputStreamReader(in); 105 BufferedReader reader = new BufferedReader(read); 106 return generalParse(reader, structure, assign); 107 } 108 109 /** 110 * Parse a DSSP format String and return the secondary structure 111 * annotation as a List of {@link SecStrucState} objects. 112 * 113 * @param dsspOut String with the DSSP output to parse 114 * @param structure Structure object associated to the dssp 115 * @param assign assigns the SS to the structure if true 116 * @return a List of SS annotation objects 117 * @throws StructureException 118 * @throws IOException 119 */ 120 public static List<SecStrucState> parseString(String dsspOut, 121 Structure structure, boolean assign) 122 throws IOException, StructureException { 123 124 Reader read = new StringReader(dsspOut); 125 BufferedReader reader = new BufferedReader(read); 126 return generalParse(reader, structure, assign); 127 } 128 129 private static List<SecStrucState> generalParse(BufferedReader reader, 130 Structure structure, boolean assign) 131 throws IOException, StructureException { 132 133 String startLine = " # RESIDUE AA STRUCTURE BP1 BP2 ACC"; 134 String line; 135 136 List<SecStrucState> secstruc = new ArrayList<SecStrucState>(); 137 138 //Find the first line of the DSSP output 139 while((line = reader.readLine()) != null) { 140 if(line.startsWith(startLine)) break; 141 } 142 143 while((line = reader.readLine()) != null) { 144 145 String indexStr = line.substring(0,5).trim(); 146 String resNumStr = line.substring(5,10).trim(); 147 148 //Only happens if dssp inserts a line indicating a chain break 149 if(!resNumStr.equals("")) { 150 151 int index = Integer.valueOf(indexStr); 152 //Get the group of the structure corresponding to the residue 153 int resNum = Integer.valueOf(resNumStr); 154 char insCode = line.charAt(10); 155 String chainId = line.substring(11,13).trim(); 156 ResidueNumber r = new ResidueNumber(chainId, resNum, insCode); 157 Group parent = structure.getChainByPDB(chainId) 158 .getGroupByPDB(r); 159 SecStrucType ssType = 160 SecStrucType.fromCharacter(line.charAt(16)); 161 162 SecStrucState ss = new SecStrucState(parent, 163 SecStrucInfo.DSSP_ASSIGNMENT, ssType); 164 165 //Parse the Bridge partners - TODO parallel or antiparallel? 166 String bp = line.substring(25,29).trim(); 167 if (bp != "") { 168 BetaBridge bb = new BetaBridge( 169 index, Integer.valueOf(bp), BridgeType.parallel); 170 ss.addBridge(bb); 171 } else logger.warn("Unable to parse beta Bridge for resn "+index); 172 173 bp = line.substring(29,33).trim(); 174 if (bp != "") { 175 BetaBridge bb = new BetaBridge( 176 index, Integer.valueOf(bp), BridgeType.parallel); 177 ss.addBridge(bb); 178 } else logger.warn("Unable to parse beta Bridge for resn "+index); 179 180 //Parse the energy terms of donor and acceptor 181 for (int i=0; i<4; i++){ 182 183 int a = 42 + i*11; 184 int b = a + 8; 185 186 String val = line.substring(a,b).trim(); 187 if (val == "") { 188 logger.warn("Unable to parse energy for resn "+index); 189 continue; 190 } 191 192 String[] p = val.split(","); 193 194 int partner = Integer.valueOf(p[0]); 195 if (partner != 0) partner += index; 196 double energy = Double.valueOf(p[1]) * 1000.0; 197 198 switch(i){ 199 case 0: 200 ss.getAccept1().setPartner(partner); 201 ss.getAccept1().setEnergy(energy); 202 break; 203 case 1: 204 ss.getDonor1().setPartner(partner); 205 ss.getDonor1().setEnergy(energy); 206 break; 207 case 2: 208 ss.getAccept2().setPartner(partner); 209 ss.getAccept2().setEnergy(energy); 210 break; 211 case 3: 212 ss.getDonor2().setPartner(partner); 213 ss.getDonor1().setEnergy(energy); 214 break; 215 } 216 } 217 218 //Angle properties 219 String val = line.substring(91,97).trim(); 220 if (val != "") ss.setKappa(Float.valueOf(val)); 221 else logger.warn("Unable to parse kappa for resn "+index); 222 223 val = line.substring(103,109).trim(); 224 if (val != "") ss.setPhi(Float.valueOf(val)); 225 else logger.warn("Unable to parse phi for resn "+index); 226 227 val = line.substring(109,116).trim(); 228 if (val != "") ss.setPsi(Float.valueOf(val)); 229 else logger.warn("Unable to parse psi for resn "+index); 230 231 if (assign) parent.setProperty(Group.SEC_STRUC, ss); 232 secstruc.add(ss); 233 } 234 } 235 236 reader.close(); 237 return secstruc; 238 } 239 240}