// 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 }
// We want to be able to quickly look up if two atoms are bonded. // To do this, make a matrix for all atom pairs such that // M[numAtoms*i+j] & bondtypeflag != 0 func makeBondTypeTable(mol *amber.System) []uint8 { numAtoms := mol.NumAtoms() bondType := make([]uint8, numAtoms*numAtoms) bondsBlocks := []string{"BONDS_INC_HYDROGEN", "BONDS_WITHOUT_HYDROGEN"} for _, blockName := range bondsBlocks { bonds := amber.VectorAsIntArray(mol.Blocks[blockName]) // atom_i atom_j indexintostuff // These are actually coordinate array indices, not atom indices for i := 0; i < len(bonds); i += 3 { a, b := bonds[i]/3, bonds[i+1]/3 bondType[numAtoms*a+b] |= BOND bondType[numAtoms*b+a] |= BOND } } angleBlocks := []string{"ANGLES_WITHOUT_HYDROGEN", "ANGLES_INC_HYDROGEN"} for _, blockName := range angleBlocks { angles := amber.VectorAsIntArray(mol.Blocks[blockName]) // atom_i atom_j atom_k indexintostuff for i := 0; i < len(angles); i += 4 { a, b := angles[i]/3, angles[i+2]/3 bondType[numAtoms*a+b] |= ANGLE bondType[numAtoms*b+a] |= ANGLE } } dihedBlocks := []string{"DIHEDRALS_INC_HYDROGEN", "DIHEDRALS_WITHOUT_HYDROGEN"} for _, blockName := range dihedBlocks { diheds := amber.VectorAsIntArray(mol.Blocks[blockName]) // atom_i atom_j atom_k atom_l indexintostuff for i := 0; i < len(diheds); i += 5 { // Fourth coordinate index is negative if this is an improper a, b := amber.Abs(diheds[i]/3), amber.Abs(diheds[i+3]/3) bondType[numAtoms*a+b] |= DIHEDRAL bondType[numAtoms*b+a] |= DIHEDRAL } } return bondType }