graphid.core package¶
Submodules¶
- graphid.core.__main__ module
- graphid.core._rhomb_dist module
- graphid.core.annot_inference module
_rectify_decision()ConsistencyFeedbackFeedback._check_edge()Feedback.add_feedback_from()Feedback.edge_decision()Feedback.edge_decision_from()Feedback.add_node_feedback()Feedback.add_feedback()Feedback._print_debug_ccs()Feedback.feedback_keysFeedback.feedback_data_keysFeedback.apply_feedback_edges()Feedback._rectify_feedback()Feedback._rectify_feedback_item()Feedback.all_feedback_items()Feedback.all_feedback()Feedback.clear_feedback()Feedback.clear_edges()Feedback.reset()Feedback.reset_name_labels()Feedback.clear_name_labels()
NameRelabelMiscHelpersAltConstructorsAnnotInference
- graphid.core.mixin_callbacks module
- graphid.core.mixin_dynamic module
DynamicUpdateDynamicUpdate.ensure_edges_from()DynamicUpdate._add_review_edges_from()DynamicUpdate._add_review_edge()DynamicUpdate._get_current_decision()DynamicUpdate.on_between()DynamicUpdate.on_within()DynamicUpdate._update_neg_metagraph()DynamicUpdate._positive_decision()DynamicUpdate._negative_decision()DynamicUpdate._uninferable_decision()
RecoveryNonDynamicUpdate
- graphid.core.mixin_helpers module
AttrAccessAttrAccess.gen_node_attrs()AttrAccess.gen_edge_attrs()AttrAccess.gen_node_values()AttrAccess.gen_edge_values()AttrAccess.get_node_attrs()AttrAccess.get_edge_attrs()AttrAccess._get_edges_where()AttrAccess.get_edges_where_eq()AttrAccess.get_edges_where_ne()AttrAccess.set_node_attrs()AttrAccess.set_edge_attrs()AttrAccess.get_edge_attr()AttrAccess.set_edge_attr()AttrAccess.get_annot_attrs()AttrAccess.edges()AttrAccess.has_edge()AttrAccess.get_edge_data()AttrAccess.get_nonvisual_edge_data()AttrAccess.get_edge_dataframe()AttrAccess.get_edge_df_text()
ConvenienceConvenience.e_()Convenience.pos_graphConvenience.neg_graphConvenience.incomp_graphConvenience.unreviewed_graphConvenience.unknown_graphConvenience.print_graph_info()Convenience.print_graph_connections()Convenience.print_within_connection_info()Convenience.pair_connection_info()Convenience.node_tag_hist()Convenience.edge_tag_hist()Convenience.match_state_df()
DummyEdges
- graphid.core.mixin_invariants module
- graphid.core.mixin_loops module
- graphid.core.mixin_priority module
PriorityPriority.remaining_reviews()Priority._pop()Priority._push()Priority._peek_many()Priority._remove_edge_priority()Priority._reinstate_edge_priority()Priority._increase_priority()Priority.remove_internal_priority()Priority.reinstate_internal_priority()Priority.prioritize()Priority.push()Priority.pop()Priority.peek()Priority.peek_many()Priority.confidently_connected()Priority.confidently_separated()Priority.generate_reviews()Priority._generate_reviews()
- graphid.core.mixin_redundancy module
_RedundancyComputers_RedundancyComputers.is_pos_redundant()_RedundancyComputers.is_neg_redundant()_RedundancyComputers.find_neg_nids_to()_RedundancyComputers.find_neg_nid_freq_to()_RedundancyComputers.find_neg_redun_nids_to()_RedundancyComputers.find_pos_redundant_pccs()_RedundancyComputers.find_non_pos_redundant_pccs()_RedundancyComputers.find_non_neg_redun_pccs()_RedundancyComputers.find_pos_redun_nids()_RedundancyComputers.find_neg_redun_nids()
_RedundancyAugmentationRedundancy
- graphid.core.mixin_simulation module
- graphid.core.mixin_viz module
GraphVisualizationGraphVisualization._get_truth_colors()GraphVisualization._error_colorGraphVisualization._get_cmap()GraphVisualization.initialize_visual_node_attrs()GraphVisualization.update_node_image_config()GraphVisualization.update_node_image_attribute()GraphVisualization.get_colored_edge_weights()GraphVisualization.get_colored_weights()GraphVisualization.visual_edge_attrsGraphVisualization.visual_edge_attrs_appearanceGraphVisualization.visual_edge_attrs_spaceGraphVisualization.visual_node_attrsGraphVisualization.simplify_graph()GraphVisualization.pin_node_layout()GraphVisualization.update_visual_attrs()GraphVisualization.show_graph()GraphVisualization.show_edge()GraphVisualization.debug_edge_repr()GraphVisualization.repr_edge_data()GraphVisualization.show_error_case()GraphVisualization.show()
on_pick()color_nodes()nx_ensure_agraph_color()
- graphid.core.refresh module
- graphid.core.state module
_Common_ConstHelperEVIDENCE_DECISIONEVIDENCE_DECISION.UNREVIEWEDEVIDENCE_DECISION.NEGATIVEEVIDENCE_DECISION.POSITIVEEVIDENCE_DECISION.INCOMPARABLEEVIDENCE_DECISION.UNKNOWNEVIDENCE_DECISION.INT_TO_CODEEVIDENCE_DECISION.INT_TO_NICEEVIDENCE_DECISION.CODE_TO_NICEEVIDENCE_DECISION.CODE_TO_INTEVIDENCE_DECISION.NICE_TO_CODEEVIDENCE_DECISION.NICE_TO_INTEVIDENCE_DECISION.MATCH_CODEEVIDENCE_DECISION.CODEEVIDENCE_DECISION.NICE
META_DECISIONCONFIDENCEQUALVIEWVIEW.UNKNOWNVIEW.RVIEW.FRVIEW.FVIEW.FLVIEW.LVIEW.BLVIEW.BVIEW.BRVIEW.UVIEW.UFVIEW.UBVIEW.ULVIEW.URVIEW.UFLVIEW.UFRVIEW.UBLVIEW.UBRVIEW.DVIEW.DFVIEW.DBVIEW.DLVIEW.DRVIEW.DFLVIEW.DFRVIEW.DBLVIEW.DBRVIEW.INT_TO_CODEVIEW.INT_TO_NICEVIEW.CODE_TO_NICEVIEW.CODE_TO_INTVIEW.NICE_TO_CODEVIEW.NICE_TO_INTVIEW.DISTVIEW.CODEVIEW.CODE.BVIEW.CODE.BLVIEW.CODE.BRVIEW.CODE.DVIEW.CODE.DBVIEW.CODE.DBLVIEW.CODE.DBRVIEW.CODE.DFVIEW.CODE.DFLVIEW.CODE.DFRVIEW.CODE.DLVIEW.CODE.DRVIEW.CODE.FVIEW.CODE.FLVIEW.CODE.FRVIEW.CODE.LVIEW.CODE.RVIEW.CODE.UVIEW.CODE.UBVIEW.CODE.UBLVIEW.CODE.UBRVIEW.CODE.UFVIEW.CODE.UFLVIEW.CODE.UFRVIEW.CODE.ULVIEW.CODE.UNKNOWNVIEW.CODE.UR
VIEW.NICEVIEW.NICE.BVIEW.NICE.BLVIEW.NICE.BRVIEW.NICE.DVIEW.NICE.DBVIEW.NICE.DBLVIEW.NICE.DBRVIEW.NICE.DFVIEW.NICE.DFLVIEW.NICE.DFRVIEW.NICE.DLVIEW.NICE.DRVIEW.NICE.FVIEW.NICE.FLVIEW.NICE.FRVIEW.NICE.LVIEW.NICE.RVIEW.NICE.UVIEW.NICE.UBVIEW.NICE.UBLVIEW.NICE.UBRVIEW.NICE.UFVIEW.NICE.UFLVIEW.NICE.UFRVIEW.NICE.ULVIEW.NICE.UNKNOWNVIEW.NICE.UR
VIEW.dVIEW.f1VIEW.f2
Module contents¶
Regenerate Input Command mkinit graphid.core –lazy_loader_typed
- class graphid.core.AltConstructors[source]¶
Bases:
object- classmethod from_netx(G, verbose=False, infer=True)[source]¶
Creates an AnnotInference object from a networkx graph
- status(extended=False)[source]¶
Returns information about the state of the graph.
- Parameters:
extended (bool) – if True, adds in extra information that requires an O(|E|) amount of computation, otherwise only O(1) stats that are dynamically tracked are returned.
- Returns:
- a dictionary containing status information. Each of the keys
represents the following information:
nNodes: number of nodes in the graph nEdges: number of edges in the graph nCCs: number of positive connected components nPostvEdges: number of edges labeled as positive nNegtvEdges: number of edges labeled as negative nIncmpEdges: number of edges labeled as incomparable nUnrevEdges: number of edges labeled as unreviewed nPosRedunCCs: the number of PCCs which are currently
k-positive-redundant, i.e. we are confident those PCCs are the same individual.
- nNegRedunPairs: the number of PCCs pairs which are
currently k-negative-redundant, i.e. we are confident those PCCs are different individuals.
- nInconsistentCCs: the number of inconsistent PCCs that need
to be fixed, i.e. the number of PCCs with an internal negative edges.
- If extended is True, then the following keys are also present
nNegEdgesWithin: number of negatives edges inside PCCs nNegEdgesBetween: number of negative edges between PCCs nIncompEdgesWithin: number of incomparable edges inside PCCs nIncompEdgesBetween: number of incomparable edges between PCCs nUnrevEdgesWithin: number of unreviewed edges inside PCCs nUrevEdgesBetween: number of unreviewed edges between PCCs
- Return type:
Example
>>> from graphid import demo >>> infr = demo.demodata_infr(num_pccs=5, p_incon=0.5, pcc_size=10) >>> print(ub.urepr(infr.status(extended=True))) { 'nNodes': 50, 'nEdges': 93, 'nCCs': 5, 'nPostvEdges': 66, 'nNegtvEdges': 10, 'nIncmpEdges': 2, 'nUnrevEdges': 15, 'nPosRedunCCs': 1, 'nNegRedunPairs': 2, 'nInconsistentCCs': 3, 'nNegEdgesWithin': 4, 'nNegEdgesBetween': 6, 'nIncompEdgesWithin': 0, 'nIncompEdgesBetween': 2, 'nUnrevEdgesWithin': 15, 'nUrevEdgesBetween': 0, }
- class graphid.core.AnnotInference(aids=[], nids=None, autoinit=True, verbose=False)[source]¶
Bases:
NiceRepr,AltConstructors,MiscHelpers,Feedback,NameRelabel,Consistency,NonDynamicUpdate,Recovery,DynamicUpdate,Redundancy,Priority,AssertInvariants,DummyEdges,Convenience,AttrAccess,SimulationHelpers,InfrReviewers,InfrLoops,InfrCallbacks,InfrCandidates,GraphVisualizationclass for maintaining state of an identification
CommandLine
python -m graphid.core.annot_inference AnnotInference python -m graphid.core.annot_inference AnnotInference --show
Example
>>> from graphid.core import AnnotInference >>> import pytest >>> infr = AnnotInference() >>> print('infr = {}'.format(infr)) infr = <AnnotInference(nNodes=0, nEdges=0, nCCs=0)> >>> infr.add_aids(list(range(1, 6))) >>> print('infr = {}'.format(infr)) infr = <AnnotInference(nNodes=5, nEdges=0, nCCs=5)> >>> # Add some feedback >>> infr.params['allow_unseen_nodes'] = False >>> infr.add_feedback((1, 2), POSTV) >>> infr.add_feedback((1, 3), INCMP) >>> infr.add_feedback((1, 4), NEGTV) >>> with pytest.raises(ValueError): >>> infr.add_feedback((1, 10), NEGTV) >>> with pytest.raises(ValueError): >>> infr.add_feedback((11, 12), NEGTV) >>> print('infr = {}'.format(infr)) infr = <AnnotInference(nNodes=5, nEdges=3, nCCs=4)> >>> # xdoctest: +REQUIRES(--show) >>> infr.show_graph() >>> util.show_if_requested()
- subgraph(aids)[source]¶
Makes a new inference object that is a subset of the original.
Note, this is not robust, be careful. The subgraph should be treated as read only. Do not commit any reviews made from here.
- subparams(prefix)[source]¶
Returns dict of params prefixed with <prefix>. The returned dict does not contain the prefix
Example
>>> infr = AnnotInference() >>> result = ub.urepr(infr.subparams('refresh'), nl=0, precision=1, sort=1) >>> print(result) {'method': 'binomial', 'patience': 72, 'thresh': 0.1, 'window': 20}
- class graphid.core.AttrAccess[source]¶
Bases:
objectContains non-core helper functions
- gen_edge_attrs(key, edges=None, default=NoParam, on_missing=None)[source]¶
maybe change to gen edge items
- class graphid.core.CONFIDENCE[source]¶
Bases:
_Common- ABSOLUTELY_SURE = 4¶
- class CODE¶
Bases:
object- ABSOLUTELY_SURE = 'absolutely_sure'¶
- GUESSING = 'guessing'¶
- NOT_SURE = 'not_sure'¶
- PRETTY_SURE = 'pretty_sure'¶
- UNKNOWN = 'unspecified'¶
- CODE_TO_INT = {'absolutely_sure': 4, 'guessing': 1, 'not_sure': 2, 'pretty_sure': 3, 'unspecified': None}¶
- CODE_TO_NICE = {'absolutely_sure': 'Doubtless', 'guessing': 'Guessing', 'not_sure': 'Unsure', 'pretty_sure': 'Sure', 'unspecified': 'Unspecified'}¶
- GUESSING = 1¶
- INT_TO_CODE = {1: 'guessing', 2: 'not_sure', 3: 'pretty_sure', 4: 'absolutely_sure', None: 'unspecified'}¶
- INT_TO_NICE = {1: 'Guessing', 2: 'Unsure', 3: 'Sure', 4: 'Doubtless', None: 'Unspecified'}¶
- class NICE¶
Bases:
object- ABSOLUTELY_SURE = 'Doubtless'¶
- GUESSING = 'Guessing'¶
- NOT_SURE = 'Unsure'¶
- PRETTY_SURE = 'Sure'¶
- UNKNOWN = 'Unspecified'¶
- NICE_TO_CODE = {'Doubtless': 'absolutely_sure', 'Guessing': 'guessing', 'Sure': 'pretty_sure', 'Unspecified': 'unspecified', 'Unsure': 'not_sure'}¶
- NICE_TO_INT = {'Doubtless': 4, 'Guessing': 1, 'Sure': 3, 'Unspecified': None, 'Unsure': 2}¶
- NOT_SURE = 2¶
- PRETTY_SURE = 3¶
- UNKNOWN = None¶
- class graphid.core.Consistency[source]¶
Bases:
object- consistent_components(graph=None)[source]¶
Generates consistent PCCs. These PCCs contain no internal negative edges.
- Yields:
cc – set: nodes within the PCC
- inconsistent_components(graph=None)[source]¶
Generates inconsistent PCCs. These PCCs contain internal negative edges indicating an error exists.
- is_consistent(cc)[source]¶
Determines if a PCC contains inconsistencies
- Parameters:
cc (set) – nodes in a PCC
- Returns:
bool: returns True unless cc contains any negative edges
- Return type:
flag
Example
>>> from graphid import demo >>> infr = demo.demodata_infr(num_pccs=1, p_incon=1) >>> assert not infr.is_consistent(next(infr.positive_components())) >>> infr = demo.demodata_infr(num_pccs=1, p_incon=0) >>> assert infr.is_consistent(next(infr.positive_components()))
- class graphid.core.Convenience[source]¶
Bases:
object- property incomp_graph¶
- match_state_df(index)[source]¶
Returns the current matching state of a list of edges.
PERHAPS WE SHOULD DEPRICATE THIS FUNCTION?
Note
This does NOT use the IBEIS database state, where as the original version of this function did.
CommandLine
python -m graphid.core.mixin_helpers Convenience.match_state_df
Example
>>> from graphid import demo >>> infr = demo.demodata_infr(num_pccs=2, p_incomp=.8, size=4) >>> index = list(infr.edges()) >>> print(infr.match_state_df(index)) NEGTV POSTV INCMP aid1 aid2 1 3 False False True 4 False False True 2 False True False 2 3 False False True 4 False False True 3 4 False True False 5 False False True 5 8 False False True 7 False False True 6 False False True 6 8 False False True 7 False False True 7 8 False False True
- property neg_graph¶
- pair_connection_info(aid1, aid2)[source]¶
Helps debugging when ibs.nids has info that annotmatch/staging do not Note: the relevant ibs parts were removed. Perhaps this is not useful now or should be moved to the ibeis plugin?
Example
>>> from graphid import demo >>> infr = demo.demodata_infr(num_pccs=3, size=4) >>> aid1, aid2 = 1, 2 >>> print(infr.pair_connection_info(aid1, aid2))
- property pos_graph¶
- property unknown_graph¶
- property unreviewed_graph¶
- class graphid.core.DummyEdges[source]¶
Bases:
object- ensure_cliques(label='name_label', meta_decision=None)[source]¶
Force each name label to be a clique.
- Parameters:
label (str) – node attribute to use as the group id to form the cliques.
meta_decision (str) – if specified adds clique edges as feedback items with this decision. Otherwise the edges are only explicitly added to the graph.
- Parameters:
label (str) – defaults to ‘name_label’
meta_decision (str) – if specified, the feedback edges added are added this meta decision and with the user_id=algo:clique.
CommandLine
python -m graphid.core.mixin_helpers ensure_cliques
Example
>>> from graphid import demo >>> label = 'name_label' >>> infr = demo.demodata_infr(num_pccs=3, size=5) >>> print(ub.urepr(infr.status())) >>> assert infr.status()['nEdges'] < 33 >>> infr.ensure_cliques() >>> print(ub.urepr(infr.status())) >>> assert infr.status()['nEdges'] == 31 >>> assert infr.status()['nUnrevEdges'] == 12 >>> assert len(list(infr.find_clique_edges(label))) > 0 >>> infr.ensure_cliques(meta_decision=SAME) >>> assert infr.status()['nUnrevEdges'] == 0 >>> assert len(list(infr.find_clique_edges(label))) == 0
- ensure_mst(label='name_label', meta_decision='same')[source]¶
Ensures that all names are names are connected.
- Parameters:
label (str) – node attribute to use as the group id to form the mst.
meta_decision (str) – if specified adds clique edges as feedback items with this decision. Otherwise the edges are only explicitly added to the graph. This makes feedback items with user_id=algo:mst and with a confidence of guessing.
Example
>>> from graphid import demo >>> infr = demo.demodata_infr(num_pccs=3, size=4) >>> assert infr.status()['nCCs'] == 3 >>> infr.clear_edges() >>> assert infr.status()['nCCs'] == 12 >>> infr.ensure_mst() >>> assert infr.status()['nCCs'] == 3
- find_clique_edges(label='name_label')[source]¶
Augmenting edges that would complete each the specified cliques. (based on the group inferred from label)
- Parameters:
label (str) – node attribute to use as the group id to form the cliques.
- find_connecting_edges()[source]¶
Searches for a small set of edges, which if reviewed as positive would ensure that each PCC is k-connected. Note that in somes cases this is not possible
- find_mst_edges(label='name_label')[source]¶
Returns edges to augment existing PCCs (by label) in order to ensure they are connected with positive edges.
Example
>>> # DISABLE_DOCTEST >>> from graphid.core.mixin_helpers import * # NOQA >>> import ibeis >>> ibs = ibeis.opendb(defaultdb='PZ_MTEST') >>> infr = ibeis.AnnotInference(ibs, 'all', autoinit=True) >>> label = 'orig_name_label' >>> label = 'name_label' >>> infr.find_mst_edges() >>> infr.ensure_mst()
- class graphid.core.DynamicUpdate[source]¶
Bases:
object# 12 total possible states
# details of these states. POSITIVE, WITHIN, CONSISTENT
pos-within never changes PCC status
never introduces inconsistency
might add pos-redun
- POSITIVE, WITHIN, INCONSISTENT
pos-within never changes PCC status
might fix inconsistent edge
- POSITIVE, BETWEEN, BOTH_CONSISTENT
pos-between edge always does merge
- POSITIVE, BETWEEN, ANY_INCONSISTENT
pos-between edge always does merge
pos-between never fixes inconsistency
- NEGATIVE, WITHIN, CONSISTENT
might split PCC, results will be consistent
might causes an inconsistency
- NEGATIVE, WITHIN, INCONSISTENT
might split PCC, results may be inconsistent
- NEGATIVE, BETWEEN, BOTH_CONSISTENT
might add neg-redun
- NEGATIVE, BETWEEN, ANY_INCONSISTENT
might add to incon-neg-external
neg-redun not tracked for incon.
- UNINFERABLE, WITHIN, CONSISTENT
might remove pos-redun
might split PCC, results will be consistent
- UNINFERABLE, WITHIN, INCONSISTENT
might split PCC, results may be inconsistent
- UNINFERABLE, BETWEEN, BOTH_CONSISTENT
might remove neg-redun
- UNINFERABLE, BETWEEN, ANY_INCONSISTENT
might remove incon-neg-external
- _negative_decision(edge)[source]¶
Logic for a dynamic negative decision. A negative decision is evidence that two annots should not be in the same PCC
- _positive_decision(edge)[source]¶
Logic for a dynamic positive decision. A positive decision is evidence that two annots should be in the same PCC
Note, this could be an incomparable edge, but with a meta_decision of same.
- _uninferable_decision(edge, decision)[source]¶
Logic for a dynamic uninferable negative decision An uninferrable decision does not provide any evidence about PCC status and is either:
incomparable, unreviewed, or unknown
- _update_neg_metagraph(decision, prev_decision, nid1, nid2, merge_nid=None, split_nids=None)[source]¶
Update the negative metagraph based a new review
Todo
we can likely consolidate lots of neg_redun_metagraph functionality into this function. Just check when the weights are above or under the threshold and update accordingly.
- ensure_edges_from(edges)[source]¶
Finds edges that don’t exist and adds them as unreviwed edges. Returns new edges that were added.
- on_between(edge, decision, prev_decision, nid1, nid2, merge_nid=None)[source]¶
Callback when a review is made between two PCCs
- on_within(edge, decision, prev_decision, nid, split_nids=None)[source]¶
Callback when a review is made inside a PCC
- Parameters:
edge – the edge reviewed
decision – the new decision
prev_decision – the old decision
nid – the old nid the edge is inside of
split_nids – the tuple of new nids created if this decision splits a PCC
- class graphid.core.EVIDENCE_DECISION[source]¶
Bases:
_CommonTODO: 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.
- class CODE¶
Bases:
object- INCOMPARABLE = 'INCMP'¶
- NEGATIVE = 'NEGTV'¶
- POSITIVE = 'POSTV'¶
- UNKNOWN = 'UNKWN'¶
- UNREVIEWED = 'UNREV'¶
- CODE_TO_INT = {'INCMP': 2, 'NEGTV': 0, 'POSTV': 1, 'UNKWN': 3, 'UNREV': None}¶
- CODE_TO_NICE = {'INCMP': 'Incomparable', 'NEGTV': 'Negative', 'POSTV': 'Positive', 'UNKWN': 'Unknown', 'UNREV': 'Unreviewed'}¶
- INCOMPARABLE = 2¶
- INT_TO_CODE = {0: 'NEGTV', 1: 'POSTV', 2: 'INCMP', 3: 'UNKWN', None: 'UNREV'}¶
- INT_TO_NICE = {0: 'Negative', 1: 'Positive', 2: 'Incomparable', 3: 'Unknown', None: 'Unreviewed'}¶
- MATCH_CODE = {'INCMP': 2, 'NEGTV': 0, 'POSTV': 1, 'UNKWN': 3, 'UNREV': None}¶
- NEGATIVE = 0¶
- class NICE¶
Bases:
object- INCOMPARABLE = 'Incomparable'¶
- NEGATIVE = 'Negative'¶
- POSITIVE = 'Positive'¶
- UNKNOWN = 'Unknown'¶
- UNREVIEWED = 'Unreviewed'¶
- NICE_TO_CODE = {'Incomparable': 'INCMP', 'Negative': 'NEGTV', 'Positive': 'POSTV', 'Unknown': 'UNKWN', 'Unreviewed': 'UNREV'}¶
- NICE_TO_INT = {'Incomparable': 2, 'Negative': 0, 'Positive': 1, 'Unknown': 3, 'Unreviewed': None}¶
- POSITIVE = 1¶
- UNKNOWN = 3¶
- UNREVIEWED = None¶
- class graphid.core.Feedback[source]¶
Bases:
object- add_feedback(edge, evidence_decision=None, tags=None, user_id=None, meta_decision=None, confidence=None, timestamp_c1=None, timestamp_c2=None, timestamp_s1=None, timestamp=None, verbose=None, priority=None)[source]¶
Primary method for adding feedback and review edges to the graph.
- Parameters:
edge (tuple) – an undirected edge represented as a pair of aids
evidence_decision (str) – decision made based on visual evidence between the two photos. Can be POSTV, NEGTV, INCMP, or UNKWN. Note: POSTV etc… are the variables not the strings.
tags (list of str) – additional information to specify
user_id (str) – who is doing this review. This can identify a human or algorithm reviewer (e.g. ‘user:joncrall’ or ‘algo:vamp’).
meta_decision (str) – decision made based on external knowledge. Perhaps the photographer knows that two animals are the same because all photos are of the same animal. This constrains the identity problem, but does not impact the computer vision learning algorithms, which aren’t given the info needed to make this sort of decision.
confidence (str) – how sure is the user of this decision.
timestamp_c1 (int) – Time that the review client started
timestamp_c2 (int) – Time that the review client ended
timestamp_s1 (int) – Time that the review server started
timestamp (int) – Time that the review server ended
verbose (bool) – verbosity
priority (float, optional) – the priority assigned to this edge before review. This is only relevant for the termination criterion.
Notes
If infr.params[‘inference.enabled’] is True, then the edge is inserted into the graph and its properties are updated dynamically. Otherwise it is only added to the internal feedback dictionary and the apply_feedback_edges method must be called.
Example
>>> from graphid import demo >>> infr = demo.demodata_infr(num_pccs=5) >>> infr.add_feedback((5, 6), POSTV) >>> infr.add_feedback((5, 6), NEGTV, tags=['photobomb']) >>> infr.add_feedback((1, 2), INCMP) >>> print(ub.urepr(infr.internal_feedback, nl=3, sk=1)) >>> assert len(infr.external_feedback) == 0 >>> assert len(infr.internal_feedback) == 2 >>> assert len(infr.internal_feedback[(5, 6)]) == 2 >>> assert len(infr.internal_feedback[(1, 2)]) == 1
- add_feedback_from(items, verbose=None, **kwargs)[source]¶
- Parameters:
items (List[Edge]) – each edge is a dictionary with aid1, aid2, evidence_decision, meta_decision, etc..
- apply_feedback_edges()[source]¶
Transforms the feedback dictionaries into nx graph edge attributes. This
- feedback_data_keys = ['evidence_decision', 'tags', 'user_id', 'meta_decision', 'timestamp_c1', 'timestamp_c2', 'timestamp_s1', 'timestamp', 'confidence']¶
- feedback_keys = ['evidence_decision', 'tags', 'user_id', 'meta_decision', 'timestamp_c1', 'timestamp_c2', 'timestamp_s1', 'timestamp', 'confidence', 'num_reviews', 'review_id']¶
- reset(state='empty')[source]¶
Removes all edges from graph and resets name labels.
Example
>>> from graphid.core.annot_inference import * # NOQA >>> from graphid import demo >>> infr = demo.demodata_infr(num_pccs=5) >>> assert len(list(infr.edges())) > 0 >>> infr.reset(state='empty') >>> assert len(list(infr.edges())) == 0
- class graphid.core.GraphVisualization[source]¶
Bases:
objectcontains plotting related code
- property _error_color¶
- pin_node_layout()[source]¶
Ensures a node layout exists and then sets the pin attribute on each node, which tells graphviz not to change node positions. Useful for making before and after pictures.
- show(graph=None, use_image=False, update_attrs=True, with_colorbar=False, pnum=(1, 1, 1), zoomable=True, pickable=False, **kwargs)¶
- Parameters:
infr (?)
graph (None) – (default = None)
use_image (bool) – (default = False)
update_attrs (bool) – (default = True)
with_colorbar (bool) – (default = False)
pnum (tuple) – plot number(default = (1, 1, 1))
zoomable (bool) – (default = True)
pickable (bool) – (de = False)
**kwargs – verbose, with_labels, fnum, layout, ax, pos, img_dict, title, layoutkw, framewidth, modify_ax, as_directed, hacknoedge, hacknode, node_labels, arrow_width, fontsize, fontweight, fontname, fontfamilty, fontproperties
Example
>>> # xdoctest: +REQUIRES(module:pygraphviz) >>> from graphid import demo >>> infr = demo.demodata_infr(ccs=util.estarmap( >>> range, [(1, 6), (6, 10), (10, 13), (13, 15), (15, 16), >>> (17, 20)])) >>> pnum_ = util.PlotNums(nRows=1, nCols=3) >>> infr.show_graph(show_cand=True, simple_labels=True, pickable=True, fnum=1, pnum=pnum_()) >>> infr.add_feedback((1, 5), INCMP) >>> infr.add_feedback((14, 18), INCMP) >>> infr.refresh_candidate_edges() >>> infr.show_graph(show_cand=True, simple_labels=True, pickable=True, fnum=1, pnum=pnum_()) >>> infr.add_feedback((17, 18), NEGTV) # add inconsistency >>> infr.apply_nondynamic_update() >>> infr.show_graph(show_cand=True, simple_labels=True, pickable=True, fnum=1, pnum=pnum_()) >>> util.show_if_requested()
- show_graph(graph=None, use_image=False, update_attrs=True, with_colorbar=False, pnum=(1, 1, 1), zoomable=True, pickable=False, **kwargs)[source]¶
- Parameters:
infr (?)
graph (None) – (default = None)
use_image (bool) – (default = False)
update_attrs (bool) – (default = True)
with_colorbar (bool) – (default = False)
pnum (tuple) – plot number(default = (1, 1, 1))
zoomable (bool) – (default = True)
pickable (bool) – (de = False)
**kwargs – verbose, with_labels, fnum, layout, ax, pos, img_dict, title, layoutkw, framewidth, modify_ax, as_directed, hacknoedge, hacknode, node_labels, arrow_width, fontsize, fontweight, fontname, fontfamilty, fontproperties
Example
>>> # xdoctest: +REQUIRES(module:pygraphviz) >>> from graphid import demo >>> infr = demo.demodata_infr(ccs=util.estarmap( >>> range, [(1, 6), (6, 10), (10, 13), (13, 15), (15, 16), >>> (17, 20)])) >>> pnum_ = util.PlotNums(nRows=1, nCols=3) >>> infr.show_graph(show_cand=True, simple_labels=True, pickable=True, fnum=1, pnum=pnum_()) >>> infr.add_feedback((1, 5), INCMP) >>> infr.add_feedback((14, 18), INCMP) >>> infr.refresh_candidate_edges() >>> infr.show_graph(show_cand=True, simple_labels=True, pickable=True, fnum=1, pnum=pnum_()) >>> infr.add_feedback((17, 18), NEGTV) # add inconsistency >>> infr.apply_nondynamic_update() >>> infr.show_graph(show_cand=True, simple_labels=True, pickable=True, fnum=1, pnum=pnum_()) >>> util.show_if_requested()
- update_visual_attrs(graph=None, show_reviewed_edges=True, show_unreviewed_edges=False, show_inferred_diff=True, show_inferred_same=True, show_recent_review=False, highlight_reviews=True, show_inconsistency=True, wavy=False, simple_labels=False, show_labels=True, reposition=True, use_image=False, edge_overrides=None, node_overrides=None, colorby='name_label', **kwargs)[source]¶
- property visual_edge_attrs¶
all edge visual attrs
- property visual_edge_attrs_appearance¶
attrs that pertain to edge color and style
- property visual_edge_attrs_space¶
attrs that pertain to edge positioning in a plot
- property visual_node_attrs¶
- class graphid.core.InfrCallbacks[source]¶
Bases:
objectMethods relating to callbacks that must be registered with the inference object for it to work properly.
- refresh_candidate_edges()[source]¶
CommandLine
python -m graphid.core.mixin_callbacks InfrCallbacks.refresh_candidate_edges
Example
>>> from graphid import demo >>> kwargs = dict(num_pccs=40, size=2) >>> infr = demo.demodata_infr(**kwargs) >>> infr.refresh_candidate_edges()
- class graphid.core.InfrCandidates[source]¶
Bases:
objectMethods that should be used by callbacks to add new edges to be considered as candidates in the priority queue.
- ensure_priority_scores(priority_edges)[source]¶
Ensures that priority attributes are assigned to the edges. This does not change the state of the queue.
Doctest
>>> from graphid import demo >>> infr = demo.demodata_infr(num_pccs=6, p_incon=.5, size_std=2) >>> edges = list(infr.edges()) >>> infr.ensure_priority_scores(edges)
- ensure_task_probs(edges)[source]¶
Ensures that probabilities are assigned to the edges. This gaurentees that infr.task_probs contains data for edges. (Currently only the primary task is actually ensured)
CommandLine
python -m graphid.core.mixin_callbacks InfrCandidates.ensure_task_probs
Doctest
>>> from graphid import demo >>> infr = demo.demodata_infr(num_pccs=6, p_incon=.5, size_std=2) >>> edges = list(infr.edges()) >>> infr.ensure_task_probs(edges) >>> assert all([np.isclose(sum(p.values()), 1) >>> for p in infr.task_probs['match_state'].values()])
- class graphid.core.InfrLoops[source]¶
Bases:
objectAlgorithm control flow loops
- _inner_priority_gen(use_refresh=False, only_auto=False)[source]¶
Helper function that implements the general inner priority loop.
Executes reviews until the queue is empty or needs refresh
- Parameters:
user_refresh (bool) – if True enables the refresh criteria. (set to True in Phase 1)
only_auto (bool) – reviews unless the graph is inconsistent. (set to True in Phase 3)
Notes
The caller is responsible for populating the priority queue. This will iterate until the queue is empty or the refresh critieron is triggered.
- hardcase_review_gen()[source]¶
Subiterator for hardcase review
Re-review non-confident edges that vsone did not classify correctly
- incon_recovery_gen()[source]¶
Subiterator for recovery mode of the mainm algorithm
Iterates until the graph is consistent
Note
inconsistency recovery is implicitly handled by the main algorithm, so other phases do not need to call this explicitly. This exists for the case where the only mode we wish to run is inconsistency recovery.
- main_gen(max_loops=None, use_refresh=True)[source]¶
The main outer loop.
This function is designed as an iterator that will execute the graph algorithm main loop as automatically as possible, but if user input is needed, it will pause and yield the decision it needs help with. Once feedback is given for this item, you can continue the main loop by calling next. StopIteration is raised once the algorithm is complete.
- Parameters:
max_loops (int) – maximum number of times to run the outer loop, i.e. ranking is run at most this many times.
use_refresh (bool) – allow the refresh criterion to stop the algo
Notes
Different phases of the main loop are implemented as subiterators
CommandLine
python -m graphid.core.mixin_loops InfrLoops.main_gen
Example
>>> from graphid.core.mixin_simulation import UserOracle >>> from graphid import demo >>> infr = demo.demodata_infr(num_pccs=3, size=5) >>> infr.params['manual.n_peek'] = 10 >>> infr.params['ranking.ntop'] = 1 >>> infr.oracle = UserOracle(.99, rng=0) >>> infr.simulation_mode = False >>> infr.reset() >>> gen = infr.main_gen() >>> while True: >>> try: >>> reviews = next(gen) >>> edge, priority, data = reviews[0] >>> feedback = infr.request_oracle_review(edge) >>> infr.add_feedback(edge, **feedback) >>> except StopIteration: >>> break
- main_loop(max_loops=None, use_refresh=True)[source]¶
DEPRICATED
use list(infr.main_gen) instead or assert not any(infr.main_gen()) maybe this is fine.
- neg_redun_gen()[source]¶
Subiterator for phase3 of the main algorithm.
Searches for decisions that would commplete negative redundancy
- pos_redun_gen()[source]¶
Subiterator for phase2 of the main algorithm.
Searches for decisions that would commplete positive redundancy
CommandLine
python -m graphid.core.mixin_loops InfrLoops.pos_redun_gen
Example
>>> from graphid.core.mixin_loops import * >>> from graphid import demo >>> infr = demo.demodata_infr(num_pccs=3, size=5, pos_redun=1) >>> gen = infr.pos_redun_gen() >>> feedback = next(gen) >>> edge_ = feedback[0][0] >>> print(edge_) (1, 5)
- class graphid.core.InfrReviewers[source]¶
Bases:
object
- class graphid.core.META_DECISION[source]¶
Bases:
_CommonEnumerated 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
>>> 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
- CODE_TO_INT = {'diff': 0, 'null': None, 'same': 1}¶
- CODE_TO_NICE = {'diff': 'Different', 'null': 'NULL', 'same': 'Same'}¶
- DIFF = 0¶
- INT_TO_CODE = {0: 'diff', 1: 'same', None: 'null'}¶
- INT_TO_NICE = {0: 'Different', 1: 'Same', None: 'NULL'}¶
- NICE_TO_CODE = {'Different': 'diff', 'NULL': 'null', 'Same': 'same'}¶
- NICE_TO_INT = {'Different': 0, 'NULL': None, 'Same': 1}¶
- NULL = None¶
- SAME = 1¶
- class graphid.core.MiscHelpers[source]¶
Bases:
object- add_aids(aids, nids=None)[source]¶
CommandLine
python -m graphid.core.annot_inference MiscHelpers.add_aids
Doctest
>>> aids_ = [1, 2, 3, 4, 5, 6, 7, 9] >>> infr = AnnotInference(aids=aids_, autoinit=True) >>> aids = [2, 22, 7, 9, 8] >>> nids = None >>> infr.add_aids(aids, nids) >>> result = infr.aids >>> print(result) >>> assert len(infr.graph) == len(infr.aids) [1, 2, 3, 4, 5, 6, 7, 9, 22, 8]
- remove_aids(aids)[source]¶
Remove annotations from the graph.
- Returns:
split: indicates which PCCs were split by this action.
- Return type:
Note
This may cause unintended splits!
CommandLine
xdoctest -m graphid.core.annot_inference MiscHelpers.remove_aids
Example
>>> from graphid import demo, util >>> infr = demo.demodata_infr(num_pccs=5, pos_redun=1) >>> infr.refresh_candidate_edges() >>> infr.pin_node_layout() >>> before = infr.copy() >>> aids = infr.aids[::5] >>> splits = infr.remove_aids(aids) >>> assert len(splits['old']) > 0 >>> infr.assert_invariants() >>> # xdoctest: +REQUIRES(--show) >>> util.autompl() >>> after = infr >>> before.show(fnum=1, pnum=(1, 2, 1), pickable=True) >>> after.show(fnum=1, pnum=(1, 2, 2), pickable=True)
- class graphid.core.NameRelabel[source]¶
Bases:
object- _rectify_names(old_names, new_labels)[source]¶
Finds the best assignment of old names based on the new groups each is assigned to.
old_names = [None, None, None, 1, 2, 3, 3, 4, 4, 4, 5, None] new_labels = [ 1, 2, 2, 3, 4, 5, 5, 6, 3, 3, 7, 7]
- relabel_using_reviews(graph=None, rectify=True)[source]¶
Relabels nodes in graph based on positive connected components
This will change the ‘name_label’ of the nodes to be consistent while preserving any existing names as best as possible. If rectify=False, this will be faster, but the old names may not be preserved and each PCC will be assigned an arbitrary name.
Note
if something messes up you can call infr.reset_labels_to_ibeis() to reset node labels to their original values — this will almost always put the graph in an inconsistent state — but then you can this with rectify=True to fix everything up.
- Parameters:
graph (nx.Graph, optional) – only edges in graph are relabeled defaults to current graph.
rectify (bool, optional) – if True names attempt to remain consistent otherwise there are no restrictions on name labels other than that they are distinct.
Example
>>> from graphid import demo, util >>> infr = demo.demodata_infr(num_pccs=5, pos_redun=1) >>> names0 = set(infr.get_node_attrs('name_label').values()) >>> infr.relabel_using_reviews(rectify=True) >>> names1 = set(infr.get_node_attrs('name_label').values()) >>> assert names0 == names1 >>> # wont change because its the entire graph >>> #infr.relabel_using_reviews(rectify=False) >>> #names2 = set(infr.get_node_attrs('name_label').values())
- class graphid.core.NonDynamicUpdate[source]¶
Bases:
object- apply_nondynamic_update(graph=None)[source]¶
Recomputes all dynamic bookkeeping for a graph in any state. This ensures that subsequent dyanmic inference can be applied.
Example
>>> from graphid import demo >>> num_pccs = 250 >>> kwargs = dict(num_pccs=100, p_incon=.3) >>> infr = demo.demodata_infr(infer=False, **kwargs) >>> graph = None >>> infr.apply_nondynamic_update() >>> infr.assert_neg_metagraph()
- categorize_edges(graph=None, ne_to_edges=None)[source]¶
Non-dynamically computes the status of each edge in the graph. This is can be used to verify the dynamic computations and update when the dynamic state is lost.
Example
>>> from graphid import demo >>> num_pccs = 250 if ub.argflag('--profile') else 100 >>> kwargs = dict(num_pccs=100, p_incon=.3) >>> infr = demo.demodata_infr(infer=False, **kwargs) >>> graph = None >>> cat = infr.categorize_edges()
- class graphid.core.Priority[source]¶
Bases:
objectHandles prioritization of edges for review.
Example
>>> from graphid.core.mixin_priority import * # NOQA >>> from graphid import demo >>> infr = demo.demodata_infr(num_pccs=20)
- confidently_connected(u, v, thresh=2)[source]¶
Checks if u and v are conneted by edges above a confidence threshold
- confidently_separated(u, v, thresh=2)[source]¶
Checks if u and v are conneted by edges above a confidence threshold
Example
>>> from graphid.core.mixin_priority import * # NOQA >>> from graphid import demo >>> infr = demo.demodata_infr(ccs=[(1, 2), (3, 4), (5, 6), (7, 8)]) >>> infr.add_feedback((1, 5), NEGTV) >>> infr.add_feedback((5, 8), NEGTV) >>> infr.add_feedback((6, 3), NEGTV) >>> u, v = (1, 4) >>> thresh = 0 >>> assert not infr.confidently_separated(u, v, thresh) >>> infr.add_feedback((2, 3), NEGTV) >>> assert not infr.confidently_separated(u, v, thresh)
- generate_reviews(pos_redun=None, neg_redun=None, data=False)[source]¶
Dynamic generator that yeilds high priority reviews
- peek_many(n)[source]¶
Peeks at the top n edges in the queue.
Example
>>> # ENABLE_DOCTEST >>> from graphid.core.mixin_priority import * # NOQA >>> from graphid import demo >>> infr = demo.demodata_infr(num_pccs=7, size=5) >>> infr.refresh_candidate_edges() >>> infr.peek_many(50)
- pop()[source]¶
Main interface to the priority queue used by the algorithm loops. Pops the highest priority edge from the queue.
- prioritize(metric=None, edges=None, scores=None, force_inconsistent=True, reset=False)[source]¶
Adds edges to the priority queue.
Note that these edges must already exist in the infr.unreviewed_graph as unreviewed edges. By default the prob_match edge attribute is used to sort edges. If you have registered a verification algorithm, then these scores are computed using infr.ensure_priority_scores(edges). However, you can have all this done for you by simply calling infr.add_candidate_edges(edges) or infr.refresh_candidate_edges().
Example
>>> from graphid.core.mixin_priority import * # NOQA >>> from graphid import demo >>> import ubelt as ub >>> from graphid.core.state import SAME >>> infr = demo.demodata_infr(num_pccs=7, size=5) >>> infr.ensure_cliques(meta_decision=SAME) >>> # Add a negative edge inside a PCC >>> ccs = list(infr.positive_components()) >>> edge1 = tuple(list(ccs[0])[0:2]) >>> edge2 = tuple(list(ccs[1])[0:2]) >>> infr.add_feedback(edge1, NEGTV) >>> infr.add_feedback(edge2, NEGTV) >>> num_new = infr.prioritize(reset=True) >>> order = infr._peek_many(np.inf) >>> scores = util.take_column(order, 1) >>> assert scores[0] > 10 >>> assert len(scores) == num_new, 'should prioritize two hypotheis edges' >>> unrev_edges = set(infr.unreviewed_graph.edges()) >>> err_edges = set(ub.flatten(infr.nid_to_errors.values())) >>> edges = set(list(unrev_edges - err_edges)[0:2]) >>> edges.update(list(err_edges)[0:2]) >>> num_new = infr.prioritize(edges=edges, reset=True) >>> order2 = infr._peek_many(np.inf) >>> scores2 = np.array(util.take_column(order2, 1)) >>> assert np.all(scores2[0:2] > 10) >>> assert np.all(scores2[2:] < 10)
- class graphid.core.QUAL[source]¶
Bases:
_Common- class CODE¶
Bases:
object- EXCELLENT = 'excellent'¶
- GOOD = 'good'¶
- JUNK = 'junk'¶
- OK = 'ok'¶
- POOR = 'poor'¶
- UNKNOWN = 'unspecified'¶
- CODE_TO_INT = {'excellent': 5, 'good': 4, 'junk': 1, 'ok': 3, 'poor': 2, 'unspecified': None}¶
- CODE_TO_NICE = {'excellent': 'Excellent', 'good': 'Good', 'junk': 'Junk', 'ok': 'OK', 'poor': 'Poor', 'unspecified': 'Unspecified'}¶
- EXCELLENT = 5¶
- GOOD = 4¶
- INT_TO_CODE = {1: 'junk', 2: 'poor', 3: 'ok', 4: 'good', 5: 'excellent', None: 'unspecified'}¶
- INT_TO_NICE = {1: 'Junk', 2: 'Poor', 3: 'OK', 4: 'Good', 5: 'Excellent', None: 'Unspecified'}¶
- JUNK = 1¶
- class NICE¶
Bases:
object- EXCELLENT = 'Excellent'¶
- GOOD = 'Good'¶
- JUNK = 'Junk'¶
- OK = 'OK'¶
- POOR = 'Poor'¶
- UNKNOWN = 'Unspecified'¶
- NICE_TO_CODE = {'Excellent': 'excellent', 'Good': 'good', 'Junk': 'junk', 'OK': 'ok', 'Poor': 'poor', 'Unspecified': 'unspecified'}¶
- NICE_TO_INT = {'Excellent': 5, 'Good': 4, 'Junk': 1, 'OK': 3, 'Poor': 2, 'Unspecified': None}¶
- OK = 3¶
- POOR = 2¶
- UNKNOWN = None¶
- class graphid.core.Recovery[source]¶
Bases:
objectrecovery funcs
- _purge_error_edges(nid)[source]¶
Removes all error edges associated with a PCC so they can be recomputed or resolved.
- is_recovering(edge=None)[source]¶
Checks to see if the graph is inconsinsistent.
- Parameters:
edge (None) – If None, then returns True if the graph contains any inconsistency. Otherwise, returns True if the edge is related to an inconsistent component via a positive or negative connection.
- Returns:
flag
- Return type:
CommandLine
python -m graphid.core.mixin_dynamic Recovery.is_recovering
Doctest
>>> from graphid import demo >>> infr = demo.demodata_infr(num_pccs=4, size=4, ignore_pair=True) >>> infr.ensure_cliques(meta_decision=SAME) >>> a, b, c, d = map(list, infr.positive_components()) >>> assert infr.is_recovering() is False >>> infr.add_feedback((a[0], a[1]), NEGTV) >>> assert infr.is_recovering() is True >>> assert infr.is_recovering((a[2], a[3])) is True >>> assert infr.is_recovering((a[3], b[0])) is True >>> assert infr.is_recovering((b[0], b[1])) is False >>> infr.add_feedback((a[3], b[2]), NEGTV) >>> assert infr.is_recovering((b[0], b[1])) is True >>> assert infr.is_recovering((c[0], d[0])) is False >>> infr.add_feedback((b[2], c[0]), NEGTV) >>> assert infr.is_recovering((c[0], d[0])) is False >>> result = ub.urepr({ >>> 'iccs': list(infr.inconsistent_components()), >>> 'pccs': sorted([cc for cc in infr.positive_components()], key=min), >>> }, nobr=1, sorted=True, si=True, itemsep='', sep='', nl=1) >>> print(result) iccs: [{1,2,3,4}], pccs: [{1,2,3,4},{5,6,7,8},{9,10,11,12},{13,14,15,16}],
- class graphid.core.Redundancy[source]¶
Bases:
_RedundancyComputers,_RedundancyAugmentationmethods for dynamic redundancy book-keeping
- _purge_redun_flags(nid)[source]¶
Removes positive and negative redundancy from nids and all other PCCs touching nids respectively. Return the external PCC nids.
(TODO: NEG REDUN CAN BE CONSOLIDATED VIA NEG-META-GRAPH)
- _set_neg_redun_flags(nid1, other_nids, flags)[source]¶
Flags or unflags an nid1 as negative redundant with other nids. (TODO: NEG REDUN CAN BE CONSOLIDATED VIA NEG-META-GRAPH)
- filter_edges_flagged_as_redun(edges)[source]¶
Returns only edges that are not flagged as redundant. Uses bookkeeping structures
Example
>>> from graphid import demo >>> infr = demo.demodata_infr(num_pccs=1, size=4) >>> infr.clear_edges() >>> infr.ensure_cliques() >>> infr.clear_feedback() >>> print(ub.urepr(infr.status())) >>> nonredun_edges = list(infr.filter_edges_flagged_as_redun( >>> infr.unreviewed_graph.edges())) >>> assert len(nonredun_edges) == 6
- update_extern_neg_redun(nid, may_add=True, may_remove=True, force=False)[source]¶
Checks if nid is negative redundant to any other cc it has at least one negative review to. (TODO: NEG REDUN CAN BE CONSOLIDATED VIA NEG-META-GRAPH)
- class graphid.core.RefreshCriteria(window=20, patience=72, thresh=0.1, method='binomial')[source]¶
Bases:
objectDetermine when to re-query for candidate edges.
Models an upper bound on the probability that any of the next patience reviews will be label-changing (meaningful). Once this probability is below a threshold the criterion triggers. The model is either binomial or poisson. They both work about the same. The binomial is a slightly better model.
Does this by maintaining an estimate of the probability any particular review will be label-chaging using an exponentially weighted moving average. This is the rate parameter / individual event probability.
- ave(method='exp')[source]¶
Example
>>> from graphid import demo >>> infr = demo.demodata_infr(num_pccs=40, size=4, size_std=2, ignore_pair=True) >>> edges = list(infr.ranker.predict_candidate_edges(infr.aids, K=100)) >>> scores = np.array(infr.verifier.predict_edges(edges)) >>> #sortx = util.shuffle(np.arange(len(edges)), rng=321) >>> sortx = scores.argsort()[::-1] >>> edges = list(ub.take(edges, sortx)) >>> scores = scores[sortx] >>> ys = infr.match_state_df(edges)[POSTV].values >>> y_remainsum = ys[::-1].cumsum()[::-1] >>> refresh = RefreshCriteria(window=250) >>> ma1 = [] >>> ma2 = [] >>> reals = [] >>> xdata = [] >>> for count, (edge, y) in enumerate(zip(edges, ys)): >>> refresh.add(y, user_id='user:oracle') >>> ma1.append(refresh._ewma) >>> ma2.append(refresh.pos_frac) >>> n_real = y_remainsum[count] / (len(edges) - count) >>> reals.append(n_real) >>> xdata.append(count + 1) >>> # xdoctest: +REQUIRES(--show) >>> from graphid import util >>> util.qtensure() >>> util.multi_plot(xdata, [ma1, ma2, reals], marker='', >>> label_list=['exp', 'win', 'real'], xlabel='review num', >>> ylabel='mu')
- property pos_frac¶
- pred_num_positives(n_remain_edges)[source]¶
Uses poisson process to estimate remaining positive reviews.
Multipling mu * n_remain_edges gives a probabilistic upper bound on the number of errors remaning. This only provides a real estimate if reviewing in a random order
Example
>>> # ENABLE_DOCTEST >>> from graphid.core.refresh import * # NOQA >>> from graphid import demo >>> infr = demo.demodata_infr(num_pccs=50, size=4, size_std=2) >>> edges = list(infr.ranker.predict_candidate_edges(infr.aids, K=100)) >>> #edges = util.shuffle(sorted(edges), rng=321) >>> scores = np.array(infr.verifier.predict_edges(edges)) >>> sortx = scores.argsort()[::-1] >>> edges = list(ub.take(edges, sortx)) >>> scores = scores[sortx] >>> ys = infr.match_state_df(edges)[POSTV].values >>> y_remainsum = ys[::-1].cumsum()[::-1] >>> refresh = RefreshCriteria(window=250) >>> n_pred_list = [] >>> n_real_list = [] >>> xdata = [] >>> for count, (edge, y) in enumerate(zip(edges, ys)): >>> refresh.add(y, user_id='user:oracle') >>> n_remain_edges = len(edges) - count >>> n_pred = refresh.pred_num_positives(n_remain_edges) >>> n_real = y_remainsum[count] >>> if count == 2000: >>> break >>> n_real_list.append(n_real) >>> n_pred_list.append(n_pred) >>> xdata.append(count + 1) >>> # xdoctest: +REQUIRES(--show) >>> import kwplot >>> kwplot.autompl() >>> import plottool_ibeis as pt >>> #pt.qtensure() >>> n_pred_list = n_pred_list[10:] >>> n_real_list = n_real_list[10:] >>> xdata = xdata[10:] >>> pt.multi_plot(xdata, [n_pred_list, n_real_list], marker='', >>> label_list=['pred', 'real'], xlabel='review num', >>> ylabel='pred remaining merges') >>> stop_point = xdata[np.where(y_remainsum[10:] == 0)[0][0]] >>> pt.gca().plot([stop_point, stop_point], [0, int(max(n_pred_list))], 'g-')
- class graphid.core.SimulationHelpers[source]¶
Bases:
object
- class graphid.core.VIEW[source]¶
Bases:
_Commoncategorical viewpoint using the faces of a Rhombicuboctahedron
References
https://en.wikipedia.org/wiki/Rhombicuboctahedron
- B = 7¶
- BL = 6¶
- BR = 8¶
- class CODE¶
Bases:
object- B = 'back'¶
- BL = 'backleft'¶
- BR = 'backright'¶
- D = 'down'¶
- DB = 'downback'¶
- DBL = 'downbackleft'¶
- DBR = 'downbackright'¶
- DF = 'downfront'¶
- DFL = 'downfrontleft'¶
- DFR = 'downfrontright'¶
- DL = 'downleft'¶
- DR = 'downright'¶
- F = 'front'¶
- FL = 'frontleft'¶
- FR = 'frontright'¶
- L = 'left'¶
- R = 'right'¶
- U = 'up'¶
- UB = 'upback'¶
- UBL = 'upbackleft'¶
- UBR = 'upbackright'¶
- UF = 'upfront'¶
- UFL = 'upfrontleft'¶
- UFR = 'upfrontright'¶
- UL = 'upleft'¶
- UNKNOWN = 'unknown'¶
- UR = 'upright'¶
- CODE_TO_INT = {'back': 7, 'backleft': 6, 'backright': 8, 'down': 18, 'downback': 20, 'downbackleft': 25, 'downbackright': 26, 'downfront': 19, 'downfrontleft': 23, 'downfrontright': 24, 'downleft': 21, 'downright': 22, 'front': 3, 'frontleft': 4, 'frontright': 2, 'left': 5, 'right': 1, 'unknown': None, 'up': 9, 'upback': 11, 'upbackleft': 16, 'upbackright': 17, 'upfront': 10, 'upfrontleft': 14, 'upfrontright': 15, 'upleft': 12, 'upright': 13}¶
- CODE_TO_NICE = {'back': 'Back', 'backleft': 'Back-Left', 'backright': 'Back-Right', 'down': 'Down', 'downback': 'Down-Back', 'downbackleft': 'Down-Back-Left', 'downbackright': 'Down-Back-Right', 'downfront': 'Down-Front', 'downfrontleft': 'Down-Front-Left', 'downfrontright': 'Down-Front-Right', 'downleft': 'Down-Left', 'downright': 'Down-Right', 'front': 'Front', 'frontleft': 'Front-Left', 'frontright': 'Front-Right', 'left': 'Left', 'right': 'Right', 'unknown': 'Unknown', 'up': 'Up', 'upback': 'Up-Back', 'upbackleft': 'Up-Back-Left', 'upbackright': 'Up-Back-Right', 'upfront': 'Up-Front', 'upfrontleft': 'Up-Front-Left', 'upfrontright': 'Up-Front-Right', 'upleft': 'Up-Left', 'upright': 'Up-Right'}¶
- D = 18¶
- DB = 20¶
- DBL = 25¶
- DBR = 26¶
- DF = 19¶
- DFL = 23¶
- DFR = 24¶
- DIST = {(1, 1): 0, (1, 10): 2, (1, 11): 2, (1, 12): 3, (1, 13): 1, (1, 14): 3, (1, 15): 1, (1, 16): 3, (1, 17): 1, (1, 18): 2, (1, 19): 2, (1, 2): 1, (1, 20): 2, (1, 21): 3, (1, 22): 1, (1, 23): 3, (1, 24): 1, (1, 25): 3, (1, 26): 1, (1, 3): 2, (1, 4): 3, (1, 5): 4, (1, 6): 3, (1, 7): 2, (1, 8): 1, (1, 9): 2, (1, None): None, (10, 1): 2, (10, 10): 0, (10, 11): 2, (10, 12): 2, (10, 13): 2, (10, 14): 1, (10, 15): 1, (10, 16): 2, (10, 17): 2, (10, 18): 3, (10, 19): 2, (10, 2): 2, (10, 20): 4, (10, 21): 3, (10, 22): 3, (10, 23): 2, (10, 24): 2, (10, 25): 3, (10, 26): 3, (10, 3): 1, (10, 4): 2, (10, 5): 2, (10, 6): 3, (10, 7): 3, (10, 8): 3, (10, 9): 1, (10, None): None, (11, 1): 2, (11, 10): 2, (11, 11): 0, (11, 12): 2, (11, 13): 2, (11, 14): 2, (11, 15): 2, (11, 16): 1, (11, 17): 1, (11, 18): 3, (11, 19): 4, (11, 2): 3, (11, 20): 2, (11, 21): 3, (11, 22): 3, (11, 23): 3, (11, 24): 3, (11, 25): 2, (11, 26): 2, (11, 3): 3, (11, 4): 3, (11, 5): 2, (11, 6): 2, (11, 7): 1, (11, 8): 2, (11, 9): 1, (11, None): None, (12, 1): 3, (12, 10): 2, (12, 11): 2, (12, 12): 0, (12, 13): 2, (12, 14): 1, (12, 15): 2, (12, 16): 1, (12, 17): 2, (12, 18): 3, (12, 19): 3, (12, 2): 3, (12, 20): 3, (12, 21): 2, (12, 22): 4, (12, 23): 2, (12, 24): 3, (12, 25): 2, (12, 26): 3, (12, 3): 2, (12, 4): 2, (12, 5): 1, (12, 6): 2, (12, 7): 2, (12, 8): 3, (12, 9): 1, (12, None): None, (13, 1): 1, (13, 10): 2, (13, 11): 2, (13, 12): 2, (13, 13): 0, (13, 14): 2, (13, 15): 1, (13, 16): 2, (13, 17): 1, (13, 18): 3, (13, 19): 3, (13, 2): 2, (13, 20): 3, (13, 21): 4, (13, 22): 2, (13, 23): 3, (13, 24): 2, (13, 25): 3, (13, 26): 2, (13, 3): 2, (13, 4): 3, (13, 5): 3, (13, 6): 3, (13, 7): 2, (13, 8): 2, (13, 9): 1, (13, None): None, (14, 1): 3, (14, 10): 1, (14, 11): 2, (14, 12): 1, (14, 13): 2, (14, 14): 0, (14, 15): 2, (14, 16): 2, (14, 17): 2, (14, 18): 3, (14, 19): 2, (14, 2): 2, (14, 20): 3, (14, 21): 2, (14, 22): 3, (14, 23): 2, (14, 24): 2, (14, 25): 2, (14, 26): 4, (14, 3): 1, (14, 4): 1, (14, 5): 1, (14, 6): 2, (14, 7): 3, (14, 8): 3, (14, 9): 1, (14, None): None, (15, 1): 1, (15, 10): 1, (15, 11): 2, (15, 12): 2, (15, 13): 1, (15, 14): 2, (15, 15): 0, (15, 16): 2, (15, 17): 2, (15, 18): 3, (15, 19): 2, (15, 2): 1, (15, 20): 3, (15, 21): 3, (15, 22): 2, (15, 23): 2, (15, 24): 2, (15, 25): 4, (15, 26): 2, (15, 3): 1, (15, 4): 2, (15, 5): 3, (15, 6): 3, (15, 7): 3, (15, 8): 2, (15, 9): 1, (15, None): None, (16, 1): 3, (16, 10): 2, (16, 11): 1, (16, 12): 1, (16, 13): 2, (16, 14): 2, (16, 15): 2, (16, 16): 0, (16, 17): 2, (16, 18): 3, (16, 19): 3, (16, 2): 3, (16, 20): 2, (16, 21): 2, (16, 22): 3, (16, 23): 2, (16, 24): 4, (16, 25): 2, (16, 26): 2, (16, 3): 3, (16, 4): 2, (16, 5): 1, (16, 6): 1, (16, 7): 1, (16, 8): 2, (16, 9): 1, (16, None): None, (17, 1): 1, (17, 10): 2, (17, 11): 1, (17, 12): 2, (17, 13): 1, (17, 14): 2, (17, 15): 2, (17, 16): 2, (17, 17): 0, (17, 18): 3, (17, 19): 3, (17, 2): 2, (17, 20): 2, (17, 21): 3, (17, 22): 2, (17, 23): 4, (17, 24): 2, (17, 25): 2, (17, 26): 2, (17, 3): 3, (17, 4): 3, (17, 5): 3, (17, 6): 2, (17, 7): 1, (17, 8): 1, (17, 9): 1, (17, None): None, (18, 1): 2, (18, 10): 3, (18, 11): 3, (18, 12): 3, (18, 13): 3, (18, 14): 3, (18, 15): 3, (18, 16): 3, (18, 17): 3, (18, 18): 0, (18, 19): 1, (18, 2): 2, (18, 20): 1, (18, 21): 1, (18, 22): 1, (18, 23): 1, (18, 24): 1, (18, 25): 1, (18, 26): 1, (18, 3): 2, (18, 4): 2, (18, 5): 2, (18, 6): 2, (18, 7): 2, (18, 8): 2, (18, 9): 4, (18, None): None, (19, 1): 2, (19, 10): 2, (19, 11): 4, (19, 12): 3, (19, 13): 3, (19, 14): 2, (19, 15): 2, (19, 16): 3, (19, 17): 3, (19, 18): 1, (19, 19): 0, (19, 2): 2, (19, 20): 2, (19, 21): 2, (19, 22): 2, (19, 23): 1, (19, 24): 1, (19, 25): 2, (19, 26): 2, (19, 3): 1, (19, 4): 2, (19, 5): 2, (19, 6): 3, (19, 7): 3, (19, 8): 3, (19, 9): 3, (19, None): None, (2, 1): 1, (2, 10): 2, (2, 11): 3, (2, 12): 3, (2, 13): 2, (2, 14): 2, (2, 15): 1, (2, 16): 3, (2, 17): 2, (2, 18): 2, (2, 19): 2, (2, 2): 0, (2, 20): 3, (2, 21): 3, (2, 22): 2, (2, 23): 2, (2, 24): 1, (2, 25): 3, (2, 26): 2, (2, 3): 1, (2, 4): 2, (2, 5): 3, (2, 6): 4, (2, 7): 3, (2, 8): 2, (2, 9): 2, (2, None): None, (20, 1): 2, (20, 10): 4, (20, 11): 2, (20, 12): 3, (20, 13): 3, (20, 14): 3, (20, 15): 3, (20, 16): 2, (20, 17): 2, (20, 18): 1, (20, 19): 2, (20, 2): 3, (20, 20): 0, (20, 21): 2, (20, 22): 2, (20, 23): 2, (20, 24): 2, (20, 25): 1, (20, 26): 1, (20, 3): 3, (20, 4): 3, (20, 5): 2, (20, 6): 2, (20, 7): 1, (20, 8): 2, (20, 9): 3, (20, None): None, (21, 1): 3, (21, 10): 3, (21, 11): 3, (21, 12): 2, (21, 13): 4, (21, 14): 2, (21, 15): 3, (21, 16): 2, (21, 17): 3, (21, 18): 1, (21, 19): 2, (21, 2): 3, (21, 20): 2, (21, 21): 0, (21, 22): 2, (21, 23): 1, (21, 24): 2, (21, 25): 1, (21, 26): 2, (21, 3): 2, (21, 4): 2, (21, 5): 1, (21, 6): 2, (21, 7): 2, (21, 8): 3, (21, 9): 3, (21, None): None, (22, 1): 1, (22, 10): 3, (22, 11): 3, (22, 12): 4, (22, 13): 2, (22, 14): 3, (22, 15): 2, (22, 16): 3, (22, 17): 2, (22, 18): 1, (22, 19): 2, (22, 2): 2, (22, 20): 2, (22, 21): 2, (22, 22): 0, (22, 23): 2, (22, 24): 1, (22, 25): 2, (22, 26): 1, (22, 3): 2, (22, 4): 3, (22, 5): 3, (22, 6): 3, (22, 7): 2, (22, 8): 2, (22, 9): 3, (22, None): None, (23, 1): 3, (23, 10): 2, (23, 11): 3, (23, 12): 2, (23, 13): 3, (23, 14): 2, (23, 15): 2, (23, 16): 2, (23, 17): 4, (23, 18): 1, (23, 19): 1, (23, 2): 2, (23, 20): 2, (23, 21): 1, (23, 22): 2, (23, 23): 0, (23, 24): 2, (23, 25): 2, (23, 26): 2, (23, 3): 1, (23, 4): 1, (23, 5): 1, (23, 6): 2, (23, 7): 3, (23, 8): 3, (23, 9): 3, (23, None): None, (24, 1): 1, (24, 10): 2, (24, 11): 3, (24, 12): 3, (24, 13): 2, (24, 14): 2, (24, 15): 2, (24, 16): 4, (24, 17): 2, (24, 18): 1, (24, 19): 1, (24, 2): 1, (24, 20): 2, (24, 21): 2, (24, 22): 1, (24, 23): 2, (24, 24): 0, (24, 25): 2, (24, 26): 2, (24, 3): 1, (24, 4): 2, (24, 5): 3, (24, 6): 3, (24, 7): 3, (24, 8): 2, (24, 9): 3, (24, None): None, (25, 1): 3, (25, 10): 3, (25, 11): 2, (25, 12): 2, (25, 13): 3, (25, 14): 2, (25, 15): 4, (25, 16): 2, (25, 17): 2, (25, 18): 1, (25, 19): 2, (25, 2): 3, (25, 20): 1, (25, 21): 1, (25, 22): 2, (25, 23): 2, (25, 24): 2, (25, 25): 0, (25, 26): 2, (25, 3): 3, (25, 4): 2, (25, 5): 1, (25, 6): 1, (25, 7): 1, (25, 8): 2, (25, 9): 3, (25, None): None, (26, 1): 1, (26, 10): 3, (26, 11): 2, (26, 12): 3, (26, 13): 2, (26, 14): 4, (26, 15): 2, (26, 16): 2, (26, 17): 2, (26, 18): 1, (26, 19): 2, (26, 2): 2, (26, 20): 1, (26, 21): 2, (26, 22): 1, (26, 23): 2, (26, 24): 2, (26, 25): 2, (26, 26): 0, (26, 3): 3, (26, 4): 3, (26, 5): 3, (26, 6): 2, (26, 7): 1, (26, 8): 1, (26, 9): 3, (26, None): None, (3, 1): 2, (3, 10): 1, (3, 11): 3, (3, 12): 2, (3, 13): 2, (3, 14): 1, (3, 15): 1, (3, 16): 3, (3, 17): 3, (3, 18): 2, (3, 19): 1, (3, 2): 1, (3, 20): 3, (3, 21): 2, (3, 22): 2, (3, 23): 1, (3, 24): 1, (3, 25): 3, (3, 26): 3, (3, 3): 0, (3, 4): 1, (3, 5): 2, (3, 6): 3, (3, 7): 4, (3, 8): 3, (3, 9): 2, (3, None): None, (4, 1): 3, (4, 10): 2, (4, 11): 3, (4, 12): 2, (4, 13): 3, (4, 14): 1, (4, 15): 2, (4, 16): 2, (4, 17): 3, (4, 18): 2, (4, 19): 2, (4, 2): 2, (4, 20): 3, (4, 21): 2, (4, 22): 3, (4, 23): 1, (4, 24): 2, (4, 25): 2, (4, 26): 3, (4, 3): 1, (4, 4): 0, (4, 5): 1, (4, 6): 2, (4, 7): 3, (4, 8): 4, (4, 9): 2, (4, None): None, (5, 1): 4, (5, 10): 2, (5, 11): 2, (5, 12): 1, (5, 13): 3, (5, 14): 1, (5, 15): 3, (5, 16): 1, (5, 17): 3, (5, 18): 2, (5, 19): 2, (5, 2): 3, (5, 20): 2, (5, 21): 1, (5, 22): 3, (5, 23): 1, (5, 24): 3, (5, 25): 1, (5, 26): 3, (5, 3): 2, (5, 4): 1, (5, 5): 0, (5, 6): 1, (5, 7): 2, (5, 8): 3, (5, 9): 2, (5, None): None, (6, 1): 3, (6, 10): 3, (6, 11): 2, (6, 12): 2, (6, 13): 3, (6, 14): 2, (6, 15): 3, (6, 16): 1, (6, 17): 2, (6, 18): 2, (6, 19): 3, (6, 2): 4, (6, 20): 2, (6, 21): 2, (6, 22): 3, (6, 23): 2, (6, 24): 3, (6, 25): 1, (6, 26): 2, (6, 3): 3, (6, 4): 2, (6, 5): 1, (6, 6): 0, (6, 7): 1, (6, 8): 2, (6, 9): 2, (6, None): None, (7, 1): 2, (7, 10): 3, (7, 11): 1, (7, 12): 2, (7, 13): 2, (7, 14): 3, (7, 15): 3, (7, 16): 1, (7, 17): 1, (7, 18): 2, (7, 19): 3, (7, 2): 3, (7, 20): 1, (7, 21): 2, (7, 22): 2, (7, 23): 3, (7, 24): 3, (7, 25): 1, (7, 26): 1, (7, 3): 4, (7, 4): 3, (7, 5): 2, (7, 6): 1, (7, 7): 0, (7, 8): 1, (7, 9): 2, (7, None): None, (8, 1): 1, (8, 10): 3, (8, 11): 2, (8, 12): 3, (8, 13): 2, (8, 14): 3, (8, 15): 2, (8, 16): 2, (8, 17): 1, (8, 18): 2, (8, 19): 3, (8, 2): 2, (8, 20): 2, (8, 21): 3, (8, 22): 2, (8, 23): 3, (8, 24): 2, (8, 25): 2, (8, 26): 1, (8, 3): 3, (8, 4): 4, (8, 5): 3, (8, 6): 2, (8, 7): 1, (8, 8): 0, (8, 9): 2, (8, None): None, (9, 1): 2, (9, 10): 1, (9, 11): 1, (9, 12): 1, (9, 13): 1, (9, 14): 1, (9, 15): 1, (9, 16): 1, (9, 17): 1, (9, 18): 4, (9, 19): 3, (9, 2): 2, (9, 20): 3, (9, 21): 3, (9, 22): 3, (9, 23): 3, (9, 24): 3, (9, 25): 3, (9, 26): 3, (9, 3): 2, (9, 4): 2, (9, 5): 2, (9, 6): 2, (9, 7): 2, (9, 8): 2, (9, 9): 0, (9, None): None, (None, 1): None, (None, 10): None, (None, 11): None, (None, 12): None, (None, 13): None, (None, 14): None, (None, 15): None, (None, 16): None, (None, 17): None, (None, 18): None, (None, 19): None, (None, 2): None, (None, 20): None, (None, 21): None, (None, 22): None, (None, 23): None, (None, 24): None, (None, 25): None, (None, 26): None, (None, 3): None, (None, 4): None, (None, 5): None, (None, 6): None, (None, 7): None, (None, 8): None, (None, 9): None, (None, None): None}¶
- DL = 21¶
- DR = 22¶
- F = 3¶
- FL = 4¶
- FR = 2¶
- INT_TO_CODE = {1: 'right', 10: 'upfront', 11: 'upback', 12: 'upleft', 13: 'upright', 14: 'upfrontleft', 15: 'upfrontright', 16: 'upbackleft', 17: 'upbackright', 18: 'down', 19: 'downfront', 2: 'frontright', 20: 'downback', 21: 'downleft', 22: 'downright', 23: 'downfrontleft', 24: 'downfrontright', 25: 'downbackleft', 26: 'downbackright', 3: 'front', 4: 'frontleft', 5: 'left', 6: 'backleft', 7: 'back', 8: 'backright', 9: 'up', None: 'unknown'}¶
- INT_TO_NICE = {1: 'Right', 10: 'Up-Front', 11: 'Up-Back', 12: 'Up-Left', 13: 'Up-Right', 14: 'Up-Front-Left', 15: 'Up-Front-Right', 16: 'Up-Back-Left', 17: 'Up-Back-Right', 18: 'Down', 19: 'Down-Front', 2: 'Front-Right', 20: 'Down-Back', 21: 'Down-Left', 22: 'Down-Right', 23: 'Down-Front-Left', 24: 'Down-Front-Right', 25: 'Down-Back-Left', 26: 'Down-Back-Right', 3: 'Front', 4: 'Front-Left', 5: 'Left', 6: 'Back-Left', 7: 'Back', 8: 'Back-Right', 9: 'Up', None: 'Unknown'}¶
- L = 5¶
- class NICE¶
Bases:
object- B = 'Back'¶
- BL = 'Back-Left'¶
- BR = 'Back-Right'¶
- D = 'Down'¶
- DB = 'Down-Back'¶
- DBL = 'Down-Back-Left'¶
- DBR = 'Down-Back-Right'¶
- DF = 'Down-Front'¶
- DFL = 'Down-Front-Left'¶
- DFR = 'Down-Front-Right'¶
- DL = 'Down-Left'¶
- DR = 'Down-Right'¶
- F = 'Front'¶
- FL = 'Front-Left'¶
- FR = 'Front-Right'¶
- L = 'Left'¶
- R = 'Right'¶
- U = 'Up'¶
- UB = 'Up-Back'¶
- UBL = 'Up-Back-Left'¶
- UBR = 'Up-Back-Right'¶
- UF = 'Up-Front'¶
- UFL = 'Up-Front-Left'¶
- UFR = 'Up-Front-Right'¶
- UL = 'Up-Left'¶
- UNKNOWN = 'Unknown'¶
- UR = 'Up-Right'¶
- NICE_TO_CODE = {'Back': 'back', 'Back-Left': 'backleft', 'Back-Right': 'backright', 'Down': 'down', 'Down-Back': 'downback', 'Down-Back-Left': 'downbackleft', 'Down-Back-Right': 'downbackright', 'Down-Front': 'downfront', 'Down-Front-Left': 'downfrontleft', 'Down-Front-Right': 'downfrontright', 'Down-Left': 'downleft', 'Down-Right': 'downright', 'Front': 'front', 'Front-Left': 'frontleft', 'Front-Right': 'frontright', 'Left': 'left', 'Right': 'right', 'Unknown': 'unknown', 'Up': 'up', 'Up-Back': 'upback', 'Up-Back-Left': 'upbackleft', 'Up-Back-Right': 'upbackright', 'Up-Front': 'upfront', 'Up-Front-Left': 'upfrontleft', 'Up-Front-Right': 'upfrontright', 'Up-Left': 'upleft', 'Up-Right': 'upright'}¶
- NICE_TO_INT = {'Back': 7, 'Back-Left': 6, 'Back-Right': 8, 'Down': 18, 'Down-Back': 20, 'Down-Back-Left': 25, 'Down-Back-Right': 26, 'Down-Front': 19, 'Down-Front-Left': 23, 'Down-Front-Right': 24, 'Down-Left': 21, 'Down-Right': 22, 'Front': 3, 'Front-Left': 4, 'Front-Right': 2, 'Left': 5, 'Right': 1, 'Unknown': None, 'Up': 9, 'Up-Back': 11, 'Up-Back-Left': 16, 'Up-Back-Right': 17, 'Up-Front': 10, 'Up-Front-Left': 14, 'Up-Front-Right': 15, 'Up-Left': 12, 'Up-Right': 13}¶
- R = 1¶
- U = 9¶
- UB = 11¶
- UBL = 16¶
- UBR = 17¶
- UF = 10¶
- UFL = 14¶
- UFR = 15¶
- UL = 12¶
- UNKNOWN = None¶
- UR = 13¶
- d = None¶
- f1 = None¶
- f2 = None¶
- graphid.core.color_nodes(graph, labelattr='label', brightness=0.878, outof=None, sat_adjust=None)[source]¶
Colors edges and nodes by nid