示例#1
0
    def isomer_init(self):
        '''
        The purpose of this function is to add to the primitives the driving coordinate prims if 
        they dont exist.
        This is depracated because it's better to build the topology properly before initializing
        GSM. See main.py
        '''

        #TODO ANGLE, TORSION or OOP between fragments will not work if using TRIC with BLOCK LA
        changed_top = False

        #TODO first check if there is any add/break then rebuild topology and makePrimitives

        for i in self.driving_coords:
            if "ADD" in i or "BREAK" in i:
                # order
                if i[1] < i[2]:
                    bond = Distance(i[1] - 1, i[2] - 1)
                else:
                    bond = Distance(i[2] - 1, i[1] - 1)
                self.nodes[0].coord_obj.Prims.add(bond, verbose=True)
                changed_top = True
            if "ANGLE" in i:
                if i[1] < i[3]:
                    angle = Angle(i[1] - 1, i[2] - 1, i[3] - 1)
                else:
                    angle = Angle(i[3] - 1, i[2] - 1, i[1] - 1)
                self.nodes[0].coord_obj.Prims.add(angle, verbose=True)
            if "TORSION" in i:
                if i[1] < i[4]:
                    torsion = Dihedral(i[1] - 1, i[2] - 1, i[3] - 1, i[4] - 1)
                else:
                    torsion = Dihedral(i[4] - 1, i[3] - 1, i[2] - 1, i[1] - 1)
                self.nodes[0].coord_obj.Prims.add(torsion, verbose=True)
            if "OOP" in i:
                if i[1] < i[4]:
                    oop = OutOfPlane(i[1] - 1, i[2] - 1, i[3] - 1, i[4] - 1)
                else:
                    oop = OutOfPlane(i[4] - 1, i[3] - 1, i[2] - 1, i[1] - 1)
                self.nodes[0].coord_obj.Prims.add(oop, verbose=True)

        self.nodes[0].coord_obj.Prims.clearCache()
        if changed_top:
            self.nodes[0].coord_obj.Prims.rebuild_topology_from_prim_bonds(
                self.nodes[0].xyz)
        self.nodes[0].coord_obj.Prims.reorderPrimitives()
        self.nodes[0].update_coordinate_basis()
示例#2
0
def get_driving_coord_prim(dc):
    prim=None
    if "ADD" in dc or "BREAK" in dc:
        if dc[1]<dc[2]:
            prim = Distance(dc[1]-1,dc[2]-1)
        else:
            prim = Distance(dc[2]-1,dc[1]-1)
    elif "ANGLE" in dc:
        if dc[1]<dc[3]:
            prim = Angle(dc[1]-1,dc[2]-1,dc[3]-1)
        else:
            prim = Angle(dc[3]-1,dc[2]-1,dc[1]-1)
    elif "TORSION" in dc:
        if dc[1]<dc[4]:
            prim = Dihedral(dc[1]-1,dc[2]-1,dc[3]-1,dc[4]-1)
        else:
            prim = Dihedral(dc[4]-1,dc[3]-1,dc[2]-1,dc[1]-1)
    elif "OOP" in dc:
        #if dc[1]<dc[4]:
        prim = OutOfPlane(dc[1]-1,dc[2]-1,dc[3]-1,dc[4]-1)
        #else:
        #    prim = OutOfPlane(dc[4]-1,dc[3]-1,dc[2]-1,dc[1]-1)
    return prim
示例#3
0
    def add_restraints(self, system):
        # Bond Restraints
        if self.restrain_bondfile is not None:
            nifty.printcool(" Adding bonding restraints!")
            # Harmonic constraint

            flat_bottom_force = openmm.CustomBondForce(
                'step(r-r0) * (k/2) * (r-r0)^2')
            flat_bottom_force.addPerBondParameter('r0')
            flat_bottom_force.addPerBondParameter('k')
            system.addForce(flat_bottom_force)

            with open(self.restrain_bondfile, 'r') as input_file:
                for line in input_file:
                    print(line)
                    columns = line.split()
                    atom_index_i = int(columns[0])
                    atom_index_j = int(columns[1])
                    r0 = float(columns[2])
                    k = float(columns[3])
                    flat_bottom_force.addBond(atom_index_i, atom_index_j,
                                              [r0, k])

        # Torsion restraint
        if self.restrain_torfile is not None:
            nifty.printcool(" Adding torsional restraints!")

            # Harmonic constraint
            tforce = openmm.CustomTorsionForce(
                "0.5*k*min(dtheta, 2*pi-dtheta)^2; dtheta = abs(theta-theta0); pi = 3.1415926535"
            )
            tforce.addPerTorsionParameter("k")
            tforce.addPerTorsionParameter("theta0")
            system.addForce(tforce)

            xyz = manage_xyz.xyz_to_np(self.geom)
            with open(self.restrain_torfile, 'r') as input_file:
                for line in input_file:
                    columns = line.split()
                    a = int(columns[0])
                    b = int(columns[1])
                    c = int(columns[2])
                    d = int(columns[3])
                    k = float(columns[4])
                    dih = Dihedral(a, b, c, d)
                    theta0 = dih.value(xyz)
                    tforce.addTorsion(a, b, c, d, [k, theta0])

        # Translation restraint
        if self.restrain_tranfile is not None:
            nifty.printcool(" Adding translational restraints!")
            trforce = openmm.CustomExternalForce(
                "k*periodicdistance(x, y, z, x0, y0, z0)^2")
            trforce.addPerParticleParameter("k")
            trforce.addPerParticleParameter("x0")
            trforce.addPerParticleParameter("y0")
            trforce.addPerParticleParameter("z0")
            system.addForce(trforce)

            xyz = manage_xyz.xyz_to_np(self.geom)
            with open(self.restrain_tranfile, 'r') as input_file:
                for line in input_file:
                    columns = line.split()
                    a = int(columns[0])
                    k = float(columns[1])
                    x0 = xyz[a, 0] * 0.1  # Units are in nm
                    y0 = xyz[a, 1] * 0.1  # Units are in nm
                    z0 = xyz[a, 2] * 0.1  # Units are in nm
                    trforce.addParticle(a, [k, x0, y0, z0])
示例#4
0
    def get_tangent(node1, node2, print_level=1, **kwargs):
        '''
        Get internal coordinate tangent between two nodes, assumes they have unique IDs
        '''

        if node2 is not None and node1.node_id != node2.node_id:
            print(" getting tangent from between %i %i pointing towards %i" %
                  (node2.node_id, node1.node_id, node2.node_id))
            assert node2 != None, 'node n2 is None'

            PMDiff = np.zeros(node2.num_primitives)
            for k, prim in enumerate(node2.primitive_internal_coordinates):
                if type(prim) is Distance:
                    PMDiff[k] = 2.5 * prim.calcDiff(node2.xyz, node1.xyz)
                else:
                    PMDiff[k] = prim.calcDiff(node2.xyz, node1.xyz)

            return np.reshape(PMDiff, (-1, 1)), None
        else:
            print(" getting tangent from node ", node1.node_id)

            driving_coords = kwargs.get('driving_coords', None)
            assert driving_coords is not None, " Driving coord is None!"

            c = Counter(elem[0] for elem in driving_coords)
            nadds = c['ADD']
            nbreaks = c['BREAK']
            nangles = c['nangles']
            ntorsions = c['ntorsions']

            ictan = np.zeros((node1.num_primitives, 1), dtype=float)
            # breakdq = 0.3
            bdist = 0.0
            atoms = node1.atoms
            xyz = node1.xyz.copy()

            for i in driving_coords:
                if "ADD" in i:

                    # order indices to avoid duplicate bonds
                    if i[1] < i[2]:
                        index = [i[1] - 1, i[2] - 1]
                    else:
                        index = [i[2] - 1, i[1] - 1]

                    bond = Distance(index[0], index[1])
                    prim_idx = node1.coord_obj.Prims.dof_index(
                        index, 'Distance')
                    if len(i) == 3:
                        # TODO why not just use the covalent radii?
                        d0 = (atoms[index[0]].vdw_radius +
                              atoms[index[1]].vdw_radius) / 2.8
                    elif len(i) == 4:
                        d0 = i[3]
                    current_d = bond.value(xyz)

                    # TODO don't set tangent if value is too small
                    ictan[prim_idx] = -1 * (d0 - current_d)
                    # if nbreaks>0:
                    #    ictan[prim_idx] *= 2
                    # => calc bdist <=
                    if current_d > d0:
                        bdist += np.dot(ictan[prim_idx], ictan[prim_idx])
                    if print_level > 0:
                        print(
                            " bond %s target (less than): %4.3f current d: %4.3f diff: %4.3f "
                            % ((i[1], i[2]), d0, current_d, ictan[prim_idx]))

                elif "BREAK" in i:
                    # order indices to avoid duplicate bonds
                    if i[1] < i[2]:
                        index = [i[1] - 1, i[2] - 1]
                    else:
                        index = [i[2] - 1, i[1] - 1]
                    bond = Distance(index[0], index[1])
                    prim_idx = node1.coord_obj.Prims.dof_index(
                        index, 'Distance')
                    if len(i) == 3:
                        d0 = (atoms[index[0]].vdw_radius +
                              atoms[index[1]].vdw_radius)
                    elif len(i) == 4:
                        d0 = i[3]

                    current_d = bond.value(xyz)
                    ictan[prim_idx] = -1 * (d0 - current_d)

                    # => calc bdist <=
                    if current_d < d0:
                        bdist += np.dot(ictan[prim_idx], ictan[prim_idx])

                    if print_level > 0:
                        print(
                            " bond %s target (greater than): %4.3f, current d: %4.3f diff: %4.3f "
                            % ((i[1], i[2]), d0, current_d, ictan[prim_idx]))
                elif "ANGLE" in i:

                    if i[1] < i[3]:
                        index = [i[1] - 1, i[2] - 1, i[3] - 1]
                    else:
                        index = [i[3] - 1, i[2] - 1, i[1] - 1]
                    angle = Angle(index[0], index[1], index[2])
                    prim_idx = node1.coord_obj.Prims.dof_index(index, 'Angle')
                    anglet = i[4]
                    ang_value = angle.value(xyz)
                    ang_diff = anglet * np.pi / 180. - ang_value
                    # print(" angle: %s is index %i " %(angle,ang_idx))
                    if print_level > 0:
                        print(
                            (" anglev: %4.3f align to %4.3f diff(rad): %4.3f" %
                             (ang_value, anglet, ang_diff)))
                    ictan[prim_idx] = -ang_diff
                    # TODO need to come up with an adist
                    # if abs(ang_diff)>0.1:
                    #    bdist+=ictan[ICoord1.BObj.nbonds+ang_idx]*ictan[ICoord1.BObj.nbonds+ang_idx]
                elif "TORSION" in i:

                    if i[1] < i[4]:
                        index = [i[1] - 1, i[2] - 1, i[3] - 1, i[4] - 1]
                    else:
                        index = [i[4] - 1, i[3] - 1, i[2] - 1, i[1] - 1]
                    torsion = Dihedral(index[0], index[1], index[2], index[3])
                    prim_idx = node1.coord_obj.Prims.dof_index(
                        index, 'Dihedral')
                    tort = i[5]
                    torv = torsion.value(xyz)
                    tor_diff = tort - torv * 180. / np.pi
                    if tor_diff > 180.:
                        tor_diff -= 360.
                    elif tor_diff < -180.:
                        tor_diff += 360.
                    ictan[prim_idx] = -tor_diff * np.pi / 180.

                    if tor_diff * np.pi / 180. > 0.1 or tor_diff * np.pi / 180. < 0.1:
                        bdist += np.dot(ictan[prim_idx], ictan[prim_idx])
                    if print_level > 0:
                        print((
                            " current torv: %4.3f align to %4.3f diff(deg): %4.3f"
                            % (torv * 180. / np.pi, tort, tor_diff)))

                elif "OOP" in i:
                    index = [i[1] - 1, i[2] - 1, i[3] - 1, i[4] - 1]
                    oop = OutOfPlane(index[0], index[1], index[2], index[3])
                    prim_idx = node1.coord_obj.Prims.dof_index(
                        index, 'OutOfPlane')
                    oopt = i[5]
                    oopv = oop.value(xyz)
                    oop_diff = oopt - oopv * 180. / np.pi
                    if oop_diff > 180.:
                        oop_diff -= 360.
                    elif oop_diff < -180.:
                        oop_diff += 360.
                    ictan[prim_idx] = -oop_diff * np.pi / 180.

                    if oop_diff * np.pi / 180. > 0.1 or oop_diff * np.pi / 180. < 0.1:
                        bdist += np.dot(ictan[prim_idx], ictan[prim_idx])
                    if print_level > 0:
                        print((
                            " current oopv: %4.3f align to %4.3f diff(deg): %4.3f"
                            % (oopv * 180. / np.pi, oopt, oop_diff)))

            bdist = np.sqrt(bdist)
            if np.all(ictan == 0.0):
                raise RuntimeError(" All elements are zero")
            return ictan, bdist
示例#5
0
    def __init__(self, options):

        super(OpenMM, self).__init__(options)

        # get simulation from options if it exists
        #self.options['job_data']['simulation'] = self.options['job_data'].get('simulation',None)
        self.simulation = self.options['job_data'].get('simulation', None)

        if self.lot_inp_file is not None and self.simulation is None:

            # Now go through the logic of determining which FILE options are activated.
            self.file_options.set_active('use_crystal', False, bool,
                                         "Use crystal unit parameters")
            self.file_options.set_active(
                'use_pme', False, bool, '',
                "Use particle mesh ewald-- requires periodic boundary conditions"
            )
            self.file_options.set_active('cutoff',
                                         1.0,
                                         float,
                                         '',
                                         depend=(self.file_options.use_pme),
                                         msg="Requires PME")
            self.file_options.set_active('prmtopfile', None, str,
                                         "parameter file")
            self.file_options.set_active('inpcrdfile', None, str,
                                         "inpcrd file")
            self.file_options.set_active('restrain_torfile', None, str,
                                         "list of torsions to restrain")
            self.file_options.set_active('restrain_tranfile', None, str,
                                         "list of translations to restrain")

            for line in self.file_options.record():
                print(line)

            # set all active values to self for easy access
            for key in self.file_options.ActiveOptions:
                setattr(self, key, self.file_options.ActiveOptions[key])

            nifty.printcool(" Options for OpenMM")
            for val in [self.prmtopfile, self.inpcrdfile]:
                assert val != None, "Missing prmtop or inpcrdfile"

            # Integrator will never be used (Simulation requires one)
            integrator = openmm.VerletIntegrator(1.0)

            # create simulation object
            if self.use_crystal:
                crystal = load_file(self.prmtopfile, self.inpcrdfile)
                if self.use_pme:
                    system = crystal.createSystem(
                        nonbondedMethod=openmm_app.PME,
                        nonbondedCutoff=self.cutoff * openmm_units.nanometer,
                    )
                else:
                    system = crystal.createSystem(
                        nonbondedMethod=openmm_app.NoCutoff, )

                # Torsion restraint
                if self.restrain_torfile is not None:
                    nifty.printcool(" Adding torsional restraints!")

                    # Harmonic constraint
                    tforce = openmm.CustomTorsionForce(
                        "0.5*k*min(dtheta, 2*pi-dtheta)^2; dtheta = abs(theta-theta0); pi = 3.1415926535"
                    )
                    tforce.addPerTorsionParameter("k")
                    tforce.addPerTorsionParameter("theta0")
                    system.addForce(tforce)

                    xyz = manage_xyz.xyz_to_np(self.geom)
                    with open(self.restrain_torfile, 'r') as input_file:
                        for line in input_file:
                            columns = line.split()
                            a = int(columns[0])
                            b = int(columns[1])
                            c = int(columns[2])
                            d = int(columns[3])
                            k = float(columns[4])
                            dih = Dihedral(a, b, c, d)
                            theta0 = dih.value(xyz)
                            tforce.addTorsion(a, b, c, d, [k, theta0])

                # Translation restraint
                if self.restrain_tranfile is not None:
                    nifty.printcool(" Adding translational restraints!")
                    trforce = openmm.CustomExternalForce(
                        "k*periodicdistance(x, y, z, x0, y0, z0)^2")
                    trforce.addPerParticleParameter("k")
                    trforce.addPerParticleParameter("x0")
                    trforce.addPerParticleParameter("y0")
                    trforce.addPerParticleParameter("z0")
                    system.addForce(trforce)

                    xyz = manage_xyz.xyz_to_np(self.geom)
                    with open(self.restrain_tranfile, 'r') as input_file:
                        for line in input_file:
                            columns = line.split()
                            a = int(columns[0])
                            k = float(columns[1])
                            x0 = xyz[a, 0] * 0.1  # Units are in nm
                            y0 = xyz[a, 1] * 0.1  # Units are in nm
                            z0 = xyz[a, 2] * 0.1  # Units are in nm
                            trforce.addParticle(a, [k, x0, y0, z0])

                self.simulation = openmm_app.Simulation(
                    crystal.topology, system, integrator)
                # set the box vectors
                inpcrd = openmm_app.AmberInpcrdFile(self.inpcrdfile)
                if inpcrd.boxVectors is not None:
                    print(" setting box vectors")
                    print(inpcrd.boxVectors)
                    self.simulation.context.setPeriodicBoxVectors(
                        *inpcrd.boxVectors)
            else:  # Do not use crystal parameters
                prmtop = openmm_app.AmberPrmtopFile(self.prmtopfile)
                if self.use_pme:
                    system = prmtop.createSystem(
                        nonbondedMethod=openmm_app.PME,
                        nonbondedCutoff=self.cutoff * openmm_units.nanometer,
                    )
                else:
                    system = prmtop.createSystem(
                        nonbondedMethod=openmm_app.NoCutoff, )

                # Torsion restraint
                if self.restrain_torfile is not None:
                    nifty.printcool(" Adding torsional restraints!")

                    # Harmonic constraint
                    tforce = openmm.CustomTorsionForce(
                        "0.5*k*min(dtheta, 2*pi-dtheta)^2; dtheta = abs(theta-theta0); pi = 3.1415926535"
                    )
                    tforce.addPerTorsionParameter("k")
                    tforce.addPerTorsionParameter("theta0")
                    system.addForce(tforce)

                    xyz = manage_xyz.xyz_to_np(self.geom)
                    with open(self.restrain_torfile, 'r') as input_file:
                        for line in input_file:
                            columns = line.split()
                            a = int(columns[0])
                            b = int(columns[1])
                            c = int(columns[2])
                            d = int(columns[3])
                            k = float(columns[4])
                            dih = Dihedral(a, b, c, d)
                            theta0 = dih.value(xyz)
                            tforce.addTorsion(a, b, c, d, [k, theta0])

                # Translation restraint
                if self.restrain_tranfile is not None:
                    nifty.printcool(" Adding translational restraints!")
                    trforce = openmm.CustomExternalForce(
                        "k*distance(x, y, z, x0, y0, z0)^2")
                    trforce.addPerParticleParameter("k")
                    trforce.addPerParticleParameter("x0")
                    trforce.addPerParticleParameter("y0")
                    trforce.addPerParticleParameter("z0")
                    system.addForce(trforce)

                    xyz = manage_xyz.xyz_to_np(self.geom)
                    with open(self.restrain_tranfile, 'r') as input_file:
                        for line in input_file:
                            columns = line.split()
                            a = int(columns[0])
                            k = float(columns[1])
                            x0 = xyz[a, 0] * 0.1  # Units are in nm
                            y0 = xyz[a, 1] * 0.1  # Units are in nm
                            z0 = xyz[a, 2] * 0.1  # Units are in nm
                            trforce.addParticle(a, [k, x0, y0, z0])

                self.simulation = openmm_app.Simulation(
                    prmtop.topology,
                    system,
                    integrator,
                )