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