1 /* $RCSfile$ 2 * $Author: hansonr $ 3 * $Date: 2006-03-15 07:52:29 -0600 (Wed, 15 Mar 2006) $ 4 * $Revision: 4614 $ 5 * 6 * Copyright (C) 2003-2005 Miguel, Jmol Development, www.jmol.org 7 * 8 * Contact: jmol-developers@lists.sf.net 9 * 10 * This library is free software; you can redistribute it and/or 11 * modify it under the terms of the GNU Lesser General Public 12 * License as published by the Free Software Foundation; either 13 * version 2.1 of the License, or (at your option) any later version. 14 * 15 * This library is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 18 * Lesser General Public License for more details. 19 * 20 * You should have received a copy of the GNU Lesser General Public 21 * License along with this library; if not, write to the Free Software 22 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 23 */ 24 25 package org.jmol.adapter.readers.more; 26 27 import javajs.util.Lst; 28 29 import org.jmol.adapter.smarter.Atom; 30 import org.jmol.util.Logger; 31 32 /** 33 * A reader for Amber Molecular Dynamics topology files -- 34 * requires subsequent COORD "xxxx.mdcrd" file 35 * 36 *<p> 37 * <a href=''> 38 * 39 * </a> 40 * 41 * PDB note: 42 * 43 * Note that topology format does not include chain designations, 44 * chain terminator, chain designator, or element symbol. 45 * 46 * Chains based on numbering reset just labeled A B C D .... Z a b c d .... z 47 * Element symbols based on reasoned guess and properties of hetero groups 48 * 49 * In principal we could use average atomic mass. 50 * 51 * 52 *<p> 53 */ 54 55 public class MdTopReader extends ForceFieldReader { 56 57 private int nAtoms = 0; 58 private int ac = 0; 59 60 @Override initializeReader()61 protected void initializeReader() throws Exception { 62 setIsPDB(); 63 setUserAtomTypes(); 64 } 65 66 @Override checkLine()67 protected boolean checkLine() throws Exception { 68 if (line.indexOf("%FLAG ") != 0) 69 return true; 70 line = line.substring(6).trim(); 71 if (line.equals("POINTERS")) 72 getPointers(); 73 else if (line.equals("ATOM_NAME")) 74 getAtomNames(); 75 else if (line.equals("CHARGE")) 76 getCharges(); 77 else if (line.equals("RESIDUE_LABEL")) 78 getResidueLabels(); 79 else if (line.equals("RESIDUE_POINTER")) 80 getResiduePointers(); 81 else if (line.equals("AMBER_ATOM_TYPE")) 82 getAtomTypes(); 83 else if (line.equals("MASS")) 84 getMasses(); 85 return false; 86 } 87 88 @Override finalizeSubclassReader()89 protected void finalizeSubclassReader() throws Exception { 90 finalizeReaderASCR(); 91 Atom[] atoms = asc.atoms; 92 Atom atom; 93 for (int i = 0; i < ac; i++) { 94 atom = atoms[i]; 95 atom.isHetero = vwr.getJBR().isHetero(atom.group3); 96 String atomType = atomTypes[i]; 97 if (!getElementSymbol(atom, atomType)) 98 atom.elementSymbol = deducePdbElementSymbol(atom.isHetero, 99 atom.atomName, atom.group3); 100 } 101 Atom[] atoms2 = null; 102 if (filter == null) { 103 nAtoms = ac; 104 } else { 105 atoms2 = new Atom[atoms.length]; 106 nAtoms = 0; 107 for (int i = 0; i < ac; i++) 108 if (filterAtom(atoms[i], i)) 109 atoms2[nAtoms++] = atoms[i]; 110 } 111 for (int i = 0, j = 0, k = 0; i < ac; i++) { 112 if (filter == null || bsFilter.get(i)) { 113 if (k % 100 == 0) 114 j++; 115 setAtomCoordXYZ(atoms[i], (i % 100) * 2, j * 2, 0); 116 } 117 } 118 if (atoms2 != null) { 119 discardPreviousAtoms(); 120 for (int i = 0; i < nAtoms; i++) 121 asc.addAtom(atoms2[i]); 122 } 123 Logger.info("Total number of atoms used=" + nAtoms); 124 setModelPDB(true); 125 htParams.put("defaultType", "mdcrd"); 126 } 127 getDataBlock()128 private String[] getDataBlock() throws Exception { 129 Lst<String> vdata = new Lst<String>(); 130 // for these purposes, we just read the first length 131 discardLinesUntilContains("FORMAT"); 132 int n = getFortranFormatLengths(line.substring(line.indexOf("("))).get(0).intValue(); 133 int i = 0; 134 int len = 0; 135 while (true) { 136 if (i >= len) { 137 if (rd() == null) 138 break; 139 i = 0; 140 len = line.length(); 141 if (len == 0 || line.indexOf("FLAG") >= 0) 142 break; 143 } 144 vdata.addLast(line.substring(i, i + n).trim()); 145 i += n; 146 } 147 return vdata.toArray(new String[vdata.size()]); 148 } 149 150 /* 151 FORMAT(12i6) NATOM, NTYPES, NBONH, MBONA, NTHETH, MTHETA, 152 NPHIH, MPHIA, NHPARM, NPARM, NEXT, NRES, 153 NBONA, NTHETA, NPHIA, NUMBND, NUMANG, NPTRA, 154 NATYP, NPHB, IFPERT, NBPER, NGPER, NDPER, 155 MBPER, MGPER, MDPER, IFBOX, NMXRS, IFCAP 156 NATOM : total number of atoms 157 NTYPES : total number of distinct atom types 158 NBONH : number of bonds containing hydrogen 159 MBONA : number of bonds not containing hydrogen 160 NTHETH : number of angles containing hydrogen 161 MTHETA : number of angles not containing hydrogen 162 NPHIH : number of dihedrals containing hydrogen 163 MPHIA : number of dihedrals not containing hydrogen 164 NHPARM : currently not used 165 NPARM : currently not used 166 NEXT : number of excluded atoms 167 NRES : number of residues 168 NBONA : MBONA + number of constraint bonds 169 NTHETA : MTHETA + number of constraint angles 170 NPHIA : MPHIA + number of constraint dihedrals 171 NUMBND : number of unique bond types 172 NUMANG : number of unique angle types 173 NPTRA : number of unique dihedral types 174 NATYP : number of atom types in parameter file, see SOLTY below 175 NPHB : number of distinct 10-12 hydrogen bond pair types 176 IFPERT : set to 1 if perturbation info is to be read in 177 NBPER : number of bonds to be perturbed 178 NGPER : number of angles to be perturbed 179 NDPER : number of dihedrals to be perturbed 180 MBPER : number of bonds with atoms completely in perturbed group 181 MGPER : number of angles with atoms completely in perturbed group 182 MDPER : number of dihedrals with atoms completely in perturbed groups 183 IFBOX : set to 1 if standard periodic box, 2 when truncated octahedral 184 NMXRS : number of atoms in the largest residue 185 IFCAP : set to 1 if the CAP option from edit was specified 186 187 %FLAG POINTERS 188 %FORMAT(10I8) 189 37300 16 29669 6234 12927 6917 28267 6499 0 0 190 87674 9013 6234 6917 6499 47 101 41 31 1 191 0 0 0 0 0 0 0 1 24 0 192 0 193 194 0 1 2 3 4 5 6 7 195 01234567890123456789012345678901234567890123456789012345678901234567890123456789 196 197 */ getPointers()198 private void getPointers() throws Exception { 199 String[] tokens = getDataBlock(); 200 ac = parseIntStr(tokens[0]); 201 boolean isPeriodic = (tokens[27].charAt(0) != '0'); 202 if (isPeriodic) { 203 Logger.info("Periodic type: " + tokens[27]); 204 htParams.put("isPeriodic", Boolean.TRUE); 205 } 206 Logger.info("Total number of atoms read=" + ac); 207 htParams.put("templateAtomCount", Integer.valueOf(ac)); 208 for (int i = 0; i < ac; i++) 209 asc.addAtom(new Atom()); 210 } 211 212 private String[] atomTypes; getAtomTypes()213 private void getAtomTypes() throws Exception { 214 atomTypes = getDataBlock(); 215 } 216 217 /* 218 %FLAG CHARGE 219 %FORMAT(5E16.8) 220 5.66713530E-01 4.24397367E+00 4.24397367E+00 4.24397367E+00 4.68313110E-01 221 1.87871913E+00 3.43490355E+00 3.88134990E-01 -6.77869560E+00 1.72565181E+00 222 1.72565181E+00 1.72565181E+00 -7.05203010E-01 3.66268230E-01 3.66268230E-01 223 224 */ getCharges()225 private void getCharges() throws Exception { 226 String[] data = getDataBlock(); 227 if (data.length != ac) 228 return; 229 Atom[] atoms = asc.atoms; 230 for (int i = ac; --i >= 0;) 231 atoms[i].partialCharge = parseFloatStr(data[i]); 232 } 233 getResiduePointers()234 private void getResiduePointers() throws Exception { 235 String[] resPtrs = getDataBlock(); 236 Logger.info("Total number of residues=" + resPtrs.length); 237 int pt1 = ac; 238 int pt2; 239 Atom[] atoms = asc.atoms; 240 for (int i = resPtrs.length; --i >= 0;) { 241 int ptr = pt2 = parseIntStr(resPtrs[i]) - 1; 242 while (ptr < pt1) { 243 if (group3s != null) 244 atoms[ptr].group3 = group3s[i]; 245 atoms[ptr++].sequenceNumber = i + 1; 246 } 247 pt1 = pt2; 248 } 249 } 250 251 String[] group3s; 252 getResidueLabels()253 private void getResidueLabels() throws Exception { 254 group3s = getDataBlock(); 255 } 256 257 /* 258 %FLAG ATOM_NAME 259 %FORMAT(20a4) 260 N H1 H2 H3 CA HA CB HB CG2 HG21HG22HG23CG1 HG12HG13CD1 HD11HD12HD13C 261 O N H CA HA CB HB2 HB3 SG HG C O N H CA HA CB HB CG1 HG11 262 HG12HG13CG2 HG21HG22HG23C O N H CA HA CB HB2 HB3 CG CD1 HD1 CE1 HE1 263 CZ OH HH CE2 HE2 CD2 HD2 C O N H CA HA CB HB CG1 HG11HG12HG13CG2 264 */ 265 getAtomNames()266 private void getAtomNames() throws Exception { 267 String[] names = getDataBlock(); 268 Atom[] atoms = asc.atoms; 269 for (int i = 0; i < ac; i++) 270 atoms[i].atomName = names[i]; 271 } 272 getMasses()273 private void getMasses() throws Exception { 274 /* float[] data = new float[ac]; 275 readLine(); 276 getTokensFloat(getDataBlock(), data, ac); 277 */ 278 } 279 280 281 } 282