Esempio n. 1
0
// 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
}
Esempio n. 2
0
// 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
}
Esempio n. 3
0
// 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
}