Exemplo n.º 1
0
def vacuum_pack(structure='vacuum',
                name='vacuum-pack',
                gro='vacuum-packed',
                pbc='nojump'):
    """
	Pack the lipids in the plane, gently.
	"""

    gmx('grompp',
        base='md-%s' % name,
        top='vacuum',
        structure=structure,
        log='grompp-%s' % name,
        mdp='input-md-%s-eq-in' % name,
        flag='-maxwarn 100')
    gmx('mdrun', base='md-%s' % name, log='mdrun-%s' % name, skip=True)
    if pbc:
        remove_jump(structure='md-%s' % name,
                    tpr='md-' + name,
                    gro='md-%s-%s' % (name, pbc))
        filecopy(wordspace['step'] + 'md-%s-%s.gro' % (name, pbc),
                 wordspace['step'] + '%s.gro' % gro)
    else:
        filecopy(wordspace['step'] + 'md-%s' % gro,
                 wordspace['step'] + '%s.gro' % gro)
    boxdims_old, boxdims = get_box_vectors(gro)
    wordspace['bilayer_dimensions_slab'][:2] = boxdims_old[:2]
Exemplo n.º 2
0
def minimize_steep_cg(name):
    """
	minimize_steep_cg(name)
	Minimization using steepest descent followed by conjugate gradient.
	Note that this method has been retired due to reliability issues.
	"""

    gmx('grompp',
        base='em-%s-steep' % name,
        top=name,
        structure=name,
        log='grompp-em-%s-steep' % name,
        mdp='input-em-steep-in')
    gmx('mdrun',
        base='em-%s-steep' % name,
        log='mdrun-%s-steep' % name,
        skip=True)
    #---if first step fails we skip it and try again with the second minimizer
    if not os.path.isfile(wordspace['step'] + 'em-%s-steep.gro'):
        filecopy(wordspace['step'] + '%s.gro' % name,
                 wordspace['step'] + 'em-%s-steep.gro' % name)
    gmx('grompp',
        base='em-%s-cg' % name,
        top=name,
        structure='em-%s-steep' % name,
        log='grompp-%s-cg' % name,
        mdp='input-em-cg-in',
        skip=True)
    gmx('mdrun', base='em-%s-cg' % name, log='mdrun-%s-cg' % name)
    select_minimum('%s-steep' % name,
                   '%s-cg' % name,
                   gro='%s-minimized' % name)
    checkpoint()
Exemplo n.º 3
0
def select_minimum(*args, **kwargs):
    """
	select_minimum(*args,**kwargs)
	Select the structure with the minimum force after consecutive energy minimization steps.
	MOVED TO COMMON
	"""

    gro = 'confout' if 'gro' not in kwargs else kwargs['gro']
    forces = {}
    for arg in args:
        #---! naming rule is applied here
        with open(wordspace['step'] + 'log-mdrun-' + arg, 'r') as fp:
            lines = fp.readlines()
        finished = filter(lambda x: re.match('^Maximum (f|F)orce', x), lines)
        if finished != []:
            forces[arg] = float(
                re.findall(
                    '^[^=]+=\s*([^\s]+)',
                    filter(lambda x: re.match('^Maximum (f|F)orce', x),
                           lines).pop()).pop())
    if len(forces) == 1: arg = forces.keys()[0]
    else:
        arg = filter(lambda x: forces[x] == min(forces.values()),
                     forces.keys())[0]
    filecopy(wordspace['step'] + 'em-' + arg + '.gro',
             wordspace['step'] + gro + '.gro')
Exemplo n.º 4
0
def vacuum_pack(structure='vacuum',name='vacuum-pack',gro='vacuum-packed'):

	"""
	Pack the lipids in the plane, gently.
	"""

	gmx('grompp',base='md-%s'%name,top='vacuum',
		structure=structure,log='grompp-%s'%name,mdp='input-md-%s-eq-in'%name,
		flag='-maxwarn 100')
	gmx('mdrun',base='md-%s'%name,log='mdrun-%s'%name,skip=True)
	remove_jump(structure='md-%s'%name,tpr='md-'+name,gro='md-%s-nojump'%name)
	filecopy(wordspace['step']+'md-%s-nojump.gro'%name,wordspace['step']+'%s.gro'%gro)
	boxdims_old,boxdims = get_box_vectors(gro)
	wordspace['bilayer_dimensions_slab'][:2] = boxdims_old[:2]
Exemplo n.º 5
0
def minimize(name,method='steep',top=None):

	"""
	minimize(name,method='steep')
	Standard minimization procedure.
	"""

	gmx('grompp',base='em-%s-%s'%(name,method),top=name if not top else re.sub('^(.+)\.top$',r'\1',top),
		structure=name,log='grompp-%s-%s'%(name,method),mdp='input-em-%s-in'%method,skip=True)
	assert os.path.isfile(wordspace['step']+'em-%s-%s.tpr'%(name,method))
	gmx('mdrun',base='em-%s-%s'%(name,method),log='mdrun-%s-%s'%(name,method))
	filecopy(wordspace['step']+'em-'+'%s-%s.gro'%(name,method),
		wordspace['step']+'%s-minimized.gro'%name)
	checkpoint()
Exemplo n.º 6
0
def minimize_steep_cg(name):

	"""
	minimize_steep_cg(name)
	Minimization using steepest descent followed by conjugate gradient.
	Note that this method has been retired due to reliability issues.
	"""

	gmx('grompp',base='em-%s-steep'%name,top=name,structure=name,
		log='grompp-em-%s-steep'%name,mdp='input-em-steep-in')
	gmx('mdrun',base='em-%s-steep'%name,log='mdrun-%s-steep'%name,skip=True)
	#---if first step fails we skip it and try again with the second minimizer
	if not os.path.isfile(wordspace['step']+'em-%s-steep.gro'):
		filecopy(wordspace['step']+'%s.gro'%name,wordspace['step']+'em-%s-steep.gro'%name)
	gmx('grompp',base='em-%s-cg'%name,top=name,structure='em-%s-steep'%name,
		log='grompp-%s-cg'%name,mdp='input-em-cg-in',skip=True)
	gmx('mdrun',base='em-%s-cg'%name,log='mdrun-%s-cg'%name)
	select_minimum('%s-steep'%name,'%s-cg'%name,gro='%s-minimized'%name)
	checkpoint()
Exemplo n.º 7
0
def select_minimum(*args,**kwargs):

	"""
	select_minimum(*args,**kwargs)
	Select the structure with the minimum force after consecutive energy minimization steps.
	MOVED TO COMMON
	"""

	gro = 'confout' if 'gro' not in kwargs else kwargs['gro']
	forces = {}
	for arg in args:
		#---! naming rule is applied here
		with open(wordspace['step']+'log-mdrun-'+arg,'r') as fp: lines = fp.readlines()
		finished = filter(lambda x: re.match('^Maximum (f|F)orce',x),lines)
		if finished != []:
			forces[arg] = float(re.findall('^[^=]+=\s*([^\s]+)',
				filter(lambda x: re.match('^Maximum (f|F)orce',x),lines).pop()).pop())
	if len(forces)==1: arg = forces.keys()[0]
	else: arg = filter(lambda x: forces[x]==min(forces.values()),forces.keys())[0]
	filecopy(wordspace['step']+'em-'+arg+'.gro',wordspace['step']+gro+'.gro')
Exemplo n.º 8
0
def minimize(name, method='steep', top=None):
    """
	minimize(name,method='steep')
	Standard minimization procedure.
	"""

    gmx('grompp',
        base='em-%s-%s' % (name, method),
        top=name if not top else re.sub('^(.+)\.top$', r'\1', top),
        structure=name,
        log='grompp-%s-%s' % (name, method),
        mdp='input-em-%s-in' % method,
        skip=True)
    assert os.path.isfile(wordspace['step'] + 'em-%s-%s.tpr' % (name, method))
    gmx('mdrun',
        base='em-%s-%s' % (name, method),
        log='mdrun-%s-%s' % (name, method))
    filecopy(wordspace['step'] + 'em-' + '%s-%s.gro' % (name, method),
             wordspace['step'] + '%s-minimized.gro' % name)
    checkpoint()
Exemplo n.º 9
0
def add_proteins():

	"""
	Protein addition procedure for CGMD bilayers.
	"""

	#---assume that cgmd-protein step named the itp as follows
	#---! assumes only a single protein ITP for now (needs further development)
	protein_itp_path, = glob.glob(wordspace['last']+'/Protein*.itp')
	protein_itp_fn = os.path.basename(protein_itp_path)
	filecopy(wordspace['last']+protein_itp_fn,wordspace['step'])
	filecopy(wordspace['last']+wordspace['protein_ready'],wordspace['step'])
	filecopy(wordspace['last']+wordspace['lipid_ready'],wordspace['step'])
	gro_combinator(wordspace['protein_ready'],wordspace['lipid_ready'],
		cwd=wordspace['step'],gro='protein-lipid')
	adhere_protein_cgmd_bilayer(bilayer='vacuum-bilayer.gro',
		protein_complex='protein-lipid.gro',combo='vacuum.gro')
	#---assume inclusion of a partner lipid here
	include(protein_itp_fn)
	include('PIP2.itp')
	component('PIP2',count=wordspace['total_proteins'],top=True)
	component(re.findall('^(.+)\.itp$',protein_itp_fn)[0],count=wordspace['total_proteins'],top=True)
	#---custom additions to the mdp_specs to allow for protein groups
	for key in ['groups','temperature']:
		wordspace['mdp_specs']['input-md-npt-bilayer-eq-in.mdp'].append({key:'protein'})
		if wordspace['mdp_specs']['input-md-in.mdp'] == None:
			wordspace['mdp_specs']['input-md-in.mdp'] = []
		wordspace['mdp_specs']['input-md-in.mdp'].append({key:'protein'})
Exemplo n.º 10
0
def add_proteins():
    """
	Protein addition procedure for CGMD bilayers.
	"""

    #---assume that cgmd-protein step named the itp as follows
    #---! assumes only a single protein ITP for now (needs further development)
    protein_itp_path, = glob.glob(wordspace['last'] + '/Protein*.itp')
    protein_itp_fn = os.path.basename(protein_itp_path)
    filecopy(wordspace['last'] + protein_itp_fn, wordspace['step'])
    filecopy(wordspace['last'] + wordspace['protein_ready'], wordspace['step'])
    filecopy(wordspace['last'] + wordspace['lipid_ready'], wordspace['step'])
    gro_combinator(wordspace['protein_ready'],
                   wordspace['lipid_ready'],
                   cwd=wordspace['step'],
                   gro='protein-lipid')
    adhere_protein_cgmd_bilayer(bilayer='vacuum-bilayer.gro',
                                protein_complex='protein-lipid.gro',
                                combo='vacuum.gro')
    #---assume inclusion of a partner lipid here
    include(protein_itp_fn)
    include('PIP2.itp')
    component('PIP2', count=wordspace['total_proteins'], top=True)
    component(re.findall('^(.+)\.itp$', protein_itp_fn)[0],
              count=wordspace['total_proteins'],
              top=True)
    #---custom additions to the mdp_specs to allow for protein groups
    for key in ['groups', 'temperature']:
        wordspace['mdp_specs']['input-md-npt-bilayer-eq-in.mdp'].append(
            {key: 'protein'})
        if wordspace['mdp_specs']['input-md-in.mdp'] == None:
            wordspace['mdp_specs']['input-md-in.mdp'] = []
        wordspace['mdp_specs']['input-md-in.mdp'].append({key: 'protein'})
Exemplo n.º 11
0
def solvate(structure,top):

	"""
	solvate(structure,top)
	Standard solvate procedure for atomistic protein in water.
	"""
	
	#---purge the wordspace of solvent and anions in case we are resuming
	for key in [wordspace['anion'],wordspace['cation'],'SOL']:
		if key in zip(*wordspace['composition'])[0]:
			del wordspace['composition'][zip(*wordspace['composition'])[0].index(key)]
	gmx('editconf',structure=structure,gro='solvate-box-alone',
		log='editconf-checksize',flag='-d 0')
	with open(wordspace['step']+'log-editconf-checksize','r') as fp: lines = fp.readlines()
	boxdims = map(lambda y:float(y),re.findall('\s*box vectors \:\s*([^\s]+)\s+([^\s]+)\s+([^\s]+)',
		filter(lambda x:re.match('\s*box vectors',x),lines).pop()).pop())
	boxvecs = tuple([i+2*wordspace['water_buffer'] for i in boxdims])
	center = tuple([i/2. for i in boxvecs])
	#---cube is not implemented yet
	gmx('editconf',structure=structure,gro='solvate-protein',
		flags='-center %f %f %f'%center+' '+'-box %f %f %f'%boxvecs,
		log='editconf-center-protein')
	gmx('genbox',structure='solvate-protein',solvent=wordspace['solvent'],
		gro='solvate-dense',#top='solvate-standard',
		log='genbox-solvate')
	#---trim waters if the protein_water_gap setting is not False
	if 'protein_water_gap' in wordspace and wordspace['protein_water_gap'] != False:
		trim_waters(structure='solvate-dense',gro='solvate',
			gap=wordspace['protein_water_gap'],boxvecs=boxvecs)
	else: filecopy(wordspace['step']+'solvate-dense.gro',wordspace['step']+'solvate.gro')
	gmx('make_ndx',structure='solvate',ndx='solvate-water-check',inpipe='q\n',
		log='make-ndx-solvate-check')
	with open(wordspace['step']+'log-make-ndx-solvate-check','r') as fp: lines = fp.readlines()
	nwaters = int(re.findall('\s*[0-9]+\s+Water\s+:\s+([0-9]+)\s+atoms',
		filter(lambda x:re.match('\s*[0-9]+\s+Water',x),lines).pop()).pop())/3
	wordspace['water_without_ions'] = nwaters
	component('SOL',count=nwaters)
	#---add the suffix so that water is referred to by its name in the settings
	include(wordspace['water'],ff=True)
	write_top('solvate.top')
Exemplo n.º 12
0
def trim_waters(structure='solvate-dense',gro='solvate',
	gap=3,boxvecs=None,method='aamd',boxcut=True):

	"""
	trim_waters(structure='solvate-dense',gro='solvate',gap=3,boxvecs=None)
	Remove waters within a certain number of Angstroms of the protein.
	#### water and all (water and (same residue as water within 10 of not water))
	note that we vided the solvate.gro as a default so this can be used with any output gro file
	"""

	use_vmd = wordspace.get('use_vmd',False)
	if (gap != 0.0 or boxcut) and use_vmd:
		if method == 'aamd': watersel = "water"
		elif method == 'cgmd': watersel = "resname %s"%wordspace.sol
		else: raise Exception("\n[ERROR] unclear method %s"%method)
		#---! gap should be conditional and excluded if zero
		vmdtrim = [
			'package require pbctools',
			'mol new %s.gro'%structure,
			'set sel [atomselect top \"(all not ('+\
			'%s and (same residue as %s and within '%(watersel,watersel)+str(gap)+\
			' of not %s)))'%watersel]
		#---box trimming is typical for e.g. atomstic protein simulations but discards anything outside
		if boxcut:
			vmdtrim += [' and '+\
			'same residue as (x>=0 and x<='+str(10*boxvecs[0])+\
			' and y>=0 and y<= '+str(10*boxvecs[1])+\
			' and z>=0 and z<= '+str(10*boxvecs[2])+')']
		vmdtrim += ['"]','$sel writepdb %s-vmd.pdb'%gro,'exit',]			
		with open(wordspace['step']+'script-vmd-trim.tcl','w') as fp:
			for line in vmdtrim: fp.write(line+'\n')
		vmdlog = open(wordspace['step']+'log-script-vmd-trim','w')
		#---previously used os.environ['VMDNOCUDA'] = "1" but this was causing segfaults on green
		p = subprocess.Popen('VMDNOCUDA=1 '+gmxpaths['vmd']+' -dispdev text -e script-vmd-trim.tcl',
			stdout=vmdlog,stderr=vmdlog,cwd=wordspace['step'],shell=True,executable='/bin/bash')
		p.communicate()
		with open(wordspace['bash_log'],'a') as fp:
			fp.write(gmxpaths['vmd']+' -dispdev text -e script-vmd-trim.tcl &> log-script-vmd-trim\n')
		gmx_run(gmxpaths['editconf']+' -f %s-vmd.pdb -o %s.gro -resnr 1'%(gro,gro),
			log='editconf-convert-vmd')
	#---scipy is more reliable than VMD
	elif gap != 0.0 or boxcut:
		import scipy
		import scipy.spatial
		import numpy as np
		#---if "sol" is not in the wordspace we assume this is atomistic and use the standard "SOL"
		watersel = wordspace.get('sol','SOL')
		incoming = read_gro(structure+'.gro')
		#---remove waters that are near not-waters
		is_water = np.array(incoming['residue_names'])==watersel
		is_not_water = np.array(incoming['residue_names'])!=watersel
		water_inds = np.where(is_water)[0]
		not_water_inds = np.where(np.array(incoming['residue_names'])!=watersel)[0]
		points = np.array(incoming['points'])
		residue_indices = np.array(incoming['residue_indices'])
		if gap>0:
			#---previous method used clumsy/slow cdist
			if False:
				#---! needs KDTree optimization
				dists = scipy.spatial.distance.cdist(points[water_inds],points[not_water_inds])
				#---list of residue indices in is_water that have at least one atom with an overlap
				excludes = np.array(incoming['residue_indices'])[is_water][
					np.where(np.any(dists<=gap/10.0,axis=1))[0]]
				#---collect waters not found in the excludes list of residues that overlap with not-water
				#---note that this command fails on redundant residues
				#---this was deprecated because it wasn't working correctly with the new KDTree method below
				surviving_water = np.all((np.all((
					np.tile(excludes,(len(residue_indices),1))!=np.tile(residue_indices,(len(excludes),1)).T),
					axis=1),is_water),axis=0)
			#---use scipy KDTree to find atom names inside the gap
			#---note that order matters: we wish to find waters too close to not_waters
			close_dists,neighbors = scipy.spatial.KDTree(points[water_inds]).query(points[not_water_inds],distance_upper_bound=gap/10.0)
			#---use the distances to find the residue indices for waters that are too close 
			excludes = np.array(incoming['residue_indices'])[is_water][np.where(close_dists<=gap/10.0)[0]]
			#---get residues that are water and in the exclude list
			#---note that the following step might be slow
			exclude_res = [ii for ii,i in enumerate(incoming['residue_indices']) if i in excludes and is_water[ii]]
			#---copy the array that marks the waters
			surviving_water = np.array(is_water)
			#---remove waters that are on the exclude list
			surviving_water[exclude_res] = False
		else: 
			excludes = np.array([])
			surviving_water = np.ones(len(residue_indices)).astype(bool)
		#---we must remove waters that lie outside the box if there is a boxcut
		insiders = np.ones(len(points)).astype(bool)
		if boxcut:
			#---remove waters that lie outside the box
			#---get points that are outside of the box
			outsiders = np.any([np.any((points[:,ii]<0,points[:,ii]>i),axis=0) 
				for ii,i in enumerate(boxvecs)],axis=0)
			#---get residue numbers for the outsiders
			outsiders_res = np.array(incoming['residue_indices'])[np.where(outsiders)[0]]
			#---note that this is consonant with the close-water exclude step above (and also may be slow)
			exclude_outsider_res = [ii for ii,i in 
				enumerate(incoming['residue_indices']) if i in outsiders_res]
			insiders[exclude_outsider_res] = False
		surviving_indices = np.any((is_not_water,np.all((surviving_water,insiders),axis=0)),axis=0)
		lines = incoming['lines']
		lines = lines[:2]+list(np.array(incoming['lines'][2:-1])[surviving_indices])+lines[-1:]
		xyzs = list(points[surviving_indices])
		write_gro(lines=lines,xyzs=xyzs,output_file=wordspace.step+'%s.gro'%gro)
	else: filecopy(wordspace['step']+'%s-dense.gro'%gro,wordspace['step']+'%s.gro'%gro)
Exemplo n.º 13
0
def solvate(structure, top):
    """
	solvate(structure,top)
	Standard solvate procedure for atomistic protein in water.
	"""

    #---purge the wordspace of solvent and anions in case we are resuming
    for key in [wordspace['anion'], wordspace['cation'], 'SOL']:
        if key in zip(*wordspace['composition'])[0]:
            del wordspace['composition'][zip(
                *wordspace['composition'])[0].index(key)]
    gmx('editconf',
        structure=structure,
        gro='solvate-box-alone',
        log='editconf-checksize',
        flag='-d 0')
    with open(wordspace['step'] + 'log-editconf-checksize', 'r') as fp:
        lines = fp.readlines()
    boxdims = map(
        lambda y: float(y),
        re.findall(
            '\s*box vectors \:\s*([^\s]+)\s+([^\s]+)\s+([^\s]+)',
            filter(lambda x: re.match('\s*box vectors', x),
                   lines).pop()).pop())
    boxvecs = tuple([i + 2 * wordspace['water_buffer'] for i in boxdims])
    center = tuple([i / 2. for i in boxvecs])
    #---cube is not implemented yet
    gmx('editconf',
        structure=structure,
        gro='solvate-protein',
        flags='-center %f %f %f' % center + ' ' + '-box %f %f %f' % boxvecs,
        log='editconf-center-protein')
    gmx(
        'genbox',
        structure='solvate-protein',
        solvent=wordspace['solvent'],
        gro='solvate-dense',  #top='solvate-standard',
        log='genbox-solvate')
    #---trim waters if the protein_water_gap setting is not False
    if 'protein_water_gap' in wordspace and wordspace[
            'protein_water_gap'] != False:
        trim_waters(structure='solvate-dense',
                    gro='solvate',
                    gap=wordspace['protein_water_gap'],
                    boxvecs=boxvecs)
    else:
        filecopy(wordspace['step'] + 'solvate-dense.gro',
                 wordspace['step'] + 'solvate.gro')
    gmx('make_ndx',
        structure='solvate',
        ndx='solvate-water-check',
        inpipe='q\n',
        log='make-ndx-solvate-check')
    with open(wordspace['step'] + 'log-make-ndx-solvate-check', 'r') as fp:
        lines = fp.readlines()
    nwaters = int(
        re.findall(
            '\s*[0-9]+\s+Water\s+:\s+([0-9]+)\s+atoms',
            filter(lambda x: re.match('\s*[0-9]+\s+Water', x),
                   lines).pop()).pop()) / 3
    wordspace['water_without_ions'] = nwaters
    component('SOL', count=nwaters)
    #---add the suffix so that water is referred to by its name in the settings
    include(wordspace['water'], ff=True)
    write_top('solvate.top')
Exemplo n.º 14
0
def multiply(nx=1,ny=1,nz=1,quirky_ions=True):

	"""
	Make a copy of a simulation box in multiple directions.
	"""

	factor = nx*ny*nz
	#---update the composition
	#---if the last step doesn't have the composition we step backwards and pick up requirements
	#---note that "protein_ready" is important for the bilayer_sorter 
	for prereq in ['composition','lipids','cation','anion','protein_ready']:
		if prereq not in wordspace:
			steplist = detect_last(steplist=True)[::-1]
			#---walk backwards through steps until we find the commposition
			for ii,i in enumerate(steplist):
				oldspace = resume(read_only=True,step=int(re.match('s([0-9]+)-',i).group(1)))
				if prereq in oldspace:
					wordspace[prereq] = deepcopy(oldspace[prereq])
					break
	#---if composition is available we continue
	wordspace['new_composition'] = [[name,count*factor] for name,count in wordspace['composition']]
	kwargs = {}
	if 'buffer' in wordspace: kwargs['flag'] = ' -dist %.2f %.2f %.2f'%tuple(wordspace['buffer'])
	gmx('genconf',structure='system-input',gro='system-multiply',
		nbox="%d %d %d"%(nx,ny,nz),log='genconf-multiply',**kwargs)
	#---copy ITP files
	for itp in wordspace.itp:
		filecopy(wordspace.last_step+itp,wordspace.step+itp)
	#---reorder the GRO for convenience
	with open(wordspace['step']+'system-multiply.gro') as fp: lines = fp.readlines()
	#---collect all unique resiue/atom combinations
	combos = list(set([l[5:15] for l in lines]))

	#---for each element in the composition, extract all of the residues for that element
	lines_reorder = []
	lines_reorder.extend(lines[:2])
	#---develop a list of filtering rules
	keylist = {}
	for key,count in wordspace['new_composition']:
		if key in [wordspace[i] for i in ['anion','cation']]:
			keylist[key] = 'regex',(('ION',key),slice(5,15),'\s*%s\s*%s\s*')
		elif re.match('^(p|P)rotein',key) and key+'.itp' in wordspace.itp:
			#---custom procedure for finding proteins which have variegated residue numbers
			itp = read_itp(wordspace.step+key+'.itp')
			residues_starts = []
			seq = list(zip(*itp['atoms'])[3])
			residues = [i[5:10].strip() for i in lines]
			for i in range(len(residues)-len(seq)):
				#---minor speed up by checking the first one
				if seq[0]==residues[i] and residues[i:i+len(seq)]==seq: 
					residues_starts.append(i)
			keylist[key] = 'slices',[slice(i,i+len(seq)) for i in residues_starts]
		else: keylist[key] = 'regex',(key,slice(5,10),'\s*%s\s*')
	for key,count in wordspace['new_composition']:
		method,details = keylist[key]
		if method == 'regex':
			key,sl,regex = details
			lines_reorder.extend([l for l in lines[2:-1] if re.match(regex%key,l[sl])])	
		elif method == 'slices':
			for sl in details: lines_reorder.extend(lines[sl])	
		else: raise
	lines_reorder.extend([lines[-1]])
	with open(wordspace['step']+'system-multiply-reorder.gro','w') as fp: 
		for line in lines_reorder: fp.write(line)

	filecopy(wordspace['step']+'system-multiply-reorder.gro',wordspace['step']+'system.gro')
	wordspace['composition'] = tuple(wordspace['new_composition'])
	del wordspace['new_composition']
Exemplo n.º 15
0
def trim_waters(structure='solvate-dense',
                gro='solvate',
                gap=3,
                boxvecs=None,
                method='aamd',
                boxcut=True):
    """
	trim_waters(structure='solvate-dense',gro='solvate',gap=3,boxvecs=None)
	Remove waters within a certain number of Angstroms of the protein.
	#### water and all (water and (same residue as water within 10 of not water))
	note that we vided the solvate.gro as a default so this can be used with any output gro file
	"""

    use_vmd = wordspace.get('use_vmd', False)
    if (gap != 0.0 or boxcut) and use_vmd:
        if method == 'aamd': watersel = "water"
        elif method == 'cgmd': watersel = "resname %s" % wordspace.sol
        else: raise Exception("\n[ERROR] unclear method %s" % method)
        #---! gap should be conditional and excluded if zero
        vmdtrim = [
         'package require pbctools',
         'mol new %s.gro'%structure,
         'set sel [atomselect top \"(all not ('+\
         '%s and (same residue as %s and within '%(watersel,watersel)+str(gap)+\
         ' of not %s)))'%watersel]
        #---box trimming is typical for e.g. atomstic protein simulations but discards anything outside
        if boxcut:
            vmdtrim += [' and '+\
            'same residue as (x>=0 and x<='+str(10*boxvecs[0])+\
            ' and y>=0 and y<= '+str(10*boxvecs[1])+\
            ' and z>=0 and z<= '+str(10*boxvecs[2])+')']
        vmdtrim += [
            '"]',
            '$sel writepdb %s-vmd.pdb' % gro,
            'exit',
        ]
        with open(wordspace['step'] + 'script-vmd-trim.tcl', 'w') as fp:
            for line in vmdtrim:
                fp.write(line + '\n')
        vmdlog = open(wordspace['step'] + 'log-script-vmd-trim', 'w')
        #---previously used os.environ['VMDNOCUDA'] = "1" but this was causing segfaults on green
        p = subprocess.Popen('VMDNOCUDA=1 ' + gmxpaths['vmd'] +
                             ' -dispdev text -e script-vmd-trim.tcl',
                             stdout=vmdlog,
                             stderr=vmdlog,
                             cwd=wordspace['step'],
                             shell=True,
                             executable='/bin/bash')
        p.communicate()
        with open(wordspace['bash_log'], 'a') as fp:
            fp.write(
                gmxpaths['vmd'] +
                ' -dispdev text -e script-vmd-trim.tcl &> log-script-vmd-trim\n'
            )
        gmx_run(gmxpaths['editconf'] + ' -f %s-vmd.pdb -o %s.gro -resnr 1' %
                (gro, gro),
                log='editconf-convert-vmd')
    #---scipy is more reliable than VMD
    elif gap != 0.0 or boxcut:
        import scipy
        import scipy.spatial
        import numpy as np
        #---if "sol" is not in the wordspace we assume this is atomistic and use the standard "SOL"
        watersel = wordspace.get('sol', 'SOL')
        incoming = read_gro(structure + '.gro')
        #---remove waters that are near not-waters
        is_water = np.array(incoming['residue_names']) == watersel
        is_not_water = np.array(incoming['residue_names']) != watersel
        water_inds = np.where(is_water)[0]
        not_water_inds = np.where(
            np.array(incoming['residue_names']) != watersel)[0]
        points = np.array(incoming['points'])
        residue_indices = np.array(incoming['residue_indices'])
        if gap > 0:
            #---previous method used clumsy/slow cdist
            if False:
                #---! needs KDTree optimization
                dists = scipy.spatial.distance.cdist(points[water_inds],
                                                     points[not_water_inds])
                #---list of residue indices in is_water that have at least one atom with an overlap
                excludes = np.array(
                    incoming['residue_indices'])[is_water][np.where(
                        np.any(dists <= gap / 10.0, axis=1))[0]]
                #---collect waters not found in the excludes list of residues that overlap with not-water
                #---note that this command fails on redundant residues
                #---this was deprecated because it wasn't working correctly with the new KDTree method below
                surviving_water = np.all((np.all(
                    (np.tile(excludes, (len(residue_indices), 1)) != np.tile(
                        residue_indices, (len(excludes), 1)).T),
                    axis=1), is_water),
                                         axis=0)
            #---use scipy KDTree to find atom names inside the gap
            #---note that order matters: we wish to find waters too close to not_waters
            close_dists, neighbors = scipy.spatial.KDTree(
                points[water_inds]).query(points[not_water_inds],
                                          distance_upper_bound=gap / 10.0)
            #---use the distances to find the residue indices for waters that are too close
            excludes = np.array(
                incoming['residue_indices'])[is_water][np.where(
                    close_dists <= gap / 10.0)[0]]
            #---get residues that are water and in the exclude list
            #---note that the following step might be slow
            exclude_res = [
                ii for ii, i in enumerate(incoming['residue_indices'])
                if i in excludes and is_water[ii]
            ]
            #---copy the array that marks the waters
            surviving_water = np.array(is_water)
            #---remove waters that are on the exclude list
            surviving_water[exclude_res] = False
        else:
            excludes = np.array([])
            surviving_water = np.ones(len(residue_indices)).astype(bool)
        #---we must remove waters that lie outside the box if there is a boxcut
        insiders = np.ones(len(points)).astype(bool)
        if boxcut:
            #---remove waters that lie outside the box
            #---get points that are outside of the box
            outsiders = np.any([
                np.any((points[:, ii] < 0, points[:, ii] > i), axis=0)
                for ii, i in enumerate(boxvecs)
            ],
                               axis=0)
            #---get residue numbers for the outsiders
            outsiders_res = np.array(
                incoming['residue_indices'])[np.where(outsiders)[0]]
            #---note that this is consonant with the close-water exclude step above (and also may be slow)
            exclude_outsider_res = [
                ii for ii, i in enumerate(incoming['residue_indices'])
                if i in outsiders_res
            ]
            insiders[exclude_outsider_res] = False
        surviving_indices = np.any(
            (is_not_water, np.all((surviving_water, insiders), axis=0)),
            axis=0)
        lines = incoming['lines']
        lines = lines[:2] + list(
            np.array(incoming['lines'][2:-1])[surviving_indices]) + lines[-1:]
        xyzs = list(points[surviving_indices])
        write_gro(lines=lines,
                  xyzs=xyzs,
                  output_file=wordspace.step + '%s.gro' % gro)
    else:
        filecopy(wordspace['step'] + '%s-dense.gro' % gro,
                 wordspace['step'] + '%s.gro' % gro)
Exemplo n.º 16
0
def multiply(nx=1, ny=1, nz=1, quirky_ions=True):
    """
	Make a copy of a simulation box in multiple directions.
	"""

    factor = nx * ny * nz
    #---update the composition
    #---if the last step doesn't have the composition we step backwards and pick up requirements
    #---note that "protein_ready" is important for the bilayer_sorter
    for prereq in [
            'composition', 'lipids', 'cation', 'anion', 'protein_ready'
    ]:
        if prereq not in wordspace:
            steplist = detect_last(steplist=True)[::-1]
            #---walk backwards through steps until we find the commposition
            for ii, i in enumerate(steplist):
                oldspace = resume(read_only=True,
                                  step=int(re.match('s([0-9]+)-', i).group(1)))
                if prereq in oldspace:
                    wordspace[prereq] = deepcopy(oldspace[prereq])
                    break
    #---if composition is available we continue
    wordspace['new_composition'] = [[name, count * factor]
                                    for name, count in wordspace['composition']
                                    ]
    kwargs = {}
    if 'buffer' in wordspace:
        kwargs['flag'] = ' -dist %.2f %.2f %.2f' % tuple(wordspace['buffer'])
    gmx('genconf',
        structure='system-input',
        gro='system-multiply',
        nbox="%d %d %d" % (nx, ny, nz),
        log='genconf-multiply',
        **kwargs)
    #---copy ITP files
    for itp in wordspace.itp:
        filecopy(wordspace.last_step + itp, wordspace.step + itp)
    #---reorder the GRO for convenience
    with open(wordspace['step'] + 'system-multiply.gro') as fp:
        lines = fp.readlines()
    #---collect all unique resiue/atom combinations
    combos = list(set([l[5:15] for l in lines]))

    #---for each element in the composition, extract all of the residues for that element
    lines_reorder = []
    lines_reorder.extend(lines[:2])
    #---develop a list of filtering rules
    keylist = {}
    for key, count in wordspace['new_composition']:
        if key in [wordspace[i] for i in ['anion', 'cation']]:
            keylist[key] = 'regex', (('ION', key), slice(5,
                                                         15), '\s*%s\s*%s\s*')
        elif re.match('^(p|P)rotein', key) and key + '.itp' in wordspace.itp:
            #---custom procedure for finding proteins which have variegated residue numbers
            itp = read_itp(wordspace.step + key + '.itp')
            residues_starts = []
            seq = list(zip(*itp['atoms'])[3])
            residues = [i[5:10].strip() for i in lines]
            for i in range(len(residues) - len(seq)):
                #---minor speed up by checking the first one
                if seq[0] == residues[i] and residues[i:i + len(seq)] == seq:
                    residues_starts.append(i)
            keylist[key] = 'slices', [
                slice(i, i + len(seq)) for i in residues_starts
            ]
        else:
            keylist[key] = 'regex', (key, slice(5, 10), '\s*%s\s*')
    for key, count in wordspace['new_composition']:
        method, details = keylist[key]
        if method == 'regex':
            key, sl, regex = details
            lines_reorder.extend(
                [l for l in lines[2:-1] if re.match(regex % key, l[sl])])
        elif method == 'slices':
            for sl in details:
                lines_reorder.extend(lines[sl])
        else:
            raise
    lines_reorder.extend([lines[-1]])
    with open(wordspace['step'] + 'system-multiply-reorder.gro', 'w') as fp:
        for line in lines_reorder:
            fp.write(line)

    filecopy(wordspace['step'] + 'system-multiply-reorder.gro',
             wordspace['step'] + 'system.gro')
    wordspace['composition'] = tuple(wordspace['new_composition'])
    del wordspace['new_composition']