docs: def get_generic_subseq_within_2_5D(protein, prop_name, within, filter_resnums=None):
          """Get a subsequence from REPSEQ based on a feature stored in REPSEQ and within the set distance in REPSTRUCT.REPCHAIN.
          If there are multiple sites within the feature, they are first searched separately for residues within the distance,
          then the residues are combined for the final output.
          """
          from ssbio.biopython.Bio.Struct.Geometry import center_of_mass
          sites = list(set(protein.representative_sequence.letter_annotations[prop_name]))
          sites.remove(False)
  
          if len(sites) > 0:
              log.debug(
                  '{} unique {} sites to find subsequence within {} angstroms of'.format(len(sites), prop_name, within))
              ps = protein.representative_structure.parse_structure()
  
              all_subseq_resnums = []
              for site in sites:
                  site_binding_residues, site_binding_resnums = protein.representative_sequence.get_subsequence_from_property(
                      property_key=prop_name,
                      property_value=site, condition='=', return_resnums=True)
                  mapping_to_structure_resnums = protein.map_seqprop_resnums_to_structprop_resnums(
                      resnums=site_binding_resnums,
                      use_representatives=True)
                  all_residues = []
                  for resnum in mapping_to_structure_resnums:
                      try:
                          target_residue = ps.first_model[protein.representative_chain][resnum]
                      except KeyError:
                          log.error('Protein {}, RepStruct {}-{}: cannot find resnum {}, not including in list of '
                                    'residues to find center of mass'.format(protein.id,
                                                                             protein.representative_structure.id,
                                                                             protein.representative_chain, resnum))
                          continue
                      all_residues.append(target_residue)
                  if not all_residues:
                      log.error('{}->{}-{}: unable to map resnums to structure'.format(site_binding_resnums,
                                                                                       protein.representative_structure.id,
                                                                                       protein.representative_chain))
                      continue
                  coords = center_of_mass(all_residues, geometric=True)
                  log.debug('{}: center of mass of site {}'.format(coords, site))
                  subseq, subseq_resnums = protein.representative_structure.get_seqprop_within(
                      chain_id=protein.representative_chain,
                      angstroms=within, resnum=None,
                      custom_coord=coords, return_resnums=True)
                  log.debug('{}: structure resnums within {} of site {} (resnums {})'.format(subseq_resnums, within, site,
                                                                                             site_binding_resnums))
                  all_subseq_resnums.extend(subseq_resnums)
          else:
              log.debug('No {} sites'.format(prop_name))
              return {'subseq_len': 0, 'subseq': None, 'subseq_resnums': []}
  
          # Combine and filter the site binding site residue numbers (if desired)
          if filter_resnums:
              all_subseq_resnums = list(set(all_subseq_resnums).intersection(filter_resnums))
          else:
              all_subseq_resnums = list(set(all_subseq_resnums))
  
          # Get the chain subseq so we can save letter annotations later
          chain_subseq = protein.get_representative_chain.get_subsequence(all_subseq_resnums)
  
          # Now get the subsequence of the repseq and return it
          mapping_dict = protein.map_structprop_resnums_to_seqprop_resnums(resnums=all_subseq_resnums,
                                                                           structprop=protein.representative_structure,
                                                                           chain_id=protein.representative_chain,
                                                                           seqprop=protein.representative_sequence)
          sub_id = '{}-{}->{}_within_{}_{}_extracted'.format(protein.representative_structure.id,
                                                             protein.representative_chain,
                                                             protein.representative_sequence.id,
                                                             within, prop_name)
          seqprop_resnums = [v for k, v in mapping_dict.items()]
          new_sp = protein.representative_sequence.get_subsequence(resnums=seqprop_resnums, new_id=sub_id,
                                                                   copy_letter_annotations=False)
          try:
              new_sp.letter_annotations = chain_subseq.letter_annotations
          except (AttributeError, TypeError):
              log.error('Protein {}, StructProp {}-{}: unable to copy chain subseq letter annotations'.format(protein.id,
                                                                                                              protein.representative_structure.id,
                                                                                                              protein.representative_chain))
  
          return {'subseq_len': len(seqprop_resnums), 'subseq': new_sp, 'subseq_resnums': seqprop_resnums}