Ejemplo n.º 1
0
    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
Ejemplo n.º 2
0
def run_refinement_pipeline(in_mtz, ref_pdb, out_dir, program='dimple'):
    """Run refinement of the input MTZ file against a reference PDB file"""

    print '*************************'
    print '*** Running Pipelines ***'
    print '*************************'

    if program == 'dimple':
        # Define output files
        out_pdb = os.path.join(out_dir, 'final.pdb')
        out_mtz = os.path.join(out_dir, 'final.mtz')
        # Create command manager for dimple
        cmd = CommandManager('dimple')
        cmd.add_command_line_arguments(
            ['--jelly', '5', in_mtz, ref_pdb, out_dir])
    else:
        raise Exception("no stop that. you're doing it wrong.")

    print_run_and_raise_error_maybe(cmd)
    if not os.path.exists(out_pdb):
        raise Failure(
            'running refinement with {} has failed -- {} does not exist'.
            format(program, out_pdb))
    if not os.path.exists(out_mtz):
        raise Failure(
            'running refinement with {} has failed -- {} does not exist'.
            format(program, out_mtz))

    return out_pdb, out_mtz
Ejemplo n.º 3
0
def generate_symmetry_mates(pdbin, pdbout, sgno, cell):
    """Takes the input pdb and generates the unit cell from the point group symmetry"""

    if not pdbout.endswith('.pdb'):
        pdbout = pdbout + '.pdb'
    if not os.path.exists(pdbin):
        raise IOError('pdbin does not exist! {!s}'.format(pdbin))
    if os.path.exists(pdbout):
        raise Exception('pdbout already exists! {!s}'.format(pdbout))

    assert isinstance(sgno,
                      int), 'SPACEGROUP MUST BE AN INTEGER! {!s}'.format(sgno)
    assert isinstance(cell, list), 'CELL MUST BE A LIST! {!s}'.format(cell)

    # Initialise Commander
    PDBSET = CommandManager('pdbset')
    # Set Command Arguments
    PDBSET.add_command_line_arguments('XYZIN', os.path.abspath(pdbin),
                                      'XYZOUT', os.path.abspath(pdbout))
    # Set inputs
    PDBSET.add_standard_input([
        'SYMGEN {!s}'.format(sgno),
        'CELL {!s}'.format(' '.join(map(str, cell))), 'END'
    ])
    # run!
    PDBSET.run()

    if not os.path.exists(pdbout):
        raise ExternalProgramError(
            'PDBSET has failed to generate SYMMETRY mates. {!s}\nCOM: {!s}\nOUT: {!s}\nERR: {!s}'
            .format(pdbin, PDBSET.command, PDBSET.out, PDBSET.err))

    return pdbout
Ejemplo n.º 4
0
def create_cryst_line(pdbin, pdbout, sg, cell):
    """Adds a cryst line to pdbin"""

    if not pdbout.endswith('.pdb'):
        pdbout = pdbout + '.pdb'
    if not os.path.exists(pdbin):
        raise IOError('pdbin does not exist! {!s}'.format(pdbin))
    if os.path.exists(pdbout):
        raise Exception('pdbout already exists! {!s}'.format(pdbout))

    # Initialise Commander
    PDBSET = CommandManager('pdbset')
    # Set Command Arguments
    PDBSET.add_command_line_arguments('XYZIN', os.path.abspath(pdbin),
                                      'XYZOUT', os.path.abspath(pdbout))
    # Set Stdin
    PDBSET.add_standard_input([
        'SPACEGROUP {!s}'.format(sg),
        'CELL {!s}'.format(' '.join(map(str, cell)))
    ])
    # run!
    PDBSET.run()

    if not os.path.exists(pdbout):
        raise ExternalProgramError(
            'PDBSET has failed to create cryst line for {!s}\nOUT: {!s}\nERR: {!s}'
            .format(pdbin, PDBSET.out, PDBSET.err))

    return PDBSET
Ejemplo n.º 5
0
def create_alpha_carbon_backbone(pdbin, pdbout):
    """Takes a pdb files and removes eveything except for the alpha carbons"""

    if not pdbout.endswith('.pdb'):
        pdbout = pdbout + '.pdb'
    if not os.path.exists(pdbin):
        raise IOError('pdbin does not exist! {!s}'.format(pdbin))
    if os.path.exists(pdbout):
        raise Exception('pdbout already exists! {!s}'.format(pdbout))

    # Initialise Commander
    PDBCUR = CommandManager('pdbcur')
    # Set Command Arguments
    PDBCUR.add_command_line_arguments('XYZIN', pdbin, 'XYZOUT', pdbout)
    # Set inputs
    PDBCUR.add_standard_input(['lvatom "CA[C]:*"', 'END'])
    # run!
    PDBCUR.run()

    if not os.path.exists(pdbout):
        raise ExternalProgramError(
            'PDBCUR has failed to create carbon backbone. {!s}\nOUT: {!s}\nERR: {!s}'
            .format(pdbin, PDBCUR.out, PDBCUR.err))

    return pdbout
Ejemplo n.º 6
0
    def run_refinement(self,
                       inpdb,
                       inmtz,
                       outdir,
                       outfile,
                       incif=None,
                       flags=[]):
        """Run Refinement of a Structure"""

        # Prepare standard settings
        self._prepare_to_refine_structure(inpdb, inmtz, outdir, outfile, incif,
                                          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.outmtz) and os.path.exists(self.outlog):
            if self.verbose:
                print('\tRefinement already done - DOING NOTHING')
        else:
            if self.verbose:
                print('\tRefining using {!s}.'.format(self.name))
            cmd_line_args, std_inpt_args = self._create_program_arguments(
                inpdb, inmtz, outdir, outfile, incif, flags)
            # Initialise CommandManager
            self.Refiner = CommandManager(self.program)
            # Set Command-Line Args
            self.Refiner.SetArguments(cmd_line_args)
            # Set Standard Input
            self.Refiner.SetInput(std_inpt_args)
            # Set Parameters
            self.Refiner.SetParameters(timeout=self.timeout)
            # RUN
            self.Refiner.Run()
            # Calculate runtime (seconds)
            self.runtime = self.Refiner.runtime

            if self.verbose:
                print('\tFinished refinement - post-processing structure.')

            try:
                # General post-process
                self._standard_post_process(inpdb, inmtz, outdir, outfile,
                                            incif, flags)

                # Could add autoprocessing here...
                self._post_process(inpdb, inmtz, outdir, outfile, incif, flags)

            finally:
                self.write_log_file()

        return self.outpdb, self.outmtz, self.outlog
Ejemplo n.º 7
0
def extract_bfactor_statistics(pdb_file):
    """Analyse the b-factors in a pdb file and return a dictionary with all of the averages, rms deviations and Z-scores for the b-factors in a structure"""

    # Create a temporary file for the output summary table and pdb_file
    temp_handle, temp_path = tempfile.mkstemp(suffix='.table',
                                              prefix='baverage_')
    temp_handle2, temp_path2 = tempfile.mkstemp(suffix='.pdb',
                                                prefix='baverage_')

    BAVERAGE = CommandManager('baverage')
    BAVERAGE.add_command_line_arguments('XYZIN', pdb_file, 'RMSTAB', temp_path,
                                        'XYZOUT', temp_path2)
    BAVERAGE.add_standard_input(['END'])
    BAVERAGE.run()

    if not os.path.exists(temp_path):
        raise ExternalProgramError(
            'BAVERAGE has failed to calculate b-factor summary statistics for {!s}'
            .format(pdb_file))

    # Process Table and Standard Out
    table_contents = open(temp_path, 'r').read().split('\n')

    if not table_contents:
        raise ExternalProgramError(
            'BAVERAGE has failed to calculate b-factor summary statistics for {!s}'
            .format(pdb_file))
    else:
        os.remove(temp_path)
        os.remove(temp_path2)

    return BAVERAGE, table_contents
Ejemplo n.º 8
0
def run_xia2(img_dir, out_dir, method='dials', verbose=True):
    """Run xia2 on the images in img_dir, and put the results in out_dir"""

    assert method in ['2d','3d','3dii','dials'], 'Invalid method provided'

    assert os.path.exists(img_dir), 'Image directory does not exist'
    if not os.path.exists(out_dir): os.mkdir(out_dir)

    # Convert to absolute path to allow folder changing
    img_dir = os.path.abspath(img_dir)
    out_dir = os.path.abspath(out_dir)

    # Store current directory
    cur_dir = os.getcwd()

    try:

        # Output logfile
        xia2_log = os.path.join(out_dir, 'xia2.log')

        # Got to directory to run MLFSOM
        os.chdir(out_dir)

        xia2 = CommandManager('xia2')
        xia2.add_command_line_arguments('-'+method, img_dir)
        if verbose: print('Running xia2 on {}').format(img_dir)
        rc = xia2.run()
        if rc != 0:
            print('STDOUT:')
            print(xia2.output)
            print('STDERR:')
            print(xia2.error)
        with open(xia2_log, 'a') as fh:
            fh.write('==================================================>\n')
            fh.write('xia2 log\n')
            fh.write('==================================================>\n')
            fh.write(xia2.output+'\n')
            fh.write('==================================================>\n')
            fh.write('xia2 errors\n')
            fh.write('==================================================>\n')
            fh.write(xia2.error+'\n')
            fh.write('==================================================>\n')

    finally:
        # Change back to original directory
        os.chdir(cur_dir)

    return xia2
Ejemplo n.º 9
0
def isolate_residue(inpdb, outpdb, resname):
    """Extract the residues identified by resname using pdbcur - i.e. 'UNL'"""

    PDBCUR = CommandManager('pdbcur')
    PDBCUR.add_command_line_arguments('XYZIN', inpdb, 'XYZOUT', outpdb)
    PDBCUR.add_standard_input(['lvresidue /*/*/({!s})'.format(resname), 'END'])
    PDBCUR.run()

    return PDBCUR
Ejemplo n.º 10
0
    def __init__(self,
                 pdb_file,
                 mtz_file=None,
                 cif_file=None,
                 out_prefix=None,
                 **kw_args):

        # Set defaults if not given
        if mtz_file is None:
            mtz_file = pdb_file.replace('.pdb', '.mtz')
        if out_prefix is None:
            out_prefix = os.path.splitext(pdb_file)[0] + '-refined'

        # Main files
        self.pdb_file = pdb_file
        self.mtz_file = mtz_file
        self.cif_file = cif_file

        # Eventual output prefix
        self.out_prefix = out_prefix
        self.out_pdb_file = self.out_prefix + '.pdb'
        self.out_mtz_file = self.out_prefix + '.mtz'
        self.out_log_file = self.out_prefix + '.log'

        # Validate input
        assert os.path.exists(self.pdb_file)
        assert os.path.exists(self.mtz_file)
        assert not os.path.exists(
            self.out_pdb_file), 'Output file already exists: {}'.format(
                self.out_pdb_file)
        assert not os.path.exists(
            self.out_mtz_file), 'Output file already exists: {}'.format(
                self.out_mtz_file)

        # Create temporary folder for refinement
        self.tmp_dir = tempfile.mkdtemp(prefix='refine-model-')
        self.tmp_pre = os.path.join(self.tmp_dir, 'refine')

        # Command object for refinement
        self.cmd = CommandManager(self.program)
        self.kw_args = kw_args

        # Setup, refine and post_process
        if self.auto is True:
            self.run()
Ejemplo n.º 11
0
def phenix_find_tls_groups(pdb_file):
    cmd = CommandManager('phenix.find_tls_groups')
    cmd.add_command_line_arguments(pdb_file)
    #cmd.print_settings()
    ret_code = cmd.run()

    if ret_code != 0:
        print cmd.output
        print cmd.error
        raise Exception('Failed to determine TLS groups: {}'.format(' '.join(
            cmd.program)))

    regex = re.compile("refinement\.refine\.adp \{([\s\S]*?)\}")
    tls_command = regex.findall(cmd.output)[0]
    tls_selections = [
        s.strip() for s in tls_command.split('tls =') if s.strip()
    ]

    return tls_selections
Ejemplo n.º 12
0
def convert_intensities_to_amplitudes(mtzin, mtzout):
    """Takes an input mtz and converts the intensities to structure factors for model building"""

    mtzobj = MtzSummary(mtzin)

    # Copy data columns from new mtz file
    I, SIGI = mtzobj.label.i, mtzobj.label.sigi
    if not (I and SIGI):
        raise LabelError('No Intensities found in {!s}'.format(mtzin))

    # TODO If rfree is present, retain rfree from the reference mtz


#    RFree = mtzobj.label.free

# Initialise Commander
    CTRUNC = CommandManager('ctruncate')
    # Set command arguments
    CTRUNC.add_command_line_arguments('-mtzin', mtzin, '-mtzout', mtzout,
                                      '-colin',
                                      '/*/*/[{!s},{!s}]'.format(I, SIGI))
    # Run!
    CTRUNC.run()

    if not os.path.exists(mtzout):
        raise ExternalProgramError(
            'CTRUNCATE has failed to convert intensities to SFs. {!s}\nOUT: {!s}\nERR: {!s}'
            .format(mtzin, CTRUNC.out, CTRUNC.err))

    return CTRUNC
Ejemplo n.º 13
0
def map_to_reference_using_symmetry(refpdb, movpdb, pdbout, conrad=5):
    """Transforms `movpdb` to the closest symmetry site to `refpdb` using csymmatch - Symmetry info must be contained in the header of the pdb file"""

    if not pdbout.endswith('.pdb'):
        pdbout = pdbout + '.pdb'
    if not os.path.exists(refpdb):
        raise IOError('refpdb does not exist! {!s}'.format(refpdb))
    if not os.path.exists(movpdb):
        raise IOError('movpdb does not exist! {!s}'.format(movpdb))
    if os.path.exists(pdbout):
        raise Exception('pdbout already exists! {!s}'.format(pdbout))

    # Initialise Commander
    CSYMMATCH = CommandManager('csymmatch')
    # Set Command Arguments
    CSYMMATCH.add_command_line_arguments('-pdbin-ref',
                                         os.path.abspath(refpdb), '-pdbin',
                                         os.path.abspath(movpdb), '-pdbout',
                                         os.path.abspath(pdbout),
                                         '-connectivity-radius', str(conrad))
    # run!
    CSYMMATCH.run()

    if not os.path.exists(pdbout):
        raise ExternalProgramError(
            'CSYMMATCH has failed to map {!s} to {!s}.\nERR: {!s}'.format(
                movpdb, refpdb, CSYMMATCH.err))

    return pdbout
Ejemplo n.º 14
0
def merge_pdb_files(pdb1, pdb2, pdbout):
    """Merge two PDB Files using CCP4s pdb_merge"""

    # Initialise Commander
    MERGER = CommandManager('pdb_merge')
    # Set command arguments
    MERGER.add_command_line_arguments('xyzin1', pdb1, 'xyzin2', pdb2, 'xyzout',
                                      pdbout)
    # Set inputs
    MERGER.add_standard_input('END')
    # run!
    MERGER.run()

    return MERGER
Ejemplo n.º 15
0
 def run(cls, script):
     assert script.endswith(cls._file_type)
     c = CommandManager('pymol')
     c.add_command_line_arguments([
         '-k', '-q', '-c', '-Q', '-s',
         script[:-len(cls._file_type)] + '.log', '-r', script
     ])
     c.run()
     return c
Ejemplo n.º 16
0
def mask_map(mapin, maskpdb, mapout, border=1):
    """Takes mapin and masks around atoms in maskpdb"""

    # Masking object
    masker = CommandManager('mapmask')
    # Set input files
    masker.add_command_line_arguments(
        ['mapin', mapin, 'mapout', mapout, 'xyzin', maskpdb])
    # Set stdin
    masker.add_standard_input(['BORDER {!s}'.format(border), 'END'])
    # Run!
    masker.run()
    # Report errors
    if masker.process.returncode != 0:
        raise RuntimeError('mapmask failed to mask map {!s}'.format(mapin))

    # Return Command Managers for flexible handling of out & err
    return masker
Ejemplo n.º 17
0
def create_asu_map(mapin, mapout):
    """Takes mapin and masks to the asymmetric unit"""

    # Masking object
    masker = CommandManager('mapmask')
    # Set input files
    masker.add_command_line_arguments(['mapin', mapin, 'mapout', mapout])
    # Set stdin
    masker.add_standard_input(['XYZLIM ASU', 'END'])
    # Run!
    masker.run()
    # Report errors
    if masker.process.returncode != 0:
        raise RuntimeError(
            'mapmask failed to create asu map from {!s}'.format(mapin))

    # Return Command Managers for flexible handling of out & err
    return masker
Ejemplo n.º 18
0
def fft_mtz_to_map(mtz_file, map_file, cols):
    """Converts an MTZ Format File to a MAP File (using fft as default)"""

    # Initialise
    writer = CommandManager('fft')
    # Set Program Arguments
    writer.add_command_line_arguments('hklin', mtz_file, 'mapout', map_file)
    # Set Program Input
    writer.add_standard_input(
        ['LABIN F1={!s} PHI={!s}'.format(cols['F'], cols['P']), 'END'])
    # RUN!
    writer.run()
    # Check Output
    if writer.process.returncode != 0:
        print('\nOUT\n\n' + writer.out)
        print('\nERR\n\n' + writer.err)
        raise RuntimeError(
            'fft failed to generate map from {!s}'.format(mtz_file))

    return writer
Ejemplo n.º 19
0
def isolate_residue_by_res_id(inpdb,
                              outpdb,
                              chain,
                              resnum,
                              model='*',
                              inscode=''):
    """Isolate the residues identified by residue ids using pdbcur - i.e. '0/A/54.A/'"""

    if inscode:
        selection = '/{!s}/{!s}/{!s}.{!s}'.format(model, chain, resnum,
                                                  inscode)
    else:
        selection = '/{!s}/{!s}/{!s}'.format(model, chain, resnum)

    PDBCUR = CommandManager('pdbcur')
    PDBCUR.add_command_line_arguments('XYZIN', inpdb, 'XYZOUT', outpdb)
    PDBCUR.add_standard_input(['lvresidue {!s}'.format(selection), 'END'])
    PDBCUR.run()

    return PDBCUR
Ejemplo n.º 20
0
def reindex_mtz_to_reference(in_mtz, out_mtz, reference_mtz, tolerance):
    """Reindex the data in one mtz to a reference mtz"""

    print '**************************'
    print '*** Running reindexing ***'
    print '**************************'

    cmd = CommandManager('pointless')
    cmd.add_command_line_arguments(
        ['hklin', in_mtz, 'hklref', reference_mtz, 'hklout', out_mtz])
    cmd.add_standard_input(['tolerance {}'.format(tolerance)])
    print_run_and_raise_error_maybe(cmd)
    if not os.path.exists(out_mtz):
        raise Failure(
            'reindexing has failed -- {} does not exist'.format(out_mtz))
Ejemplo n.º 21
0
def remove_residue_by_res_id(inpdb,
                             outpdb,
                             chain,
                             resnum,
                             model='*',
                             inscode='',
                             removeSolvent=False):
    """Remove the residues identified by res info using pdbcur - i.e. 'UNL'"""

    if inscode:
        selection = '/{!s}/{!s}/{!s}.{!s}'.format(model, chain, resnum,
                                                  inscode)
    else:
        selection = '/{!s}/{!s}/{!s}'.format(model, chain, resnum)

    std_input = ['delresidue {!s}'.format(selection)
                 ] + (removeSolvent) * ['delsolvent'] + ['END']

    PDBCUR = CommandManager('pdbcur')
    PDBCUR.add_command_line_arguments('XYZIN', inpdb, 'XYZOUT', outpdb)
    PDBCUR.add_standard_input(std_input)
    PDBCUR.run()

    return PDBCUR
Ejemplo n.º 22
0
def run_coot(script, graphical=False, noguano=True):
    """Runs coot with the provided script"""

    # Check that the script is valid (e.g. causes coot to exit at the end)
    validate_coot_script(script)

    # Stop coot droppings?
    coot_flags = ['--no-guano']*(noguano)
    # Run with/without graphics?
    if graphical:
        coot_flags.extend(['-script',script])
    else:
        coot_flags.extend(['--no-graphics','-s',script])

    # Initialise
    COOT = CommandManager('coot')
    # Load arguments
    COOT.add_command_line_arguments(*coot_flags)
    # Run!
    COOT.run()

    return COOT
Ejemplo n.º 23
0
def get_mtz_resolution(mtz_file):
    """Gets the max resolution from the file"""

    # Extract Contents of MTZ
    MTZDMP = CommandManager('mtzdmp')
    MTZDMP.add_command_line_arguments(mtz_file)
    MTZDMP.run()
    # Check for errors
    if MTZDMP.process.returncode != 0:
        raise RuntimeError(
            'mtzdmp failed to read file {!s}:\nReturn: {!s}\nOut: {!s}'.format(
                mtz_file, MTZDMP.process.returncode, MTZDMP.output))
    # Search for the Column Headings
    regex = re.compile('\*  Resolution Range :.*\n.*\n.*\((.*)A \)\n')
    matches = regex.findall(MTZDMP.output)
    # Check for validity of matches
    assert matches, 'No Resolution Range found in MTZFile {!s}'.format(
        mtz_file)
    assert len(
        matches
    ) == 1, 'Too many matching lines found for Column Headings in MTZFile {!s}\n\t{!s}'.format(
        mtz_file, matches)
    # Return
    return map(float, matches[0].replace(' ', '').split('-'))
Ejemplo n.º 24
0
def merge_cif_libraries(incifs, outcif):
    """Take a list of cifs and merge into one cif"""

    assert isinstance(incifs, list), "'incifs' is not a list!"
    assert len(incifs) > 1, "'incifs' must be two or more files!"

    current = incifs.pop(0)

    to_be_deleted = []

    for additional in incifs:

        # Create a file handle and path for the output
        temp_handle, temp_path = tempfile.mkstemp(suffix='.lib',
                                                  prefix='libcheck_')
        to_be_deleted.append(temp_path)

        # Merge current and additional to temp_path
        LIBCHK = CommandManager('libcheck')
        LIBCHK.add_standard_input(
            '_DOC N', '_FILE_L {!s}'.format(current),
            '_FILE_L2 {!s}'.format(additional),
            '_FILE_O {!s}'.format(temp_path.replace('.lib', '')), '_END')
        LIBCHK.run()

        current = temp_path

    shutil.copy(current, outcif)

    for file in to_be_deleted:
        os.remove(file)

    assert os.path.exists(outcif), 'OUTPUT CIF DOES NOT EXIST! {!s}'.format(
        outcif)

    return outcif
Ejemplo n.º 25
0
def run_mlfsom(pdb_file, res_h, out_dir='mlfsom_out', n_images=180, osc=1.0, energy=12660, verbose=True):
    """Run MLFSOM on the given file."""

    ftd_pre = ['1H87.pdb', 'example.com', 'example.mat', 'mlfsom.log', 'refined.pdb', 'pristine.mtz']

    assert not os.path.exists(out_dir), 'output directory already exists!'
    assert os.path.exists(pdb_file)
    assert isinstance(n_images, int)

    # Store current directory
    cur_dir = os.getcwd()

    try:
        # Create a temporary directory for mlfsom to run in (and go to it)
        tmp_dir = tempfile.mkdtemp(prefix='mlfsom_')
        mlfsom_pdb = os.path.join(tmp_dir, 'refined.pdb')
        mlfsom_mtz = os.path.join(tmp_dir, 'pristine.mtz')
        mlfsom_log = os.path.join(tmp_dir, 'mlfsom.log')
        mlfsom_img = 'image_###.img'

        # Get the mlfsom tarball and move it to the temporary directory
        mlfsom_file = os.path.join(bamboo.resources.__path__[0], 'mlfsom.tar.gz')
        assert os.path.exists(mlfsom_file), 'MLFSOM tarball not found'
        shutil.copy(mlfsom_file, tmp_dir)
        mlfsom_file = os.path.join(tmp_dir, 'mlfsom.tar.gz')
        assert os.path.exists(mlfsom_file), 'MLFSOM tarball not in temporary directory'

        # Untar the file
        t = tarfile.open(mlfsom_file, 'r:gz')
        try: t.extractall(tmp_dir)
        finally: t.close()

        # Delete unnecessary files
        for f in ftd_pre:
            fp = os.path.join(tmp_dir, f)
            if os.path.exists(fp): os.remove(fp)

        # Move the input files in
        shutil.copy(pdb_file, mlfsom_pdb)

        # Got to directory to run MLFSOM
        os.chdir(tmp_dir)

        # Convert the pdb_file to structure factors
        ano_sfall = CommandManager('./ano_sfall.com')
        ano_sfall.add_command_line_arguments(os.path.basename(mlfsom_pdb))
        ano_sfall.add_command_line_arguments('energy={}'.format(energy))
        ano_sfall.add_command_line_arguments('{}A'.format(res_h))
        if verbose: print('Running ./ano_sfall.com on {}').format(pdb_file)
        rc = ano_sfall.run()
        if rc != 0:
            print('STDOUT:')
            print(ano_sfall.output)
            print('STDERR:')
            print(ano_sfall.error)
        shutil.move('ideal_ano.mtz', mlfsom_mtz)
        with open(mlfsom_log, 'a') as fh:
            fh.write('==================================================>\n')
            fh.write('ano_sfall log\n')
            fh.write('==================================================>\n')
            fh.write(ano_sfall.output+'\n')
            fh.write('==================================================>\n')
            fh.write('ano_sfall errors\n')
            fh.write('==================================================>\n')
            fh.write(ano_sfall.error+'\n')
            fh.write('==================================================>\n')

        # Run MLFSOM on the resulting mtzfile
        mlfsom = CommandManager('./mlfsom.com')
        mlfsom.add_command_line_arguments(mlfsom_img)
        mlfsom.add_command_line_arguments('frames={}'.format(n_images))
        mlfsom.add_command_line_arguments('osc={}'.format(osc))
        if verbose: print('Running ./mlfsom.com on {}. This may take a while...').format(pdb_file)
        rc = mlfsom.run()
        if rc != 0:
            print('STDOUT:')
            print(mlfsom.output)
            print('STDERR:')
            print(mlfsom.error)
        with open(mlfsom_log, 'a') as fh:
            fh.write('==================================================>\n')
            fh.write('mlfsom log\n')
            fh.write('==================================================>\n')
            fh.write(mlfsom.output+'\n')
            fh.write('==================================================>\n')
            fh.write('mlfsom errors\n')
            fh.write('==================================================>\n')
            fh.write(mlfsom.error+'\n')
            fh.write('==================================================>\n')

    finally:
        # Change back to original directory
        os.chdir(cur_dir)
        # Delete temporary directory
        shutil.move(tmp_dir, out_dir)

    return ano_sfall, mlfsom
Ejemplo n.º 26
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)
Ejemplo n.º 27
0
class _refiner(object):

    program = None
    auto = True

    def __init__(self,
                 pdb_file,
                 mtz_file=None,
                 cif_file=None,
                 out_prefix=None,
                 **kw_args):

        # Set defaults if not given
        if mtz_file is None:
            mtz_file = pdb_file.replace('.pdb', '.mtz')
        if out_prefix is None:
            out_prefix = os.path.splitext(pdb_file)[0] + '-refined'

        # Main files
        self.pdb_file = pdb_file
        self.mtz_file = mtz_file
        self.cif_file = cif_file

        # Eventual output prefix
        self.out_prefix = out_prefix
        self.out_pdb_file = self.out_prefix + '.pdb'
        self.out_mtz_file = self.out_prefix + '.mtz'
        self.out_log_file = self.out_prefix + '.log'

        # Validate input
        assert os.path.exists(self.pdb_file)
        assert os.path.exists(self.mtz_file)
        assert not os.path.exists(
            self.out_pdb_file), 'Output file already exists: {}'.format(
                self.out_pdb_file)
        assert not os.path.exists(
            self.out_mtz_file), 'Output file already exists: {}'.format(
                self.out_mtz_file)

        # Create temporary folder for refinement
        self.tmp_dir = tempfile.mkdtemp(prefix='refine-model-')
        self.tmp_pre = os.path.join(self.tmp_dir, 'refine')

        # Command object for refinement
        self.cmd = CommandManager(self.program)
        self.kw_args = kw_args

        # Setup, refine and post_process
        if self.auto is True:
            self.run()

    def run(self):
        """...run refinement amd export files"""
        self.setup()
        ret = self.refine()
        self.export()
        return ret

    def setup(self):
        raise Exception('Dummy class -- not implemented')

    def refine(self):
        """...run the refinement"""
        self.cmd.print_settings()
        return self.cmd.run()

    def export(self):
        """Copy files to output destination"""
        # Find pdb file in the output folder
        tmp_pdb = glob.glob(self.tmp_pre + '*.pdb')
        assert tmp_pdb, 'No refined files found: {}'.format(self.tmp_dir)
        tmp_pdb = tmp_pdb[0]
        tmp_mtz = tmp_pdb.replace('.pdb', '.mtz')
        assert os.path.exists(tmp_pdb)
        assert os.path.exists(tmp_mtz)
        # Copy to output folder
        shutil.copy(tmp_pdb, self.out_pdb_file)
        shutil.copy(tmp_mtz, self.out_mtz_file)
        assert os.path.exists(self.out_pdb_file)
        assert os.path.exists(self.out_mtz_file)
        # Write the log to the output log file
        self.cmd.write_output(self.out_log_file)
        # Delete temporary directory
        shutil.rmtree(self.tmp_dir)
Ejemplo n.º 28
0
def run(params):

    # Identify any existing output directories
    current_dirs = sorted(glob.glob(params.output.dir_prefix + '*'))
    if not current_dirs:
        next_int = 1
    else:
        current_nums = [
            s.replace(params.output.dir_prefix, '') for s in current_dirs
        ]
        next_int = sorted(map(int, current_nums))[-1] + 1

    # Create output directory name from int
    out_dir = params.output.dir_prefix + '{:04}'.format(next_int)
    # Create output directory
    os.mkdir(out_dir)

    # Create log object
    log = Log(log_file=os.path.join(
        out_dir, params.output.out_prefix + '.quick-refine.log'),
              verbose=params.settings.verbose)

    # Report
    if current_dirs:
        log('Found existing refinement directories: \n\t{}'.format(
            '\n\t'.join(current_dirs)))
        log('')
    log('Creating new output directory: {}'.format(out_dir))

    # Validate input parameters
    log.subheading('Validating input parameters')
    assert params.input.pdb is not None, 'No PDB given for refinement'
    assert params.input.mtz is not None, 'No MTZ given for refinement'

    if os.path.islink(params.input.mtz):
        log('Converting mtz path to real path:')
        log('{} -> {}'.format(params.input.mtz,
                              os.path.realpath(params.input.mtz)))
        params.input.mtz = os.path.realpath(params.input.mtz)

    # Link input
    log('Copying/linking files to refinement folder')
    shutil.copy(params.input.pdb,
                os.path.abspath(os.path.join(out_dir, 'input.pdb')))
    rel_symlink(params.input.mtz,
                os.path.abspath(os.path.join(out_dir, 'input.mtz')))
    # Copy parameter file to output folder
    if params.input.params:
        shutil.copy(params.input.params,
                    os.path.abspath(os.path.join(out_dir, 'input.params')))

    # Create output prefixes
    output_prefix = os.path.join(out_dir, params.output.out_prefix)
    log('Real output file path prefixes: {}'.format(output_prefix))
    log('Link output file path prefixes: {}'.format(params.output.link_prefix))

    # Create command objects
    log.subheading('Preparing command line input for refinement program')

    # PHENIX
    if params.options.program == 'phenix':
        cm = CommandManager('phenix.refine')
        # Command line args
        cm.add_command_line_arguments([params.input.pdb, params.input.mtz])
        cm.add_command_line_arguments(
            ['output.prefix={}'.format(output_prefix)])
        if params.input.cif:
            cm.add_command_line_arguments(params.input.cif)
        if params.input.params and os.path.exists(params.input.params):
            cm.add_command_line_arguments([params.input.params])

    # REFMAC
    elif params.options.program == 'refmac':
        cm = CommandManager('refmac5')
        # Command line args
        cm.add_command_line_arguments(
            ['xyzin', params.input.pdb, 'hklin', params.input.mtz])

        cm.add_command_line_arguments([
            'xyzout', output_prefix + '.pdb', 'hklout', output_prefix + '.mtz'
        ])
        if params.input.cif:
            for cif in params.input.cif:
                cm.add_command_line_arguments(['libin', cif])
        # Standard input
        if params.input.params:
            cm.add_standard_input(open(params.input.params).read().split('\n'))

        cm.add_standard_input(['END'])

    elif params.options.program == "buster":
        cm = CommandManager('refine')
        # Command line arguments
        # inputs
        cm.add_command_line_arguments(
            ['-p', params.input.pdb, '-m', params.input.mtz, '-d', out_dir])

        if params.input.cif:
            for cif in params.input.cif:
                cm.add_command_line_arguments(['-l', cif])

        if params.input.params:
            cm.add_command_line_arguments(['-Gelly', params.input.params])

    # Pass additional command line arguments?
    if params.input.args:
        cm.add_command_line_arguments(params.input.args)

    # Report
    log(str(cm))

    log.bar()
    log('running refinement... ({})'.format(cm.program[0]))
    out = cm.run()

    log.subheading('Refinement output')
    if not log.verbose:
        log('output written to log file ({} lines)'.format(
            cm.output.count('\n')))

    log('\n' + cm.output, show=False)

    if out != 0:
        log.subheading('Refinement Errors')
        log(cm.error)

    log.subheading('Post-processing output files')

    if params.options.program == "buster":
        log.subheading('Renaming buster output files')

        shutil.move(src=os.path.join(out_dir, 'refine.pdb'),
                    dst=output_prefix + '.pdb')

        shutil.move(src=os.path.join(out_dir, 'refine.mtz'),
                    dst=output_prefix + '.mtz')

    # Find output files
    try:
        real_pdb = glob.glob(output_prefix + '*.pdb')[0]
        real_mtz = glob.glob(output_prefix + '*.mtz')[0]
    except:
        log('Refinement has failed - output files do not exist')
        log('{}: {}'.format(output_prefix + '*.pdb',
                            glob.glob(output_prefix + '*.pdb')))
        log('{}: {}'.format(output_prefix + '*.mtz',
                            glob.glob(output_prefix + '*.mtz')))
        raise

    # List of links to make at the end of the run
    link_file_pairs = [(real_pdb, params.output.link_prefix + '.pdb'),
                       (real_mtz, params.output.link_prefix + '.mtz')]

    # Split conformations
    if params.options.split_conformations:
        params.split_conformations.settings.verbose = params.settings.verbose
        log.subheading('Splitting refined structure conformations')
        # Running split conformations
        out_files = split_conformations.split_conformations(
            filename=real_pdb, params=params.split_conformations, log=log)
        # Link output files to top
        for real_file in out_files:
            link_file = params.output.link_prefix + os.path.basename(
                real_file.replace(os.path.splitext(real_pdb)[0], ''))
            link_file_pairs.append([real_file, link_file])

    # Link output files
    log.subheading('linking output files')
    for real_file, link_file in link_file_pairs:
        log('Linking {} -> {}'.format(link_file, real_file))
        if not os.path.exists(real_file):
            log('file does not exist: {}'.format(real_file))
            continue
        if os.path.exists(link_file) and os.path.islink(link_file):
            log('removing existing link: {}'.format(link_file))
            os.unlink(link_file)
        if not os.path.exists(link_file):
            rel_symlink(real_file, link_file)

    log.heading('finished - refinement')
Ejemplo n.º 29
0
class FitterObject(object):
    def __init__(self, time=True, verbose=True):

        self.allowedArgs = allowed_fitter_args
        self.preferChain = DEFAULT_OUTPUT_CHAIN[0]
        # Settings
        self.time = time
        self.verbose = verbose
        self.runtime = -1.0
        self.timeout = 99999
        # Custom Init
        self._custom_init()

    def fit_ligand(self,
                   ligcif,
                   ligpdb,
                   mtz,
                   apopdb,
                   outdir,
                   outfile,
                   flags=[]):
        """Fit Ligand to a structure"""

        # Prepare input and output filenames
        self._prepare_to_fit_ligand(ligcif, ligpdb, mtz, apopdb, 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.outlog):
            if self.verbose:
                print('\tLigand already fitted - DOING NOTHING')
            self._post_process(ligcif, ligpdb, mtz, apopdb, outdir, outfile,
                               flags)
        else:
            if self.verbose:
                print('\tFitting using {!s}.'.format(self.name))
            cmd_line_args, std_inpt_args = self._create_program_arguments(
                ligcif, ligpdb, mtz, apopdb, outdir, outfile, flags)
            # Initialise CommandManager
            self.Fitter = CommandManager(self.program)
            # Set Command-Line Args
            if cmd_line_args: self.Fitter.SetArguments(cmd_line_args)
            # Set Standard Input
            if std_inpt_args: self.Fitter.SetInput(std_inpt_args)
            # Set Parameters
            self.Fitter.SetParameters(timeout=self.timeout)
            # RUN
            self.Fitter.Run()
            # Calculate runtime (seconds)
            self.runtime = self.Fitter.runtime

            try:
                # Process results and generate the list of modelled ligands
                if self.verbose:
                    print('\tFinished fitting - post-processing models.')
                self._post_process(ligcif, ligpdb, mtz, apopdb, outdir,
                                   outfile, flags)

                if not self.outmodels:
                    raise FittingError(
                        'No fitted models found! Log: {!s}'.format(
                            self.outlog))

                if not os.path.exists(self.outpdb):
                    # Map the model of the best ligand to the asu and check it's near to the protein
                    self._map_to_asu(ligcif, ligpdb, mtz, apopdb, outdir,
                                     outfile, flags)
                    # Create symbolic links to the output file
                    self._link_output_files()

                # Merge the best ligand with the apo structure
                if not os.path.exists(self.mergedpdb):
                    self.Merger = merge_pdb_files(apopdb, self.outpdb,
                                                  self.mergedpdb)

            finally:
                self.write_log_file()

        return self.outpdb, self.mergedpdb, self.outlog

    def _prepare_to_fit_ligand(self, ligcif, ligpdb, mtz, apopdb, 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 + '.lig.pdb'
        self.mergedpdb = self.outtemplate + '.pdb'
        self.outlog = self.outtemplate + '.log'
        # Storage
        self.outmodels = []
        self.filtmodels = []
        self.bestmodel = None
        self.fittingdata = None

        # Prepare custom settings
        self._custom_prepare_to_fit_ligand(ligcif, ligpdb, mtz, apopdb, outdir,
                                           outfile, flags)

        return

    def _map_to_asu(self, ligcif, ligpdb, mtz, apopdb, outdir, outfile, flags):
        """Map the best ligand file to the asu of the protein - pick the symmetry version with the most contacts"""

        candidate = None

        if self.verbose:
            print('\tMapping fitted models back to the asymmetric unit.')

        for model in self.outmodels:

            ligand_sym_file = model.replace('.pdb', '.sym.pdb')

            if os.path.exists(ligand_sym_file):
                self.filtmodels.append(model)
            else:
                try:
                    # Create Cryst Line
                    shutil.move(model, model + '.temp.pdb')
                    PDBSET = create_cryst_line_from_mtz(
                        model + '.temp.pdb', ligand_sym_file, mtz)
                    # Rename the original file, then create a symmetry equivalent ligand that is close to the protein
                    #                    shutil.move(model, ligand_sym_file)
                    #                    candidate, ordered_files = map_structure_to_asu(apopdb, mtz, ligand_sym_file, model, delete_structures=True)
                    candidate = map_to_reference_using_symmetry(
                        refpdb=apopdb, movpdb=ligand_sym_file, pdbout=model)
                    self.filtmodels.append(candidate)
                except (DistanceError, IOError) as err:
                    print(err)
                    continue

            # If it gets here we have a candidate
            # Break here for fast (1 model per fitter max)
#            break

        if not self.filtmodels:
            raise FittingError('No fitted models within range of protein!')
        else:
            # Rename all of the filtered models
            [
                change_residue_chain_and_number(filtfile)
                for filtfile in self.filtmodels
            ]
            # Pick the `best` one to be the output
            self.bestmodel = self.filtmodels[0]

        return

    def _link_output_files(self):
        """Make links to the output files"""

        # Create Symlinks
        os.symlink(os.path.relpath(self.bestmodel, start=self.outdir),
                   self.outpdb)

        return

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

        if self.verbose:
            print('\tWriting fitting logfile.')

        with open(self.outlog, 'w') as logfile:

            if hasattr(self, 'Fitter'):
                # Write out the input command
                logfile.write('\nCOMMAND\n\n')
                logfile.write('\n'.join(self.Fitter.command))
                logfile.write('\nINPUT\n\n')
                logfile.write(self.Fitter.inp)
                # Write out & err
                logfile.write('\nFITTER STDOUT\n\n')
                logfile.write(self.Fitter.out)
                logfile.write('\nFITTER STDERR\n\n')
                logfile.write(self.Fitter.err)

            if hasattr(self, 'Merger'):
                # Write out the input command
                logfile.write('\nCOMMAND\n\n')
                logfile.write('\n'.join(self.Merger.command))
                logfile.write('\nINPUT\n\n')
                logfile.write(self.Merger.inp)
                # Write out & err
                logfile.write('\nMERGER STDOUT\n\n')
                logfile.write(self.Merger.out)
                logfile.write('\nMERGER STDERR\n\n')
                logfile.write(self.Merger.err)

        return
Ejemplo n.º 30
0
    def fit_ligand(self,
                   ligcif,
                   ligpdb,
                   mtz,
                   apopdb,
                   outdir,
                   outfile,
                   flags=[]):
        """Fit Ligand to a structure"""

        # Prepare input and output filenames
        self._prepare_to_fit_ligand(ligcif, ligpdb, mtz, apopdb, 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.outlog):
            if self.verbose:
                print('\tLigand already fitted - DOING NOTHING')
            self._post_process(ligcif, ligpdb, mtz, apopdb, outdir, outfile,
                               flags)
        else:
            if self.verbose:
                print('\tFitting using {!s}.'.format(self.name))
            cmd_line_args, std_inpt_args = self._create_program_arguments(
                ligcif, ligpdb, mtz, apopdb, outdir, outfile, flags)
            # Initialise CommandManager
            self.Fitter = CommandManager(self.program)
            # Set Command-Line Args
            if cmd_line_args: self.Fitter.SetArguments(cmd_line_args)
            # Set Standard Input
            if std_inpt_args: self.Fitter.SetInput(std_inpt_args)
            # Set Parameters
            self.Fitter.SetParameters(timeout=self.timeout)
            # RUN
            self.Fitter.Run()
            # Calculate runtime (seconds)
            self.runtime = self.Fitter.runtime

            try:
                # Process results and generate the list of modelled ligands
                if self.verbose:
                    print('\tFinished fitting - post-processing models.')
                self._post_process(ligcif, ligpdb, mtz, apopdb, outdir,
                                   outfile, flags)

                if not self.outmodels:
                    raise FittingError(
                        'No fitted models found! Log: {!s}'.format(
                            self.outlog))

                if not os.path.exists(self.outpdb):
                    # Map the model of the best ligand to the asu and check it's near to the protein
                    self._map_to_asu(ligcif, ligpdb, mtz, apopdb, outdir,
                                     outfile, flags)
                    # Create symbolic links to the output file
                    self._link_output_files()

                # Merge the best ligand with the apo structure
                if not os.path.exists(self.mergedpdb):
                    self.Merger = merge_pdb_files(apopdb, self.outpdb,
                                                  self.mergedpdb)

            finally:
                self.write_log_file()

        return self.outpdb, self.mergedpdb, self.outlog