nodes: 0, module; 1, function_definition; 2, function_name:map_uniprot_to_pdb; 3, parameters; 4, block; 5, identifier:self; 6, default_parameter; 7, default_parameter; 8, default_parameter; 9, expression_statement; 10, if_statement; 11, comment:# Check if a UniProt ID is attached to the representative sequence; 12, expression_statement; 13, if_statement; 14, if_statement; 15, if_statement; 16, expression_statement; 17, expression_statement; 18, if_statement; 19, return_statement; 20, identifier:seq_ident_cutoff; 21, float:0.0; 22, identifier:outdir; 23, None; 24, identifier:force_rerun; 25, False; 26, comment:"""Map the representative sequence's UniProt ID to PDB IDs using the PDBe "Best Structures" API.
          Will save a JSON file of the results to the protein sequences folder.
  
          The "Best structures" API is available at https://www.ebi.ac.uk/pdbe/api/doc/sifts.html
          The list of PDB structures mapping to a UniProt accession sorted by coverage of the protein and,
          if the same, resolution.
  
          Args:
              seq_ident_cutoff (float): Sequence identity cutoff in decimal form
              outdir (str): Output directory to cache JSON results of search
              force_rerun (bool): Force re-downloading of JSON results if they already exist
  
          Returns:
              list: A rank-ordered list of PDBProp objects that map to the UniProt ID
  
          """; 27, not_operator; 28, block; 29, assignment; 30, not_operator; 31, block; 32, comparison_operator:'-' in uniprot_id; 33, block; 34, not_operator; 35, block; 36, assignment; 37, assignment; 38, identifier:best_structures; 39, block; 40, else_clause; 41, identifier:new_pdbs; 42, attribute; 43, expression_statement; 44, return_statement; 45, identifier:uniprot_id; 46, attribute; 47, identifier:uniprot_id; 48, expression_statement; 49, return_statement; 50, string; 51, identifier:uniprot_id; 52, expression_statement; 53, expression_statement; 54, identifier:outdir; 55, expression_statement; 56, if_statement; 57, identifier:best_structures; 58, call; 59, identifier:new_pdbs; 60, list; 61, expression_statement; 62, for_statement; 63, expression_statement; 64, block; 65, identifier:self; 66, identifier:representative_sequence; 67, call; 68, None; 69, attribute; 70, identifier:uniprot; 71, call; 72, None; 73, string_content:-; 74, call; 75, assignment; 76, assignment; 77, not_operator; 78, block; 79, attribute; 80, argument_list; 81, assignment; 82, identifier:best_structure; 83, identifier:best_structures; 84, block; 85, call; 86, expression_statement; 87, attribute; 88, argument_list; 89, identifier:self; 90, identifier:representative_sequence; 91, attribute; 92, argument_list; 93, attribute; 94, argument_list; 95, identifier:uniprot_id; 96, subscript; 97, identifier:outdir; 98, attribute; 99, identifier:outdir; 100, raise_statement; 101, attribute; 102, identifier:best_structures; 103, identifier:uniprot_id; 104, keyword_argument; 105, keyword_argument; 106, keyword_argument; 107, keyword_argument; 108, identifier:rank; 109, integer:1; 110, expression_statement; 111, expression_statement; 112, expression_statement; 113, comment:# load_pdb will append this protein to the list; 114, expression_statement; 115, comment:# Also add this chain to the chains attribute so we can save the; 116, comment:# info we get from best_structures; 117, expression_statement; 118, expression_statement; 119, expression_statement; 120, expression_statement; 121, expression_statement; 122, expression_statement; 123, expression_statement; 124, expression_statement; 125, attribute; 126, argument_list; 127, call; 128, identifier:log; 129, identifier:error; 130, call; 131, identifier:log; 132, identifier:error; 133, call; 134, identifier:log; 135, identifier:debug; 136, call; 137, call; 138, integer:0; 139, identifier:self; 140, identifier:sequence_dir; 141, call; 142, attribute; 143, identifier:pdb; 144, identifier:outname; 145, call; 146, identifier:outdir; 147, identifier:outdir; 148, identifier:seq_ident_cutoff; 149, identifier:seq_ident_cutoff; 150, identifier:force_rerun; 151, identifier:force_rerun; 152, assignment; 153, call; 154, assignment; 155, assignment; 156, call; 157, assignment; 158, assignment; 159, call; 160, assignment; 161, call; 162, call; 163, augmented_assignment; 164, identifier:log; 165, identifier:debug; 166, call; 167, attribute; 168, argument_list; 169, attribute; 170, argument_list; 171, attribute; 172, argument_list; 173, attribute; 174, argument_list; 175, attribute; 176, argument_list; 177, identifier:ValueError; 178, argument_list; 179, identifier:ssbio; 180, identifier:databases; 181, attribute; 182, argument_list; 183, identifier:currpdb; 184, call; 185, attribute; 186, argument_list; 187, identifier:currchain; 188, call; 189, identifier:new_pdb; 190, call; 191, attribute; 192, argument_list; 193, identifier:pdb_specific_keys; 194, list; 195, identifier:chain_specific_keys; 196, list; 197, attribute; 198, argument_list; 199, identifier:new_chain; 200, call; 201, attribute; 202, argument_list; 203, attribute; 204, argument_list; 205, identifier:rank; 206, integer:1; 207, attribute; 208, argument_list; 209, identifier:log; 210, identifier:debug; 211, call; 212, string; 213, identifier:format; 214, attribute; 215, string; 216, identifier:format; 217, attribute; 218, string:'{}: "-" detected in UniProt ID, isoform specific sequences are ignored with best structures API'; 219, identifier:format; 220, attribute; 221, identifier:uniprot_id; 222, identifier:split; 223, string; 224, string; 225, string; 226, identifier:format; 227, call; 228, identifier:str; 229, argument_list; 230, identifier:new_pdbs; 231, identifier:append; 232, identifier:currpdb; 233, identifier:str; 234, argument_list; 235, attribute; 236, argument_list; 237, identifier:new_pdb; 238, identifier:add_chain_ids; 239, identifier:currchain; 240, string; 241, string; 242, string; 243, string; 244, string; 245, string; 246, string; 247, identifier:new_pdb; 248, identifier:update; 249, identifier:best_structure; 250, keyword_argument; 251, attribute; 252, argument_list; 253, identifier:new_chain; 254, identifier:update; 255, identifier:best_structure; 256, keyword_argument; 257, identifier:new_chain; 258, identifier:update; 259, dictionary; 260, string; 261, identifier:format; 262, attribute; 263, identifier:uniprot_id; 264, call; 265, attribute; 266, argument_list; 267, string_content:{}: no representative sequence set, cannot use best structures API; 268, identifier:self; 269, identifier:id; 270, string_content:{}: no representative UniProt ID set, cannot use best structures API; 271, identifier:self; 272, identifier:id; 273, identifier:self; 274, identifier:id; 275, string_content:-; 276, string_content:Output directory must be specified; 277, string_content:{}_best_structures; 278, identifier:custom_slugify; 279, argument_list; 280, call; 281, subscript; 282, identifier:self; 283, identifier:load_pdb; 284, keyword_argument; 285, keyword_argument; 286, string_content:experimental_method; 287, string_content:resolution; 288, string_content:coverage; 289, string_content:start; 290, string_content:end; 291, string_content:unp_start; 292, string_content:unp_end; 293, identifier:only_keys; 294, identifier:pdb_specific_keys; 295, attribute; 296, identifier:get_by_id; 297, identifier:currchain; 298, identifier:only_keys; 299, identifier:chain_specific_keys; 300, pair; 301, string_content:{}, {}: {} PDB/chain pairs mapped; 302, identifier:self; 303, identifier:id; 304, identifier:len; 305, argument_list; 306, string; 307, identifier:format; 308, attribute; 309, identifier:uniprot_id; 310, identifier:uniprot_id; 311, attribute; 312, argument_list; 313, identifier:best_structure; 314, string; 315, identifier:pdb_id; 316, identifier:currpdb; 317, identifier:mapped_chains; 318, identifier:currchain; 319, identifier:new_pdb; 320, identifier:chains; 321, string; 322, identifier:rank; 323, identifier:best_structures; 324, string_content:{}, {}: no PDB/chain pairs mapped; 325, identifier:self; 326, identifier:id; 327, subscript; 328, identifier:lower; 329, string_content:chain_id; 330, string_content:rank; 331, identifier:best_structure; 332, string; 333, string_content:pdb_id
code: def map_uniprot_to_pdb(self, seq_ident_cutoff=0.0, outdir=None, force_rerun=False):
          """Map the representative sequence's UniProt ID to PDB IDs using the PDBe "Best Structures" API.
          Will save a JSON file of the results to the protein sequences folder.
  
          The "Best structures" API is available at https://www.ebi.ac.uk/pdbe/api/doc/sifts.html
          The list of PDB structures mapping to a UniProt accession sorted by coverage of the protein and,
          if the same, resolution.
  
          Args:
              seq_ident_cutoff (float): Sequence identity cutoff in decimal form
              outdir (str): Output directory to cache JSON results of search
              force_rerun (bool): Force re-downloading of JSON results if they already exist
  
          Returns:
              list: A rank-ordered list of PDBProp objects that map to the UniProt ID
  
          """
          if not self.representative_sequence:
              log.error('{}: no representative sequence set, cannot use best structures API'.format(self.id))
              return None
  
          # Check if a UniProt ID is attached to the representative sequence
          uniprot_id = self.representative_sequence.uniprot
          if not uniprot_id:
              log.error('{}: no representative UniProt ID set, cannot use best structures API'.format(self.id))
              return None
  
          if '-' in uniprot_id:
              log.debug('{}: "-" detected in UniProt ID, isoform specific sequences are ignored with best structures API'.format(self.id))
              uniprot_id = uniprot_id.split('-')[0]
  
          if not outdir:
              outdir = self.sequence_dir
              if not outdir:
                  raise ValueError('Output directory must be specified')
  
          best_structures = ssbio.databases.pdb.best_structures(uniprot_id,
                                                                outname='{}_best_structures'.format(custom_slugify(uniprot_id)),
                                                                outdir=outdir,
                                                                seq_ident_cutoff=seq_ident_cutoff,
                                                                force_rerun=force_rerun)
  
          new_pdbs = []
          if best_structures:
              rank = 1
              for best_structure in best_structures:
                  currpdb = str(best_structure['pdb_id'].lower())
                  new_pdbs.append(currpdb)
                  currchain = str(best_structure['chain_id'])
  
                  # load_pdb will append this protein to the list
                  new_pdb = self.load_pdb(pdb_id=currpdb, mapped_chains=currchain)
  
                  # Also add this chain to the chains attribute so we can save the
                  # info we get from best_structures
                  new_pdb.add_chain_ids(currchain)
  
                  pdb_specific_keys = ['experimental_method', 'resolution']
                  chain_specific_keys = ['coverage', 'start', 'end', 'unp_start', 'unp_end']
  
                  new_pdb.update(best_structure, only_keys=pdb_specific_keys)
                  new_chain = new_pdb.chains.get_by_id(currchain)
                  new_chain.update(best_structure, only_keys=chain_specific_keys)
                  new_chain.update({'rank': rank})
  
                  rank += 1
  
              log.debug('{}, {}: {} PDB/chain pairs mapped'.format(self.id, uniprot_id, len(best_structures)))
          else:
              log.debug('{}, {}: no PDB/chain pairs mapped'.format(self.id, uniprot_id))
  
          return new_pdbs