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.util.ArrayList; 032import java.util.List; 033 034import org.biojava.nbio.structure.Group; 035import org.biojava.nbio.structure.ResidueNumber; 036import org.biojava.nbio.structure.Structure; 037import org.biojava.nbio.structure.StructureException; 038import org.slf4j.Logger; 039import org.slf4j.LoggerFactory; 040 041/** 042 * Class to parse a DSSP file (output of the DSSP program), 043 * that contains the secondary structure assignment of a structure. 044 * <p> 045 * This class has been ported from the OWL Java library for 046 * Structural Bioinformatics (https://github.com/eppic-team/owl). 047 * <p> 048 * As of September 2015, the DSSP source code and executables can 049 * be downloaded from http://swift.cmbi.ru.nl/gv/dssp/. 050 * 051 * @author Aleix Lafita 052 * @since 4.1.1 053 * 054 */ 055public class DSSPParser { 056 057 private static final Logger logger = 058 LoggerFactory.getLogger(DSSPParser.class); 059 060 /** 061 * Parse a DSSP output file and return the secondary structure 062 * annotation as a List of {@link SecStrucState} objects. 063 * 064 * @param dsspIs an InputStream to a DSSP file 065 * @param structure Structure object associated to the dssp 066 * @param assign assigns the SS to the structure if true 067 * @return a List of SS annotation objects 068 * @throws StructureException 069 * @throws IOException 070 */ 071 public static List<SecStrucState> parseInputStream(InputStream dsspIs, 072 Structure structure, boolean assign) 073 throws IOException, StructureException { 074 075 BufferedReader reader = new BufferedReader(new InputStreamReader(dsspIs)); 076 return generalParse(reader, structure, assign); 077 } 078 079 /** 080 * Parse a DSSP output file and return the secondary structure 081 * annotation as a List of {@link SecStrucState} objects. 082 * 083 * @param dsspPath path to the DSSP file to parse 084 * @param structure Structure object associated to the dssp 085 * @param assign assigns the SS to the structure if true 086 * @return a List of SS annotation objects 087 * @throws StructureException 088 * @throws IOException 089 */ 090 public static List<SecStrucState> parseFile(String dsspPath, 091 Structure structure, boolean assign) 092 throws IOException, StructureException { 093 094 File file = new File(dsspPath); 095 Reader read = new FileReader(file); 096 BufferedReader reader = new BufferedReader(read); 097 return generalParse(reader, structure, assign); 098 } 099 100 /** 101 * Parse a DSSP format String and return the secondary structure 102 * annotation as a List of {@link SecStrucState} objects. 103 * 104 * @param dsspOut String with the DSSP output to parse 105 * @param structure Structure object associated to the dssp 106 * @param assign assigns the SS to the structure if true 107 * @return a List of SS annotation objects 108 * @throws StructureException 109 * @throws IOException 110 */ 111 public static List<SecStrucState> parseString(String dsspOut, 112 Structure structure, boolean assign) 113 throws IOException, StructureException { 114 115 Reader read = new StringReader(dsspOut); 116 BufferedReader reader = new BufferedReader(read); 117 return generalParse(reader, structure, assign); 118 } 119 120 private static List<SecStrucState> generalParse(BufferedReader reader, 121 Structure structure, boolean assign) 122 throws IOException, StructureException { 123 124 String startLine = " # RESIDUE AA STRUCTURE BP1 BP2 ACC"; 125 String line; 126 127 List<SecStrucState> secstruc = new ArrayList<SecStrucState>(); 128 129 //Find the first line of the DSSP output 130 while((line = reader.readLine()) != null) { 131 if(line.startsWith(startLine)) break; 132 } 133 134 while((line = reader.readLine()) != null) { 135 136 String indexStr = line.substring(0,5).trim(); 137 String resNumStr = line.substring(5,10).trim(); 138 139 //Only happens if dssp inserts a line indicating a chain break 140 if(!resNumStr.equals("")) { 141 142 int index = Integer.parseInt(indexStr); 143 //Get the group of the structure corresponding to the residue 144 int resNum = Integer.parseInt(resNumStr); 145 char insCode = line.charAt(10); 146 String chainId = line.substring(11,13).trim(); 147 ResidueNumber r = new ResidueNumber(chainId, resNum, insCode); 148 Group parent = structure.getPolyChainByPDB(chainId) 149 .getGroupByPDB(r); 150 SecStrucType ssType = 151 SecStrucType.fromCharacter(line.charAt(16)); 152 153 SecStrucState ss = new SecStrucState(parent, 154 SecStrucInfo.DSSP_ASSIGNMENT, ssType); 155 156 //Parse the Bridge partners - TODO parallel or antiparallel? 157 String bp = line.substring(25,29).trim(); 158 if (!bp.equals("")) { 159 BetaBridge bb = new BetaBridge( 160 index, Integer.parseInt(bp), BridgeType.parallel); 161 ss.addBridge(bb); 162 } else logger.warn("Unable to parse beta Bridge for resn "+index); 163 164 bp = line.substring(29,33).trim(); 165 if (!bp.equals("")) { 166 BetaBridge bb = new BetaBridge( 167 index, Integer.parseInt(bp), BridgeType.parallel); 168 ss.addBridge(bb); 169 } else logger.warn("Unable to parse beta Bridge for resn "+index); 170 171 //Parse the energy terms of donor and acceptor 172 for (int i=0; i<4; i++){ 173 174 int a = 42 + i*11; 175 int b = a + 8; 176 177 String val = line.substring(a,b).trim(); 178 if (val.equals("")) { 179 logger.warn("Unable to parse energy for resn "+index); 180 continue; 181 } 182 183 String[] p = val.split(","); 184 185 int partner = Integer.parseInt(p[0]); 186 if (partner != 0) partner += index; 187 double energy = Double.parseDouble(p[1]) * 1000.0; 188 189 switch(i){ 190 case 0: 191 ss.getAccept1().setPartner(partner); 192 ss.getAccept1().setEnergy(energy); 193 break; 194 case 1: 195 ss.getDonor1().setPartner(partner); 196 ss.getDonor1().setEnergy(energy); 197 break; 198 case 2: 199 ss.getAccept2().setPartner(partner); 200 ss.getAccept2().setEnergy(energy); 201 break; 202 case 3: 203 ss.getDonor2().setPartner(partner); 204 ss.getDonor1().setEnergy(energy); 205 break; 206 } 207 } 208 209 //Angle properties 210 String val = line.substring(91,97).trim(); 211 if (!val.equals("")) ss.setKappa(Float.parseFloat(val)); 212 else logger.warn("Unable to parse kappa for resn "+index); 213 214 val = line.substring(103,109).trim(); 215 if (!val.equals("")) ss.setPhi(Float.parseFloat(val)); 216 else logger.warn("Unable to parse phi for resn "+index); 217 218 val = line.substring(109,116).trim(); 219 if (!val.equals("")) ss.setPsi(Float.parseFloat(val)); 220 else logger.warn("Unable to parse psi for resn "+index); 221 222 if (assign) parent.setProperty(Group.SEC_STRUC, ss); 223 secstruc.add(ss); 224 } 225 } 226 227 reader.close(); 228 return secstruc; 229 } 230 231}