use of ffx.potential.bonded.Residue in project ffx by mjschnie.
the class TitrationUtils method chooseTitratables.
/**
* Choose titratables with intrinsic pKa inside (pH-window,pH+window).
*
* @param pH
* @param window
*/
public static List<Residue> chooseTitratables(double pH, double window, MolecularAssembly searchMe) {
List<Residue> chosen = new ArrayList<>();
Polymer[] polymers = searchMe.getChains();
for (int i = 0; i < polymers.length; i++) {
ArrayList<Residue> residues = polymers[i].getResidues();
for (int j = 0; j < residues.size(); j++) {
Residue res = residues.get(j);
Titration[] avail = Titration.multiLookup(res);
for (Titration titration : avail) {
double pKa = titration.pKa;
if (pKa >= pH - window && pKa <= pH + window) {
chosen.add(residues.get(j));
}
}
}
}
return chosen;
}
use of ffx.potential.bonded.Residue in project ffx by mjschnie.
the class TitrationUtils method openFullyProtonated.
public static MolecularAssembly openFullyProtonated(File structure) {
String name = format("%s-prot", FilenameUtils.removeExtension(structure.getName()));
MolecularAssembly mola = new MolecularAssembly(name);
mola.setFile(structure);
List<Mutation> mutations = new ArrayList<>();
List<Residue> residues = mola.getResidueList();
for (Residue res : residues) {
char chain = res.getChainID();
int resID = res.getResidueNumber();
Titration titration = Titration.lookup(res);
if (res.getAminoAcid3() != titration.protForm) {
String protName = titration.protForm.name();
mutations.add(new PDBFilter.Mutation(chain, resID, protName));
}
}
PotentialsUtils utils = new PotentialsUtils();
return utils.openWithMutations(structure, mutations);
}
use of ffx.potential.bonded.Residue in project ffx by mjschnie.
the class TitrationUtils method titratingMultiresidueFactory.
/**
* Create a MultiResidue from the given Residue by adding its alternated
* protonation state(s) as alternate possibilities.
*/
public static MultiResidue titratingMultiresidueFactory(MolecularAssembly mola, Residue res) {
ForceField ff = mola.getForceField();
Potential potential = mola.getPotentialEnergy();
if (!(potential instanceof ForceFieldEnergy)) {
logger.warning(String.format("TitrationFactory only supported by ForceFieldEnergy potentials."));
throw new IllegalStateException();
}
ForceFieldEnergy ffe = (ForceFieldEnergy) potential;
/* Create new titration state. */
Titration titration = Titration.lookup(res);
String targetName = (titration.protForm != res.getAminoAcid3()) ? titration.protForm.toString() : titration.deprotForm.toString();
int resNumber = res.getResidueNumber();
Residue.ResidueType resType = res.getResidueType();
Residue newRes = new Residue(targetName, resNumber, resType);
/* Wrap both states in a MultiResidue. */
MultiResidue multiRes = new MultiResidue(res, ff, ffe);
Polymer polymer = findResiduePolymer(res, mola);
polymer.addMultiResidue(multiRes);
multiRes.addResidue(newRes);
/* Begin in protonated state by default. */
multiRes.setActiveResidue(titration.protForm);
propagateInactiveResidues(multiRes, false);
ffe.reInit();
return multiRes;
}
use of ffx.potential.bonded.Residue in project ffx by mjschnie.
the class RotamerOptimization method slidingWindowOptimization.
private double slidingWindowOptimization(ArrayList<Residue> residueList, int windowSize, int increment, boolean revert, double distance, Direction direction) {
long beginTime = -System.nanoTime();
boolean incrementTruncated = false;
boolean firstWindowSaved = false;
int counter = 1;
int windowEnd;
int nOptimize = residueList.size();
if (nOptimize < windowSize) {
windowSize = nOptimize;
logger.info(" Window size too small for given residue range; truncating window size.");
}
switch(direction) {
case BACKWARD:
ArrayList<Residue> temp = new ArrayList<>();
for (int i = nOptimize - 1; i >= 0; i--) {
temp.add(residueList.get(i));
}
residueList = temp;
// Fall through into the FORWARD case.
case FORWARD:
for (int windowStart = 0; windowStart + (windowSize - 1) < nOptimize; windowStart += increment) {
long windowTime = -System.nanoTime();
windowEnd = windowStart + (windowSize - 1);
logIfMaster(format("\n Iteration %d of the sliding window.\n", counter++));
Residue firstResidue = residueList.get(windowStart);
Residue lastResidue = residueList.get(windowEnd);
if (firstResidue != lastResidue) {
logIfMaster(format(" Residues %s ... %s", firstResidue.toString(), lastResidue.toString()));
} else {
logIfMaster(format(" Residue %s", firstResidue.toString()));
}
ArrayList<Residue> currentWindow = new ArrayList<>();
// Not filled if useForcedResidues == false.
ArrayList<Residue> onlyRotameric = new ArrayList<>();
for (int i = windowStart; i <= windowEnd; i++) {
Residue residue = residueList.get(i);
if (useForcedResidues && residue.getRotamers(library) != null) {
onlyRotameric.add(residue);
}
currentWindow.add(residueList.get(i));
}
if (distance > 0) {
for (int i = windowStart; i <= windowEnd; i++) {
Residue residuei = residueList.get(i);
int indexI = allResiduesList.indexOf(residuei);
int lengthRi;
if (checkIfForced(residuei)) {
lengthRi = 1;
} else {
lengthRi = residuei.getRotamers(library).length;
}
for (int ri = 0; ri < lengthRi; ri++) {
for (int j = 0; j < numResidues; j++) {
Residue residuej = allResiduesArray[j];
Rotamer[] rotamersj = residuej.getRotamers(library);
if (currentWindow.contains(residuej) || rotamersj == null) {
continue;
}
int lengthRj = rotamersj.length;
for (int rj = 0; rj < lengthRj; rj++) {
double rotamerSeparation = get2BodyDistance(indexI, ri, j, rj);
// if (distanceMatrix[indexI][ri][j][rj] <= distance) {
if (rotamerSeparation <= distance) {
if (!currentWindow.contains(residuej)) {
logIfMaster(format(" Adding residue %s at distance %16.8f Ang from %s %d.", residuej.toFormattedString(false, true), rotamerSeparation, residuei.toFormattedString(false, true), ri));
currentWindow.add(residuej);
if (useForcedResidues) {
onlyRotameric.add(residuej);
}
}
break;
}
}
}
}
}
}
/**
* If the window starts with a nucleic acid, and there is a
* 5' NA residue, ensure that 5' NA residue has been
* included in the window. Otherwise, that previous residue
* may not have had a chance to be flexible about its sugar
* pucker.
*
* If window size is greater than increment, however, this
* has already been handled. Additionally, do not perform
* this for the first window (counter is already incremented
* by the time this check is performed, so first window's
* counter will be 2). Furthermore, do not include Residues
* with null Rotamer lists (this breaks things).
*
* The issue: if window size = increment, the last NA
* residue in each window will not have flexibility about
* its sugar pucker, because its self-energy includes the
* O3' (i) to P (i+1) bond, so it must remain in the
* original sugar pucker to meet the i+1 residue. However,
* this problem can be solved by ensuring that final residue
* is included in the next window, where it will have
* flexibility about its sugar pucker.
*
* If you are running successive sliding window jobs on the
* same file, I would suggest starting the next job on the
* last residue of the previous job, unless you know your
* settings will include it.
*/
if (counter > 2 && windowSize <= increment && firstResidue.getResidueType() == NA) {
Residue prevResidue = firstResidue.getPreviousResidue();
if (prevResidue != null && prevResidue.getResidueType() == NA && !currentWindow.contains(prevResidue) && prevResidue.getRotamers(library) != null) {
logIfMaster(format(" Adding nucleic acid residue 5' of window start %s to give it flexibility about its sugar pucker.", prevResidue.toString()));
currentWindow.add(prevResidue);
if (useForcedResidues) {
onlyRotameric.add(prevResidue);
}
}
}
if (useForcedResidues) {
sortResidues(onlyRotameric);
} else {
sortResidues(currentWindow);
}
if (revert) {
ResidueState[] coordinates = ResidueState.storeAllCoordinates(currentWindow);
// If x has not yet been constructed, construct it.
if (x == null) {
Atom[] atoms = molecularAssembly.getAtomArray();
int nAtoms = atoms.length;
x = new double[nAtoms * 3];
}
double startingEnergy = Double.NaN;
try {
startingEnergy = currentEnergy(currentWindow);
} catch (ArithmeticException ex) {
logger.severe(String.format(" Exception %s in calculating starting energy of a window; FFX shutting down", ex.toString()));
}
if (useForcedResidues) {
if (onlyRotameric.size() < 1) {
logger.info(" Window has no rotameric residues.");
ResidueState.revertAllCoordinates(currentWindow, coordinates);
} else {
globalOptimization(onlyRotameric);
double finalEnergy = Double.NaN;
try {
finalEnergy = currentEnergy(currentWindow);
} catch (ArithmeticException ex) {
logger.severe(String.format(" Exception %s in calculating final energy of a window; FFX shutting down", ex.toString()));
}
if (startingEnergy <= finalEnergy) {
logger.warning("Optimization did not yield a better energy. Reverting to orginal coordinates.");
ResidueState.revertAllCoordinates(currentWindow, coordinates);
}
}
} else {
globalOptimization(currentWindow);
double finalEnergy = Double.NaN;
try {
finalEnergy = currentEnergy(currentWindow);
} catch (ArithmeticException ex) {
logger.severe(String.format(" Exception %s in calculating final energy of a window; FFX shutting down", ex.toString()));
}
if (startingEnergy <= finalEnergy) {
logger.warning("Optimization did not yield a better energy. Reverting to orginal coordinates.");
ResidueState.revertAllCoordinates(currentWindow, coordinates);
}
}
} else if (useForcedResidues) {
if (onlyRotameric.size() < 1) {
logger.info(" Window has no rotameric residues.");
} else {
globalOptimization(onlyRotameric);
}
} else {
globalOptimization(currentWindow);
}
if (!incrementTruncated) {
if (windowStart + (windowSize - 1) + increment > nOptimize - 1) {
increment = nOptimize - windowStart - windowSize;
if (increment == 0) {
break;
}
logger.warning(" Increment truncated in order to optimize entire residue range.");
incrementTruncated = true;
}
}
if (master && printFiles) {
File file = molecularAssembly.getFile();
if (firstWindowSaved) {
file.delete();
}
// Don't write a file if its the final iteration.
if (windowStart + windowSize == nOptimize) {
continue;
}
// String filename = FilenameUtils.removeExtension(file.getAbsolutePath());
// File tempFile = new File(filename + ".win");
// PDBFilter windowFilter = new PDBFilter(new File(filename + ".win"), molecularAssembly, null, null);
PDBFilter windowFilter = new PDBFilter(file, molecularAssembly, null, null);
// StringBuilder header = new StringBuilder(format("Iteration %d of the sliding window\n", counter - 1));
try {
windowFilter.writeFile(file, false);
if (firstResidue != lastResidue) {
logger.info(format(" File with residues %s ... %s in window written to.", firstResidue.toString(), lastResidue.toString()));
} else {
logger.info(format(" File with residue %s in window written to.", firstResidue.toString()));
}
} catch (Exception e) {
logger.warning(format("Exception writing to file: %s", file.getName()));
}
firstWindowSaved = true;
}
long currentTime = System.nanoTime();
windowTime += currentTime;
logIfMaster(format(" Time elapsed for this iteration: %11.3f sec", windowTime * 1.0E-9));
logIfMaster(format(" Overall time elapsed: %11.3f sec", (currentTime + beginTime) * 1.0E-9));
/*for (Residue residue : residueList) {
if (residue instanceof MultiResidue) {
((MultiResidue) residue).setDefaultResidue();
residue.reInitOriginalAtomList();
}
}*/
}
break;
default:
// No default case.
break;
}
return 0.0;
}
use of ffx.potential.bonded.Residue in project ffx by mjschnie.
the class RotamerOptimization method optimize.
/**
* Execute the rotamer optimization.
*
* @return The lowest energy found.
*/
public double optimize() {
boolean ignoreNA = false;
String ignoreNAProp = System.getProperty("ignoreNA");
if (ignoreNAProp != null && ignoreNAProp.equalsIgnoreCase("true")) {
logger.info("(Key) Ignoring nucleic acids.");
ignoreNA = true;
}
logger.info(format("\n Rotamer Library: %s", library.getLibrary()));
logger.info(format(" Algorithm: %s", algorithm));
logger.info(format(" Goldstein Criteria: %b", useGoldstein));
logger.info(format(" Three-Body Energies: %b\n", threeBodyTerm));
/*
* Collect all residues in the MolecularAssembly. Use all Residues with
* Rotamers and all forced residues if using sliding window and forced
* residues. Forced residues is meaningless for other algorithms, and
* will be reverted to false.
*/
allResiduesList = new ArrayList<>();
polymers = molecularAssembly.getChains();
for (Polymer polymer : polymers) {
ArrayList<Residue> current = polymer.getResidues();
for (Residue residuej : current) {
if (useForcedResidues) {
switch(algorithm) {
case WINDOW:
if (residuej == null) {
// Do nothing.
} else if (residuej.getRotamers(library) != null) {
allResiduesList.add(residuej);
} else {
int indexJ = residuej.getResidueNumber();
if (checkIfForced(indexJ)) {
allResiduesList.add(residuej);
}
}
break;
default:
// Should only trigger once before resetting useForcedResidues to false.
logIfMaster(" Forced residues only applicable to sliding window.", Level.WARNING);
useForcedResidues = false;
if (residuej != null && (residuej.getRotamers(library) != null)) {
if (!(ignoreNA && residuej.getResidueType() == Residue.ResidueType.NA)) {
allResiduesList.add(residuej);
}
}
break;
}
} else if (residuej != null && (residuej.getRotamers(library) != null)) {
if (!(ignoreNA && residuej.getResidueType() == Residue.ResidueType.NA)) {
allResiduesList.add(residuej);
}
}
}
}
sortResidues(allResiduesList);
sortResidues(residueList);
// If -DignoreNA=true, then remove nucleic acids from residue list.
if (ignoreNA) {
for (int i = 0; i < residueList.size(); i++) {
Residue res = residueList.get(i);
if (res.getResidueType() == Residue.ResidueType.NA) {
residueList.remove(i);
}
}
}
// for NA only
RotamerLibrary.initializeDefaultAtomicCoordinates(molecularAssembly.getChains());
numResidues = allResiduesList.size();
allResiduesArray = allResiduesList.toArray(new Residue[numResidues]);
/*
* Distance matrix is used to add residues to the sliding window
* based on distance cutoff, and to automatically set some 3-body terms
* to 0 at > 10 angstroms.
*
* The memory and compute overhead can be a problem for some very large
* structures.
*/
if (distance > 0) {
distanceMatrix();
}
double e = 0.0;
if (residueList != null) {
done = false;
terminate = false;
switch(algorithm) {
case INDEPENDENT:
e = independent(residueList);
break;
case BRUTE_FORCE:
e = bruteForce(residueList);
break;
case ALL:
e = globalOptimization(residueList);
break;
case WINDOW:
e = slidingWindowOptimization(residueList, windowSize, increment, revert, distance, direction);
break;
case BOX:
e = boxOptimization(residueList);
break;
default:
break;
}
terminate = false;
done = true;
}
return e;
}
Aggregations