def _decode_atom(self, obj):
     kwargs = {}
     for key in ["element", "coords", "flag", "name", "tags"]:
         kwargs[key] = obj[key]
     rv = Atom(**kwargs)
     rv._rank = obj["_rank"]
     return rv
Exemple #2
0
    def __init__(self, filename, get_all=False, just_geom=True):
        """
        :filename: a file name or a tuple(file_name, file_extension, IOstream)
        :get_all: if true, optimization steps are  also saved in
            self.other['all_geom']; otherwise only saves last geometry
        :just_geom: if true, does not store other information, such as
            frequencies, only what is needed to construct a Geometry() obj
        """
        if isinstance(filename, str):
            self.name, self.file_ext = filename.rsplit('.', 1)
        else:
            self.name, self.file_ext = filename[:2]
            filename = filename[2]
        self.file_type = ''
        self.comment = ''
        self.atoms = []
        self.all_geom = None
        self.other = {}

        try:
            parser = cclib.io.ccopen(filename)
            data = parser.parse()
            self.file_type = str(parser).split()[0].split('.')[-1]
            self.other = data.__dict__
        except AttributeError:
            if self.file_ext == 'com':
                self.file_type = 'Gaussian'
                self.read_com(filename)
                return

        for key in self.other:
            print(key)
            print(self.other[key])
        for i, (n, c) in enumerate(zip(data.atomnos, data.atomcoords[-1])):
            self.atoms += [Atom(element=ELEMENTS[n], coords=c, name=i + 1)]
        if len(data.atomcoords) == 1:
            # if > 1, there are more geometries to handle
            del self.other['atomnos']
            del self.other['atomcoords']
        elif get_all:
            # only handle them if get_all is true
            self.all_geom = []
            for i, coords in enumerate(data.atomcoords[:-1]):
                atoms = []
                for j, (n, c) in enumerate(zip(data.atomnos, coords)):
                    self.atoms += [
                        Atom(element=ELEMENTS[n], coords=c, name=j + 1)
                    ]
                self.all_geoms += [atoms]
        # cclib doesn't store XYZ file comments
        if self.file_type == 'XYZ':
            self.read_xyz(filename)
        # Grab things cclib doesn't from log files
        if self.file_type == 'Gaussian' and self.file_ext == 'log':
            self.read_log(filename)
        # fix naming conventions
        self.other = self.fix_names(self.other)
        return
Exemple #3
0
    def new_atom(self):
        element = ChangeElementMouseMode.element
        adjust_bonds = True
        vsepr = ChangeElementMouseMode.vsepr

        if vsepr == "do not change":
            vsepr = False
        elif vsepr == "linear (1 bond)":
            vsepr = "linear 1"
        elif vsepr == "linear (2 bonds)":
            vsepr = "linear 2"
        elif vsepr == "trigonal planar (2 bonds)":
            vsepr = "bent 2 planar"
        elif vsepr == "tetrahedral (2 bonds)":
            vsepr = "bent 2 tetrahedral"
        elif vsepr == "tetrahedral (3 bonds)":
            vsepr = "bent 3 tetrahedral"

        if vsepr:
            atoms = Atom.get_shape(vsepr)
            atoms[0].element = element
            for atom in atoms[1:]:
                atom.element = "H"
            if adjust_bonds:
                # this works b/c all atoms are 1 angstrom from the center
                # just multiply by the distance we want
                expected_dist = RADII[element] + RADII["H"]
                for atom in atoms[1:]:
                    atom.coords *= expected_dist
            for atom in atoms[1:]:
                atoms[0].connected.add(atom)
                atom.connected.add(atoms[0])
        else:
            atoms = [Atom(element=element, coords=np.zeros(3))]

        rescol = ResidueCollection(atoms, name="new", refresh_connected=False)
        rescol.coord_shift(self._coords)

        model = self.model_selector.currentData()
        if model is None:
            chix = rescol.get_chimera(self.session)
            self.session.models.add([chix])
            apply_seqcrow_preset(chix, fallback="Ball-Stick-Endcap")

        else:
            res = model.new_residue("new", "a", len(model.residues) + 1)
            rescol.residues[0].update_chix(res)
            run(
                self.session, "select add %s" %
                " ".join([atom.atomspec for atom in res.atoms]))

        self.delete()
Exemple #4
0
    def gaussian_input_from_dict(cls, json_dict, fname=None):
        """write gaussian input file to fname using info in dict
        any keys (self.GAUSSIAN_*) should be strings instead of integers"""
        s = ""

        s += json_dict['header']

        if json_dict['geometry'] is not None:
            atoms = []
            for atom in json_dict['geometry']:
                atom_info = atom.split()
                atoms.append(Atom(element=atom_info[0], coords=[float(x) for x in atom_info[1:]]))
            
            geometry = Geometry(atoms)

            for atom in geometry.atoms:
                s += "%-2s %13.6f %13.6f %13.6f\n" % (atom.element, *atom.coords)

        s += json_dict['footer']

        if fname is not None:
            with open(fname, "w") as f:
                f.write(s)

        return s
Exemple #5
0
 def read_xyz(self, f, get_all=False):
     self.all_geom = []
     # number of atoms
     f.readline()
     # comment
     self.comment = f.readline().strip()
     # atom info
     for line in f:
         line = line.strip()
         if line == "":
             continue
         try:
             int(line)
             if get_all:
                 self.all_geom += [
                     (deepcopy(self.comment), deepcopy(self.atoms))
                 ]
             self.comment = f.readline().strip()
             self.atoms = []
         except ValueError:
             line = line.split()
             self.atoms += [Atom(element=line[0], coords=line[1:4])]
             for i, a in enumerate(self.atoms):
                 a.name = str(i + 1)
     if get_all:
         self.all_geom += [(deepcopy(self.comment), deepcopy(self.atoms))]
Exemple #6
0
 def grab_coords(line):
     rv = {}
     for i, word in enumerate(line.split('\\')):
         word = word.split(',')
         if i == 0:
             rv['charge'] = int(word[0])
             rv['multiplicity'] = int(word[1])
             rv['atoms'] = []
             continue
         rv['atoms'] += [Atom(element=word[0],
                              coords=word[1:4], name=str(i))]
     return rv
Exemple #7
0
 def grab_coords(line):
     rv = {}
     for i, word in enumerate(line.split("\\")):
         word = word.split(",")
         if i == 0:
             rv["charge"] = int(word[0])
             rv["multiplicity"] = int(word[1])
             rv["atoms"] = []
             continue
         rv["atoms"] += [
             Atom(element=word[0], coords=word[1:4], name=str(i))
         ]
     return rv
Exemple #8
0
def main(args):
    geom_patt = re.compile("([A-Z][a-z]*)((?:\s+-?\d+\.?\d*){3})")
    float_patt = re.compile("-?\d+\.?\d*")

    all_names = []
    atoms = []
    name = None
    for i, page in enumerate(extract_pages(args.infile)):
        print("parsing page {: 4d} please wait...".format(i + 1), end="\r")
        for element in page:
            last_line = None
            if hasattr(element, "get_text"):
                for line in element:
                    text = line.get_text()
                    match = geom_patt.search(text)
                    if not match and last_line and atoms:
                        name_match = geom_patt.search(name)
                        if name_match:
                            geom = Geometry(all_names[-1] + ".xyz")
                            geom.atoms.extend(atoms)
                        else:
                            geom = Geometry(atoms)
                            geom.name = name
                            geom.comment = name
                            if args.directory != "CURRENTDIR":
                                geom.name = os.path.join(
                                    args.directory, geom.name)
                            orig_name = geom.name
                            i = 2
                            while geom.name in all_names:
                                geom.name = "{}_{:03d}".format(orig_name, i)
                                i += 1
                        if args.sort:
                            geom.refresh_connected()
                            geom.refresh_ranks()
                            geom.atoms = geom.reorder()[0]
                        geom.write()
                        all_names.append(geom.name)
                        atoms = []
                        name = None
                        # print()
                        # print(geom.name, len(geom.atoms))
                        # print(geom)
                    if match:
                        if not name:
                            name = last_line
                        element = match.group(1)
                        coords = float_patt.findall(match.group(2))
                        atoms.append(Atom(element, [float(c) for c in coords]))
                    last_line = text.strip()
Exemple #9
0
    def test_refresh_connected(self):
        # refresh_connected should be run upon creation
        mol = Geometry(TestGeometry.benz_NO2_Cl)
        conn_valid = TestGeometry.benz_NO2_Cl_conn
        for a, b in zip(mol.atoms, conn_valid):
            tmpa = [int(c.name) for c in a.connected]
            tmpb = [int(c) for c in b]
            self.assertSequenceEqual(sorted(tmpa), sorted(tmpb))

        # old connectivity shouldn't remain in the set
        mol.atoms[0].connected.add(Atom())
        old = mol.atoms[0].connected
        mol.refresh_connected()
        self.assertTrue(len(old) - len(mol.atoms[0].connected) == 1)
Exemple #10
0
    def read_sd(self, f, get_all=False):
        self.all_geom = []
        lines = f.readlines()
        self.comment = lines[0]
        counts = lines[3].split()
        natoms = int(counts[0])
        nbonds = int(counts[1])
        self.atoms = []
        for line in lines[4:4+natoms]:
            atom_info = line.split()
            self.atoms += [Atom(element=atom_info[3], coords = atom_info[0:3])]

        for i, a in enumerate(self.atoms):
            a.name = str(i + 1)
Exemple #11
0
 def read_xyz(self, fname):
     mol = []
     with open(fname) as f:
         # split xyz file into info matrix
         tmp = f.read()
         tmp = tmp.split("\n")
         for line in tmp:
             line = line.strip().split()
             if len(line):
                 mol += [line]
         # remove atom number and comment line
         mol = mol[2:]
     atoms = []
     for i, a in enumerate(mol):
         a = Atom(element=a[0], coords=a[1:4], name=(i + 1), tags=i)
         atoms += [a]
     return atoms
Exemple #12
0
 def test_float(self):
     atom_args = [{
         'element': 'H',
         'coords': [0, 0, 0],
         'name': '1'
     }, {
         'element': 'H',
         'coords': [0, 0, 0],
         'name': '1.1'
     }, {
         'element': 'H',
         'coords': [0, 0, 0],
         'name': '1.1.1'
     }]
     atom_floats = [1., 1.1, 1.1]
     for kwarg, ref in zip(atom_args, atom_floats):
         atom = Atom(**kwarg)
         self.assertTrue(float(atom) == ref)
Exemple #13
0
    def test_store_atoms(self):
        atoms_read = self.read_xyz(TestAtoms.small_mol)
        atoms_manual = []
        mol = []
        with open(TestAtoms.small_mol) as f:
            # split xyz file into info matrix
            tmp = f.read()
            tmp = tmp.split("\n")
            for line in tmp:
                line = line.strip().split()
                if len(line):
                    mol += [line]
            # remove atom number and comment line
            mol = mol[2:]
        for i, line in enumerate(mol):
            a = Atom()
            a.element = line[0]
            a.coords = np.array(line[1:4], dtype=float)
            a.flag = False
            a.name = str(i + 1)
            a.tags = set([i])
            atoms_manual += [a]

        # test manual and **kwargs assignment match
        for a, b in zip(atoms_read, atoms_manual):
            self.assertEqual(a.element, b.element)
            self.assertTrue(np.linalg.norm(a.coords - b.coords) < 10**(-8))
            self.assertEqual(a.name, b.name)
            self.assertEqual(a.tags, b.tags)
            # should have automatic lookup of _radii
            self.assertTrue(a._radii is not None)

        # transform back into xyz format for verification
        atom_matrix = []
        for a in atoms_read:
            tmp = [str(a.element)]
            for c in a.coords:
                tmp += ["{:7.5f}".format(c)]
            atom_matrix += [tmp]
        for a, b in zip(mol, atom_matrix):
            a = ' '.join(a)
            b = ' '.join(b)
            self.assertEqual(a, b)

        return
Exemple #14
0
 def get_atoms(f, n):
     rv = []
     self.skip_lines(f, 4)
     line = f.readline()
     n += 5
     while "--" not in line:
         line = line.strip()
         line = line.split()
         for l in line:
             try:
                 float(l)
             except ValueError:
                 msg = "Error detected with log file on line {}"
                 raise IOError(msg.format(n))
         elem = ELEMENTS[int(line[1])]
         flag = not bool(line[2])
         rv += [Atom(element=elem, flag=flag, coords=line[3:])]
         line = f.readline()
         n += 1
     return rv, n
Exemple #15
0
 def test_float(self):
     atom_args = [
         {
             "element": "H",
             "coords": [0, 0, 0],
             "name": "1"
         },
         {
             "element": "H",
             "coords": [0, 0, 0],
             "name": "1.1"
         },
         {
             "element": "H",
             "coords": [0, 0, 0],
             "name": "1.1.1"
         },
     ]
     atom_floats = [1.0, 1.1, 1.1]
     for kwarg, ref in zip(atom_args, atom_floats):
         atom = Atom(**kwarg)
         self.assertTrue(float(atom) == ref)
Exemple #16
0
 def test_bond(self):
     a1 = Atom(element='H', coords=[0, 0, 0])
     a2 = Atom(element='H', coords=[1, 0, 0])
     self.assertTrue(np.linalg.norm(a1.bond(a2) - [1, 0, 0]) == 0)
Exemple #17
0
 def read_com(self, f):
     found_atoms = False
     found_constraint = False
     atoms = []
     other = {}
     for line in f:
         # header
         if line.startswith("%"):
             continue
         if line.startswith("#"):
             method = re.search("^#([NnPpTt]\s+?)(\S+)|^#\s*?(\S+)", line)
             #route can be #n functional/basis ...
             #or #functional/basis ...
             #or # functional/basis ...
             if method.group(3):
                 other['method'] = method.group(3)
             else:
                 other['method'] = method.group(2)
             if "temperature=" in line:
                 other["temperature"] = re.search(
                     "temperature=(\d+\.?\d*)", line
                 ).group(1)
             if "solvent=" in line:
                 other["solvent"] = re.search(
                     "solvent=(\S+)\)", line
                 ).group(1)
             if "scrf=" in line:
                 other["solvent_model"] = re.search(
                     "scrf=\((\S+),", line
                 ).group(1)
             if "EmpiricalDispersion=" in line:
                 other["emp_dispersion"] = re.search(
                     "EmpiricalDispersion=(\S+)", line
                 ).group(1)
             if "int=(grid(" in line:
                 other["grid"] = re.search("int=\(grid(\S+)", line).group(1)
             for _ in range(4):
                 line = f.readline()
             line = line.split()
             other["charge"] = line[0]
             other["mult"] = line[1]
             found_atoms = True
             continue
         # constraints
         if found_atoms and line.startswith("B") and line.endswith("F"):
             found_constraint = True
             if "constraint" not in other:
                 other["constraint"] = []
             other["constraint"] += [float_num.findall(line)]
             continue
         # footer
         if found_constraint:
             if "footer" not in other:
                 other["footer"] = ""
             other["footer"] += line
             continue
         # atom coords
         nums = float_num.findall(line)
         line = line.split()
         if len(line) == 5 and is_alpha(line[0]) and len(nums) == 4:
             if not is_int(line[1]):
                 continue
             a = Atom(element=line[0], coords=nums[1:], flag=nums[0])
             atoms += [a]
         elif len(line) == 4 and is_alpha(line[0]) and len(nums) == 3:
             a = Atom(element=line[0], coords=nums)
             atoms += [a]
         else:
             continue
     self.atoms = atoms
     self.other = other
     return
Exemple #18
0
 def test_set_radii(self):
     atom = Atom("H", [0, 0, 0])
     self.assertEqual(atom._radii, 0.32)
     atom = Atom("X", [0, 0, 0])  # ghost atom
     self.assertEqual(atom._radii, 0.0)
     with self.assertRaises(ValueError):
         atom = Atom("NotAnElement", [0, 0, 0])
     atom = Atom()
     atom.element = "NotAnElement"
     with self.assertLogs(logger=Atom.LOG, level="WARNING"):
         atom._set_radii()
Exemple #19
0
    def read_com(self, filename):
        if isinstance(filename, str):
            f = open(filename)
        else:
            f = filename

        atoms = []
        other = {}
        found_atoms = False
        found_constraint = False
        for line in f:
            # header
            if line.startswith('%'):
                # checkfile spec
                other['checkfile'] = line.strip().split('=')[1]
                continue
            if line.startswith('#'):
                match = re.search('^#(\S+)', line).group(1)
                other['method'] = match.split('/')[0]
                other['basis'] = match.split('/')[1]
                if 'temperature=' in line:
                    other['temperature'] = re.search('temperature=(\d+\.?\d*)',
                                                     line).group(1)
                if 'solvent=' in line:
                    other['solvent'] = re.search('solvent=(\S+)\)',
                                                 line).group(1)
                if 'scrf=' in line:
                    other['solvent_model'] = re.search('scrf=\((\S+),',
                                                       line).group(1)
                if 'EmpiricalDispersion=' in line:
                    other['emp_dispersion'] = re.search(
                        'EmpiricalDispersion=(\s+)', line).group(1)
                if 'int=(grid(' in line:
                    other['grid'] = re.search('int=\(grid(\S+)', line).group(1)
                for _ in range(4):
                    line = f.readline()
                line = line.split()
                other['charge'] = line[0]
                other['mult'] = line[1]
                found_atoms = True
                continue

            # constraints
            if found_atoms and line.startswith('B') and line.endswith('F'):
                found_constraint = True
                if 'constraint' not in other:
                    other['constraint'] = []
                other['constraint'] += [float_num.findall(line)]
                continue

            # footer
            if found_constraint:
                if 'footer' not in other:
                    other['footer'] = ''
                other['footer'] += line
                continue

            # atom coords
            nums = float_num.findall(line)
            line = line.split()
            if len(line) == 5 and is_alpha(line[0]) and len(nums) == 4:
                if not is_int(line[1]):
                    continue
                a = Atom(element=line[0], coords=nums[1:], flag=nums[0])
                atoms += [a]
            elif len(line) == 4 and is_alpha(line[0]) and len(nums) == 3:
                a = Atom(element=line[0], coords=nums)
                atoms += [a]
            else:
                continue

        self.atoms = atoms
        self.other = other
        return
Exemple #20
0
    def sterimol(self,
                 return_vector=False,
                 radii="bondi",
                 old_L=False,
                 **kwargs):
        """
        returns sterimol parameter values in a dictionary
        keys are B1, B2, B3, B4, B5, and L
        see Verloop, A. and Tipker, J. (1976), Use of linear free energy
        related and other parameters in the study of fungicidal
        selectivity. Pestic. Sci., 7: 379-390.
        (DOI: 10.1002/ps.2780070410)

        return_vector: bool/returns dict of tuple(vector start, vector end) instead
        radii: "bondi" - Bondi vdW radii
               "umn"   - vdW radii from Mantina, Chamberlin, Valero, Cramer, and Truhlar
        old_L: bool - True: use original L (ideal bond length between first substituent
                            atom and hydrogen + 0.40 angstrom
                      False: use AaronTools definition

        AaronTools' definition of the L parameter is different than the original
        STERIMOL program. In STERIMOL, the van der Waals radii of the substituent is
        projected onto a plane parallel to the bond between the molecule and the substituent.
        The L parameter is 0.40 Å plus the distance from the first substituent atom to the
        outer van der Waals surface of the projection along the bond vector. This 0.40 Å is
        a correction for STERIMOL using a hydrogen to represent the molecule, when a carbon
        would be more likely. In AaronTools the substituent is projected the same, but L is
        calculated starting from the van der Waals radius of the first substituent atom
        instead. This means AaronTools will give the same L value even if the substituent
        is capped with something besides a hydrogen. When comparing AaronTools' L values
        with STERIMOL (using the same set of radii for the atoms), the values usually
        differ by < 0.1 Å.
        """
        from AaronTools.finders import BondedTo

        CITATION = "doi:10.1002/ps.2780070410"
        self.LOG.citation(CITATION)

        if self.end is None:
            raise RuntimeError(
                "cannot calculate sterimol values for substituents without end"
            )

        atom1 = self.find(BondedTo(self.end))[0]
        atom2 = self.end

        if isinstance(radii, dict):
            radii_dict = radii
        elif radii.lower() == "bondi":
            radii_dict = BONDI_RADII
        elif radii.lower() == "umn":
            radii_dict = VDW_RADII

        if old_L:
            from AaronTools.atoms import Atom, BondOrder
            bo = BondOrder
            key = bo.key(atom1, Atom(element="H"))
            dx = bo.bonds[key]["1.0"] + 0.4

            def L_func(atom, start, radius, L_axis, dx=dx, atom1=atom1):
                test_v = start.bond(atom)
                test_L = (np.dot(test_v, L_axis) - start.dist(atom1) + dx +
                          radius)
                start_x = atom1.coords - dx * L_axis
                L_vec = (start_x, start_x + test_L * L_axis)
                return test_L, L_vec

        else:
            r1 = radii_dict[atom1.element]

            def L_func(atom, start, radius, L_axis, atom1=atom1, r1=r1):
                test_v = start.bond(atom)
                test_L = (np.dot(test_v, L_axis) - start.dist(atom1) + r1 +
                          radius)
                start_x = atom1.coords - r1 * L_axis
                L_vec = (start_x, start_x + test_L * L_axis)
                return test_L, L_vec

        L_axis = atom2.bond(atom1)
        L_axis /= np.linalg.norm(L_axis)

        return super().sterimol(
            L_axis,
            atom2,
            self.atoms,
            L_func=L_func,
            return_vector=return_vector,
            radii=radii,
            **kwargs,
        )
Exemple #21
0
    def do_change_element(self):
        element = self.element.text()
        adjust_bonds = self.change_bonds.isChecked()
        self.settings.change_bonds = adjust_bonds
        vsepr = self.vsepr.currentText()
        
        if vsepr == "do not change":
            vsepr = False
        elif vsepr == "linear (1 bond)":
            vsepr = "linear 1"
            goal = 1
        elif vsepr == "linear (2 bonds)":
            vsepr = "linear 2"
            goal = 2
        elif vsepr == "trigonal planar (2 bonds)":
            vsepr = "bent 2 planar"
            goal = 2
        elif vsepr == "tetrahedral (2 bonds)":
            vsepr = "bent 2 tetrahedral"
            goal = 2
        elif vsepr == "trigonal planar":
            goal = 3
        elif vsepr == "tetrahedral (3 bonds)":
            vsepr = "bent 3 tetrahedral"
            goal = 3
        else:
            goal = len(Atom.get_shape(vsepr)) - 1
        
        sel = selected_atoms(self.session)
        models, _ = guessAttachmentTargets(sel, self.session, allow_adjacent=False)
        for model in models:
            conv_res = list(models[model].keys())
            for res in models[model]:
                for target in models[model][res]:
                    for neighbor in target.neighbors:
                        if neighbor.residue not in conv_res:
                            conv_res.append(neighbor.residue)
            
                    for pbg in self.session.models.list(type=PseudobondGroup):
                        for pbond in pbg.pseudobonds:
                            if target in pbond.atoms and all(atom.structure is model for atom in pbond.atoms):
                                other_atom = pbond.other_atom(target)
                                if other_atom.residue not in conv_res:
                                    conv_res.append(other_atom.residue)
            
            rescol = ResidueCollection(model, convert_residues=conv_res)
            for res in models[model]:
                residue = [resi for resi in rescol.residues if resi.chix_residue is res][0]
                
                for target in models[model][res]:
                    targ = rescol.find_exact(AtomSpec(target.atomspec))[0]
                    adjust_hydrogens = vsepr
                    if vsepr is not False:
                        cur_bonds = len(targ.connected)
                        change_Hs = goal - cur_bonds
                        adjust_hydrogens = (change_Hs, vsepr)

                    residue.change_element(targ, 
                                           element, 
                                           adjust_bonds=adjust_bonds, 
                                           adjust_hydrogens=adjust_hydrogens,
                    )
                
                residue.update_chix(res)    
Exemple #22
0
    def mouse_up(self, event):
        if event.shift_down():
            _ElementPicker(self.session, "pick element")
            return

        if not self.element:
            self.session.logger.warning(
                "no element selected; shift-click to set element")
            self.session.logger.status(
                "no element selected; shift-click to set element")
            _ElementPicker(self.session, "pick element")
            return

        x, y = event.position()
        pick = self.view.picked_object(x, y)

        if not pick:
            x1, x2 = self.session.main_view.clip_plane_points(x, y)
            coords = (x1 + x2) / 2
            new_fragment = _ModelSelector(self.session, "place atom in model",
                                          coords)
            if new_fragment.model_selector.count() == 1:
                new_fragment.new_atom()
            return

        # import cProfile
        #
        # profile = cProfile.Profile()
        # profile.enable()

        vsepr = self.vsepr

        if vsepr == "do not change":
            vsepr = False
        elif vsepr == "linear (1 bond)":
            vsepr = "linear 1"
            goal = 1
        elif vsepr == "linear (2 bonds)":
            vsepr = "linear 2"
            goal = 2
        elif vsepr == "trigonal planar (2 bonds)":
            vsepr = "bent 2 planar"
            goal = 2
        elif vsepr == "tetrahedral (2 bonds)":
            vsepr = "bent 2 tetrahedral"
            goal = 2
        elif vsepr == "trigonal planar":
            goal = 3
        elif vsepr == "tetrahedral (3 bonds)":
            vsepr = "bent 3 tetrahedral"
            goal = 3
        elif vsepr == "tetrahedral":
            goal = 4
        else:
            goal = len(Atom.get_shape(vsepr)) - 1

        if not isinstance(pick, PickedAtom):
            return

        atom = pick.atom
        # # use built-in ChimeraX command for some of the more common things
        # # because it's faster for proteins
        # if False:
        #     run(
        #         self.session,
        #         "build modify %s %s %i geometry %s" % (
        #             atom.atomspec,
        #             self.element,
        #             goal,
        #             vsepr,
        #         )
        #     )
        #

        frags = []
        for neighbor in atom.neighbors:
            frags.append(
                get_fragment(neighbor,
                             stop=atom,
                             max_len=atom.structure.num_atoms))

        residues = [atom.residue]
        hold_steady = None
        for i, frag in enumerate(sorted(frags, key=len)):
            if i == len(frags) - 1:
                hold_steady = AtomSpec(frag[0].atomspec)
                residues.append(frag[0].residue)
                continue
            residues.extend(frag.residues)

        rescol = ResidueCollection(atom.structure,
                                   convert_residues=set(residues),
                                   refresh_ranks=False)
        res = [
            residue for residue in rescol.residues
            if residue.chix_residue is atom.residue
        ][0]
        target = res.find_exact(AtomSpec(atom.atomspec))[0]
        adjust_hydrogens = vsepr
        if vsepr is not False:
            cur_bonds = len(target.connected)
            change_Hs = goal - cur_bonds
            adjust_hydrogens = (change_Hs, vsepr)

        rescol.change_element(
            target,
            self.element,
            adjust_bonds=True,
            adjust_hydrogens=adjust_hydrogens,
            hold_steady=hold_steady,
        )

        res.update_chix(res.chix_residue,
                        apply_preset=True,
                        refresh_connected=True)
        rescol.update_chix(atom.structure,
                           apply_preset=False,
                           refresh_connected=False)
Exemple #23
0
 def test_set_connectivity(self):
     atom = Atom("H", [0, 0, 0])
     self.assertEqual(atom._connectivity, 1)
     atom = Atom("C", [0, 0, 0])
     self.assertEqual(atom._connectivity, 4)
Exemple #24
0
 def test_repr(self):
     atom = Atom("H", [0, 0, 0], True, "1", ["test"])
     s = repr(atom)
     self.assertEqual(
         s, "  H     0.00000000    0.00000000    0.00000000  -1    1")
Exemple #25
0
 def test_dist(self):
     a1 = Atom(element='H', coords=[0, 0, 0])
     a2 = Atom(element='H', coords=[1, 0, 0])
     self.assertTrue(a1.dist(a2) == 1)
Exemple #26
0
    def read_com(self, filename):
        if isinstance(filename, str):
            f = open(filename)
        else:
            f = filename

        atoms = []
        other = {}
        found_atoms = False
        found_constraint = False
        for line in f:
            # header
            if line.startswith("%"):
                # checkfile spec
                other["checkfile"] = line.strip().split("=")[1]
                continue
            if line.startswith("#"):
                match = re.search("^#(\S+)", line).group(1)
                other["method"] = match.split("/")[0]
                other["basis"] = match.split("/")[1]
                if "temperature=" in line:
                    other["temperature"] = re.search("temperature=(\d+\.?\d*)",
                                                     line).group(1)
                if "solvent=" in line:
                    other["solvent"] = re.search("solvent=(\S+)\)",
                                                 line).group(1)
                if "scrf=" in line:
                    other["solvent_model"] = re.search("scrf=\((\S+),",
                                                       line).group(1)
                if "EmpiricalDispersion=" in line:
                    other["emp_dispersion"] = re.search(
                        "EmpiricalDispersion=(\s+)", line).group(1)
                if "int=(grid(" in line:
                    other["grid"] = re.search("int=\(grid(\S+)", line).group(1)
                for _ in range(4):
                    line = f.readline()
                line = line.split()
                other["charge"] = line[0]
                other["mult"] = line[1]
                found_atoms = True
                continue

            # constraints
            if found_atoms and line.startswith("B") and line.endswith("F"):
                found_constraint = True
                if "constraint" not in other:
                    other["constraint"] = []
                other["constraint"] += [float_num.findall(line)]
                continue

            # footer
            if found_constraint:
                if "footer" not in other:
                    other["footer"] = ""
                other["footer"] += line
                continue

            # atom coords
            nums = float_num.findall(line)
            line = line.split()
            if len(line) == 5 and is_alpha(line[0]) and len(nums) == 4:
                if not is_int(line[1]):
                    continue
                a = Atom(element=line[0], coords=nums[1:], flag=nums[0])
                atoms += [a]
            elif len(line) == 4 and is_alpha(line[0]) and len(nums) == 3:
                a = Atom(element=line[0], coords=nums)
                atoms += [a]
            else:
                continue

        self.atoms = atoms
        self.other = other
        return
Exemple #27
0
if isinstance(args.change_hs, int):
    adjust_hs = args.change_hs
elif args.change_hs is None:
    adjust_hs = True
else:
    adjust_hs = 0

new_vsepr = None
if args.geometry:
    new_vsepr = args.geometry.replace("_", " ")

if adjust_hs == 0 and new_vsepr is None:
    adjust_structure = False
elif adjust_hs == 0 and new_vsepr:
    goal = len(Atom.get_shape(new_vsepr)) - 1
    def goal_func(atom, goal=goal):
        return goal - len(atom.connected)
    adjust_structure = (goal_func, new_vsepr)
elif adjust_hs is True:
    adjust_structure = True
else:
    adjust_structure = (adjust_hs, new_vsepr)

for f in glob_files(args.infile, parser=element_parser):
    if isinstance(f, str):
        if args.input_format is not None:
            infile = FileReader((f, args.input_format, None))
        else:
            infile = FileReader(f)
    else: