Exemple #1
0
func main() {
	var prmtopFilename, rstFilename, outFilename string
	var stride int
	var savePreprocessed bool

	flag.StringVar(&prmtopFilename, "p", "prmtop", "Prmtop filename (required)")
	flag.StringVar(&rstFilename, "c", "", "Inpcrd/rst filename")
	flag.IntVar(&stride, "s", 1, "Frame stride; 1 = don't skip any")
	flag.StringVar(&outFilename, "o", "energies.bin", "Energy decomposition output filename")
	flag.BoolVar(&savePreprocessed, "e", false, "Save prmtop preprocessed output (use with -c)")
	flag.Parse()
	trjFilenames := flag.Args()

	mol := amber.LoadSystem(prmtopFilename)
	if mol == nil {
		return
	}
	fmt.Println("Number of atoms:", mol.NumAtoms())
	fmt.Println("Number of residues:", mol.NumResidues())
	hasBox := false
	fmt.Print("Periodic box in prmtop: ")
	if mol.GetInt("POINTERS", amber.IFBOX) > 0 {
		hasBox = true
		fmt.Println("Yes")
	} else {
		fmt.Println("No")
	}

	// Set up nonbonded parameters. We load them here so we don't have to keep
	// doing it later
	var params NonbondedParamsCache
	params.Ntypes = mol.GetInt("POINTERS", amber.NTYPES)
	params.NBIndices = amber.VectorAsIntArray(mol.Blocks["NONBONDED_PARM_INDEX"])  // ICO
	params.AtomTypeIndices = amber.VectorAsIntArray(mol.Blocks["ATOM_TYPE_INDEX"]) // IAC
	params.LJ12 = amber.VectorAsFloat32Array(mol.Blocks["LENNARD_JONES_ACOEF"])    // CN1
	params.LJ6 = amber.VectorAsFloat32Array(mol.Blocks["LENNARD_JONES_BCOEF"])     // CN2
	params.Charges = amber.VectorAsFloat32Array(mol.Blocks["CHARGE"])
	// If we were given a single snapshot, just do that one
	if rstFilename != "" || savePreprocessed {
		var request EnergyCalcRequest
		if rstFilename != "" {
			fmt.Printf("Calculating energies for single snapshot %s.\n", rstFilename)
			mol.LoadRst(rstFilename)
			request.Coords = mol.Coords[0]
		}

		request.NBParams = params
		request.Molecule = mol
		// Lookup table for bond types so we don't calculate electrostatics
		// and such between bonded atoms
		request.BondType = makeBondTypeTable(mol)
		request.ResidueMap = makeResidueMap(mol)
		request.Decomp = make([]float64, mol.NumResidues()*mol.NumResidues())

		// Dump the preprocessed info to a file so a C version of this program can easily load and parse it
		if savePreprocessed {
			outFile, _ := os.OpenFile("solute.top.tom", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644)
			defer outFile.Close()

			WriteInt32(outFile, mol.NumAtoms())
			WriteInt32(outFile, mol.NumResidues())
			WriteInt32(outFile, params.Ntypes)
			WriteInt32Array(outFile, params.NBIndices)
			WriteInt32Array(outFile, params.AtomTypeIndices)
			WriteFloat32Array(outFile, params.LJ12)
			WriteFloat32Array(outFile, params.LJ6)
			WriteFloat32Array(outFile, params.Charges)
			WriteInt8Array(outFile, request.BondType)
			WriteInt32Array(outFile, request.ResidueMap)
			if hasBox {
				WriteInt32(outFile, 1)
			} else {
				WriteInt32(outFile, 0)
			}

			fmt.Println("Wrote preprocessed prmtop data. Done!")
			os.Exit(0)
		}

		fmt.Println("Electrostatic energy:", Electro(&request), "kcal/mol")
		fmt.Println("van der Waals energy:", LennardJones(&request), "kcal/mol")
		fmt.Println(amber.Status())

		amber.DumpFloat64MatrixAsText(request.Decomp, mol.NumResidues(), "decomp.txt")
		fmt.Println("Saved decomposition matrix to decomp.txt")
	} else if len(trjFilenames) > 0 {
		fmt.Println("Frame stride:", stride)

		// Lookup table for bond types so we don't calculate nonbonded energies
		// between bonded atoms
		bondType := makeBondTypeTable(mol)
		residueMap := makeResidueMap(mol)

		ch := make(chan int)
		decompCh := make(chan []float64, 32)
		// This goroutine will be fed the decomposition matrices made by the energy functions
		fmt.Println("Writing residue decomposition matrices to", outFilename)
		go decompProcessor(outFilename, mol.NumResidues(), decompCh, ch)
		numAtoms := mol.NumAtoms()

		fileId := 0
		trj, err := openTrj(trjFilenames[fileId])
		if err != nil {
			return
		}

		numKids := 0
		frame := 0
		strideCountdown := stride

		for {
			// If there was an error reading the next frame, move on to the next trajectory file
			coords, err := amber.GetNextFrameFromTrajectory(trj, numAtoms, hasBox)
			if err != nil {
				fileId++
				if fileId >= len(trjFilenames) {
					break
				}
				trj, err = openTrj(trjFilenames[fileId])
				if err != nil {
					fmt.Println("Error opening", trjFilenames[fileId])
					break
				}
				coords, err = amber.GetNextFrameFromTrajectory(trj, numAtoms, hasBox)
				if err != nil {
					fmt.Printf("Trajectory file %s doesn't have even one valid frame\n", trjFilenames[fileId])
					break
				}
			}
			frame++
			// Only actually process the frames indicated by stride
			strideCountdown--
			if strideCountdown == 0 {
				strideCountdown = stride
				go calcSingleTrjFrame(mol, params, coords, frame, bondType, residueMap, decompCh, ch)
				numKids++
			}
		}

		if false {
			for i := 0; i < numKids; i++ {
				<-ch
			}
		}
		decompCh <- nil
		<-ch // Wait for decompProcessor to finish
	}
}
Exemple #2
0
func main() {
	var prmtopFilename, rstFilename, outFilename string
	var stride int
	var savePreprocessed bool

	flag.StringVar(&prmtopFilename, "p", "prmtop", "Prmtop filename (required)")
	flag.StringVar(&rstFilename, "c", "", "Inpcrd/rst filename")
	flag.IntVar(&stride, "s", 1, "Frame stride; 1 = don't skip any")
	flag.StringVar(&outFilename, "o", "energies.bin", "Energy decomposition output filename")
	flag.BoolVar(&savePreprocessed, "e", false, "Save prmtop preprocessed output (use with -c)")
	flag.Parse()

	mol := amber.LoadSystem(prmtopFilename)
	if mol == nil {
		return
	}
	fmt.Println("Number of atoms:", mol.NumAtoms())
	fmt.Println("Number of residues:", mol.NumResidues())
	hasBox := false
	fmt.Print("Periodic box in prmtop: ")
	if mol.GetInt("POINTERS", amber.IFBOX) > 0 {
		hasBox = true
		fmt.Println("Yes")
	} else {
		fmt.Println("No")
	}

	// Set up nonbonded parameters. We load them here so we don't have to keep
	// doing it later
	var params NonbondedParamsCache
	params.Ntypes = mol.GetInt("POINTERS", amber.NTYPES)
	params.NBIndices = amber.VectorAsIntArray(mol.Blocks["NONBONDED_PARM_INDEX"])  // ICO
	params.AtomTypeIndices = amber.VectorAsIntArray(mol.Blocks["ATOM_TYPE_INDEX"]) // IAC
	params.LJ12 = amber.VectorAsFloat32Array(mol.Blocks["LENNARD_JONES_ACOEF"])    // CN1
	params.LJ6 = amber.VectorAsFloat32Array(mol.Blocks["LENNARD_JONES_BCOEF"])     // CN2
	params.Charges = amber.VectorAsFloat32Array(mol.Blocks["CHARGE"])

	var request EnergyCalcRequest
	request.NBParams = params
	request.Molecule = mol
	// Lookup table for bond types so we don't calculate electrostatics
	// and such between bonded atoms
	request.BondType = makeBondTypeTable(mol)
	request.ResidueMap = makeResidueMap(mol)
	request.Decomp = make([]float64, mol.NumResidues()*mol.NumResidues())

	// Dump the preprocessed info to a file so a C version of this program can easily load and parse it
	outFile, _ := os.OpenFile("solute.top.tom", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644)
	defer outFile.Close()

	WriteInt32(outFile, mol.NumAtoms())
	WriteInt32(outFile, mol.NumResidues())
	WriteInt32(outFile, params.Ntypes)
	WriteInt32Array(outFile, params.NBIndices)
	WriteInt32Array(outFile, params.AtomTypeIndices)
	WriteFloat32Array(outFile, params.LJ12)
	WriteFloat32Array(outFile, params.LJ6)
	WriteFloat32Array(outFile, params.Charges)
	WriteInt8Array(outFile, request.BondType)
	WriteInt32Array(outFile, request.ResidueMap)

	if hasBox {
		WriteInt32(outFile, 1)
	} else {
		WriteInt32(outFile, 0)
	}
	fmt.Println("Wrote preprocessed prmtop data. Done!")
	os.Exit(0)
}