Example #1
0
    def __init__(self, topologies):
        """
        Initializes an OBC1 object.

        Parameters
        ----------
        topologies : a Topology object or list[Topology object]
            The molecular topology representation to write as a
            Impact template
        """
        # Not implemented in PELE
        logger = Logger()
        logger.warning('OBC1 is not implemented in PELE')

        super().__init__(topologies)
Example #2
0
    def _build(self):
        """The topology builder."""

        # In case the molecule has not been initialized
        if (self.molecule.rdkit_molecule is None
                or len(list(self.parameters.atom_iterator)) == 0):
            logger = Logger()
            logger.warning('Warning: the input molecule has not been ' +
                           ' initialized and its topology will be empty')
            return

        self._build_atoms()
        self._build_bonds()
        self._build_angles()
        self._build_propers()
        self._build_impropers()
Example #3
0
    def _pdb_checkup(self, path):
        """
        Safety check for PDB files in order to properly handle exceptions
        related with its format prior running the parser.

        Parameters
        ----------
        path : str
            The path to a PDB with the molecule structure
        """

        # Parse PDB file
        atom_id, res_name, res_id = ([] for i in range(3))
        connectivity = False
        with open(path) as pdb_file:
            for line in pdb_file:
                if line.startswith('ATOM') or line.startswith('HETATM'):
                    atom_id.append(line[12:16])
                    res_name.append(line[17:20])
                    res_id.append(line[22:26])
                if line.startswith('CONECT'):
                    connectivity = True

        # Handle exceptions related with the PDB file format
        if not res_id[:-1] == res_id[1:]:
            raise Exception(
                'A single ligand with immutable residue ids is expected')
        if not res_name[:-1] == res_name[1:]:
            raise Exception(
                'A single ligand with immutable residue names is expected')
        if not len(atom_id) == len(set(atom_id)):
            raise Exception('Ligand in input PDB has no unique atom names')
        if not connectivity and self.connectivity_template is None:
            log = Logger()
            log.warning(
                "Warning: input PDB has no information about the " +
                "connectivity and this could result in an unexpected " +
                "bond assignment")
Example #4
0
    def _extract_molecules_from_chain(self, chain, rotamer_resolution,
                                      exclude_terminal_rotamers,
                                      allow_undefined_stereo,
                                      core_constraints):
        """
        It extracts all hetero molecules found in the selected the chain
        of a PDB file.

        Parameters
        ----------
        chain_id : str
            Chain ID.
        rotamer_resolution : float
            The resolution in degrees to discretize the rotamer's
            conformational space. Default is 30
        exclude_terminal_rotamers : bool
            Whether to exclude terminal rotamers when generating the
            rotamers library  or not
        allow_undefined_stereo : bool
            Whether to allow a molecule with undefined stereochemistry
            to be defined or try to assign the stereochemistry and
            raise a complaint if not possible. Default is False
        core_constraints : list[int or str]
            It defines the list of atoms to constrain in the core, thus,
            the core will be forced to contain them. Atoms can be specified
            through integers that match the atom index or strings that
            match with the atom PDB name

        Returns
        -------
        molecules : list[peleffy.topology.Molecule object]
            Selected molecules
        """
        from peleffy.topology.molecule import Molecule

        # Check if there is more than one hetero molecule in the same chain
        residues_ids = set([
            line[22:26].strip() for line in self.pdb_content
            if line.startswith('HETATM') and line[21:22] == chain
            and not line[17:20].strip() == 'HOH'
        ])

        molecules = []
        for residue_id in residues_ids:
            res_name = set([
                line[17:20].strip() for line in self.pdb_content
                if line.startswith('HETATM') and line[21:22] == chain
                and line[22:26].strip() == residue_id
            ])

            # Select which atoms compose this hetero molecule
            atom_ids = [
                line[6:11].strip() for line in self.pdb_content
                if line.startswith('HETATM') and line[21:22] == chain
                and line[22:26].strip() == residue_id
            ]

            # Extract the PDB block of the molecule
            pdb_block = [
                line for line in self.pdb_content
                if (line.startswith('HETATM') or line.startswith('CONECT'))
                and any(' {} '.format(a) in line for a in atom_ids)
            ]

            try:
                molecules.append(
                    Molecule(
                        pdb_block=''.join(pdb_block),
                        rotamer_resolution=rotamer_resolution,
                        exclude_terminal_rotamers=exclude_terminal_rotamers,
                        allow_undefined_stereo=allow_undefined_stereo,
                        core_constraints=core_constraints))
            except Exception as e:
                log = Logger()
                log.warning(' - Skipping {} '.format(list(res_name)[0]) +
                            'from chain {}'.format(chain))
                log.warning('  - The following exception was raised: ' +
                            '{}'.format(e))

        return molecules
Example #5
0
    def _read_and_fix_pdb(self, path):
        """
        It reads the input PDB file returns the corresponding PDB block.
        It also applies some modifications, in case it requires some
        fixing prior running the parser.

        Parameters
        ----------
        path : str
            The path to a PDB with the molecule structure

        Returns
        -------
        pdb_block : str
            The corresponding PDB block, with applied fixes if required
        """
        log = Logger()

        # Skip PDB fixing if it has been deactivated
        if not self.fix_pdb:
            with open(path) as pdb_file:
                pdb_block = pdb_file.read()

            return pdb_block

        # Fix PDB
        missing_element = False
        any_fail = False
        pdb_block = ''
        with open(path) as pdb_file:
            for line in pdb_file:
                if line.startswith('ATOM') or line.startswith('HETATM'):
                    if len(line) < 78 or line[76:78] == '  ':
                        missing_element = True
                        atom_name = line[12:16]
                        # Try to infer element from atom name
                        inferred_element = ''.join([
                            c for c in atom_name
                            if not c.isdigit() and c != ' '
                        ])

                        # Format properly the element identifier
                        if len(inferred_element) == 1:
                            inferred_element = inferred_element.upper()
                        elif len(inferred_element) == 2:
                            inferred_element = inferred_element[0].upper() + \
                                inferred_element[1].lower()
                        else:
                            # We were expecting an element identifier of 1 or 2 chars
                            any_fail = True
                            break

                        # Remove line breaks, if any
                        line = line.strip()

                        # Fill a short line with white spaces
                        while (len(line) < 79):
                            line += ' '

                        # Add element to line (right-justified)
                        line = line[:76] + '{:>2s}'.format(inferred_element) \
                            + line[79:] + '\n'

                pdb_block += line

        if missing_element:
            log.warning("Warning: input PDB has no information about atom " +
                        "elements and they were inferred from atom names. " +
                        "Please, verify that the resulting elements are " +
                        "correct")

        if any_fail:
            log.error("Error: PDB could not be fixed")
            with open(path) as pdb_file:
                pdb_block = pdb_file.read()

        return pdb_block