def qt_edge_reviewer(infr, edge=None): import guitool_ibeis as gt gt.ensure_qapp() from ibeis.viz import viz_graph2 infr.manual_wgt = viz_graph2.AnnotPairDialog( edge=edge, infr=infr, standalone=False, cfgdict=infr.verifier_params) if edge is not None: # infr.emit_manual_review(edge, priority=None) infr.manual_wgt.seek(0) # infr.manual_wgt.show() return infr.manual_wgt
def launch_review_matches_interface(ibs, cm_list, dodraw=False, filter_reviewed=False): """ TODO: move to a more general function """ from ibeis.gui import inspect_gui gt.ensure_qapp() #backend_callback = back.front.update_tables backend_callback = None review_cfg = dict(filter_reviewed=filter_reviewed) qres_wgt = inspect_gui.QueryResultsWidget(ibs, cm_list, callback=backend_callback, review_cfg=review_cfg) if dodraw: qres_wgt.show() qres_wgt.raise_() return qres_wgt
def make_test_result_custom_api(ibs, testres): import guitool_ibeis guitool_ibeis.ensure_qapp() cfgx = 0 cfgres_info = testres.cfgx2_cmsinfo[cfgx] qaids = testres.qaids gt_aids = cfgres_info['qx2_gt_aid'] gf_aids = cfgres_info['qx2_gf_aid'] qx2_gt_timedelta = ibs.get_annot_pair_timedelta(qaids, gt_aids) qx2_gf_timedelta = ibs.get_annot_pair_timedelta(qaids, gf_aids) col_name_list = [ 'qaids', 'qx2_gt_aid', 'qx2_gf_aid', 'qx2_gt_timedelta', 'qx2_gf_timedelta', ] col_types_dict = {} col_getter_dict = {} col_getter_dict.update(**cfgres_info) col_getter_dict['qaids'] = testres.qaids col_getter_dict['qx2_gt_timedelta'] = qx2_gt_timedelta col_getter_dict['qx2_gf_timedelta'] = qx2_gf_timedelta col_bgrole_dict = {} col_ider_dict = {} col_setter_dict = {} editable_colnames = [] sortby = 'qaids' def get_thumb_size(): return 128 col_width_dict = {} custom_api = guitool_ibeis.CustomAPI(col_name_list, col_types_dict, col_getter_dict, col_bgrole_dict, col_ider_dict, col_setter_dict, editable_colnames, sortby, get_thumb_size, True, col_width_dict) #headers = custom_api.make_headers(tblnice='results') #print(ut.repr2(headers)) wgt = guitool_ibeis.APIItemWidget() wgt.connect_api(custom_api) return wgt
def setup_dummy_menus(): r""" CommandLine: python -m ibeis.gui.guimenus --test-setup_dummy_menus Example: >>> # DISABLE_DOCTEST >>> from ibeis.gui.guimenus import * # NOQA >>> result = setup_dummy_menus() >>> print(result) """ #import unittest import guitool_ibeis as gt gt.ensure_qapp() # must be ensured before any embeding mainwin = gt.QtWidgets.QMainWindow() back = DummyBack() import mock mainwin.expand_names_tree = mock.Mock setup_menus(mainwin, back) mainwin.show() mainwin.resize(600, 100) #ut.embed() gt.qtapp_loop(mainwin, frequency=100)
def demo_classes(pblm): r""" CommandLine: python -m ibeis.algo.verif.vsone demo_classes --saveparts --save=classes.png --clipwhite python -m ibeis.algo.verif.vsone demo_classes --saveparts --save=figures/classes.png --clipwhite --dpath=~/latex/crall-iccv-2017 Example: >>> # DISABLE_DOCTEST >>> from ibeis.algo.verif.vsone import * # NOQA >>> pblm = OneVsOneProblem.from_empty(defaultdb='PZ_PB_RF_TRAIN') >>> pblm.load_features() >>> pblm.load_samples() >>> pblm.build_feature_subsets() >>> pblm.demo_classes() >>> ut.show_if_requested() """ task_key = 'match_state' labels = pblm.samples.subtasks[task_key] pb_labels = pblm.samples.subtasks['photobomb_state'] classname_offset = { POSTV: 0, NEGTV: 0, INCMP: 0, } class_name = POSTV class_name = NEGTV class_name = INCMP feats = pblm.samples.X_dict['learn(sum,glob)'] offset = 0 class_to_edge = {} for class_name in labels.class_names: print('Find example of %r' % (class_name, )) # Find an example of each class (that is not a photobomb) pbflags = pb_labels.indicator_df['notpb'] flags = labels.indicator_df[class_name] assert np.all(pbflags.index == flags.index) flags = flags & pbflags ratio = feats['sum(ratio)'] if class_name == INCMP: # flags &= feats['global(delta_yaw)'] > 3 flags &= feats['global(delta_view)'] > 2 # flags &= feats['sum(ratio)'] > 0 if class_name == NEGTV: low = ratio[flags].max() flags &= feats['sum(ratio)'] >= low if class_name == POSTV: low = ratio[flags].median() / 2 high = ratio[flags].median() flags &= feats['sum(ratio)'] < high flags &= feats['sum(ratio)'] > low # flags &= pblm.samples.simple_scores[flags]['score_lnbnn_1vM'] > 0 idxs = np.where(flags)[0] print('Found %d candidates' % (len(idxs))) offset = classname_offset[class_name] idx = idxs[offset] series = labels.indicator_df.iloc[idx] assert series[class_name] edge = series.name class_to_edge[class_name] = edge import plottool_ibeis as pt import guitool_ibeis as gt gt.ensure_qapp() pt.qtensure() fnum = 1 pt.figure(fnum=fnum, pnum=(1, 3, 1)) pnum_ = pt.make_pnum_nextgen(1, 3) # classname_alias = { # POSTV: 'positive', # NEGTV: 'negative', # INCMP: 'incomparable', # } ibs = pblm.infr.ibs for class_name in class_to_edge.keys(): edge = class_to_edge[class_name] aid1, aid2 = edge # alias = classname_alias[class_name] print('class_name = %r' % (class_name, )) annot1 = ibs.annots([aid1])[0]._make_lazy_dict() annot2 = ibs.annots([aid2])[0]._make_lazy_dict() vt.matching.ensure_metadata_normxy(annot1) vt.matching.ensure_metadata_normxy(annot2) match = vt.PairwiseMatch(annot1, annot2) cfgdict = pblm.hyper_params.vsone_match.asdict() match.apply_all(cfgdict) pt.figure(fnum=fnum, pnum=pnum_()) match.show(show_ell=False, show_ori=False)
def fix_annotmatch_pzmaster1(): """ PZ_Master1 had annotmatch rowids that did not agree with the current name labeling. Looking at the inconsistencies in the graph interface was too cumbersome, because over 3000 annots were incorrectly grouped together. This function deletes any annotmatch rowid that is not consistent with the current labeling so we can go forward with using the new AnnotInference object """ import ibeis ibs = ibeis.opendb('PZ_Master1') infr = ibeis.AnnotInference(ibs=ibs, aids=ibs.get_valid_aids(), verbose=5) infr.initialize_graph() annots = ibs.annots() aid_to_nid = ut.dzip(annots.aids, annots.nids) if False: infr.reset_feedback() infr.ensure_mst() infr.apply_feedback_edges() infr.relabel_using_reviews() infr.start_qt_interface() # Get annotmatch rowids that agree with current labeling if False: annotmatch = ibs.db.get_table_as_pandas('annotmatch') import pandas as pd flags1 = pd.isnull(annotmatch['annotmatch_evidence_decision']) flags2 = annotmatch['annotmatch_tag_text'] == '' bad_part = annotmatch[flags1 & flags2] rowids = bad_part.index.tolist() ibs.delete_annotmatch(rowids) if False: # Delete bidirectional annotmatches annotmatch = ibs.db.get_table_as_pandas('annotmatch') df = annotmatch.set_index(['annot_rowid1', 'annot_rowid2']) # Find entires that have both directions pairs1 = annotmatch[['annot_rowid1', 'annot_rowid2']].values f_edges = {tuple(p) for p in pairs1} b_edges = {tuple(p[::-1]) for p in pairs1} isect_edges = {tuple(sorted(p)) for p in b_edges.intersection(f_edges)} isect_edges1 = list(isect_edges) isect_edges2 = [p[::-1] for p in isect_edges] # cols = ['annotmatch_evidence_decision', 'annotmatch_tag_text'] import pandas as pd custom_ = { (559, 4909): (False, ['photobomb']), (7918, 8041): (False, ['photobomb']), (6634, 6754): (False, ['photobomb']), (3707, 3727): (False, ['photobomb']), (86, 103): (False, ['photobomb']), } extra_ = { } fixme_edges = [] d1 = df.loc[isect_edges1].reset_index(drop=False) d2 = df.loc[isect_edges2].reset_index(drop=False) flags = d1['annotmatch_evidence_decision'] != d2['annotmatch_evidence_decision'] from ibeis.tag_funcs import _parse_tags for f, r1, r2 in zip(flags, d1.iterrows(), d2.iterrows()): v1, v2 = r1[1], r2[1] aid1 = v1['annot_rowid1'] aid2 = v1['annot_rowid2'] truth_real = (ibs.const.EVIDENCE_DECISION.POSITIVE if aid_to_nid[aid1] == aid_to_nid[aid2] else ibs.const.EVIDENCE_DECISION.NEGATIVE) truth1 = v1['annotmatch_evidence_decision'] truth2 = v2['annotmatch_evidence_decision'] t1 = _parse_tags(v1['annotmatch_tag_text']) t2 = _parse_tags(v2['annotmatch_tag_text']) newtag = ut.union_ordered(t1, t2) if (aid1, aid2) in custom_: continue fixme_flag = False if not pd.isnull(truth1): if truth_real != truth1: fixme_flag = True if not pd.isnull(truth2): if truth_real != truth2: fixme_flag = True if fixme_flag: print('newtag = %r' % (newtag,)) print('truth_real = %r' % (truth_real,)) print('truth1 = %r' % (truth1,)) print('truth2 = %r' % (truth2,)) print('aid1 = %r' % (aid1,)) print('aid2 = %r' % (aid2,)) fixme_edges.append((aid1, aid2)) else: extra_[(aid1, aid2)] = (truth_real, newtag) extra_.update(custom_) new_pairs = extra_.keys() new_truths = ut.take_column(ut.dict_take(extra_, new_pairs), 0) new_tags = ut.take_column(ut.dict_take(extra_, new_pairs), 1) new_tag_texts = [';'.join(t) for t in new_tags] aids1, aids2 = ut.listT(new_pairs) # Delete the old ibs.delete_annotmatch((d1['annotmatch_rowid'].values.tolist() + d2['annotmatch_rowid'].values.tolist())) # Add the new ams = ibs.add_annotmatch_undirected(aids1, aids2) ibs.set_annotmatch_evidence_decision(ams, new_truths) ibs.set_annotmatch_tag_text(ams, new_tag_texts) if False: import guitool_ibeis as gt gt.ensure_qapp() ut.qtensure() from ibeis.gui import inspect_gui inspect_gui.show_vsone_tuner(ibs, aid1, aid2) # pairs2 = pairs1.T[::-1].T # idx1, idx2 = ut.isect_indices(list(map(tuple, pairs1)), # list(map(tuple, pairs2))) # r_edges = list(set(map(tuple, map(sorted, pairs1[idx1])))) # unique_pairs = list(set(map(tuple, map(sorted, pairs1[idx1])))) # df = annotmatch.set_index(['annot_rowid1', 'annot_rowid2']) x = ut.ddict(list) annotmatch = ibs.db.get_table_as_pandas('annotmatch') import ubelt as ub _iter = annotmatch.iterrows() prog = ub.ProgIter(_iter, length=len(annotmatch)) for k, m in prog: aid1 = m['annot_rowid1'] aid2 = m['annot_rowid2'] if m['annotmatch_evidence_decision'] == ibs.const.EVIDENCE_DECISION.POSITIVE: if aid_to_nid[aid1] == aid_to_nid[aid2]: x['agree1'].append(k) else: x['disagree1'].append(k) elif m['annotmatch_evidence_decision'] == ibs.const.EVIDENCE_DECISION.NEGATIVE: if aid_to_nid[aid1] == aid_to_nid[aid2]: x['disagree2'].append(k) else: x['agree2'].append(k) ub.map_vals(len, x) ut.dict_hist(annotmatch.loc[x['disagree1']]['annotmatch_tag_text']) disagree1 = annotmatch.loc[x['disagree1']] pb_disagree1 = disagree1[disagree1['annotmatch_tag_text'] == 'photobomb'] aids1 = pb_disagree1['annot_rowid1'].values.tolist() aids2 = pb_disagree1['annot_rowid2'].values.tolist() aid_pairs = list(zip(aids1, aids2)) infr = ibeis.AnnotInference.from_pairs(aid_pairs, ibs=ibs, verbose=5) if False: feedback = infr.read_ibeis_annotmatch_feedback(edges=infr.edges()) infr.external_feedback = feedback infr.apply_feedback_edges() infr.start_qt_interface(loop=False) # Delete these values if False: nonpb_disagree1 = disagree1[disagree1['annotmatch_tag_text'] != 'photobomb'] disagree2 = annotmatch.loc[x['disagree2']] ibs.delete_annotmatch(nonpb_disagree1['annotmatch_rowid']) ibs.delete_annotmatch(disagree2['annotmatch_rowid']) # ut.dict_hist(disagree1['annotmatch_tag_text']) import networkx as nx graph = nx.Graph() graph.add_edges_from(zip(pb_disagree1['annot_rowid1'], pb_disagree1['annot_rowid2'])) list(nx.connected_components(graph)) set(annotmatch.loc[x['disagree2']]['annotmatch_tag_text'])
def fix_bidirectional_annotmatch(ibs): import ibeis infr = ibeis.AnnotInference(ibs=ibs, aids='all', verbose=5) infr.initialize_graph() annots = ibs.annots() aid_to_nid = ut.dzip(annots.aids, annots.nids) # Delete bidirectional annotmatches annotmatch = ibs.db.get_table_as_pandas('annotmatch') df = annotmatch.set_index(['annot_rowid1', 'annot_rowid2']) # Find entires that have both directions pairs1 = annotmatch[['annot_rowid1', 'annot_rowid2']].values f_edges = {tuple(p) for p in pairs1} b_edges = {tuple(p[::-1]) for p in pairs1} isect_edges = {tuple(sorted(p)) for p in b_edges.intersection(f_edges)} print('Found %d bidirectional edges' % len(isect_edges)) isect_edges1 = list(isect_edges) isect_edges2 = [p[::-1] for p in isect_edges] import pandas as pd extra_ = {} fixme_edges = [] d1 = df.loc[isect_edges1].reset_index(drop=False) d2 = df.loc[isect_edges2].reset_index(drop=False) flags = d1['annotmatch_evidence_decision'] != d2['annotmatch_evidence_decision'] from ibeis.tag_funcs import _parse_tags for f, r1, r2 in zip(flags, d1.iterrows(), d2.iterrows()): v1, v2 = r1[1], r2[1] aid1 = v1['annot_rowid1'] aid2 = v1['annot_rowid2'] truth_real = (ibs.const.EVIDENCE_DECISION.POSITIVE if aid_to_nid[aid1] == aid_to_nid[aid2] else ibs.const.EVIDENCE_DECISION.NEGATIVE) truth1 = v1['annotmatch_evidence_decision'] truth2 = v2['annotmatch_evidence_decision'] t1 = _parse_tags(v1['annotmatch_tag_text']) t2 = _parse_tags(v2['annotmatch_tag_text']) newtag = ut.union_ordered(t1, t2) fixme_flag = False if not pd.isnull(truth1): if truth_real != truth1: fixme_flag = True if not pd.isnull(truth2): if truth_real != truth2: fixme_flag = True if fixme_flag: print('--') print('t1, t2 = %r, %r' % (t1, t2)) print('newtag = %r' % (newtag,)) print('truth_real, truth1, truth2 = %r, %r, %r' % ( truth_real, truth1, truth2,)) print('aid1, aid2 = %r, %r' % (aid1, aid2)) fixme_edges.append(tuple(sorted((aid1, aid2)))) else: extra_[(aid1, aid2)] = (truth_real, newtag) if len(fixme_edges) > 0: # need to manually fix these edges fix_infr = ibeis.AnnotInference.from_pairs(fixme_edges, ibs=ibs, verbose=5) feedback = fix_infr.read_ibeis_annotmatch_feedback(only_existing_edges=True) infr = fix_infr fix_infr.external_feedback = feedback fix_infr.apply_feedback_edges() fix_infr.start_qt_interface(loop=False) # DELETE OLD EDGES TWICE ams = ibs.get_annotmatch_rowid_from_edges(fixme_edges) ibs.delete_annotmatch(ams) ams = ibs.get_annotmatch_rowid_from_edges(fixme_edges) ibs.delete_annotmatch(ams) # MANUALLY CALL THIS ONCE FINISHED # TO ONLY CHANGE ANNOTMATCH EDGES infr.write_ibeis_staging_feedback() infr.write_ibeis_annotmatch_feedback() # extra_.update(custom_) new_pairs = extra_.keys() new_truths = ut.take_column(ut.dict_take(extra_, new_pairs), 0) new_tags = ut.take_column(ut.dict_take(extra_, new_pairs), 1) new_tag_texts = [';'.join(t) for t in new_tags] aids1, aids2 = ut.listT(new_pairs) # Delete the old ibs.delete_annotmatch((d1['annotmatch_rowid'].values.tolist() + d2['annotmatch_rowid'].values.tolist())) # Add the new ams = ibs.add_annotmatch_undirected(aids1, aids2) ibs.set_annotmatch_evidence_decision(ams, new_truths) ibs.set_annotmatch_tag_text(ams, new_tag_texts) if False: import guitool_ibeis as gt gt.ensure_qapp() ut.qtensure() from ibeis.gui import inspect_gui inspect_gui.show_vsone_tuner(ibs, aid1, aid2)
def make_metadata_custom_api(metadata): r""" CommandLine: python -m ibeis.expt.experiment_drawing --test-make_metadata_custom_api --show Example: >>> # DISABLE_DOCTEST >>> from ibeis.expt.experiment_drawing import * # NOQA >>> import guitool_ibeis >>> guitool_ibeis.ensure_qapp() >>> metadata_fpath = '/media/raid/work/Elephants_drop1_ears/_ibsdb/figures/result_metadata.shelf' >>> metadata = ResultMetadata(metadata_fpath, autoconnect=True) >>> wgt = make_metadata_custom_api(metadata) >>> ut.quit_if_noshow() >>> wgt.show() >>> wgt.raise_() >>> guitool_ibeis.qtapp_loop(wgt, frequency=100) """ import guitool_ibeis from guitool_ibeis.__PYQT__ import QtCore class MetadataViewer(guitool_ibeis.APIItemWidget): def __init__(wgt, parent=None, tblnice='Result Metadata Viewer', **kwargs): guitool_ibeis.APIItemWidget.__init__(wgt, parent=parent, tblnice=tblnice, **kwargs) wgt.connect_signals_and_slots() @guitool_ibeis.slot_(QtCore.QModelIndex) def _on_doubleclick(wgt, qtindex): print('[wgt] _on_doubleclick: ') col = qtindex.column() if wgt.api.col_edit_list[col]: print('do nothing special for editable columns') return model = qtindex.model() colname = model.get_header_name(col) if colname.endswith('fpath'): print('showing fpath') fpath = model.get_header_data(colname, qtindex) ut.startfile(fpath) def connect_signals_and_slots(wgt): #wgt.view.clicked.connect(wgt._on_click) wgt.view.doubleClicked.connect(wgt._on_doubleclick) #wgt.view.pressed.connect(wgt._on_pressed) #wgt.view.activated.connect(wgt._on_activated) guitool_ibeis.ensure_qapp() #cfgstr_list = metadata col_name_list, column_list = metadata.get_square_data() # Priority of column names colname_priority = [ 'qaids', 'qx2_gt_rank', 'qx2_gt_timedelta', 'qx2_gf_timedelta', 'analysis_fpath', 'qx2_gt_raw_score', 'qx2_gf_raw_score' ] colname_priority += sorted( ut.setdiff_ordered(col_name_list, colname_priority)) sortx = ut.priority_argsort(col_name_list, colname_priority) col_name_list = ut.take(col_name_list, sortx) column_list = ut.take(column_list, sortx) col_lens = list(map(len, column_list)) print('col_name_list = %r' % (col_name_list, )) print('col_lens = %r' % (col_lens, )) assert len(col_lens) > 0, 'no columns' assert col_lens[0] > 0, 'no rows' assert all([len_ == col_lens[0] for len_ in col_lens]), 'inconsistant data' col_types_dict = {} col_getter_dict = dict(zip(col_name_list, column_list)) col_bgrole_dict = {} col_ider_dict = {} col_setter_dict = {} col_nice_dict = {name: name.replace('qx2_', '') for name in col_name_list} col_nice_dict.update({ 'qx2_gt_timedelta': 'GT TimeDelta', 'qx2_gf_timedelta': 'GF TimeDelta', 'qx2_gt_rank': 'GT Rank', }) editable_colnames = [] sortby = 'qaids' def get_thumb_size(): return 128 col_width_dict = {} custom_api = guitool_ibeis.CustomAPI(col_name_list, col_types_dict, col_getter_dict, col_bgrole_dict, col_ider_dict, col_setter_dict, editable_colnames, sortby, get_thumb_size, sort_reverse=True, col_width_dict=col_width_dict, col_nice_dict=col_nice_dict) #headers = custom_api.make_headers(tblnice='results') #print(ut.repr2(headers)) wgt = MetadataViewer() wgt.connect_api(custom_api) return wgt
def draw_results(ibs, testres): r""" Draws results from an experiment harness run. Rows store different qaids (query annotation ids) Cols store different configurations (algorithm parameters) Args: testres (TestResult): CommandLine: python dev.py -t custom:rrvsone_on=True,constrained_coeff=0 custom --qaid 12 --db PZ_MTEST --show --va python dev.py -t custom:rrvsone_on=True,constrained_coeff=.3 custom --qaid 12 --db PZ_MTEST --show --va --noqcache python dev.py -t custom:rrvsone_on=True custom --qaid 4 --db PZ_MTEST --show --va --noqcache python dev.py -t custom:rrvsone_on=True,grid_scale_factor=1 custom --qaid 12 --db PZ_MTEST --show --va --noqcache python dev.py -t custom:rrvsone_on=True,grid_scale_factor=1,grid_steps=1 custom --qaid 12 --db PZ_MTEST --show --va --noqcache CommandLine: python dev.py -t best --db seals2 --allgt --vz --fig-dname query_analysis_easy --show python dev.py -t best --db seals2 --allgt --vh --fig-dname query_analysis_hard --show python dev.py -t pyrscale --db PZ_MTEST --allgt --vn --fig-dname query_analysis_interesting --show python dev.py -t pyrscale --db testdb3 --allgt --vn --fig-dname query_analysis_interesting --vf python dev.py -t pyrscale --db testdb3 --allgt --vn --fig-dname query_analysis_interesting --vf --quality python -m ibeis.expt.experiment_drawing --test-draw_results --show --vn python -m ibeis.expt.experiment_drawing --test-draw_results --show --vn --db PZ_MTEST python -m ibeis.expt.old_storage --test-draw_results --show --db PZ_MTEST --gv Example: >>> # DISABLE_DOCTEST >>> from ibeis.expt.old_storage import * # NOQA >>> from ibeis.init import main_helpers >>> ibs, testres = main_helpers.testdata_expts('PZ_MTEST') >>> result = draw_results(ibs, testres) >>> # verify results >>> print(result) """ print(' --- DRAW RESULTS ---') # It is very inefficient to turn off caching when view_all is true figdir = ibs.get_fig_dir() ut.ensuredir(figdir) if ut.get_argflag(('--view-fig-directory', '--vf')): ut.view_directory(figdir) figdir_suffix = ut.get_argval('--fig-dname', type_=str, default=None) from os.path import join if figdir_suffix is not None: figdir = join(figdir, figdir_suffix) ut.ensuredir(figdir) #gx2_gt_timedelta # cfgres_info['qx2_gf_timedelta'] = qx2_gf_timedelta metadata_fpath = join(figdir, 'result_metadata.shelf') metadata = ResultMetadata(metadata_fpath) #metadata.rrr() metadata.connect() metadata.sync_test_results(testres) #cfgstr = qreq_.get_cfgstr() #cfg_metadata = ensure_item(metadata, cfgstr, {}) #avuuids = ibs.get_annot_visual_uuids(qaids) #avuuid2_ax = ensure_item(cfg_metadata, 'avuuid2_ax', {}) #cfg_columns = ensure_item(cfg_metadata, 'columns', {}) #import guitool_ibeis # ut.argv_flag_dec(draw_rank_cmc)(ibs, testres) # VIZ_INDIVIDUAL_RESULTS = True # if VIZ_INDIVIDUAL_RESULTS: # draw_match_cases(ibs, testres, metadata=metadata) metadata.write() if ut.get_argflag(('--guiview', '--gv')): import guitool_ibeis guitool_ibeis.ensure_qapp() #wgt = make_test_result_custom_api(ibs, testres) wgt = make_metadata_custom_api(metadata) wgt.show() wgt.raise_() guitool_ibeis.qtapp_loop(wgt, frequency=100) metadata.close() if ut.NOT_QUIET: print('[DRAW_RESULT] EXIT EXPERIMENT HARNESS')