def minimize(parm, igb, saltcon, cutoff, tol, maxcyc): """ Minimizes a snapshot. Use the existing System if it exists """ if not HAS_SANDER: raise SimulationError('Could not import sander') if not HAS_SCIPY: raise SimulationError('Could not import scipy') if parm.box is None: if not igb in (0, 1, 2, 5, 6, 7, 8): raise SimulationError('Bad igb value. Must be 0, 1, 2, 5, ' '6, 7, or 8') if cutoff is None: cutoff = 999.0 inp = sander.gas_input(igb) inp.saltcon = saltcon inp.cut = cutoff else: if cutoff is None: cutoff = 8.0 inp = sander.pme_input() inp.cut = cutoff # Define the objective function to minimize def energy_function(xyz): sander.set_positions(xyz) e, f = sander.energy_forces() return e.tot, -np.array(f) with sander.setup(parm, parm.coordinates, parm.box, inp): options = dict(maxiter=maxcyc, disp=True, gtol=tol) results = optimize.minimize(energy_function, parm.coordinates, method='L-BFGS-B', jac=True, options=options) parm.coordinates = results.x if not results.success: print('Problem minimizing structure with scipy and sander:', file=sys.stderr) print('\t' + results.message)
def minimize(parm, igb, saltcon, cutoff, tol, maxcyc, disp=True, callback=None): """ Minimizes a snapshot. Use the existing System if it exists """ if not HAS_SANDER: raise SimulationError('Could not import sander') if not HAS_SCIPY: raise SimulationError('Could not import scipy') if parm.box is None: if not igb in {0, 1, 2, 5, 6, 7, 8}: raise SimulationError('Bad igb value. Must be 0, 1, 2, 5, 6, 7, or 8') if cutoff is None: cutoff = 999.0 inp = sander.gas_input(igb) inp.saltcon = saltcon inp.cut = cutoff else: if cutoff is None: cutoff = 8.0 inp = sander.pme_input() inp.cut = cutoff # Define the objective function to minimize def energy_function(xyz): sander.set_positions(xyz) e, f = sander.energy_forces() return e.tot, -np.array(f) with sander.setup(parm, parm.coordinates, parm.box, inp): options = dict(maxiter=maxcyc, disp=disp, gtol=tol) more_options = dict() if callable(callback): more_options['callback'] = callback results = optimize.minimize(energy_function, parm.coordinates, method='L-BFGS-B', jac=True, options=options, **more_options) parm.coordinates = results.x if not results.success: LOGGER.error(f'Problem minimizing structure with scipy and sander: {results.message}')
def main(): # require 'sanderapi' and 'parmed' packages in AmberTools15 # http://ambermd.org/#AmberTools # more info about `sanderapi` in Amber15 manual # http://ambermd.org/doc12/Amber15.pdf (page 341) traj = io.iterload("../tests/data/Tc5b.x", "../tests/data/Tc5b.top") print(traj) edict0 = pyca.energy_decomposition(parm="../tests/data/Tc5b.top", traj=traj, igb=8, input_options=None) print(edict0) # edict1: use default igb=8 edict1 = pyca.energy_decomposition(traj=traj) print(edict1) aa_eq(edict0['tot'], edict1['tot']) # update `input` and get minimal output import sander inp = sander.gas_input(6) edict2 = pyca.energy_decomposition(traj, input_options=inp, mode='minimal') print(edict2)
def test_GB_QMMM(self): # compare to saved test: GB + QMMM topfile = os.path.join(amberhome, "test/qmmm2/lysine_PM3_qmgb2/prmtop") rstfile = os.path.join(amberhome, "test/qmmm2/lysine_PM3_qmgb2/lysine.crd") traj = pt.load(rstfile, topfile) options = sander.gas_input(1) options.cut = 99.0 options.ifqnt = 1 qm_options = sander.qm_input() qm_options.iqmatoms[:3] = [8, 9, 10] qm_options.qm_theory = "PM3" qm_options.qmcharge = 0 qm_options.qmgb = 2 qm_options.adjust_q = 0 edict = pt.energy_decomposition(traj=traj, mm_options=options, qm_options=qm_options) assert_close(edict['bond'][0], 0.0016, tol=3E-4) assert_close(edict['vdw'][0], 0.1908, tol=3E-4) assert_close(edict['vdw_14'][0], 3.7051, tol=3E-4) assert_close(edict['elec'][0], -4.1241, tol=3E-4) assert_close(edict['elec_14'][0], 65.9137, tol=3E-4) assert_close(edict['gb'][0], -80.1406, tol=3E-4) assert_close(edict['scf'][0], -11.9100, tol=3E-4)
def test_mm_options_as_string(self): traj = pt.iterload(fn('tz2.nc'), fn('tz2.parm7')) igb = 8 mm_options = sander.gas_input(igb) mm_options_str = 'mm_options = sander.gas_input(8)' e0 = pt.energy_decomposition(traj, mm_options=mm_options, dtype='dict') e1 = pt.energy_decomposition(traj, mm_options=mm_options_str, dtype='dict') assert sorted(e0) == sorted(e1)
def test_update_dihedral_parm(self): traj = pt.iterload("./data/Tc5b.crd", fn('Tc5b.top')) p = pmd.load_file(traj.top.filename) inp = sander.gas_input(8) coords = traj[0].xyz with pt.utils.context.tempfolder(): for k in range(20, 100): p.bonds[3].type.k = k p.remake_parm() with sander.setup(p, coords, None, inp): ene, frc = sander.energy_forces()
def test_gbneck2nu(self): # compare to saved test: GBneck2nu topfile = os.path.join(amberhome, "test/gbneck2nu/1hji/prmtop") rstfile = os.path.join(amberhome, "test/gbneck2nu/1hji/min.r") traj = pt.load(rstfile, topfile) options = sander.gas_input(8) options.cut = 9999.0 edict = pt.esander(traj=traj, mm_options=options, prmtop=topfile) assert_close(edict['gb'][0], -2287.6880, tol=3E-4) assert_close(edict['gb'][0], -2287.6880, tol=3E-4) assert_close(edict['elec'][0], -1659.5740, tol=3E-4) assert_close(edict['vdw'][0], 384.2512, tol=3E-4)
def test_update_dihedral_parm(self): traj = pt.iterload("./data/Tc5b.crd", "./data/Tc5b.top") p = pmd.load_file(traj.top.filename) inp = sander.gas_input(8) coords = traj[0].xyz fname = "tmp.parm7" with pt.utils.context.tempfolder(): for k in range(20, 100): p.bonds[3].type.k = k p.remake_parm() with sander.setup(p, coords, None, inp): ene, frc = sander.energy_forces()
def test_gbneck2nu(self): # compare to saved test: GBneck2nu topfile = os.path.join(amberhome, "test/gbneck2nu/1hji/prmtop") rstfile = os.path.join(amberhome, "test/gbneck2nu/1hji/min.r") traj = pt.load(rstfile, topfile) options = sander.gas_input(8) options.cut = 9999.0 edict = pt.energy_decomposition(traj=traj, mm_options=options, prmtop=topfile) assert_close(edict['gb'][0], -2287.6880, tol=3E-4) assert_close(edict['gb'][0], -2287.6880, tol=3E-4) assert_close(edict['elec'][0], -1659.5740, tol=3E-4) assert_close(edict['vdw'][0], 384.2512, tol=3E-4)
def test_GB(self): # compare to saved test: GB topfile = os.path.join(amberhome, "test/gb7_trx/prmtop_an") rstfile = os.path.join(amberhome, "test/gb7_trx/trxox.2.4ns.x") traj = pt.load(rstfile, topfile) options = sander.gas_input(7) options.cut = 9999.0 options.saltcon = 0.2 options.gbsa = 1 edict = pt.energy_decomposition(traj=traj, mm_options=options, prmtop=topfile) assert_close(edict['bond'][0], 631.8993, tol=3E-4) assert_close(edict['angle'][0], 898.2543, tol=3E-4) assert_close(edict['surf'][0], 33.8338, tol=3E-4) assert_close(edict['gb'][0], -1943.0838, tol=3E-4) # dummy test to make sure `energy_decomposition` can work with list edict2 = pt.energy_decomposition(traj=[ traj, ], mm_options=options, prmtop=topfile, top=traj.top) edict3 = pt.energy_decomposition(traj=traj(), mm_options=options, prmtop=topfile, top=traj.top) edict4 = pt.energy_decomposition(traj=[traj[:5], traj[5:]], mm_options=options, prmtop=topfile, top=traj.top) edict5 = pt.energy_decomposition(traj=[traj[:5], traj(start=5)], mm_options=options, prmtop=topfile, top=traj.top) # test dtype dslist = pt.energy_decomposition(traj=[ traj, ], mm_options=options, prmtop=topfile, top=traj.top, dtype='dataset') assert edict == edict2 assert edict == edict3 assert edict == edict4 assert sorted(dslist.to_dict()) == sorted(edict)
def get_total_energy(agls): # get the coor from pyrosetta inp_coor=generate_coord(agls) # initialize the object topology with coordinates parm=AmberParm("tpp-1.prmtop",inp_coor) # set up the input options inp=sander.gas_input() sander.setup (parm, parm.coordinates, None, inp) # compute the energy and force eney, frc=sander.energy_forces() # print('sander',eney.tot,eney.gb,eney.vdw, eney.elec, eney.dihedral,eney.angle, eney.bond) # clean and finish sander.cleanup() return eney.tot
def test_GB(self): # compare to saved test: GB topfile = os.path.join(amberhome, "test/gb7_trx/prmtop_an") rstfile = os.path.join(amberhome, "test/gb7_trx/trxox.2.4ns.x") traj = pt.load(rstfile, topfile) options = sander.gas_input(7) options.cut = 9999.0 options.saltcon = 0.2 options.gbsa = 1 edict = pt.energy_decomposition(traj=traj, mm_options=options, prmtop=topfile) assert_close(edict['bond'][0], 631.8993, tol=3E-4) assert_close(edict['angle'][0], 898.2543, tol=3E-4) assert_close(edict['surf'][0], 33.8338, tol=3E-4) assert_close(edict['gb'][0], -1943.0838, tol=3E-4) # dummy test to make sure `energy_decomposition` can work with list edict2 = pt.energy_decomposition(traj=[traj, ], mm_options=options, prmtop=topfile, top=traj.top) edict3 = pt.energy_decomposition(traj=traj(), mm_options=options, prmtop=topfile, top=traj.top) edict4 = pt.energy_decomposition(traj=[traj[:5], traj[5:]], mm_options=options, prmtop=topfile, top=traj.top) edict5 = pt.energy_decomposition(traj=[traj[:5], traj(start=5)], mm_options=options, prmtop=topfile, top=traj.top) # test dtype dslist = pt.energy_decomposition(traj=[traj, ], mm_options=options, prmtop=topfile, top=traj.top, dtype='dataset') assert edict == edict2 assert edict == edict3 assert edict == edict4 assert sorted(dslist.to_dict()) == sorted(edict)
def test_sander_pmap_with_options(self): '''need to write mm_options as text ''' code_local = ''' mm_options = sander.gas_input(8) ''' traj = pt.iterload(fn('Tc5b.x'), fn('Tc5b.top')) for code in [code_global, code_local]: data_parallel = pt.pmap(pt.energy_decomposition, traj, mm_options=code, n_cores=3, dtype='dict') mm_options = sander.gas_input(8) data_serial = pt.energy_decomposition(traj, mm_options=mm_options, dtype='dict') aa_eq(pt.tools.dict_to_ndarray(data_parallel), pt.tools.dict_to_ndarray(data_serial))
def test_sander_pmap_with_options(self): '''need to write mm_options as text ''' code_local = ''' mm_options = sander.gas_input(8) ''' traj = pt.iterload('./data/Tc5b.x', './data/Tc5b.top') for code in [code_global, code_local]: data_parallel = pt.pmap(pt.energy_decomposition, traj, mm_options=code, n_cores=3, dtype='dict') mm_options = sander.gas_input(8) data_serial = pt.energy_decomposition(traj, mm_options=mm_options, dtype='dict') aa_eq( pt.tools.dict_to_ndarray(data_parallel), pt.tools.dict_to_ndarray(data_serial))
def sanderforce(self,parmstr,atmlst,boxflag=False,pmeflag=False): """Calculates energy and forces for a provided Amber parm string and set of coordinates using the Sander API. Also takes box dimensions and a flag for use of PME. Currently uses standard simulation options for gas phase or pme based on pmeflag. Only returns forces on first 2 atoms in atmlst Returns a sander energy object and a 3 x 2 x traj length array of forces with units""" self.forces=[] self.energies=[] # sander.APPLY_UNITS = True # More bugs/inconsistencies in pysander in amber15, may be fixed later indices = [a.idx for a in atmlst[:2]] if pmeflag is True: # These default options will be suitable in most cases # PME,cut=8.0,ntb=1,ntf=1,ntc=1 # Should be adapted if shake is required (not important here for ele) inp = sander.pme_input() else: inp = sander.gas_input() for i in range(0,self.traj.frame): coord = self.traj.coordinates[i] if boxflag is True: box = self.traj.box[i] # print box else: box = None with sander.setup(parmstr,coord,box=box,mm_options=inp): #Pass a string, else a temp parmfile is created that fills up tmp directory! ene,frc = sander.energy_forces(as_numpy=False) # pysander __init__ bug/inconsistency, can't use as_numpy! frc = np.asarray(frc) frc = np.reshape(frc,((len(frc)/3.),3)) frcslice = frc[indices] # Add units for forces: kcal mol-1 A-1 frcslice = frcslice * u.kilocalorie / (u.mole * u.angstroms) self.forces.append(frcslice) self.energies.append(ene)
import numpy as np import pytraj as pt import sander traj = pt.datafiles.load_tz2() inp = sander.gas_input(8) frcs = [] with sander.setup(traj.top.filename, traj[0].xyz, traj.top.box, inp): for frame in traj: sander.set_box(*frame.box.tolist()) sander.set_positions(frame.xyz) ene, frc = sander.energy_forces() frcs.append(np.array(frc).reshape(traj.n_atoms, 3)) def get_frame_with_force(traj, forces=frcs): frame0 = pt.Frame() crdinfo = dict(has_force=True) frame0._allocate_force_and_velocity(traj.top, crdinfo) for frame, frc in zip(traj, frcs): frame0.xyz[:] = frame.xyz frame0.force[:] = frc yield frame0 pt.write_traj('traj.nc',
help='''Cutoff for nonbonded forces in Angstroms. Cutoff is always infinite for non-periodic systems''') group.add_argument('--platform', dest='platform', default='Reference', help='OpenMM platform to use. Default is %(default)s') args = parser.parse_args() # Get the Amber forces and energies if args.pbc: inp = sander.pme_input() inp.cut = args.cutoff inp.ntc = inp.ntf = 1 else: inp = sander.gas_input(args.igb) inp.cut = 1000 inp.rgbmax = 1000 with sander.setup(args.prmtop, args.inpcrd, None, inp) as context: e, f = sander.energy_forces() f = np.array(f).reshape((context.natom, 3)) # Get the OpenMM forces and energies parm = app.AmberPrmtopFile(args.prmtop) inpcrd = app.AmberInpcrdFile(args.inpcrd) gbmap = collections.defaultdict(lambda: None) gbmap[1] = app.HCT gbmap[2] = app.OBC1 gbmap[5] = app.OBC2
help='''GB model to use (see Amber manual). Default is %(default)s''') group.add_argument('--cutoff', dest='cutoff', type=float, default=8, help='''Cutoff for nonbonded forces in Angstroms. Cutoff is always infinite for non-periodic systems''') group.add_argument('--platform', dest='platform', default='Reference', help='OpenMM platform to use. Default is %(default)s') args = parser.parse_args() # Get the Amber forces and energies if args.pbc: inp = sander.pme_input() inp.cut = args.cutoff else: inp = sander.gas_input(args.igb) inp.cut = 1000 with sander.setup(args.prmtop, args.inpcrd, None, inp) as context: e, f = sander.energy_forces() f = np.array(f).reshape((context.natom, 3)) # Get the OpenMM forces and energies parm = app.AmberPrmtopFile(args.prmtop) inpcrd = app.AmberInpcrdFile(args.inpcrd) gbmap = collections.defaultdict(lambda: None) gbmap[1] = app.HCT gbmap[2] = app.OBC1 gbmap[5] = app.OBC2 gbmap[7] = app.GBn
def energy(parm, args, output=sys.stdout): """ Compute a single-point energy using sander and print the result to the desired output Parameters ---------- parm : Structure args : ArgumentList output : file handler, default sys.stdout """ global HAS_SANDER if not HAS_SANDER: raise SimulationError('Could not import sander') cutoff = args.get_key_float('cutoff', None) igb = args.get_key_int('igb', 5) saltcon = args.get_key_float('saltcon', 0.0) do_ewald = args.has_key('Ewald') vdw_longrange = not args.has_key('nodisper') has_1264 = 'LENNARD_JONES_CCOEF' in parm.parm_data # Get any unmarked arguments unmarked_cmds = args.unmarked() if len(unmarked_cmds) > 0: warnings.warn("Un-handled arguments: " + ' '.join(unmarked_cmds), UnhandledArgumentWarning) if parm.ptr('ifbox') == 0: if not igb in (0, 1, 2, 5, 6, 7, 8): raise SimulationError('Bad igb value. Must be 0, 1, 2, 5, ' '6, 7, or 8') # Force vacuum electrostatics down the GB code path if igb == 0: igb = 6 inp = sander.gas_input(igb) if cutoff is None: cutoff = 1000.0 if cutoff <= 0: raise SimulationError('cutoff must be > 0') inp.cut = cutoff if saltcon < 0: raise SimulationError('salt concentration must be >= 0') inp.saltcon = saltcon elif parm.ptr('ifbox') > 0: inp = sander.pme_input() if cutoff is None: cutoff = 8.0 elif cutoff <= 0: raise SimulationError('cutoff must be > 0') inp.cut = cutoff inp.ew_type = int(do_ewald) inp.vdwmeth = int(vdw_longrange) inp.lj1264 = int(has_1264) if parm.coordinates is None: raise SimulationError('No coordinates are loaded') # Time to set up sander with sander.setup(parm, parm.coordinates, parm.box, inp): e, f = sander.energy_forces() if parm.chamber: output.write('Bond = %20.7f Angle = %20.7f\n' 'Dihedral = %20.7f Urey-Bradley = %20.7f\n' 'Improper = %20.7f ' % (e.bond, e.angle, e.dihedral, e.angle_ub, e.imp)) if parm.has_cmap: output.write('CMAP = %20.7f\n' % e.cmap) output.write('1-4 vdW = %20.7f 1-4 Elec. = %20.7f\n' 'Lennard-Jones = %20.7f Electrostatic = %20.7f\n' 'TOTAL = %20.7f\n' % (e.vdw_14, e.elec_14, e.vdw, e.elec, e.tot)) else: output.write( 'Bond = %20.7f Angle = %20.7f\n' 'Dihedral = %20.7f 1-4 vdW = %20.7f\n' '1-4 Elec = %20.7f vdWaals = %20.7f\n' 'Elec. = %20.7f' % (e.bond, e.angle, e.dihedral, e.vdw_14, e.elec_14, e.vdw, e.elec)) if igb != 0 and inp.ntb == 0: output.write(' Egb = %20.7f' % e.gb) elif e.hbond != 0: output.write(' EHbond = %20.7f' % e.hbond) output.write('\nTOTAL = %20.7f\n' % e.tot)
def energy_decomposition(traj=None, prmtop=None, igb=8, mm_options=None, qm_options=None, mode=None, dtype='dict', frame_indices=None, top=None): """energy decomposition by calling `libsander` Parameters ---------- traj : Trajectory-like or iterables that produce Frame if `traj` does not hold Topology information, `top` must be provided prmtop : str or Structure from ParmEd, default=None, optional To avoid any unexpected error, you should always provide original topology filename. If prmtop is None, pytraj will load Topology from traj.top.filename. - why do you need to load additional topology filename? Because cpptraj and sander use different Topology object, can not convert from one to another. igb : GB model, default=8 (GB-Neck2) If specify `mm_options`, this `igb` input will be ignored mm_options : InputOptions from `sander`, default=None, optional if `mm_options` is None, use `gas_input` with given igb. If `mm_options` is not None, use this qm_options : InputOptions from `sander` for QMMM, optional mode : str, default=None, optional if mode='minimal', get only 'bond', 'angle', 'dihedral' and 'total' energies top : pytraj.Topology or str, default=None, optional only need to specify this ``top`` if ``traj`` does not hold Topology dtype : str, {'dict', 'dataset', 'ndarray', 'dataframe'}, default='dict' return data type frame_indices : None or 1D array-like, default None if not None, only perform calculation for given frames Returns ------- Dict of energies (to be used with DataFrame) or DatasetList Examples -------- Examples are adapted from $AMBERHOME/test/sanderapi >>> import pytraj as pt >>> # GB energy >>> traj = pt.datafiles.load_ala3() >>> traj.n_frames 1 >>> data = pt.energy_decomposition(traj, igb=8) >>> data['gb'] array([-92.88577683]) >>> data['bond'] array([ 5.59350521]) >>> # PME >>> import os >>> from pytraj.testing import amberhome >>> import sander >>> topfile = os.path.join(amberhome, "test/4096wat/prmtop") >>> rstfile = os.path.join(amberhome, "test/4096wat/eq1.x") >>> traj = pt.iterload(rstfile, topfile) >>> options = sander.pme_input() >>> options.cut = 8.0 >>> edict = pt.energy_decomposition(traj=traj, mm_options=options) >>> edict['vdw'] array([ 6028.95167558]) >>> # GB + QMMM >>> topfile = os.path.join(amberhome, "test/qmmm2/lysine_PM3_qmgb2/prmtop") >>> rstfile = os.path.join(amberhome, "test/qmmm2/lysine_PM3_qmgb2/lysine.crd") >>> traj = pt.iterload(rstfile, topfile) >>> options = sander.gas_input(8) >>> options.cut = 99.0 >>> options.ifqnt = 1 >>> qm_options = sander.qm_input() >>> qm_options.iqmatoms[:3] = [8, 9, 10] >>> qm_options.qm_theory = "PM3" >>> qm_options.qmcharge = 0 >>> qm_options.qmgb = 2 >>> qm_options.adjust_q = 0 >>> edict = pt.energy_decomposition(traj=traj, mm_options=options, qm_options=qm_options) >>> edict['bond'] array([ 0.00160733]) >>> edict['scf'] array([-11.92177575]) Notes ----- This method does not work with `pytraj.pmap` when you specify mm_options and qm_options. Use `pytraj.pmap_mpi` with MPI instead. Work with ``pytraj.pmap``:: pt.pmap(pt.energy_decomposition, traj, igb=8, dtype='dict') Will NOT work with ``pytraj.pmap``:: import sander inp = sander.gas_input(8) pt.pmap(pt.energy_decomposition, traj, mm_options=inp, dtype='dict') Why? Because Python need to pickle each object to send to different cores and Python does not know how to pickle mm_options from sander.gas_input(8). This works with ``pytraj.pmap_mpi`` because pytraj explicitly create ``mm_options`` in each core without pickling. """ from collections import defaultdict, OrderedDict from pytraj.misc import get_atts import numpy as np try: import sander except ImportError: raise ImportError("need both `pysander` installed. Check Ambertools15") ddict = defaultdict(_default_func) if mm_options is None: inp = sander.gas_input(igb) elif igb is not None: inp = mm_options if isinstance(inp, string_types): # dangerous local_dict = {'sander': sander} exec(inp.lstrip(), local_dict) inp = local_dict['mm_options'] if isinstance(qm_options, string_types): # dangerous local_dict = {'sander': sander} exec(qm_options.lstrip(), local_dict) qm_options = local_dict['qm_options'] if prmtop is None: try: # try to load from file by taking top.filename prmtop_ = top.filename except AttributeError: raise ValueError("prmtop must be AmberParm object in ParmEd") else: # Structure, string prmtop_ = prmtop if not hasattr(prmtop_, 'coordinates') or prmtop_.coordinates is None: try: # if `traj` is Trajectory-like (not frame_iter), try to take 1st # coords coords = traj[0].xyz except (TypeError, AttributeError): # create fake list coords = [0. for _ in range(top.n_atoms * 3)] else: # use default coords in `AmberParm` coords = prmtop_.coordinates if top.has_box(): box = top.box.tolist() has_box = True else: box = None has_box = False with sander.setup(prmtop_, coords, box, inp, qm_options): for frame in iterframe_master(traj): if has_box: sander.set_box(*frame.box.tolist()) sander.set_positions(frame.xyz) ene, frc = sander.energy_forces() # potentially slow ene_atts = get_atts(ene) for att in ene_atts: ddict[att].append(getattr(ene, att)) new_dict = None if mode == 'minimal': new_dict = {} for key in ['bond', 'angle', 'dihedral', 'tot']: new_dict[key] = ddict[key] else: new_dict = ddict for key in new_dict.keys(): new_dict[key] = np.asarray(new_dict[key]) if dtype == 'dict': return OrderedDict(new_dict) else: from pytraj.datasets.c_datasetlist import DatasetList dslist = DatasetList() size = new_dict['tot'].__len__() for key in new_dict.keys(): dslist.add('double') dslist[-1].key = key dslist[-1].resize(size) dslist[-1].data[:] = new_dict[key] return get_data_from_dtype(dslist, dtype)
def energy(parm, args, output=sys.stdout): """ Compute a single-point energy using sander and print the result to the desired output """ global HAS_SANDER if not HAS_SANDER: raise SimulationError('Could not import sander') cutoff = args.get_key_float('cutoff', None) igb = args.get_key_int('igb', 5) saltcon = args.get_key_float('saltcon', 0.0) do_ewald = args.has_key('Ewald') vdw_longrange = not args.has_key('nodisper') has_1264 = 'LENNARD_JONES_CCOEF' in parm.parm_data # Get any unmarked arguments unmarked_cmds = args.unmarked() if len(unmarked_cmds) > 0: warnings.warn("Un-handled arguments: " + ' '.join(unmarked_cmds), UnhandledArgumentWarning) if parm.ptr('ifbox') == 0: if not igb in (0, 1, 2, 5, 6, 7, 8): raise SimulationError('Bad igb value. Must be 0, 1, 2, 5, ' '6, 7, or 8') # Force vacuum electrostatics down the GB code path if igb == 0: igb = 6 inp = sander.gas_input(igb) if cutoff is None: cutoff = 1000.0 if cutoff <= 0: raise SimulationError('cutoff must be > 0') inp.cut = cutoff if saltcon < 0: raise SimulationError('salt concentration must be >= 0') inp.saltcon = saltcon elif parm.ptr('ifbox') > 0: inp = sander.pme_input() if cutoff is None: cutoff = 8.0 elif cutoff <= 0: raise SimulationError('cutoff must be > 0') inp.cut = cutoff inp.ew_type = int(do_ewald) inp.vdwmeth = int(vdw_longrange) inp.lj1264 = int(has_1264) if parm.coordinates is None: raise SimulationError('No coordinates are loaded') # Time to set up sander with sander.setup(parm, parm.coordinates, parm.box, inp): e, f = sander.energy_forces() if parm.chamber: output.write('Bond = %20.7f Angle = %20.7f\n' 'Dihedral = %20.7f Urey-Bradley = %20.7f\n' 'Improper = %20.7f ' % (e.bond, e.angle, e.dihedral, e.angle_ub, e.imp)) if parm.has_cmap: output.write('CMAP = %20.7f\n' % e.cmap) output.write('1-4 vdW = %20.7f 1-4 Elec. = %20.7f\n' 'Lennard-Jones = %20.7f Electrostatic = %20.7f\n' 'TOTAL = %20.7f\n' % (e.vdw_14, e.elec_14, e.vdw, e.elec, e.tot)) else: output.write('Bond = %20.7f Angle = %20.7f\n' 'Dihedral = %20.7f 1-4 vdW = %20.7f\n' '1-4 Elec = %20.7f vdWaals = %20.7f\n' 'Elec. = %20.7f' % (e.bond, e.angle, e.dihedral, e.vdw_14, e.elec_14, e.vdw, e.elec)) if igb != 0 and inp.ntb == 0: output.write(' Egb = %20.7f' % e.gb) elif e.hbond != 0: output.write(' EHbond = %20.7f' % e.hbond) output.write('\nTOTAL = %20.7f\n' % e.tot)
# import MPI to get rank from mpi4py import MPI import pytraj as pt from pytraj.testing import aa_eq try: import sander comm = MPI.COMM_WORLD # end. you are free to update anything below here # split remd.x.000 to N cores and do calc_surf in parallel root_dir = "../../tests/data/" traj_name = root_dir + "tz2.nc" parm_name = root_dir + "tz2.parm7" # load to TrajectoryIterator traj = pt.iterload(traj_name, parm_name) inp = sander.gas_input(8) # gather the data # if rank != 0: data is None data = pt.pmap_mpi(pt.energy_decomposition, traj, mm_options=inp) if comm.rank == 0: # make sure to reproduce serial output serial_data = pt.energy_decomposition(traj, mm_options=inp) aa_eq(pt.tools.dict_to_ndarray(data), pt.tools.dict_to_ndarray(serial_data)) except ImportError: print('does not have sander. skip this example')