Exemple #1
0
def score_with_edstats_to_list(mtz_file, pdb_file, f_label=None):
    """Scores residues against density, then returns list"""

    assert os.path.exists(
        mtz_file), 'MTZ file for edstats does not exist! {!s}'.format(mtz_file)
    assert os.path.exists(
        pdb_file), 'PDB file for edstats does not exist! {!s}'.format(mtz_file)

    # Create a file handle and path for the output
    temp_handle, temp_path = tempfile.mkstemp(suffix='.table',
                                              prefix='edstats_')

    # Collate summary of MTZ file
    m_summ = MtzSummary(mtz_file)

    # Use column labels if given
    if (f_label is not None) and (f_label
                                  not in m_summ.summary['colheadings']):
        raise Sorry(
            'Selected f_label ({}) not found in mtz file ({}) -- mtz contains columns {}'
            .format(f_label, mtz_file, m_summ.summary['colheadings']))
    # else guess the labels in the mtzfile
    else:
        f_label = m_summ.label.f

    # Check for f_label
    if not f_label:
        raise Sorry(
            'No F label selected/found in mtz file: {!s} -- mtz contains columns {}'
            .format(mtz_file, m_summ.summary['colheadings']))

    # Run EDSTATS on the files
    try:
        # Initialise Command Manager to run edstats
        command = CommandManager('edstats.pl')
        command.add_command_line_arguments([
            '-hklin', mtz_file, '-xyzin', pdb_file, '-output', temp_path,
            '-noerror', '-flabel', f_label
        ])
        command.set_timeout(timeout=600)
        command.run()
        # Read the output
        with os.fdopen(temp_handle) as f:
            output = f.read().strip().replace('\r\n',
                                              '\n').replace('\r',
                                                            '\n').splitlines()
        command.file_output = output
    finally:
        os.remove(temp_path)

    # Process the output header
    if output:
        # Check header and then remove the first three columns
        header = output.pop(0).split()
        assert header[:3] == [
            'RT', 'CI', 'RN'
        ], 'edstats output headers are not as expected! {!s}'.format(output)
        num_fields = len(header)
        header = header[3:]
    else:
        header = []

    # List to be returned
    outputdata = []

    # Process the rest of the data
    for line in output:
        line = line.strip()
        if not line:
            continue

        fields = line.split()
        if len(fields) != num_fields:
            raise ValueError(
                "Error Parsing EDSTATS output: Header & Data rows have different numbers of fields"
            )

        # Get and process the residue information - TODO CI column can include alternate conformer?! TODO
        residue, chain, resnum = fields[:3]
        try:
            resnum = int(resnum)
            inscode = ' '
        except ValueError:
            inscode = resnum[-1:]
            resnum = int(resnum[:-1])

        # Remove the processed columns
        fields = fields[3:]

        # Process the other columns (changing n/a to None and value to int)
        for i, x in enumerate(fields):
            if x == 'n/a':
                fields[i] = None
            else:
                try:
                    fields[i] = int(x)
                except ValueError:
                    try:
                        fields[i] = float(x)
                    except ValueError:
                        pass

        outputdata.append([(residue, chain, resnum, inscode), fields])

    return outputdata, header, command
Exemple #2
0
class BuilderObject(object):
    """Template Object for creating an Object to generate ligand restraints"""
    def __init__(self, time=True, verbose=True):

        self.allowed_args = allowed_builder_args
        self.ligname = DEFAULT_LIGAND_NAMES[0]
        # Settings
        self.time = time
        self.verbose = verbose
        self.runtime = -1.0
        self.timeout = 1800
        # Custom Init
        self._custom_init()

    def generate_ligand(self, ligsmile, outdir, outfile, flags=[]):
        """Generate ligand PDB and CIF from smile string"""

        # Prepare standard settings
        self._prepare_to_generate_ligand(ligsmile, outdir, outfile, flags)
        # Check to see if already run, and if not, run the custom part of the object - different for each program
        if os.path.exists(self.outpdb) and os.path.exists(
                self.outcif) and os.path.exists(self.outlog):
            if self.verbose:
                print('\tLigand already generated - DOING NOTHING')
        else:
            cmd_line_args, std_inpt_args = self._create_program_arguments(
                ligsmile, outdir, outfile, flags)
            # Initialise CommandManager
            self.builder = CommandManager(self.program)
            # Set Command-Line Args
            if cmd_line_args:
                self.builder.add_command_line_arguments(cmd_line_args)
            # Set Standard Input
            if std_inpt_args: self.builder.add_standard_input(std_inpt_args)
            # Set Parameters
            self.builder.set_timeout(timeout=self.timeout)
            # RUN
            self.builder.run()
            # Get runtime
            self.runtime = self.builder.runtime

            try:
                # Could add postprocess here
                pass

            finally:
                self.write_log_file()

        return self.outpdb, self.outcif, self.outlog

    def _prepare_to_generate_ligand(self, ligsmile, outdir, outfile, flags):
        """Set up the generic file names"""

        # Process outputfile
        if '/' in outfile:
            raise ValueError('outfile must be a file, not a path')
        # Record Template and Outdir
        self.outtemplate = os.path.join(outdir, outfile)
        self.outdir = outdir
        # Record Filenames
        self.outpdb = self.outtemplate + '.pdb'
        self.outcif = self.outtemplate + '.cif'
        self.outlog = self.outtemplate + '.log'

    def write_log_file(self):
        """Write the log file"""

        with open(self.outlog, 'w') as logfile:
            # Write out the input command
            logfile.write('\nCOMMAND\n\n')
            logfile.write('\n'.join(self.builder.cmd_line_args) + '\n')
            logfile.write('\nINPUT\n\n')
            logfile.write('\n'.join(self.builder.std_inp_lines) + '\n')
            # Write out & err
            logfile.write('\nSTDOUT\n\n')
            logfile.write(self.builder.output)
            logfile.write('\nSTDERR\n\n')
            logfile.write(self.builder.error)
Exemple #3
0
def score_with_edstats_to_list(mtz_file, pdb_file):
    """Scores residues against density, then returns list"""

    assert os.path.exists(
        mtz_file), 'MTZ FILE FOR EDSTATS DOES NOT EXIST! {!s}'.format(mtz_file)
    assert os.path.exists(
        pdb_file), 'PDB FILE FOR EDSTATS DOES NOT EXIST! {!s}'.format(mtz_file)

    # Create a file handle and path for the output
    temp_handle, temp_path = tempfile.mkstemp(suffix='.table',
                                              prefix='edstats_')

    # Find the labels in the mtzfile
    file_obj = MtzSummary(mtz_file)
    f_label = file_obj.label.f
    if not f_label:
        raise ReflectionException(
            'MTZ Summary ERROR: No F Label Found in MTZ File: {!s}'.format(
                mtz_file))

    # Run EDSTATS on the files
    try:
        # Initialise Command Manager to run edstats
        command = CommandManager('edstats.pl')
        command.add_command_line_arguments([
            '-hklin', mtz_file, '-xyzin', pdb_file, '-output', temp_path,
            '-noerror', '-flabel', f_label
        ])
        command.set_timeout(timeout=600)
        command.run()
        # Read the output
        with os.fdopen(temp_handle) as f:
            output = f.read().strip().replace('\r\n',
                                              '\n').replace('\r',
                                                            '\n').splitlines()
        command.file_output = output
    finally:
        os.remove(temp_path)

    # Process the output header
    if output:
        header = output.pop(0).split()
        assert header[:3] == [
            'RT', 'CI', 'RN'
        ], 'EDSTATS OUTPUT HEADERS ARE NOT AS EXPECTED! {!s}'.format(output)
        num_fields = len(header)
        header = header[3:]
    else:
        header = []

    # List to be returned
    outputdata = []

    # Process the rest of the data
    for line in output:
        line = line.strip()
        if not line:
            continue

        fields = line.split()
        if len(fields) != num_fields:
            raise ValueError(
                "Error Parsing EDSTATS output: Header & Data rows have different numbers of fields"
            )

        # Get and process the residue information
        residue, chain, resnum = fields[:3]
        try:
            resnum = int(resnum)
            inscode = ' '
        except ValueError:
            inscode = resnum[-1:]
            resnum = int(resnum[:-1])

        # Remove the processed columns
        fields = fields[3:]

        # Process the other columns (changing n/a to None and value to int)
        for i, x in enumerate(fields):
            if x == 'n/a':
                fields[i] = None
            else:
                try:
                    fields[i] = int(x)
                except ValueError:
                    fields[i] = float(x)

        outputdata.append([(residue, chain, resnum, inscode), fields])

    return outputdata, header, command