Search in sources :

Example 31 with Residue

use of ffx.potential.bonded.Residue in project ffx by mjschnie.

the class PhMD method mcUpdate.

/**
 * The primary driver. Called by the MD engine at each dynamics step.
 */
@Override
public boolean mcUpdate(double temperature) {
    startTime = System.nanoTime();
    if (thermostat.getCurrentTemperature() > config.meltdownTemperature) {
        meltdown();
    }
    if (thermostat.getCurrentTemperature() > config.warningTemperature) {
        Atom[] atoms = mola.getAtomArray();
        logger.info(format(" System heating! Dumping atomic velocities for %d D.o.F.:", ffe.getNumberOfVariables()));
        double[] velocity = new double[3];
        for (Atom atom : atoms) {
            atom.getVelocity(velocity);
            logger.info(format(" %s: %s", atom.describe(Atom.Descriptions.Trim), Arrays.toString(velocity)));
        }
    }
    esvSystem.setTemperature(temperature);
    propagateInactiveResidues(titratingMultis);
    stepCount++;
    // Decide on the type of step to be taken.
    StepType stepType;
    if (stepCount % mcStepFrequency == 0 && stepCount % rotamerStepFrequency == 0) {
        stepType = StepType.COMBO;
    } else if (stepCount % mcStepFrequency == 0) {
        stepType = StepType.TITRATE;
    } else if (stepCount % rotamerStepFrequency == 0) {
        stepType = StepType.ROTAMER;
    } else {
        // Not yet time for an MC step, return to MD.
        if (config.logTimings) {
            long took = System.nanoTime() - startTime;
            logger.info(String.format(" CpHMD propagation time: %.6f", took * NS_TO_SEC));
        }
        return false;
    }
    logger.info(format("TitratingMultis: %d", titratingMultis.size()));
    // Randomly choose a target titratable residue to attempt protonation switch.
    int random = (config.titrateTermini) ? rng.nextInt(titratingMultis.size() + titratingTermini.size()) : rng.nextInt(titratingMultis.size());
    if (random >= titratingMultis.size()) {
        Residue target = titratingTermini.get(random - titratingMultis.size());
        boolean accepted = tryTerminusTitration((MultiTerminus) target);
        snapshotIndex++;
        if (accepted) {
            molDyn.reInit();
            previousTarget = target;
        }
        return accepted;
    }
    MultiResidue targetMulti = titratingMultis.get(random);
    // Check whether rotamer moves are possible for the selected residue.
    Residue targetMultiActive = targetMulti.getActive();
    Rotamer[] targetMultiRotamers = targetMultiActive.getRotamers(library);
    if (targetMultiRotamers == null || targetMultiRotamers.length <= 1) {
        if (stepType == StepType.ROTAMER) {
            return false;
        } else if (stepType == StepType.COMBO) {
            stepType = StepType.TITRATE;
        }
    }
    // Perform the MC move.
    boolean accepted;
    switch(stepType) {
        case TITRATE:
            accepted = tryTitrationStep(targetMulti);
            break;
        case ROTAMER:
            accepted = (config.useConformationalBias) ? tryCBMCStep(targetMulti) : tryRotamerStep(targetMulti);
            break;
        case COMBO:
            accepted = (config.useConformationalBias) ? tryCBMCStep(targetMulti) || tryTitrationStep(targetMulti) : tryComboStep(targetMulti);
            break;
        default:
            accepted = false;
            throw new IllegalStateException();
    }
    snapshotIndex++;
    if (accepted) {
        previousTarget = targetMulti;
    }
    if (config.logTimings) {
        long took = System.nanoTime() - startTime;
        logger.info(String.format(" CpHMD step time:        %.6f", took * NS_TO_SEC));
    }
    return accepted;
}
Also used : TitrationUtils.inactivateResidue(ffx.potential.extended.TitrationUtils.inactivateResidue) MultiResidue(ffx.potential.bonded.MultiResidue) Residue(ffx.potential.bonded.Residue) Rotamer(ffx.potential.bonded.Rotamer) Atom(ffx.potential.bonded.Atom) MultiResidue(ffx.potential.bonded.MultiResidue) MCOverride(ffx.potential.extended.TitrationUtils.MCOverride)

Example 32 with Residue

use of ffx.potential.bonded.Residue in project ffx by mjschnie.

the class PhMD method tryComboStep.

/**
 * Attempt a combination titration/rotamer MC move.
 *
 * @param targetMulti
 * @return accept/reject
 */
private boolean tryComboStep(MultiResidue targetMulti) {
    if (CAUTIOUS) {
        throw new UnsupportedOperationException();
    }
    // Record the pre-change total energy.
    double previousTotalEnergy = currentTotalEnergy();
    double previousElectrostaticEnergy = currentElectrostaticEnergy();
    // Write the pre-combo snapshot.
    writeSnapshot(true, StepType.COMBO, config.snapshots);
    String startString = targetMulti.toString();
    String startName = targetMulti.getActive().getName();
    // Choose from the list of available titrations for the active residue.
    List<Titration> avail = titrationMap.get(targetMulti.getActive());
    Titration titration = avail.get(rng.nextInt(avail.size()));
    // Perform the chosen titration.
    TitrationType titrationType = performTitration(targetMulti, titration, config.inactivateBackground);
    // Change rotamer state, but first save coordinates so we can return to them if rejected.
    Residue residue = targetMulti.getActive();
    ArrayList<Atom> atoms = residue.getAtomList();
    ResidueState origState = residue.storeState();
    double[] chi = new double[4];
    RotamerLibrary.measureAARotamer(residue, chi, false);
    AminoAcid3 aa = AminoAcid3.valueOf(residue.getName());
    Rotamer origCoordsRotamer = new Rotamer(aa, origState, chi[0], 0, chi[1], 0, chi[2], 0, chi[3], 0);
    // Swap to the new rotamer.
    Rotamer[] rotamers = residue.getRotamers(library);
    int rotaRand = rng.nextInt(rotamers.length);
    RotamerLibrary.applyRotamer(residue, rotamers[rotaRand]);
    // Write the post-combo snapshot.
    writeSnapshot(false, StepType.COMBO, config.snapshots);
    // Evaluate both MC criteria.
    String endName = targetMulti.getActive().getName();
    // Evaluate the titration probability of the step.
    double pKaref = titration.pKa;
    double dG_ref = titration.refEnergy;
    double temperature = thermostat.getCurrentTemperature();
    double kT = BOLTZMANN * temperature;
    double dG_elec = currentElectrostaticEnergy() - previousElectrostaticEnergy;
    if (config.zeroReferenceEnergies) {
        dG_ref = 0.0;
    }
    double prefix = Math.log(10) * kT * (pH - pKaref);
    if (titrationType == TitrationType.DEPROT) {
        prefix = -prefix;
    }
    double postfix = dG_elec - dG_ref;
    double dG_titr = prefix + postfix;
    double titrCriterion = exp(-dG_titr / kT);
    // Evaluate the rotamer probability of the step.
    double dG_rota = currentTotalEnergy() - previousTotalEnergy;
    double rotaCriterion = exp(-dG_rota / kT);
    StringBuilder sb = new StringBuilder();
    sb.append(String.format(" Assessing possible MC combo step:\n"));
    sb.append(String.format("     dG_elec: %16.8f\n", dG_elec));
    sb.append(String.format("     dG_titr: %16.8f\n", dG_titr));
    sb.append(String.format("     dG_rota: %16.8f\n", dG_rota));
    sb.append(String.format("     -----\n"));
    // Automatic acceptance if both energy changes are favorable.
    if (dG_titr < 0 && dG_rota < 0 && config.mcOverride != MCOverride.REJECT) {
        sb.append(String.format("     Accepted!"));
        logger.info(sb.toString());
        numMovesAccepted++;
        propagateInactiveResidues(titratingMultis, false);
        return true;
    } else {
        // Conditionally accept based on combined probabilities.
        if (dG_titr < 0 || config.mcOverride == MCOverride.ACCEPT) {
            titrCriterion = 1.0;
        }
        if (dG_rota < 0) {
            rotaCriterion = 1.0;
        }
        if (config.mcOverride == MCOverride.REJECT) {
            titrCriterion = 0.0;
        }
        double metropolis = random();
        double comboCriterion = titrCriterion * rotaCriterion;
        sb.append(String.format("     titrCrit:   %9.4f\n", titrCriterion));
        sb.append(String.format("     rotaCrit:   %9.4f\n", rotaCriterion));
        sb.append(String.format("     criterion:  %9.4f\n", comboCriterion));
        sb.append(String.format("     rng:        %9.4f\n", metropolis));
        if (metropolis < comboCriterion) {
            sb.append(String.format("     Accepted!"));
            logger.info(sb.toString());
            numMovesAccepted++;
            propagateInactiveResidues(titratingMultis, false);
            return true;
        } else {
            // Move was denied.
            sb.append(String.format("     Denied."));
            logger.info(sb.toString());
            // Undo both pieces of the rejected move IN THE RIGHT ORDER.
            RotamerLibrary.applyRotamer(residue, origCoordsRotamer);
            performTitration(targetMulti, titration, config.inactivateBackground);
            ffe.reInit();
            molDyn.reInit();
            return false;
        }
    }
}
Also used : ResidueState(ffx.potential.bonded.ResidueState) AminoAcid3(ffx.potential.bonded.ResidueEnumerations.AminoAcid3) TitrationType(ffx.potential.extended.TitrationUtils.TitrationType) Rotamer(ffx.potential.bonded.Rotamer) Atom(ffx.potential.bonded.Atom) TitrationUtils.inactivateResidue(ffx.potential.extended.TitrationUtils.inactivateResidue) MultiResidue(ffx.potential.bonded.MultiResidue) Residue(ffx.potential.bonded.Residue) Titration(ffx.potential.extended.TitrationUtils.Titration) TitrationUtils.performTitration(ffx.potential.extended.TitrationUtils.performTitration)

Example 33 with Residue

use of ffx.potential.bonded.Residue in project ffx by mjschnie.

the class PhMD method tryRotamerStep.

/**
 * Attempt a rotamer MC move.
 *
 * @param targetMulti
 * @return accept/reject
 */
private boolean tryRotamerStep(MultiResidue targetMulti) {
    if (CAUTIOUS) {
        throw new UnsupportedOperationException();
    }
    // Record the pre-change total energy.
    double previousTotalEnergy = currentTotalEnergy();
    // Write the before-step snapshot.
    writeSnapshot(true, StepType.ROTAMER, config.snapshots);
    // Save coordinates so we can return to them if move is rejected.
    Residue residue = targetMulti.getActive();
    ArrayList<Atom> atoms = residue.getAtomList();
    ResidueState origState = residue.storeState();
    double[] chi = new double[4];
    RotamerLibrary.measureAARotamer(residue, chi, false);
    AminoAcid3 aa = AminoAcid3.valueOf(residue.getName());
    Rotamer origCoordsRotamer = new Rotamer(aa, origState, chi[0], 0, chi[1], 0, chi[2], 0, chi[3], 0);
    // Select a new rotamer and swap to it.
    Rotamer[] rotamers = residue.getRotamers(library);
    int rotaRand = rng.nextInt(rotamers.length);
    RotamerLibrary.applyRotamer(residue, rotamers[rotaRand]);
    // Write the post-rotamer change snapshot.
    writeSnapshot(false, StepType.ROTAMER, config.snapshots);
    // Check the MC criterion.
    double temperature = thermostat.getCurrentTemperature();
    double kT = BOLTZMANN * temperature;
    double postTotalEnergy = currentTotalEnergy();
    double dG_tot = postTotalEnergy - previousTotalEnergy;
    double criterion = exp(-dG_tot / kT);
    StringBuilder sb = new StringBuilder();
    sb.append(String.format(" Assessing possible MC rotamer step:\n"));
    sb.append(String.format("     prev:   %16.8f\n", previousTotalEnergy));
    sb.append(String.format("     post:   %16.8f\n", postTotalEnergy));
    sb.append(String.format("     dG_tot: %16.8f\n", dG_tot));
    sb.append(String.format("     -----\n"));
    // Automatic acceptance if energy change is favorable.
    if (dG_tot < 0) {
        sb.append(String.format("     Accepted!"));
        logger.info(sb.toString());
        numMovesAccepted++;
        propagateInactiveResidues(titratingMultis, true);
        return true;
    } else {
        // Conditional acceptance if energy change is positive.
        double metropolis = random();
        sb.append(String.format("     criterion:  %9.4f\n", criterion));
        sb.append(String.format("     rng:        %9.4f\n", metropolis));
        if (metropolis < criterion) {
            sb.append(String.format("     Accepted!"));
            logger.info(sb.toString());
            numMovesAccepted++;
            propagateInactiveResidues(titratingMultis, true);
            return true;
        } else {
            // Move was denied.
            sb.append(String.format("     Denied."));
            logger.info(sb.toString());
            // Undo the rejected move.
            RotamerLibrary.applyRotamer(residue, origCoordsRotamer);
            return false;
        }
    }
}
Also used : TitrationUtils.inactivateResidue(ffx.potential.extended.TitrationUtils.inactivateResidue) MultiResidue(ffx.potential.bonded.MultiResidue) Residue(ffx.potential.bonded.Residue) ResidueState(ffx.potential.bonded.ResidueState) AminoAcid3(ffx.potential.bonded.ResidueEnumerations.AminoAcid3) Rotamer(ffx.potential.bonded.Rotamer) Atom(ffx.potential.bonded.Atom)

Example 34 with Residue

use of ffx.potential.bonded.Residue in project ffx by mjschnie.

the class PhMD method readyup.

private void readyup() {
    // Create MultiTerminus objects to wrap termini.
    if (config.titrateTermini) {
        for (Residue res : mola.getResidueList()) {
            if (res.getPreviousResidue() == null || res.getNextResidue() == null) {
                MultiTerminus multiTerminus = new MultiTerminus(res, ff, ffe, mola);
                Polymer polymer = findResiduePolymer(res, mola);
                polymer.addMultiTerminus(res, multiTerminus);
                reInitialize(true, false);
                titratingTermini.add(multiTerminus);
                logger.info(String.format(" Titrating: %s", multiTerminus));
            }
        }
    }
    /* Create containers for titratables: MultiResidues for discrete, ExtendedVariables for continuous. */
    if (distribution == Distribution.CONTINUOUS) {
        esvSystem = new ExtendedSystem(mola);
        esvSystem.setConstantPh(pH);
        for (Residue res : chosenResidues) {
            MultiResidue multi = TitrationUtils.titratingMultiresidueFactory(mola, res);
            TitrationESV esv = new TitrationESV(esvSystem, multi);
            titratingESVs.add(esv);
            for (Residue background : multi.getInactive()) {
                inactivateResidue(background);
            }
            esvSystem.addVariable(esv);
        }
        ffe.attachExtendedSystem(esvSystem);
        logger.info(format(" Continuous pHMD readied with %d residues.", titratingESVs.size()));
    } else {
        for (Residue res : chosenResidues) {
            // Create MultiResidue objects to wrap titratables.
            MultiResidue multiRes = new MultiResidue(res, ff, ffe);
            Polymer polymer = findResiduePolymer(res, mola);
            polymer.addMultiResidue(multiRes);
            recursiveMap(res, multiRes);
            // Switch back to the original form and ready the ForceFieldEnergy.
            multiRes.setActiveResidue(res);
            reInitialize(true, false);
            titratingMultis.add(multiRes);
            logger.info(String.format(" Titrating: %s", multiRes));
        }
        logger.info(format(" Discrete MCMD readied with %d residues.", titratingMultis.size()));
    }
    switch(distribution) {
        default:
        case DISCRETE:
            molDyn.setMonteCarloListener(this, MonteCarloNotification.EACH_STEP);
            break;
        case CONTINUOUS:
            ffe.attachExtendedSystem(esvSystem);
            molDyn.attachExtendedSystem(esvSystem, 100);
            break;
    }
}
Also used : TitrationUtils.inactivateResidue(ffx.potential.extended.TitrationUtils.inactivateResidue) MultiResidue(ffx.potential.bonded.MultiResidue) Residue(ffx.potential.bonded.Residue) ExtendedSystem(ffx.potential.extended.ExtendedSystem) MultiTerminus(ffx.potential.bonded.MultiTerminus) Polymer(ffx.potential.bonded.Polymer) TitrationUtils.findResiduePolymer(ffx.potential.extended.TitrationUtils.findResiduePolymer) MultiResidue(ffx.potential.bonded.MultiResidue) TitrationESV(ffx.potential.extended.TitrationESV)

Example 35 with Residue

use of ffx.potential.bonded.Residue in project ffx by mjschnie.

the class RotamerOptimizationTest method testSelfEnergyElimination.

@Test
public void testSelfEnergyElimination() {
    // Load the test system.
    load();
    // Initialize Parallel Java
    try {
        String[] args = new String[0];
        Comm.init(args);
    } catch (Exception e) {
        String message = String.format(" Exception starting up the Parallel Java communication layer.");
        logger.log(Level.WARNING, message, e.toString());
        message = String.format(" Skipping rotamer optimization test.");
        logger.log(Level.WARNING, message, e.toString());
        return;
    }
    // Run the optimization.
    RotamerLibrary rLib = RotamerLibrary.getDefaultLibrary();
    rLib.setLibrary(RotamerLibrary.ProteinLibrary.Richardson);
    rLib.setUseOrigCoordsRotamer(useOriginalRotamers);
    int counter = 1;
    ArrayList<Residue> residueList = new ArrayList<Residue>();
    Polymer[] polymers = molecularAssembly.getChains();
    int nPolymers = polymers.length;
    for (int p = 0; p < nPolymers; p++) {
        Polymer polymer = polymers[p];
        ArrayList<Residue> residues = polymer.getResidues();
        for (int i = 0; i < endResID; i++) {
            Residue residue = residues.get(i);
            Rotamer[] rotamers = residue.getRotamers(rLib);
            if (rotamers != null) {
                int nrot = rotamers.length;
                if (nrot == 1) {
                    RotamerLibrary.applyRotamer(residue, rotamers[0]);
                }
                if (counter >= startResID) {
                    residueList.add(residue);
                }
            }
            counter++;
        }
    }
    RotamerOptimization rotamerOptimization = new RotamerOptimization(molecularAssembly, forceFieldEnergy, null);
    rotamerOptimization.setThreeBodyEnergy(useThreeBody);
    rotamerOptimization.setUseGoldstein(useGoldstein);
    rotamerOptimization.setPruning(pruningLevel);
    rotamerOptimization.setEnergyRestartFile(restartFile);
    rotamerOptimization.setResidues(residueList);
    double energy;
    int nRes = residueList.size();
    if (doOverallOpt) {
        rotamerOptimization.turnRotamerPairEliminationOff();
        rotamerOptimization.setTestOverallOpt(true);
        energy = rotamerOptimization.optimize(RotamerOptimization.Algorithm.ALL);
        // System.out.println("The expected overall energy is: " + energy);
        assertEquals(info + " Total Energy", expectedEnergy, energy, tolerance);
    }
    if (doSelfOpt) {
        rotamerOptimization.turnRotamerPairEliminationOff();
        rotamerOptimization.setTestSelfEnergyEliminations(true);
        energy = rotamerOptimization.optimize(RotamerOptimization.Algorithm.ALL);
        // System.out.println("The expected self is: " + energy);
        assertEquals(info + " Self-Energy", expectedSelfEnergy, energy, tolerance);
        // Check that optimized rotamers are equivalent to the lowest self-energy of each residue.
        int[] optimum = rotamerOptimization.getOptimumRotamers();
        // Loop over all residues
        for (int i = 0; i < nRes; i++) {
            Residue res = residueList.get(i);
            Rotamer[] rotI = res.getRotamers(rLib);
            int nRot = rotI.length;
            int rotCounter = 0;
            while (rotCounter < nRot && rotamerOptimization.checkPrunedSingles(i, rotCounter)) {
                rotCounter++;
            }
            double lowEnergy = rotamerOptimization.getSelf(i, rotCounter);
            int bestRot = rotCounter;
            for (int ri = 1; ri < nRot; ri++) {
                if (rotamerOptimization.checkPrunedSingles(i, ri)) {
                    continue;
                } else {
                    double selfEnergy = rotamerOptimization.getSelf(i, ri);
                    if (selfEnergy < lowEnergy) {
                        lowEnergy = selfEnergy;
                        bestRot = ri;
                    }
                }
            }
            assertEquals(String.format(" %s Self-Energy of residue %d", info, i), optimum[i], bestRot);
        }
    }
    if (doPairOpt) {
        rotamerOptimization.turnRotamerPairEliminationOff();
        rotamerOptimization.setTestPairEnergyEliminations(pairResidue);
        energy = rotamerOptimization.optimize(RotamerOptimization.Algorithm.ALL);
        assertEquals(info + " Pair-Energy", expectedPairEnergy, energy, tolerance);
        // Check that optimized rotamers are equivalent to the lowest 2-Body energy sum for the "pairResidue".
        int[] optimum = rotamerOptimization.getOptimumRotamers();
        Residue resI = residueList.get(pairResidue);
        Rotamer[] rotI = resI.getRotamers(rLib);
        int ni = rotI.length;
        double minEnergy = Double.POSITIVE_INFINITY;
        int bestRotI = -1;
        // Loop over the pairResidue rotamers to find its lowest energy rotamer.
        for (int ri = 0; ri < ni; ri++) {
            double energyForRi = 0.0;
            if (rotamerOptimization.checkPrunedSingles(pairResidue, ri)) {
                continue;
            }
            // Loop over residue J
            for (int j = 0; j < nRes; j++) {
                if (j == pairResidue) {
                    continue;
                }
                Residue resJ = residueList.get(j);
                Rotamer[] rotJ = resJ.getRotamers(rLib);
                int nRot = rotJ.length;
                int rj = 0;
                while (rotamerOptimization.checkPrunedSingles(j, rj) || rotamerOptimization.checkPrunedPairs(pairResidue, ri, j, rj)) {
                    if (++rj >= nRot) {
                        logger.warning("RJ is too large.");
                    }
                }
                double lowEnergy = rotamerOptimization.get2Body(pairResidue, ri, j, rj);
                for (rj = 1; rj < nRot; rj++) {
                    if (rotamerOptimization.checkPrunedSingles(j, rj) || rotamerOptimization.checkPrunedPairs(pairResidue, ri, j, rj)) {
                        continue;
                    } else {
                        double pairEnergy = rotamerOptimization.get2Body(pairResidue, ri, j, rj);
                        if (pairEnergy < lowEnergy) {
                            lowEnergy = pairEnergy;
                        }
                    }
                }
                energyForRi += lowEnergy;
            }
            if (energyForRi < minEnergy) {
                minEnergy = energyForRi;
                bestRotI = ri;
            }
        }
        assertEquals(String.format(" %s Best 2-body energy sum for residue %d is with rotamer %d at %10.4f.", info, pairResidue, bestRotI, minEnergy), optimum[pairResidue], bestRotI);
        // Given the minimum energy rotamer for "pairResidue" is "bestRotI", we can check selected rotamers for all other residues.
        for (int j = 0; j < nRes; j++) {
            if (j == pairResidue) {
                continue;
            }
            Residue resJ = residueList.get(j);
            Rotamer[] rotJ = resJ.getRotamers(rLib);
            int nRotJ = rotJ.length;
            int rotCounter = 0;
            while (rotamerOptimization.checkPrunedPairs(pairResidue, bestRotI, j, rotCounter) && rotCounter < nRotJ) {
                rotCounter++;
            }
            double lowEnergy = rotamerOptimization.get2Body(pairResidue, bestRotI, j, rotCounter);
            int bestRotJ = rotCounter;
            for (int rj = 1; rj < nRotJ; rj++) {
                if (rotamerOptimization.checkPrunedSingles(j, rj) || rotamerOptimization.checkPrunedPairs(pairResidue, bestRotI, j, rj)) {
                    continue;
                } else {
                    double pairEnergy = rotamerOptimization.get2Body(pairResidue, bestRotI, j, rj);
                    if (pairEnergy < lowEnergy) {
                        lowEnergy = pairEnergy;
                        bestRotJ = rj;
                    }
                }
            }
            assertEquals(String.format(" %s Pair-Energy of residue (%d,%d) with residue %d", info, pairResidue, bestRotI, j), optimum[j], bestRotJ);
        }
    }
    // Test 3-Body Energy Eliminations.
    if (doTripleOpt) {
        rotamerOptimization.turnRotamerPairEliminationOff();
        rotamerOptimization.setTestTripleEnergyEliminations(tripleResidue1, tripleResidue2);
        try {
            energy = rotamerOptimization.optimize(RotamerOptimization.Algorithm.ALL);
            assertEquals(info + " Triple-Energy", expectedTripleEnergy, energy, tolerance);
        } catch (Exception e) {
            e.fillInStackTrace();
            e.printStackTrace();
            logger.log(java.util.logging.Level.INFO, "Error in doTripleOpt", e);
        }
        // Check that optimized rotamers are equivalent to the lowest 3-body energy of each residue with the tripleResidue1 and 2.
        int[] optimum = rotamerOptimization.getOptimumRotamers();
        // fix residue 1 and gets its rotamers
        Residue resI = residueList.get(tripleResidue1);
        Rotamer[] rotI = resI.getRotamers(rLib);
        int ni = rotI.length;
        // fix residue 2 and get its rotamers
        Residue resJ = residueList.get(tripleResidue2);
        Rotamer[] rotJ = resJ.getRotamers(rLib);
        int nj = rotJ.length;
        double minEnergyIJ = Double.POSITIVE_INFINITY;
        int bestRotI = -1;
        int bestRotJ = -1;
        for (int ri = 0; ri < ni; ri++) {
            // loop through rot I
            if (rotamerOptimization.check(tripleResidue1, ri)) {
                continue;
            }
            for (int rj = 0; rj < nj; rj++) {
                // loop through rot J
                if (rotamerOptimization.checkPrunedSingles(tripleResidue2, rj) || rotamerOptimization.checkPrunedPairs(tripleResidue1, ri, tripleResidue2, rj)) {
                    continue;
                }
                double currentEnergy = 0.0;
                for (int k = 0; k < nRes; k++) {
                    // loop through all other residues
                    if (k == tripleResidue1 || k == tripleResidue2) {
                        continue;
                    }
                    Residue resK = residueList.get(k);
                    Rotamer[] rotK = resK.getRotamers(rLib);
                    int nk = rotK.length;
                    int rkStart = 0;
                    while (rotamerOptimization.checkPrunedSingles(k, rkStart) || rotamerOptimization.checkPrunedPairs(tripleResidue1, ri, k, rkStart) || rotamerOptimization.checkPrunedPairs(tripleResidue2, rj, k, rkStart)) {
                        if (++rkStart >= nk) {
                            logger.warning("RJ is too large.");
                        }
                    }
                    double lowEnergy = rotamerOptimization.get3Body(tripleResidue1, ri, tripleResidue2, rj, k, rkStart);
                    for (int rk = rkStart; rk < nk; rk++) {
                        if (rotamerOptimization.checkPrunedSingles(k, rk) || rotamerOptimization.checkPrunedPairs(tripleResidue1, ri, k, rk) || rotamerOptimization.checkPrunedPairs(tripleResidue2, rj, k, rk)) {
                            continue;
                        } else {
                            double tripleEnergy = rotamerOptimization.get3Body(tripleResidue1, ri, tripleResidue2, rj, k, rk);
                            if (tripleEnergy < lowEnergy) {
                                lowEnergy = tripleEnergy;
                            }
                        }
                    }
                    // adds lowest energy conformation of residue k to that of the rotamer I
                    currentEnergy += lowEnergy;
                }
                if (currentEnergy < minEnergyIJ) {
                    minEnergyIJ = currentEnergy;
                    bestRotI = ri;
                    bestRotJ = rj;
                }
            }
        }
        assertEquals(String.format(" %s Best three-body energy sum for residue %d is with rotamer %d at %10.4f.", info, tripleResidue1, bestRotI, minEnergyIJ), optimum[tripleResidue1], bestRotI);
        assertEquals(String.format(" %s Best three-body energy sum for residue %d is with rotamer %d at %10.4f.", info, tripleResidue2, bestRotJ, minEnergyIJ), optimum[tripleResidue2], bestRotJ);
        // loop over the residues to find the best rotamer per residue given bestRotI and bestRotJ
        for (int k = 0; k < nRes; k++) {
            if (k == tripleResidue1 || k == tripleResidue2) {
                continue;
            }
            Residue resK = residueList.get(k);
            Rotamer[] rotK = resK.getRotamers(rLib);
            int nk = rotK.length;
            int rotCounter = 0;
            while (rotamerOptimization.checkPrunedPairs(tripleResidue1, bestRotI, k, rotCounter) && rotamerOptimization.checkPrunedPairs(tripleResidue2, bestRotJ, k, rotCounter) && rotCounter < nk) {
                rotCounter++;
            }
            double lowEnergy = rotamerOptimization.get3Body(tripleResidue1, bestRotI, tripleResidue2, bestRotJ, k, rotCounter);
            int bestRotK = rotCounter;
            for (int rk = 1; rk < nk; rk++) {
                if (rotamerOptimization.checkPrunedSingles(k, rk) || rotamerOptimization.checkPrunedPairs(tripleResidue1, bestRotI, k, rk) || rotamerOptimization.checkPrunedPairs(tripleResidue2, bestRotJ, k, rk)) {
                    continue;
                } else {
                    double tripleEnergy = rotamerOptimization.get3Body(tripleResidue1, bestRotI, tripleResidue2, bestRotJ, k, rk);
                    if (tripleEnergy < lowEnergy) {
                        lowEnergy = tripleEnergy;
                        bestRotK = rk;
                    }
                }
            }
            assertEquals(String.format(" %s Triple-Energy of residue (%d,%d) and residue (%d,%d) with residue %d", info, tripleResidue1, bestRotI, tripleResidue2, bestRotJ, k), optimum[k], bestRotK);
        }
    }
}
Also used : RotamerLibrary(ffx.potential.bonded.RotamerLibrary) ArrayList(java.util.ArrayList) Polymer(ffx.potential.bonded.Polymer) Rotamer(ffx.potential.bonded.Rotamer) Residue(ffx.potential.bonded.Residue) Test(org.junit.Test)

Aggregations

Residue (ffx.potential.bonded.Residue)102 MultiResidue (ffx.potential.bonded.MultiResidue)66 Rotamer (ffx.potential.bonded.Rotamer)44 Atom (ffx.potential.bonded.Atom)41 RotamerLibrary.applyRotamer (ffx.potential.bonded.RotamerLibrary.applyRotamer)39 ArrayList (java.util.ArrayList)30 Polymer (ffx.potential.bonded.Polymer)29 IOException (java.io.IOException)20 Molecule (ffx.potential.bonded.Molecule)13 NACorrectionException (ffx.potential.bonded.NACorrectionException)13 MSNode (ffx.potential.bonded.MSNode)12 ResidueState (ffx.potential.bonded.ResidueState)11 Bond (ffx.potential.bonded.Bond)10 Crystal (ffx.crystal.Crystal)8 MissingAtomTypeException (ffx.potential.bonded.BondedUtils.MissingAtomTypeException)8 MissingHeavyAtomException (ffx.potential.bonded.BondedUtils.MissingHeavyAtomException)8 File (java.io.File)8 AminoAcid3 (ffx.potential.bonded.ResidueEnumerations.AminoAcid3)7 TitrationUtils.inactivateResidue (ffx.potential.extended.TitrationUtils.inactivateResidue)6 BufferedWriter (java.io.BufferedWriter)6