Answers.Body: <p>OK using <a href="https://mmcif.wwpdb.org/docs/sw-examples/python/html/index.html" rel="nofollow noreferrer">PDBx Python Parser</a> and .cif of <a href="https://files.rcsb.org/view/1FFK.cif" rel="nofollow noreferrer">1ffk</a> , <a href="https://files.rcsb.org/view/1W2B.cif" rel="nofollow noreferrer">1w2b</a> , <a href="https://files.rcsb.org/view/3CXC.cif" rel="nofollow noreferrer">3cxc</a> and <code>1ffM.cif</code> that is modded 1fkk where first row reads:</p>
  <pre><code>data_1FFM
  # 
  _entry.id   1FFM
  </code></pre>
  <p>and modded <code>_entity_name_com</code> loop :</p>
  <pre><code>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' 
  #
  </code></pre>
  <p>where I changen protein name with <strong>X</strong>:</p>
  <pre><code>16 '50S RIBOSOMAL PROTEIN L21E, HLXX'               
  17 '50S RIBOSOMAL PROTEIN L22P, HMALXX, HL23'    
  </code></pre>
  <p>Using code:</p>
  <pre><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(&quot;\n\nERROR !!! while reetriving 'entity_name_com' of  :&quot;, pdb,'   ',  exc)
                              
                  else:
                      
                      print(&quot;\n\nERROR !!! while reetriving block.getName()  of  :&quot;, 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()
  
  </code></pre>
  <p>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</p>
  <p><a href="https://i.sstatic.net/9QBR13MK.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/9QBR13MK.png" alt="enter image description here" /></a></p>
  <p><strong>NOTES</strong> :</p>
  <p>In the table <em>No. of unique proteins</em> 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 : <a href="https://mmcif.wwpdb.org/dictionaries/mmcif_pdbx_v50.dic/Index/" rel="nofollow noreferrer">Dictionary Index mmcif_pdbx.dic</a>).</p>
  <p>I just used the first big complexes I got from  a fast search on RCSB Protein Data Bank (RCSB PDB).</p>
  <p>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.</p>
  <p>Could be that Parser I am using is <a href="https://github.com/ostrokach/pdbx" rel="nofollow noreferrer">ostrokach/pdbx</a> its on pypi too <a href="https://pypi.org/project/pdbx-mmcif/" rel="nofollow noreferrer">pdbx-mmcif 0.0.2 </a>, but to be used with latest Python had to change :</p>
  <p><code>PdbxReader.py</code></p>
  <p>line 360 to :</p>
  <pre><code># Tokenizer loop begins here ---
          while True:
              try:
                  line = next(fileIter)
                  self.__curLineNumber += 1
              except:
                  return
  </code></pre>
  <p>not sure if it is because of PEP 479.</p>
  <p><strong>3CXC</strong> is skipped by my code because  <code>_entity_name_com.name</code> loop_ is missing in its <code>.cif</code> 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.</p>
  <p>I am not sure about univocity of protein names in RCSB Protein Data Bank (RCSB PDB) as  shown  by <code>1W2B.cis</code> complex that is still a 50S ribosomal subunit of <code>H. marismortui</code> , see table results.</p>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2024-06-08T21:34:59.277Z
Answers.LastActivityDate: 2024-06-08T21:34:59.277Z
Answers.UserDisplayName: pippo1980
Answers.Body: <p>for complexes like <a href="https://www.rcsb.org/structure/1FFK" rel="nofollow noreferrer">1FFK</a> , <code>.cif</code> file : <a href="https://files.rcsb.org/view/1FFK.cif" rel="nofollow noreferrer">1FFK.cif</a></p>
  <p>think you can try to parse each PDBx/mmcif file and extract what you need from this loop_ of the file :</p>
  <pre><code>..........
  .........
  .......
  
  # 
  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'         
  # 
  ..........
  .........
  .......
  </code></pre>
  <p>Although not sure will always work see differences in <a href="https://files.rcsb.org/view/3CXC.cif" rel="nofollow noreferrer">3CXC.cif</a> vs <a href="https://files.rcsb.org/view/1W2B.cif" rel="nofollow noreferrer">1W2B.cif</a> where the former has the <code>_entity_name_com.name</code> loop_ missing</p>
  <p>But before that think you'll have to filter <code>_entity_poly.entity_id</code></p>
  <p>for  <code>_entity_poly.type  == 'polypeptide(L)'</code></p>
  <p>Have a look at parsers here : <a href="https://mmcif.wwpdb.org/docs/software-resources.html" rel="nofollow noreferrer">PDBx/mmCIF Software Resources </a></p>
  <p>for the table <a href="https://stackoverflow.com/questions/58326392/how-to-create-excel-table-with-pandas-to-excel">How to create Excel <strong>Table</strong> with pandas.to_excel()?</a>  SO post</p>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2024-06-06T16:17:36.297Z
Answers.LastActivityDate: 2024-06-06T22:43:04.120Z
Answers.LastEditDate: 2024-06-06T22:43:04.120Z
Answers.UserDisplayName: pippo1980
Body: <p>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?</p>
  <p>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.</p>
  <p>PDB1 for example have ABC and XYZ &amp; so on in the complex but without ADG &amp; QRS.</p>
  <p>Say ultimately there would be 45 different unique/non-redundant proteins across all complex structures.</p>
  <p>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)</p>
  <p>And also tick or cross the proteins listed (e.g. ABC) depending on when complexes (e.g. PDB1) have it.<a href="https://i.sstatic.net/Wx2hfFHw.jpg" rel="nofollow noreferrer"><img src="https://i.sstatic.net/Wx2hfFHw.jpg" alt="enter image description here" /></a></p>
  <p>Thank you.</p>
  
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2024-06-04T16:14:44.847Z
Comments.Text: 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.
Comments.UserDisplayName: Community
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2024-06-05T12:26:09.730Z
Comments.Text: 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.
Comments.UserDisplayName: terdon
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2024-06-06T16:13:42.890Z
Comments.Text: do you mean something like https://www.rcsb.org/structure/1FFK , think you need to get a PDBx/mmcif parser get for each PDB the different entities and compare them
Comments.UserDisplayName: pippo1980
Tags: <r><python><pdb><shell><biopython>
Title: Python/R/bash script to ease the comparison of different protein complexes in PDB
ThreadText: # Python/R/bash script to ease the comparison of different protein complexes in PDB
  
  (Asked by: username_0 on 2024-06-04)
  
  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](https://i.sstatic.net/Wx2hfFHw.jpg)](https://i.sstatic.net/Wx2hfFHw.jpg)
  
  Thank you.
  
  **Tags:** r, python, pdb, shell, biopython
  
  > **Comments:**
  > **username_1**: 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.  
  > **username_2**: 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.  
  > **username_3**: do you mean something like https://www.rcsb.org/structure/1FFK , think you need to get a PDBx/mmcif parser get for each PDB the different entities and compare them  
  
  ---
  
  ## 2 answers
  
  ### Answer by username_3 on 2024-06-08. Score: 1
  
  OK using [PDBx Python Parser](https://mmcif.wwpdb.org/docs/sw-examples/python/html/index.html) and .cif of [1ffk](https://files.rcsb.org/view/1FFK.cif) , [1w2b](https://files.rcsb.org/view/1W2B.cif) , [3cxc](https://files.rcsb.org/view/3CXC.cif) 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](https://i.sstatic.net/9QBR13MK.png)](https://i.sstatic.net/9QBR13MK.png)
  
  **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](https://mmcif.wwpdb.org/dictionaries/mmcif_pdbx_v50.dic/Index/)).
  
  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](https://github.com/ostrokach/pdbx) its on pypi too [pdbx-mmcif 0.0.2](https://pypi.org/project/pdbx-mmcif/) , 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.
  
  
  ---
  
  ### Answer by username_3 on 2024-06-06. Score: 1
  
  for complexes like [1FFK](https://www.rcsb.org/structure/1FFK) , `.cif` file : [1FFK.cif](https://files.rcsb.org/view/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](https://files.rcsb.org/view/3CXC.cif) vs [1W2B.cif](https://files.rcsb.org/view/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](https://mmcif.wwpdb.org/docs/software-resources.html)
  
  for the table [How to create Excel **Table** with pandas.to\_excel()?](https://stackoverflow.com/questions/58326392/how-to-create-excel-table-with-pandas-to-excel) SO post
  
  
  ---
  
  