docs: def best_structures(uniprot_id, outname=None, outdir=None, seq_ident_cutoff=0.0, force_rerun=False):
      """Use the PDBe REST service to query for the best PDB structures for a UniProt ID.
  
      More information found here: https://www.ebi.ac.uk/pdbe/api/doc/sifts.html
      Link used to retrieve results: https://www.ebi.ac.uk/pdbe/api/mappings/best_structures/:accession
      The list of PDB structures mapping to a UniProt accession sorted by coverage of the protein and, if the same, resolution.
  
      Here is the ranking algorithm described by the PDB paper:
      https://nar.oxfordjournals.org/content/44/D1/D385.full
  
      "Finally, a single quality indicator is also calculated for each entry by taking the harmonic average
      of all the percentile scores representing model and model-data-fit quality measures and then subtracting
      10 times the numerical value of the resolution (in Angstrom) of the entry to ensure that resolution plays
      a role in characterising the quality of a structure. This single empirical 'quality measure' value is used
      by the PDBe query system to sort results and identify the 'best' structure in a given context. At present,
      entries determined by methods other than X-ray crystallography do not have similar data quality information
      available and are not considered as 'best structures'."
  
      Args:
          uniprot_id (str): UniProt Accession ID
          outname (str): Basename of the output file of JSON results
          outdir (str): Path to output directory of JSON results
          seq_ident_cutoff (float): Cutoff results based on percent coverage (in decimal form)
          force_rerun (bool): Obtain best structures mapping ignoring previously downloaded results
  
      Returns:
          list: Rank-ordered list of dictionaries representing chain-specific PDB entries. Keys are:
              * pdb_id: the PDB ID which maps to the UniProt ID
              * chain_id: the specific chain of the PDB which maps to the UniProt ID
              * coverage: the percent coverage of the entire UniProt sequence
              * resolution: the resolution of the structure
              * start: the structure residue number which maps to the start of the mapped sequence
              * end: the structure residue number which maps to the end of the mapped sequence
              * unp_start: the sequence residue number which maps to the structure start
              * unp_end: the sequence residue number which maps to the structure end
              * experimental_method: type of experiment used to determine structure
              * tax_id: taxonomic ID of the protein's original organism
  
      """
      outfile = ''
  
      if not outdir:
          outdir = ''
  
      # if output dir is specified but not outname, use the uniprot
      if not outname and outdir:
          outname = uniprot_id
  
      if outname:
          outname = op.join(outdir, outname)
          outfile = '{}.json'.format(outname)
  
      # Load a possibly existing json file
      if not ssbio.utils.force_rerun(flag=force_rerun, outfile=outfile):
          with open(outfile, 'r') as f:
              raw_data = json.load(f)
          log.debug('{}: loaded existing json file'.format(uniprot_id))
  
      # Otherwise run the web request
      else:
          # TODO: add a checker for a cached file of uniprot -> PDBs - can be generated within gempro pipeline and stored
          response = requests.get('https://www.ebi.ac.uk/pdbe/api/mappings/best_structures/{}'.format(uniprot_id),
                                  data={'key': 'value'})
          if response.status_code == 404:
              log.debug('{}: 404 returned, probably no structures available.'.format(uniprot_id))
              raw_data = {uniprot_id: {}}
          else:
              log.debug('{}: Obtained best structures'.format(uniprot_id))
              raw_data = response.json()
  
          # Write the json file if specified
          if outfile:
              with open(outfile, 'w') as f:
                  json.dump(raw_data, f)
              log.debug('{}: Saved json file of best structures'.format(uniprot_id))
  
      data = dict(raw_data)[uniprot_id]
  
      # Filter for sequence identity percentage
      if seq_ident_cutoff != 0:
          for result in data:
              if result['coverage'] < seq_ident_cutoff:
                  data.remove(result)
  
      return data