// Converts the RESIDUE_POINTER block into an array, index by atom, that // provides the residue number (starting at 0) for each atom. func makeResidueMap(mol *amber.System) []int { residueList := amber.VectorAsIntArray(mol.Blocks["RESIDUE_POINTER"]) residueMap := make([]int, mol.NumAtoms()) // len(residueList) == #resideus for res_i := 1; res_i < len(residueList); res_i++ { a := residueList[res_i-1] - 1 // Fortran starts counting at 1 b := residueList[res_i] - 1 for i := a; i < b; i++ { residueMap[i] = res_i - 1 } } // RESIDUE_POINTER doesn't specify the last residue because that's implied numResidues := mol.NumResidues() for i := residueList[numResidues-1] - 1; i < len(residueMap); i++ { residueMap[i] = numResidues - 1 } return residueMap }
// Calculates the nonbonded energies for a single snapshot. // Results are returned through reqOutCh. func calcSingleTrjFrame(mol *amber.System, params NonbondedParamsCache, coords []float32, frame int, bondType []uint8, residueMap []int, reqOutCh chan []float64, ch chan int) { var request EnergyCalcRequest request.Molecule = mol request.Frame = frame request.NBParams = params request.Coords = coords request.BondType = bondType request.ResidueMap = residueMap var ok bool request.Decomp = <-decompFreeList if !ok { fmt.Println("Allocating a new decomposition matrix buffer.") request.Decomp = make([]float64, mol.NumResidues()*mol.NumResidues()) } // Since we're reusing buffers, we need to zero them out for i := 0; i < len(request.Decomp); i++ { request.Decomp[i] = 0.0 } /* //DEBUG: print first few coordinates fmt.Printf("%d [%d]:", frame, len(coords)); for i := 0; i < 6; i++ { fmt.Printf(" %f", coords[i]); } fmt.Println(); */ elec := Electro(&request) vdw := LennardJones(&request) if math.IsNaN(elec) || math.IsNaN(vdw) { fmt.Println("Weird energies. Does your trajectory have boxes but your prmtop doesn't, or vice versa?") os.Exit(1) } fmt.Printf("%d: Electrostatic: %f vdW: %f Total: %f\n", frame, elec, vdw, elec+vdw) // Release coords buffer so it can be reused amber.ReleaseCoordsBuffer(coords) // Send request to listening something that will probably average the decomp matrix // but could in theory do whatever it wants. reqOutCh <- request.Decomp // Return frame ID through channel //ch <- frame }