class SanderInput(object): """ Base class sander input file """ program = 'sander' # This runs with sander input_items = {'foo': 'bar'} # replace this in derived classes name_map = {'foo': 'orig'} # replace this in derived classes parent_namelist = { 'foo': 'foo_namelist' } # replace this in derived classes def __init__(self, INPUT): self.mdin = Mdin(self.program) self.mdin.title = 'File generated by gmx_MMPBSA' for key in list(self.input_items.keys()): # Skip ioutfm since it is handled explicitly later if key == 'ioutfm': continue try: self.mdin.change(self.parent_namelist[key], key, INPUT[self.name_map[key]]) except KeyError: self.mdin.change(self.parent_namelist[key], key, self.input_items[key]) self.mdin.change('cntrl', 'ioutfm', int(bool(INPUT['netcdf']))) def write_input(self, filename): """ Write the mdin file """ self.mdin.write(filename)
def __init__(self, INPUT): self.mdin = Mdin(self.program) self.mdin.title = 'File generated by gmx_MMPBSA' for key in list(self.input_items.keys()): # Skip ioutfm since it is handled explicitly later if key == 'ioutfm': continue try: self.mdin.change(self.parent_namelist[key], key, INPUT[self.name_map[key]]) except KeyError: self.mdin.change(self.parent_namelist[key], key, self.input_items[key]) self.mdin.change('cntrl', 'ioutfm', int(bool(INPUT['netcdf'])))
def Calculate_AMBER(Structure, mdp_opts): pbc = mdp_opts["pbc"].lower() == "xyz" # Create AMBER inpcrd file inpcrd = amber.AmberAsciiRestart("inpcrd", mode="w") inpcrd.coordinates = np.array(Structure.positions.value_in_unit( u.angstrom)).reshape(-1, 3) inpcrd.box = Structure.box inpcrd.close() # sander insists on providing a trajectory to iterate over, # so we feed it the same coordinates again. But we don't use it # because the positions are imprecise. mdcrd = amber.AmberMdcrd("mdcrd", natom=len(Structure.atoms), hasbox=pbc, mode="w") mdcrd.add_coordinates( np.array(Structure.positions.value_in_unit(u.angstrom)).reshape(-1, 3)) if pbc: mdcrd.add_box(Structure.box[:3]) mdcrd.close() # Create AMBER prmtop object from ParmEd Structure :) prmtop = amber.AmberParm.from_structure(Structure) prmtop.write_parm("prmtop") # Create AMBER mdin file and append some stuff mdin = Mdin() # Single point energies? mdin.change('cntrl', 'imin', '5') # Periodic boundary conditions? if pbc: mdin.change('cntrl', 'ntb', '1') else: mdin.change('cntrl', 'ntb', '0') # Cutoff zero is really infinite if float(mdp_opts['rlist']) == 0.0: mdin.change('cntrl', 'cut', '9999') else: mdin.change('cntrl', 'cut', str(int(float(mdp_opts['rlist']) * 10))) # Take zero MD steps mdin.change('cntrl', 'nstlim', '0') # Don't update nonbond parameters mdin.change('cntrl', 'nsnb', '0') # if mdp_opts['coulombtype'].lower() == 'pme': # mdin.change('ewald','order',5) # mdin.change('ewald','skinnb',0) mdin.write("mdin") # Nonbonded method if mdp_opts['coulombtype'].lower() == 'pme': with open("mdin", 'a') as f: print >> f, """&ewald order=5, skinnb=0 /""" with open("mdin", 'a') as f: print >> f, """&debugf do_debugf=1, dumpfrc=1 /""" # Call sander for energy and force os.system('rm -f forcedump.dat') _exec("sander -O -y mdcrd", print_command=False) # Parse energy and force ParseMode = 0 Energies = [] Forces = [] Force = [] iatom = 0 isAtom = [atom.atomic_number > 0 for atom in Structure.atoms] for line in open('forcedump.dat'): line = line.strip() sline = line.split() if ParseMode == 1: if len(sline) == 1 and isfloat(sline[0]): Energies.append(float(sline[0]) * 4.184) ParseMode = 0 if ParseMode == 2: if len(sline) == 3 and all(isfloat(sline[i]) for i in range(3)): if isAtom[iatom]: Force += [float(sline[i]) * 4.184 * 10 for i in range(3)] iatom += 1 if len(Force) == 3 * sum(isAtom): Forces.append(np.array(Force)) Force = [] ParseMode = 0 iatom = 0 if line == '0 START of Energies': ParseMode = 1 elif line == '1 Total Force' or line == '2 Total Force': ParseMode = 2 # Obtain energy components ParseMode = 0 Ecomps = OrderedDict() for line in open("mdout").readlines(): if "NSTEP = " in line: ParseMode = 1 if ParseMode == 1: if "=" not in line: ParseMode = 0 continue else: ieq = None wkey = [] # Assume the line is split-able for i, w in enumerate(line.split()): if w == '=': ieq = i elif i - 1 == ieq: Ecomps.setdefault(' '.join(wkey), []).append(float(w) * 4.184) wkey = [] else: wkey.append(w) Ecomps_Sav = OrderedDict() for key in Ecomps: if set(Ecomps[key]) == set([0.0]): continue elif key.lower() in ['eptot', 'etot', 'volume', 'density']: continue else: Ecomps_Sav[key] = Ecomps[key][0] Ecomps_Sav['EPTOT'] = Ecomps['EPtot'][0] # Save just the first frame from the .mdcrd Energies = Energies[0] Forces = Forces[0] return Energies, Forces, Ecomps_Sav
def Calculate_AMBER(Structure, mdp_opts): pbc = mdp_opts["pbc"].lower() == "xyz" # Create AMBER inpcrd file inpcrd = amber.AmberAsciiRestart("inpcrd", mode="w") inpcrd.coordinates = np.array(Structure.positions.value_in_unit(u.angstrom)).reshape(-1, 3) inpcrd.box = Structure.box inpcrd.close() # sander insists on providing a trajectory to iterate over, # so we feed it the same coordinates again. But we don't use it # because the positions are imprecise. mdcrd = amber.AmberMdcrd("mdcrd", natom=len(Structure.atoms), hasbox=pbc, mode="w") mdcrd.add_coordinates(np.array(Structure.positions.value_in_unit(u.angstrom)).reshape(-1, 3)) if pbc: mdcrd.add_box(Structure.box[:3]) mdcrd.close() # Create AMBER prmtop object from ParmEd Structure :) prmtop = amber.AmberParm.from_structure(Structure) prmtop.write_parm("prmtop") # Create AMBER mdin file and append some stuff mdin = Mdin() # Single point energies? mdin.change("cntrl", "imin", "5") # Periodic boundary conditions? if pbc: mdin.change("cntrl", "ntb", "1") else: mdin.change("cntrl", "ntb", "0") # Cutoff zero is really infinite if float(mdp_opts["rlist"]) == 0.0: mdin.change("cntrl", "cut", "9999") else: mdin.change("cntrl", "cut", str(int(float(mdp_opts["rlist"]) * 10))) # Take zero MD steps mdin.change("cntrl", "nstlim", "0") # Don't update nonbond parameters mdin.change("cntrl", "nsnb", "0") # if mdp_opts['coulombtype'].lower() == 'pme': # mdin.change('ewald','order',5) # mdin.change('ewald','skinnb',0) mdin.write("mdin") # Nonbonded method if mdp_opts["coulombtype"].lower() == "pme": with open("mdin", "a") as f: print >> f, """&ewald order=5, skinnb=0 /""" with open("mdin", "a") as f: print >> f, """&debugf do_debugf=1, dumpfrc=1 /""" # Call sander for energy and force os.system("rm -f forcedump.dat") _exec("sander -O -y mdcrd", print_command=False) # Parse energy and force ParseMode = 0 Energies = [] Forces = [] Force = [] iatom = 0 isAtom = [atom.atomic_number > 0 for atom in Structure.atoms] for line in open("forcedump.dat"): line = line.strip() sline = line.split() if ParseMode == 1: if len(sline) == 1 and isfloat(sline[0]): Energies.append(float(sline[0]) * 4.184) ParseMode = 0 if ParseMode == 2: if len(sline) == 3 and all(isfloat(sline[i]) for i in range(3)): if isAtom[iatom]: Force += [float(sline[i]) * 4.184 * 10 for i in range(3)] iatom += 1 if len(Force) == 3 * sum(isAtom): Forces.append(np.array(Force)) Force = [] ParseMode = 0 iatom = 0 if line == "0 START of Energies": ParseMode = 1 elif line == "1 Total Force" or line == "2 Total Force": ParseMode = 2 # Obtain energy components ParseMode = 0 Ecomps = OrderedDict() for line in open("mdout").readlines(): if "NSTEP = " in line: ParseMode = 1 if ParseMode == 1: if "=" not in line: ParseMode = 0 continue else: ieq = None wkey = [] # Assume the line is split-able for i, w in enumerate(line.split()): if w == "=": ieq = i elif i - 1 == ieq: Ecomps.setdefault(" ".join(wkey), []).append(float(w) * 4.184) wkey = [] else: wkey.append(w) Ecomps_Sav = OrderedDict() for key in Ecomps: if set(Ecomps[key]) == set([0.0]): continue elif key.lower() in ["eptot", "etot", "volume", "density"]: continue else: Ecomps_Sav[key] = Ecomps[key][0] Ecomps_Sav["EPTOT"] = Ecomps["EPtot"][0] # Save just the first frame from the .mdcrd Energies = Energies[0] Forces = Forces[0] return Energies, Forces, Ecomps_Sav