You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit bc649d6
Browse filesBrowse the repository at this point in the historyBrowse files
Refactor LineageTree to SciPy CSR sparse array representation and array-level simulation (#1000) (#1002)
* Migrate to uv, ty, and ruff; simplify and fix typing issues
* Clean up code duplication across datasets, state censoring, figures, and tree traversal
* Optimize test performance: reduce oversized fixtures and seed RNG deterministically
* Implement analytical gradient for gamma_estimator
* Implement exact 1D profile likelihood solver and PAVA isotonic regression for gamma estimation
* Replace linked-list lineage tree with SciPy CSR array representation (#1000)
* Refactor tree simulation and censoring to array-based data model
* Remove legacy CellVar censoring methods and update documentation
---------
Co-authored-by: Aaron Meyer <git@ameyer.me>
Copy file name to clipboardExpand all lines: docs/tHMM-getting-started.rst
+9-98Lines changed: 9 additions & 98 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -13,117 +13,28 @@ This way, we can quantify phenotypic heterogeneity within a population of cells
13
13
We first introduce how to synthesize these populations by working up from the basic unit; cells. We then introduce how to synthesize lineages, which are just hierarchical lineage tree groupings of cells based on their family history. Our model ultimately analyzes populations which are groups of one or more lineages that share the same states.
14
14
15
15
16
-
1. Synthesizing Cells
17
-
---------------------
16
+
1. Lineage Tree Data Model
17
+
---------------------------
18
18
19
-
Users will rarely ever have to create individual cells, but their
20
-
functionality is presented so the user is familiar with them. Users will
21
-
however, create lineages, and as such, they will have to become
22
-
comfortable with creating transition matrices using ``numpy``.
23
-
Transition matrices define the probabilities of how cells will divide.
24
-
Cells can only be made (new cells as a result of an existing cell
25
-
dividing) when given a transition matrix. We provide an example below.
19
+
Lineage trees in tHMM are represented at the lineage level using a **SciPy CSR sparse array** (representing parent-to-daughter connectivity) alongside **NumPy arrays** for observations, hidden states, and cell lifetimes.
26
20
27
-
The transition matrix defines the rate at which cells are likely to
28
-
change from one state to another. We use the defintion of a stochastic
29
-
transition rate matrix from Wikipedia, that is, the column index defines
30
-
the state in which we start, and the row defines the state at which we
31
-
end up. That is, if an element at the index of a transition matrix
32
-
:math:`T` at row :math:`i` and at column :math:`j`, is defined as
33
-
:math:`T_{i,j}`, then
21
+
Transition matrices define the probabilities of how cells divide and switch states across generations.
34
22
35
-
.. math:: T_{i,j} = \mathbb{P}(z = j | z = i).
23
+
The transition matrix defines the rate at which cells change from one state to another. Specifically, if an element of a transition matrix :math:`T` at row :math:`i` and column :math:`j` is defined as :math:`T_{i,j}`, then
\ Indexing for this matrix and the states starts at :math:`0`. Usually
39
-
the number of states is represented as the capital letter :math:`K` and
40
-
indexed by the lower-case letter :math:`k`. For most of our examples, we
41
-
will deal with two states, i.e., :math:`K=2`.
27
+
Indexing for states starts at :math:`0`. Usually the number of states is represented as the capital letter :math:`K` and indexed by :math:`k`. For most examples, we deal with two states, i.e., :math:`K=2`.
42
28
43
29
.. code:: ipython3
44
30
45
31
import numpy as np
46
-
# The capital letter T will represent the state transition probability matrix.
47
-
# This transition matrix, in particular, is the two-dimensional
48
-
# identity matrix. Recall that the elements of the transition matrix
49
-
# represent the probability of transitioning from one state to another.
50
-
T = np.array([[1.0, 0.0],
51
-
[0.0, 1.0]], dtype="float")
52
-
# This identity matrix implies that there are no transitions between cells of
53
-
# state 0 to cells of state 1. It also implies that there are no transitions
54
-
# between cells of state 1 to cells of state 0.
55
-
# Another transition matrix could be the following:
56
-
#
57
-
# T = np.array([[0.75, 0.25],
58
-
# [0.15, 0.85]], dtype="float")
59
-
#
60
-
# Note that the rows of the transition matrix have to sum one, because of the
61
-
# Law of Total Probability and the Law of Conditional Probability. This will be
62
-
# expanded on in a later notebook.
63
-
64
-
Cells are defined by their state, their relationships to other cells,
65
-
and collections of observations. Knowing how to create cells, however,
66
-
is not required by the user. It is beneficial to understand how the
67
-
``CellVar`` class is designed to create objects that store a ``state``,
68
-
its relationships (``left``, ``right``, ``parent``) to other cells, and
69
-
its multivariate observations (``obs``). When cells are created via the
70
-
``member`` function, their familiar relationships are automatically
71
-
assigned. The two daughters are assigned to ``left`` and ``right`` and
72
-
for the daughters, the parent is assigned to ``parent``. Other familiar
73
-
relationships can be accessed through other member variables and
74
-
functions. Note that the first generation is empty (we can see this
75
-
because the ``parent_cell`` is instantiated with ``parent=None`` and
76
-
with ``gen=1`` which means that ``gen=0`` of the lineage contains
77
-
nothing except ``None``). As such, indexing for generations of lineages
78
-
starts at ``1``. We will discuss more about the multivariate
79
-
observations that cells store later; for now, the following exercises
80
-
will focus on the transition matrix and the familiar relationships of
81
-
cells.
82
32
83
-
.. code:: ipython3
84
-
85
-
import numpy as np
86
-
from lineage.CellVar import CellVar as c
87
-
88
-
parent_cell = c(state=0, parent=None)
33
+
# State transition probability matrix
89
34
T = np.array([[0.75, 0.25],
90
35
[0.15, 0.85]], dtype="float")
91
-
left_cell, right_cell = parent_cell.divide(T)
92
-
93
-
--------------
94
-
95
-
.. code:: ipython3
96
-
97
-
print(parent_cell)
98
-
# <lineage.CellVar.CellVar object at 0x000001A685C55E10>
99
-
print(left_cell, right_cell)
100
-
# <lineage.CellVar.CellVar object at 0x000001A6961B3EF0> <lineage.CellVar.CellVar object at 0x000001A69609C978>
101
-
print(f"\nThe value of the element at (0,0) of the transition rate matrix is {T[0,0]}")
102
-
# The value of the element at (0,0) of the transition rate matrix is 0.75
103
-
104
-
--------------
105
-
106
-
The ``gen`` argument for instantiating cells represents the generation
107
-
of the cell which start at 1.
108
-
109
-
110
-
--------------
111
-
112
-
113
-
``parent_cell``, ``left_cell``, and ``right_cell`` define a 3-cell
114
-
lineage, with 2 generations. The first generation has one cell which was
115
-
declared and can be accessed at ``parent_cell``. Calling the member
116
-
function ``divide`` on ``parent_cell`` created two new cells which can
117
-
be accessed at ``left_cell`` and ``right_cell``. The daughter cells of
118
-
any cell can also be accessed using “dot” notation, using the
119
-
member variables, ``left`` and ``right``. The division process
120
-
utilizes the transition matrix. Our code provides some very basic
121
-
printing methods to print out cells. The following code verifies that the ``left_cell`` is actually the left daughter of ``parent_cell``.
122
-
123
-
.. code:: ipython3
124
36
125
-
# Use the `is` keyword to compare Python objects.
126
-
assert left_cell is parent_cell.left
37
+
Note that the rows of the transition matrix must sum to 1 by the Law of Total Probability.
0 commit comments