def do_solvate( name='solvate', # name of run part; used as dirname prev_conf='../conf.gro', # input conformation prev_ndx='../index.ndx', # input index file gro_cgpair='', # gro files? nat_cgpair=0 # nr of atoms? ): # solvate structure with cg water # create and change to run dir: prev_dir = os.getcwd() dir = name ot.GotoDir(dir) # link input conformation file: this_conf = 'conf.gro' ot.symlink(prev_conf, this_conf) # solvate structure with cg water optionlist = [ '-cp ' + this_conf, '-cs ' + env.mffstruct.replace(' ', '\ ') + '/water.gro', '-vdwd 0.19' ] result = gmx.g_genbox(optionlist, log='genbox.err') if result: return result # make a new ndx file of the solvated structure outgro = 'out.gro' tmpndx = 'tmp.ndx' optionlist = ['-f ' + outgro, '-o ' + tmpndx] stdin = ['q'] # just quit; writes out all default index groups result = gmx.g_make_ndx(optionlist, log='make_ndx.err', stdin=stdin) if result: return result ngroups = st.ngroups_in_ndx(tmpndx) os.remove(tmpndx) ndx_sol = re.sub('.ndx', '_sol.ndx', prev_ndx) ndxlist = gmx.gen_ndxUIlist(ngroups, gro_cgpair, nat_cgpair) optionlist = [ '-f ' + outgro, '-o ' + ndx_sol, ] result = gmx.g_make_ndx(optionlist, log='make_ndx.err', stdin=ndxlist) if result: return result # return to original (parent) dir os.chdir(prev_dir) # next step needs to know our dirname and output index and gro files: return result, dir, ndx_sol, outgro
def neutralize(cggro, itppair, nat_cgpair): q = 0 for i in range(len(itppair)): itp = itppair[i] nat = nat_cgpair[i] q += get_charge_from_itp(itp, nat) cggro_neutral = re.sub('.gro', '_neutral.gro', cggro) if (q == 0): # add nothing if ot.cp(cggro, cggro_neutral): print("cp failed for", cggro, cggro_neutral) exit(-1) else: ifacelist = [] ifacelist.append('-cp ' + cggro) if (q > 0): # add chloride ifacelist.append('-ci ' + env.mffstruct.replace(' ', '\ ') + '/cl-.gro') ifacelist.append('-nmol ' + str(q)) elif (q < 0): # add sodium q = abs(q) ifacelist.append('-ci ' + env.mffstruct.replace(' ', '\ ') + '/na+.gro') ifacelist.append('-nmol ' + str(q)) ifacelist.append('-try 1000') ifacelist.append('-vdwd 0.19') ifacelist.append('-o ' + cggro_neutral) gmx.g_genbox(ifacelist, log='genbox.err') del ifacelist return cggro_neutral
def select_restr(itpname, ifacelist, elbndsitp): ifline = '' for i in ifacelist: ifline += ' ' + i if ot.system(env.sel_restr, options=[itpname + ifline], log=elbndsitp): print("sel_restr failed for", itpname, ifacelist, elbndsitp) exit(-1)
def displace_struct(dcom, groups, d, grofile, ndxfile): ndx_mem = ot.put_ifile_in_memory(ndxfile) grouplist1 = st.indexlist(ndx_mem, groups[0]) grouplist2 = st.indexlist(ndx_mem, groups[1]) del ndx_mem del groups gro_mem = gio.put_grofile_in_memory(grofile) head_mem = gro_mem[0:2] tail_mem = gro_mem[-1] coordsnew_mem = gio.strip_gro(gro_mem) del gro_mem u = unit_vector(dcom) d_add = dcom[3] - float(d) add_to_gr1 = unit_vector_scalar_product(0.5 * d_add, u) add_to_gr2 = unit_vector_scalar_product(-0.5 * d_add, u) for i in grouplist1: line = coordsnew_mem[int(i) - 1] for j in range(len(add_to_gr1)): line[4 + j] = str(float(line[4 + j]) + add_to_gr1[j]) del grouplist1 del add_to_gr1 for i in grouplist2: line = coordsnew_mem[int(i) - 1] for j in range(len(add_to_gr2)): line[4 + j] = str(float(line[4 + j]) + add_to_gr2[j]) del grouplist2 del add_to_gr2 coordsnew_mem[:0] = head_mem coordsnew_mem.append(tail_mem) del head_mem del tail_mem ogrofile = re.sub('.gro', '_d' + d + '.gro', grofile) gio.write_gro(ogrofile, coordsnew_mem) return ogrofile
def finegrained2coarsegrained(fgpair): cgpair = [] for fgfile in fgpair: cgfname = re.sub('.pdb', '_cg.pdb', fgfile) if ot.system(env.fg2cg, options=[fgfile], log=cgfname): print("fg2cg failed for", fgfile) exit(-1) cgpair.append(cgfname) return cgpair
def pdb2dssp(fgpair): dssppair = [] for fgfile in fgpair: dsspname = re.sub('.pdb', '.dssp', fgfile) if ot.system(env.dssp, options=[fgfile, dsspname], log='dsspcmbi.err'): print("dssp failed for", fgfile) exit(-1) dssppair.append(dsspname) return dssppair
def find_groupnumber(group, ndxname): ndx_mem = ot.put_ifile_in_memory(ndxname) countgroup = 0 for line in ndx_mem: if ((len(line) > 0) and (re.match('\[', line[0]))): if (re.match(group, line[1])): break countgroup += 1 del ndx_mem return countgroup
def do_simulations( pdbfile, # input PDB file pair, # set of chains distances, # list of distances boRun=True, # start production run after equilibration pull='cons', # type of pull: _cons_traints or _umbrella_ nsteps=None # nsteps for production run (None=default) ): # make directory for output: pdbase = pdbfile.split('.pdb')[0] dir = pdbase if (not (os.path.exists(dir) and os.path.isdir(dir))): os.mkdir(dir) os.chdir(dir) # create symlink to input pdbfile ot.symlink('../' + pdbfile, pdbfile) # create CG (coarse-grained MARTINI) representation of protein: cggro_merged, cgndx_merged, cg_stable_itppair, \ gro_cgpair, nat_cgpair, fgpair = \ mfft.do_fg2cg(pdbfile, pair) print("After CG2FG got output files:", cggro_merged, cgndx_merged, cg_stable_itppair, gro_cgpair, nat_cgpair, fgpair) groups = [] for i in gro_cgpair: groups.append(re.sub('_cg.gro', '', i)) root_dir = os.getcwd() for distance in sorted(distances): result = ps.do_pullsim(root_dir, distance, cggro_merged, cgndx_merged, groups, cg_stable_itppair, nat_cgpair, pdbase, fgpair, gro_cgpair, boRun, pull, nsteps) if result: print("pullsim failed in", os.getcwd()) # make empty file to flag this error open("FAILED", 'w').close() os.chdir(root_dir)
def mindist_between_groups(cggrofile, cgndxfile, groups): mindistfile = 'mindist.xvg' ifacelist = ['-f ' + cggrofile, '-n ' + cgndxfile] stdin = [ str(find_groupnumber(groups[0], cgndxfile)), str(find_groupnumber(groups[1], cgndxfile)) ] gmx.g_g_mindist(ifacelist, stdin=stdin, log='mindist.err ') mindist_mem = ot.put_ifile_in_memory(mindistfile) mindist = float(mindist_mem[-1][-1]) del mindist_mem return mindist
def n_atoms(gro_in): if (type(gro_in) == str): if (not ot.checkfile(os.getcwd(), gro_in)): print('ERROR (n_atoms): checkfile() failed for args \"'+os.getcwd()+\ '\" and \"'+gro_in+'\"') sys.exit(1) gro_mem = gio.put_grofile_in_memory(gro_in) nat = int(gro_mem[1][0]) del gro_mem return nat elif (type(gro_in) == list): nat_list = [] for file in gro_in: if (not ot.checkfile(os.getcwd(), file)): print('ERROR (n_atoms): checkfile() failed for args \"'+os.getcwd()+\ '\" and \"'+file+'\"') sys.exit(1) gro_mem = gio.put_grofile_in_memory(file) nat = int(gro_mem[1][0]) del gro_mem nat_list.append(nat) return nat_list
def to_gro(pdb_in): if (type(pdb_in) == str): if (not ot.checkfile(os.getcwd(), pdb_in)): print('ERROR (to_gro): checkfile() failed for args \"'+os.getcwd()+\ '\" and \"'+pdb_in+'\"') sys.exit(1) gro_out = re.sub('.pdb', '.gro', pdb_in) ifacelist = ['-f ' + pdb_in, '-o ' + gro_out] gmx.g_editconf(ifacelist, log='editconf.err') del ifacelist return gro_out elif (type(pdb_in) == list): gro_out_list = [] for file in pdb_in: if (not ot.checkfile(os.getcwd(), file)): print('ERROR (to_gro): checkfile() failed for args \"'+os.getcwd()+\ '\" and \"'+file+'\"') sys.exit(1) gro_out = re.sub('.pdb', '.gro', file) ifacelist = ['-f ' + file, '-o ' + gro_out] gmx.g_editconf(ifacelist, log='editconf.err') del ifacelist gro_out_list.append(gro_out) return gro_out_list
def com_dist(cggro_merged, cgndx_merged): ndx_mem = ot.put_ifile_in_memory(cgndx_merged) # make backbone_grouplist bbgrouplist = [] for i in ndx_mem: for j in i: if (re.search('backbone', j)): bbgrouplist.append(j) bbatomlist = [] for group in bbgrouplist: bbatomlist.append(st.indexlist(ndx_mem, group)) del ndx_mem gro_mem = gio.put_grofile_in_memory(cggro_merged) comlist = [] for atlist in bbatomlist: comlist.append(COM(gro_mem, atlist)) return distance(comlist[0], comlist[1])
def to_itp(fastassddict): itppair = [] for fasta, ssd in fastassddict.items(): # Changed iteritems() to items() itpraw = re.sub('.fasta', '_raw.itp', fasta) itp = re.sub('.fasta', '.itp', fasta) if ot.system(env.seq2itp, options=['-s ' + fasta, '-2 ' + ssd, '-t ' + itpraw]): print("seq2itp failed for", fasta) exit(-1) fm = open(itpraw, 'r').readlines() print("Read", len(fm), "from", itpraw) molname = fasta.split('.')[0] if (len(molname) < 8): molname += '\t' fw = open(itp, 'w') for line in fm: if (re.match('Protein\t1\n', line)): line = re.sub('Protein', molname, line) fw.write(line) fw.close() itppair.append(itp) return itppair
def do_one_sim( name='em_vac', # name of run part; used as dirname run_type='em', # type of run: em, em_posre, # md_pull_eq, md_pull_prod, md_umbr_prod top_type='cg', # type of topology: cg, cg_posre prev_conf='../conf.gro', # input conformation prev_ndx=None, # input index file pdbase='system', # name for system/molecule in topology file cg_stable_itppair='', # some itp file? fgpair='', # some itp file? posrepair=[], # position restraints itp file, posredir=None, # dir where to find pr itp file groups='', # index groups for chains across interface nat_cgpair=[], # nr of atoms in each chain sdistance=None, # con/restraint distance boRun=True # start mdrun ): # create and change to run dir: prev_dir = os.getcwd() dir = name ot.GotoDir(dir) # link input conformation file: this_conf = 'conf.gro' ot.symlink(prev_conf, this_conf) # generate MD parameter file: if sdistance: # add pull groups to MDP: bbgroups = [group + '_backbone' for group in groups] else: bbgroups = [] mdpfile = mdp.generate_mdp(run_type, sdistance, bbgroups) # we rely on being two dir levels deep: e.g., 'd2.30/md_sol_pr' for file in cg_stable_itppair: ot.symlink('../../' + file, './' + file) # link to Martini base topology files: if ot.symlink(env.mffFF + '/' + env.mffitp, env.mffitp): exit(-1) if ot.symlink(env.mffFF + '/' + env.mffions, env.mffions): exit(-1) if prev_ndx: # link index file this_ndx = os.path.split(prev_ndx)[1] # returns ['/path', 'file'] ot.symlink(prev_ndx, this_ndx) else: this_ndx = None ret_posrepair = [] if posrepair: # make local links: this_posrepair = [] for file in posrepair: this = os.path.split(file)[1] # returns ['/path', 'file'] ot.symlink('../' + posredir + '/' + file, this) this_posrepair.append(this) posrepair = this_posrepair # now trim pathname from posrepair file names: elif this_ndx: # generate posre files: print("Gen POSRE", this_ndx, this_conf, groups, nat_cgpair) posrepair = st.gen_posre(this_ndx, this_conf, groups, nat_cgpair) print("Got POSRE", posrepair) ret_posrepair = posrepair topfile = top.generate_top(top_type, pdbase, cg_stable_itppair, fgpair, this_conf, posrepair) # grompp optionlist = ['-f ' + mdpfile, '-c ' + this_conf, '-p ' + topfile] if this_ndx: optionlist.append('-n ' + this_ndx) if run_type.startswith('em'): optionlist.append('-maxwarn 1') elif run_type.startswith('md'): optionlist.append('-maxwarn 3') result = gmx.g_grompp(optionlist, log='grompp.err') # return immediately if error occurred if result: return result, dir, ret_posrepair # mdrun if boRun: optionlist = ['-s topol.tpr'] result = gmx.g_mdrun(optionlist, log='md.err') else: print('Ready for production in', os.getcwd()) print('option list', optionlist) # return to original (parent) dir os.chdir(prev_dir) # next step needs to know our dirname, and posre files return result, dir, ret_posrepair
def g_analyze(*options, **keywords): return ot.system(env.g_analyze, *options, **keywords)
def g_mdrun(*options, **keywords): return ot.system(env.mdrun, *options, **keywords)
def g_grompp(*options, **keywords): return ot.system(env.grompp, *options, **keywords)
def g_genbox(*options, **keywords): return ot.system(env.genbox, *options, **keywords)
def g_genrestr(*options, **keywords): return ot.system(env.genrestr, *options, **keywords)
def g_g_mindist(*options, **keywords): return ot.system(env.g_mindist, *options, **keywords)
def g_make_ndx(*options, **keywords): return ot.system(env.make_ndx, *options, **keywords)
def g_editconf(*options, **keywords): return ot.system(env.editconf, *options, **keywords)
def g_pdb2gmx(*options, **keywords): return ot.system(env.pdb2gmx, *options, **keywords)
def g_energy(*options, **keywords): return ot.system(env.g_energy, *options, **keywords)
def g_gmxdump(*options, **keywords): return ot.system(env.g_gmxdump, *options, **keywords)
def g_tpbconv(*options, **keywords): return ot.system(env.g_tpbconv, *options, **keywords)
def do_pullsim(root_dir, distance, cggro_merged, cgndx_merged, groups, cg_stable_itppair, nat_cgpair, pdbase, fgpair, gro_cgpair, boRun=True, pull='cons', nsteps=None): os.chdir(root_dir) # check if distance is string or float: try: distance += 0.0 # is float, make string version sdistance = str(distance) except TypeError: # is not float try: sdistance = distance + '' distance = float(sdistance) except TypeError: print('Unknown type for distance:', distance, type(distance)) # make dir for this distance and cd to dir d_dir = os.getcwd() + '/d' + sdistance ot.GotoDir(d_dir) ot.symlink(root_dir + '/' + cggro_merged, './' + cggro_merged) ot.symlink(root_dir + '/' + cgndx_merged, './' + cgndx_merged) # displace structure dcom_of_cgpdb = ct.com_dist(cggro_merged, cgndx_merged) cggro_disp = ct.displace_struct(dcom_of_cgpdb, groups, sdistance, cggro_merged, cgndx_merged) # center structure in box cggro_cntr = re.sub('.gro', '_cntr.gro', cggro_disp) # distance to box edge should be more than mindist+0.5*rcut (rcut = 1.2 nm) distance_to_box_edge = 1.0 + st.mindist_between_groups( cggro_merged, cgndx_merged, groups) optionlist = [ '-f ' + cggro_disp, '-o ' + cggro_cntr, # use default rectangular/triclinic; alternate box shapes: # '-bt cubic', '-bt dodecahedron', '-c', '-princ', '-d ' + str(distance_to_box_edge) ] result = gmx.g_editconf(optionlist, log='editconf.err', stdin=['0']) if result: return result # neutralize the total structure for itp in cg_stable_itppair: ot.symlink(root_dir + '/' + itp, './' + itp) cggro_neutral = st.neutralize(cggro_cntr, cg_stable_itppair, nat_cgpair) # vacuum energy minimization result, em_vac_dir, ignore = \ do_one_sim(name='em_vac', run_type='em', top_type='cg', prev_conf='../'+cggro_neutral, pdbase=pdbase, cg_stable_itppair=cg_stable_itppair, fgpair=fgpair ) if result: return result # vacuum energy minimization using position restraints result, em_vac_pr_dir, posrepair = \ do_one_sim(name='em_vac_posre', run_type='em_posre', top_type='cg_posre', prev_conf='../'+em_vac_dir+'/confout.gro', prev_ndx ='../../'+cgndx_merged, pdbase=pdbase, cg_stable_itppair=cg_stable_itppair, fgpair=fgpair, groups=groups, nat_cgpair=nat_cgpair ) if result: return result # solvate structure with cg water result, solvate_dir, cgndx_sol, outgro = \ do_solvate(name='solvate', prev_conf = '../'+em_vac_pr_dir+'/conf.gro', prev_ndx = cgndx_merged, gro_cgpair = gro_cgpair, nat_cgpair = nat_cgpair ) if result: return result # solution energy minimization using position restraints result, em_sol_pr_dir, ignore = \ do_one_sim(name='em_sol_posre', run_type='em_posre', top_type='cg_posre', prev_conf='../'+solvate_dir+'/'+outgro, prev_ndx ='../'+solvate_dir+'/'+cgndx_sol, pdbase=pdbase, cg_stable_itppair=cg_stable_itppair, fgpair=fgpair, posrepair=posrepair, posredir=em_vac_pr_dir ) if result: return result # solution md using position restraints result, md_sol_pr_dir, ignore = \ do_one_sim(name='md_sol_posre', run_type='md_posre', top_type='cg_posre', prev_conf='../'+em_sol_pr_dir+'/confout.gro', prev_ndx ='../'+solvate_dir+'/'+cgndx_sol, pdbase=pdbase, cg_stable_itppair=cg_stable_itppair, fgpair=fgpair, posrepair=posrepair, posredir=em_vac_pr_dir ) if result: return result # solution equilibration md run result, md_sol_eq_dir, ignore = \ do_one_sim(name='md_sol_eq', run_type='md_pull_eq', top_type='cg', prev_conf='../'+md_sol_pr_dir+'/confout.gro', prev_ndx ='../'+solvate_dir+'/'+cgndx_sol, pdbase=pdbase, cg_stable_itppair=cg_stable_itppair, fgpair=fgpair, groups=groups, nat_cgpair=nat_cgpair, sdistance=sdistance ) if result: return result # solution production md run if pull == 'cons': run = 'md_pull_prod' elif pull == 'umbr': run = 'md_umbr_prod' else: print("Unknown pull option", pull) exit(-1) result, md_sol_prod_dir, ignore = \ do_one_sim(name='md_sol_prod', run_type=run, top_type='cg', prev_conf='../'+md_sol_eq_dir+'/confout.gro', prev_ndx ='../'+solvate_dir+'/'+cgndx_sol, pdbase=pdbase, cg_stable_itppair=cg_stable_itppair, fgpair=fgpair, groups=groups, nat_cgpair=nat_cgpair, sdistance=sdistance, boRun=boRun ) if result: return result os.chdir(d_dir)
def do_fg2cg(pdbfile, pair): pdbase = pdbfile.split('.pdb')[0] # file parsing and conversion ListChains = [] if (ot.checkfile(os.getcwd(), pdbfile)): splitpdb = 1 ListChains = env.a2f.run(pdbfile, splitpdb) else: print('ERROR: checkfile() failed for args \"'+os.getcwd()+\ '\" and \"'+pdbfile+'\"') sys.exit(1) # First make CG structures of AA chains: FastaLs = [] for file in os.listdir(os.getcwd()): if (re.search('fasta', file)): FastaLs.append(file) DictIsChainAA = {} for c in ListChains: IsAA = False for file in FastaLs: if (re.search('_' + c + '.[0-9].fasta', file)): IsAA = True if (IsAA): DictIsChainAA[c] = 'AASequence' else: DictIsChainAA[c] = 'NonProtein' PdbLs = [] for file in os.listdir(os.getcwd()): if (re.search('[0-9].pdb', file)): PdbLs.append(file) os.system('ls -lfh ' + file) print("Found pdb files", PdbLs) FgStructFiles = [] CgStructFiles = [] FgFastaFiles = [] FgDsspFiles = [] FgSsdFiles = [] CgItpFiles = [] for key, value in DictIsChainAA.items(): # Changed iteritems() to items() if (value == 'AASequence'): FgPdbs = [] CgPdbs = [] FgFastas = [] FgDssps = [] FgSsds = [] CgItps = [] for file in PdbLs: if (re.search('_' + key + '.[0-9].pdb', file)): FgPdbs.append(file) FgFastas.append(re.sub('.pdb', '.fasta', file)) FgStructFiles.extend(FgPdbs) FgFastaFiles.extend(FgFastas) for file in FgPdbs: CgPdbs.extend(finegrained2coarsegrained([file])) FgDssps.extend(pdbt.pdb2dssp([file])) for file in FgDssps: FgSsds.extend(dssp2ssd([file])) DictFastaSsd = {} for file in FgSsds: FastaFile = re.sub('.ssd', '.fasta', file) DictFastaSsd[FastaFile] = file CgItps.extend(to_itp(DictFastaSsd)) CgStructFiles.extend(CgPdbs) FgDsspFiles.extend(FgDssps) FgSsdFiles.extend(FgSsds) CgItpFiles.extend(CgItps) elif (value == 'NonProtein'): FgPdbs = [] CgPdbs = [] CgItps = [] for file in PdbLs: if (re.search('_' + key + '.[0-9].pdb', file)): FgPdbs.append(file) CgPdbs.append(Fg2Cg_NonProtein(file)) # print(FgStructFiles # print(CgStructFiles # print(FgFastaFiles # print(FgDsspFiles # print(FgSsdFiles # print(CgItpFiles fgpair = pdbt.merge_pdbs(pdbase, pair) fastapair = pdbt.merge_fastas(pdbase, pair) for i in fgpair: if (not ot.checkfile(os.getcwd(), i)): print('ERROR: checkfile() failed for args \"'+os.getcwd()+\ '\" and \"'+i+'\"') sys.exit(1) cgpair = finegrained2coarsegrained(fgpair) dssppair = pdbt.pdb2dssp(fgpair) for i in dssppair: if (not ot.checkfile(os.getcwd(), i)): print('ERROR: checkfile() failed for args \"'+os.getcwd()+\ '\" and \"'+i+'\"') sys.exit(1) ssdpair = dssp2ssd(dssppair) itppair = [] if (len(ssdpair) == len(fastapair)): fastassddict = {} i = 0 for fasta in fastapair: fastassddict[fasta] = ssdpair[i] i += 1 for fasta in fastassddict.keys(): # Changed iterkeys() to keys() if (not ot.checkfile(os.getcwd(), fasta)): print('ERROR: checkfile() failed for args \"'+os.getcwd()+\ '\" and \"'+fasta+'\"') sys.exit(1) for ssd in fastassddict.values(): # Changed itervalues() to values() if (not ot.checkfile(os.getcwd(), ssd)): print('ERROR: checkfile() failed for args \"'+os.getcwd()+\ '\" and \"'+ssd+'\"') sys.exit(1) itppair = to_itp(fastassddict) # check if order of fastapair == order of itppair # since dictionary order can be different from list order for i in range(len(itppair)): itpname = itppair[i] itpbase = itpname.split('.')[0] itpext = itpname.split('.')[1] fastaname = fastapair[i] fastabase = fastaname.split('.')[0] if (not re.match(fastabase, itpbase)): itppair[i] = fastabase + '.' + itpext else: print('ERROR: len(ssdpair)!=len(fastapair)') sys.exit(1) gro_cgpair = gio.to_gro(cgpair) nat_cgpair = st.n_atoms(gro_cgpair) nrs_cgpair = st.n_residues(gro_cgpair) cggro_merged = pdbase + '_cg.gro' gio.merge_gro(cggro_merged, gro_cgpair, nat_cgpair, nrs_cgpair) # make indexfile ifacelist = ['-f ' + cggro_merged, '-o ' + 'tmp.ndx'] gmx.g_make_ndx(ifacelist, stdin=['q'], log='make_ndx.err') del ifacelist ngroups = st.ngroups_in_ndx('tmp.ndx') os.remove('tmp.ndx') cgndx_merged = re.sub('.gro', '.ndx', cggro_merged) ifacelist = ['-f ' + cggro_merged, '-o ' + cgndx_merged] gmx.g_make_ndx(ifacelist, stdin=gmx.gen_ndxUIlist(ngroups, gro_cgpair, nat_cgpair), log='make_ndx.err') del ifacelist # stabilize the tertiary structure: cg_stable_itppair = stabilize_tertiary_structure(cggro_merged, cgndx_merged, itppair, 'backbone', nat_cgpair) return cggro_merged, cgndx_merged, cg_stable_itppair, \ gro_cgpair, nat_cgpair, fgpair