Search in sources :

Example 1 with MultiResidue

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

the class RotamerOptimization method prunePairClashes.

/**
 * Prunes rotamer ri of residue i if all ri-j pair energies are worse than
 * the best i-j pair by some threshold value; additionally prunes ri-rj
 * pairs if they exceed the best i-j pair by a greater threshold value;
 * additionally performs this in reverse (searches over j-i).
 *
 * @param residues Residues whose rotamers are to be pruned.
 */
private void prunePairClashes(Residue[] residues) {
    if (!prunePairClashes) {
        return;
    }
    int nResidues = residues.length;
    for (int i = 0; i < nResidues - 1; i++) {
        Residue resi = residues[i];
        Rotamer[] rotsi = resi.getRotamers(library);
        int lenri = rotsi.length;
        for (int j = i + 1; j < nResidues; j++) {
            Residue resj = residues[j];
            Rotamer[] rotsj = resj.getRotamers(library);
            int lenrj = rotsj.length;
            double minPair = Double.MAX_VALUE;
            int minRI = -1;
            int minRJ = -1;
            for (int ri = 0; ri < lenri; ri++) {
                if (check(i, ri)) {
                    continue;
                }
                for (int rj = 0; rj < lenrj; rj++) {
                    if (check(j, rj) || check(i, ri, j, rj)) {
                        continue;
                    }
                    double pairEnergy = get2Body(i, ri, j, rj) + getSelf(i, ri) + getSelf(j, rj);
                    assert Double.isFinite(pairEnergy);
                    if (pairEnergy < minPair) {
                        minPair = pairEnergy;
                        minRI = ri;
                        minRJ = rj;
                    }
                }
            }
            // Otherwise, i and j are not on a well-packed backbone.
            assert (minRI >= 0 && minRJ >= 0);
            // Calculate all the modifiers to the pair clash elimination threshold.
            double threshold = pairClashThreshold;
            if (resi instanceof MultiResidue) {
                threshold += multiResPairClashAddn;
            }
            if (resj instanceof MultiResidue) {
                threshold += multiResPairClashAddn;
            }
            int numNARes = (resi.getResidueType() == NA ? 1 : 0) + (resj.getResidueType() == NA ? 1 : 0);
            switch(numNARes) {
                case 0:
                    break;
                case 1:
                    threshold *= pairHalfPruningFactor;
                    break;
                case 2:
                    threshold *= pruningFactor;
                    break;
                default:
                    throw new ArithmeticException(" RotamerOptimization.prunePairClashes() has somehow " + "found less than zero or more than two nucleic acid residues in a pair of" + " residues. This result should be impossible.");
            }
            double toEliminate = threshold + minPair;
            for (int ri = 0; ri < lenri; ri++) {
                if (check(i, ri)) {
                    continue;
                }
                for (int rj = 0; rj < lenrj; rj++) {
                    if (check(j, rj) || check(i, ri, j, rj)) {
                        continue;
                    }
                    double pairEnergy = get2Body(i, ri, j, rj) + getSelf(i, ri) + getSelf(j, rj);
                    assert Double.isFinite(pairEnergy);
                    if (pairEnergy > toEliminate) {
                        logIfMaster(format(" Pruning pair %s-%d %s-%d by %s-%d %s-%d; energy %s > " + "%s + %s", resi.toFormattedString(false, true), ri, resj.toFormattedString(false, true), rj, resi.toFormattedString(false, true), minRI, resj.toFormattedString(false, true), minRJ, formatEnergy(pairEnergy), formatEnergy(threshold), formatEnergy(minPair)));
                    }
                }
            }
            pairsToSingleElimination(residues, i, j);
        }
    }
}
Also used : Residue(ffx.potential.bonded.Residue) MultiResidue(ffx.potential.bonded.MultiResidue) RotamerLibrary.applyRotamer(ffx.potential.bonded.RotamerLibrary.applyRotamer) Rotamer(ffx.potential.bonded.Rotamer) MultiResidue(ffx.potential.bonded.MultiResidue)

Example 2 with MultiResidue

use of ffx.potential.bonded.MultiResidue 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 3 with MultiResidue

use of ffx.potential.bonded.MultiResidue 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 4 with MultiResidue

use of ffx.potential.bonded.MultiResidue 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 5 with MultiResidue

use of ffx.potential.bonded.MultiResidue 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)

Aggregations

MultiResidue (ffx.potential.bonded.MultiResidue)19 Residue (ffx.potential.bonded.Residue)18 Atom (ffx.potential.bonded.Atom)10 Rotamer (ffx.potential.bonded.Rotamer)6 TitrationUtils.inactivateResidue (ffx.potential.extended.TitrationUtils.inactivateResidue)6 ArrayList (java.util.ArrayList)6 ResidueState (ffx.potential.bonded.ResidueState)5 AminoAcid3 (ffx.potential.bonded.ResidueEnumerations.AminoAcid3)4 NACorrectionException (ffx.potential.bonded.NACorrectionException)3 Polymer (ffx.potential.bonded.Polymer)3 RotamerLibrary.applyRotamer (ffx.potential.bonded.RotamerLibrary.applyRotamer)3 Titration (ffx.potential.extended.TitrationUtils.Titration)3 TitrationUtils.performTitration (ffx.potential.extended.TitrationUtils.performTitration)3 File (java.io.File)3 IOException (java.io.IOException)3 Crystal (ffx.crystal.Crystal)2 MultiTerminus (ffx.potential.bonded.MultiTerminus)2 TitrationType (ffx.potential.extended.TitrationUtils.TitrationType)2 PDBFilter (ffx.potential.parsers.PDBFilter)2 ParallelTeam (edu.rit.pj.ParallelTeam)1