2
$\begingroup$

I would like to create a table of comparison among similar protein complexes from the pdb. This would be based on their numbers of proteins and the presence of each protein. Is there any way like Python etc. to do it more effectively?

For examples, PDB1, 2, 3 and 4 have 33, 22, 34 and 21 proteins in the complex respectively. Some proteins are commonly found in different PDB structures, while others are unique to specific PDB complex structures.

PDB1 for example have ABC and XYZ & so on in the complex but without ADG & QRS.

Say ultimately there would be 45 different unique/non-redundant proteins across all complex structures.

How to extract the name of all proteins from each complex structure and then create a non-redundant list at the left most column of table (e.g. ABC, ADG, QRS, XYZ and so on)

And also tick or cross the proteins listed (e.g. ABC) depending on when complexes (e.g. PDB1) have it.enter image description here

Thank you.

$\endgroup$
3
  • $\begingroup$ Please clarify your specific problem or provide additional details to highlight exactly what you need. As it's currently written, it's hard to tell exactly what you're asking. $\endgroup$
    – Community Bot
    Commented Jun 4 at 16:14
  • $\begingroup$ We need i) an example input, ii) the output you would expect from that example, and iii) the script you have written that doesn't work. This isn't a free script writing service, but we are happy to help you do it. $\endgroup$
    – terdon
    Commented Jun 5 at 12:26
  • $\begingroup$ do you mean something like rcsb.org/structure/1FFK , think you need to get a PDBx/mmcif parser get for each PDB the different entities and compare them $\endgroup$
    – pippo1980
    Commented Jun 6 at 16:13

2 Answers 2

1
$\begingroup$

for complexes like 1FFK , .cif file : 1FFK.cif

think you can try to parse each PDBx/mmcif file and extract what you need from this loop_ of the file :

..........
.........
.......

# 
loop_
_entity.id 
_entity.type 
_entity.src_method 
_entity.pdbx_description 
_entity.formula_weight 
_entity.pdbx_number_of_molecules 
_entity.pdbx_ec 
_entity.pdbx_mutation 
_entity.pdbx_fragment 
_entity.details 
1  polymer     nat '23S RRNA'                946034.375 1 ? ?                                  ? ? 
2  polymer     nat '5S RRNA'                 39318.414  1 ? ?                                  ? ? 
3  polymer     nat 'RIBOSOMAL PROTEIN L2'    25237.475  1 ? ?                                  ? ? 
4  polymer     nat 'RIBOSOMAL PROTEIN L3'    37223.176  1 ? 'GLU67 DELETION, TYR312 INSERTION' ? ? 
5  polymer     nat 'RIBOSOMAL PROTEIN L4'    26443.082  1 ? ?                                  ? ? 
6  polymer     nat 'RIBOSOMAL PROTEIN L5'    19420.498  1 ? ?                                  ? ? 
7  polymer     nat 'RIBOSOMAL PROTEIN L7AE'  12600.822  1 ? ?                                  ? ? 
8  polymer     nat 'RIBOSOMAL PROTEIN L10E'  17231.412  1 ? ?                                  ? ? 
9  polymer     nat 'RIBOSOMAL PROTEIN L13'   16249.214  1 ? ?                                  ? ? 
10 polymer     nat 'RIBOSOMAL PROTEIN L14'   14216.233  1 ? ?                                  ? ? 
11 polymer     nat 'RIBOSOMAL PROTEIN L15E'  23372.602  1 ? ?                                  ? ? 
12 polymer     nat 'RIBOSOMAL PROTEIN L15'   17874.172  1 ? ?                                  ? ? 
13 polymer     nat 'RIBOSOMAL PROTEIN L18'   20509.740  1 ? ?                                  ? ? 
14 polymer     nat 'RIBOSOMAL PROTEIN L18E'  12307.720  1 ? ?                                  ? ? 
15 polymer     nat 'RIBOSOMAL PROTEIN L19'   16631.322  1 ? ?                                  ? ? 
16 polymer     nat 'RIBOSOMAL PROTEIN L21E'  10436.604  1 ? ?                                  ? ? 
17 polymer     nat 'RIBOSOMAL PROTEIN L22'   16835.746  1 ? ?                                  ? ? 
18 polymer     nat 'RIBOSOMAL PROTEIN L23'   9481.340   1 ? ?                                  ? ? 
19 polymer     nat 'RIBOSOMAL PROTEIN L24'   13539.759  1 ? ?                                  ? ? 
20 polymer     nat 'RIBOSOMAL PROTEIN L24E'  7233.720   1 ? ?                                  ? ? 
21 polymer     nat 'RIBOSOMAL PROTEIN L29'   7758.667   1 ? ?                                  ? ? 
22 polymer     nat 'RIBOSOMAL PROTEIN L30'   17062.885  1 ? ?                                  ? ? 
23 polymer     nat 'RIBOSOMAL PROTEIN L31E'  10253.417  1 ? ?                                  ? ? 
24 polymer     nat 'RIBOSOMAL PROTEIN L32E'  16223.084  1 ? ?                                  ? ? 
25 polymer     nat 'RIBOSOMAL PROTEIN L37AE' 8085.725   1 ? ?                                  ? ? 
26 polymer     nat 'RIBOSOMAL PROTEIN L37E'  6199.007   1 ? ?                                  ? ? 
27 polymer     nat 'RIBOSOMAL PROTEIN L39E'  5994.880   1 ? ?                                  ? ? 
28 polymer     nat 'RIBOSOMAL PROTEIN L44E'  10815.245  1 ? ?                                  ? ? 
29 polymer     nat 'RIBOSOMAL PROTEIN L6'    19830.523  1 ? ?                                  ? ? 
30 non-polymer syn 'POTASSIUM ION'           39.098     1 ? ?                                  ? ? 
31 non-polymer syn 'MAGNESIUM ION'           24.305     2 ? ?                                  ? ? 
32 non-polymer syn 'CADMIUM ION'             112.411    4 ? ?                                  ? ? 
33 water       nat water                     18.015     6 ? ?                                  ? ? 
# 
loop_
_entity_name_com.entity_id 
_entity_name_com.name 
3  '50S RIBOSOMAL PROTEIN L2P, HMAL2, HL4'          
4  '50S RIBOSOMAL PROTEIN L3P, HMAL3, HL1'          
5  '50S RIBOSOMAL PROTEIN L4E, HMAL4, HL6'          
6  '50S RIBOSOMAL PROTEIN L5P, HMAL5, HL13'         
7  '30S RIBOSOMAL PROTEIN HS6'                      
9  '50S RIBOSOMAL PROTEIN L13P, HMAL13'             
10 '50S RIBOSOMAL PROTEIN L14P, HMAL14, HL27'       
12 '50S RIBOSOMAL PROTEIN L15P, HMAL15, HL9'        
13 '50S RIBOSOMAL PROTEIN L18P, HMAL18, HL12'       
14 '50S RIBOSOMAL PROTEIN L18E, HL29, L19'          
15 '50S RIBOSOMAL PROTEIN L19E, HMAL19, HL24'       
16 '50S RIBOSOMAL PROTEIN L21E, HL31'               
17 '50S RIBOSOMAL PROTEIN L22P, HMAL22, HL23'       
18 '50S RIBOSOMAL PROTEIN L23P, HMAL23, HL25, L21'  
19 '50S RIBOSOMAL PROTEIN L24P, HMAL24, HL16, HL15' 
20 '50S RIBOSOMAL PROTEIN L24E, HL21/HL22'          
21 '50S RIBOSOMAL PROTEIN L29P, HMAL29, HL33'       
22 '50S RIBOSOMAL PROTEIN L30P, HMAL30, HL20, HL16' 
23 '50S RIBOSOMAL PROTEIN L31E, L34, HL30'          
24 '50S RIBOSOMAL PROTEIN L32E, HL5'                
26 '50S RIBOSOMAL PROTEIN L37E, L35E'               
27 '50S RIBOSOMAL PROTEINS L39E, HL39E, HL46E'      
28 '50S RIBOSOMAL PROTEIN L44E, LA, HLA'            
29 '50S RIBOSOMAL PROTEIN L6P, HMAL6, HL10'         
# 
..........
.........
.......

Although not sure will always work see differences in 3CXC.cif vs 1W2B.cif where the former has the _entity_name_com.name loop_ missing

But before that think you'll have to filter _entity_poly.entity_id

for _entity_poly.type == 'polypeptide(L)'

Have a look at parsers here : PDBx/mmCIF Software Resources

for the table How to create Excel Table with pandas.to_excel()? SO post

$\endgroup$
1
$\begingroup$

OK using PDBx Python Parser and .cif of 1ffk , 1w2b , 3cxc and 1ffM.cif that is modded 1fkk where first row reads:

data_1FFM
# 
_entry.id   1FFM

and modded _entity_name_com loop :

loop_
_entity_name_com.entity_id 
_entity_name_com.name 
3  '50S RIBOSOMAL PROTEIN L2P, HMAL2, HL4'          
4  '50S RIBOSOMAL PROTEIN L3P, HMAL3, HL1'          
5  '50S RIBOSOMAL PROTEIN L4E, HMAL4, HL6'          
6  '50S RIBOSOMAL PROTEIN L5P, HMAL5, HL13'         
7  '30S RIBOSOMAL PROTEIN HS6'                      
9  '50S RIBOSOMAL PROTEIN L13P, HMAL13'             
10 '50S RIBOSOMAL PROTEIN L14P, HMAL14, HL27'       
12 '50S RIBOSOMAL PROTEIN L15P, HMAL15, HL9'        
13 '50S RIBOSOMAL PROTEIN L18P, HMAL18, HL12'       
14 '50S RIBOSOMAL PROTEIN L18E, HL29, L19'          
15 '50S RIBOSOMAL PROTEIN L19E, HMAL19, HL24'       
16 '50S RIBOSOMAL PROTEIN L21E, HLXX'               
17 '50S RIBOSOMAL PROTEIN L22P, HMALXX, HL23'       
18 '50S RIBOSOMAL PROTEIN L23P, HMAL23, HL25, L21'  
19 '50S RIBOSOMAL PROTEIN L24P, HMAL24, HL16, HL15' 
20 '50S RIBOSOMAL PROTEIN L24E, HL21/HL22'          
21 '50S RIBOSOMAL PROTEIN L29P, HMAL29, HL33'       
22 '50S RIBOSOMAL PROTEIN L30P, HMAL30, HL20, HL16' 
23 '50S RIBOSOMAL PROTEIN L31E, L34, HL30'          
24 '50S RIBOSOMAL PROTEIN L32E, HL5'                
26 '50S RIBOSOMAL PROTEIN L37E, L35E'               
27 '50S RIBOSOMAL PROTEINS L39E, HL39E, HL46E'      
28 '50S RIBOSOMAL PROTEIN L44E, LA, HLA'            
29 '50S RIBOSOMAL PROTEIN L6P, HMAL6, HL10' 
#

where I changen protein name with X:

16 '50S RIBOSOMAL PROTEIN L21E, HLXX'               
17 '50S RIBOSOMAL PROTEIN L22P, HMALXX, HL23'    

Using code:

import pdbx

from pdbx.reader.PdbxReader import PdbxReader

from pdbx.reader.PdbxContainers import *

print('PDBx version : ', pdbx.__version__)




import pandas as pd

# import xlsxwriter



pdbs = ['1ffk', '1w2b', '3cxc', '1ffM']


pdbs_dict = {}



for pdb in pdbs:
    
    try:
        
        with open( './' + pdb + '.cif') as open_cif:


            cif_parser = PdbxReader(open_cif)
            
            cif_data = []
            
            try :
            
                cif_parser.read(cif_data)
                
            except Exception as exc:
                
                print('\n\nERROR !!! while PDBxReader reads data of  :', pdb,'   ',  exc)
        
        
            for block in cif_data:
                
                
                if block.getName() == pdb.upper():
                    
                
                    print('\n\n', block.getObj('entry').getValue('id'),('\n\n_____________________'))
                    
                    
                    print(block)
                        
                    entities = [l[0] for l in block.getObj('entity_poly').getRowList() if l[1] == 'polypeptide(L)']
                        
                    print('entities :\n', entities)
                    

                    try :
                        
                        entities_names = []
                        
                        for i in entities :
                            
                            print('\n\n', i , type(i),'\n')
                            
                            # print(block.getObj('entity_name_com').getRowList())
                            
                            name = [l[1] for l in block.getObj('entity_name_com').getRowList() if l[0] == i]
    
                            print('1n1nname :\n', name, type(name))
                            
                            if name :
                            
                                entities_names.append(name[0])
                            
                    
                        pdbs_dict[pdb] = [len(entities_names), entities_names]
                            
                    
                    except Exception as exc:
                            
                            print("\n\nERROR !!! while reetriving 'entity_name_com' of  :", pdb,'   ',  exc)
                            
                else:
                    
                    print("\n\nERROR !!! while reetriving block.getName()  of  :", pdb)
          
    except :
        
        print('something went wrong with instatiating PdbxReader for : ' , pdb)
        
        
print('\n\npdbs_dict : \n', pdbs_dict)




for i, value in pdbs_dict.items():
    
    print(i , value[0], len(value[1]))


header = ['PDB Accession No.'] + [i for i, value in pdbs_dict.items()]

first_row = ['No. of unique proteins'] + [value[0] for i, value in pdbs_dict.items()]



## correct 2 linee
# unique_proteins_unflatten = [value[1] for i, value in pdbs_dict.items()]
# unique_proteins = [[x for xs in unique_proteins_unflatten for x in xs]]

## correct 1 linea
# unique_proteins =  [x for xs in [value[1] for i, value in pdbs_dict.items()] for x in xs]

# unique_proteins_set = set(unique_proteins)

# unique_proteins_list = list(unique_proteins_set)


unique_proteins_list =  list(set([x for xs in [value[1] for i, value in pdbs_dict.items()] for x in xs]))



print('\n\nheader : ' , header)

print('\n\nfirst_row :', first_row)

# print('\n\nunique_proteins', unique_proteins , len(unique_proteins))

# print('\n\nunique_proteins_set', unique_proteins_set, len(unique_proteins_set))

print('\n\nunique_proteins_list', unique_proteins_list, len(unique_proteins_list))




other_rows = []


for i in unique_proteins_list :
    
    
    row = [i]
    
    for pdb, value in pdbs_dict.items() :
        
        if i in value[1] :
            
            row.append('X')
            
        else:
            
            row.append('/')
            
    
    other_rows.append(row)
            
            
print('\n\n-------------------------')

for row in other_rows:
    
    print(row)
            
            




data = [first_row] + other_rows

print('\n\ndata : ', data , len(data))



df = pd.DataFrame(data, columns = header)

writer = pd.ExcelWriter('file.xlsx', engine='xlsxwriter')



df.to_excel(writer, sheet_name='Sheet1', index = False)

#https://stackoverflow.com/questions/69263078/pandas-dataframe-to-excel-cell-alignment
def align_center(x):
    return ['text-align: center' for x in x]

df.style.apply(align_center, axis=0).to_excel(
        writer,
        index=False,
        header=True
    )
workbook = writer.book
worksheet = writer.sheets['Sheet1']

## https://stackoverflow.com/questions/17326973/is-there-a-way-to-auto-adjust-excel-column-widths-with-pandas-excelwriter
#Iterate through each column and set the width == the max length in that column. A padding length of 2 is also added.
for i, col in enumerate(df.columns):
    # find length of column i
    column_len = df[col].astype(str).str.len().max()
    # Setting the length if the column header is larger
    # than the max column value length
    column_len = max(column_len, len(col)) + 2
    # set the column length
    worksheet.set_column(i, i, column_len)

writer.save()

Sorry for the number of prints, but needed to debug, I get the table below just check it to be sure it is what you where looking for

enter image description here

NOTES :

In the table No. of unique proteins means that I kept count of the names of proteins, not the amount of time the same protein is present in a complex (that I think would be difficult to parse, think you'll have to count it from the number of chains in which the proteis is present, check the dictionary : Dictionary Index mmcif_pdbx.dic).

I just used the first big complexes I got from a fast search on RCSB Protein Data Bank (RCSB PDB).

Countercheck my code, was the first time I tried this kinf of stuff, probably there are faster/better/cleaniest eway to get the risult, just use it as a blueprint.

Could be that Parser I am using is ostrokach/pdbx its on pypi too pdbx-mmcif 0.0.2 , but to be used with latest Python had to change :

PdbxReader.py

line 360 to :

# Tokenizer loop begins here ---
        while True:
            try:
                line = next(fileIter)
                self.__curLineNumber += 1
            except:
                return

not sure if it is because of PEP 479.

3CXC is skipped by my code because _entity_name_com.name loop_ is missing in its .cif file, not sure how the RCSB Protein Data Bank (RCSB PDB) is mantained so probably you'll have to keep it in mind or user other Categories.

I am not sure about univocity of protein names in RCSB Protein Data Bank (RCSB PDB) as shown by 1W2B.cis complex that is still a 50S ribosomal subunit of H. marismortui , see table results.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.