Pools ===== Every PoolParty operation returns a **Pool**. A Pool represents a designed sequence library: it records which operation was applied and to what inputs, forming a directed acyclic graph (DAG) of operations. PoolParty walks this graph to generate sequences on demand when you call ``generate_library()``, ``print_library()``, ``to_df()``, or ``to_file()``. Every operation returns a **new** Pool — the original is never modified. This means you can branch a pipeline at any point and apply different operations to each branch without interference. Each pool carries a reference to the operation that created it. You can inspect it via ``pool.operation`` to check settings like ``operation.mode`` and ``operation.num_states`` at any point in a pipeline. See :doc:`operations/modes` for details. Pools must be created inside an active context. Call ``pp.init()`` once at the top of a notebook, or use ``with pp.Party():`` for automatic cleanup when the block exits. See :doc:`quickstart` for details. All examples assume: .. code-block:: python import poolparty as pp pp.init() ---- Properties ---------- .. list-table:: :widths: 25 15 60 :header-rows: 1 * - Attribute - Type - Description * - ``name`` - ``str`` - Human-readable name for this pool. Settable. Defaults to ``"pool[N]"``. * - ``num_states`` - ``int`` - Number of distinct sequences this pool produces. * - ``seq_length`` - ``int | None`` - Fixed sequence length, or ``None`` for variable-length pools. * - ``iter_order`` - ``float`` - Iteration priority. Controls which pool's sequences change most rapidly when generating combinations in a joined or stacked pool. * - ``regions`` - ``set[Region]`` - Set of :class:`~poolparty.Region` objects present in this pool's sequences. See :doc:`regions` for details. * - ``parents`` - ``list[Pool]`` - Input pools that this pool's operation reads from. * - ``operation`` - ``Operation`` - The operation that created this pool. Exposes ``operation.mode``, ``operation.num_states``, and ``operation.natural_num_states``. Note that ``pool.num_states`` and ``pool.operation.num_states`` are different values. The pool's ``num_states`` is the total across the entire pipeline, while the operation's ``num_states`` is just that operation's contribution (see :doc:`operations/modes` and :doc:`operations/library_size`): .. code-block:: python seqs = pp.from_seqs(["AAA", "CCC", "GGG"], mode="sequential") mut = seqs.mutagenize(num_mutations=1, mode="sequential") mut.num_states # 27 (3 inputs × 9 mutants) mut.operation.num_states # 9 (mutagenize alone) mut.operation.natural_num_states # 9 (before any num_states override) ---- Naming and copying ------------------ ``named(name)`` ~~~~~~~~~~~~~~~ Set the pool's name and return ``self``, allowing in-line renaming without breaking a chain. .. code-block:: python wt = pp.from_seq("ACGT").named("wildtype") # wt.name == "wildtype" scored = ( pp.from_iupac("NNNN", mode="sequential") .mutagenize(num_mutations=1) .named("single_mut") ) ``copy()`` and ``deepcopy()`` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ``copy()`` creates a new pool that shares the same input pools — useful for branching a design at a specific point without re-running earlier operations. ``deepcopy()`` creates a fully independent copy of the entire upstream DAG — nothing is shared with the original. In most cases ``copy()`` is sufficient. Use ``deepcopy()`` when the two branches must be fully independent and share no input pools. .. code-block:: python base = pp.from_iupac("NNNN", mode="sequential") branch_a = base.mutagenize(num_mutations=1).named("branch_a") branch_b = base.copy().mutagenize(num_mutations=2).named("branch_b") # branch_a and branch_b share the same "base" input pool ---- Operator shortcuts ------------------ Pools support three Python operators as shorthand for common operations: ``pool_a + pool_b`` Equivalent to ``pp.stack([pool_a, pool_b])``. See :doc:`operations/stack`. ``pool * N`` Equivalent to ``pp.repeat(pool, times=N)``. See :doc:`operations/repeat`. ``pool[start:stop]`` Equivalent to ``pp.slice_states(pool, start=start, stop=stop)``. See :doc:`operations/slice_states`. .. code-block:: python a = pp.from_seqs(["AAA", "CCC"], mode="sequential") b = pp.from_seqs(["GGG", "TTT"], mode="sequential") combined = a + b # 4 states (2 + 2) repeated = a * 3 # 6 states (2 × 3) sliced = combined[:3] # 3 states (first 3 of 4) ---- Generating sequences -------------------- ``generate_library(...)`` ~~~~~~~~~~~~~~~~~~~~~~~~~ Generate all sequences from this pool and return them as a :class:`pandas.DataFrame`. Best for small to medium pools; for libraries above ~10k sequences, use ``to_df`` which streams in chunks. See :doc:`operations/generate_library` for full documentation. .. code-block:: python pool = pp.from_iupac("NNNN", mode="sequential") df = pool.generate_library() # df has columns: name, seq (plus any design card columns) ``print_library(...)`` ~~~~~~~~~~~~~~~~~~~~~~ Print a formatted preview of the pool's sequences to stdout. Returns ``self`` so it can be used mid-pipeline. .. list-table:: :widths: 25 15 15 45 :header-rows: 1 * - Parameter - Type - Default - Description * - ``num_seqs`` - ``int | None`` - ``None`` - Number of sequences to show. * - ``num_cycles`` - ``int | None`` - ``1`` - Number of complete passes through the pool's ``num_states`` sequences (used when ``num_seqs`` is not given). One cycle produces ``num_states`` sequences. * - ``show_header`` - ``bool`` - ``True`` - Print a summary header line before the sequences. * - ``show_name`` - ``bool`` - ``True`` - Include the sequence name column. * - ``show_seq`` - ``bool`` - ``True`` - Include the sequence column. * - ``show_state`` - ``bool`` - ``False`` - Include the state index column. * - ``pad_names`` - ``bool`` - ``True`` - Align sequences by padding names to the same width. * - ``seed`` - ``int | None`` - ``None`` - Random seed for reproducible previews. * - ``discard_null_seqs`` - ``bool`` - ``False`` - Skip sequences removed by a ``filter`` operation (``NullSeq``). See :class:`~poolparty.Pool` in the :doc:`api` for the full parameter list. .. code-block:: python pp.from_iupac("NNNNN", mode="sequential").print_library(num_seqs=6) .. raw:: html