starplast.star_map
The star map: one gene in the middle, the genes linked to it around it, and who says so.
The 3D map answers "what is near what" in one embedding. This view answers a different question --
"what links THIS gene to others, and through which evidence or inference" -- by drawing the chosen
gene (the "star") at the centre and its linked genes on rings around it. Every edge is a link from
:mod:starplast.star_edges and carries its provenance:
- colour = its source: each measured layer, each strategy, and one colour for your own runs;
- line = solid for measured, dashed for inferred;
- width = its strength (the score's percentile within its run);
- hover = the gene's id and product, or the link's layer / strategy / run, setting and score.
Click a neighbour to re-centre on it (Back returns), double-click it to select it on the 3D map.
Depth is one or two hops. Each source keeps only its strongest links around each gene
(per source), so a dense layer cannot hide a sparse one. The list on the right is the legend,
the per-source toggle and the per-source link count at once.
The larger network. The mode box chooses how much is drawn: one gene (the star above), the
neighbourhood of that gene (breadth-first, strongest links first, up to E.MAX_HOPS hops and
E.NEIGHBOURHOOD_MAX genes), or the whole network (up to E.OVERVIEW_MAX genes and
E.LARGE_EDGE_MAX links, with the largest clusters coloured). Both larger views degrade by keeping
the strongest links and the best-linked genes, and print the sentence that says what they left out.
They are drawn by :class:_NetworkCanvas, which builds one path per source and strength bucket once
and paints it into a cached pixmap, so panning, zooming and hovering rebuild nothing.
What counts as a link is the user's to decide: which sources may contribute, a minimum strength,
a cap on how many links one gene may bring, and "at least N different sources must agree"
(:class:star_edges.Definition). The resulting network is counted live, and a definition can be
saved and reloaded by name (:class:star_edges.DefinitionStore, under paths.user_cache_dir()).
Nothing in this module moves the graph when the pointer does. A hover changes a colour, a
highlight and the text in a fixed-height box, and nothing else: the layout is cached per centre,
mode and definition, the view is framed by the rectangle that layout fixed, and hover text is
rebuilt on a timer. The history of why each of those is necessary is in
instructions/open/58_star_map_steady_larger_defined.md.
Runs made in the Strategies tab arrive through :meth:StarMapPanel.add_result and appear at once, in
the "your runs" colour; they are also kept on disk (star_edges.UserEdgeStore) and come back next
session. :func:install puts the panel in the main window as a dock beside Strategies.
A navigable network centred on one gene, drawing measured and inferred links by source.
Build the panel over one organism's table. Links are loaded on first use.
:param ctx: a strategies.Context over the same table; needed to turn a user run into
links (and its graph is reused for the measured layers).
:param graph: measured layers (layer__a/b/w arrays); default: ctx.graph, else the
space's own graph file.
:param store: where the user's runs are kept; None keeps them for this session only.
:param theme: a theme name, or a callable returning the current one.
:param definitions: where the user's named connection definitions are kept; None keeps
them for this session only.
pyqtSignal(*types, name: str = ..., revision: int = ..., arguments: Sequence = ...) -> PYQT_SIGNAL
types is normally a sequence of individual types. Each type is either a type object or a string that is the name of a C++ type. Alternatively each type could itself be a sequence of types each describing a different overloaded signal. name is the optional C++ name of the signal. If it is not specified then the name of the class attribute that is bound to the signal is used. revision is the optional revision of the signal that is exported to QML. If it is not specified then 0 is used. arguments is the optional sequence of the names of the signal's arguments.
pyqtSignal(*types, name: str = ..., revision: int = ..., arguments: Sequence = ...) -> PYQT_SIGNAL
types is normally a sequence of individual types. Each type is either a type object or a string that is the name of a C++ type. Alternatively each type could itself be a sequence of types each describing a different overloaded signal. name is the optional C++ name of the signal. If it is not specified then the name of the class attribute that is bound to the signal is used. revision is the optional revision of the signal that is exported to QML. If it is not specified then 0 is used. arguments is the optional sequence of the names of the signal's arguments.
pyqtSignal(*types, name: str = ..., revision: int = ..., arguments: Sequence = ...) -> PYQT_SIGNAL
types is normally a sequence of individual types. Each type is either a type object or a string that is the name of a C++ type. Alternatively each type could itself be a sequence of types each describing a different overloaded signal. name is the optional C++ name of the signal. If it is not specified then the name of the class attribute that is bound to the signal is used. revision is the optional revision of the signal that is exported to QML. If it is not specified then 0 is used. arguments is the optional sequence of the names of the signal's arguments.
Add the links of a strategy run made in the application; returns how many.
They are kept by the store (on disk when it has a root) and drawn at once under "your runs". A run that relates no genes to each other adds nothing and says so.
A gene id (or position) as a position in this table, or None.
Put a gene at the centre and redraw. False if the gene is not in this table.
Centre a gene selected elsewhere, if following is on (deferred while hidden).
Show exactly these groups (None: all of them, including ones added later).
The links this definition calls edges: (EdgeIndex, frame, counts).
Cached on the definition's signature, so moving the pointer, changing the view or re-centring never re-applies the rules.
Keep the rules now set under the name in the box; returns the name, or "".
gene -> (x, y): the centre at the origin, hop 1 on the inner ring grouped by source, hop 2 on the outer ring beside the gene that reached it.
Rebuild the view for the centre, the mode and the connection rules -- and only for those.
Nothing here runs on a hover. The positions it computes are cached under
:meth:_layout_key, so asking for the same picture twice gives the same coordinates, and
fit frames the rectangle they define rather than whatever the scene currently measures.
Frame the whole graph in the view, from the rectangle the LAYOUT fixed.
The rectangle comes from the frozen positions, not from scene.itemsBoundingRect(): that
one answers differently while an item is hovered, and framing the view by it made the graph
jump under the pointer.
Add the star map to the main window as a dock beside Strategies, and wire it up.
Strategy runs feed it (result_ready); "Select on 3D map" goes through the window's own search;
selecting a gene in the window centres it here when following is on (the window calls
:meth:StarMapPanel.follow from its pick handler).