biocrnpyler.components.dna.DNA_construct

class biocrnpyler.components.dna.DNA_construct(parts_list, name=None, circular=False, mechanisms=None, parameters=None, attributes=None, initial_concentration=None, copy_parts=True, component_enumerators=None, **kwargs)[source]

Bases: Construct, DNA

DNA construct representing a functional genetic circuit.

A DNA_construct is a specialized Construct for DNA sequences that can contain promoters, RBS sites, coding sequences, terminators, and other genetic elements. It supports transcription to generate RNA constructs and provides DNA-specific functionality. The class uses the ‘transcription’ mechanism to generate RNA products and related species/reactions during CRN compilation.

Parameters:
  • parts_list (list of list) – List of parts in format [[part, direction], …] where each part must be a DNA_part or OrderedMonomer.

  • name (str, optional) – Name of the DNA construct. If None, automatically generated.

  • circular (bool, default False) – If True, represents a circular DNA molecule (e.g., plasmid).

  • mechanisms (dict or list, optional) – Custom mechanisms for this construct, overriding mixture defaults.

  • parameters (dict, optional) – Parameter values specific to this construct.

  • attributes (list of str, optional) – List of attribute tags for the construct.

  • initial_concentration (float, optional) – Initial concentration of the DNA construct.

  • copy_parts (bool, default True) – If True, makes deep copies of parts when adding to construct.

  • component_enumerators (list, optional) – List of enumerators for generating construct variants. Defaults to [TxExplorer()] which explores transcriptional variants.

  • **kwargs – Additional keyword arguments passed to parent constructors.

Attributes:
  • material_type (str) – Always ‘dna’ for DNA constructs.

  • predicted_rnas (list or None) – Cached list of RNA_construct objects that can be transcribed.

  • predicted_proteins (list or None) – Cached list of protein species that can be produced.

See also

Construct

Base class for all constructs.

RNA_construct

RNA version of constructs.

DNA_part

Base class for DNA parts within constructs.

TxExplorer

Default enumerator for transcriptional exploration.

Notes

DNA_constructs support several key features:

  • Transcription enumeration: Automatically identifies all possible transcripts based on promoter positions and orientations

  • Protein prediction: Predicts protein products from transcripts containing RBS sites

  • Circular DNA: Special handling for plasmids and other circular DNA molecules

  • Component enumeration: Generates functional variants based on the genetic parts present

The default TxExplorer enumerator automatically explores all possible transcriptional units in the construct.

Examples

Create a simple gene expression construct:

>>> promoter = bcp.Promoter('ptet')
>>> rbs = bcp.RBS('RBS_standard')
>>> cds = bcp.CDS('GFP')
>>> terminator = bcp.Terminator('BBa_B0022')
>>> parts = [
...     [promoter, 'forward'], [rbs, 'forward'],
...     [cds, 'forward'], [terminator, 'forward']
... ]
>>> gene = bcp.DNA_construct(
...     parts_list=parts,
...     name='expression_cassette'
... )

Create a circular plasmid:

>>> ori = bcp.DNA_part('p15A')
>>> plasmid_parts = [
...     [ori, 'forward'], [promoter, 'forward'], [rbs, 'forward'],
...     [gene, 'forward'], [terminator, 'forward']
... ]
>>> plasmid = bcp.DNA_construct(
...     parts_list=plasmid_parts,
...     name='pUC19_GFP',
...     circular=True,
...     initial_concentration=10
... )

Methods

add_attribute

Add a single attribute to the component.

add_mechanism

Add a mechanism to the construct and all its parts.

add_mechanisms

Add multiple mechanisms to this component.

append

Add a monomer to the end of the polymer.

changed

Handle construct changes by resetting caches and updating name.

combinatorial_enumeration

Generate components for all combinatorial binding states.

create_hashless_reverse

Create a reversed construct without computing its hash.

delpart

Remove a monomer from the polymer at a specific position.

direction_invert

Invert a direction value.

direction_rotation_free_hash

Compute the best hash considering both rotation and direction.

enumerate_components

Generate all derived components and constructs from this construct.

enumerate_constructs

Run all enumerators to generate new construct variants.

get_circularly_permuted

Create a circularly permuted version of this construct.

get_mechanism

Retrieve a mechanism by type from the component or its mixture.

get_parameter

Retrieve parameter from component or mixture parameter database.

get_part

Find and return a part from the construct by various criteria.

get_partlist_hash

Generate a hash string for an ordered list of parts.

get_partstring

Generate a string identifier for a part including its direction.

get_reversed

Create a deep copy of the construct with reversed orientation.

get_species

Returns species of DNA construct, using OrderedPolymerSpecies.

insert

Insert a monomer at a specific position in the polymer.

linear_direction_free_hash

Compute the best hash for a linear construct in either direction.

located_allcomb

Generate all combinatorial placement dictionaries for species.

make_name

Generate a systematic name for the construct based on its parts.

make_polymers

Create polymer species from combinatorial binding combinations.

omnihash

Compute a canonical hash for the construct.

replace

Replace a monomer at a specific position in the polymer.

reset_stored_data

Clear all cached enumeration and prediction data.

reverse

Reverse the construct without modifying the underlying DNA.

rotation_free_hash

Compute the most alphabetically ordered circular permutation hash.

set_attributes

Set multiple attributes for the component.

set_mixture

Set the mixture containing this construct and all its parts.

set_species

Convert various inputs into Species objects.

update_base_species

Update the base species representation of this construct.

update_combinatorial_complexes

Generate all combinatorial binding state species for the construct.

update_parameters

Update parameters for the construct and all its parts.

update_permutation_hash

Update the direction-independent hash for this construct.

update_reactions

Generate reactions for the construct.

update_species

Generate species for the construct.

__contains__(obj2)[source]

Check if the construct contains a specific part.

Tests whether a DNA_part or copy of a DNA_part exists in this construct’s parts list.

Parameters:

obj2 (DNA_part) – The part to search for in the construct.

Returns:

True if the part (or a copy with the same name and type) is in the construct, False otherwise.

Return type:

bool

Notes

This method supports two types of containment checks:

  1. Direct membership: The exact part object is in the construct (checked via obj2.parent == self)

  2. Copy membership: A different part object with the same type and name exists in the construct

Examples

Check if construct contains a part:

>>> promoter = bcp.Promoter('ptet')
>>> rbs = bcp.RBS('RBS_standard')
>>> cds = bcp.CDS('GFP')
>>> parts = [
...    [promoter, 'forward'], [rbs, 'forward'], [cds, 'forward']
... ]
>>> construct = bcp.Construct(
...     parts_list=parts,
...     name='gene_circuit'
... )
>>> promoter in construct
True
>>> unknown_part = bcp.Promoter('plac')
>>> unknown_part in construct
False
__eq__(construct2)[source]

Test equality between two constructs.

Two constructs are considered equal if they have the same string representation and the same name.

Parameters:

construct2 (Construct) – The other construct to compare with.

Returns:

True if constructs are equal, False otherwise.

Return type:

bool

Notes

This is a simple equality test based on string representation. It does not use deep comparison of parts or the direction-independent hash. For more sophisticated equivalence testing that accounts for rotations and reversals, use the omnihash method.

See also

omnihash

Compute canonical hash accounting for rotation and direction.

__getitem__(ii)[source]

Get a monomer or slice of monomers from the polymer.

Parameters:

ii (int or slice) – Index or slice to retrieve from the polymer.

Returns:

The monomer at the given index, or a tuple of monomers for a slice.

Return type:

OrderedMonomer or tuple

__len__()[source]

Return the number of monomers in the polymer.

Returns:

The number of monomers in the polymer sequence.

Return type:

int

__setitem__(ii, val)[source]

Replace a monomer at a specific position.

Parameters:
  • ii (int) – Index at which to replace the monomer.

  • val (OrderedMonomer) – The new monomer to insert at the position.

Notes

Internally calls replace with the monomer’s existing direction.

add_attribute(attribute: str)[source]

Add a single attribute to the component.

Adds an attribute tag to the component’s attribute list and to its associated species object, if one exists. Attributes can be used for mechanism selection, species filtering, and tracking special properties.

Parameters:

attribute (str) – Attribute string to add to the component. Must be a non-None string value.

Raises:
  • AssertionError – If attribute is not a string or is None.

  • Warning – If the component has no internal species to which the attribute can be added.

Notes

Attributes are commonly used to tag components with properties such as:

  • Degradation tags (e.g., ‘degtagged’, ‘ssrAtagged’, )

  • Functional properties (e.g., ‘fluorescent’, ‘membranebound’)

  • Regulatory elements (e.g., ‘inducible’, ‘repressible’)

Examples

Add attributes to tag a protein with special properties:

>>> protein = bcp.Protein('GFP')
>>> protein.add_attribute('fluorescent')
>>> protein.add_attribute('ssrAtagged')
>>> protein.attributes
['fluorescent', 'ssrAtagged']
add_mechanism(mechanism, mech_type=None, overwrite=False, optional_mechanism=False)[source]

Add a mechanism to the construct and all its parts.

Adds the mechanism to the construct’s mechanism dictionary and propagates it to all parts in the construct.

Parameters:
  • mechanism (Mechanism) – The mechanism object to add.

  • mech_type (str, optional) – The mechanism type key. If None, uses the mechanism’s mechanism_type attribute.

  • overwrite (bool, default False) – If True, overwrites existing mechanisms with the same type. If False, raises ValueError for duplicate types.

  • optional_mechanism (bool, default False) – If True, suppresses ValueError when a mechanism key conflict occurs and overwrite is False.

Notes

This method:

  1. Adds the mechanism to the construct via the parent Component class

  2. Propagates the mechanism to each part in the construct

This ensures mechanism consistency across the entire construct.

add_mechanisms(mechanisms: Mechanism | GlobalMechanism, overwrite=False, optional_mechanism=False)[source]

Add multiple mechanisms to this component.

Accepts mechanisms as a single object, list, or dictionary and adds them to the component’s mechanism dictionary.

Parameters:
  • mechanisms (Mechanism, GlobalMechanism, dict, or list) – The mechanism(s) to add. Can be a single mechanism, a dict with mechanism types as keys and mechanisms as values, or a list of mechanisms.

  • overwrite (bool, default False) – If True, replaces any existing mechanisms with the same keys. If False, raises ValueError when keys already exist.

  • optional_mechanism (bool, default False) – If True, suppresses ValueError when mechanism key conflicts occur and overwrite is False.

Raises:

ValueError – If mechanisms is not a valid type, or if mechanism key conflicts occur with overwrite=False and optional_mechanism=False.

append(part, direction=None)[source]

Add a monomer to the end of the polymer.

Appends a copy of the given monomer to the end of the polymer sequence by calling insert at the final position.

Parameters:
  • part (OrderedMonomer) – The monomer to append. A copy of this monomer will be added.

  • direction (str, int, or None, optional) – Direction for the appended monomer. If None, uses the monomer’s existing direction if available.

See also

insert

Insert a monomer at a specific position.

Examples

>>> polymer = bcp.OrderedPolymer(parts=[])
>>> mon = bcp.OrderedMonomer()
>>> polymer.append(mon, direction='forward')
>>> len(polymer)
1
changed()[source]

Handle construct changes by resetting caches and updating name.

Called when the construct has been modified, this method resets all cached data and regenerates the construct’s name to reflect its current state.

Notes

This method performs two operations:

  1. Resets all cached enumeration and prediction data via reset_stored_data

  2. Regenerates the construct name via make_name to ensure it reflects the current parts configuration

This should be called after any structural modification to the construct.

combinatorial_enumeration()[source]

Generate components for all combinatorial binding states.

Creates copies of parts that can react with different combinatorial binding states of the construct, ensuring reactions are generated for all possible binding configurations.

Returns:

Components configured to react with different combinatorial binding states of the construct.

Return type:

list of Component

Notes

This method handles the generation of components that account for multiple simultaneous binding events. For example, given construct <A,B,C> where both A and B can bind RNAP:

  • Binary complexes: <[A:RNAP],B,C> and <A,[B:RNAP],C>

  • Combinatorial complex: <[A:RNAP],[B:RNAP],C>

The method returns multiple versions of components A and B, each configured to bind to different pre-existing binding states:

  • A component binding to <A,B,C> \(\rightarrow\) <[A:RNAP],B,C>

  • A component binding to <A,[B:RNAP],C> \(\rightarrow\) <[A:RNAP],[B:RNAP],C>

  • B component binding to <A,B,C> \(\rightarrow\) <A,[B:RNAP],C>

  • B component binding to <[A:RNAP],B,C> \(\rightarrow\) <[A:RNAP],[B:RNAP],C>

This ensures proper reaction enumeration for all binding combinations.

property compartment

The compartment containing this component.

Type:

Compartment or None

classmethod create_hashless_reverse(construct)[source]

Create a reversed construct without computing its hash.

Generates a reversed version of the construct with parts in reverse order and flipped directions, but skips hash computation to avoid infinite recursion during hash calculations.

Parameters:

construct (Construct) – The construct to reverse.

Returns:

A new construct with reversed parts order and flipped directions, with make_dirless_hash=False to prevent hash computation.

Return type:

Construct

Notes

This method is used internally by hash computation routines that need to compare forward and reverse orientations. Setting make_dirless_hash=False prevents infinite loops where hash computation would trigger reverse computation, which would trigger hash computation, etc.

The circularity status of the construct is preserved.

delpart(position)[source]

Remove a monomer from the polymer at a specific position.

Removes the monomer at the given position, shifts all subsequent monomers to lower positions, and calls the changed callback.

Parameters:

position (int) – Index of the monomer to remove. Must be a valid position in the polymer.

See also

replace

Replace a monomer at a specific position.

insert

Insert a monomer at a specific position.

Notes

The removed monomer’s remove method is called to clear its parent, position, and direction. If the polymer has a name attribute and a make_name method, the name is regenerated after deletion.

direction_invert(dirname)[source]

Invert a direction value.

Converts a direction to its opposite orientation. Used during polymer reversal operations.

Parameters:

dirname (str, int, or None) –

The direction to invert. Supported values:

  • ’forward’ \(\rightleftharpoons\) ‘reverse’

  • 0 \(\rightleftharpoons\) 1

  • None -> None

Returns:

The inverted direction. Returns the input unchanged if it cannot be inverted.

Return type:

str, int, or None

Warns:

UserWarning – If the direction value is not recognized.

Examples

>>> polymer = bcp.OrderedPolymer(parts=[])
>>> polymer.direction_invert('forward')
'reverse'
>>> polymer.direction_invert(0)
1
classmethod direction_rotation_free_hash(construct)[source]

Compute the best hash considering both rotation and direction.

Finds the most alphabetically ordered representation of a circular construct by evaluating all rotations in both forward and reverse orientations.

Parameters:

construct (Construct) – The circular construct to hash.

Returns:

  • hash (str) – String hash of the most alphabetically ordered permutation in either direction.

  • direction (int) – Direction of the best ordering: 1 for forward, -1 for reverse.

  • first_position (int) – The position that should be used as the first position in the best permutation.

Notes

This method:

  1. Computes the best forward rotation using rotation_free_hash

  2. Creates a reversed construct and computes its best rotation

  3. Returns whichever produces the more alphabetically ordered hash

To recreate the canonical form:

  1. If direction is -1, reverse the construct

  2. Rotate to start at first_position

This provides complete normalization for circular constructs, accounting for both rotation and direction symmetries.

enumerate_components(previously_enumerated=None)[source]

Generate all derived components and constructs from this construct.

Combines both construct enumeration (e.g., transcripts) and combinatorial component enumeration (for binding states) to produce a complete set of derived components.

Parameters:

previously_enumerated (set or list, optional) – Collection of components already enumerated, used to prevent infinite recursion.

Returns:

All new components and constructs generated, including:

  • New constructs from enumerators (e.g., RNA_constructs)

  • Components for combinatorial binding states

Return type:

list of Component

Notes

This method generates new components in two scenarios:

  1. Binding-induced species: When a component creates a species that binds to part of the construct. For example, <A,B,C> \(\rightarrow\) <[A:RNAP],B,C> would return component A configured for this binding.

  2. Combinatorial binding states: When multiple components can bind simultaneously. For construct <A,B,C> where both A and B can bind RNAP:

    • Binary species: <[A:RNAP],B,C> and <A,[B:RNAP],C>

    • Combinatorial: <[A:RNAP],[B:RNAP],C>

    Returns components A and B configured to bind to various pre-bound states, ensuring all binding combinations are enumerated.

  3. New constructs: Generated by enumerate_constructs(). For example, a DNA_construct with promoter A generates an RNA_construct containing <B,C>.

enumerate_constructs(previously_enumerated=None)[source]

Run all enumerators to generate new construct variants.

Applies all component enumerators to this construct to generate derived constructs (e.g., RNA_constructs from transcription).

Parameters:

previously_enumerated (set or list, optional) – Collection of constructs that have already been enumerated, used to prevent infinite recursion and duplicate enumeration.

Returns:

New constructs generated by all enumerators. For DNA_constructs with the default TxExplorer, this includes all possible RNA_construct transcripts.

Return type:

list of Construct

Notes

Each enumerator’s enumerate_components method is called with this construct and the previously enumerated set, allowing enumerators to explore transcriptional units, translational products, or other construct-derived components.

See also

TxExplorer

Default enumerator for DNA transcription exploration.

TlExplorer

Default enumerator for RNA translation exploration.

get_circularly_permuted(new_first_position)[source]

Create a circularly permuted version of this construct.

Returns a new construct where the circular ordering of parts starts at a different position. Only valid for circular constructs.

Parameters:

new_first_position (int) – The index of the part that should become the first position in the new construct.

Returns:

A new circular DNA_construct with parts reordered starting from the specified position.

Return type:

DNA_construct

Raises:

ValueError – If the construct is linear (circular permutation only applies to circular constructs).

Notes

The parts list is rotated so that parts_list[new_first_position] becomes the new first element, maintaining the circular structure.

Examples

Permute a circular plasmid:

>>> ori = bcp.DNA_part('p15A')
>>> promoter = bcp.Promoter('ptet')
>>> cds = bcp.CDS('GFP')
>>> plasmid = bcp.DNA_construct(
...     [[ori, 'forward'], [promoter, 'forward'], [cds, 'forward']],
...     circular=True
... )
>>> plasmid
DNA_construct = p15A_ptet_GFP_o
>>> plasmid.get_circularly_permuted(1)
DNA_construct = ptet_GFP_p15A_o
get_mechanism(mechanism_type, optional_mechanism=False)[source]

Retrieve a mechanism by type from the component or its mixture.

Searches first in the component’s mechanism dictionary, then falls back to the mixture’s mechanisms if not found.

Parameters:
  • mechanism_type (str) – The type identifier of the mechanism to retrieve (e.g., ‘transcription’, ‘translation’, ‘binding’).

  • optional_mechanism (bool, default False) – If True, returns None when mechanism not found. If False, raises KeyError when mechanism not found.

Returns:

The requested mechanism object, or None if not found and optional_mechanism is True.

Return type:

Mechanism or None

Raises:
  • TypeError – If mechanism_type is not a string.

  • KeyError – If mechanism not found and optional_mechanism is False.

get_parameter(param_name: str, part_id=None, mechanism=None, return_numerical=False, return_none=False, check_mixture=True) Parameter | Real[source]

Retrieve parameter from component or mixture parameter database.

Searches first in the component’s parameter database, then falls back to the mixture’s parameter database if not found.

Parameters:
  • param_name (str) – Name of the parameter to retrieve.

  • part_id (str, optional) – Part identifier for the parameter lookup key.

  • mechanism (str, optional) – Mechanism identifier for the parameter lookup key.

  • return_numerical (bool, default False) – If True, returns the numerical value. If False, returns the Parameter object.

  • return_none (bool, default False) – If True, returns None when parameter not found. If False, raises ValueError when parameter not found.

  • check_mixture (bool, default True) – If True, searches the mixture’s parameter database if not found in the component’s database.

Returns:

The parameter object or its numerical value, or None if not found and return_none is True.

Return type:

Parameter, Real, or None

Raises:

ValueError – If parameter not found and return_none is False.

Notes

Parameter lookup follows the hierarchy:

  1. Component.parameter_database

  2. Component.mixture.parameter_database (if check_mixture is True)

get_part(part=None, part_type=None, name=None, index=None)[source]

Find and return a part from the construct by various criteria.

Searches the construct’s parts list for a part matching the given criteria. Only one search criterion should be provided at a time.

Parameters:
  • part (DNA_part, optional) – A specific DNA_part instance to find. Matches both type and name.

  • part_type (type, optional) – Find all parts that are instances of this type (e.g., Promoter).

  • name (str, optional) – Find part(s) with this exact name.

  • index (int, optional) – Return the part at this position in parts_list.

Returns:

Single matching part if exactly one match found. List of parts if multiple matches found. None if no matches found.

Return type:

DNA_part, list of DNA_part, or None

Raises:

ValueError – If multiple search criteria are provided simultaneously, or if invalid types are provided for parameters.

Warns:

UserWarning – If multiple matching parts are found (returns list).

Notes

The search is performed with the following priority:

  1. Index (direct lookup)

  2. Part instance (type and name must match)

  3. Name (string match)

  4. Type (isinstance check)

Only one search criterion should be provided at a time.

Examples

Find a part by name:

>>> promoter = bcp.Promoter('ptet')
>>> rbs = bcp.RBS('RBS_standard')
>>> cds = bcp.CDS('GFP')
>>> parts = [
...     [promoter, 'forward'], [rbs, 'forward'], [cds, 'forward']
... ]
>>> construct = bcp.Construct(
...     parts_list=parts,
...     name='gene_circuit',
...     circular=False
... )
>>> promoter = construct.get_part(name='ptet')

Get the third part in the construct:

>>> third_part = construct.get_part(index=2)

Find all RBS parts:

>>> all_rbs = construct.get_part(part_type=bcp.RBS)
classmethod get_partlist_hash(partlist)[source]

Generate a hash string for an ordered list of parts.

Creates a unique string identifier for a parts list by concatenating part names with position indices, capturing the order and content of parts (but not their absolute positions).

Parameters:

partlist (list) – List of (part_string, part) tuples where part_string is typically generated by get_partstring.

Returns:

Hash string representing the ordered parts list.

Return type:

str

Notes

The hash format concatenates each part’s string representation with its index in the list, separated by underscores. This creates a unique identifier for the parts sequence.

classmethod get_partstring(part)[source]

Generate a string identifier for a part including its direction.

Creates a unique string representation of a part that includes its name and direction but not its position, useful for construct comparison.

Parameters:

part (DNA_part or OrderedMonomer) – The part to generate a string identifier for.

Returns:

String combining the part’s name and direction (e.g., ‘promoter_pLacforward’ or ‘gene_GFPreverse’).

Return type:

str

Notes

This method creates an “orphan” copy of the part (without position or direction) to get the base name, then appends the direction to create a direction-aware identifier.

get_reversed()[source]

Create a deep copy of the construct with reversed orientation.

Returns a new construct that is the reverse complement of this construct, with all parts in reverse order and flipped directions. The original construct is not modified.

Returns:

A new construct object with reversed parts and directions.

Return type:

Construct

See also

reverse

Reverse the construct in place.

Examples

Get reversed version without modifying original:

>>> promoter = bcp.Promoter('ptet')
>>> cds = bcp.CDS('GFP')
>>> original = bcp.Construct(
...     [[promoter, 'forward'], [cds, 'forward']])
>>> original.get_reversed()
Construct = GFP_r_ptet_r
get_species()[source]

Returns species of DNA construct, using OrderedPolymerSpecies.

insert(position, part, direction=None)[source]

Insert a monomer at a specific position in the polymer.

Inserts a copy of the given monomer at the specified position, shifting all subsequent monomers to higher positions. Calls the changed callback after insertion.

Parameters:
  • position (int) – Index at which to insert the monomer. Must be between 0 and len(polymer) (inclusive).

  • part (OrderedMonomer) – The monomer to insert. A copy of this monomer will be added.

  • direction (str, int, or None, optional) – Direction for the inserted monomer. If None, uses the monomer’s existing direction.

See also

append

Add a monomer to the end of the polymer.

replace

Replace a monomer at a specific position.

Notes

The monomer is deep-copied before insertion to maintain independence from the original object.

classmethod linear_direction_free_hash(construct)[source]

Compute the best hash for a linear construct in either direction.

Determines which orientation (forward or reverse) produces the most alphabetically ordered sequence for a linear construct.

Parameters:

construct (Construct) – The linear construct to hash.

Returns:

  • hash (str) – String hash of the most alphabetically ordered orientation.

  • direction (int) – Direction of the best ordering: 1 for forward, -1 for reverse.

  • first_position (int) – Always 0 for linear constructs (no circular permutation).

Notes

This method compares forward and reverse orientations part-by-part, stopping as soon as one orientation is determined to be more alphabetically ordered than the other.

To recreate the canonical form:

  1. If direction is -1, reverse the construct

  2. Start at position 0 (always the first position for linear constructs)

Unlike circular constructs, linear constructs have a defined start and end, so the first_position is always 0.

located_allcomb(spec_list)[source]

Generate all combinatorial placement dictionaries for species.

Creates all possible combinations of species placements when multiple species can bind at different positions in the construct.

Parameters:

spec_list (list of Species) – List of species that have position attributes, typically ComplexSpecies that can bind at specific locations.

Returns:

List of dictionaries where each dict maps positions (int) to [species, direction] pairs representing one possible combinatorial binding state.

Return type:

list of dict

Notes

This method handles the combinatorics of placing multiple binding species at different positions. For example:

  • Species A binds at position 0

  • Species B binds at position 3

  • Species C also binds at position 0

The method generates all valid combinations: {0: [A, direction]}, {0: [C, direction]}, {0: [A, direction], 3: [B, direction]}, {0: [C, direction], 3: [B, direction]}, etc.

The algorithm:

  1. Extracts positions from spec_list

  2. Groups species by position into prototype_list

  3. Generates all position combinations via all_comb

  4. For each position combination, generates all possible species selections at those positions

make_name()[source]

Generate a systematic name for the construct based on its parts.

Creates a name by concatenating all part names with underscores. Parts in reverse orientation are suffixed with ‘_r’, and circular constructs are suffixed with ‘_o’.

Returns:

The generated construct name.

Return type:

str

Examples

Linear construct with forward parts:

>>> promoter = bcp.Promoter('pLac')
>>> rbs = bcp.CDS('RBS1')
>>> cds = bcp.CDS('GFP')
>>> construct = bcp.DNA_construct(
...     [[promoter, 'forward'], [rbs, 'forward'], [cds, 'forward']]
... )
>>> construct.make_name()
'pLac_RBS1_GFP'

Linear construct with reversed part:

>>> construct = bcp.DNA_construct(
...     [[promoter, 'forward'], [rbs, 'reverse'], [cds, 'forward']]
... )
>>> construct.make_name()
'pLac_RBS1_r_GFP'

Circular construct:

>>> construct = bcp.DNA_construct(
...     [[promoter, 'forward'], [rbs, 'forward'], [cds, 'forward']],
...     circular=True
... )
>>> construct.make_name()
'pLac_RBS1_GFP_o'
make_polymers(species_lists, backbone)[source]

Create polymer species from combinatorial binding combinations.

Generates OrderedPolymerSpecies by replacing specific monomers in a backbone polymer with bound versions according to the replacement dictionaries.

Parameters:
  • species_lists (list of dict) – List of replacement dictionaries where each dict maps positions (int) to [species, direction] pairs indicating which monomers to replace with bound versions.

  • backbone (OrderedPolymerSpecies) – The base polymer species serving as the template for creating bound variants.

Returns:

List of polymer species representing all specified combinatorial binding states.

Return type:

list of OrderedPolymerSpecies

Notes

This method takes a backbone polymer (typically the unbound construct) and creates variants where specific positions contain bound complexes.

For example, given backbone <A,B,C> and replacements:

  • {0: [A:RNAP, forward]} creates <[A:RNAP],B,C>

  • {0: [A:RNAP, forward], 1: [B:RNAP, forward]} creates <[A:RNAP],[B:RNAP],C>

classmethod omnihash(construct)[source]

Compute a canonical hash for the construct.

Creates the most alphabetically ordered representation of a construct, accounting for direction (forward/reverse) and, for circular constructs, rotation. This provides a unique canonical identifier for functionally equivalent constructs.

Parameters:

construct (Construct) – The construct to hash (can be linear or circular).

Returns:

  • hash (str) – Canonical hash string with ‘circular’ or ‘linear’ suffix indicating construct topology.

  • direction (int) – Direction of the canonical form: 1 for forward, -1 for reverse.

  • first_position (int) – Starting position for the canonical form. For circular constructs, this is the optimal rotation point. For linear constructs, always 0.

Notes

For circular constructs:

  1. Evaluates all rotations in both orientations

  2. Selects the most alphabetically ordered permutation

  3. Appends ‘circular’ to the hash

For linear constructs:

  1. Compares forward and reverse orientations

  2. Selects the most alphabetically ordered orientation

  3. Appends ‘linear’ to the hash

To recreate the canonical form:

  1. If direction is -1, reverse the construct

  2. For circular constructs, rotate to start at first_position

  3. For linear constructs, first_position is always 0

This hash enables identification of equivalent constructs that differ only in representation (rotation or direction).

Examples

Two circular constructs with the same parts in different rotations will produce the same omnihash:

>>> A, B, C = (bcp.DNA_part(s) for s in ['A', 'B', 'C'])
>>> construct1 = bcp.DNA_construct(
...     [[A, 'forward'], [B, 'forward'], [C, 'forward']],
...     circular=True)
>>> construct2 = bcp.DNA_construct(
...     [[B, 'forward'], [C, 'forward'], [A, 'forward']],
...     circular=True)
>>> hash1, _, _ = bcp.Construct.omnihash(construct1)
>>> hash2, _, _ = bcp.Construct.omnihash(construct2)
>>> hash1 == hash2
True
replace(position, part, direction=None)[source]

Replace a monomer at a specific position in the polymer.

Removes the monomer at the given position and inserts a copy of the new monomer in its place. Calls the changed callback after replacement.

Parameters:
  • position (int) – Index of the monomer to replace. Must be a valid position in the polymer.

  • part (OrderedMonomer) – The monomer to insert. A copy of this monomer will be added.

  • direction (str, int, or None, optional) – Direction for the new monomer. If None, uses the monomer’s existing direction.

See also

insert

Insert a monomer at a specific position.

delpart

Remove a monomer from the polymer.

Notes

The removed monomer’s remove method is called to clear its parent, position, and direction attributes.

reset_stored_data()[source]

Clear all cached enumeration and prediction data.

Resets the cached results from component enumeration, RNA prediction, and protein prediction, forcing these to be recomputed on the next access.

Notes

This method should be called whenever the construct is modified in a way that would invalidate cached data, such as:

  • Reversing the construct

  • Changing parts

  • Updating mechanisms or parameters

The cached attributes that are reset:

  • out_components: Results from enumerate_components

  • predicted_rnas: List of predicted RNA products

  • predicted_proteins: List of predicted protein products

reverse()[source]

Reverse the construct without modifying the underlying DNA.

Creates a reversed representation of the construct where all parts are in reverse order and each part’s direction is flipped. This is useful for generating the reverse complement of a construct.

Returns:

Returns self after reversing the parts list and flipping directions.

Return type:

Construct

Notes

This method modifies the construct in place by:

  1. Reversing the order of parts in the parts_list

  2. Flipping each part’s direction (forward \(\rightleftharpoons\) reverse)

The underlying DNA sequence is not modified, only the representation changes.

Examples

Reverse a simple construct:

>>> promoter = bcp.Promoter('ptet')
>>> gene = bcp.CDS('GFP')
>>> construct = bcp.Construct(
...    [[promoter, 'forward'], [gene, 'forward']])
>>> construct.reverse()
Construct = GFP_r_pLac_r
classmethod rotation_free_hash(construct)[source]

Compute the most alphabetically ordered circular permutation hash.

Finds the circular permutation of the construct that produces the most alphabetically ordered sequence of parts, providing a canonical representation for circular constructs regardless of starting position.

Parameters:

construct (Construct) – The circular construct to hash. Should have circular=True.

Returns:

  • hash (str) – String hash of the most alphabetically ordered permutation.

  • direction (int) – Always 1 (forward direction, since only rotation is considered).

  • first_position (int) – The position that should be used as the first position to recreate this canonical permutation.

Notes

This method evaluates every possible starting position for a circular construct and selects the permutation that produces the most alphabetically ordered sequence when parts are compared lexicographically.

To recreate the canonical form from the original construct:

  1. Rotate to start at first_position

The direction is always 1 because this method only considers rotations, not reversals.

Examples

For a circular construct with parts A, B, C, if starting at C gives the most alphabetically ordered sequence (C, A, B), then first_position would be 2.

set_attributes(attributes: List[str])[source]

Set multiple attributes for the component.

Adds a list of attribute tags to the component and its associated species by calling add_attribute for each attribute in the list.

Parameters:

attributes (list of str or None) – List of attribute strings to add to the component. If None, no action is taken.

See also

add_attribute

Add a single attribute to the component.

Examples

>>> comp = bcp.Protein(name="MyProtein")
>>> comp.set_attributes(["degtagged", "fluorescent"])
>>> comp.attributes
['degtagged', 'fluorescent']
set_mixture(mixture)[source]

Set the mixture containing this construct and all its parts.

Propagates the mixture reference to all parts in the construct, ensuring they share access to the same parameter database and mechanisms.

Parameters:

mixture (Mixture) – The mixture object that contains this construct.

Notes

This method ensures that all parts in the construct have access to the same mixture-level parameters and mechanisms, maintaining consistency across the entire construct.

classmethod set_species(species: Species | str, material_type=None, compartment=None, attributes=None) Species[source]

Convert various inputs into Species objects.

Parameters:
  • species (Species, str, Component, or list) – The species to convert. Can be a Species object (returned as-is), a string (creates new Species), a Component (extracts its species), or a list of any of these types.

  • material_type (str, optional) – Material type for the species (e.g., ‘dna’, ‘rna’, ‘protein’). Only used when creating new Species from strings.

  • compartment (Compartment, optional) – Compartment to assign to the species. Only used when creating new Species from strings.

  • attributes (list of str, optional) – Attributes to assign to the species. Only used when creating new Species from strings.

Returns:

The converted Species object(s). Returns a list if input was a list.

Return type:

Species or list of Species

Raises:

ValueError – If the input cannot be converted to a valid Species.

update_base_species(base_name=None, attributes=None)[source]

Update the base species representation of this construct.

Sets the base_species attribute to a Species object representing the construct’s primary chemical species in the CRN.

Parameters:
  • base_name (str, optional) – Name for the base species. If None, uses the construct’s name.

  • attributes (list of str, optional) – Attribute tags to add to the species.

Notes

The base species serves as the chemical representation of the construct in CRN compilation, with material_type matching the construct’s material_type (e.g., ‘dna’ for DNA_constructs).

update_combinatorial_complexes(active_components)[source]

Generate all combinatorial binding state species for the construct.

Given components that can bind to different positions in the construct, this method generates all possible combinations of binding states by mixing and matching bound species at different locations.

Parameters:

active_components (list of Component) – Components that generate binding complexes with the construct. Each is assumed to bind at only one position.

Returns:

All possible combinatorial binding states of the construct, including the unbound state and all single and multiple binding combinations.

Return type:

list of OrderedPolymerSpecies

Notes

The method:

  1. Collects all binary complex species from each active component

  2. Identifies unique positioned complexes

  3. Generates all combinatorial placements using located_allcomb

  4. Creates polymer species for each combination using make_polymers

For example, given construct <A,B,C> with two components that create <[A:RNAP],B,C> and <A,[B:RNAP],C>, this method generates:

  • <A,B,C> (unbound)

  • <[A:RNAP],B,C> (A bound)

  • <A,[B:RNAP],C> (B bound)

  • <[A:RNAP],[B:RNAP],C> (both bound)

assuming A and B act independently.

update_parameters(overwrite_parameters=True)[source]

Update parameters for the construct and all its parts.

Propagates parameter updates from the construct’s parameter database to all parts in the parts list, ensuring consistent parameters throughout the construct.

Parameters:

overwrite_parameters (bool, default True) – If True, new parameter values overwrite existing ones in the parts. If False, existing parameters in parts are preserved.

Notes

This method:

  1. Updates the construct’s own parameters via the parent Component class

  2. Propagates these parameters to each part in the construct

This ensures that all parts have access to the same parameter values unless explicitly overridden at the part level.

update_permutation_hash()[source]

Update the direction-independent hash for this construct.

Generates a unique string representation of the construct that is invariant to direction (forward/reverse) and circular permutations (for circular constructs). This enables comparison of functionally equivalent constructs regardless of their representation.

Notes

The hash is stored in the directionless_hash attribute and is used for identifying equivalent constructs that differ only in orientation or circular starting position.

The hash is computed using the omnihash class method, which finds the most alphabetically ordered representation of the construct.

See also

omnihash

Class method that computes the direction and rotation-free hash.

update_reactions(norna=False)[source]

Generate reactions for the construct.

Returns:

Empty list. Base Construct class does not generate reactions directly. Subclasses override this method to provide specific reaction generation.

Return type:

list of Reaction

Parameters:

norna (bool, default False) – If True, RNA-related reactions are excluded (used in some subclass implementations).

Notes

This method is called during CRN compilation by Mixture.compile_crn(). The base implementation returns an empty list because the base Construct class does not generate reactions directly - reactions are generated by the parts within the construct through their associated mechanisms.

Subclasses like DNA_construct and RNA_construct may override this to provide construct-specific reaction generation.

update_species()[source]

Generate species for the construct.

Returns:

List containing the construct’s primary species representation.

Return type:

list of Species

Notes

This method is called during CRN compilation by Mixture.compile_crn() to generate the species associated with this construct. For most constructs, this returns a single species representing the entire construct.