org.jmol.adapter.readers.simple.FoldingXyzReader Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jmol Show documentation
Show all versions of jmol Show documentation
Jmol: an open-source Java viewer for chemical structures in 3D
/* $RCSfile$
* $Author: hansonr $
* $Date: 2006-09-10 10:36:58 -0500 (Sun, 10 Sep 2006) $
* $Revision: 5478 $
*
* Copyright (C) 2004-2005 The Jmol Development Team
*
* Contact: [email protected]
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*/
package org.jmol.adapter.readers.simple;
import org.jmol.adapter.smarter.AtomSetCollectionReader;
import org.jmol.adapter.smarter.Atom;
import java.util.Hashtable;
import java.util.Map;
import javajs.util.PT;
/**
* This reader is for current.xyz files generated by Folding@Home project
* (see http://folding.stanford.edu)
*
* I have not found a precise description of the file format.
* I used source code from fpd from Dick Howell to analyze the file format.
* (see http://boston.quik.com/rph)
* -- Nico Vervelle
*
* Extended by Bob Hanson 2/2014:
*
* - adds support for newer Tinker files (see data/folding)
* - adds desired model options
* - adds atom type if available
*
*/
public class FoldingXyzReader extends AtomSetCollectionReader {
@Override
protected void initializeReader() {
}
@Override
protected void finalizeSubclassReader() throws Exception {
if (asc.bondCount > 0)
asc.setNoAutoBond();
isTrajectory = false;
finalizeReaderASCR();
}
/**
* @return true if next line needs to be read.
*
* Note that just a single token on line 1 is NOT possible.
* If that were the case, the xyz reader would have captured this.
*
*/
@Override
protected boolean checkLine() throws Exception {
int[] next = new int[] { 0 };
String token = PT.parseTokenNext(line, next);
if (token == null)
return true;
boolean addAtoms = doGetModel(++modelNumber, null);
int modelAtomCount = parseIntStr(token);
if (addAtoms) {
asc.newAtomSet();
String[] tokens = getTokens();
asc.setAtomSetName(tokens.length == 2 ? "Protein "
+ tokens[1] : line.substring(next[0]).trim());
}
boolean readLine = readAtoms(modelAtomCount + 1, addAtoms); // Some Tinker files are one off!
continuing = !addAtoms || !isLastModel(modelNumber);
return readLine;
}
/**
* Lots of possibilities here:
*
* atom count is real; atom count is one less than true atom count
* sixth column is atom type; sixth column is first bond
*
*
* @param ac
* @param addAtoms
* @return true if next line needs to be read
* @throws Exception
*/
boolean readAtoms(int ac, boolean addAtoms) throws Exception {
// Stores bond informations
Map htBondCounts = new Hashtable();
String[][] bonds = new String[ac][];
boolean haveAtomTypes = true;
boolean checking = true;
String lastAtom = null;
boolean readNextLine = true;
for (int i = 0; i < ac; i++) {
discardLinesUntilNonBlank();
if (line == null)
break; // no problem.
String[] tokens = getTokens();
String sIndex = tokens[0];
if (sIndex.equals(lastAtom)) {
readNextLine = false;
break; // end; next structure;
}
lastAtom = sIndex;
if (!addAtoms)
continue;
Atom atom = new Atom();
atom.atomName = tokens[1];
atom.elementSymbol = getElement(tokens[1]);
atom.atomSerial = parseIntStr(sIndex);
if (!filterAtom(atom, i))
continue;
setAtomCoordTokens(atom, tokens, 2);
asc.addAtomWithMappedSerialNumber(atom);
int n = tokens.length - 5;
bonds[i] = new String[n + 1];
bonds[i][n] = sIndex;
for (int j = 0; j < n; j++) {
String t = tokens[j + 5];
int i2 = parseIntStr(t);
bonds[i][j] = t;
if (checking) {
// Tinker files may or may not include an atom type in column 6
if (n == 0 || t.equals(sIndex) || i2 <= 0 || i2 > ac) {
haveAtomTypes = (n > 0);
checking = false;
} else {
int[] count = htBondCounts.get(t);
if (count == null)
htBondCounts.put(t, count = new int[1]);
if (++count[0] > 10) // even 10 is quite many bonds!
haveAtomTypes = !(checking = false);
}
}
}
}
if (addAtoms) {
makeBonds(bonds, !checking && haveAtomTypes);
applySymmetryAndSetTrajectory();
}
return readNextLine;
}
private void makeBonds(String[][] bonds, boolean haveAtomTypes) {
for (int i = bonds.length; --i >= 0;) {
String[] b = bonds[i];
if (b == null)
continue; // discarded atom
Atom a1 = asc.getAtomFromName(b[b.length - 1]);
int b0 = 0;
if (haveAtomTypes)
a1.atomName += "\0" + b[b0++];
for (int j = b.length - 1; --j >= b0;) {
Atom a2 = asc.getAtomFromName(b[j]);
if (a1.index < a2.index)
asc.addNewBondWithOrderA(a1, a2, 1);
}
}
}
private String getElement(String name) {
int n = name.length();
switch (n) {
case 1:
break;
default:
char c1 = name.charAt(0);
char c2 = name.charAt(1);
n = (Atom.isValidSym2(c1, c2) || c1 == 'C' && c2 == 'L' ? 2 : 1);
}
return name.substring(0, n);
}
}