Search in sources :

Example 1 with BooleanBuf

use of edu.rit.mp.BooleanBuf in project ffx by mjschnie.

the class RotamerOptimization method rotamerEnergies.

/**
 * Turn off non-bonded contributions from all residues except for one.
 * Compute the self-energy for each residue relative to the backbone
 * contribution.
 *
 * @param residues A list of residues that we undergo rotamer optimization.
 * @return template energy
 */
private double rotamerEnergies(Residue[] residues) {
    if (residues == null) {
        logger.warning(" Attempt to compute rotamer energies for an empty array of residues.");
        return 0.0;
    }
    int nResidues = residues.length;
    Atom[] atoms = molecularAssembly.getAtomArray();
    int nAtoms = atoms.length;
    allocateEliminationMemory(residues);
    if (decomposeOriginal) {
        assert library.getUsingOrigCoordsRotamer();
        for (int i = 0; i < nResidues; i++) {
            Residue resi = residues[i];
            Rotamer[] rotsi = resi.getRotamers(library);
            int lenri = rotsi.length;
            // Leave the 0'th original-coordinates rotamer alone.
            for (int ri = 1; ri < lenri; ri++) {
                eliminateRotamer(residues, i, ri, false);
            }
        }
    }
    /**
     * Initialize all atoms to be used.
     */
    for (int i = 0; i < nAtoms; i++) {
        atoms[i].setUse(true);
    }
    if (!usingBoxOptimization) {
        energiesToWrite = Collections.synchronizedList(new ArrayList<String>());
        receiveThread = new ReceiveThread(residues);
        receiveThread.start();
        if (master && writeEnergyRestart && printFiles) {
            energyWriterThread = new EnergyWriterThread(receiveThread);
            energyWriterThread.start();
        }
    }
    int loaded = 0;
    if (loadEnergyRestart) {
        if (usingBoxOptimization) {
            loaded = loadEnergyRestart(energyRestartFile, residues, boxLoadIndex, boxLoadCellIndices);
        } else {
            loaded = loadEnergyRestart(energyRestartFile, residues);
        }
    }
    long energyStartTime = System.nanoTime();
    SelfEnergyRegion singlesRegion = new SelfEnergyRegion(residues);
    TwoBodyEnergyRegion pairsRegion = new TwoBodyEnergyRegion(residues);
    ThreeBodyEnergyRegion triplesRegion = new ThreeBodyEnergyRegion(residues);
    FourBodyEnergyRegion quadsRegion = new FourBodyEnergyRegion(residues);
    try {
        if (loaded < 1) {
            selfEnergyMap.clear();
            // allocate selfEnergy
            int singleJobIndex = 0;
            selfEnergy = new double[nResidues][];
            for (int i = 0; i < nResidues; i++) {
                Residue resi = residues[i];
                Rotamer[] roti = resi.getRotamers(library);
                selfEnergy[i] = new double[roti.length];
                for (int ri = 0; ri < roti.length; ri++) {
                    if (!check(i, ri)) {
                        Integer[] selfJob = { i, ri };
                        if (decomposeOriginal && ri != 0) {
                            continue;
                        }
                        selfEnergyMap.put(singleJobIndex++, selfJob);
                    }
                }
            }
        }
        // broadcast that this proc is done with startup and allocation; ready for singles
        boolean thisProcReady = true;
        BooleanBuf thisProcReadyBuf = BooleanBuf.buffer(thisProcReady);
        multicastBuf(thisProcReadyBuf);
        // launch parallel singles calculation
        while (!readyForSingles) {
            Thread.sleep(POLLING_FREQUENCY);
        }
        logger.info(String.format(" Number of self energies to calculate: %d", selfEnergyMap.size()));
        energyWorkerTeam.execute(singlesRegion);
        long singlesTime = System.nanoTime() - energyStartTime;
        logIfMaster(format(" Time for single energies: %12.4g", (singlesTime * 1.0E-9)));
        if (loaded < 2) {
            twoBodyEnergyMap.clear();
            // allocate twoBodyEnergy and create jobs
            int pairJobIndex = 0;
            twoBodyEnergy = new double[nResidues][][][];
            for (int i = 0; i < nResidues; i++) {
                Residue resi = residues[i];
                Rotamer[] roti = resi.getRotamers(library);
                twoBodyEnergy[i] = new double[roti.length][][];
                for (int ri = 0; ri < roti.length; ri++) {
                    if (check(i, ri)) {
                        continue;
                    }
                    twoBodyEnergy[i][ri] = new double[nResidues][];
                    for (int j = i + 1; j < nResidues; j++) {
                        Residue resj = residues[j];
                        Rotamer[] rotj = resj.getRotamers(library);
                        twoBodyEnergy[i][ri][j] = new double[rotj.length];
                        for (int rj = 0; rj < rotj.length; rj++) {
                            if (checkToJ(i, ri, j, rj)) {
                                continue;
                            }
                            Integer[] pairJob = { i, ri, j, rj };
                            if (decomposeOriginal && (ri != 0 || rj != 0)) {
                                continue;
                            }
                            twoBodyEnergyMap.put(pairJobIndex++, pairJob);
                        }
                    }
                }
            }
        }
        // broadcast that this proc is done with pruning and allocation; ready for pairs
        multicastBuf(thisProcReadyBuf);
        // launch parallel pair calculation
        while (!readyFor2Body) {
            Thread.sleep(POLLING_FREQUENCY);
        }
        logger.info(String.format(" Number of 2-body energies to calculate: %d", twoBodyEnergyMap.size()));
        energyWorkerTeam.execute(pairsRegion);
        long pairsTime = System.nanoTime() - (singlesTime + energyStartTime);
        long triplesTime = 0;
        long quadsTime = 0;
        logIfMaster(format(" Time for 2-body energies:   %12.4g", (pairsTime * 1.0E-9)));
        if (threeBodyTerm) {
            if (loaded < 3) {
                threeBodyEnergyMap.clear();
                // allocate threeBodyEnergy and create jobs
                int trimerJobIndex = 0;
                threeBodyEnergy = new double[nResidues][][][][][];
                for (int i = 0; i < nResidues; i++) {
                    Residue resi = residues[i];
                    Rotamer[] roti = resi.getRotamers(library);
                    threeBodyEnergy[i] = new double[roti.length][][][][];
                    for (int ri = 0; ri < roti.length; ri++) {
                        if (check(i, ri)) {
                            continue;
                        }
                        threeBodyEnergy[i][ri] = new double[nResidues][][][];
                        for (int j = i + 1; j < nResidues; j++) {
                            Residue resj = residues[j];
                            Rotamer[] rotj = resj.getRotamers(library);
                            threeBodyEnergy[i][ri][j] = new double[rotj.length][][];
                            for (int rj = 0; rj < rotj.length; rj++) {
                                if (checkToJ(i, ri, j, rj)) {
                                    continue;
                                }
                                threeBodyEnergy[i][ri][j][rj] = new double[nResidues][];
                                for (int k = j + 1; k < nResidues; k++) {
                                    Residue resk = residues[k];
                                    Rotamer[] rotk = resk.getRotamers(library);
                                    threeBodyEnergy[i][ri][j][rj][k] = new double[rotk.length];
                                    for (int rk = 0; rk < rotk.length; rk++) {
                                        if (checkToK(i, ri, j, rj, k, rk)) {
                                            continue;
                                        }
                                        Integer[] trimerJob = { i, ri, j, rj, k, rk };
                                        if (decomposeOriginal && (ri != 0 || rj != 0 || rk != 0)) {
                                            continue;
                                        }
                                        threeBodyEnergyMap.put(trimerJobIndex++, trimerJob);
                                    }
                                }
                            }
                        }
                    }
                }
            }
            // broadcast that this proc is done with pruning and allocation; ready for trimers
            multicastBuf(thisProcReadyBuf);
            // launch parallel 3-Body calculation
            while (!readyFor3Body) {
                Thread.sleep(POLLING_FREQUENCY);
            }
            logger.info(String.format(" Number of 3-Body energies to calculate: %d", threeBodyEnergyMap.size()));
            energyWorkerTeam.execute(triplesRegion);
            triplesTime = System.nanoTime() - (pairsTime + singlesTime + energyStartTime);
            logIfMaster(format(" Time for 3-Body energies: %12.4g", (triplesTime * 1.0E-9)));
        }
        if (compute4BodyEnergy) {
            logger.info(" Creating 4-Body jobs...");
            fourBodyEnergyMap.clear();
            boolean maxedOut = false;
            // create 4-Body jobs (no memory allocation)
            int quadJobIndex = 0;
            for (int i = 0; i < nResidues; i++) {
                Residue resi = residues[i];
                Rotamer[] roti = resi.getRotamers(library);
                for (int ri = 0; ri < roti.length; ri++) {
                    if (check(i, ri)) {
                        continue;
                    }
                    for (int j = i + 1; j < nResidues; j++) {
                        Residue resj = residues[j];
                        Rotamer[] rotj = resj.getRotamers(library);
                        for (int rj = 0; rj < rotj.length; rj++) {
                            /*if (check(j, rj) || check(i, ri, j, rj)) {
                                        continue;
                                    }*/
                            if (checkToJ(i, ri, j, rj)) {
                                continue;
                            }
                            for (int k = j + 1; k < nResidues; k++) {
                                Residue resk = residues[k];
                                Rotamer[] rotk = resk.getRotamers(library);
                                for (int rk = 0; rk < rotk.length; rk++) {
                                    /*if (check(k, rk) || check(i, ri, k, rk) || check(j, rj, k, rk) || check(i, ri, j, rj, k, rk)) {
                                                continue;
                                            }*/
                                    if (checkToK(i, ri, j, rj, k, rk)) {
                                        continue;
                                    }
                                    for (int l = k + 1; l < nResidues; l++) {
                                        Residue resl = residues[l];
                                        Rotamer[] rotl = resl.getRotamers(library);
                                        for (int rl = 0; rl < rotl.length; rl++) {
                                            /*if (check(l, rl) || check(i, ri, l, rl) ||
                                                            check(j, rj, l, rl) || check(k, rk, l, rl) ||
                                                            check(i, ri, j, rj, l, rl) || check(i, ri, k, rk, l, rl) ||
                                                            check(j, rj, k, rk, l, rl)) {
                                                        continue;
                                                    }*/
                                            if (checkToL(i, ri, j, rj, k, rk, l, rl)) {
                                                continue;
                                            }
                                            Integer[] quadJob = { i, ri, j, rj, k, rk, l, rl };
                                            if (decomposeOriginal && (ri != 0 || rj != 0 || rk != 0 || rl != 0)) {
                                                continue;
                                            }
                                            fourBodyEnergyMap.put(quadJobIndex++, quadJob);
                                            if (fourBodyEnergyMap.size() > max4BodyCount) {
                                                maxedOut = true;
                                                break;
                                            }
                                        }
                                        if (maxedOut) {
                                            break;
                                        }
                                    }
                                    if (maxedOut) {
                                        break;
                                    }
                                }
                                if (maxedOut) {
                                    break;
                                }
                            }
                            if (maxedOut) {
                                break;
                            }
                        }
                        if (maxedOut) {
                            break;
                        }
                    }
                    if (maxedOut) {
                        break;
                    }
                }
                if (maxedOut) {
                    break;
                }
            }
            // broadcast that this proc is done with pruning and allocation; ready for quads
            // logger.info(format(" Proc %d broadcasting ready for quads.", world.rank()));
            multicastBuf(thisProcReadyBuf);
            // launch parallel 3-Body calculation
            int waiting = 0;
            while (!readyFor4Body) {
                Thread.sleep(POLLING_FREQUENCY);
            }
            logger.info(format(" Running quads: %d jobs.", fourBodyEnergyMap.size()));
            energyWorkerTeam.execute(quadsRegion);
            quadsTime = System.nanoTime() - (triplesTime + pairsTime + singlesTime + energyStartTime);
            logIfMaster(format(" Time for 4-Body energies:   %12.4g", quadsTime * 1.0E-9));
        }
        long allTime = singlesTime + pairsTime + triplesTime + quadsTime;
        logIfMaster(format(" Time for all energies:    %12.4g", allTime * 1.0E-9));
    } catch (Exception ex) {
        String message = " Exception computing rotamer energies in parallel.";
        logger.log(Level.SEVERE, message, ex);
    }
    // Turn on all atoms.
    for (int i = 0; i < atoms.length; i++) {
        atoms[i].setUse(true);
    }
    // Print the energy with all rotamers in their default conformation.
    if (verboseEnergies && master) {
        try {
            double defaultEnergy = currentEnergy(residues);
            logger.info(format(" Energy of the system with rotamers in their default conformation: %s", formatEnergy(defaultEnergy)));
        } catch (ArithmeticException ex) {
            logger.severe(String.format(" Exception %s in calculating default energy; FFX shutting down", ex.toString()));
        }
    }
    return backboneEnergy;
}
Also used : ArrayList(java.util.ArrayList) RotamerLibrary.applyRotamer(ffx.potential.bonded.RotamerLibrary.applyRotamer) Rotamer(ffx.potential.bonded.Rotamer) BooleanBuf(edu.rit.mp.BooleanBuf) Atom(ffx.potential.bonded.Atom) IOException(java.io.IOException) NACorrectionException(ffx.potential.bonded.NACorrectionException) Residue(ffx.potential.bonded.Residue) MultiResidue(ffx.potential.bonded.MultiResidue)

Aggregations

BooleanBuf (edu.rit.mp.BooleanBuf)1 Atom (ffx.potential.bonded.Atom)1 MultiResidue (ffx.potential.bonded.MultiResidue)1 NACorrectionException (ffx.potential.bonded.NACorrectionException)1 Residue (ffx.potential.bonded.Residue)1 Rotamer (ffx.potential.bonded.Rotamer)1 RotamerLibrary.applyRotamer (ffx.potential.bonded.RotamerLibrary.applyRotamer)1 IOException (java.io.IOException)1 ArrayList (java.util.ArrayList)1