biwt.gui¶
The Qt layer. create_biwt_widget is the host entry point; everything else here is internal.
Note
Importing this module requires PyQt5 (pip install "biwt[gui]").
The factory¶
biwt.gui.walkthrough.create_biwt_widget
¶
create_biwt_widget(
biwt_input: BiwtInputSource,
on_complete: Optional[
Callable[[BiwtResult], None]
] = None,
*,
cell_template_paths=(),
host_name: str = "Host",
name_matches: Optional[
Callable[[str, str], bool]
] = None,
name_match_cutoff: float = 0.85
) -> BioinformaticsWalkthrough
Create and return a BIWT walkthrough widget, suitable for embedding or use as a popup.
The widget does not close itself on completion — the host is responsible for closing or resetting it if desired.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
biwt_input
|
BiwtInputSource
|
A |
required |
on_complete
|
Optional[Callable[[BiwtResult], None]]
|
Callback called with the |
None
|
cell_template_paths
|
Paths to BIWT ships no templates and never parses the contents; the files are read
at the cell-templates step and nowhere else, so an unreadable one costs a
warning there rather than anything at startup. |
()
|
|
host_name
|
str
|
Your application's name, shown in BIWT's UI — the domain editor's
"Use |
'Host'
|
name_matches
|
Optional[Callable[[str, str], bool]]
|
Predicate deciding whether two strings name the same cell type, used for
rename suggestions and template pre-selection. Supplying it replaces
BIWT's default and Must be deterministic and free of side effects: it is called once per (cell type, candidate) pair whenever matches are resolved, from inside widget construction and Qt signal handlers, and the total number of calls is not part of the contract. |
None
|
name_match_cutoff
|
float
|
Similarity threshold for that default only; ignored when |
0.85
|
Example
::
from biwt import BiwtInput, DomainSpec
from biwt.gui import create_biwt_widget
widget = create_biwt_widget(
BiwtInput(
preferred_domain=DomainSpec(xmin=-500, xmax=500,
ymin=-500, ymax=500),
host_cell_type_names=["default", "tumor", "immune"],
),
on_complete=lambda result: print(result.coordinates.head()),
host_name="My App",
cell_template_paths=["/path/to/my_templates.toml"],
)
widget.show()
An embedded, long-lived host passes a callable instead, and BIWT reads it at the start of every run::
def host_input():
return BiwtInput(preferred_domain=my_app.current_domain(),
host_cell_type_names=my_app.cell_type_names())
widget = create_biwt_widget(host_input, on_complete=save,
host_name="My App")
BIWT never writes to disk. To persist the result, do it in
on_complete — e.g. result.to_csv("cells.csv").
Source code in src/biwt/gui/walkthrough.py
1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 | |
Session state¶
WalkthroughSession is the pure-Python state machine behind the widget — no Qt dependency.
All the answers you give during the walkthrough accumulate here, and each step window reads
and writes it. Internal.
biwt.gui.walkthrough.WalkthroughSession
dataclass
¶
WalkthroughSession(
biwt_input: BiwtInput,
data: Optional[BiwtData] = None,
user_domain: Optional[DomainSpec] = None,
data_domain: Optional[DomainSpec] = None,
domain_accepted: bool = False,
scale_factor: Optional[float] = None,
apply_scale: bool = True,
spatial_data: Optional[ndarray] = None,
spatial_data_final: Optional[ndarray] = None,
spatial_query_answer: Optional[bool] = None,
spot_deconv_asked: bool = False,
perform_spot_deconvolution: bool = False,
cell_types_max: Optional[list] = None,
cell_prob_feature_dicts: Optional[list] = None,
cell_prob_feature_dicts_final: Optional[list] = None,
current_column: Optional[str] = None,
cell_types_original: Optional[list] = None,
cell_types_list_original: Optional[list] = None,
cell_type_dict_on_edit: Optional[dict] = None,
intermediate_types: Optional[list] = None,
intermediate_type_pre_image: Optional[dict] = None,
cell_types_list_final: Optional[list] = None,
cell_type_dict_on_rename: Optional[dict] = None,
cell_types_final: Optional[list] = None,
cell_counts: Optional[dict] = None,
cell_counts_confirmed: bool = False,
cell_volume: Optional[dict] = None,
coords_by_type: dict = dict(),
plotted_cell_types_per_spot: list = list(),
positions_set: bool = False,
template_library_paths: Optional[list] = None,
cell_templates: dict = dict(),
templates_assigned: bool = False,
)
Accumulates all data decisions made during the BIWT workflow.
This object is the single source of truth shared between the walkthrough controller and all step windows. No Qt objects are stored here.
Fields are populated progressively as the user advances through steps.
None means "not yet determined".
biwt_input is the host's state for this run. The widget's own setup —
its host name, its template library, its name matcher — is not here: it does
not change between runs, and copying it into every session would invite the
two to disagree.
spatial_data_final
class-attribute
instance-attribute
¶
spatial_data_final: Optional[ndarray] = None
spatial_query_answer
class-attribute
instance-attribute
¶
spatial_query_answer: Optional[bool] = None
perform_spot_deconvolution
class-attribute
instance-attribute
¶
perform_spot_deconvolution: bool = False
cell_prob_feature_dicts
class-attribute
instance-attribute
¶
cell_prob_feature_dicts: Optional[list] = None
cell_prob_feature_dicts_final
class-attribute
instance-attribute
¶
cell_prob_feature_dicts_final: Optional[list] = None
cell_types_list_original
class-attribute
instance-attribute
¶
cell_types_list_original: Optional[list] = None
cell_type_dict_on_edit
class-attribute
instance-attribute
¶
cell_type_dict_on_edit: Optional[dict] = None
intermediate_type_pre_image
class-attribute
instance-attribute
¶
intermediate_type_pre_image: Optional[dict] = None
cell_types_list_final
class-attribute
instance-attribute
¶
cell_types_list_final: Optional[list] = None
cell_type_dict_on_rename
class-attribute
instance-attribute
¶
cell_type_dict_on_rename: Optional[dict] = None
coords_by_type
class-attribute
instance-attribute
¶
coords_by_type: dict = field(default_factory=dict)
plotted_cell_types_per_spot
class-attribute
instance-attribute
¶
plotted_cell_types_per_spot: list = field(
default_factory=list
)
template_library_paths
class-attribute
instance-attribute
¶
template_library_paths: Optional[list] = None
cell_templates
class-attribute
instance-attribute
¶
cell_templates: dict = field(default_factory=dict)
effective_domain
property
¶
effective_domain: DomainSpec
Domain to use for coordinate placement.
The host's domain until the user accepts an edited one in BIWT's own
editor. There is deliberately no third value between them: a second
latched copy of the host's domain is what let one dialog compute its
mismatch warning against one box and resolve "Use
data_has_z
property
¶
data_has_z: bool
True when the imported file supplied a third coordinate axis.
Decides whether the scale factor applies to z: a z the file measured converts like x and y, a synthesized slab has nothing to convert.
use_spatial_data
property
¶
use_spatial_data: bool
Whether cells are placed at their measured coordinates.
Derived, never stored, so it is always a real bool:
- spot deconvolution is on → True (deconvolution is spatial)
- the data has no coordinates → False (nothing to ask about)
- otherwise → the user's SpatialQuery answer, False until they answer
The last case is safe because the SpatialQuery step runs before any consumer of this property is reachable.
effective_scale
¶
effective_scale() -> float
Uniform factor applied to place cells (1.0 = no conversion).
The stored scale_factor (host-units per data unit) is applied only
when apply_scale is on and a positive factor exists; otherwise cells
are placed at their raw extent, centered.
Source code in src/biwt/gui/walkthrough.py
889 890 891 892 893 894 895 896 897 898 | |
collect_cell_type_data
¶
collect_cell_type_data() -> None
Extract unique cell types from the selected obs column.
Source code in src/biwt/gui/walkthrough.py
923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 | |
setup_spot_deconvolution_data
¶
setup_spot_deconvolution_data() -> None
Build per-spot probability dicts from probability columns.
Source code in src/biwt/gui/walkthrough.py
940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 | |
setup_spatial_data
¶
setup_spatial_data() -> None
Extract raw spatial coordinates into self.spatial_data.
Source code in src/biwt/gui/walkthrough.py
960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 | |
reseed_derived_state
¶
reseed_derived_state() -> None
Re-derive the bulk data that follows from the user's answers.
_STEP_FIELDS lists the fields whose values a step's user chose;
anything derived from those choices belongs here instead, so that a
downstream invalidation can wipe the choices without destroying what
follows from the ones still standing. Called right after that
invalidation and again before every step-predicate evaluation, so it
must be idempotent, and it must never overwrite a user decision.
Not called from go_back_to_prev_window: that path can reuse cached
windows, and repairing the session behind a live window would leave the
two disagreeing.
Spot deconvolution dominates the body because it is the only answer in
the walkthrough from which bulk data follows — three arrays over every
spot. Every other step's answer is its own state. Implications that are
merely logical, such as "deconvolution means spatial coordinates are in
use", need no derivation at all: see the use_spatial_data property.
Source code in src/biwt/gui/walkthrough.py
981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 | |
resolved_cell_type_map
¶
resolved_cell_type_map() -> dict
Every original data label → its final name, or None if deleted.
Reads the two dicts the walkthrough actually fills: an original absent
from cell_type_dict_on_rename was deleted at the edit step, since only
surviving types have a pre-image there. Merged originals all resolve to
the one name their group was given.
Source code in src/biwt/gui/walkthrough.py
1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 | |
compute_intermediate_types
¶
compute_intermediate_types() -> None
Derive intermediate_types from cell_type_dict_on_edit.
Source code in src/biwt/gui/walkthrough.py
1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 | |
apply_rename
¶
apply_rename() -> None
Build cell_types_final, spatial_data_final, counts, and volumes.
Source code in src/biwt/gui/walkthrough.py
1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 | |
_count_final_cell_types
¶
_count_final_cell_types() -> None
Source code in src/biwt/gui/walkthrough.py
1097 1098 1099 1100 1101 | |
_compute_cell_volumes
¶
_compute_cell_volumes() -> None
Default volume 2494 µm³ (PhysiCell default). TODO: accept host cell volumes via BiwtInput.
Source code in src/biwt/gui/walkthrough.py
1103 1104 1105 1106 | |
Step ordering¶
biwt.gui.walkthrough._step_predicates
¶
_step_predicates(s: 'WalkthroughSession') -> list
Return [(predicate, label), ...] in walkthrough order.
Each predicate is a zero-arg callable returning bool.
Each label is a stable string identifier for the step.
This function is the single source of truth for step-selection logic.
BioinformaticsWalkthrough._build_next_window maps each label to its
factory; tests import this function directly so they never duplicate the
predicate logic.
Predicates read derived state, so s.reseed_derived_state() must run
first — _build_next_window does that for every real evaluation.
Source code in src/biwt/gui/walkthrough.py
1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 | |
The widget¶
biwt.gui.walkthrough.BioinformaticsWalkthrough
¶
BioinformaticsWalkthrough(
biwt_input: BiwtInputSource,
on_complete: Optional[
Callable[[BiwtResult], None]
] = None,
*,
cell_template_paths=(),
host_name: str = "Host",
name_matches: Optional[
Callable[[str, str], bool]
] = None,
name_match_cutoff: float = 0.85
)
Bases: QWidget
Top-level BIWT popup controller.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
biwt_input
|
BiwtInputSource
|
The host's state, re-read at the start of every run (domain, cell-type names, etc.) |
required |
on_complete
|
Optional[Callable[[BiwtResult], None]]
|
Callback receiving a |
None
|
cell_template_paths
|
How this widget is set up, as opposed to what the host currently is —
see :func: |
()
|
|
host_name
|
How this widget is set up, as opposed to what the host currently is —
see :func: |
()
|
|
name_matches
|
How this widget is set up, as opposed to what the host currently is —
see :func: |
()
|
|
name_match_cutoff
|
How this widget is set up, as opposed to what the host currently is —
see :func: |
()
|
Source code in src/biwt/gui/walkthrough.py
1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 | |
advance
¶
advance() -> None
Move forward one step.
If stale_futures is True (user changed something on the current
step), reset all downstream session fields and build a fresh window.
If stale_futures is False and cached future windows exist, reuse
the next one so that back→forward without changes preserves state.
Source code in src/biwt/gui/walkthrough.py
1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 | |
go_back_to_prev_window
¶
go_back_to_prev_window() -> None
Return to the previous step.
If the current window has been marked stale (user changed something),
discard all future windows — they must be rebuilt when the user
advances again. Otherwise, save the current window to the front of
window_future so it can be reused on the next forward step.
Source code in src/biwt/gui/walkthrough.py
1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 | |