def _get_charges_from_openmm_system(omm_sys: openmm.System): for force in omm_sys.getForces(): if type(force) == openmm.NonbondedForce: break for idx in range(omm_sys.getNumParticles()): param = force.getParticleParameters(idx) yield param[0].value_in_unit(simtk_unit.elementary_charge)
def add_constraints(system: mm.System, args: ListOfArgs): print(" Adding constraints...") print(f" r = {args.POL_CONSTRAINT_DISTANCE}") counter = 0 for i in range(system.getNumParticles() - 1): system.addConstraint(i, i + 1, args.POL_CONSTRAINT_DISTANCE) counter += 1 print(f" {counter} constraints added.")
def _get_lj_params_from_openmm_system(omm_sys: openmm.System): for force in omm_sys.getForces(): if type(force) == openmm.NonbondedForce: break n_particles = omm_sys.getNumParticles() sigmas = np.asarray([*_get_sigma_from_nonbonded_force(n_particles, force)]) epsilons = np.asarray([*_get_epsilon_from_nonbonded_force(n_particles, force)]) return sigmas, epsilons
def add_harmonic_bond(system: mm.System, args: ListOfArgs): print(" Adding harmonic bonds...") print(f" r0 = {args.POL_HARMONIC_BOND_R0}") print(f" k = {args.POL_HARMONIC_BOND_K} kJ/mol/nm^2") bond_force = mm.HarmonicBondForce() system.addForce(bond_force) counter = 0 for i in range(system.getNumParticles() - 1): bond_force.addBond(i, i + 1, args.POL_HARMONIC_BOND_R0, args.POL_HARMONIC_BOND_K) counter += 1 print(f" {counter} harmonic bonds added.")
def add_harmonic_angle(system: mm.System, args: ListOfArgs): print(" Adding harmonic angles...") print(f" r0 = {args.POL_HARMONIC_ANGLE_R0}") print(f" k = {args.POL_HARMONIC_ANGLE_K} kJ/mol/radian^2") bond_force = mm.HarmonicAngleForce() system.addForce(bond_force) counter = 0 for i in range(system.getNumParticles() - 2): bond_force.addAngle(i, i + 1, i + 2, args.POL_HARMONIC_ANGLE_R0, args.POL_HARMONIC_ANGLE_K) counter += 1 print(f" {counter} harmonic bonds added.")
def add_excluded_volume(system: mm.System, args: ListOfArgs): print(" Adding excluded volume...") print(f" epsilon = {args.EV_EPSILON}") print(f" sigma = {args.EV_SIGMA}") ev_force = mm.CustomNonbondedForce('epsilon*((sigma1+sigma2)/r)^12') ev_force.addGlobalParameter('epsilon', defaultValue=args.EV_EPSILON) ev_force.addPerParticleParameter('sigma') system.addForce(ev_force) counter = 0 for i in range(system.getNumParticles()): ev_force.addParticle([args.EV_SIGMA]) counter += 1 print(f" {counter} ev interactions added.")
def add_external_field(system: mm.System, args: ListOfArgs): """Add external forcefield for image-driven modelling purposes.""" print(' Adding external forcefield.') size = os.stat(args.EF_PATH).st_size print(f" Reading {args.EF_PATH} file ({sizeof_fmt(size)})...") img = np.load(args.EF_PATH) print(f" Array of shape {img.shape} loaded.") print(f" Number of values: {img.size}") print(f" Min: {np.min(img)}") print(f" Max: {np.max(img)}") if args.EF_NORMALIZE: print(' [INFO] Field will be normalized to [0, -1]') img = standardize_image(img) print(f' [INFO] IMG min = {np.min(img)}, max = {np.max(img)}') print(f' [INFO] Adding funnel like border to image') mask_p = (img < -0.1) mask_n = np.logical_not(mask_p) img = add_funnel(img, mask_n) print(" Creating a force based on density...") voxel_size = np.array((args.EF_VOXEL_SIZE_X, args.EF_VOXEL_SIZE_Y, args.EF_VOXEL_SIZE_Z)) real_size = img.shape * voxel_size density_fun_args = dict( xsize=img.shape[2], ysize=img.shape[1], zsize=img.shape[0], values=img.flatten().astype(np.float64), xmin=0 * simtk.unit.angstrom - 0.5 * voxel_size[0], ymin=0 * simtk.unit.angstrom - 0.5 * voxel_size[1], zmin=0 * simtk.unit.angstrom - 0.5 * voxel_size[2], xmax=(img.shape[0] - 1) * voxel_size[0] + 0.5 * voxel_size[0], ymax=(img.shape[1] - 1) * voxel_size[1] + 0.5 * voxel_size[1], zmax=(img.shape[2] - 1) * voxel_size[2] + 0.5 * voxel_size[2]) print(f' [INFO] Voxel size: ({args.EF_VOXEL_SIZE_X}, {args.EF_VOXEL_SIZE_Y}, {args.EF_VOXEL_SIZE_Z})') print(f' [INFO] Real size (Shape * voxel size): ({real_size[0]}, {real_size[1]}, {real_size[2]})') print( f" [INFO] begin coords: ({density_fun_args['xmin']}, {density_fun_args['ymin']}, {density_fun_args['zmin']})") print( f" [INFO] end coords: ({density_fun_args['xmax']}, {density_fun_args['ymax']}, {density_fun_args['zmax']})") center_x = (density_fun_args['xmax'] - density_fun_args['xmin']) / 2 + density_fun_args['xmin'] center_y = (density_fun_args['ymax'] - density_fun_args['ymin']) / 2 + density_fun_args['ymin'] center_z = (density_fun_args['zmax'] - density_fun_args['zmin']) / 2 + density_fun_args['zmin'] print(f" [INFO] Image central point: ({center_x}, {center_y}, {center_z}) ") field_function = mm.Continuous3DFunction(**density_fun_args) field_force = mm.CustomCompoundBondForce(1, 'ksi*fi(x1,y1,z1)') field_force.addTabulatedFunction('fi', field_function) field_force.addGlobalParameter('ksi', args.EF_SCALING_FACTOR) print(" Adding force to the system...") for i in range(system.getNumParticles()): field_force.addBond([i], []) system.addForce(field_force)
def add_spherical_container(system: mm.System, args: ListOfArgs): print(" Adding spherical container...") container_force = mm.CustomExternalForce( '{}*max(0, r-{})^2; r=sqrt((x-{})^2+(y-{})^2+(z-{})^2)'.format(args.SC_SCALE, args.SC_RADIUS, args.SC_CENTER_X, args.SC_CENTER_Y, args.SC_CENTER_Z, )) system.addForce(container_force) for i in range(system.getNumParticles()): container_force.addParticle(i, []) print(f" Spherical container added.") print(f" radius: {args.SC_RADIUS} nm") print(f" scale: {args.SC_SCALE} ") print(f" center: ({args.SC_CENTER_X}, {args.SC_CENTER_Y}, {args.SC_CENTER_Z})")
def _add_restraints(system: openmm.System, reference_pdb: openmm_app.PDBFile, stiffness: unit.Unit, rset: str, exclude_residues: Sequence[int]): """Adds a harmonic potential that restrains the system to a structure.""" assert rset in ["non_hydrogen", "c_alpha"] force = openmm.CustomExternalForce( "0.5 * k * ((x-x0)^2 + (y-y0)^2 + (z-z0)^2)") force.addGlobalParameter("k", stiffness) for p in ["x0", "y0", "z0"]: force.addPerParticleParameter(p) for i, atom in enumerate(reference_pdb.topology.atoms()): if atom.residue.index in exclude_residues: continue if will_restrain(atom, rset): force.addParticle(i, reference_pdb.positions[i]) logger.info("Restraining %d / %d particles.", force.getNumParticles(), system.getNumParticles()) system.addForce(force)