Ejemplo n.º 1
0
class CONFIDENCE(object):
    UNKNOWN = None
    GUESSING = 1
    NOT_SURE = 2
    PRETTY_SURE = 3
    ABSOLUTELY_SURE = 4

    INT_TO_CODE = ut.odict([
        (ABSOLUTELY_SURE, 'absolutely_sure'),
        (PRETTY_SURE, 'pretty_sure'),
        (NOT_SURE, 'not_sure'),
        (GUESSING, 'guessing'),
        (UNKNOWN, 'unspecified'),
    ])

    INT_TO_NICE = ut.odict([
        (ABSOLUTELY_SURE, 'Doubtless'),
        (PRETTY_SURE, 'Sure'),
        (NOT_SURE, 'Unsure'),
        (GUESSING, 'Guessing'),
        (UNKNOWN, 'Unspecified'),
    ])

    CODE_TO_NICE = ut.map_keys(INT_TO_CODE, INT_TO_NICE)
    CODE_TO_INT = ut.invert_dict(INT_TO_CODE)
    NICE_TO_CODE = ut.invert_dict(CODE_TO_NICE)
    NICE_TO_INT = ut.invert_dict(INT_TO_NICE)
Ejemplo n.º 2
0
class QUAL(object):
    EXCELLENT = 5
    GOOD = 4
    OK = 3
    POOR = 2
    JUNK = 1
    UNKNOWN = None

    INT_TO_CODE = ut.odict([
        (EXCELLENT, 'excellent'),
        (GOOD, 'good'),
        (OK, 'ok'),
        (POOR, 'poor'),
        (JUNK, 'junk'),
        (UNKNOWN, 'unspecified'),
    ])

    INT_TO_NICE = ut.odict([
        (EXCELLENT, 'Excellent'),
        (GOOD, 'Good'),
        (OK, 'OK'),
        (POOR, 'Poor'),
        (JUNK, 'Junk'),
        (UNKNOWN, 'Unspecified'),
    ])

    CODE_TO_NICE = ut.map_keys(INT_TO_CODE, INT_TO_NICE)
    CODE_TO_INT = ut.invert_dict(INT_TO_CODE)
    NICE_TO_CODE = ut.invert_dict(CODE_TO_NICE)
    NICE_TO_INT = ut.invert_dict(INT_TO_NICE)
Ejemplo n.º 3
0
class META_DECISION(object):  # NOQA
    """
    Enumerated types of review codes and texts

    Notes:
        unreviewed: we dont have a meta decision
        same: we know this is the same animal through non-visual means
        diff: we know this is the different animal through non-visual means

    Example:
        >>> # ENABLE_DOCTEST
        >>> from wbia.constants import *  # NOQA
        >>> assert hasattr(META_DECISION, 'CODE')
        >>> assert hasattr(META_DECISION, 'NICE')
        >>> code1 = META_DECISION.INT_TO_CODE[META_DECISION.NULL]
        >>> code2 = META_DECISION.CODE.NULL
        >>> assert code1 == code2
        >>> nice1 = META_DECISION.INT_TO_NICE[META_DECISION.NULL]
        >>> nice2 = META_DECISION.NICE.NULL
        >>> assert nice1 == nice2
    """

    NULL = None
    DIFF = 0
    SAME = 1
    INT_TO_CODE = ut.odict([(NULL, 'null'), (DIFF, 'diff'), (SAME, 'same')])
    INT_TO_NICE = ut.odict([(NULL, 'NULL'), (DIFF, 'Different'),
                            (SAME, 'Same')])
    CODE_TO_NICE = ut.map_keys(INT_TO_CODE, INT_TO_NICE)
    CODE_TO_INT = ut.invert_dict(INT_TO_CODE)
    NICE_TO_CODE = ut.invert_dict(CODE_TO_NICE)
    NICE_TO_INT = ut.invert_dict(INT_TO_NICE)
Ejemplo n.º 4
0
def get_oracle_name_decision(metatup, ibs, qaid, choicetup, oracle_method=1):
    """
    Find what the correct decision should be ibs is the database we are working
    with ibs_gt has pristine groundtruth
    """
    if ut.VERBOSE:
        print('Oracle is making decision using oracle_method=%r' %
              oracle_method)
    if metatup is None:
        print('WARNING METATUP IS NONE')
        return None
    MAX_LOOK = 3  # the oracle should only see what the user sees
    (sorted_nids, sorted_nscore, sorted_rawscore, sorted_aids,
     sorted_ascores) = choicetup
    (ibs_gt, aid1_to_aid2) = metatup
    # Get the annotations that the user can see
    aid_list2 = ut.get_list_column(sorted_aids, 0)
    # Get the groundtruth name of the query
    aid2_to_aid1 = ut.invert_dict(aid1_to_aid2)
    qnid1 = ibs_gt.get_annot_name_rowids(aid2_to_aid1[qaid])
    # Make an oracle decision by choosing a name (like a user would)
    if oracle_method == 1:
        chosen_names = oracle_method1(ibs_gt, ibs, qnid1, aid_list2,
                                      aid2_to_aid1, sorted_nids, MAX_LOOK)
    elif oracle_method == 2:
        chosen_names = oracle_method2(ibs_gt, qnid1)
    else:
        raise AssertionError('unknown oracle method %r' % (oracle_method, ))
    if ut.VERBOSE:
        print('Oracle decision is chosen_names=%r' % (chosen_names, ))
    return chosen_names
Ejemplo n.º 5
0
def get_oracle_name_decision(metatup, ibs, qaid, choicetup, oracle_method=1):
    """
    Find what the correct decision should be ibs is the database we are working
    with ibs_gt has pristine groundtruth
    """
    if ut.VERBOSE:
        print('Oracle is making decision using oracle_method=%r' % oracle_method)
    if metatup is None:
        print('WARNING METATUP IS NONE')
        return None
    MAX_LOOK = 3  # the oracle should only see what the user sees
    (sorted_nids, sorted_nscore, sorted_rawscore, sorted_aids, sorted_ascores) = choicetup
    (ibs_gt, aid1_to_aid2) = metatup
    # Get the annotations that the user can see
    aid_list2 = ut.get_list_column(sorted_aids, 0)
    # Get the groundtruth name of the query
    aid2_to_aid1 = ut.invert_dict(aid1_to_aid2)
    qnid1 = ibs_gt.get_annot_name_rowids(aid2_to_aid1[qaid])
    # Make an oracle decision by choosing a name (like a user would)
    if oracle_method == 1:
        chosen_names = oracle_method1(ibs_gt, ibs, qnid1, aid_list2, aid2_to_aid1, sorted_nids, MAX_LOOK)
    elif oracle_method == 2:
        chosen_names = oracle_method2(ibs_gt, qnid1)
    else:
        raise AssertionError('unknown oracle method %r' % (oracle_method,))
    if ut.VERBOSE:
        print('Oracle decision is chosen_names=%r' % (chosen_names,))
    return chosen_names
Ejemplo n.º 6
0
    def _update_state_gco(model,
                          weight_key='cut_weight',
                          name_label_key='name_label'):
        import networkx as nx
        # Get nx graph properties
        external_nodes = sorted(list(model.graph.nodes()))
        external_edges = list(model.graph.edges())
        edge_to_weights = nx.get_edge_attributes(model.graph, weight_key)
        node_to_labeling = nx.get_node_attributes(model.graph, name_label_key)
        edge_weights = ut.dict_take(edge_to_weights, external_edges, 0)
        external_labeling = [
            node_to_labeling.get(node, -node) for node in external_nodes
        ]
        # Map to internal ids for pygco
        internal_nodes = ut.rebase_labels(external_nodes)
        extern2_intern = dict(zip(external_nodes, internal_nodes))
        internal_edges = ut.unflat_take(extern2_intern, external_edges)
        internal_labeling = ut.rebase_labels(external_labeling)

        internal_labeling = np.array(internal_labeling)
        internal_edges = np.array(internal_edges)

        n_nodes = len(internal_nodes)
        # Model state
        model.n_nodes = n_nodes
        model.extern2_intern = extern2_intern
        model.intern2_extern = ut.invert_dict(extern2_intern)
        model.edges = internal_edges
        model.edge_weights = edge_weights
        # Model parameters
        model.labeling = np.zeros(model.n_nodes, dtype=np.int32)
        model._update_labels(labeling=internal_labeling)
        model._update_weights()
Ejemplo n.º 7
0
def config_graph_subattrs(cfg, depc):
    # TODO: if this hack is fully completed need a way of getting the
    # full config belonging to both chip + feat
    # cfg = request.config.feat_cfg
    import networkx as netx
    tablename = ut.invert_dict(depc.configclass_dict)[cfg.__class__]
    #tablename = cfg.get_config_name()
    ancestors = netx.dag.ancestors(depc.graph, tablename)
    subconfigs_ = ut.dict_take(depc.configclass_dict, ancestors, None)
    subconfigs = ut.filter_Nones(subconfigs_)  # NOQA
Ejemplo n.º 8
0
def config_graph_subattrs(cfg, depc):
    # TODO: if this hack is fully completed need a way of getting the
    # full config belonging to both chip + feat
    # cfg = request.config.feat_cfg
    import networkx as netx
    tablename = ut.invert_dict(depc.configclass_dict)[cfg.__class__]
    #tablename = cfg.get_config_name()
    ancestors = netx.dag.ancestors(depc.graph, tablename)
    subconfigs_ = ut.dict_take(depc.configclass_dict, ancestors, None)
    subconfigs = ut.filter_Nones(subconfigs_)  # NOQA
Ejemplo n.º 9
0
class EVIDENCE_DECISION(object):  # NOQA
    """
    TODO: change to EVIDENCE_DECISION / VISUAL_DECISION
    Enumerated types of review codes and texts

    Notes:
        Unreviewed: Not comparared yet.
        nomatch: Visually comparable and the different
        match: Visually comparable and the same
        notcomp: Not comparable means it is actually impossible to determine.
        unknown: means that it was reviewed, but we just can't figure it out.
    """

    UNREVIEWED = None
    NEGATIVE = 0
    POSITIVE = 1
    INCOMPARABLE = 2
    UNKNOWN = 3

    INT_TO_CODE = ut.odict([
        (POSITIVE, 'match'),
        (NEGATIVE, 'nomatch'),
        (INCOMPARABLE, 'notcomp'),
        (UNKNOWN, 'unknown'),
        (UNREVIEWED, 'unreviewed'),
    ])

    INT_TO_NICE = ut.odict([
        (POSITIVE, 'Positive'),
        (NEGATIVE, 'Negative'),
        (INCOMPARABLE, 'Incomparable'),
        (UNKNOWN, 'Unknown'),
        (UNREVIEWED, 'Unreviewed'),
    ])

    CODE_TO_NICE = ut.map_keys(INT_TO_CODE, INT_TO_NICE)
    CODE_TO_INT = ut.invert_dict(INT_TO_CODE)
    NICE_TO_CODE = ut.invert_dict(CODE_TO_NICE)
    NICE_TO_INT = ut.invert_dict(INT_TO_NICE)

    MATCH_CODE = CODE_TO_INT
Ejemplo n.º 10
0
    def static_new(cls, depc, parent_rowids, cfgdict=None, tablename=None):
        """ hack for autoreload """
        request = cls()
        if tablename is None:
            try:
                if hasattr(cls, '_tablename'):
                    tablename = cls._tablename
                else:
                    tablename = ut.invert_dict(depc.requestclass_dict)[cls]
            except Exception as ex:
                ut.printex(ex, 'tablename must be given')
                raise
        request.tablename = tablename
        request.parent_rowids = parent_rowids
        request.depc = depc
        if cfgdict is None:
            cfgdict = {}
        configclass = depc.configclass_dict[tablename]
        config = configclass(**cfgdict)
        request.config = config
        # HACK FOR IBEIS
        request.params = dict(config.parse_items())
        # HACK-ier FOR BACKWARDS COMPATABILITY
        if True:
            # params.featweight_cfgstr = query_cfg._featweight_cfg.get_cfgstr()
            # TODO: if this hack is fully completed need a way of getting the
            # full config belonging to both chip + feat
            try:
                request.params['chip_cfgstr'] = config.chip_cfg.get_cfgstr()
                request.params['chip_cfg_dict'] = config.chip_cfg.asdict()
                request.params['feat_cfgstr'] = config.feat_cfg.get_cfgstr()
                request.params[
                    'hesaff_params'] = config.feat_cfg.get_hesaff_params()
                request.params[
                    'featweight_cfgstr'] = config.feat_weight_cfg.get_cfgstr()
            except AttributeError:
                pass
        request.qparams = ut.DynStruct()
        for key, val in request.params.items():
            setattr(request.qparams, key, val)

        return request
Ejemplo n.º 11
0
    def static_new(cls, depc, parent_rowids, cfgdict=None, tablename=None):
        """ hack for autoreload """
        request = cls()
        if tablename is None:
            try:
                if hasattr(cls, '_tablename'):
                    tablename = cls._tablename
                else:
                    tablename = ut.invert_dict(depc.requestclass_dict)[cls]
            except Exception as ex:
                ut.printex(ex, 'tablename must be given')
                raise
        request.tablename = tablename
        request.parent_rowids = parent_rowids
        request.depc = depc
        if cfgdict is None:
            cfgdict = {}
        configclass = depc.configclass_dict[tablename]
        config = configclass(**cfgdict)
        request.config = config
        # HACK FOR IBEIS
        request.params = dict(config.parse_items())
        # HACK-ier FOR BACKWARDS COMPATABILITY
        if True:
            #params.featweight_cfgstr = query_cfg._featweight_cfg.get_cfgstr()
            # TODO: if this hack is fully completed need a way of getting the
            # full config belonging to both chip + feat
            try:
                request.params['chip_cfgstr']       = config.chip_cfg.get_cfgstr()
                request.params['chip_cfg_dict']     = config.chip_cfg.asdict()
                request.params['feat_cfgstr']       = config.feat_cfg.get_cfgstr()
                request.params['hesaff_params']     = config.feat_cfg.get_hesaff_params()
                request.params['featweight_cfgstr'] = config.feat_weight_cfg.get_cfgstr()
            except AttributeError:
                pass
        request.qparams = ut.DynStruct()
        for key, val in request.params.items():
            setattr(request.qparams, key, val)

        return request
Ejemplo n.º 12
0
 def __init__(self,
              infr,
              selected_aids=[],
              use_image=False,
              temp_nids=None):
     super(AnnotGraphInteraction, self).__init__()
     self.infr = infr
     self.selected_aids = selected_aids
     self.node2_aid = nx.get_node_attributes(self.infr.graph, 'aid')
     self.aid2_node = ut.invert_dict(self.node2_aid)
     node2_label = {
         #node: '%d:aid=%r' % (node, aid)
         node: 'aid=%r' % (aid)
         for node, aid in self.node2_aid.items()
     }
     #self.show_cuts = False
     self.use_image = use_image
     self.show_cuts = False
     self.config = InferenceConfig()
     nx.set_node_attributes(self.infr.graph,
                            name='label',
                            values=node2_label)
Ejemplo n.º 13
0
    def __init__(verif, infr):
        verif.rng = np.random.RandomState(4033913)
        verif.dummy_params = {
            NEGTV: {
                'mean': 0.2,
                'std': 0.25
            },
            POSTV: {
                'mean': 0.85,
                'std': 0.2
            },
            INCMP: {
                'mean': 0.15,
                'std': 0.1
            },
        }
        verif.score_dist = randn

        verif.infr = infr
        verif.orig_nodes = set(infr.aids)
        verif.orig_labels = infr.get_node_attrs('orig_name_label')
        verif.orig_groups = ut.invert_dict(verif.orig_labels, False)
        verif.orig_groups = ut.map_vals(set, verif.orig_groups)
Ejemplo n.º 14
0
def netrun():
    r"""
    CommandLine:
        # --- UTILITY
        python -m ibeis_cnn --tf get_juction_dpath --show

        # --- DATASET BUILDING ---
        # Build Dataset Aliases
        python -m ibeis_cnn --tf netrun --db PZ_MTEST --acfg ctrl --ensuredata --show
        python -m ibeis_cnn --tf netrun --db PZ_Master1 --acfg timectrl --ensuredata
        python -m ibeis_cnn --tf netrun --db PZ_Master1 --acfg timectrl:pername=None --ensuredata
        python -m ibeis_cnn --tf netrun --db PZ_Master1 --acfg timectrl:pername=None --ensuredata
        python -m ibeis_cnn --tf netrun --db mnist --ensuredata --show
        python -m ibeis_cnn --tf netrun --db mnist --ensuredata --show --datatype=category
        python -m ibeis_cnn --tf netrun --db mnist --ensuredata --show --datatype=siam-patch

        python -m ibeis_cnn --tf netrun --db PZ_Master1 --acfg ctrl:pername=None,excluderef=False,contributor_contains=FlankHack --ensuredata --show --datatype=siam-part

        # Parts based datasets
        python -m ibeis_cnn --tf netrun --db PZ_MTEST --acfg ctrl --datatype=siam-part --ensuredata --show

        % Patch based dataset (big one)
        python -m ibeis_cnn --tf netrun --db PZ_Master1 --acfg default:is_known=True,qmin_pername=2,view=primary,species=primary,minqual=ok --ensuredata --show --vtd
        python -m ibeis_cnn --tf netrun --ds pzm4 --weights=new --arch=siaml2_128 --train --monitor
        python -m ibeis_cnn --tf netrun --ds pzm4 --arch=siaml2_128 --test
        python -m ibeis_cnn --tf netrun --ds pzm4 --arch=siaml2_128 --veryverbose --no-flask

        # --- TRAINING ---
        python -m ibeis_cnn --tf netrun --db PZ_Master1 --acfg default:is_known=True,qmin_pername=2,view=primary,species=primary,minqual=ok --weights=new --arch=siaml2_128 --train --monitor

        python -m ibeis_cnn --tf netrun --ds timectrl_pzmaster1 --acfg ctrl:pername=None,excluderef=False,contributor_contains=FlankHack --train --weights=new --arch=siaml2_128  --monitor  # NOQA
        python -m ibeis_cnn --tf netrun --ds timectrl_pzmaster1 --acfg ctrl:pername=None,excluderef=False --train --weights=new --arch=siaml2_128  --monitor  # NOQA
        python -m ibeis_cnn --tf netrun --ds pzmtest --weights=new --arch=siaml2_128 --train --monitor --DEBUG_AUGMENTATION
        python -m ibeis_cnn --tf netrun --ds pzmtest --weights=new --arch=siaml2_128 --train --monitor

        python -m ibeis_cnn --tf netrun --ds flankhack --weights=new --arch=siaml2_partmatch --train --monitor --learning_rate=.00001
        python -m ibeis_cnn --tf netrun --ds flankhack --weights=new --arch=siam_deepfaceish --train --monitor --learning_rate=.00001

        # Different ways to train mnist
        python -m ibeis_cnn --tf netrun --db mnist --weights=new --arch=mnist_siaml2 --train --monitor --datatype=siam-patch
        python -m ibeis_cnn --tf netrun --db mnist --weights=new --arch=mnist-category --train --monitor --datatype=category

        # --- INITIALIZED-TRAINING ---
        python -m ibeis_cnn --tf netrun --ds pzmtest --arch=siaml2_128 --weights=gz-gray:current --train --monitor

        # --- TESTING ---
        python -m ibeis_cnn --tf netrun --db liberty --weights=liberty:current --arch=siaml2_128 --test
        python -m ibeis_cnn --tf netrun --db PZ_Master0 --weights=combo:current --arch=siaml2_128 --testall

    Example:
        >>> # DISABLE_DOCTEST
        >>> from ibeis_cnn.netrun import *  # NOQA
        >>> netrun()
        >>> ut.show_if_requested()
    """
    ut.colorprint('[netrun] NET RUN', 'red')

    requests, hyperparams, tags = parse_args()
    ds_tag         = tags['ds_tag']
    datatype       = tags['datatype']
    extern_ds_tag  = tags['extern_ds_tag']
    arch_tag       = tags['arch_tag']
    checkpoint_tag = tags['checkpoint_tag']

    # ----------------------------
    # Choose the main dataset
    ut.colorprint('[netrun] Ensuring Dataset', 'yellow')
    dataset = ingest_data.grab_dataset(ds_tag, datatype)
    if extern_ds_tag is not None:
        extern_dpath = ingest_data.get_extern_training_dpath(extern_ds_tag)
    else:
        extern_dpath = None

    print('dataset.training_dpath = %r' % (dataset.training_dpath,))

    print('Dataset Alias Key: %r' % (dataset.alias_key,))
    print('Current Dataset Tag: %r' % (
        ut.invert_dict(DS_TAG_ALIAS2).get(dataset.alias_key, None),))

    if requests['ensuredata']:
        # Print alias key that maps to this particular dataset
        if ut.show_was_requested():
            interact_ = dataset.interact()  # NOQA
            return
        print('...exiting')
        sys.exit(1)

    # ----------------------------
    # Choose model architecture
    # TODO: data will need to return info about number of labels in viewpoint models
    # Specify model archichitecture
    ut.colorprint('[netrun] Architecture Specification', 'yellow')
    if arch_tag == 'siam2stream':
        model = models.SiameseCenterSurroundModel(
            data_shape=dataset.data_shape,
            training_dpath=dataset.training_dpath, **hyperparams)
    elif arch_tag.startswith('siam'):
        model = models.SiameseL2(
            data_shape=dataset.data_shape,
            arch_tag=arch_tag,
            training_dpath=dataset.training_dpath, **hyperparams)
    elif arch_tag == 'mnist-category':
        model = models.MNISTModel(
            data_shape=dataset.data_shape,
            output_dims=dataset.output_dims,
            arch_tag=arch_tag,
            training_dpath=dataset.training_dpath, **hyperparams)
        pass
    else:
        raise ValueError('Unknown arch_tag=%r' % (arch_tag,))

    ut.colorprint('[netrun] Initialize archchitecture', 'yellow')
    model.init_arch()

    # ----------------------------
    # Choose weight initialization
    ut.colorprint('[netrun] Setting weights', 'yellow')
    if checkpoint_tag == 'new':
        ut.colorprint('[netrun] * Initializing new weights', 'lightgray')
        model.reinit_weights()
    else:
        checkpoint_tag = model.resolve_fuzzy_checkpoint_pattern(
            checkpoint_tag, extern_dpath)
        ut.colorprint('[netrun] * Resolving weights checkpoint_tag=%r' %
                      (checkpoint_tag,), 'lightgray')
        if extern_dpath is not None:
            model.load_extern_weights(dpath=extern_dpath,
                                      checkpoint_tag=checkpoint_tag)
        elif model.has_saved_state(checkpoint_tag=checkpoint_tag):
            model.load_model_state(checkpoint_tag=checkpoint_tag)
        else:
            model_state_fpath = model.get_model_state_fpath(
                checkpoint_tag=checkpoint_tag)
            print('model_state_fpath = %r' % (model_state_fpath,))
            ut.checkpath(model_state_fpath, verbose=True)
            print('Known checkpoints are: ' + ut.repr3(model.list_saved_checkpoints()))
            raise ValueError(('Unresolved weight init: '
                              'checkpoint_tag=%r, extern_ds_tag=%r') % (
                                  checkpoint_tag, extern_ds_tag,))

    #print('Model State:')
    #print(model.get_state_str())
    # ----------------------------
    if not model.is_train_state_initialized():
        ut.colorprint('[netrun] Need to initialize training state', 'yellow')
        X_train, y_train = dataset.subset('train')
        model.ensure_data_params(X_train, y_train)

    # Run Actions
    if requests['train']:
        ut.colorprint('[netrun] Training Requested', 'yellow')
        # parse training arguments
        config = ut.argparse_dict(dict(
            era_size=15,
            max_epochs=1200,
            rate_decay=.8,
        ))
        model.monitor_config.update(**config)
        X_train, y_train = dataset.subset('train')
        X_valid, y_valid = dataset.subset('valid')
        model.fit(X_train, y_train, X_valid=X_valid, y_valid=y_valid)

    elif requests['test']:
        #assert model.best_results['epoch'] is not None
        ut.colorprint('[netrun] Test Requested', 'yellow')
        if requests['testall']:
            ut.colorprint('[netrun]  * Testing on all data', 'lightgray')
            X_test, y_test = dataset.subset('all')
            flat_metadata = dataset.subset_metadata('all')
        else:
            ut.colorprint('[netrun]  * Testing on test subset', 'lightgray')
            X_test, y_test = dataset.subset('test')
            flat_metadata = dataset.subset_metadata('test')
        data, labels = X_test, y_test
        dataname = dataset.alias_key
        experiments.test_siamese_performance(model, data, labels,
                                             flat_metadata, dataname)
    else:
        if not ut.get_argflag('--cmd'):
            raise ValueError('nothing here. need to train or test')

    if requests['publish']:
        ut.colorprint('[netrun] Publish Requested', 'yellow')
        publish_dpath = ut.truepath('~/Dropbox/IBEIS')
        published_model_state = ut.unixjoin(
            publish_dpath, model.arch_tag + '_model_state.pkl')
        ut.copy(model.get_model_state_fpath(), published_model_state)
        ut.view_directory(publish_dpath)
        print('You need to get the dropbox link and '
              'register it into the appropriate file')
        # pip install dropbox
        # https://www.dropbox.com/developers/core/start/python
        # import dropbox  # need oauth
        #client.share('/myfile.txt', short_url=False)
        # https://cthulhu.dyn.wildme.io/public/models/siaml2_128_model_state.pkl

    if ut.get_argflag('--cmd'):
        ut.embed()
Ejemplo n.º 15
0
def _inject_getter_attrs(metaself,
                         objname,
                         attrs,
                         configurable_attrs,
                         depc_name=None,
                         depcache_attrs=None,
                         settable_attrs=None,
                         aliased_attrs=None):
    """
    Used by the metaclass to inject methods and properties into the class
    inheriting from ObjectList1D
    """

    if settable_attrs is None:
        settable_attrs = []
    settable_attrs = set(settable_attrs)

    # Inform the class of which variables will be injected
    metaself._settable_attrs = settable_attrs
    metaself._attrs = attrs
    metaself._configurable_attrs = configurable_attrs
    if depcache_attrs is None:
        metaself._depcache_attrs = []
    else:
        metaself._depcache_attrs = [
            '%s_%s' % (tbl, col) for tbl, col in depcache_attrs
        ]
    if aliased_attrs is not None:
        metaself._attrs_aliases = aliased_attrs
    else:
        metaself._attrs_aliases = {}

    # if not getattr(metaself, '__needs_inject__', True):
    #     return

    attr_to_aliases = ut.invert_dict(metaself._attrs_aliases,
                                     unique_vals=False)

    # What is difference between configurable and depcache getters?
    # Could depcache getters just be made configurable?
    # I guess its just an efficincy thing. Actually its config2_-vs-config
    # FIXME: rectify differences between normal / configurable / depcache
    # getter

    def _make_caching_setter(attrname, _rowid_setter):
        def _setter(self, values, *args, **kwargs):
            if self._ibs is None:
                self._internal_attrs[attrname] = values
            else:
                if self._caching and attrname in self._internal_attrs:
                    self._internal_attrs[attrname] = values
                _rowid_setter(self, self._rowids, values)

        ut.set_funcname(_setter, '_set_' + attrname)
        return _setter

    def _make_caching_getter(attrname, _rowid_getter):
        def _getter(self):
            if self._ibs is None or (self._caching
                                     and attrname in self._internal_attrs):
                data = self._internal_attrs[attrname]
            else:
                data = _rowid_getter(self, self._rowids)
                if self._caching:
                    self._internal_attrs[attrname] = data
            return data

        ut.set_funcname(_getter, '_get_' + attrname)
        return _getter

    # make default version use implicit rowids and another
    # that takes explicit rowids.

    def _make_setters(objname, attrname):
        ibs_funcname = 'set_%s_%s' % (objname, attrname)

        def _rowid_setter(self, rowids, values, *args, **kwargs):
            ibs_callable = getattr(self._ibs, ibs_funcname)
            ibs_callable(rowids, values, *args, **kwargs)

        ut.set_funcname(_rowid_setter, '_rowid_set_' + attrname)
        _setter = _make_caching_setter(attrname, _rowid_setter)
        return _rowid_setter, _setter

    # ---

    def _make_getters(objname, attrname):
        ibs_funcname = 'get_%s_%s' % (objname, attrname)

        def _rowid_getter(self, rowids):
            ibs_callable = getattr(self._ibs, ibs_funcname)
            data = ibs_callable(rowids)
            if self._asarray:
                data = np.array(data)
            return data

        ut.set_funcname(_rowid_getter, '_rowid_get_' + attrname)
        _getter = _make_caching_getter(attrname, _rowid_getter)
        return _rowid_getter, _getter

    def _make_cfg_getters(objname, attrname):
        ibs_funcname = 'get_%s_%s' % (objname, attrname)

        def _rowid_getter(self, rowids):
            ibs_callable = getattr(self._ibs, ibs_funcname)
            data = ibs_callable(rowids, config2_=self._config)
            if self._asarray:
                data = np.array(data)
            return data

        ut.set_funcname(_rowid_getter, '_rowid_get_' + attrname)
        _getter = _make_caching_getter(attrname, _rowid_getter)
        return _rowid_getter, _getter

    def _make_depc_getters(depc_name, attrname, tbl, col):
        def _rowid_getter(self, rowids):
            depc = getattr(self._ibs, depc_name)
            data = depc.get(tbl, rowids, col, config=self._config)
            if self._asarray:
                data = np.array(data)
            return data

        ut.set_funcname(_rowid_getter, '_rowid_get_' + attrname)
        _getter = _make_caching_getter(attrname, _rowid_getter)
        return _rowid_getter, _getter

    # Collect setter / getter functions and properties
    rowid_getters = []
    getters = []
    setters = []
    properties = []
    for attrname in attrs:
        _rowid_getter, _getter = _make_getters(objname, attrname)
        if attrname in settable_attrs:
            _rowid_setter, _setter = _make_setters(objname, attrname)
            setters.append(_setter)
        else:
            _setter = None
        prop = property(fget=_getter, fset=_setter)
        rowid_getters.append((attrname, _rowid_getter))
        getters.append(_getter)
        properties.append((attrname, prop))

    for attrname in configurable_attrs:
        _rowid_getter, _getter = _make_cfg_getters(objname, attrname)
        prop = property(fget=_getter)
        rowid_getters.append((attrname, _rowid_getter))
        getters.append(_getter)
        properties.append((attrname, prop))

    if depcache_attrs is not None:
        for tbl, col in depcache_attrs:
            attrname = '%s_%s' % (tbl, col)
            _rowid_getter, _getter = _make_depc_getters(
                depc_name, attrname, tbl, col)
            prop = property(fget=_getter, fset=None)
            rowid_getters.append((attrname, _rowid_getter))
            getters.append(_getter)
            properties.append((attrname, prop))

    aliases = []

    # Inject all gathered information
    for attrname, func in rowid_getters:
        funcname = ut.get_funcname(func)
        setattr(metaself, funcname, func)
        # ensure aliases have rowid getters
        for alias in attr_to_aliases.get(attrname, []):
            alias_funcname = '_rowid_get_' + alias
            setattr(metaself, alias_funcname, func)

    for func in getters:
        funcname = ut.get_funcname(func)
        setattr(metaself, funcname, func)

    for func in setters:
        funcname = ut.get_funcname(func)
        setattr(metaself, funcname, func)

    for attrname, prop in properties:
        setattr(metaself, attrname, prop)
        for alias in attr_to_aliases.pop(attrname, []):
            aliases.append((alias, attrname))
            setattr(metaself, alias, prop)

    if ut.get_argflag('--autogen-core'):
        # TODO: turn on autogenertion given a flag
        def expand_closure_source(funcname, func):
            source = ut.get_func_sourcecode(func)
            closure_vars = [
                (k, v.cell_contents)
                for k, v in zip(func.func_code.co_freevars, func.func_closure)
            ]
            source = ut.unindent(source)
            import re
            for k, v in closure_vars:
                source = re.sub('\\b' + k + '\\b', ut.repr2(v), source)
            source = re.sub('def .*\(self', 'def ' + funcname + '(self',
                            source)
            source = ut.indent(source.strip(), '    ') + '\n'
            return source

        explicit_lines = []
        # build explicit version for jedi?
        for funcname, func in getters:
            source = expand_closure_source(funcname, func)
            explicit_lines.append(source)
        # build explicit version for jedi?
        for funcname, func in setters:
            source = expand_closure_source(funcname, func)
            explicit_lines.append(source)

        for attrname, prop in properties:
            getter_name = None if prop.fget is None else ut.get_funcname(
                prop.fget)
            setter_name = None if prop.fset is None else ut.get_funcname(
                prop.fset)
            source = '    %s = property(%s, %s)' % (attrname, getter_name,
                                                    setter_name)
            explicit_lines.append(source)

        for alias, attrname in aliases:
            source = '    %s = %s' % (alias, attrname)
            explicit_lines.append(source)

        explicit_source = '\n'.join([
            'from ibeis import _ibeis_object',
            '',
            '',
            'class _%s_base_class(_ibeis_object.ObjectList1D):',
            '    __needs_inject__ = False',
            '',
        ]) % (objname, )
        explicit_source += '\n'.join(explicit_lines)
        explicit_fname = '_autogen_%s_base.py' % (objname, )
        from os.path import dirname, join
        ut.writeto(join(dirname(__file__), explicit_fname),
                   explicit_source + '\n')

    if attr_to_aliases:
        raise AssertionError('Unmapped aliases %r' % (attr_to_aliases, ))
Ejemplo n.º 16
0
class VIEW(object):
    """
    categorical viewpoint using the faces of a Rhombicuboctahedron

    References:
        https://en.wikipedia.org/wiki/Rhombicuboctahedron
    """

    UNKNOWN = None
    R = 1
    FR = 2
    F = 3
    FL = 4
    L = 5
    BL = 6
    B = 7
    BR = 8

    U = 9
    UF = 10
    UB = 11
    UL = 12
    UR = 13
    UFL = 14
    UFR = 15
    UBL = 16
    UBR = 17

    D = 18
    DF = 19
    DB = 20
    DL = 21
    DR = 22
    DFL = 23
    DFR = 24
    DBL = 25
    DBR = 26

    INT_TO_CODE = ut.odict([
        (UNKNOWN, 'unknown'),
        (R, 'right'),
        (FR, 'frontright'),
        (F, 'front'),
        (FL, 'frontleft'),
        (L, 'left'),
        (BL, 'backleft'),
        (B, 'back'),
        (BR, 'backright'),
        (U, 'up'),
        (UF, 'upfront'),
        (UB, 'upback'),
        (UL, 'upleft'),
        (UR, 'upright'),
        (UFL, 'upfrontleft'),
        (UFR, 'upfrontright'),
        (UBL, 'upbackleft'),
        (UBR, 'upbackright'),
        (D, 'down'),
        (DF, 'downfront'),
        (DB, 'downback'),
        (DL, 'downleft'),
        (DR, 'downright'),
        (DFL, 'downfrontleft'),
        (DFR, 'downfrontright'),
        (DBL, 'downbackleft'),
        (DBR, 'downbackright'),
    ])

    INT_TO_NICE = ut.odict([
        (UNKNOWN, 'Unknown'),
        (R, 'Right'),
        (FR, 'Front-Right'),
        (F, 'Front'),
        (FL, 'Front-Left'),
        (L, 'Left'),
        (BL, 'Back-Left'),
        (B, 'Back'),
        (BR, 'Back-Right'),
        (U, 'Up'),
        (UF, 'Up-Front'),
        (UB, 'Up-Back'),
        (UL, 'Up-Left'),
        (UR, 'Up-Right'),
        (UFL, 'Up-Front-Left'),
        (UFR, 'Up-Front-Right'),
        (UBL, 'Up-Back-Left'),
        (UBR, 'Up-Back-Right'),
        (D, 'Down'),
        (DF, 'Down-Front'),
        (DB, 'Down-Back'),
        (DL, 'Down-Left'),
        (DR, 'Down-Right'),
        (DFL, 'Down-Front-Left'),
        (DFR, 'Down-Front-Right'),
        (DBL, 'Down-Back-Left'),
        (DBR, 'Down-Back-Right'),
    ])

    CODE_TO_NICE = ut.map_keys(INT_TO_CODE, INT_TO_NICE)
    CODE_TO_INT = ut.invert_dict(INT_TO_CODE)
    NICE_TO_CODE = ut.invert_dict(CODE_TO_NICE)
    NICE_TO_INT = ut.invert_dict(INT_TO_NICE)

    DIST = {
        # DIST 0 PAIRS
        (B, B): 0,
        (BL, BL): 0,
        (BR, BR): 0,
        (D, D): 0,
        (DB, DB): 0,
        (DBL, DBL): 0,
        (DBR, DBR): 0,
        (DF, DF): 0,
        (DFL, DFL): 0,
        (DFR, DFR): 0,
        (DL, DL): 0,
        (DR, DR): 0,
        (F, F): 0,
        (FL, FL): 0,
        (FR, FR): 0,
        (L, L): 0,
        (R, R): 0,
        (U, U): 0,
        (UB, UB): 0,
        (UBL, UBL): 0,
        (UBR, UBR): 0,
        (UF, UF): 0,
        (UFL, UFL): 0,
        (UFR, UFR): 0,
        (UL, UL): 0,
        (UR, UR): 0,
        # DIST 1 PAIRS
        (B, BL): 1,
        (B, BR): 1,
        (B, DB): 1,
        (B, DBL): 1,
        (B, DBR): 1,
        (B, UB): 1,
        (B, UBL): 1,
        (B, UBR): 1,
        (BL, DBL): 1,
        (BL, L): 1,
        (BL, UBL): 1,
        (BR, DBR): 1,
        (BR, R): 1,
        (BR, UBR): 1,
        (D, DB): 1,
        (D, DBL): 1,
        (D, DBR): 1,
        (D, DF): 1,
        (D, DFL): 1,
        (D, DFR): 1,
        (D, DL): 1,
        (D, DR): 1,
        (DB, DBL): 1,
        (DB, DBR): 1,
        (DBL, DL): 1,
        (DBL, L): 1,
        (DBR, DR): 1,
        (DBR, R): 1,
        (DF, DFL): 1,
        (DF, DFR): 1,
        (DF, F): 1,
        (DFL, DL): 1,
        (DFL, F): 1,
        (DFL, FL): 1,
        (DFL, L): 1,
        (DFR, DR): 1,
        (DFR, F): 1,
        (DFR, FR): 1,
        (DFR, R): 1,
        (DL, L): 1,
        (DR, R): 1,
        (F, FL): 1,
        (F, FR): 1,
        (F, UF): 1,
        (F, UFL): 1,
        (F, UFR): 1,
        (FL, L): 1,
        (FL, UFL): 1,
        (FR, R): 1,
        (FR, UFR): 1,
        (L, UBL): 1,
        (L, UFL): 1,
        (L, UL): 1,
        (R, UBR): 1,
        (R, UFR): 1,
        (R, UR): 1,
        (U, UB): 1,
        (U, UBL): 1,
        (U, UBR): 1,
        (U, UF): 1,
        (U, UFL): 1,
        (U, UFR): 1,
        (U, UL): 1,
        (U, UR): 1,
        (UB, UBL): 1,
        (UB, UBR): 1,
        (UBL, UL): 1,
        (UBR, UR): 1,
        (UF, UFL): 1,
        (UF, UFR): 1,
        (UFL, UL): 1,
        (UFR, UR): 1,
        # DIST 2 PAIRS
        (B, D): 2,
        (B, DL): 2,
        (B, DR): 2,
        (B, L): 2,
        (B, R): 2,
        (B, U): 2,
        (B, UL): 2,
        (B, UR): 2,
        (BL, BR): 2,
        (BL, D): 2,
        (BL, DB): 2,
        (BL, DBR): 2,
        (BL, DFL): 2,
        (BL, DL): 2,
        (BL, FL): 2,
        (BL, U): 2,
        (BL, UB): 2,
        (BL, UBR): 2,
        (BL, UFL): 2,
        (BL, UL): 2,
        (BR, D): 2,
        (BR, DB): 2,
        (BR, DBL): 2,
        (BR, DFR): 2,
        (BR, DR): 2,
        (BR, FR): 2,
        (BR, U): 2,
        (BR, UB): 2,
        (BR, UBL): 2,
        (BR, UFR): 2,
        (BR, UR): 2,
        (D, F): 2,
        (D, FL): 2,
        (D, FR): 2,
        (D, L): 2,
        (D, R): 2,
        (DB, DF): 2,
        (DB, DFL): 2,
        (DB, DFR): 2,
        (DB, DL): 2,
        (DB, DR): 2,
        (DB, L): 2,
        (DB, R): 2,
        (DB, UB): 2,
        (DB, UBL): 2,
        (DB, UBR): 2,
        (DBL, DBR): 2,
        (DBL, DF): 2,
        (DBL, DFL): 2,
        (DBL, DFR): 2,
        (DBL, DR): 2,
        (DBL, FL): 2,
        (DBL, UB): 2,
        (DBL, UBL): 2,
        (DBL, UBR): 2,
        (DBL, UFL): 2,
        (DBL, UL): 2,
        (DBR, DF): 2,
        (DBR, DFL): 2,
        (DBR, DFR): 2,
        (DBR, DL): 2,
        (DBR, FR): 2,
        (DBR, UB): 2,
        (DBR, UBL): 2,
        (DBR, UBR): 2,
        (DBR, UFR): 2,
        (DBR, UR): 2,
        (DF, DL): 2,
        (DF, DR): 2,
        (DF, FL): 2,
        (DF, FR): 2,
        (DF, L): 2,
        (DF, R): 2,
        (DF, UF): 2,
        (DF, UFL): 2,
        (DF, UFR): 2,
        (DFL, DFR): 2,
        (DFL, DR): 2,
        (DFL, FR): 2,
        (DFL, UBL): 2,
        (DFL, UF): 2,
        (DFL, UFL): 2,
        (DFL, UFR): 2,
        (DFL, UL): 2,
        (DFR, DL): 2,
        (DFR, FL): 2,
        (DFR, UBR): 2,
        (DFR, UF): 2,
        (DFR, UFL): 2,
        (DFR, UFR): 2,
        (DFR, UR): 2,
        (DL, DR): 2,
        (DL, F): 2,
        (DL, FL): 2,
        (DL, UBL): 2,
        (DL, UFL): 2,
        (DL, UL): 2,
        (DR, F): 2,
        (DR, FR): 2,
        (DR, UBR): 2,
        (DR, UFR): 2,
        (DR, UR): 2,
        (F, L): 2,
        (F, R): 2,
        (F, U): 2,
        (F, UL): 2,
        (F, UR): 2,
        (FL, FR): 2,
        (FL, U): 2,
        (FL, UBL): 2,
        (FL, UF): 2,
        (FL, UFR): 2,
        (FL, UL): 2,
        (FR, U): 2,
        (FR, UBR): 2,
        (FR, UF): 2,
        (FR, UFL): 2,
        (FR, UR): 2,
        (L, U): 2,
        (L, UB): 2,
        (L, UF): 2,
        (R, U): 2,
        (R, UB): 2,
        (R, UF): 2,
        (UB, UF): 2,
        (UB, UFL): 2,
        (UB, UFR): 2,
        (UB, UL): 2,
        (UB, UR): 2,
        (UBL, UBR): 2,
        (UBL, UF): 2,
        (UBL, UFL): 2,
        (UBL, UFR): 2,
        (UBL, UR): 2,
        (UBR, UF): 2,
        (UBR, UFL): 2,
        (UBR, UFR): 2,
        (UBR, UL): 2,
        (UF, UL): 2,
        (UF, UR): 2,
        (UFL, UFR): 2,
        (UFL, UR): 2,
        (UFR, UL): 2,
        (UL, UR): 2,
        # DIST 3 PAIRS
        (B, DF): 3,
        (B, DFL): 3,
        (B, DFR): 3,
        (B, FL): 3,
        (B, FR): 3,
        (B, UF): 3,
        (B, UFL): 3,
        (B, UFR): 3,
        (BL, DF): 3,
        (BL, DFR): 3,
        (BL, DR): 3,
        (BL, F): 3,
        (BL, R): 3,
        (BL, UF): 3,
        (BL, UFR): 3,
        (BL, UR): 3,
        (BR, DF): 3,
        (BR, DFL): 3,
        (BR, DL): 3,
        (BR, F): 3,
        (BR, L): 3,
        (BR, UF): 3,
        (BR, UFL): 3,
        (BR, UL): 3,
        (D, UB): 3,
        (D, UBL): 3,
        (D, UBR): 3,
        (D, UF): 3,
        (D, UFL): 3,
        (D, UFR): 3,
        (D, UL): 3,
        (D, UR): 3,
        (DB, F): 3,
        (DB, FL): 3,
        (DB, FR): 3,
        (DB, U): 3,
        (DB, UFL): 3,
        (DB, UFR): 3,
        (DB, UL): 3,
        (DB, UR): 3,
        (DBL, F): 3,
        (DBL, FR): 3,
        (DBL, R): 3,
        (DBL, U): 3,
        (DBL, UF): 3,
        (DBL, UR): 3,
        (DBR, F): 3,
        (DBR, FL): 3,
        (DBR, L): 3,
        (DBR, U): 3,
        (DBR, UF): 3,
        (DBR, UL): 3,
        (DF, U): 3,
        (DF, UBL): 3,
        (DF, UBR): 3,
        (DF, UL): 3,
        (DF, UR): 3,
        (DFL, R): 3,
        (DFL, U): 3,
        (DFL, UB): 3,
        (DFL, UR): 3,
        (DFR, L): 3,
        (DFR, U): 3,
        (DFR, UB): 3,
        (DFR, UL): 3,
        (DL, FR): 3,
        (DL, R): 3,
        (DL, U): 3,
        (DL, UB): 3,
        (DL, UBR): 3,
        (DL, UF): 3,
        (DL, UFR): 3,
        (DR, FL): 3,
        (DR, L): 3,
        (DR, U): 3,
        (DR, UB): 3,
        (DR, UBL): 3,
        (DR, UF): 3,
        (DR, UFL): 3,
        (F, UB): 3,
        (F, UBL): 3,
        (F, UBR): 3,
        (FL, R): 3,
        (FL, UB): 3,
        (FL, UBR): 3,
        (FL, UR): 3,
        (FR, L): 3,
        (FR, UB): 3,
        (FR, UBL): 3,
        (FR, UL): 3,
        (L, UBR): 3,
        (L, UFR): 3,
        (L, UR): 3,
        (R, UBL): 3,
        (R, UFL): 3,
        (R, UL): 3,
        # DIST 4 PAIRS
        (B, F): 4,
        (BL, FR): 4,
        (BR, FL): 4,
        (D, U): 4,
        (DB, UF): 4,
        (DBL, UFR): 4,
        (DBR, UFL): 4,
        (DF, UB): 4,
        (DFL, UBR): 4,
        (DFR, UBL): 4,
        (DL, UR): 4,
        (DR, UL): 4,
        (L, R): 4,
        # UNDEFINED DIST PAIRS
        (B, UNKNOWN): None,
        (BL, UNKNOWN): None,
        (BR, UNKNOWN): None,
        (D, UNKNOWN): None,
        (DB, UNKNOWN): None,
        (DBL, UNKNOWN): None,
        (DBR, UNKNOWN): None,
        (DF, UNKNOWN): None,
        (DFL, UNKNOWN): None,
        (DFR, UNKNOWN): None,
        (DL, UNKNOWN): None,
        (DR, UNKNOWN): None,
        (F, UNKNOWN): None,
        (FL, UNKNOWN): None,
        (FR, UNKNOWN): None,
        (L, UNKNOWN): None,
        (R, UNKNOWN): None,
        (U, UNKNOWN): None,
        (UB, UNKNOWN): None,
        (UBL, UNKNOWN): None,
        (UBR, UNKNOWN): None,
        (UF, UNKNOWN): None,
        (UFL, UNKNOWN): None,
        (UFR, UNKNOWN): None,
        (UL, UNKNOWN): None,
        (UNKNOWN, B): None,
        (UNKNOWN, BL): None,
        (UNKNOWN, BR): None,
        (UNKNOWN, D): None,
        (UNKNOWN, DB): None,
        (UNKNOWN, DBL): None,
        (UNKNOWN, DBR): None,
        (UNKNOWN, DF): None,
        (UNKNOWN, DFL): None,
        (UNKNOWN, DFR): None,
        (UNKNOWN, DL): None,
        (UNKNOWN, DR): None,
        (UNKNOWN, F): None,
        (UNKNOWN, FL): None,
        (UNKNOWN, FR): None,
        (UNKNOWN, L): None,
        (UNKNOWN, R): None,
        (UNKNOWN, U): None,
        (UNKNOWN, UB): None,
        (UNKNOWN, UBL): None,
        (UNKNOWN, UBR): None,
        (UNKNOWN, UF): None,
        (UNKNOWN, UFL): None,
        (UNKNOWN, UFR): None,
        (UNKNOWN, UL): None,
        (UNKNOWN, UR): None,
        (UR, UNKNOWN): None,
        (UNKNOWN, UNKNOWN): None,
    }
    # make distance symmetric
    for (f1, f2), d in list(DIST.items()):
        DIST[(f2, f1)] = d
Ejemplo n.º 17
0
QUAL_OK        = 'ok'
QUAL_POOR      = 'poor'
QUAL_JUNK      = 'junk'
QUAL_UNKNOWN   = 'UNKNOWN'

QUALITY_INT_TO_TEXT = OrderedDict([
    (5,  QUAL_EXCELLENT,),
    (4,  QUAL_GOOD,),
    (3,  QUAL_OK,),
    (2,  QUAL_POOR,),
    # oops forgot 1. will be mapped to poor
    (0,  QUAL_JUNK,),
    (-1, QUAL_UNKNOWN,),
])

QUALITY_TEXT_TO_INT       = ut.invert_dict(QUALITY_INT_TO_TEXT)
QUALITY_INT_TO_TEXT[1]    = QUAL_JUNK
#QUALITY_TEXT_TO_INTS      = ut.invert_dict(QUALITY_INT_TO_TEXT)
QUALITY_TEXT_TO_INTS = ut.group_items(
    list(QUALITY_INT_TO_TEXT.keys()),
    list(QUALITY_INT_TO_TEXT.values()))
QUALITY_TEXT_TO_INTS[QUAL_UNKNOWN] = -1
QUALITY_INT_TO_TEXT[None] = QUALITY_INT_TO_TEXT[-1]


SEX_INT_TO_TEXT = {
    None: 'UNKNOWN NAME',
    -1  : 'UNKNOWN SEX',
    0   : 'Female',
    1   : 'Male',
}
Ejemplo n.º 18
0
def nx_transitive_reduction(G, mode=1):
    """
    References:
        https://en.wikipedia.org/wiki/Transitive_reduction#Computing_the_reduction_using_the_closure
        http://dept-info.labri.fr/~thibault/tmp/0201008.pdf
        http://stackoverflow.com/questions/17078696/im-trying-to-perform-the-transitive-reduction-of-directed-graph-in-python

    CommandLine:
        python -m utool.util_graph nx_transitive_reduction --show

    Example:
        >>> # DISABLE_DOCTEST
        >>> from utool.util_graph import *  # NOQA
        >>> import utool as ut
        >>> import networkx as nx
        >>> G = nx.DiGraph([('a', 'b'), ('a', 'c'), ('a', 'e'),
        >>>                 ('a', 'd'), ('b', 'd'), ('c', 'e'),
        >>>                 ('d', 'e'), ('c', 'e'), ('c', 'd')])
        >>> G = testdata_graph()[1]
        >>> G_tr = nx_transitive_reduction(G, mode=1)
        >>> G_tr2 = nx_transitive_reduction(G, mode=1)
        >>> ut.quit_if_noshow()
        >>> import plottool as pt
        >>> G_ = nx.dag.transitive_closure(G)
        >>> pt.show_nx(G    , pnum=(1, 5, 1), fnum=1)
        >>> pt.show_nx(G_tr , pnum=(1, 5, 2), fnum=1)
        >>> pt.show_nx(G_tr2 , pnum=(1, 5, 3), fnum=1)
        >>> pt.show_nx(G_   , pnum=(1, 5, 4), fnum=1)
        >>> pt.show_nx(nx.dag.transitive_closure(G_tr), pnum=(1, 5, 5), fnum=1)
        >>> ut.show_if_requested()
    """

    import utool as ut
    import networkx as nx
    has_cycles = not nx.is_directed_acyclic_graph(G)
    if has_cycles:
        # FIXME: this does not work for cycle graphs.
        # Need to do algorithm on SCCs
        G_orig = G
        G = nx.condensation(G_orig)

    nodes = list(G.nodes())
    node2_idx = ut.make_index_lookup(nodes)

    # For each node u, perform DFS consider its set of (non-self) children C.
    # For each descendant v, of a node in C, remove any edge from u to v.

    if mode == 1:
        G_tr = G.copy()

        for parent in G_tr.nodes():
            # Remove self loops
            if G_tr.has_edge(parent, parent):
                G_tr.remove_edge(parent, parent)
            # For each child of the parent
            for child in list(G_tr.successors(parent)):
                # Preorder nodes includes its argument (no added complexity)
                for gchild in list(G_tr.successors(child)):
                    # Remove all edges from parent to non-child descendants
                    for descendant in nx.dfs_preorder_nodes(G_tr, gchild):
                        if G_tr.has_edge(parent, descendant):
                            G_tr.remove_edge(parent, descendant)

        if has_cycles:
            # Uncondense graph
            uncondensed_G_tr = G.__class__()
            mapping = G.graph['mapping']
            uncondensed_G_tr.add_nodes_from(mapping.keys())
            inv_mapping = ut.invert_dict(mapping, unique_vals=False)
            for u, v in G_tr.edges():
                u_ = inv_mapping[u][0]
                v_ = inv_mapping[v][0]
                uncondensed_G_tr.add_edge(u_, v_)

            for key, path in inv_mapping.items():
                if len(path) > 1:
                    directed_cycle = list(ut.itertwo(path, wrap=True))
                    uncondensed_G_tr.add_edges_from(directed_cycle)
            G_tr = uncondensed_G_tr

    else:

        def make_adj_matrix(G):
            edges = list(G.edges())
            edge2_idx = ut.partial(ut.dict_take, node2_idx)
            uv_list = ut.lmap(edge2_idx, edges)
            A = np.zeros((len(nodes), len(nodes)))
            A[tuple(np.array(uv_list).T)] = 1
            return A

        G_ = nx.dag.transitive_closure(G)

        A = make_adj_matrix(G)
        B = make_adj_matrix(G_)

        #AB = A * B
        #AB = A.T.dot(B)
        AB = A.dot(B)
        #AB = A.dot(B.T)

        A_and_notAB = np.logical_and(A, np.logical_not(AB))
        tr_uvs = np.where(A_and_notAB)

        #nodes = G.nodes()
        edges = list(zip(*ut.unflat_take(nodes, tr_uvs)))

        G_tr = G.__class__()
        G_tr.add_nodes_from(nodes)
        G_tr.add_edges_from(edges)

        if has_cycles:
            # Uncondense graph
            uncondensed_G_tr = G.__class__()
            mapping = G.graph['mapping']
            uncondensed_G_tr.add_nodes_from(mapping.keys())
            inv_mapping = ut.invert_dict(mapping, unique_vals=False)
            for u, v in G_tr.edges():
                u_ = inv_mapping[u][0]
                v_ = inv_mapping[v][0]
                uncondensed_G_tr.add_edge(u_, v_)

            for key, path in inv_mapping.items():
                if len(path) > 1:
                    directed_cycle = list(ut.itertwo(path, wrap=True))
                    uncondensed_G_tr.add_edges_from(directed_cycle)
            G_tr = uncondensed_G_tr
    return G_tr
Ejemplo n.º 19
0
def test_vsone_errors(ibs, daids, qaid2_qres_vsmany, qaid2_qres_vsone, incinfo):
    """
    ibs1 = ibs_gt
    ibs2 = ibs (the current test database, sorry for the backwardness)
    aid1_to_aid2 - maps annots from ibs1 to ibs2
    """
    WASH                = 'wash'
    BOTH_FAIL           = 'both_fail'
    SINGLETON           = 'singleton'
    VSMANY_OUTPERFORMED = 'vsmany_outperformed'
    VSMANY_DOMINATES    = 'vsmany_dominates'
    VSMANY_WINS         = 'vsmany_wins'
    VSONE_WINS          = 'vsone_wins'
    if 'testcases' not in incinfo:
        testcases = {}
        for case in [WASH, BOTH_FAIL, SINGLETON, VSMANY_OUTPERFORMED,
                     VSMANY_DOMINATES, VSMANY_WINS, VSONE_WINS]:
            testcases[case] = []
        incinfo['testcases'] = testcases
    testcases = incinfo['testcases']

    def append_case(case, testtup):
        print('APPENDED NEW TESTCASE: case=%r' % (case,))
        print('* testup = %r' % (testtup,))
        print('* vuuid = %r' % (ibs_gt.get_annot_visual_uuids(testtup.qaid_t),))
        if ut.get_argflag('--interupt-case') and case in [VSMANY_WINS, VSMANY_DOMINATES]:
            incinfo['interactive'] = True
            incinfo['use_oracle'] = False
            incinfo['STOP'] = True
            if ut.is_developer():
                import plottool as pt  # NOQA
                IPYTHON_COMMANDS = """
                >>> %pylab qt4
                >>> from ibeis.viz.interact import interact_matches  # NOQA
                >>> #qres_vsmany = ut.search_stack_for_localvar('qres_vsmany')
                >>> ibs        = ut.search_stack_for_localvar('ibs')
                >>> daids      = ut.search_stack_for_localvar('daids')
                >>> qnid_t     = ut.search_stack_for_localvar('qnid_t')
                >>> qres_vsone = ut.search_stack_for_localvar('qres_vsone')
                >>> all_nids_t = ut.search_stack_for_localvar('all_nids_t')
                >>> # Find index in daids of correct matches
                >>> cm = qres_vsone
                >>> correct_indices = np.where(np.array(all_nids_t) == qnid_t)[0]
                >>> correct_aids2 = ut.take(daids, correct_indices)
                >>> qaid = cm.qaid
                >>> aid = correct_aids2[0]
                >>> # Report visual uuid for inclusion or exclusion in script
                >>> print(ibs.get_annot_visual_uuids([qaid, aid]))

                >>> # Feature match things
                >>> print('cm.filtkey_list = %r' % (cm.filtkey_list,))
                >>> fm  = cm.aid2_fm[aid]
                >>> fs  = cm.aid2_fs[aid]
                >>> fsv = cm.aid2_fsv[aid]
                >>> mx = 2
                >>> qfx, dfx = fm[mx]
                >>> fsv_single = fsv[mx]
                >>> fs_single = fs[mx]
                >>> # check featweights
                >>> data_featweights = ibs.get_annot_fgweights([aid])[0]
                >>> data_featweights[dfx]
                >>> fnum = pt.next_fnum()
                >>> bad_aid = cm.get_top_aids()[0]
                >>> #match_interaction_good = interact_matches.MatchInteraction(ibs, cm, aid, annot_mode=1)
                >>> #match_interaction_bad = interact_matches.MatchInteraction(ibs, cm, bad_aid)
                >>> match_interaction_good = cm.ishow_matches(ibs, aid, annot_mode=1, fnum=1)
                >>> match_interaction_bad = cm.ishow_matches(ibs, bad_aid, annot_mode=1, fnum=2)
                >>> match_interaction = match_interaction_good
                >>> self = match_interaction
                >>> self.select_ith_match(mx)
                >>> #impossible_to_match = len(correct_indices) > 0
                """
                y = """
                >>> from os.path import exists
                >>> import vtool as vt
                >>> import vtool.patch as vtpatch
                >>> import vtool.image as vtimage  # NOQA
                >>> chip_list = ibs.get_annot_chips([aid])
                >>> kpts_list = ibs.get_annot_kpts([aid])
                >>> probchip_fpath_list = ibs.get_probchip_fpath(aid)
                >>> probchip_list = [vt.imread(fpath, grayscale=True) if exists(fpath) else None for fpath in probchip_fpath_list]
                >>> kpts  = kpts_list[0]
                >>> probchip = probchip_list[0]
                >>> kp = kpts[dfx]
                >>> patch  = vt.get_warped_patch(probchip, kp)[0].astype(np.float32) / 255.0
                >>> fnum2 = pt.next_fnum()
                >>> pt.figure(fnum2, pnum=(1, 2, 1), doclf=True, docla=True)
                >>> pt.imshow(probchip)
                >>> pt.draw_kpts2([kp])
                >>> pt.figure(fnum2, pnum=(1, 2, 2))
                >>> pt.imshow(patch * 255)
                >>> pt.update()
                >>> vt.gaussian_average_patch(patch)
                >>> cm.ishow_top(ibs, annot_mode=1)
                """
                y
                ut.set_clipboard(IPYTHON_COMMANDS)
                #ut.spawn_delayed_ipython_paste()
                ut.embed(remove_pyqt_hook=False)
                IPYTHON_COMMANDS

        testcases[case].append(testtup)

    for qaid in six.iterkeys(qaid2_qres_vsmany):
        qres_vsmany = qaid2_qres_vsmany[qaid]
        qres_vsone  = qaid2_qres_vsone[qaid]
        nscoretup_vsone  = qres_vsone.get_nscoretup()
        nscoretup_vsmany = qres_vsmany.get_nscoretup()
        metatup = incinfo['metatup']
        ibs_gt, aid1_to_aid2 = metatup
        aid2_to_aid1 = ut.invert_dict(aid1_to_aid2)

        top_aids_vsone  = ut.get_list_column(nscoretup_vsone.sorted_aids, 0)
        top_aids_vsmany = ut.get_list_column(nscoretup_vsmany.sorted_aids, 0)
        # tranform to groundtruth database coordinates
        all_daids_t = ut.dict_take_list(aid2_to_aid1, daids)
        top_aids_vsone_t  = ut.dict_take_list(aid2_to_aid1, top_aids_vsone)
        top_aids_vsmany_t = ut.dict_take_list(aid2_to_aid1, top_aids_vsmany)
        qaid_t = aid2_to_aid1[qaid]

        aids_tup = (all_daids_t, top_aids_vsone_t, top_aids_vsmany_t, (qaid_t,),)
        nids_tup = ibs_gt.unflat_map(ibs_gt.get_annot_nids, aids_tup)
        (all_nids_t, top_nids_vsone_t, top_nids_vsmany_t, (qnid_t,),) = nids_tup

        vsmany_rank  = ut.listfind(top_nids_vsmany_t, qnid_t)
        vsone_rank   = ut.listfind(top_nids_vsone_t, qnid_t)
        impossible_to_match = ut.listfind(all_nids_t, qnid_t) is None

        # Sort the test case into a category
        testtup = TestTup(qaid_t, qaid, vsmany_rank, vsone_rank)
        if vsmany_rank is None and vsone_rank is None and impossible_to_match:
            append_case(SINGLETON, testtup)
        elif vsmany_rank is not None and vsone_rank is None:
            if vsmany_rank < 5:
                append_case(VSMANY_DOMINATES, testtup)
            else:
                append_case(VSMANY_OUTPERFORMED, testtup)
        elif vsmany_rank is None:
            append_case(BOTH_FAIL, testtup)
        elif vsone_rank > vsmany_rank:
            append_case(VSMANY_WINS, testtup)
        elif vsone_rank < vsmany_rank:
            append_case(VSONE_WINS, testtup)
        elif vsone_rank == vsmany_rank:
            append_case(WASH, testtup)
        else:
            raise AssertionError('unenumerated case')
        count_dict = ut.count_dict_vals(testcases)
        print('+--')
        #print(ut.dict_str(testcases))
        print('---')
        print(ut.dict_str(count_dict))
        print('L__')
Ejemplo n.º 20
0
    (
        2,
        QUAL_POOR,
    ),
    # oops forgot 1. will be mapped to poor
    (
        0,
        QUAL_JUNK,
    ),
    (
        -1,
        QUAL_UNKNOWN,
    ),
])

QUALITY_TEXT_TO_INT = ut.invert_dict(QUALITY_INT_TO_TEXT)
QUALITY_INT_TO_TEXT[1] = QUAL_JUNK
# QUALITY_TEXT_TO_INTS      = ut.invert_dict(QUALITY_INT_TO_TEXT)
QUALITY_TEXT_TO_INTS = ut.group_items(list(QUALITY_INT_TO_TEXT.keys()),
                                      list(QUALITY_INT_TO_TEXT.values()))
QUALITY_TEXT_TO_INTS[QUAL_UNKNOWN] = -1
QUALITY_INT_TO_TEXT[None] = QUALITY_INT_TO_TEXT[-1]

SEX_INT_TO_TEXT = {
    None: 'UNKNOWN NAME',
    -1: 'UNKNOWN SEX',
    0: 'Female',
    1: 'Male',
    2: 'INDETERMINATE SEX',
}
SEX_TEXT_TO_INT = ut.invert_dict(SEX_INT_TO_TEXT)
Ejemplo n.º 21
0
                y
                ut.set_clipboard(IPYTHON_COMMANDS)
                #ut.spawn_delayed_ipython_paste()
                ut.embed(remove_pyqt_hook=False)
                IPYTHON_COMMANDS

        testcases[case].append(testtup)

    for qaid in six.iterkeys(qaid2_qres_vsmany):
        qres_vsmany = qaid2_qres_vsmany[qaid]
        qres_vsone = qaid2_qres_vsone[qaid]
        nscoretup_vsone = qres_vsone.get_nscoretup()
        nscoretup_vsmany = qres_vsmany.get_nscoretup()
        metatup = incinfo['metatup']
        ibs_gt, aid1_to_aid2 = metatup
        aid2_to_aid1 = ut.invert_dict(aid1_to_aid2)

        top_aids_vsone = ut.get_list_column(nscoretup_vsone.sorted_aids, 0)
        top_aids_vsmany = ut.get_list_column(nscoretup_vsmany.sorted_aids, 0)
        # tranform to groundtruth database coordinates
        all_daids_t = ut.dict_take_list(aid2_to_aid1, daids)
        top_aids_vsone_t = ut.dict_take_list(aid2_to_aid1, top_aids_vsone)
        top_aids_vsmany_t = ut.dict_take_list(aid2_to_aid1, top_aids_vsmany)
        qaid_t = aid2_to_aid1[qaid]

        aids_tup = (
            all_daids_t,
            top_aids_vsone_t,
            top_aids_vsmany_t,
            (qaid_t, ),
        )
Ejemplo n.º 22
0
def check_results(ibs_gt, ibs2, aid1_to_aid2, aids_list1_, incinfo):
    """
    reports how well the incremental query ran when the oracle was calling the
    shots.
    """
    print('--------- CHECKING RESULTS ------------')
    testcases = incinfo.get('testcases')
    if testcases is not None:
        count_dict = ut.count_dict_vals(testcases)
        print('+--')
        #print(ut.dict_str(testcases))
        print('---')
        print(ut.dict_str(count_dict))
        print('L__')
    # TODO: dont include initially added aids in the result reporting
    aid_list1 = aids_list1_  # ibs_gt.get_valid_aids()
    #aid_list1 = ibs_gt.get_aids_with_groundtruth()
    aid_list2 = ibs2.get_valid_aids()

    nid_list1 = ibs_gt.get_annot_nids(aid_list1)
    nid_list2 = ibs2.get_annot_nids(aid_list2)

    # Group annotations from test and gt database by their respective names
    grouped_dict1 = ut.group_items(aid_list1, nid_list1)
    grouped_dict2 = ut.group_items(aid_list2, nid_list2)
    grouped_aids1 = list(six.itervalues(grouped_dict1))
    grouped_aids2 = list(map(tuple, six.itervalues(grouped_dict2)))
    #group_nids1 = list(six.iterkeys(grouped_dict1))
    #group_nids2 = list(six.iterkeys(grouped_dict2))

    # Transform annotation ids from database1 space to database2 space
    grouped_aids1_t = [tuple(ut.dict_take_list(aid1_to_aid2, aids1)) for aids1 in grouped_aids1]

    set_grouped_aids1_t = set(grouped_aids1_t)
    set_grouped_aids2   = set(grouped_aids2)

    # Find names we got right. (correct groupings of annotations)
    # these are the annotation groups that are intersecting between
    # the test database and groundtruth database
    perfect_groups = set_grouped_aids2.intersection(set_grouped_aids1_t)
    # Find names we got wrong. (incorrect groupings of annotations)
    # The test database sets that were not perfect
    nonperfect_groups = set_grouped_aids2.difference(perfect_groups)
    # What we should have got
    # The ground truth database sets that were not fully identified
    missed_groups = set_grouped_aids1_t.difference(perfect_groups)

    # Mark non perfect groups by their error type
    false_negative_groups = []  # failed to link enough
    false_positive_groups = []  # linked too much
    for nonperfect_group in nonperfect_groups:
        if ut.is_subset_of_any(nonperfect_group, missed_groups):
            false_negative_groups.append(nonperfect_group)
        else:
            false_positive_groups.append(nonperfect_group)

    # Get some more info on the nonperfect groups
    # find which groups should have been linked
    aid2_to_aid1 = ut.invert_dict(aid1_to_aid2)
    false_negative_groups_t = [tuple(ut.dict_take_list(aid2_to_aid1, aids2)) for aids2 in false_negative_groups]
    false_negative_group_nids_t = ibs_gt.unflat_map(ibs_gt.get_annot_nids, false_negative_groups_t)
    assert all(map(ut.allsame, false_negative_group_nids_t)), 'inconsistent nids'
    false_negative_group_nid_t = ut.get_list_column(false_negative_group_nids_t, 0)
    # These are the links that should have been made
    missed_links = ut.group_items(false_negative_groups, false_negative_group_nid_t)

    print(ut.dict_str(missed_links))

    print('# Name with failed links (FN) = %r' % len(false_negative_groups))
    print('... should have reduced to %d names.' % (len(missed_links)))
    print('# Name with wrong links (FP)  = %r' % len(false_positive_groups))
    print('# Name correct names (TP)     = %r' % len(perfect_groups))
Ejemplo n.º 23
0
    def initialize_graph_and_model(infr):
        """ Unused in internal split stuff

        pt.qt4ensure()
        layout_info = pt.show_nx(graph, as_directed=False, fnum=1,
                                 layoutkw=dict(prog='neato'), use_image=True,
                                 verbose=0)
        ax = pt.gca()
        pt.zoom_factory()
        pt.interactions.PanEvents()
        """
        #import networkx as nx
        #import itertools
        cm_list = infr.cm_list
        hack = True
        hack = False
        if hack:
            cm_list = cm_list[:10]
        qaid_list = [cm.qaid for cm in cm_list]
        daids_list = [cm.daid_list for cm in cm_list]
        unique_aids = sorted(ut.list_union(*daids_list + [qaid_list]))
        if hack:
            unique_aids = sorted(ut.isect(unique_aids, qaid_list))
        aid2_aidx = ut.make_index_lookup(unique_aids)

        # Construct K-broken graph
        edges = []
        edge_weights = []
        #top = (infr.qreq_.qparams.K + 1) * 2
        #top = (infr.qreq_.qparams.K) * 2
        top = (infr.qreq_.qparams.K + 2)
        for count, cm in enumerate(cm_list):
            qidx = aid2_aidx[cm.qaid]
            score_list = cm.annot_score_list
            sortx = ut.argsort(score_list)[::-1]
            score_list = ut.take(score_list, sortx)[:top]
            daid_list = ut.take(cm.daid_list, sortx)[:top]
            for score, daid in zip(score_list, daid_list):
                if daid not in qaid_list:
                    continue
                didx = aid2_aidx[daid]
                edge_weights.append(score)
                edges.append((qidx, didx))

        # make symmetric
        directed_edges = dict(zip(edges, edge_weights))
        # Find edges that point in both directions
        undirected_edges = {}
        for (u, v), w in directed_edges.items():
            if (v, u) in undirected_edges:
                undirected_edges[(v, u)] += w
                undirected_edges[(v, u)] /= 2
            else:
                undirected_edges[(u, v)] = w

        edges = list(undirected_edges.keys())
        edge_weights = list(undirected_edges.values())
        nodes = list(range(len(unique_aids)))

        nid_labeling = infr.qreq_.ibs.get_annot_nids(unique_aids)
        labeling = ut.rebase_labels(nid_labeling)

        import networkx as nx
        from ibeis.viz import viz_graph
        set_node_attrs = nx.set_node_attributes
        set_edge_attrs = nx.set_edge_attributes

        # Create match-based graph structure
        graph = nx.DiGraph()
        graph.add_nodes_from(nodes)
        graph.add_edges_from(edges)

        # Important properties
        nid_list = infr.qreq_.ibs.get_annot_nids(unique_aids)
        labeling = ut.rebase_labels(nid_list)

        set_node_attrs(graph, 'name_label', dict(zip(nodes, labeling)))
        set_edge_attrs(graph, 'weight', dict(zip(edges, edge_weights)))

        # Visualization properties
        import plottool as pt
        ax2_aid = ut.invert_dict(aid2_aidx)
        set_node_attrs(graph, 'aid', ax2_aid)
        viz_graph.ensure_node_images(infr.qreq_.ibs, graph)
        set_node_attrs(graph, 'framewidth', dict(zip(nodes, [3.0] * len(nodes))))
        set_node_attrs(graph, 'framecolor', dict(zip(nodes, [pt.DARK_BLUE] * len(nodes))))
        ut.color_nodes(graph, labelattr='name_label')

        edge_colors = pt.scores_to_color(np.array(edge_weights), cmap_='viridis')
        #import utool
        #utool.embed()
        #edge_colors = [pt.color_funcs.ensure_base255(color) for color in edge_colors]
        #print('edge_colors = %r' % (edge_colors,))
        set_edge_attrs(graph, 'color', dict(zip(edges, edge_colors)))

        # Build inference model
        from ibeis.algo.hots import graph_iden
        #graph_iden.rrr()
        model = graph_iden.InfrModel(graph)
        #model = graph_iden.InfrModel(len(nodes), edges, edge_weights, labeling=labeling)
        infr.model = model
Ejemplo n.º 24
0
def check_results(ibs_gt, ibs2, aid1_to_aid2, aids_list1_, incinfo):
    """
    reports how well the incremental query ran when the oracle was calling the
    shots.
    """
    print('--------- CHECKING RESULTS ------------')
    testcases = incinfo.get('testcases')
    if testcases is not None:
        count_dict = ut.count_dict_vals(testcases)
        print('+--')
        #print(ut.dict_str(testcases))
        print('---')
        print(ut.dict_str(count_dict))
        print('L__')
    # TODO: dont include initially added aids in the result reporting
    aid_list1 = aids_list1_  # ibs_gt.get_valid_aids()
    #aid_list1 = ibs_gt.get_aids_with_groundtruth()
    aid_list2 = ibs2.get_valid_aids()

    nid_list1 = ibs_gt.get_annot_nids(aid_list1)
    nid_list2 = ibs2.get_annot_nids(aid_list2)

    # Group annotations from test and gt database by their respective names
    grouped_dict1 = ut.group_items(aid_list1, nid_list1)
    grouped_dict2 = ut.group_items(aid_list2, nid_list2)
    grouped_aids1 = list(six.itervalues(grouped_dict1))
    grouped_aids2 = list(map(tuple, six.itervalues(grouped_dict2)))
    #group_nids1 = list(six.iterkeys(grouped_dict1))
    #group_nids2 = list(six.iterkeys(grouped_dict2))

    # Transform annotation ids from database1 space to database2 space
    grouped_aids1_t = [
        tuple(ut.dict_take_list(aid1_to_aid2, aids1))
        for aids1 in grouped_aids1
    ]

    set_grouped_aids1_t = set(grouped_aids1_t)
    set_grouped_aids2 = set(grouped_aids2)

    # Find names we got right. (correct groupings of annotations)
    # these are the annotation groups that are intersecting between
    # the test database and groundtruth database
    perfect_groups = set_grouped_aids2.intersection(set_grouped_aids1_t)
    # Find names we got wrong. (incorrect groupings of annotations)
    # The test database sets that were not perfect
    nonperfect_groups = set_grouped_aids2.difference(perfect_groups)
    # What we should have got
    # The ground truth database sets that were not fully identified
    missed_groups = set_grouped_aids1_t.difference(perfect_groups)

    # Mark non perfect groups by their error type
    false_negative_groups = []  # failed to link enough
    false_positive_groups = []  # linked too much
    for nonperfect_group in nonperfect_groups:
        if ut.is_subset_of_any(nonperfect_group, missed_groups):
            false_negative_groups.append(nonperfect_group)
        else:
            false_positive_groups.append(nonperfect_group)

    # Get some more info on the nonperfect groups
    # find which groups should have been linked
    aid2_to_aid1 = ut.invert_dict(aid1_to_aid2)
    false_negative_groups_t = [
        tuple(ut.dict_take_list(aid2_to_aid1, aids2))
        for aids2 in false_negative_groups
    ]
    false_negative_group_nids_t = ibs_gt.unflat_map(ibs_gt.get_annot_nids,
                                                    false_negative_groups_t)
    assert all(map(ut.allsame,
                   false_negative_group_nids_t)), 'inconsistent nids'
    false_negative_group_nid_t = ut.get_list_column(
        false_negative_group_nids_t, 0)
    # These are the links that should have been made
    missed_links = ut.group_items(false_negative_groups,
                                  false_negative_group_nid_t)

    print(ut.dict_str(missed_links))

    print('# Name with failed links (FN) = %r' % len(false_negative_groups))
    print('... should have reduced to %d names.' % (len(missed_links)))
    print('# Name with wrong links (FP)  = %r' % len(false_positive_groups))
    print('# Name correct names (TP)     = %r' % len(perfect_groups))
Ejemplo n.º 25
0
    def initialize_graph_and_model(infr):
        """ Unused in internal split stuff

        pt.qt4ensure()
        layout_info = pt.show_nx(graph, as_directed=False, fnum=1,
                                 layoutkw=dict(prog='neato'), use_image=True,
                                 verbose=0)
        ax = pt.gca()
        pt.zoom_factory()
        pt.interactions.PanEvents()
        """
        #import networkx as nx
        #import itertools
        cm_list = infr.cm_list
        hack = True
        hack = False
        if hack:
            cm_list = cm_list[:10]
        qaid_list = [cm.qaid for cm in cm_list]
        daids_list = [cm.daid_list for cm in cm_list]
        unique_aids = sorted(ut.list_union(*daids_list + [qaid_list]))
        if hack:
            unique_aids = sorted(ut.isect(unique_aids, qaid_list))
        aid2_aidx = ut.make_index_lookup(unique_aids)

        # Construct K-broken graph
        edges = []
        edge_weights = []
        #top = (infr.qreq_.qparams.K + 1) * 2
        #top = (infr.qreq_.qparams.K) * 2
        top = (infr.qreq_.qparams.K + 2)
        for count, cm in enumerate(cm_list):
            qidx = aid2_aidx[cm.qaid]
            score_list = cm.annot_score_list
            sortx = ut.argsort(score_list)[::-1]
            score_list = ut.take(score_list, sortx)[:top]
            daid_list = ut.take(cm.daid_list, sortx)[:top]
            for score, daid in zip(score_list, daid_list):
                if daid not in qaid_list:
                    continue
                didx = aid2_aidx[daid]
                edge_weights.append(score)
                edges.append((qidx, didx))

        # make symmetric
        directed_edges = dict(zip(edges, edge_weights))
        # Find edges that point in both directions
        undirected_edges = {}
        for (u, v), w in directed_edges.items():
            if (v, u) in undirected_edges:
                undirected_edges[(v, u)] += w
                undirected_edges[(v, u)] /= 2
            else:
                undirected_edges[(u, v)] = w

        edges = list(undirected_edges.keys())
        edge_weights = list(undirected_edges.values())
        nodes = list(range(len(unique_aids)))

        nid_labeling = infr.qreq_.ibs.get_annot_nids(unique_aids)
        labeling = ut.rebase_labels(nid_labeling)

        import networkx as nx
        from ibeis.viz import viz_graph
        set_node_attrs = nx.set_node_attributes
        set_edge_attrs = nx.set_edge_attributes

        # Create match-based graph structure
        graph = nx.DiGraph()
        graph.add_nodes_from(nodes)
        graph.add_edges_from(edges)

        # Important properties
        nid_list = infr.qreq_.ibs.get_annot_nids(unique_aids)
        labeling = ut.rebase_labels(nid_list)

        set_node_attrs(graph, 'name_label', dict(zip(nodes, labeling)))
        set_edge_attrs(graph, 'weight', dict(zip(edges, edge_weights)))

        # Visualization properties
        import plottool as pt
        ax2_aid = ut.invert_dict(aid2_aidx)
        set_node_attrs(graph, 'aid', ax2_aid)
        viz_graph.ensure_node_images(infr.qreq_.ibs, graph)
        set_node_attrs(graph, 'framewidth', dict(zip(nodes,
                                                     [3.0] * len(nodes))))
        set_node_attrs(graph, 'framecolor',
                       dict(zip(nodes, [pt.DARK_BLUE] * len(nodes))))
        ut.color_nodes(graph, labelattr='name_label')

        edge_colors = pt.scores_to_color(np.array(edge_weights),
                                         cmap_='viridis')
        #import utool
        #utool.embed()
        #edge_colors = [pt.color_funcs.ensure_base255(color) for color in edge_colors]
        #print('edge_colors = %r' % (edge_colors,))
        set_edge_attrs(graph, 'color', dict(zip(edges, edge_colors)))

        # Build inference model
        from ibeis.algo.hots import graph_iden
        #graph_iden.rrr()
        model = graph_iden.InfrModel(graph)
        #model = graph_iden.InfrModel(len(nodes), edges, edge_weights, labeling=labeling)
        infr.model = model