def test_against_vmd(pdb, get_fn): pdb = get_fn(pdb) # this is probably not cross-platform compatible. I assume that the exact # path to this CHARMM topology that is included with VMD depends on # the install mechanism, especially for bundled mac or windows installers VMD_ROOT = os.path.join(os.path.dirname(os.path.realpath(VMD)), '..') top_paths = [os.path.join(r, f) for (r, _, fs) in os.walk(VMD_ROOT) for f in fs if 'top_all27_prot_lipid_na.inp' in f] assert len(top_paths) >= 0 top = os.path.abspath(top_paths[0]).replace(" ", "\\ ") TEMPLATE = ''' package require psfgen topology %(top)s pdbalias residue HIS HSE pdbalias atom ILE CD1 CD segment U {pdb %(pdb)s} coordpdb %(pdb)s U guesscoord writepdb out.pdb writepsf out.psf exit ''' % {'top': top, 'pdb': pdb} with enter_temp_directory(): with open('script.tcl', 'w') as f: f.write(TEMPLATE) subprocess.check_call([VMD, '-startup', 'script.tcl', '-dispdev', 'none']) out_pdb = md.load('out.pdb') out_psf = md.load_psf('out.psf') # make sure the two topologies are equal eq(out_pdb.top, out_psf)
def _test_against_vmd(pdb): # this is probably not cross-platform compatible. I assume that the exact # path to this CHARMM topology that is included with VMD depends on # the install mechanism, especially for bundled mac or windows installers VMD_ROOT = os.path.join(os.path.dirname(os.path.realpath(VMD)), '..') top_paths = [os.path.join(r, f) for (r, _, fs) in os.walk(VMD_ROOT) for f in fs if 'top_all27_prot_lipid_na.inp' in f] assert len(top_paths) >= 0 top = os.path.abspath(top_paths[0]).replace(" ", "\\ ") TEMPLATE = ''' package require psfgen topology %(top)s pdbalias residue HIS HSE pdbalias atom ILE CD1 CD segment U {pdb %(pdb)s} coordpdb %(pdb)s U guesscoord writepdb out.pdb writepsf out.psf exit ''' % {'top': top, 'pdb' : pdb} with enter_temp_directory(): with open('script.tcl', 'w') as f: f.write(TEMPLATE) os.system(' '.join([VMD, '-e', 'script.tcl', '-dispdev', 'none'])) out_pdb = md.load('out.pdb') out_psf = md.load_psf('out.psf') # make sure the two topologies are equal eq(out_pdb.top, out_psf)
def __init__(self, true_value=None, initial_value=None, n_increments=18, rj=True, sample_phase=False, continuous=False): self._param = CharmmParameterSet(get_fun('toy.str')) self._struct = CharmmPsfFile(get_fun('toy.psf')) self._pdb = app.PDBFile(get_fun('toy.pdb')) self._topology = md.load_psf(get_fun('toy.psf')) self.synthetic_energy = units.Quantity() self._positions = units.Quantity() self._platform = mm.Platform.getPlatformByName('Reference') # Replace ('CG331', 'CG321', 'CG321', 'CG331') torsion with true_value self._dih_type = ('CG331', 'CG321', 'CG321', 'CG331') original_torsion = self._param.dihedral_types[self._dih_type] if true_value is not None: if type(true_value) == DihedralTypeList: dih_tlist = true_value elif type(true_value) == DihedralType: dih_tlist = DihedralTypeList() dih_tlist.append(true_value) else: dih_tlist = self._randomize_dih_param(return_dih=True) self.true_value = copy.deepcopy(dih_tlist) self._param.dihedral_types[self._dih_type] = dih_tlist # parametrize toy self._struct.load_parameters(self._param, copy_parameters=False) self._struct.positions = self._pdb.positions # generate synthetic torsion scan self._torsion_scan(n_increments=n_increments) # initialize parameter if initial_value is not None: if type(initial_value) == DihedralTypeList: dih_tlist = initial_value if type(initial_value) == DihedralType: dih_tlist = DihedralTypeList() dih_tlist.append(initial_value) elif initial_value == 'cgenff': dih_tlist = original_torsion else: dih_tlist = self._randomize_dih_param(return_dih=True) self.initial_value = copy.deepcopy(dih_tlist) self._param.dihedral_types[self._dih_type] = dih_tlist # create torsionfit.TorsionScanSet torsions = np.zeros((len(self._positions), 4)) torsions[:] = [1, 2, 3, 4] direction = None steps = None self.scan_set = ScanSet.QMDataBase(positions=self._positions.value_in_unit(units.nanometers), topology=self._topology, structure=self._struct, torsions=torsions, steps=steps, directions=direction, qm_energies=self.synthetic_energy.value_in_unit(units.kilojoules_per_mole)) self.model = model.TorsionFitModel(param=self._param, frags=self.scan_set, platform=self._platform, param_to_opt=[self._dih_type], rj=rj, continuous_phase=continuous, sample_phase=sample_phase)
def read_scan_logfile(logfiles, structure): """ parses Guassian09 torsion-scan log file parameters ---------- logfiles: str of list of str Name of Guassian 09 torsion scan log file structure: charmm psf file returns ------- TorsionScanSet """ topology = md.load_psf(structure) structure = CharmmPsfFile(structure) positions = np.ndarray((0, topology.n_atoms, 3)) qm_energies = np.ndarray(0) torsions = np.ndarray((0, 4), dtype=int) directions = np.ndarray(0, dtype=int) steps = np.ndarray((0, 3), dtype=int) if type(logfiles) != list: logfiles = [logfiles] for file in logfiles: print("loading %s" % file) direction = np.ndarray(1) torsion = np.ndarray((1, 4), dtype=int) step = [] index = (2, 12, -1) f = file.split("/")[-1].split(".") if f[2] == "pos": direction[0] = 1 else: direction[0] = 0 fi = open(file, "r") for line in fi: if re.search(" Scan ", line): t = line.split()[2].split(",") t[0] = t[0][-1] t[-1] = t[-1][0] for i in range(len(t)): torsion[0][i] = int(t[i]) - 1 if re.search("Step", line): try: step = np.array(([int(line.rsplit()[j]) for j in index])) step = step[np.newaxis, :] steps = np.append(steps, step, axis=0) except: pass fi.close() log = Gaussian(file) data = log.parse() # convert angstroms to nanometers positions = np.append(positions, data.atomcoords * 0.1, axis=0) qm_energies = np.append( qm_energies, (convertor(data.scfenergies, "eV", "kJmol-1") - min(convertor(data.scfenergies, "eV", "kJmol-1"))), axis=0, ) for i in range(len(data.scfenergies)): torsions = np.append(torsions, torsion, axis=0) directions = np.append(directions, direction, axis=0) return TorsionScanSet(positions, topology, structure, torsions, directions, steps, qm_energies)
def parse_psi4_log(logfiles, structure): """ Parses output of psi4 torsion scan script :param logfiles: list of str logfiles of psi4 script :param structure: str Charmm psf file of structure :return: TorsionScanSet """ topology = md.load_psf(structure) structure = CharmmPsfFile(structure) positions = np.ndarray((0, topology.n_atoms, 3)) qm_energies = np.ndarray(0) torsions = np.ndarray((0, 4), dtype=int) directions = np.ndarray(0, dtype=int) angles = np.ndarray(0, dtype=float) if type(logfiles) != list: logfiles = [logfiles] for file in logfiles: qm = np.ndarray(0) fi = open(file, 'r') # check if log file is complete complete = False # complete flag for line in fi: if line.startswith('Relative'): complete = True fi.seek(0) section = None torsion = np.ndarray((1, 4), dtype=int) angle = np.ndarray(0, dtype=float) for line in fi: # Flag if structure is optimized optimized = False if line.startswith('Optimizer'): optimized = True # Store Dihedral and position of optimized structures fi.next() l = filter(None, fi.next().strip().split(' ')) dih = round(float(l[-2])) try: t = l[-6:-2] for i in range(len(t)): torsion[0][i] = int(t[i]) - 1 torsions = np.append(torsions, torsion, axis=0) except ValueError: pass angle = np.append(angle, dih) fi.next() pos = filter(None, re.split("[, \[\]]", fi.next().strip())) pos = [float(i) for i in pos] pos = np.asarray(pos).reshape((-1, 3)) # convert angstroms to nanometers positions = np.append(positions, pos[np.newaxis] * 0.1, axis=0) if not complete and optimized: # Find line that starts with energy for line in fi: if line.startswith('Energy'): energy = filter(None, line.strip().split(' '))[-1] # Convert to KJ/mol energy = float(energy) * 2625.5 qm = np.append(qm, energy) break if line.startswith('Relative'): section = 'Energy' fi.next() continue if section == 'Energy': line = filter(None, line.strip().split(' ')) if line != []: dih = round(float(line[0])) if dih in angle: # Only save energies of optimized structures qm_energies = np.append(qm_energies, float(line[-1])) if qm.size is not 0: qm = qm - min(qm) qm_energies = np.append(qm_energies, qm) fi.close() angles = np.append(angles, angle, axis=0) return QMDataBase(positions, topology, structure, torsions, directions, angles, qm_energies)
def parse_gauss(logfiles, structure): """ parses Guassian09 torsion-scan log file parameters ---------- logfiles: str of list of str Name of Guassian 09 torsion scan log file structure: charmm psf file returns ------- TorsionScanSet """ topology = md.load_psf(structure) structure = CharmmPsfFile(structure) positions = np.ndarray((0, topology.n_atoms, 3)) qm_energies = np.ndarray(0) torsions = np.ndarray((0, 4), dtype=int) directions = np.ndarray(0, dtype=int) steps = np.ndarray((0, 3), dtype=int) if type(logfiles) != list: logfiles = [logfiles] for file in (logfiles): direction = np.ndarray(1) torsion = np.ndarray((1, 4), dtype=int) step = np.ndarray((0, 3), dtype=int) index = (2, 12, -1) log = Gaussian(file) data = log.parse() # convert angstroms to nanometers positions = np.append(positions, data.atomcoords * 0.1, axis=0) # Only add qm energies for structures that converged (because cclib throws out those coords but not other info) qm_energies = np.append(qm_energies, (convertor( data.scfenergies[:len(data.atomcoords)], "eV", "kJmol-1") - min( convertor(data.scfenergies[:len(data.atomcoords)], "eV", "kJmol-1"))), axis=0) fi = open(file, 'r') for line in fi: if re.search(' Scan ', line): t = line.split()[2].split(',') t[0] = t[0][-1] t[-1] = t[-1][0] for i in range(len(t)): torsion[0][i] = (int(t[i]) - 1) if re.search('^ D ', line): d = line.split()[-1] if d[0] == '-': direction[0] = 0 elif d[0] == '1': direction[0] = 1 if re.search('Step', line): try: point = np.array(([int(line.rsplit()[j]) for j in index])) point = point[np.newaxis, :] step = np.append(step, point, axis=0) except: pass fi.close() # only add scan points from converged structures steps = np.append(steps, step[:len(data.atomcoords)], axis=0) for i in range(len(data.atomcoords)): torsions = np.append(torsions, torsion, axis=0) directions = np.append(directions, direction, axis=0) del log del data return QMDataBase(positions=positions, topology=topology, structure=structure, torsions=torsions, steps=steps, qm_energies=qm_energies, directions=directions)
def parse_psi4_out(oufiles_dir, structure, pattern="*.out"): """ Parse psi4 out files from distributed torsion scan (there are many output files, one for each structure) :param oufiles_dir: str path to directory where the psi4 output files are :param structure: str path to psf, mol2 or pbd file of structure :param pattern: str pattern for psi4 output file. Default is *.out :return: TorsionScanSet """ # Check extension of structure file if structure.endswith('psf'): topology = md.load_psf(structure) structure = CharmmPsfFile(structure) else: topology = md.load(structure).topology structure = parmed.load_file(structure) positions = np.ndarray((0, topology.n_atoms, 3)) qm_energies = np.ndarray(0) torsions = np.ndarray((0, 4), dtype=int) angles = np.ndarray(0, dtype=float) optimized = np.ndarray(0, dtype=bool) out_files = {} for path, subdir, files in os.walk(oufiles_dir): for name in files: if fnmatch(name, pattern): if name.startswith('timer'): continue name_split = name.split('_') try: torsion_angle = (name_split[1] + '_' + name_split[2] + '_' + name_split[3] + '_' + name_split[4]) except IndexError: warnings.warn( "Do you only have one torsion scan? The output files will be treated as one scan" ) torsion_angle = 'only_one_scan' try: out_files[torsion_angle] except KeyError: out_files[torsion_angle] = [] path = os.path.join(os.getcwd(), path, name) out_files[torsion_angle].append(path) # Sort files in increasing angles order for each torsion sorted_files = [] dih_angles = [] for tor in out_files: dih_angle = [] for file in out_files[tor]: dih_angle.append(int(file.split('_')[-1].split('.')[0])) sorted_files.append([ out_file for (angle, out_file) in sorted(zip(dih_angle, out_files[tor])) ]) dih_angle.sort() dih_angles.append(dih_angle) if not out_files: raise Exception( "There are no psi4 output files. Did you choose the right directory?" ) # Parse files for f in itertools.chain.from_iterable(sorted_files): torsion = np.ndarray((1, 4), dtype=int) fi = open(f, 'r') for line in fi: if line.startswith('dih_string'): t = line.strip().split('"')[1].split(' ')[:4] for i in range(len(t)): torsion[0][i] = int(t[i]) - 1 torsions = np.append(torsions, torsion, axis=0) fi.close() optimizer = True log = Psi(f) data = log.parse() try: data.optdone except AttributeError: optimizer = False warnings.warn("Warning: Optimizer failed for {}".format(f)) optimized = np.append(optimized, optimizer) positions = np.append(positions, data.atomcoords[-1][np.newaxis] * 0.1, axis=0) # Try MP2 energies. Otherwise take SCFenergies try: qm_energy = convertor(data.mpenergies[-1], "eV", "kJmol-1") except AttributeError: try: qm_energy = convertor(np.array([data.scfenergies[-1]]), "eV", "kJmol-1") except AttributeError: warnings.warn( "Warning: Check if the file terminated before completing SCF" ) qm_energy = np.array([np.nan]) qm_energies = np.append(qm_energies, qm_energy, axis=0) # Subtract lowest energy to find relative energies qm_energies = qm_energies - min(qm_energies) angles = np.asarray(list(itertools.chain.from_iterable(dih_angles))) return QMDataBase(positions=positions, topology=topology, structure=structure, torsions=torsions, angles=angles, qm_energies=qm_energies, optimized=optimized)
""" Based on trajectories from umbrella sampling, we compute the butane dihedral and save them in .csv files. """ import numpy as np import mdtraj import math from sys import exit topology = mdtraj.load_psf("./data/butane.psf") M = 30 for theta0_index in range(M): print(theta0_index) traj = mdtraj.load_dcd(f"./output/traj/traj_{theta0_index}.dcd", topology) theta = mdtraj.compute_dihedrals(traj, [[3, 6, 9, 13]]) np.savetxt(f"./output/dihedral/dihedral_{theta0_index}.csv", theta, fmt="%.5f", delimiter=",")
__author__ = "Xinqiang Ding <*****@*****.**>" __date__ = "2019/10/05 02:25:36" import numpy as np import matplotlib.pyplot as plt import mdtraj import math import simtk.unit as unit import sys #sys.path.insert(0, "/home/xqding/course/projectsOnGitHub/FastMBAR/FastMBAR/") from FastMBAR import * from sys import exit import pickle topology = mdtraj.load_psf("./output/dialanine.psf") K = 100 m = 25 M = m * m psi = np.linspace(-math.pi, math.pi, m, endpoint=False) phi = np.linspace(-math.pi, math.pi, m, endpoint=False) psis = [] phis = [] for psi_index in range(m): for phi_index in range(m): traj = mdtraj.load_dcd( f"./output/traj/traj_psi_{psi_index}_phi_{phi_index}.dcd", topology) psis.append(mdtraj.compute_dihedrals(traj, [[4, 6, 8, 14]])) phis.append(mdtraj.compute_dihedrals(traj, [[6, 8, 14, 16]]))
def read_scan_logfile(logfiles, structure): """ parses Guassian09 torsion-scan log file parameters ---------- logfiles: str of list of str Name of Guassian 09 torsion scan log file structure: charmm psf file returns ------- TorsionScanSet """ topology = md.load_psf(structure) structure = CharmmPsfFile(structure) positions = np.ndarray((0, topology.n_atoms, 3)) qm_energies = np.ndarray(0) torsions = np.ndarray((0, 4), dtype=int) directions = np.ndarray(0, dtype=int) steps = np.ndarray((0, 3), dtype=int) if type(logfiles) != list: logfiles = [logfiles] for file in (logfiles): #print("loading %s" % file) direction = np.ndarray(1) torsion = np.ndarray((1, 4), dtype=int) step = np.ndarray((0, 3), dtype=int) index = (2, 12, -1) # f = file.split('/')[-1].split('.') # if f[2] == 'pos': # direction[0] = 1 # else: # direction[0] = 0 log = Gaussian(file) data = log.parse() # convert angstroms to nanometers positions = np.append(positions, data.atomcoords*0.1, axis=0) # Only add qm energies for structures that converged (because cclib throws out those coords but not other info) qm_energies = np.append(qm_energies, (convertor(data.scfenergies[:len(data.atomcoords)], "eV", "kJmol-1") - min(convertor(data.scfenergies[:len(data.atomcoords)], "eV", "kJmol-1"))), axis=0) fi = open(file, 'r') for line in fi: if re.search(' Scan ', line): t = line.split()[2].split(',') t[0] = t[0][-1] t[-1] = t[-1][0] for i in range(len(t)): torsion[0][i] = (int(t[i]) - 1) if re.search('^ D ', line): d = line.split()[-1] if d[0] == '-': direction[0] = 0 elif d[0] == '1': direction[0] = 1 if re.search('Step', line): try: point = np.array(([int(line.rsplit()[j]) for j in index])) point = point[np.newaxis,:] step = np.append(step, point, axis=0) except: pass fi.close() # only add scan points from converged structures steps = np.append(steps, step[:len(data.atomcoords)], axis=0) for i in range(len(data.atomcoords)): torsions = np.append(torsions, torsion, axis=0) directions = np.append(directions, direction, axis=0) del log del data return TorsionScanSet(positions, topology, structure, torsions, directions, steps, qm_energies)