use of ffx.potential.parameters.AtomType in project ffx by mjschnie.
the class BiojavaFilter method assignAminoAcidAtomTypes.
private void assignAminoAcidAtomTypes(Residue residue, Residue previousResidue, Residue nextResidue) throws MissingHeavyAtomException, MissingAtomTypeException {
String residueName = residue.getName().toUpperCase();
int j = 1;
ResiduePosition position = MIDDLE_RESIDUE;
if (previousResidue == null) {
j = 0;
position = FIRST_RESIDUE;
} else if (nextResidue == null) {
j = 2;
position = LAST_RESIDUE;
/**
* If the last residue only contains a nitrogen turn it into an NH2
* group.
*/
Atom N = (Atom) residue.getAtomNode("N");
if (residue.getAtomNodeList().size() == 1 && N != null) {
residueName = "NH2".intern();
residue.setName(residueName);
}
}
AminoAcid3 aminoAcid = getAminoAcid(residueName);
int aminoAcidNumber = getAminoAcidNumber(residueName);
/**
* Non-standard Amino Acid; use ALA backbone types.
*/
boolean nonStandard = false;
if (aminoAcid == AminoAcid3.UNK) {
aminoAcidNumber = getAminoAcidNumber("ALA");
nonStandard = true;
}
/**
* Only the last residue in a chain should have an OXT/OT2 atom.
*/
if (nextResidue != null) {
removeOXT_OT2(residue);
}
/**
* Only the first nitrogen should have H1, H2 and H3 atoms, unless it's
* an NME cap.
*/
if (previousResidue != null) {
removeH1_H2_H3(aminoAcid, residue);
}
/**
* Check for missing heavy atoms. This check ignores special terminating
* groups like FOR, NH2, etc.
*/
if (!nonStandard) {
try {
checkForMissingHeavyAtoms(aminoAcidNumber, aminoAcid, position, residue);
} catch (MissingHeavyAtomException e) {
logger.log(Level.INFO, " {0} could not be parsed.", residue.toString());
throw e;
}
}
Atom pC = null;
Atom pCA = null;
if (previousResidue != null) {
pC = (Atom) previousResidue.getAtomNode("C");
pCA = (Atom) previousResidue.getAtomNode("CA");
}
/**
* Backbone heavy atoms.
*/
Atom N = (Atom) residue.getAtomNode("N");
if (N != null) {
N.setAtomType(findAtomType(AA_N[j][aminoAcidNumber]));
if (position != FIRST_RESIDUE) {
buildBond(pC, N);
}
}
Atom CA = null;
Atom C = null;
Atom O = null;
if (!(position == LAST_RESIDUE && aminoAcid == AminoAcid3.NH2)) {
if (aminoAcid == AminoAcid3.ACE || aminoAcid == AminoAcid3.NME) {
CA = buildHeavy(residue, "CH3", N, AA_CA[j][aminoAcidNumber]);
} else {
CA = buildHeavy(residue, "CA", N, AA_CA[j][aminoAcidNumber]);
}
if (!(position == LAST_RESIDUE && aminoAcid == AminoAcid3.NME)) {
C = buildHeavy(residue, "C", CA, AA_C[j][aminoAcidNumber]);
O = (Atom) residue.getAtomNode("O");
if (O == null) {
O = (Atom) residue.getAtomNode("OT1");
}
AtomType atomType = findAtomType(AA_O[j][aminoAcidNumber]);
if (O == null) {
MissingHeavyAtomException missingHeavyAtom = new MissingHeavyAtomException("O", atomType, C);
throw missingHeavyAtom;
}
O.setAtomType(atomType);
buildBond(C, O);
}
}
/**
* Nitrogen hydrogen atoms.
*/
AtomType atomType = findAtomType(AA_HN[j][aminoAcidNumber]);
switch(position) {
case FIRST_RESIDUE:
switch(aminoAcid) {
case PRO:
buildHydrogenAtom(residue, "H2", N, 1.02, CA, 109.5, C, 0.0, 0, atomType);
buildHydrogenAtom(residue, "H3", N, 1.02, CA, 109.5, C, -120.0, 0, atomType);
break;
case PCA:
buildHydrogenAtom(residue, "H", N, 1.02, CA, 109.5, C, -60.0, 0, atomType);
break;
case ACE:
break;
default:
buildHydrogenAtom(residue, "H1", N, 1.02, CA, 109.5, C, 180.0, 0, atomType);
buildHydrogenAtom(residue, "H2", N, 1.02, CA, 109.5, C, 60.0, 0, atomType);
buildHydrogenAtom(residue, "H3", N, 1.02, CA, 109.5, C, -60.0, 0, atomType);
}
break;
case LAST_RESIDUE:
switch(aminoAcid) {
case NH2:
buildHydrogenAtom(residue, "H1", N, 1.02, pC, 119.0, pCA, 0.0, 0, atomType);
buildHydrogenAtom(residue, "H2", N, 1.02, pC, 119.0, pCA, 180.0, 0, atomType);
break;
case NME:
buildHydrogenAtom(residue, "H", N, 1.02, pC, 118.0, CA, 121.0, 1, atomType);
break;
default:
buildHydrogenAtom(residue, "H", N, 1.02, pC, 119.0, CA, 119.0, 1, atomType);
}
break;
default:
// Mid-chain nitrogen hydrogen.
buildHydrogenAtom(residue, "H", N, 1.02, pC, 119.0, CA, 119.0, 1, atomType);
}
/**
* C-alpha hydrogen atoms.
*/
String haName = "HA";
if (aminoAcid == AminoAcid3.GLY) {
haName = "HA2";
}
atomType = findAtomType(AA_HA[j][aminoAcidNumber]);
switch(position) {
case FIRST_RESIDUE:
switch(aminoAcid) {
case FOR:
buildHydrogenAtom(residue, "H", C, 1.12, O, 0.0, null, 0.0, 0, atomType);
break;
case ACE:
buildHydrogenAtom(residue, "H1", CA, 1.10, C, 109.5, O, 180.0, 0, atomType);
buildHydrogenAtom(residue, "H2", CA, 1.10, C, 109.5, O, 60.0, 0, atomType);
buildHydrogenAtom(residue, "H3", CA, 1.10, C, 109.5, O, -60.0, 0, atomType);
break;
default:
buildHydrogenAtom(residue, haName, CA, 1.10, N, 109.5, C, 109.5, -1, atomType);
break;
}
break;
case LAST_RESIDUE:
switch(aminoAcid) {
case NME:
buildHydrogenAtom(residue, "H1", CA, 1.10, N, 109.5, pC, 180.0, 0, atomType);
buildHydrogenAtom(residue, "H2", CA, 1.10, N, 109.5, pC, 60.0, 0, atomType);
buildHydrogenAtom(residue, "H3", CA, 1.10, N, 109.5, pC, -60.0, 0, atomType);
break;
default:
buildHydrogenAtom(residue, haName, CA, 1.10, N, 109.5, C, 109.5, -1, atomType);
}
break;
default:
buildHydrogenAtom(residue, haName, CA, 1.10, N, 109.5, C, 109.0, -1, atomType);
}
/**
* Build the amino acid side chain.
*/
assignAminoAcidSideChain(position, aminoAcid, residue, CA, N, C);
/**
* Build the terminal oxygen if the residue is not NH2 or NME.
*/
if (position == LAST_RESIDUE && !(aminoAcid == AminoAcid3.NH2 || aminoAcid == AminoAcid3.NME)) {
atomType = findAtomType(AA_O[2][aminoAcidNumber]);
Atom OXT = (Atom) residue.getAtomNode("OXT");
if (OXT == null) {
OXT = (Atom) residue.getAtomNode("OT2");
if (OXT != null) {
OXT.setName("OXT");
}
}
if (OXT == null) {
String resName = C.getResidueName();
int resSeq = C.getResidueNumber();
Character chainID = C.getChainID();
Character altLoc = C.getAltLoc();
String segID = C.getSegID();
double occupancy = C.getOccupancy();
double tempFactor = C.getTempFactor();
OXT = new Atom(0, "OXT", altLoc, new double[3], resName, resSeq, chainID, occupancy, tempFactor, segID);
OXT.setAtomType(atomType);
residue.addMSNode(OXT);
intxyz(OXT, C, 1.25, CA, 117.0, O, 126.0, 1);
} else {
OXT.setAtomType(atomType);
}
buildBond(C, OXT);
}
/**
* Do some checks on the current residue to make sure all atoms have
* been assigned an atom type.
*/
List<Atom> resAtoms = residue.getAtomList();
for (Atom atom : resAtoms) {
atomType = atom.getAtomType();
if (atomType == null) {
MissingAtomTypeException missingAtomTypeException = new MissingAtomTypeException(residue, atom);
throw missingAtomTypeException;
}
int numberOfBonds = atom.getNumBonds();
if (numberOfBonds != atomType.valence) {
if (atom == C && numberOfBonds == atomType.valence - 1 && position != LAST_RESIDUE) {
continue;
}
logger.warning(format(" An atom for residue %s has the wrong number of bonds:\n %s", residueName, atom.toString()));
logger.warning(format(" Expected: %d Actual: %d.", atomType.valence, numberOfBonds));
}
}
}
use of ffx.potential.parameters.AtomType in project ffx by mjschnie.
the class BiojavaFilter method assignAtomTypes.
/**
* Assign force field atoms types to common chemistries using "biotype"
* records.
*/
public void assignAtomTypes() {
/**
* Create a new List to store bonds determined based on PDB atom names.
*/
bondList = new ArrayList<>();
/**
* To Do: Look for cyclic peptides and disulfides.
*/
Polymer[] polymers = activeMolecularAssembly.getChains();
/**
* Loop over chains.
*/
if (polymers != null) {
logger.info(format("\n Assigning atom types for %d chains.", polymers.length));
for (Polymer polymer : polymers) {
List<Residue> residues = polymer.getResidues();
int numberOfResidues = residues.size();
/**
* Check if all residues are known amino acids.
*/
boolean isProtein = true;
if (!residues.isEmpty()) {
// renameNTerminusHydrogens(residues.get(0)); Not safe to use until it distinguishes between true N-termini and N-terminal residues in general.
}
for (int residueNumber = 0; residueNumber < numberOfResidues; residueNumber++) {
Residue residue = residues.get(residueNumber);
String name = residue.getName().toUpperCase();
boolean aa = false;
for (AminoAcid3 amino : aminoAcidList) {
if (amino.toString().equalsIgnoreCase(name)) {
aa = true;
renameNonstandardHydrogens(residue);
break;
}
}
// Check for a patch.
if (!aa) {
HashMap<String, AtomType> types = forceField.getAtomTypes(name);
if (types.isEmpty()) {
isProtein = false;
break;
} else {
logger.info(" Patch found for non-standard amino acid " + name);
}
}
}
/**
* If all the residues in this chain have known amino acids
* names, then attempt to assign atom types.
*/
if (isProtein) {
try {
logger.info(format(" Amino acid chain %s", polymer.getName()));
double dist = properties.getDouble("chainbreak", 3.0);
// Detect main chain breaks!
List<List<Residue>> subChains = findChainBreaks(residues, dist);
for (List<Residue> subChain : subChains) {
assignAminoAcidAtomTypes(subChain);
}
} catch (MissingHeavyAtomException missingHeavyAtomException) {
logger.severe(missingHeavyAtomException.toString());
} catch (MissingAtomTypeException missingAtomTypeException) {
logger.severe(missingAtomTypeException.toString());
}
continue;
}
/**
* Check if all residues have known nucleic acids names.
*/
boolean isNucleicAcid = true;
for (int residueNumber = 0; residueNumber < numberOfResidues; residueNumber++) {
Residue residue = residues.get(residueNumber);
String name = residue.getName().toUpperCase();
/**
* Convert 1 and 2-character nucleic acid names to
* 3-character names.
*/
if (name.length() == 1) {
if (name.equals("A")) {
name = NucleicAcid3.ADE.toString();
} else if (name.equals("C")) {
name = NucleicAcid3.CYT.toString();
} else if (name.equals("G")) {
name = NucleicAcid3.GUA.toString();
} else if (name.equals("T")) {
name = NucleicAcid3.THY.toString();
} else if (name.equals("U")) {
name = NucleicAcid3.URI.toString();
}
} else if (name.length() == 2) {
if (name.equals("YG")) {
name = NucleicAcid3.YYG.toString();
}
}
residue.setName(name);
NucleicAcid3 nucleicAcid = null;
for (NucleicAcid3 nucleic : nucleicAcidList) {
String nuc3 = nucleic.toString();
nuc3 = nuc3.substring(nuc3.length() - 3);
if (nuc3.equalsIgnoreCase(name)) {
nucleicAcid = nucleic;
break;
}
}
if (nucleicAcid == null) {
logger.info(format("Nucleic acid was not recognized %s.", name));
isNucleicAcid = false;
break;
}
}
/**
* If all the residues in this chain have known nucleic acids
* names, then attempt to assign atom types.
*/
if (isNucleicAcid) {
try {
logger.info(format(" Nucleic acid chain %s", polymer.getName()));
assignNucleicAcidAtomTypes(residues);
} catch (MissingHeavyAtomException missingHeavyAtomException) {
logger.severe(missingHeavyAtomException.toString());
} catch (MissingAtomTypeException missingAtomTypeException) {
logger.severe(missingAtomTypeException.toString());
}
}
}
}
// Assign ion atom types.
ArrayList<MSNode> ions = activeMolecularAssembly.getIons();
if (ions != null && ions.size() > 0) {
logger.info(format(" Assigning atom types for %d ions.", ions.size()));
for (MSNode m : ions) {
Molecule ion = (Molecule) m;
String name = ion.getResidueName().toUpperCase();
HetAtoms hetatm = HetAtoms.valueOf(name);
Atom atom = ion.getAtomList().get(0);
if (ion.getAtomList().size() != 1) {
logger.severe(format(" Check residue %s of chain %s.", ion.toString(), ion.getChainID()));
}
try {
switch(hetatm) {
case NA:
atom.setAtomType(findAtomType(2003));
break;
case K:
atom.setAtomType(findAtomType(2004));
break;
case MG:
case MG2:
atom.setAtomType(findAtomType(2005));
break;
case CA:
case CA2:
atom.setAtomType(findAtomType(2006));
break;
case CL:
atom.setAtomType(findAtomType(2007));
break;
case ZN:
case ZN2:
atom.setAtomType(findAtomType(2008));
break;
case BR:
atom.setAtomType(findAtomType(2009));
break;
default:
logger.severe(format(" Check residue %s of chain %s.", ion.toString(), ion.getChainID()));
}
} catch (Exception e) {
String message = "Error assigning atom types.";
logger.log(Level.SEVERE, message, e);
}
}
}
// Assign water atom types.
ArrayList<MSNode> water = activeMolecularAssembly.getWaters();
if (water != null && water.size() > 0) {
logger.info(format(" Assigning atom types for %d waters.", water.size()));
for (MSNode m : water) {
Molecule wat = (Molecule) m;
try {
Atom O = buildHeavy(wat, "O", null, 2001);
Atom H1 = buildHydrogen(wat, "H1", O, 0.96e0, null, 109.5e0, null, 120.0e0, 0, 2002);
H1.setHetero(true);
Atom H2 = buildHydrogen(wat, "H2", O, 0.96e0, H1, 109.5e0, null, 120.0e0, 0, 2002);
H2.setHetero(true);
} catch (Exception e) {
String message = "Error assigning atom types to a water.";
logger.log(Level.SEVERE, message, e);
}
}
}
// Assign small molecule atom types.
ArrayList<Molecule> molecules = activeMolecularAssembly.getMolecules();
for (MSNode m : molecules) {
Molecule molecule = (Molecule) m;
String moleculeName = molecule.getResidueName();
logger.info(" Attempting to patch " + moleculeName);
ArrayList<Atom> moleculeAtoms = molecule.getAtomList();
boolean patched = true;
HashMap<String, AtomType> types = forceField.getAtomTypes(moleculeName);
/**
* Assign atom types for all known atoms.
*/
for (Atom atom : moleculeAtoms) {
String atomName = atom.getName().toUpperCase();
AtomType atomType = types.get(atomName);
if (atomType == null) {
logger.info(" No atom type was found for " + atomName + " of " + moleculeName + ".");
patched = false;
break;
} else {
atom.setAtomType(atomType);
types.remove(atomName);
}
}
/**
* Create missing hydrogen atoms. Check for missing heavy atoms.
*/
if (patched && !types.isEmpty()) {
for (AtomType type : types.values()) {
if (type.atomicNumber != 1) {
logger.info(" Missing heavy atom " + type.name);
patched = false;
break;
}
}
}
// Create bonds between known atoms.
if (patched) {
for (Atom atom : moleculeAtoms) {
String atomName = atom.getName();
String[] bonds = forceField.getBonds(moleculeName, atomName);
if (bonds != null) {
for (String name : bonds) {
Atom atom2 = molecule.getAtom(name);
if (atom2 != null && !atom.isBonded(atom2)) {
buildBond(atom, atom2);
}
}
}
}
}
// Create missing hydrogen atoms.
if (patched && !types.isEmpty()) {
// Create a hashmap of the molecule's atoms
HashMap<String, Atom> atomMap = new HashMap<String, Atom>();
for (Atom atom : moleculeAtoms) {
atomMap.put(atom.getName().toUpperCase(), atom);
}
for (String atomName : types.keySet()) {
AtomType type = types.get(atomName);
String[] bonds = forceField.getBonds(moleculeName, atomName.toUpperCase());
if (bonds == null || bonds.length != 1) {
patched = false;
logger.info(" Check biotype for hydrogen " + type.name + ".");
break;
}
// Get the heavy atom the hydrogen is bonded to.
Atom ia = atomMap.get(bonds[0].toUpperCase());
Atom hydrogen = new Atom(0, atomName, ia.getAltLoc(), new double[3], ia.getResidueName(), ia.getResidueNumber(), ia.getChainID(), ia.getOccupancy(), ia.getTempFactor(), ia.getSegID());
logger.fine(" Created hydrogen " + atomName + ".");
hydrogen.setAtomType(type);
hydrogen.setHetero(true);
molecule.addMSNode(hydrogen);
int valence = ia.getAtomType().valence;
List<Bond> aBonds = ia.getBonds();
int numBonds = aBonds.size();
/**
* Try to find the following configuration: ib-ia-ic
*/
Atom ib = null;
Atom ic = null;
Atom id = null;
if (numBonds > 0) {
Bond bond = aBonds.get(0);
ib = bond.get1_2(ia);
}
if (numBonds > 1) {
Bond bond = aBonds.get(1);
ic = bond.get1_2(ia);
}
if (numBonds > 2) {
Bond bond = aBonds.get(2);
id = bond.get1_2(ia);
}
/**
* Building the hydrogens depends on hybridization and the
* locations of other bonded atoms.
*/
logger.fine(" Bonding " + atomName + " to " + ia.getName() + " (" + numBonds + " of " + valence + ").");
switch(valence) {
case 4:
switch(numBonds) {
case 3:
// Find the average coordinates of atoms ib, ic and id.
double[] b = ib.getXYZ(null);
double[] c = ib.getXYZ(null);
double[] d = ib.getXYZ(null);
double[] a = new double[3];
a[0] = (b[0] + c[0] + d[0]) / 3.0;
a[1] = (b[1] + c[1] + d[1]) / 3.0;
a[2] = (b[2] + c[2] + d[2]) / 3.0;
// Place the hydrogen at chiral position #1.
intxyz(hydrogen, ia, 1.0, ib, 109.5, ic, 109.5, 1);
double[] e1 = new double[3];
hydrogen.getXYZ(e1);
double[] ret = new double[3];
diff(a, e1, ret);
double l1 = r(ret);
// Place the hydrogen at chiral position #2.
intxyz(hydrogen, ia, 1.0, ib, 109.5, ic, 109.5, -1);
double[] e2 = new double[3];
hydrogen.getXYZ(e2);
diff(a, e2, ret);
double l2 = r(ret);
// Revert to #1 if it is farther from the average.
if (l1 > l2) {
hydrogen.setXYZ(e1);
}
break;
case 2:
intxyz(hydrogen, ia, 1.0, ib, 109.5, ic, 109.5, 0);
break;
case 1:
intxyz(hydrogen, ia, 1.0, ib, 109.5, null, 0.0, 0);
break;
case 0:
intxyz(hydrogen, ia, 1.0, null, 0.0, null, 0.0, 0);
break;
default:
logger.info(" Check biotype for hydrogen " + atomName + ".");
patched = false;
}
break;
case 3:
switch(numBonds) {
case 2:
intxyz(hydrogen, ia, 1.0, ib, 120.0, ic, 0.0, 0);
break;
case 1:
intxyz(hydrogen, ia, 1.0, ib, 120.0, null, 0.0, 0);
break;
case 0:
intxyz(hydrogen, ia, 1.0, null, 0.0, null, 0.0, 0);
break;
default:
logger.info(" Check biotype for hydrogen " + atomName + ".");
patched = false;
}
break;
case 2:
switch(numBonds) {
case 1:
intxyz(hydrogen, ia, 1.0, ib, 120.0, null, 0.0, 0);
break;
case 0:
intxyz(hydrogen, ia, 1.0, null, 0.0, null, 0.0, 0);
break;
default:
logger.info(" Check biotype for hydrogen " + atomName + ".");
patched = false;
}
break;
case 1:
switch(numBonds) {
case 0:
intxyz(hydrogen, ia, 1.0, null, 0.0, null, 0.0, 0);
break;
default:
logger.info(" Check biotype for hydrogen " + atomName + ".");
patched = false;
}
break;
default:
logger.info(" Check biotype for hydrogen " + atomName + ".");
patched = false;
}
if (!patched) {
break;
} else {
buildBond(ia, hydrogen);
}
}
}
if (!patched) {
logger.log(Level.WARNING, format(" Deleting unrecognized molecule %s.", m.toString()));
activeMolecularAssembly.deleteMolecule((Molecule) m);
} else {
logger.info(" Patch for " + moleculeName + " succeeded.");
}
}
}
use of ffx.potential.parameters.AtomType in project ffx by mjschnie.
the class ForceFieldFilter method parseAtom.
private void parseAtom(String input, String[] tokens) {
if (tokens.length < 7) {
logger.log(Level.WARNING, "Invalid ATOM type:\n{0}", input);
return;
}
try {
int index = 1;
// Atom Type
int type = Integer.parseInt(tokens[index++]);
// Atom Class
int atomClass;
// and the atomClass field will remain equal to null.
try {
atomClass = Integer.parseInt(tokens[index]);
// If the parseInt succeeds, this force field has atom classes.
index++;
} catch (NumberFormatException e) {
// Some force fields do not use atom classes.
atomClass = -1;
}
// Name
String name = tokens[index++].intern();
// The "environment" string may contain spaces,
// and is therefore surrounded in quotes located at "first" and
// "last".
int first = input.indexOf("\"");
int last = input.lastIndexOf("\"");
if (first >= last) {
logger.log(Level.WARNING, "Invalid ATOM type:\n{0}", input);
return;
}
// Environment
String environment = input.substring(first, last + 1).intern();
// Shrink the tokens array to only include entries
// after the environment field.
tokens = input.substring(last + 1).trim().split(" +");
index = 0;
// Atomic Number
int atomicNumber = Integer.parseInt(tokens[index++]);
// Atomic Mass
double mass = Double.parseDouble(tokens[index++]);
// Hybridization
int hybridization = Integer.parseInt(tokens[index++]);
AtomType atomType = new AtomType(type, atomClass, name, environment, atomicNumber, mass, hybridization);
forceField.addForceFieldType(atomType);
} catch (NumberFormatException e) {
String message = "Exception parsing CHARGE type:\n" + input + "\n";
logger.log(Level.SEVERE, message, e);
}
}
use of ffx.potential.parameters.AtomType in project ffx by mjschnie.
the class XYZFilter method readFile.
/**
* {@inheritDoc}
*
* Parse the XYZ File
*/
@Override
public boolean readFile() {
File xyzFile = activeMolecularAssembly.getFile();
if (forceField == null) {
logger.warning(format(" No force field is associated with %s.", xyzFile.toString()));
return false;
}
try {
FileReader fr = new FileReader(xyzFile);
BufferedReader br = new BufferedReader(fr);
String data = br.readLine();
// Read blank lines at the top of the file
while (data != null && data.trim().equals("")) {
data = br.readLine();
}
if (data == null) {
return false;
}
String[] tokens = data.trim().split(" +", 2);
int numberOfAtoms = Integer.parseInt(tokens[0]);
if (numberOfAtoms < 1) {
return false;
}
if (tokens.length == 2) {
getActiveMolecularSystem().setName(tokens[1]);
}
logger.info(format("\n Opening %s with %d atoms\n", xyzFile.getName(), numberOfAtoms));
// The header line is reasonable. Check for periodic box dimensions.
br.mark(10000);
data = br.readLine();
if (!readPBC(data, activeMolecularAssembly)) {
br.reset();
}
// Prepare to parse atom lines.
HashMap<Integer, Integer> labelHash = new HashMap<>();
int[] label = new int[numberOfAtoms];
int[][] bonds = new int[numberOfAtoms][8];
double[][] d = new double[numberOfAtoms][3];
boolean renumber = false;
atomList = new ArrayList<>();
// Loop over the expected number of atoms.
for (int i = 0; i < numberOfAtoms; i++) {
if (!br.ready()) {
return false;
}
data = br.readLine();
if (data == null) {
logger.warning(format(" Check atom %d in %s.", (i + 1), activeMolecularAssembly.getFile().getName()));
return false;
}
tokens = data.trim().split(" +");
if (tokens == null || tokens.length < 6) {
logger.warning(format(" Check atom %d in %s.", (i + 1), activeMolecularAssembly.getFile().getName()));
return false;
}
// Valid number of tokens, so try to parse this line.
label[i] = Integer.parseInt(tokens[0]);
// Check for valid atom numbering, or flag for re-numbering.
if (label[i] != i + 1) {
renumber = true;
}
String atomName = tokens[1];
d[i][0] = Double.parseDouble(tokens[2]);
d[i][1] = Double.parseDouble(tokens[3]);
d[i][2] = Double.parseDouble(tokens[4]);
int type = Integer.parseInt(tokens[5]);
AtomType atomType = forceField.getAtomType(Integer.toString(type));
if (atomType == null) {
StringBuilder message = new StringBuilder("Check atom type ");
message.append(type).append(" for Atom ").append(i + 1);
message.append(" in ").append(activeMolecularAssembly.getFile().getName());
logger.warning(message.toString());
return false;
}
Atom a = new Atom(i + 1, atomName, atomType, d[i]);
atomList.add(a);
// Bond Data
int numberOfBonds = tokens.length - 6;
for (int b = 0; b < 8; b++) {
if (b < numberOfBonds) {
int bond = Integer.parseInt(tokens[6 + b]);
bonds[i][b] = bond;
} else {
bonds[i][b] = 0;
}
}
}
// Check if this is an archive.
if (br.ready()) {
// Read past blank lines between archive files
data = br.readLine().trim();
while (data != null && data.equals("")) {
data = br.readLine().trim();
}
if (data != null) {
tokens = data.split(" +", 2);
if (tokens != null && tokens.length > 0) {
try {
int archiveNumberOfAtoms = Integer.parseInt(tokens[0]);
if (archiveNumberOfAtoms == numberOfAtoms) {
setType(FileType.ARC);
}
} catch (NumberFormatException e) {
tokens = null;
}
}
}
}
br.close();
fr.close();
// Try to renumber
if (renumber) {
for (int i = 0; i < numberOfAtoms; i++) {
if (labelHash.containsKey(label[i])) {
logger.warning(format(" Two atoms have the same index: %d.", label[i]));
return false;
}
labelHash.put(label[i], i + 1);
}
for (int i = 0; i < numberOfAtoms; i++) {
int j = -1;
while (j < 3 && bonds[i][++j] > 0) {
bonds[i][j] = labelHash.get(bonds[i][j]);
}
}
}
bondList = new ArrayList<>();
int[] c = new int[2];
for (int i = 1; i <= numberOfAtoms; i++) {
int a1 = i;
int j = -1;
while (j < 7 && bonds[i - 1][++j] > 0) {
int a2 = bonds[i - 1][j];
if (a1 < a2) {
if (a1 > numberOfAtoms || a1 < 1 || a2 > numberOfAtoms || a2 < 1) {
logger.warning(format(" Check the bond between %d and %d in %s.", a1, a2, activeMolecularAssembly.getFile().getName()));
return false;
}
// Check for bidirectional connection
boolean bidirectional = false;
int k = -1;
while (k < 7 && bonds[a2 - 1][++k] > 0) {
int a3 = bonds[a2 - 1][k];
if (a3 == a1) {
bidirectional = true;
break;
}
}
if (!bidirectional) {
logger.warning(format(" Check the bond between %d and %d in %s.", a1, a2, activeMolecularAssembly.getFile().getName()));
return false;
}
Atom atom1 = atomList.get(a1 - 1);
Atom atom2 = atomList.get(a2 - 1);
if (atom1 == null || atom2 == null) {
logger.warning(format(" Check the bond between %d and %d in %s.", a1, a2, activeMolecularAssembly.getFile().getName()));
return false;
}
Bond bond = new Bond(atom1, atom2);
c[0] = atom1.getAtomType().atomClass;
c[1] = atom2.getAtomType().atomClass;
String key = BondType.sortKey(c);
BondType bondType = forceField.getBondType(key);
if (bondType == null) {
logger.severe(format(" No BondType for key %s", key));
} else {
bond.setBondType(bondType);
}
bondList.add(bond);
}
}
}
return true;
} catch (IOException e) {
logger.severe(e.toString());
}
return false;
}
use of ffx.potential.parameters.AtomType in project ffx by mjschnie.
the class INTFilter method readFile.
/**
* {@inheritDoc}
*
* Parse the INT File.
*
* @since 1.0
*/
@Override
public boolean readFile() {
File intFile = activeMolecularAssembly.getFile();
if (forceField == null) {
logger.warning("No force field is associated with " + intFile.toString());
return false;
}
// Open a data stream to the Internal Coordinate file
try {
FileReader fr = new FileReader(intFile);
BufferedReader br = new BufferedReader(fr);
String data = br.readLine().trim();
// Read blank lines at the top of the file
while (data != null && data.length() == 0) {
data = br.readLine().trim();
}
if (data == null) {
logger.warning("Empty file: " + intFile.toString());
return false;
}
int numberOfAtoms;
String[] tokens = data.trim().split(" +");
try {
numberOfAtoms = Integer.parseInt(tokens[0]);
if (numberOfAtoms < 1) {
logger.warning("Invalid number of atoms: " + numberOfAtoms);
return false;
}
} catch (Exception e) {
logger.severe("Error parsing the number of atoms.\n" + e);
return false;
}
if (tokens.length >= 2) {
tokens = data.trim().split(" +", 2);
activeMolecularAssembly.setName(tokens[1]);
}
logger.info(" Opening " + intFile.getName() + " with " + numberOfAtoms + " atoms");
double[] d = { 0.0d, 0.0d, 0.0d };
int[][] zi = new int[numberOfAtoms][4];
double[][] zv = new double[numberOfAtoms][3];
Vector<int[]> zadd = new Vector<int[]>();
Vector<int[]> zdel = new Vector<int[]>();
atomList = new ArrayList<Atom>();
for (int i = 0; i < numberOfAtoms; i++) {
// Atom Data
if (!br.ready()) {
return false;
}
data = br.readLine();
if (data == null) {
logger.severe(" Check atom " + (i + 1) + " in " + activeMolecularAssembly.getFile().getName());
return false;
}
tokens = data.trim().split(" +");
if (tokens == null || tokens.length < 3) {
logger.severe(" Check atom " + (i + 1) + " in " + activeMolecularAssembly.getFile().getName());
return false;
}
// Atom number, name, type
String name = tokens[1];
int type = Integer.parseInt(tokens[2]);
AtomType atomType = forceField.getAtomType(String.valueOf(type));
if (atomType == null) {
logger.severe(" Check atom " + (i + 1) + " in " + activeMolecularAssembly.getFile().getName());
return false;
}
Atom atom = new Atom(i + 1, name, atomType, d);
atomList.add(atom);
// Bond partner and bond value
if (tokens.length >= 5) {
zi[i][0] = Integer.parseInt(tokens[3]);
zv[i][0] = Double.parseDouble(tokens[4]);
} else {
zi[i][0] = 0;
zv[i][0] = 0.0d;
}
// Angle partner and angle value
if (tokens.length >= 7) {
zi[i][1] = Integer.parseInt(tokens[5]);
zv[i][1] = Double.parseDouble(tokens[6]);
} else {
zi[i][1] = 0;
zv[i][1] = 0.0d;
}
// Torsion partner and dihedral value
if (tokens.length >= 10) {
zi[i][2] = Integer.parseInt(tokens[7]);
zv[i][2] = Double.parseDouble(tokens[8]);
zi[i][3] = Integer.parseInt(tokens[9]);
} else {
zi[i][2] = 0;
zv[i][2] = 0.0d;
zi[i][3] = 0;
}
}
if (br.ready()) {
data = br.readLine();
// Check for a first blank line
if (data.trim().equalsIgnoreCase("")) {
// Parse bond pairs to add until EOF or a blank line is
// reached
boolean blank = false;
while (br.ready() && !blank) {
data = br.readLine();
if (data.trim().equalsIgnoreCase("")) {
blank = true;
} else {
tokens = data.trim().split(" +");
if (tokens.length != 2) {
logger.severe(" Check Additional Bond Pair: " + (zadd.size() + 1) + " in " + activeMolecularAssembly.getFile().getName());
return false;
}
int[] pair = new int[2];
pair[0] = Integer.parseInt(tokens[0]);
pair[1] = Integer.parseInt(tokens[1]);
zadd.add(pair);
}
}
// Parse bond pairs to be removed until EOF
while (br.ready()) {
data = br.readLine();
tokens = data.trim().split(" +");
if (tokens.length != 2) {
logger.severe(" Check Bond Pair to Remove: " + (zadd.size() + 1) + " in " + activeMolecularAssembly.getFile().getName());
return false;
}
int[] pair = new int[2];
pair[0] = Integer.parseInt(tokens[0]);
pair[1] = Integer.parseInt(tokens[1]);
zdel.add(pair);
}
}
}
br.close();
fr.close();
if (atomList.size() == numberOfAtoms) {
// Add bonds specified in the Z-matrix
bondList = new ArrayList<Bond>();
for (int i = 1; i < numberOfAtoms; i++) {
int partner = zi[i][0];
boolean del = false;
for (int j = 0; j < zdel.size(); j++) {
int[] pair = zdel.get(j);
if (pair[0] == i + 1 && pair[1] == partner) {
del = true;
}
if (pair[1] == i + 1 && pair[0] == partner) {
del = true;
}
}
if (!del) {
Atom atom1 = atomList.get(i);
Atom atom2 = atomList.get(partner - 1);
bondList.add(new Bond(atom1, atom2));
}
}
// Add additional bonds
for (int i = 0; i < zadd.size(); i++) {
int[] pair = zadd.get(i);
Atom atom1 = atomList.get(pair[0] - 1);
Atom atom2 = atomList.get(pair[1] - 1);
bondList.add(new Bond(atom1, atom2));
}
// Determine coordinates from Z-matrix values
for (int i = 0; i < numberOfAtoms; i++) {
Atom atom = atomList.get(i);
Atom ia = null;
Atom ib = null;
Atom ic = null;
int[] atoms = zi[i];
if (atoms[0] > 0) {
ia = atomList.get(atoms[0] - 1);
}
if (atoms[1] > 0) {
ib = atomList.get(atoms[1] - 1);
}
if (atoms[2] > 0) {
ic = atomList.get(atoms[2] - 1);
}
double bond = zv[i][0];
double angle1 = zv[i][1];
double angle2 = zv[i][2];
int chiral = atoms[3];
intxyz(atom, ia, bond, ib, angle1, ic, angle2, chiral);
}
return true;
}
logger.warning("Reported number of Atoms: " + numberOfAtoms + "\nNumber of Atoms Found: " + atomList.size());
} catch (IOException e) {
logger.severe(e.toString());
}
return false;
}
Aggregations