Ejemplo n.º 1
0
def wait_for_user_exemplar_decision(autoexemplar_msg, exemplar_decision,
                                    exemplar_condience, incinfo=None):
    r""" hooks into to some method of getting user input for exemplars

    TODO: really good interface

    Args:
        autoexemplar_msg (?):
        exemplar_decision (?):
        exemplar_condience (?):

    Returns:
        ?: True

    CommandLine:
        python -m ibeis.algo.hots.automated_matcher --test-get_user_exemplar_decision

    Example:
        >>> # DISABLE_DOCTEST
        >>> from ibeis.algo.hots.automated_matcher import *  # NOQA
        >>> import ibeis  # NOQA
        >>> # build test data
        >>> autoexemplar_msg = '?'
        >>> exemplar_decision = '?'
        >>> exemplar_condience = '?'
        >>> get_user_exemplar_decision(autoexemplar_msg, exemplar_decision,
        >>>                            exemplar_condience)
        >>> # verify results
        >>> result = str(True)
        >>> print(result)
    """
    import guitool
    options = ['No', 'Yes']
    msg = 'Add query as new exemplar?. IBEIS suggests: ' + options[exemplar_decision]
    title = 'exemplar decision'
    responce = guitool.user_option(None, msg, title, options)  # NOQA
    if responce is None:
        raise AssertionError('User Canceled Query')
    if responce == 'Yes':
        exemplar_decision = True
    elif responce == 'No':
        exemplar_decision = False
    else:
        raise AssertionError('answer yes or no')
    # TODO CALLBACK HERE
    exemplar_decision_callback = incinfo['exemplar_decision_callback']
    exemplar_decision_callback(exemplar_decision)
Ejemplo n.º 2
0
 def imagesDropped(ibswgt, url_list):
     from os.path import isdir
     print('[drop_event] url_list=%r' % (url_list,))
     gpath_list = filter(utool.matches_image, url_list)
     dir_list   = filter(isdir, url_list)
     if len(dir_list) > 0:
         ans = guitool.user_option(ibswgt, title='Non-Images dropped',
                                   msg='Recursively import from directories?')
         if ans == 'Yes':
             gpath_list.extend(map(utool.unixpath,
                                   utool.flatten([utool.list_images(dir_, fullpath=True, recursive=True)
                                                  for dir_ in dir_list])))
         else:
             return
     print('[drop_event] gpath_list=%r' % (gpath_list,))
     if len(gpath_list) > 0:
         ibswgt.back.import_images_from_file(gpath_list=gpath_list)
Ejemplo n.º 3
0
def guiselect_workdir():
    """ Prompts the user to specify a work directory """
    import guitool
    guitool.ensure_qtapp()
    # Gui selection
    work_dir = guitool.select_directory('Select a work directory')

    # Make sure selection is ok
    if not exists(work_dir):
        try_again = guitool.user_option(
            paremt=None,
            msg='Directory %r does not exist.' % work_dir,
            title='get work dir failed',
            options=['Try Again'],
            use_cache=False)
        if try_again == 'Try Again':
            return guiselect_workdir()
    return work_dir
Ejemplo n.º 4
0
def guiselect_workdir():
    """ Prompts the user to specify a work directory """
    import guitool
    guitool.ensure_qtapp()
    # Gui selection
    work_dir = guitool.select_directory('Select a work directory')

    # Make sure selection is ok
    if not exists(work_dir):
        try_again = guitool.user_option(paremt=None,
                                        msg='Directory %r does not exist.' %
                                        work_dir,
                                        title='get work dir failed',
                                        options=['Try Again'],
                                        use_cache=False)
        if try_again == 'Try Again':
            return guiselect_workdir()
    return work_dir
Ejemplo n.º 5
0
def set_annot_pair_as_negative_match_(ibs, aid1, aid2, cm, qreq_, **kwargs):
    """
    MARK AS INCORRECT
    """
    def on_nontrivial_split(ibs, aid1, aid2):
        aid1_groundtruth = ibs.get_annot_groundtruth(aid1, noself=True)
        print(
            'There are %d annots in this name. Need more sophisticated split' %
            (len(aid1_groundtruth)))
        raise guiexcept.NeedsUserInput('non-trivial split')

    try:
        status = ibs.set_annot_pair_as_negative_match(
            aid1,
            aid2,
            on_nontrivial_split=on_nontrivial_split,
            logger=kwargs.get('logger', None))
        print('status = %r' % (status, ))
    except guiexcept.NeedsUserInput:
        options = ['Flag for later', 'Review now']
        reply = gt.user_option(msg=ut.codeblock('''
                Marking this as False induces a split case.
                Choose how to handle this.
                '''),
                               options=options)
        if reply == options[0]:
            prop = 'SplitCase'
            if 'logger' in kwargs:
                log = kwargs['logger'].info
            else:
                log = print
            annot_uuid_pair = ibs.get_annot_uuids((aid1, aid2))
            log('FLAG SplitCase: (annot_uuid_pair=%r)' % annot_uuid_pair)
            am_rowid = ibs.add_annotmatch_undirected([aid1], [aid2])[0]
            ibs.set_annotmatch_prop(prop, [am_rowid], [True])
            ibs.set_annotmatch_evidence_decision(
                [am_rowid], [ibs.const.EVIDENCE_DECISION.NEGATIVE])
        elif reply == options[1]:
            review_match(ibs, aid1, aid2, qreq_=qreq_, cm=cm, **kwargs)
    except guiexcept.UserCancel:
        print('user canceled negative match')
Ejemplo n.º 6
0
    def confirm(self, event=None):
        """

        CommandLine:
            python -m ibeis.viz.interact.interact_query_decision --test-confirm

        Example:
            >>> # DISABLE_DOCTEST
            >>> from ibeis.viz.interact.interact_query_decision import *  # NOQA
            >>> import utool as ut
            >>> # build test data
            >>> import ibeis
            >>> ibs = ibeis.opendb('testdb1')
            >>> self = ibs
            >>> self.ibs = ibs
            >>> selected_aids = ut.get_list_column(ibs.get_name_aids(ibs.get_valid_nids()), 0)
            >>> comfirm_res = 'jeff'
            >>> # execute function
            >>> #result = self.confirm(event)
            >>> # verify results
            >>> #print(result)
        """
        print('[interact_query_decision] Confirming selected animals.')

        selected_aids = [
            aid for aid in self.comp_aids
            if aid is not None and self.aid_checkbox_states[aid]
        ]
        if len(selected_aids) == 0:
            print('[interact_query_decision] Confirming no match.')
            chosen_aids = []
            if self.other_checkbox_states['none']:
                chosen_aids = 'newname'
            elif self.other_checkbox_states['junk']:
                chosen_aids = 'junk'
            else:
                msg = 'INTERACT_QUERY_DECISION IMPOSSIBLE STATE'
                raise AssertionError(msg)
        elif len(selected_aids) == 1:
            print('[interact_query_decision] Confirming single match')
            chosen_aids = selected_aids
        else:
            print('[interact_query_decision] Confirming merge')
            msg = ut.textblock('''
                You have selected more than one animal as a match to the query
                animal.  By doing this you are telling IBEIS that these are ALL
                the SAME ANIMAL.  \n\n\nIf this is not what you want, click
                Cancel.  If it is what you want, choose one of the names below
                as the name to keep.
                ''')
            selected_names = self.ibs.get_annot_names(selected_aids)
            options = selected_names
            parent = None
            title = 'Confirm Merge'
            merge_name = guitool.user_option(parent,
                                             msg=msg,
                                             title=title,
                                             options=options)
            if merge_name is None:
                print('[interact_query_decision] cancelled merge')
                self.update_callback()
                self.backend_callback()
                self.show_page()
                return
            else:
                print('[interact_query_decision] confirmed merge')
                is_merge_name = [
                    merge_name == name_ for name_ in selected_names
                ]
                chosen_aids = ut.sortedby(selected_aids, is_merge_name)[::-1]

        print('[interact_query_decision] Calling update callbacks')
        self.update_callback()
        self.backend_callback()
        print('[interact_query_decision] Calling decision callback')
        print('[interact_query_decision] self.name_decision_callback = %r' %
              (self.name_decision_callback, ))
        if isinstance(chosen_aids, six.string_types):
            # hack for string non-match commands
            chosen_names = chosen_aids
        else:
            chosen_names = self.ibs.get_annot_names(chosen_aids)
        self.name_decision_callback(chosen_names)
        print(
            '[interact_query_decision] sent name_decision_callback(chosen_names=%r)'
            % (chosen_names, ))
Ejemplo n.º 7
0
 def user_option(back, **kwargs):
     return guitool.user_option(parent=back.front, **kwargs)
Ejemplo n.º 8
0
    def confirm(self, event=None):
        """

        CommandLine:
            python -m ibeis.viz.interact.interact_query_decision --test-confirm

        Example:
            >>> # DISABLE_DOCTEST
            >>> from ibeis.viz.interact.interact_query_decision import *  # NOQA
            >>> import utool as ut
            >>> # build test data
            >>> import ibeis
            >>> ibs = ibeis.opendb('testdb1')
            >>> self = ibs
            >>> self.ibs = ibs
            >>> selected_aids = ut.get_list_column(ibs.get_name_aids(ibs.get_valid_nids()), 0)
            >>> comfirm_res = 'jeff'
            >>> # execute function
            >>> #result = self.confirm(event)
            >>> # verify results
            >>> #print(result)
        """
        print('[interact_query_decision] Confirming selected animals.')

        selected_aids = [aid for aid in self.comp_aids
                         if aid is not None and self.aid_checkbox_states[aid]]
        if len(selected_aids) == 0:
            print('[interact_query_decision] Confirming no match.')
            chosen_aids = []
            if self.other_checkbox_states['none']:
                chosen_aids = 'newname'
            elif self.other_checkbox_states['junk']:
                chosen_aids = 'junk'
            else:
                msg = 'INTERACT_QUERY_DECISION IMPOSSIBLE STATE'
                raise AssertionError(msg)
        elif len(selected_aids) == 1:
            print('[interact_query_decision] Confirming single match')
            chosen_aids = selected_aids
        else:
            print('[interact_query_decision] Confirming merge')
            msg = ut.textblock(
                '''
                You have selected more than one animal as a match to the query
                animal.  By doing this you are telling IBEIS that these are ALL
                the SAME ANIMAL.  \n\n\nIf this is not what you want, click
                Cancel.  If it is what you want, choose one of the names below
                as the name to keep.
                ''')
            selected_names = self.ibs.get_annot_names(selected_aids)
            options = selected_names
            parent = None
            title = 'Confirm Merge'
            merge_name = guitool.user_option(parent, msg=msg, title=title,
                                             options=options)
            if merge_name is None:
                print('[interact_query_decision] cancelled merge')
                self.update_callback()
                self.backend_callback()
                self.show_page()
                return
            else:
                print('[interact_query_decision] confirmed merge')
                is_merge_name = [merge_name == name_ for name_ in selected_names]
                chosen_aids = ut.sortedby(selected_aids, is_merge_name)[::-1]

        print('[interact_query_decision] Calling update callbacks')
        self.update_callback()
        self.backend_callback()
        print('[interact_query_decision] Calling decision callback')
        print('[interact_query_decision] self.name_decision_callback = %r' % (self.name_decision_callback,))
        if isinstance(chosen_aids, six.string_types):
            # hack for string non-match commands
            chosen_names = chosen_aids
        else:
            chosen_names = self.ibs.get_annot_names(chosen_aids)
        self.name_decision_callback(chosen_names)
        print('[interact_query_decision] sent name_decision_callback(chosen_names=%r)' % (chosen_names,))
Ejemplo n.º 9
0
def wait_for_user_name_decision(ibs, cm, qreq_, choicetup, name_suggest_tup, incinfo=None):
    r"""
    Prompts the user for input
    hooks into to some method of getting user input for names

    Args:
        ibs (IBEISController):
        cm (QueryResult):  object of feature correspondences and scores
        autoname_func (function):

    CommandLine:
        python -m ibeis.algo.hots.user_dialogs --test-wait_for_user_name_decision --show

    Example:
        >>> # DISABLE_DOCTEST
        >>> from ibeis.algo.hots.user_dialogs import *  # NOQA
        >>> import ibeis
        >>> # build test data
        >>> ibs = ibeis.opendb('testdb1')
        >>> qaids = [1]
        >>> daids = [2, 3, 4, 5]
        >>> cm, qreq_ = ibs.query_chips(qaids, daids, cfgdict=dict(),
        >>>                             return_request=True)[0]
        >>> choicetup = '?'
        >>> name_suggest_tup = '?'
        >>> incinfo = None
        >>> # execute function
        >>> result = wait_for_user_name_decision(ibs, cm, qreq_, choicetup,
        >>>                                      name_suggest_tup, incinfo)
        >>> # verify results
        >>> print(result)
        >>> ut.show_if_requested()
    """
    import plottool as pt
    if cm is None:
        print('WARNING: chipmatch is None')

    new_mplshow = True and cm is not None
    mplshowtop = False and cm is not None
    qtinspect = False and cm is not None

    if new_mplshow:
        from ibeis.viz.interact import interact_query_decision
        print('Showing matplotlib window')
        # convert name choices into data for gui
        comp_aids, suggest_aids = convert_name_suggestion_to_aids(ibs,
                                                                  choicetup,
                                                                  name_suggest_tup)
        # Update names tree callback
        # Let the harness do these callbacks
        #backend_callback = incinfo.get('backend_callback', None)
        #update_callback = incinfo.get('update_callback', None)
        name_decision_callback = incinfo['name_decision_callback']
        progress_current       = incinfo['count']
        progress_total         = incinfo['nTotal']
        fnum = incinfo['fnum']
        qvi = interact_query_decision.QueryVerificationInteraction(
            qreq_, cm, comp_aids, suggest_aids,
            name_decision_callback=name_decision_callback,
            #update_callback=update_callback,
            #backend_callback=backend_callback,
            progress_current=progress_current, progress_total=progress_total,
            fnum=fnum)
        qvi.fig.show()
        pt.bring_to_front(qvi.fig)
    if mplshowtop:
        import guitool
        fnum = 513
        pt.figure(fnum=fnum, pnum=(2, 3, 1), doclf=True, docla=True)
        fig = cm.ishow_top(qreq_, fnum=fnum, in_image=False, annot_mode=0,
                           sidebyside=False, show_query=True)
        fig.show()
        #fig.canvas.raise_()
        #from plottool import fig_presenter
        #fig_presenter.bring_to_front(fig)
        newname = ibs.make_next_name()
        newname_prefix = 'New Name:\n'
        # FIXME or remoev
        name = None
        #if chosen_names is None:
        #    name = newname_prefix + newname

        aid_list = ut.get_list_column(choicetup.sorted_aids, 0)
        name_options = ibs.get_annot_names(aid_list) + [newname_prefix + newname]
        msg = 'Decide on query name. System suggests; ' + str(name)
        title = 'name decision'
        options = name_options[::-1]
        user_chosen_name = guitool.user_option(None, msg, title, options)  # NOQA
        if user_chosen_name is None:
            raise AssertionError('User Canceled Query')
        user_chosen_name = user_chosen_name.replace(newname_prefix, '')
        # TODO: Make the old interface use the correct sorted_aids format
        #name_decision_callback(user_chosen_name)
    if qtinspect:
        print('Showing qt inspect window')
        qres_wgt = cm.qt_inspect_gui(qreq_)
        qres_wgt.show()
        qres_wgt.raise_()
Ejemplo n.º 10
0
    def mark_unreviewed_above_score_as_correct(qres_wgt):
        selected_qtindex_list = qres_wgt.selectedRows()
        if len(selected_qtindex_list) == 1:
            qtindex = selected_qtindex_list[0]
            #aid1, aid2 = qres_wgt.get_aidpair_from_qtindex(qtindex)
            thresh = qtindex.model().get_header_data('score', qtindex)
            print('thresh = %r' % (thresh, ))

            rows = qres_wgt.review_api.ider()
            scores_ = qres_wgt.review_api.get(
                qres_wgt.review_api.col_name_list.index('score'), rows)
            valid_rows = ut.compress(rows, scores_ >= thresh)
            aids1 = qres_wgt.review_api.get(
                qres_wgt.review_api.col_name_list.index('qaid'), valid_rows)
            aids2 = qres_wgt.review_api.get(
                qres_wgt.review_api.col_name_list.index('aid'), valid_rows)
            #ibs = qres_wgt.ibs
            ibs = qres_wgt.ibs
            am_rowids = ibs.get_annotmatch_rowid_from_undirected_superkey(
                aids1, aids2)
            reviewed = ibs.get_annotmatch_reviewed(am_rowids)
            unreviewed = ut.not_list(reviewed)

            valid_rows = ut.compress(valid_rows, unreviewed)
            aids1 = ut.compress(aids1, unreviewed)
            aids2 = ut.compress(aids2, unreviewed)

            import networkx as nx
            graph = nx.Graph()
            graph.add_edges_from(list(zip(aids1, aids2)),
                                 {'user_thresh_match': True})
            review_groups = list(nx.connected_component_subgraphs(graph))

            changing_aids = list(graph.nodes())
            nids = ibs.get_annot_nids(changing_aids)
            nid2_aids = ut.group_items(changing_aids, nids)
            for nid, aids in nid2_aids.items():
                # Connect all original names in the database to denote merges
                for u, v in ut.itertwo(aids):
                    graph.add_edge(u, v)
            dbside_groups = list(nx.connected_component_subgraphs(graph))

            options = [
                'Accept',
                #'Review More'
            ]
            msg = ut.codeblock('''
                There are %d names and %d annotations in this mass review set.
                Mass review has discovered %d internal groups.
                Accepting will induce a database grouping of %d names.
                ''') % (len(nid2_aids), len(changing_aids), len(review_groups),
                        len(dbside_groups))

            reply = gt.user_option(msg=msg, options=options)

            if reply == options[0]:
                # This is not the smartest way to group names.
                # Ideally what will happen here, is that reviewed edges will go into
                # the new graph name inference algorithm.
                # then the chosen point will be used as the threshold. Then
                # the graph cut algorithm will be applied.
                logger = qres_wgt.logger
                logger.debug(msg)
                logger.info('START MASS_THRESHOLD_MERGE')
                logger.info('num_groups=%d thresh=%r' % (
                    len(dbside_groups),
                    thresh,
                ))
                for count, subgraph in enumerate(dbside_groups):
                    thresh_aid_pairs = [
                        edge for edge, flag in nx.get_edge_attributes(
                            graph, 'user_thresh_match').items() if flag
                    ]
                    thresh_uuid_pairs = ibs.unflat_map(ibs.get_annot_uuids,
                                                       thresh_aid_pairs)
                    aids = list(subgraph.nodes())
                    nids = ibs.get_annot_name_rowids(aids)
                    flags = ut.not_list(ibs.is_aid_unknown(aids))
                    previous_names = ibs.get_name_texts(nids)
                    valid_nids = ut.compress(nids, flags)
                    if len(valid_nids) == 0:
                        merge_nid = ibs.make_next_nids(num=1)[0]
                        type_ = 'new'
                    else:
                        merge_nid = min(valid_nids)
                        type_ = 'existing'

                    # Need to find other non-exemplar / query names that may
                    # need merging
                    other_aids = ibs.get_name_aids(valid_nids)
                    other_aids = set(ut.flatten(other_aids)) - set(aids)
                    other_auuids = ibs.get_annot_uuids(other_aids)
                    other_previous_names = ibs.get_annot_names(other_aids)

                    merge_name = ibs.get_name_texts(merge_nid)
                    annot_uuids = ibs.get_annot_uuids(aids)
                    ###
                    # Set as reviewed (so we dont see them again), but mark it
                    # with a different code to denote that it was a MASS review
                    aid1_list = ut.take_column(thresh_aid_pairs, 0)
                    aid2_list = ut.take_column(thresh_aid_pairs, 1)
                    am_rowids = ibs.add_annotmatch_undirected(
                        aid1_list, aid2_list)
                    ibs.set_annotmatch_reviewer(
                        am_rowids, ['algo:lnbnn_thresh'] * len(am_rowids))

                    logger.info('START GROUP %d' % (count, ))
                    logger.info(
                        'GROUP BASED ON %d ANNOT_PAIRS WITH SCORE ABOVE (thresh=%r)'
                        % (
                            len(thresh_uuid_pairs),
                            thresh,
                        ))
                    logger.debug('(uuid_pairs=%r)' % (thresh_uuid_pairs))
                    logger.debug('(merge_name=%r)' % (merge_name))
                    logger.debug(
                        'CHANGE NAME OF %d (annot_uuids=%r) WITH (previous_names=%r) TO (%s) (merge_name=%r)'
                        % (len(annot_uuids), annot_uuids, previous_names,
                           type_, merge_name))
                    logger.debug(
                        'ADDITIONAL CHANGE NAME OF %d (annot_uuids=%r) WITH (previous_names=%r) TO (%s) (merge_name=%r)'
                        % (len(other_auuids), other_auuids,
                           other_previous_names, type_, merge_name))
                    logger.info('END GROUP %d' % (count, ))
                    new_nids = [merge_nid] * len(aids)
                    ibs.set_annot_name_rowids(aids, new_nids)
                logger.info('END MASS_THRESHOLD_MERGE')
        else:
            print('[context] Multiple %d selection' %
                  (len(selected_qtindex_list), ))