Esempio n. 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()
Esempio n. 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
Esempio n. 3
0
    def check_for_reaction_g(self, rtype, driving_coords):
        '''
        '''

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

        if (nadds + nbreaks) < 1:
            return False
        nadded = 0
        nbroken = 0
        nnR = self.nR - 1
        xyz = self.nodes[nnR].xyz
        atoms = self.nodes[nnR].atoms

        for i in driving_coords:
            if "ADD" in i:
                index = [i[1] - 1, i[2] - 1]
                bond = Distance(index[0], index[1])
                d = bond.value(xyz)
                d0 = (atoms[index[0]].vdw_radius +
                      atoms[index[1]].vdw_radius) / 2
                if d < d0:
                    nadded += 1
            if "BREAK" in i:
                index = [i[1] - 1, i[2] - 1]
                bond = Distance(index[0], index[1])
                d = bond.value(xyz)
                d0 = (atoms[index[0]].vdw_radius +
                      atoms[index[1]].vdw_radius) / 2
                if d > d0:
                    nbroken += 1
        if rtype == 1:
            if (nadded + nbroken) >= (nadds + nbreaks):
                isrxn = True
                #isrxn=nadded+nbroken
        else:
            isrxn = True
            #isrxn=nadded+nbroken
        print(" check_for_reaction_g isrxn: %r nadd+nbrk: %i" %
              (isrxn, nadds + nbreaks))
        return isrxn
Esempio n. 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