Source code for wbia.control.manual_species_funcs

# -*- coding: utf-8 -*-
"""
python -c "import utool as ut; ut.write_modscript_alias('Tgen.sh', 'wbia.templates.template_generator')"
sh Tgen.sh --key species --invert --Tcfg with_getters=True with_setters=False --modfname manual_species_funcs

# TODO: Fix this name it is too special case
"""
import logging
import uuid
import functools

# import numpy as np
# import vtool as vt
import numpy as np
from wbia import constants as const
from wbia.control import accessor_decors, controller_inject  # NOQA
import utool as ut
from wbia.control.controller_inject import make_ibs_register_decorator

print, rrr, profile = ut.inject2(__name__)
logger = logging.getLogger('wbia')


CLASS_INJECT_KEY, register_ibs_method = make_ibs_register_decorator(__name__)


register_api = controller_inject.get_wbia_flask_api(__name__)


SPECIES_ROWID = 'species_rowid'
SPECIES_UUID = 'species_uuid'
SPECIES_TEXT = 'species_text'
SPECIES_NICE = 'species_nice'
SPECIES_CODE = 'species_code'
SPECIES_NOTE = 'species_note'
SPECIES_ENABLED = 'species_toggle_enabled'


@register_ibs_method
@accessor_decors.ider
@register_api('/api/species/', methods=['GET'], __api_plural_check__=False)
def _get_all_species_rowids(ibs):
    r"""
    Returns:
        list_ (list): all nids of known animals
        (does not include unknown names)
    """
    # all_known_species_rowids = ibs._get_all_known_lblannot_rowids(const.SPECIES_KEY)
    all_known_species_rowids = ibs.db.get_all_rowids(const.SPECIES_TABLE)
    return all_known_species_rowids


[docs]@register_ibs_method @accessor_decors.ider def get_all_species_texts(ibs): r""" Returns: list_ (list): all nids of known animals (does not include unknown names) """ species_rowid_list = ibs._get_all_species_rowids() species_text_list = ibs.get_species_texts(species_rowid_list) return species_text_list
[docs]@register_ibs_method @accessor_decors.ider def get_all_species_nice(ibs): r""" Returns: list_ (list): all nids of known animals (does not include unknown names) """ species_rowid_list = ibs._get_all_species_rowids() species_nice_list = ibs.get_species_nice(species_rowid_list) return species_nice_list
[docs]@register_ibs_method # @register_api('/api/species/sanitize/', methods=['PUT']) def sanitize_species_texts(ibs, species_text_list): r""" changes unknown species to the unknown value Args: ibs (IBEISController): wbia controller object species_text_list (list): Returns: list: species_text_list_ CommandLine: python -m wbia.control.manual_species_funcs --test-sanitize_species_texts RESTful: Method: POST URL: /api/species/sanitize Example: >>> # ENABLE_DOCTEST >>> from wbia.control.manual_species_funcs import * # NOQA >>> import wbia >>> # build test data >>> ibs = wbia.opendb('testdb1') >>> species_text_list = ['foo', 'bar', 'zebra_plains'] >>> # execute function >>> species_text_list_ = sanitize_species_texts(ibs, species_text_list) >>> # verify results >>> result = ut.repr2(species_text_list_, nl=False) >>> print(result) ['foo', 'bar', 'zebra_plains'] """ # valid_species = ibs.get_all_species_texts() # ibsfuncs.assert_valid_species_texts(ibs, species_text_list, iswarning=True) # def _sanitize_species_text(species_text): # if species_text is None: # return None # elif species_text in valid_species: # return species_text # else: # return const.UNKNOWN # species_text_list_ = [_sanitize_species_text(species_text) # for species_text in species_text_list] # # old but same logic # #species_text_list_ = [None if species_text is None else # # species_text if species_text in valid_species else # # const.UNKNOWN # # for species_text in species_text_list] # # oldest different logic # #species_text_list_ = [None # # if species_text is None or species_text == const.UNKNOWN # # else species_text.lower() # # for species_text in species_text_list] # #species_text_list_ = [species_text if species_text in valid_species else None # # for species_text in species_text_list_] # return species_text_list_ return species_text_list
def _convert_species_nice_to_text(species_nice_list): import re def _convert(nice): nice = re.sub(r'[ ]+', '_', nice) nice = re.sub(r'[^a-zA-Z0-9_\+]+', '', nice) nice = re.sub(r'[_]+', '_', nice) nice = nice.lower() return nice return [_convert(species_nice) for species_nice in species_nice_list] def _convert_species_nice_to_code(species_nice_list): import re def _convert(text): text = re.sub(r'[_]+', ' ', text) text = text.title() text = re.sub(r'[^A-Z0-9\+]+', '', text) return text species_text_list = _convert_species_nice_to_text(species_nice_list) return [_convert(species_text) for species_text in species_text_list]
[docs]@register_ibs_method @accessor_decors.adder @register_api('/api/species/', methods=['POST'], __api_plural_check__=False) def add_species( ibs, species_nice_list, species_text_list=None, species_code_list=None, species_uuid_list=None, species_note_list=None, skip_cleaning=False, ): r""" Adds a list of species. Returns: list: speciesid_list - species rowids RESTful: Method: POST URL: /api/species/ CommandLine: python -m wbia.control.manual_species_funcs --test-add_species Example: >>> # ENABLE_DOCTEST >>> from wbia.control.manual_species_funcs import * # NOQA >>> import wbia >>> import utool as ut >>> ibs = wbia.opendb('testdb1') >>> species_text_list = [ ... 'jaguar', 'zebra_plains', 'zebra_plains', '____', 'TYPO', ... '____', 'zebra_grevys', 'bear_polar+head'] >>> species_rowid_list = ibs.add_species(species_text_list) >>> print(ut.repr2(list(zip(species_text_list, species_rowid_list)))) >>> ibs.print_species_table() >>> species_text = ibs.get_species_texts(species_rowid_list) >>> # Ensure we leave testdb1 in a clean state >>> ibs.delete_species(ibs.get_species_rowids_from_text(['jaguar', 'TYPO'])) >>> all_species_rowids = ibs._get_all_species_rowids() >>> result = ut.repr2(species_text, nl=False) + '\n' >>> result += ut.repr2(all_species_rowids, nl=False) + '\n' >>> result += ut.repr2(ibs.get_species_texts(all_species_rowids), nl=False) + '\n' >>> result += ut.repr2(ibs.get_species_codes(all_species_rowids), nl=False) >>> print(result) ['jaguar', 'zebra_plains', 'zebra_plains', '____', 'typo', '____', 'zebra_grevys', 'bear_polar+head'] [1, 2, 3, 6] ['zebra_plains', 'zebra_grevys', 'bear_polar', 'bear_polar+head'] ['PZ', 'GZ', 'PB', 'BP+H'] """ # Strip all spaces species_nice_list = [ const.UNKNOWN if _ is None else _.strip() for _ in species_nice_list ] if species_text_list is None: species_text_list = _convert_species_nice_to_text(species_nice_list) if species_code_list is None: species_code_list = _convert_species_nice_to_code(species_nice_list) if species_note_list is None: species_note_list = [''] * len(species_text_list) if species_uuid_list is None: species_uuid_list = [uuid.uuid4() for _ in range(len(species_text_list))] # Sanatize to remove invalid names flag_list = np.array( [ species_nice is None or species_nice.strip() in ['_', const.UNKNOWN, 'none', 'None', ''] for species_nice in species_nice_list ] ) species_uuid_list = ut.filterfalse_items(species_uuid_list, flag_list) species_nice_list = ut.filterfalse_items(species_nice_list, flag_list) species_text_list = ut.filterfalse_items(species_text_list, flag_list) species_code_list = ut.filterfalse_items(species_code_list, flag_list) species_note_list = ut.filterfalse_items(species_note_list, flag_list) superkey_paramx = (1,) # TODO Allow for better ensure=False without using partial # Just autogenerate these functions get_rowid_from_superkey = functools.partial( ibs.get_species_rowids_from_text, ensure=False ) colnames = [SPECIES_UUID, SPECIES_TEXT, SPECIES_NICE, SPECIES_CODE, SPECIES_NOTE] params_iter = list( zip( species_uuid_list, species_text_list, species_nice_list, species_code_list, species_note_list, ) ) species_rowid_list = ibs.db.add_cleanly( const.SPECIES_TABLE, colnames, params_iter, get_rowid_from_superkey, superkey_paramx, ) temp_list = np.array([-1] * len(flag_list)) temp_list[flag_list == False] = np.array(species_rowid_list) # NOQA temp_list[flag_list == True] = const.UNKNOWN_SPECIES_ROWID # NOQA species_rowid_list = list(temp_list) assert -1 not in species_rowid_list # Clean species if not skip_cleaning: species_mapping_dict = ibs._clean_species() if species_mapping_dict is not None: species_rowid_list = [ species_mapping_dict.get(species_rowid, species_rowid) for species_rowid in species_rowid_list ] return species_rowid_list
# value_list = ibs.sanitize_species_texts(species_text_list) # lbltype_rowid = ibs.lbltype_ids[const.SPECIES_KEY] # lbltype_rowid_list = [lbltype_rowid] * len(species_text_list) # species_rowid_list = ibs.add_lblannots(lbltype_rowid_list, value_list, species_note_list) # # species_rowid_list = [const.UNKNOWN_SPECIES_ROWID if rowid is None else # rowid for rowid in species_rowid_list] # return species_rowid_list
[docs]@register_ibs_method @accessor_decors.deleter # @cache_invalidator(const.SPECIES_TABLE) @register_api('/api/species/', methods=['DELETE'], __api_plural_check__=False) def delete_species(ibs, species_rowid_list): r""" deletes species from the database CAREFUL. YOU PROBABLY DO NOT WANT TO USE THIS at least ensure that no annot is associated with any of these species rowids RESTful: Method: DELETE URL: /api/species/ """ if ut.VERBOSE: logger.info('[ibs] deleting %d speciess' % len(species_rowid_list)) ibs.db.delete_rowids(const.SPECIES_TABLE, species_rowid_list)
# ibs.delete_lblannots(species_rowid_list)
[docs]@register_ibs_method # @accessor_decors.deleter def delete_empty_species(ibs): r""" deletes empty species from the database """ species_text_set = set(ibs.get_all_species_texts()) aid_list = ibs.get_valid_aids() used_species_text_set = set(ibs.get_annot_species_texts(aid_list)) unused_species_text_set = species_text_set - used_species_text_set unused_species_text_list = list(unused_species_text_set) unused_species_rowid_list = ibs.get_species_rowids_from_text(unused_species_text_list) logger.info('Deleting unused species: %r' % (unused_species_text_list,)) ibs.delete_species(unused_species_rowid_list)
[docs]@register_ibs_method @accessor_decors.getter_1to1 @register_api('/api/species/rowid/text/', methods=['GET'], __api_plural_check__=False) def get_species_rowids_from_text(ibs, species_text_list, ensure=True, **kwargs): r""" Returns: species_rowid_list (list): Creates one if it doesnt exist CommandLine: python -m wbia.control.manual_species_funcs --test-get_species_rowids_from_text:0 python -m wbia.control.manual_species_funcs --test-get_species_rowids_from_text:1 RESTful: Method: GET URL: /api/species/rowid/text/ Example: >>> # ENABLE_DOCTEST >>> from wbia.control.manual_species_funcs import * # NOQA >>> import wbia >>> import utool as ut >>> ibs = wbia.opendb('testdb1') >>> species_text_list = [ ... u'jaguar', u'zebra_plains', u'zebra_plains', '____', 'TYPO', ... '____', u'zebra_grevys', u'bear_polar'] >>> ensure = False >>> species_rowid_list = ibs.get_species_rowids_from_text(species_text_list, ensure) >>> # print(ut.repr2(list(zip(species_text_list, species_rowid_list)))) >>> ensure = True >>> species_rowid_list = ibs.get_species_rowids_from_text(species_text_list, ensure) >>> # print(ut.repr2(list(zip(species_text_list, species_rowid_list)))) >>> ibs.print_species_table() >>> species_text = ibs.get_species_texts(species_rowid_list) >>> # Ensure we leave testdb1 in a clean state >>> ibs.delete_species(ibs.get_species_rowids_from_text(['jaguar', 'TYPO'])) >>> all_species_rowids = ibs._get_all_species_rowids() >>> assert ut.repr2(species_text, nl=False) == ['jaguar', 'zebra_plains', 'zebra_plains', '____', 'typo', '____', 'zebra_grevys', 'bear_polar'] >>> assert ut.repr2(all_species_rowids, nl=False) == [1, 2, 3, 6] >>> assert ut.repr2(ibs.get_species_texts(all_species_rowids), nl=False) == ['zebra_plains', 'zebra_grevys', 'bear_polar', 'bear_polar+head'] Example: >>> # ENABLE_DOCTEST >>> from wbia.control.manual_species_funcs import * # NOQA >>> import wbia >>> import utool as ut # NOQA >>> ibs = wbia.opendb('testdb1') >>> species_text_list = [ ... u'jaguar', u'zebra_plains', u'zebra_plains', '____', 'TYPO', ... '____', u'zebra_grevys', u'bear_polar'] >>> ensure = False >>> species_rowid_list = ibs.get_species_rowids_from_text(species_text_list, ensure) """ if ensure: species_rowid_list = ibs.add_species(species_text_list, **kwargs) else: species_text_list_ = ibs.sanitize_species_texts(species_text_list) # lbltype_rowid = ibs.lbltype_ids[const.SPECIES_KEY] # lbltype_rowid_list = [lbltype_rowid] * len(species_text_list_) # species_rowid_list = ibs.get_lblannot_rowid_from_superkey(lbltype_rowid_list, species_text_list_) # Ugg species and names need their own table # species_rowid_list = [const.UNKNOWN_SPECIES_ROWID if rowid is None else # rowid for rowid in species_rowid_list] species_rowid_list = ibs.db.get( const.SPECIES_TABLE, (SPECIES_ROWID,), species_text_list_, id_colname=SPECIES_TEXT, ) # BIG HACK FOR ENFORCING UNKNOWN SPECIESS HAVE ROWID 0 species_rowid_list = [ const.UNKNOWN_SPECIES_ROWID if text is None or text == const.UNKNOWN else rowid for rowid, text in zip(species_rowid_list, species_text_list_) ] return species_rowid_list
[docs]@register_ibs_method @accessor_decors.getter_1to1 @register_api('/api/species/rowid/uuid/', methods=['GET'], __api_plural_check__=False) def get_species_rowids_from_uuids(ibs, species_uuid_list): r""" Returns: species_rowid_list (list): Creates one if it doesnt exist CommandLine: python -m wbia.control.manual_species_funcs --test-get_species_rowids_from_text:0 python -m wbia.control.manual_species_funcs --test-get_species_rowids_from_text:1 RESTful: Method: GET URL: /api/species/rowid/uuid/ """ species_rowid_list = ibs.db.get( const.SPECIES_TABLE, (SPECIES_ROWID,), species_uuid_list, id_colname=SPECIES_UUID ) species_rowid_list = [ const.UNKNOWN_SPECIES_ROWID if text is None or text == const.UNKNOWN else rowid for rowid, text in zip(species_rowid_list, species_uuid_list) ] return species_rowid_list
[docs]@register_ibs_method @accessor_decors.getter_1to1 @register_api('/api/species/uuid/', methods=['GET'], __api_plural_check__=False) def get_species_uuids(ibs, species_rowid_list): r""" Returns: list_ (list): uuids_list - species uuids RESTful: Method: GET URL: /api/species/uuid/ """ uuids_list = ibs.db.get(const.SPECIES_TABLE, (SPECIES_UUID,), species_rowid_list) # notes_list = ibs.get_lblannot_notes(nid_list) return uuids_list
[docs]@register_ibs_method @accessor_decors.getter_1to1 @accessor_decors.cache_getter(const.SPECIES_TABLE, SPECIES_TEXT) @register_api('/api/species/text/', methods=['GET'], __api_plural_check__=False) def get_species_texts(ibs, species_rowid_list): r""" Returns: list: species_text_list text names CommandLine: python -m wbia.control.manual_species_funcs --test-get_species_texts --enableall RESTful: Method: GET URL: /api/species/text/ Example: >>> # ENABLE_DOCTEST >>> from wbia.control.manual_species_funcs import * # NOQA >>> import wbia >>> ibs = wbia.opendb('testdb1') >>> species_rowid_list = ibs._get_all_species_rowids() >>> result = get_species_texts(ibs, species_rowid_list) >>> result = ut.repr2(result) >>> print(result) ['zebra_plains', 'zebra_grevys', 'bear_polar', 'bear_polar+head'] """ # FIXME: use standalone species table # species_text_list = ibs.get_lblannot_values(species_rowid_list, const.SPECIES_KEY) species_text_list = ibs.db.get( const.SPECIES_TABLE, (SPECIES_TEXT,), species_rowid_list ) species_text_list = [ const.UNKNOWN if rowid == const.UNKNOWN_SPECIES_ROWID else species_text for species_text, rowid in zip(species_text_list, species_rowid_list) ] species_text_list = [ const.UNKNOWN if code is None else code for code in species_text_list ] return species_text_list
[docs]@register_ibs_method @accessor_decors.getter_1to1 @accessor_decors.cache_getter(const.SPECIES_TABLE, SPECIES_NICE) @register_api('/api/species/nice/', methods=['GET'], __api_plural_check__=False) def get_species_nice(ibs, species_rowid_list): r""" Returns: list: species_text_list nice names CommandLine: python -m wbia.control.manual_species_funcs --test-get_species_nice --enableall RESTful: Method: GET URL: /api/species/nice/ Example: >>> # ENABLE_DOCTEST >>> from wbia.control.manual_species_funcs import * # NOQA >>> import wbia >>> ibs = wbia.opendb('testdb1') >>> ibs._clean_species() >>> species_rowid_list = ibs._get_all_species_rowids() >>> result = get_species_nice(ibs, species_rowid_list) >>> result = ut.repr2(result) >>> print(result) ['Zebra (Plains)', "Zebra (Grevy's)", 'Polar Bear', 'bear_polar+head'] """ # FIXME: use standalone species table # species_nice_list = ibs.get_lblannot_values(species_rowid_list, const.SPECIES_KEY) species_nice_list = ibs.db.get( const.SPECIES_TABLE, (SPECIES_NICE,), species_rowid_list ) species_nice_list = [ const.UNKNOWN if rowid == const.UNKNOWN_SPECIES_ROWID else species_nice for species_nice, rowid in zip(species_nice_list, species_rowid_list) ] species_nice_list = [ 'Unknown' if code is None else code for code in species_nice_list ] return species_nice_list
[docs]@register_ibs_method @accessor_decors.getter_1to1 @register_api('/api/species/code/', methods=['GET'], __api_plural_check__=False) def get_species_codes(ibs, species_rowid_list): r""" Returns: list_ (list): code_list - species codes RESTful: Method: GET URL: /api/species/code/ """ species_code_list = ibs.db.get( const.SPECIES_TABLE, (SPECIES_CODE,), species_rowid_list ) species_code_list = [ 'UNKNOWN' if code is None else code for code in species_code_list ] return species_code_list
[docs]@register_ibs_method @accessor_decors.getter_1to1 @register_api('/api/species/note/', methods=['GET'], __api_plural_check__=False) def get_species_notes(ibs, species_rowid_list): r""" Returns: list_ (list): notes_list - species notes RESTful: Method: GET URL: /api/species/note/ """ notes_list = ibs.db.get(const.SPECIES_TABLE, (SPECIES_NOTE,), species_rowid_list) # notes_list = ibs.get_lblannot_notes(nid_list) return notes_list
[docs]@register_ibs_method @accessor_decors.getter_1to1 # @register_api('/api/species/enabled/', methods=['GET']) def get_species_enabled(ibs, species_rowid_list): r""" Returns: list_ (list): "Species Enabled" flag, true if the species is enabled """ enabled_list = ibs.db.get(const.SPECIES_TABLE, (SPECIES_ENABLED,), species_rowid_list) return enabled_list
@register_ibs_method @accessor_decors.setter def _set_species_texts(ibs, species_rowid_list, species_text_list): r""" Sets the species nice names """ id_iter = ((species_rowid,) for species_rowid in species_rowid_list) val_list = ((enabled,) for enabled in species_text_list) ibs.db.set(const.SPECIES_TABLE, (SPECIES_TEXT,), val_list, id_iter) @register_ibs_method @accessor_decors.setter def _set_species_nice(ibs, species_rowid_list, species_nice_list): r""" Sets the species nice names """ id_iter = ((species_rowid,) for species_rowid in species_rowid_list) val_list = ((enabled,) for enabled in species_nice_list) ibs.db.set(const.SPECIES_TABLE, (SPECIES_NICE,), val_list, id_iter) @register_ibs_method @accessor_decors.setter def _set_species_code(ibs, species_rowid_list, species_code_list): r""" Sets the species nice names """ id_iter = ((species_rowid,) for species_rowid in species_rowid_list) val_list = ((enabled,) for enabled in species_code_list) ibs.db.set(const.SPECIES_TABLE, (SPECIES_CODE,), val_list, id_iter)
[docs]@register_ibs_method @accessor_decors.setter # @register_api('/api/species/enabled/', methods=['PUT']) def set_species_enabled(ibs, species_rowid_list, enabled_list): r""" Sets the species all instances enabled bit """ id_iter = ((species_rowid,) for species_rowid in species_rowid_list) val_list = ((enabled,) for enabled in enabled_list) ibs.db.set(const.SPECIES_TABLE, (SPECIES_ENABLED,), val_list, id_iter)