<commit_before>#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
PDB related functions used in the SCT suite of programs
"""

# Copyright 2014 University College London

# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at

#    http://www.apache.org/licenses/LICENSE-2.0

# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import seq

charmm_resids = {
'ASH': 'ASP',
'ANE': 'SIA',
'BFU': 'FUC',
'BGA': 'GAL',
'BGL': 'GLC',
'BMA': 'MAN',
'CYM': 'CYS',
'CYX': 'CYS',
'GLH': 'GLU',
'HIP': 'HIS',
'HID': 'HIS',
'HIE': 'HIS',
'HSD': 'HIS',
'LYN': 'LYS',
'TYM': 'TYR'
}

def pdb_res_line_parse(line):
    """Parse a single line from a PDB file into a dictionary according to
    the standard PDB column definitions

    @type  line: string
    @param line: Line from a PDB file.
    @rtype:      dictionary
    @return:     Contains:
                     - atom_no:   integer, atom number
                     - atom_name: string, atom name
                     - res_id:    string, residue three letter code
                     - chain:     string, chain identifier
                     - res_no:    integer, residue number
                     - coords:    list of floats, the x, y & z coordinates
    """

    data = {}

    # Only interested in ATOM and HETATM lines not REMARKs etc.
    # The type of record on the line is determined by the first 6 characters
    record = line[0:6].strip()
    if record in ['ATOM','HETATM']:

        # Split data on the line according to column definitions for PDB files
        # Ignore residues that we can't handle in SCT
        # TODO: This should perhaps give a warning

        # res_id is a three letter residue code
        res_id = line[17:20].strip()
        if res_id in seq.all_residues:
            data['atom_no'] = int(line[6:11])
            data['atom_name'] = line[12:16].strip()
            data['res_id'] = res_id
            data['chain'] = line[21:22].strip()
            data['res_no'] = int(line[22:26])
            x = float(line[30:38])
            y = float(line[38:46])
            z = float(line[46:54])
            data['coords'] = [x, y, z]

    return data

def read_pdb_atom_data (filename):
    """
    Read PDB file and return residue frequencies and atom coordinates

    @type  filename: string
    @param filename: Path to a PDB file.
    @rtype:   dictionary, list
    @return:  
              - Dictionary for residue type frequency. 
                Three letter residue code for the key and residue type
                frequency as the values. 
              - A list containing lists of x, y & z coordinates (3 * floats)
    """

    # Initialize a dictionary of all recognized residues (frequency = 0)
    res_freq = seq.residue_freq_dict()

    # Track the last residues seen
    last_res_no = 0

    atom_coords = []

    # Read in lines of the PDB
    # ATOM and HETATM records are interpretted - others ignored
    with open(filename) as f:
        for line in f:
            data = pdb_res_line_parse(line)

            if len(data) != 0:
                atom_coords.append(data['coords'])
                # If residue number has changed increment res_id tally

                if data['res_no'] != last_res_no:
                    if data['res_id'] in charmm_resids:
                        res_name = charmm_resids[data['res_id']]
                    else:<commit_msg>Improved the CHARMM residue reading code (nearly works now)<commit_after>#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
PDB related functions used in the SCT suite of programs
"""

# Copyright 2014 University College London

# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at

#    http://www.apache.org/licenses/LICENSE-2.0

# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import seq

# Dictionary of CHARMM residue names to standard naming
charmm_resids = {
'ASH': 'ASP',
'ANE': 'SIA',
'BFU': 'FUC',
'BGA': 'GAL',
'BGL': 'GLC',
'BMA': 'MAN',
'CYM': 'CYS',
'CYX': 'CYS',
'GLH': 'GLU',
'HIP': 'HIS',
'HID': 'HIS',
'HIE': 'HIS',
'HSD': 'HIS',
'LYN': 'LYS',
'TYM': 'TYR'
}

# We will accept either standard or CHARMM residue naming
accept_resids = seq.all_residues + charmm_resids.keys()

def pdb_res_line_parse(line):
    """Parse a single line from a PDB file into a dictionary according to
    the standard PDB column definitions

    @type  line: string
    @param line: Line from a PDB file.
    @rtype:      dictionary
    @return:     Contains:
                     - atom_no:   integer, atom number
                     - atom_name: string, atom name
                     - res_id:    string, residue three letter code
                     - chain:     string, chain identifier
                     - res_no:    integer, residue number
                     - coords:    list of floats, the x, y & z coordinates
    """

    data = {}

    # Only interested in ATOM and HETATM lines not REMARKs etc.
    # The type of record on the line is determined by the first 6 characters
    record = line[0:6].strip()
    if record in ['ATOM','HETATM']:

        # Split data on the line according to column definitions for PDB files
        # Ignore residues that we can't handle in SCT
        # TODO: This should perhaps give a warning

        # res_id is a three letter residue code
        res_id = line[17:20].strip()
        if res_id in accept_resids:
            data['atom_no'] = int(line[6:11])
            data['atom_name'] = line[12:16].strip()
            data['res_id'] = res_id
            data['chain'] = line[21:22].strip()
            data['res_no'] = int(line[22:26])
            x = float(line[30:38])
            y = float(line[38:46])
            z = float(line[46:54])
            data['coords'] = [x, y, z]

    return data

def read_pdb_atom_data (filename):
    """
    Read PDB file and return residue frequencies and atom coordinates

    @type  filename: string
    @param filename: Path to a PDB file.
    @rtype:   dictionary, list
    @return:  
              - Dictionary for residue type frequency. 
                Three letter residue code for the key and residue type
                frequency as the values. 
              - A list containing lists of x, y & z coordinates (3 * floats)
    """

    # Initialize a dictionary of all recognized residues (frequency = 0)
    res_freq = seq.residue_freq_dict()

    # Track the last residues seen
    last_res_no = 0

    atom_coords = []

    # Read in lines of the PDB
    # ATOM and HETATM records are interpretted - others ignored
    with open(filename) as f:
        for line in f:
            data = pdb_res_line_parse(line)

            if len(data) != 0:
                atom_coords.append(data['coords'])
                # If residue number has changed increment res_id tally

                if data['res_no'] != last_res_no:
                    # If a CHARMM residue name is used convert to standard naming
                    if data['res_id'] in charmm_resids:
                        res_name = charmm_resids[data['res_id']]
                    else:
{'fraction_non_alphanumeric': 0.09938366718027734, 'fraction_numerical': 0.012069851052901901, 'mean_word_length': 2.2359783963439965, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '303498', 'n_tokens_mistral': 2413, 'n_tokens_neox': 2242, 'n_words': 858}