use of ffx.potential.bonded.Rotamer in project ffx by mjschnie.
the class RotamerOptimization method evaluateDistance.
/**
* Evaluates the pairwise distance between two residues' rotamers under any
* symmetry operator; does "lazy loading" for the distance matrix.
*
* @param i Residue i
* @param ri Rotamer for i
* @param j Residue j
* @param rj Rotamer for j
* @return Shortest distance
*/
private double evaluateDistance(int i, int ri, int j, int rj) {
Residue resi = allResiduesArray[i];
Rotamer[] rotamersI = resi.getRotamers(library);
Rotamer roti = rotamersI[ri];
double[][] xi;
if (roti.equals(resi.getRotamer())) {
xi = resi.storeCoordinateArray();
} else {
ResidueState origI = resi.storeState();
RotamerLibrary.applyRotamer(resi, roti);
xi = resi.storeCoordinateArray();
resi.revertState(origI);
}
Residue resj = allResiduesArray[j];
Rotamer[] rotamersJ = resj.getRotamers(library);
Rotamer rotj = rotamersJ[rj];
double[][] xj;
if (rotj.equals(resj.getRotamer())) {
xj = resj.storeCoordinateArray();
} else {
ResidueState origJ = resj.storeState();
RotamerLibrary.applyRotamer(resj, rotj);
xj = resj.storeCoordinateArray();
resj.revertState(origJ);
}
Crystal crystal = molecularAssembly.getCrystal();
int nSymm = crystal.spaceGroup.getNumberOfSymOps();
double minDist = Double.MAX_VALUE;
for (int iSymOp = 0; iSymOp < nSymm; iSymOp++) {
SymOp symOp = crystal.spaceGroup.getSymOp(iSymOp);
double dist = interResidueDistance(xi, xj, symOp);
minDist = dist < minDist ? dist : minDist;
}
return minDist;
}
use of ffx.potential.bonded.Rotamer in project ffx by mjschnie.
the class RotamerOptimization method pairsToSingleElimination.
/**
* Method to check if pairs elimination for some residue pair has enabled a
* singles rotamer elimination by eliminating all ri-rj for some ri or some
* rj.
*
* @param residues Residues under consideration.
* @param i A residue index.
* @param j A residue index j!=i
* @return If any singletons were eliminated.
*/
private boolean pairsToSingleElimination(Residue[] residues, int i, int j) {
assert i != j;
assert i < residues.length;
assert j < residues.length;
Residue residuei = residues[i];
Residue residuej = residues[j];
Rotamer[] rotsi = residuei.getRotamers(library);
Rotamer[] rotsj = residuej.getRotamers(library);
int lenri = rotsi.length;
int lenrj = rotsj.length;
boolean eliminated = false;
// Now check ris with no remaining pairs to j.
for (int ri = 0; ri < lenri; ri++) {
if (check(i, ri)) {
continue;
}
boolean pairRemaining = false;
for (int rj = 0; rj < lenrj; rj++) {
if (!check(j, rj) && !check(i, ri, j, rj)) {
pairRemaining = true;
break;
}
}
if (!pairRemaining) {
if (eliminateRotamer(residues, i, ri, print)) {
eliminated = true;
logIfMaster(format(" Eliminating rotamer %s-%d with no remaining pairs to residue %s.", residuei.toFormattedString(false, true), ri, residuej));
} else {
logIfMaster(format(" Already eliminated rotamer %s-%d with no remaining pairs to residue %s.", residuei.toFormattedString(false, true), ri, residuej), Level.WARNING);
}
}
}
// Check rjs with no remaining pairs to i.
for (int rj = 0; rj < lenrj; rj++) {
if (check(j, rj)) {
continue;
}
boolean pairRemaining = false;
for (int ri = 0; ri < lenri; ri++) {
if (!check(i, ri) && !check(i, ri, j, rj)) {
pairRemaining = true;
break;
}
}
if (!pairRemaining) {
if (eliminateRotamer(residues, j, rj, print)) {
eliminated = true;
logIfMaster(format(" Eliminating rotamer %s-%d with no remaining pairs to residue %s.", residuej.toFormattedString(false, true), rj, residuei));
} else {
logIfMaster(format(" Already eliminated rotamer J %s-%d with no remaining pairs to residue %s.", residuej.toFormattedString(false, true), rj, residuei), Level.WARNING);
}
}
}
return eliminated;
}
use of ffx.potential.bonded.Rotamer in project ffx by mjschnie.
the class RotamerOptimization method setResidues.
/**
* Set a contiguous block of residues to optimize.
*
* @param startResID
* @param finalResID
*/
public void setResidues(int startResID, int finalResID) {
Polymer polymer;
if (chain != null) {
polymer = molecularAssembly.getChain(chain);
} else {
polymers = molecularAssembly.getChains();
polymer = polymers[0];
}
residueList = new ArrayList<>();
for (int i = startResID; i <= finalResID; i++) {
Residue residue = polymer.getResidue(i);
if (residue != null) {
Rotamer[] rotamers = residue.getRotamers(library);
if (rotamers != null) {
if (rotamers.length == 1) {
switch(residue.getResidueType()) {
case NA:
residue.initializeDefaultAtomicCoordinates();
break;
case AA:
default:
RotamerLibrary.applyRotamer(residue, rotamers[0]);
break;
}
if (addOrigRot) {
residueList.add(residue);
}
} else {
residueList.add(residue);
}
} else if (useForcedResidues && checkIfForced(i)) {
residueList.add(residue);
}
}
}
}
use of ffx.potential.bonded.Rotamer in project ffx by mjschnie.
the class RotamerOptimization method rotamerOptimization.
/**
* A brute-force global optimization over side-chain rotamers using a
* recursive algorithm.
*
* @param molecularAssembly
* @param residues
* @param i
* @param lowEnergy
* @param optimum
* @return the current energy.
*/
public double rotamerOptimization(MolecularAssembly molecularAssembly, Residue[] residues, int i, double lowEnergy, int[] optimum) {
// This is the initialization condition.
if (i == 0) {
evaluatedPermutations = 0;
}
int nResidues = residues.length;
Residue current = residues[i];
Rotamer[] rotamers = current.getRotamers(library);
int lenri = rotamers.length;
double currentEnergy = Double.MAX_VALUE;
List<Residue> resList = Arrays.asList(residues);
if (i < nResidues - 1) {
/**
* As long as there are more residues, continue the recursion for
* each rotamer of the current residue.
*/
int minRot = -1;
for (int ri = 0; ri < lenri; ri++) {
applyRotamer(current, rotamers[ri]);
double rotEnergy = rotamerOptimization(molecularAssembly, residues, i + 1, lowEnergy, optimum);
if (rotEnergy < currentEnergy) {
currentEnergy = rotEnergy;
}
if (rotEnergy < lowEnergy) {
minRot = ri;
lowEnergy = rotEnergy;
}
}
if (minRot > -1) {
optimum[i] = minRot;
}
} else {
/**
* At the end of the recursion, compute the potential energy for
* each rotamer of the final residue. If a lower potential energy is
* discovered, the rotamers of each residue will be collected as the
* recursion returns up the chain.
*/
for (int ri = 0; ri < lenri; ri++) {
applyRotamer(current, rotamers[ri]);
double rotEnergy = Double.NaN;
try {
rotEnergy = currentEnergy(resList);
logger.info(format(" %d Energy: %s", ++evaluatedPermutations, formatEnergy(rotEnergy)));
} catch (ArithmeticException ex) {
logger.info(String.format(" %d Energy set to NaN (unreasonable conformation)", ++evaluatedPermutations));
}
if (algorithmListener != null) {
algorithmListener.algorithmUpdate(molecularAssembly);
}
if (rotEnergy < currentEnergy) {
currentEnergy = rotEnergy;
}
if (rotEnergy < lowEnergy) {
lowEnergy = rotEnergy;
optimum[nResidues - 1] = ri;
}
}
}
return currentEnergy;
}
use of ffx.potential.bonded.Rotamer in project ffx by mjschnie.
the class RotamerOptimization method printLargeInteractions.
/**
* Prints a summary of pair and trimer energies above [cutoff] kcal/mol.
*
* @param pairCutoff
* @param trimerCutoff
* @param dOMode
*/
public void printLargeInteractions(double pairCutoff, double trimerCutoff, boolean dOMode) {
Residue[] residues = residueList.toArray(new Residue[residueList.size()]);
int nRes = residues.length;
if (dOMode) {
logger.info(format(" Large pair interactions (>%.2f):", pairCutoff));
for (int i = 0; i < nRes; i++) {
for (int j = i + 1; j < nRes; j++) {
if (Math.abs(twoBodyEnergy[i][0][j][0]) >= pairCutoff) {
logger.info(format(" Large Pair %s %s: %16.5f", residues[i].toFormattedString(false, true), residues[j].toFormattedString(false, true), twoBodyEnergy[i][0][j][0]));
}
}
}
logger.info(format("\n Large trimer interactions (>%.2f):", trimerCutoff));
for (int i = 0; i < nRes; i++) {
for (int j = i + 1; j < nRes; j++) {
for (int k = j + 1; k < nRes; k++) {
if (Math.abs(threeBodyEnergy[i][0][j][0][k][0]) >= trimerCutoff) {
logger.info(format(" Large Trimer %s %s %s: %16.5f", residues[i].toFormattedString(false, true), residues[j].toFormattedString(false, true), residues[k].toFormattedString(false, true), threeBodyEnergy[i][0][j][0][k][0]));
}
}
}
}
return;
}
logger.info(format(" Large pair interactions (>%.2f):", pairCutoff));
for (int i = 0; i < nRes; i++) {
Residue resi = residues[i];
Rotamer[] roti = resi.getRotamers(library);
for (int ri = 0; ri < roti.length; ri++) {
for (int j = i + 1; j < nRes; j++) {
Residue resj = residues[j];
Rotamer[] rotj = resj.getRotamers(library);
for (int rj = 0; rj < rotj.length; rj++) {
try {
if (Math.abs(twoBodyEnergy[i][ri][j][rj]) >= pairCutoff) {
logger.info(format(" Large Pair %8s %-2d, %8s %-2d: %s", resi.toFormattedString(false, true), ri, resj.toFormattedString(false, true), rj, formatEnergy(twoBodyEnergy[i][ri][j][rj])));
}
} catch (Exception ex) {
}
}
}
}
}
logger.info(format("\n Large trimer interactions (>%.2f):", trimerCutoff));
for (int i = 0; i < nRes; i++) {
Residue resi = residues[i];
Rotamer[] roti = resi.getRotamers(library);
for (int ri = 0; ri < roti.length; ri++) {
for (int j = i + 1; j < nRes; j++) {
Residue resj = residues[j];
Rotamer[] rotj = resj.getRotamers(library);
for (int rj = 0; rj < rotj.length; rj++) {
for (int k = j + 1; k < nRes; k++) {
Residue resk = residues[k];
Rotamer[] rotk = resk.getRotamers(library);
for (int rk = 0; rk < rotk.length; rk++) {
try {
if (Math.abs(threeBodyEnergy[i][ri][j][rj][k][rk]) >= trimerCutoff) {
logger.info(format(" Large Trimer %8s %-2d, %8s %-2d, %8s %-2d: %s", resi.toFormattedString(false, true), ri, resj.toFormattedString(false, true), rj, resk.toFormattedString(false, true), rk, formatEnergy(threeBodyEnergy[i][ri][j][rj][k][rk])));
}
} catch (Exception ex) {
}
}
}
}
}
}
}
}
Aggregations