stack
=====
Combine multiple pools into one by stacking their state spaces as a disjoint
union — each state in the resulting pool comes from exactly one of the input
pools, enumerated in order.
.. code-block:: python
import poolparty as pp
pp.init()
----
Parameters
----------
.. list-table::
:widths: 20 18 12 50
:header-rows: 1
* - Parameter
- Type
- Default
- Description
* - ``pools``
- ``list[Pool]``
- *(required)*
- List of pools to stack. States are concatenated in order.
* - ``prefix``
- ``str | None``
- ``None``
- Prefix for the operation node name in the pool graph.
* - ``iter_order``
- ``float | None``
- ``None``
- Enumeration order when combined with other pools.
* - ``cards``
- ``dict | list | None``
- ``None``
- Design card columns to include in library output. Available card
key: ``"active_parent"`` (index of which input pool produced each
state).
----
.. note::
Only the most commonly used parameters are shown above. For the full
parameter list, see :func:`~poolparty.stack` in the
:doc:`API Reference `.
Examples
--------
Stack Three Fixed-Sequence Pools
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Merge three single-sequence pools into one pool that contains all three
sequences.
.. code-block:: python
a = pp.from_seq("AAAA")
b = pp.from_seq("CCCC")
c = pp.from_seq("GGGG")
combined = pp.stack([a, b, c])
combined.print_library()
.. raw:: html
AAAA
CCCC
GGGG
Stack Pools of Different Sizes
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Stack a four-sequence pool and a two-sequence pool to produce a single pool
with six states total.
.. code-block:: python
pool_a = pp.from_seqs(["AAAA", "CCCC", "GGGG", "TTTT"], mode="sequential")
pool_b = pp.from_seqs(["ACGT", "TGCA"], mode="sequential")
combined = pp.stack([pool_a, pool_b])
combined.print_library()
.. raw:: html
AAAA
CCCC
GGGG
TTTT
ACGT
TGCA
Stack the Results of Two Scan Operations
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Combine deletion scans over two different sequences into one pooled library
covering both targets.
.. code-block:: python
wt_a = pp.from_seq("AAAACCCC")
wt_b = pp.from_seq("GGGGTTTT")
dels_a = wt_a.deletion_scan(deletion_length=2, mode="sequential")
dels_b = wt_b.deletion_scan(deletion_length=2, mode="sequential")
merged = pp.stack([dels_a, dels_b])
merged.print_library()
.. raw:: html
--AACCCC
A--ACCCC
AA--CCCC
AAA--CCC
AAAA--CC
... (14 total)
Track which input pool each sequence came from
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The ``active_parent`` card records the index of the input pool that
produced each sequence. This is useful when stacking mutants with
controls and you need to distinguish them in the output DataFrame.
.. code-block:: python
muts = pp.from_seqs(["CTCG", "GTCG", "TTCG"], mode="sequential")
ctrl = pp.from_seqs(["AAAA", "TTTT"], mode="sequential")
lib = pp.stack([muts, ctrl], cards={"active_parent": "source"})
df = lib.generate_library()
.. raw:: html
| name | seq | source |
| None | CTCG | 0 |
| None | GTCG | 0 |
| None | TTCG | 0 |
| None | AAAA | 1 |
| None | TTTT | 1 |
Operator shorthand (``+``)
~~~~~~~~~~~~~~~~~~~~~~~~~~
``pool_a + pool_b`` is equivalent to ``pp.stack([pool_a, pool_b])`` — it
creates a disjoint union of both pools' states so draws can come from either
pool. Chaining ``+`` appends additional pools.
.. code-block:: python
wt = pp.from_seq("ATCG")
muts = pp.mutagenize(wt, num_mutations=1, mode="sequential")
ctrl = pp.from_seqs(["AAAA", "TTTT"], mode="sequential")
lib = muts + ctrl # all single-point mutants + 2 controls
lib.print_library()
.. raw:: html
CTCG
GTCG
TTCG
AACG
ACCG
... (14 total)
.. code-block:: python
a = pp.from_seqs(["AAAA", "CCCC"], mode="sequential")
b = pp.from_seqs(["GGGG"], mode="sequential")
c = pp.from_seqs(["TTTT", "ACGT"], mode="sequential")
lib = a + b + c
lib.print_library()
.. raw:: html
AAAA
CCCC
GGGG
TTTT
ACGT
See :func:`~poolparty.stack`.