biocrnpyler.components.dna.construct

Classes

Construct(parts_list[, name, circular, ...])

Base class for ordered genetic constructs with multiple parts.

DNA_construct(parts_list[, name, circular, ...])

DNA construct representing a functional genetic circuit.

DNA_part(name[, assembly, direction, pos, ...])

Base class for individual DNA parts in constructs.

RNA_construct(parts_list[, name, promoter, ...])

RNA construct representing a functional transcript.

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

Base class for ordered genetic constructs with multiple parts.

A Construct represents an ordered arrangement of genetic parts (promoters, RBS, coding sequences, terminators, etc.) that form a functional unit. This class provides the infrastructure for handling complex genetic constructs with multiple components, their enumeration, and generation of combinatorial variants. Constructs can be linear or circular and support both forward and reverse orientations of their constituent parts.

Parameters:
parts_listlist of list

List of parts in the format [[part, direction], [part, direction], …] where each part must be an OrderedMonomer and direction is ‘forward’ or ‘reverse’.

namestr, optional

Name of the construct. If None, automatically generated from parts.

circularbool, default=False

If True, the construct is circular (e.g., plasmid). If False, linear.

mechanismsdict or list, optional

Custom mechanisms for this construct, overriding mixture defaults.

parametersdict, optional

Parameter values specific to this construct.

attributeslist of str, optional

List of attribute tags for the construct.

initial_concentrationfloat, optional

Initial concentration of the construct species.

component_enumeratorslist, optional

List of enumerator objects that generate construct variants.

make_dirless_hashbool, default=True

If True, generates direction-independent hash for construct comparison.

**kwargs

Additional keyword arguments passed to Component constructor.

Attributes:
parts_listlist

Ordered list of parts in the construct.

circularbool

Whether the construct is circular.

component_enumeratorslist

Enumerators for generating construct variants.

out_componentslist or None

Cached list of output components from enumeration.

predicted_rnaslist or None

Cached list of predicted RNA species.

predicted_proteinslist or None

Cached list of predicted protein species.

See also

DNA_construct

DNA-specific construct implementation.

RNA_construct

RNA-specific construct implementation.

DNA_part

Base class for individual DNA parts.

OrderedPolymer

Base class for ordered polymer structures.

Notes

Constructs support several advanced features:

  • Part enumeration: Automatically generates all functional variants based on the parts present (e.g., all promoter-RBS combinations)

  • Combinatorial complexes: Generates all possible binding states when regulatory proteins bind to different parts

  • Direction-free comparison: Can identify equivalent constructs regardless of orientation or circular permutation

The class maintains caches for enumerated components, RNA products, and protein products to avoid redundant computation.

Examples

Create a simple linear construct:

>>> 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
... )

Create a circular plasmid:

>>> ori = bcp.DNA_part('p15A')
>>> terminator = bcp.Terminator('BBa_B0022')
>>> parts = [
>>>     [ori, 'forward'], [promoter, 'forward'], [rbs, 'forward'],
>>>     [cds, 'forward'], [terminator, 'forward']
>>> ]
>>> plasmid = bcp.Construct(
...     parts_list=parts,
...     name='pExpression',
...     circular=True
... )
__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:
obj2DNA_part

The part to search for in the construct.

Returns:
bool

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

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:
construct2Construct

The other construct to compare with.

Returns:
bool

True if constructs are equal, False otherwise.

See also

omnihash

Compute canonical hash accounting for rotation and direction.

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.

__getitem__(ii)[source]

Get a monomer or slice of monomers from the polymer.

Parameters:
iiint or slice

Index or slice to retrieve from the polymer.

Returns:
OrderedMonomer or tuple

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

__hash__()[source]

Return hash(self).

__len__()[source]

Return the number of monomers in the polymer.

Returns:
int

The number of monomers in the polymer sequence.

__setitem__(ii, val)[source]

Replace a monomer at a specific position.

Parameters:
iiint

Index at which to replace the monomer.

valOrderedMonomer

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:
attributestr

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:
mechanismMechanism

The mechanism object to add.

mech_typestr, optional

The mechanism type key. If None, uses the mechanism’s mechanism_type attribute.

overwritebool, default=False

If True, overwrites existing mechanisms with the same type. If False, raises ValueError for duplicate types.

optional_mechanismbool, 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:
mechanismsMechanism, 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.

overwritebool, default=False

If True, replaces any existing mechanisms with the same keys. If False, raises ValueError when keys already exist.

optional_mechanismbool, 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:
partOrderedMonomer

The monomer to append. A copy of this monomer will be added.

directionstr, 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:
list of Component

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

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> –> <[A:RNAP],B,C>

  • A component binding to <A,[B:RNAP],C> –> <[A:RNAP],[B:RNAP],C>

  • B component binding to <A,B,C> –> <A,[B:RNAP],C>

  • B component binding to <[A:RNAP],B,C> –> <[A:RNAP],[B:RNAP],C>

This ensures proper reaction enumeration for all binding combinations.

property compartment

Compartment or None: The compartment containing this component.

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:
constructConstruct

The construct to reverse.

Returns:
Construct

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

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:
positionint

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:
dirnamestr, int, or None

The direction to invert. Supported values:

  • ‘forward’ <–> ‘reverse’

  • 0 <–> 1

  • None -> None

Returns:
str, int, or None

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

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:
constructConstruct

The circular construct to hash.

Returns:
hashstr

String hash of the most alphabetically ordered permutation in either direction.

directionint

Direction of the best ordering: 1 for forward, -1 for reverse.

first_positionint

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_enumeratedset or list, optional

Collection of components already enumerated, used to prevent infinite recursion.

Returns:
list of Component

All new components and constructs generated, including:

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

  • Components for combinatorial binding states

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> –> <[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_enumeratedset or list, optional

Collection of constructs that have already been enumerated, used to prevent infinite recursion and duplicate enumeration.

Returns:
list of Construct

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

See also

TxExplorer

Default enumerator for DNA transcription exploration.

TlExplorer

Default enumerator for RNA translation exploration.

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.

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_positionint

The index of the part that should become the first position in the new construct.

Returns:
DNA_construct

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

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_typestr

The type identifier of the mechanism to retrieve (e.g., ‘transcription’, ‘translation’, ‘binding’).

optional_mechanismbool, default=False

If True, returns None when mechanism not found. If False, raises KeyError when mechanism not found.

Returns:
Mechanism or None

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

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_namestr

Name of the parameter to retrieve.

part_idstr, optional

Part identifier for the parameter lookup key.

mechanismstr, optional

Mechanism identifier for the parameter lookup key.

return_numericalbool, default=False

If True, returns the numerical value. If False, returns the Parameter object.

return_nonebool, default=False

If True, returns None when parameter not found. If False, raises ValueError when parameter not found.

check_mixturebool, default=True

If True, searches the mixture’s parameter database if not found in the component’s database.

Returns:
Parameter, Real, or None

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

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:
partDNA_part, optional

A specific DNA_part instance to find. Matches both type and name.

part_typetype, optional

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

namestr, optional

Find part(s) with this exact name.

indexint, optional

Return the part at this position in parts_list.

Returns:
DNA_part, list of DNA_part, or None

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

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:
partlistlist

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

Returns:
str

Hash string representing the ordered parts list.

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:
partDNA_part or OrderedMonomer

The part to generate a string identifier for.

Returns:
str

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

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:
Construct

A new construct object with reversed parts and directions.

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:
positionint

Index at which to insert the monomer. Must be between 0 and len(polymer) (inclusive).

partOrderedMonomer

The monomer to insert. A copy of this monomer will be added.

directionstr, 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:
constructConstruct

The linear construct to hash.

Returns:
hashstr

String hash of the most alphabetically ordered orientation.

directionint

Direction of the best ordering: 1 for forward, -1 for reverse.

first_positionint

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_listlist of Species

List of species that have position attributes, typically ComplexSpecies that can bind at specific locations.

Returns:
list of dict

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

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:
str

The generated construct name.

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_listslist of dict

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

backboneOrderedPolymerSpecies

The base polymer species serving as the template for creating bound variants.

Returns:
list of OrderedPolymerSpecies

List of polymer species representing all specified combinatorial binding states.

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:
constructConstruct

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

Returns:
hashstr

Canonical hash string with ‘circular’ or ‘linear’ suffix indicating construct topology.

directionint

Direction of the canonical form: 1 for forward, -1 for reverse.

first_positionint

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:
positionint

Index of the monomer to replace. Must be a valid position in the polymer.

partOrderedMonomer

The monomer to insert. A copy of this monomer will be added.

directionstr, 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:
Construct

Returns self after reversing the parts list and flipping directions.

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 <–> 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:
constructConstruct

The circular construct to hash. Should have circular=True.

Returns:
hashstr

String hash of the most alphabetically ordered permutation.

directionint

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

first_positionint

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:
attributeslist 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:
mixtureMixture

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:
speciesSpecies, 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_typestr, optional

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

compartmentCompartment, optional

Compartment to assign to the species. Only used when creating new Species from strings.

attributeslist of str, optional

Attributes to assign to the species. Only used when creating new Species from strings.

Returns:
Species or list of Species

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

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_namestr, optional

Name for the base species. If None, uses the construct’s name.

attributeslist 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_componentslist of Component

Components that generate binding complexes with the construct. Each is assumed to bind at only one position.

Returns:
list of OrderedPolymerSpecies

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

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_parametersbool, 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.

See also

omnihash

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

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.

update_reactions(norna=False)[source]

Generate reactions for the construct.

Parameters:
nornabool, default=False

If True, RNA-related reactions are excluded (used in some subclass implementations).

Returns:
list of Reaction

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

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 of Species

List containing the construct’s primary species representation.

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.

class biocrnpyler.components.dna.construct.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]

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_listlist of list

List of parts in format [[part, direction], …] where each part must be a DNA_part or OrderedMonomer.

namestr, optional

Name of the DNA construct. If None, automatically generated.

circularbool, default=False

If True, represents a circular DNA molecule (e.g., plasmid).

mechanismsdict or list, optional

Custom mechanisms for this construct, overriding mixture defaults.

parametersdict, optional

Parameter values specific to this construct.

attributeslist of str, optional

List of attribute tags for the construct.

initial_concentrationfloat, optional

Initial concentration of the DNA construct.

copy_partsbool, default=True

If True, makes deep copies of parts when adding to construct.

component_enumeratorslist, 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_typestr

Always ‘dna’ for DNA constructs.

predicted_rnaslist or None

Cached list of RNA_construct objects that can be transcribed.

predicted_proteinslist 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
... )
__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:
obj2DNA_part

The part to search for in the construct.

Returns:
bool

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

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:
construct2Construct

The other construct to compare with.

Returns:
bool

True if constructs are equal, False otherwise.

See also

omnihash

Compute canonical hash accounting for rotation and direction.

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.

__getitem__(ii)[source]

Get a monomer or slice of monomers from the polymer.

Parameters:
iiint or slice

Index or slice to retrieve from the polymer.

Returns:
OrderedMonomer or tuple

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

__hash__()[source]

Return hash(self).

__len__()[source]

Return the number of monomers in the polymer.

Returns:
int

The number of monomers in the polymer sequence.

__setitem__(ii, val)[source]

Replace a monomer at a specific position.

Parameters:
iiint

Index at which to replace the monomer.

valOrderedMonomer

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:
attributestr

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:
mechanismMechanism

The mechanism object to add.

mech_typestr, optional

The mechanism type key. If None, uses the mechanism’s mechanism_type attribute.

overwritebool, default=False

If True, overwrites existing mechanisms with the same type. If False, raises ValueError for duplicate types.

optional_mechanismbool, 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:
mechanismsMechanism, 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.

overwritebool, default=False

If True, replaces any existing mechanisms with the same keys. If False, raises ValueError when keys already exist.

optional_mechanismbool, 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:
partOrderedMonomer

The monomer to append. A copy of this monomer will be added.

directionstr, 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:
list of Component

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

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> –> <[A:RNAP],B,C>

  • A component binding to <A,[B:RNAP],C> –> <[A:RNAP],[B:RNAP],C>

  • B component binding to <A,B,C> –> <A,[B:RNAP],C>

  • B component binding to <[A:RNAP],B,C> –> <[A:RNAP],[B:RNAP],C>

This ensures proper reaction enumeration for all binding combinations.

property compartment

Compartment or None: The compartment containing this component.

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:
constructConstruct

The construct to reverse.

Returns:
Construct

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

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:
positionint

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:
dirnamestr, int, or None

The direction to invert. Supported values:

  • ‘forward’ <–> ‘reverse’

  • 0 <–> 1

  • None -> None

Returns:
str, int, or None

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

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:
constructConstruct

The circular construct to hash.

Returns:
hashstr

String hash of the most alphabetically ordered permutation in either direction.

directionint

Direction of the best ordering: 1 for forward, -1 for reverse.

first_positionint

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_enumeratedset or list, optional

Collection of components already enumerated, used to prevent infinite recursion.

Returns:
list of Component

All new components and constructs generated, including:

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

  • Components for combinatorial binding states

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> –> <[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_enumeratedset or list, optional

Collection of constructs that have already been enumerated, used to prevent infinite recursion and duplicate enumeration.

Returns:
list of Construct

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

See also

TxExplorer

Default enumerator for DNA transcription exploration.

TlExplorer

Default enumerator for RNA translation exploration.

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.

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_positionint

The index of the part that should become the first position in the new construct.

Returns:
DNA_construct

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

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_typestr

The type identifier of the mechanism to retrieve (e.g., ‘transcription’, ‘translation’, ‘binding’).

optional_mechanismbool, default=False

If True, returns None when mechanism not found. If False, raises KeyError when mechanism not found.

Returns:
Mechanism or None

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

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_namestr

Name of the parameter to retrieve.

part_idstr, optional

Part identifier for the parameter lookup key.

mechanismstr, optional

Mechanism identifier for the parameter lookup key.

return_numericalbool, default=False

If True, returns the numerical value. If False, returns the Parameter object.

return_nonebool, default=False

If True, returns None when parameter not found. If False, raises ValueError when parameter not found.

check_mixturebool, default=True

If True, searches the mixture’s parameter database if not found in the component’s database.

Returns:
Parameter, Real, or None

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

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:
partDNA_part, optional

A specific DNA_part instance to find. Matches both type and name.

part_typetype, optional

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

namestr, optional

Find part(s) with this exact name.

indexint, optional

Return the part at this position in parts_list.

Returns:
DNA_part, list of DNA_part, or None

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

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:
partlistlist

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

Returns:
str

Hash string representing the ordered parts list.

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:
partDNA_part or OrderedMonomer

The part to generate a string identifier for.

Returns:
str

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

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:
Construct

A new construct object with reversed parts and directions.

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:
positionint

Index at which to insert the monomer. Must be between 0 and len(polymer) (inclusive).

partOrderedMonomer

The monomer to insert. A copy of this monomer will be added.

directionstr, 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:
constructConstruct

The linear construct to hash.

Returns:
hashstr

String hash of the most alphabetically ordered orientation.

directionint

Direction of the best ordering: 1 for forward, -1 for reverse.

first_positionint

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_listlist of Species

List of species that have position attributes, typically ComplexSpecies that can bind at specific locations.

Returns:
list of dict

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

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:
str

The generated construct name.

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_listslist of dict

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

backboneOrderedPolymerSpecies

The base polymer species serving as the template for creating bound variants.

Returns:
list of OrderedPolymerSpecies

List of polymer species representing all specified combinatorial binding states.

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:
constructConstruct

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

Returns:
hashstr

Canonical hash string with ‘circular’ or ‘linear’ suffix indicating construct topology.

directionint

Direction of the canonical form: 1 for forward, -1 for reverse.

first_positionint

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:
positionint

Index of the monomer to replace. Must be a valid position in the polymer.

partOrderedMonomer

The monomer to insert. A copy of this monomer will be added.

directionstr, 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:
Construct

Returns self after reversing the parts list and flipping directions.

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 <–> 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:
constructConstruct

The circular construct to hash. Should have circular=True.

Returns:
hashstr

String hash of the most alphabetically ordered permutation.

directionint

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

first_positionint

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:
attributeslist 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:
mixtureMixture

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:
speciesSpecies, 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_typestr, optional

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

compartmentCompartment, optional

Compartment to assign to the species. Only used when creating new Species from strings.

attributeslist of str, optional

Attributes to assign to the species. Only used when creating new Species from strings.

Returns:
Species or list of Species

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

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_namestr, optional

Name for the base species. If None, uses the construct’s name.

attributeslist 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_componentslist of Component

Components that generate binding complexes with the construct. Each is assumed to bind at only one position.

Returns:
list of OrderedPolymerSpecies

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

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_parametersbool, 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.

See also

omnihash

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

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.

update_reactions(norna=False)[source]

Generate reactions for the construct.

Parameters:
nornabool, default=False

If True, RNA-related reactions are excluded (used in some subclass implementations).

Returns:
list of Reaction

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

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 of Species

List containing the construct’s primary species representation.

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.

class biocrnpyler.components.dna.construct.DNA_part(name, assembly=None, direction=None, pos=None, sequence=None, no_stop_codons=[], material_type='part', **kwargs)[source]

Base class for individual DNA parts in constructs.

A DNA_part represents a single functional genetic element (promoter, RBS, coding sequence, terminator, etc.) that can be assembled into larger DNA_constructs. Parts have position and direction within constructs and serve as the modular building blocks for synthetic genetic circuits. Unlike full Components, DNA_parts do not have initial concentrations - these must be set on the containing construct or assembly.

Parameters:
namestr

Name of the DNA part.

assemblyDNAassembly or OrderedPolymer, optional

The assembly or construct containing this part.

directionstr, optional

Orientation of the part: ‘forward’ or ‘reverse’.

posint, optional

Position of this part within its parent construct.

sequencestr, optional

DNA sequence of the part (for future sequence-level modeling).

no_stop_codonslist, optional

List of reading frames without stop codons. Used for identifying potential coding sequences. Default is empty list.

material_typestr, default=’part’

Material classification for the part.

**kwargs

Additional keyword arguments passed to Component constructor. Note: ‘initial_concentration’ is not allowed for DNA_parts.

Attributes:
namestr

Name of the part.

sequencestr or None

DNA sequence of the part.

material_typestr

Material classification (‘part’).

no_stop_codonslist

Reading frames without stop codons.

assemblyDNAassembly or None

Reference to containing assembly.

positionint or None

Position within parent construct.

directionstr

Orientation (‘forward’ or ‘reverse’).

Raises:
AttributeError

If ‘initial_concentration’ is provided (not allowed for DNA_parts).

See also

Promoter

DNA_part for transcriptional control.

RBS

DNA_part for translational control.

DNA_construct

Container for multiple DNA_parts.

OrderedMonomer

Base class for positioned elements.

Notes

DNA_parts are the fundamental building blocks of genetic constructs:

  • Modular: Can be reused in different constructs

  • Directional: Support forward and reverse orientations

  • Positional: Track their location within constructs

  • No concentration: Cannot have initial concentrations (only constructs/assemblies can)

The no_stop_codons attribute is used to identify potential open reading frames for translation.

Examples

Create a generic DNA part:

>>> part = bcp.DNA_part(
...     name='regulatory_element',
...     direction='forward'
... )

Create a part with sequence information:

>>> promoter_part = bcp.DNA_part(
...     name='pLac',
...     sequence='ATGCGATCG...',
...     direction='forward'
... )

Use within a construct:

>>> gene_part = bcp.DNA_part(
...    name='GFP',
...    sequence='TGAGTAAAGGAGAAGAA...',
...     direction='forward'
... )
>>> parts = [[promoter_part, 'forward'], [gene_part, 'forward']]
>>> construct = bcp.DNA_construct(parts_list=parts)
__eq__(other)[source]

Test equality between two DNA_parts.

Parts are equal if they have the same type, name, parent assembly/ construct, direction, and position.

Parameters:
otherDNA_part

The other part to compare with.

Returns:
bool

True if parts are equal, False otherwise.

Notes

Equality requires matching:

  1. Type (both must be the same DNA_part subclass)

  2. Name (identical names)

  3. Assembly/parent (same parent construct or both have None)

  4. Direction (both forward or both reverse)

  5. Position (same position in parent construct)

Parts are considered equal even if their parent constructs are different objects, as long as the string representations of the parents match.

__hash__()[source]

Compute hash value for this monomer.

Returns:
int

Hash value based on position, direction, name (if present), and parent.

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:
attributestr

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: Mechanism, mech_type=None, overwrite=False, optional_mechanism=False)[source]

Add a mechanism to this component’s mechanism dictionary.

Parameters:
mechanismMechanism

The mechanism object to add.

mech_typestr, optional

The type key under which to store the mechanism. If None, uses the mechanism’s mechanism_type attribute.

overwritebool, default=False

If True, replaces any existing mechanism with the same key. If False, raises ValueError when key already exists.

optional_mechanismbool, default=False

If True, suppresses the ValueError when a mechanism key conflict occurs and overwrite is False.

Raises:
TypeError

If mechanism is not a Mechanism object, or if mech_type is not a string.

ValueError

If mechanism key already exists, overwrite is False, and optional_mechanism is False.

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:
mechanismsMechanism, 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.

overwritebool, default=False

If True, replaces any existing mechanisms with the same keys. If False, raises ValueError when keys already exist.

optional_mechanismbool, 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.

clone(position, direction, parent_dna)[source]

Attach this part to a specific position in a DNA construct.

Parameters:
positionint

Position in the parent DNA where this part should be placed.

directionstr

Orientation of the part: ‘forward’ or ‘reverse’.

parent_dnaDNA_construct or OrderedPolymer

The DNA construct that will contain this part.

Returns:
DNA_part

Returns self after setting position and parent.

Notes

This method establishes the relationship between a part and its containing construct, setting the part’s position and orientation.

property compartment

Compartment or None: The compartment containing this component.

property dna_species

Species: The chemical species representation of this DNA part.

Returns a Species object with material_type=’part’ representing this DNA_part as a chemical species in the CRN.

enumerate_components(previously_enumerated=None) List[source]

Enumerate derived components created from this component.

This method generates new components based on the current component, typically used during CRN compilation to expand higher-level components into their constituent parts and products.

Parameters:
previously_enumeratedset or list, optional

Collection of components that have already been enumerated, used to prevent infinite recursion in component enumeration.

Returns:
list

List of new components created from this component. This base implementation returns an empty list.

Notes

Subclasses override this method to implement specific enumeration behavior. For example:

  • A DNA_construct returns copies of its parts and RNA_construct objects representing transcripts.

  • An RNA_construct returns copies of its parts and Protein components representing translation products.

find_polymer_component()[source]

Find the polymer component within this monomer or its species.

Searches this monomer and, if it is a ComplexSpecies, its constituent species to find which one is marked as a polymer component.

Returns:
OrderedMonomer or None

The monomer that is part of a polymer structure, or None if no polymer component is found.

Raises:
ValueError

If multiple species are marked as polymer components in the same location.

Notes

This method is primarily used internally to handle complex species that may contain monomers as part of larger structures.

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_typestr

The type identifier of the mechanism to retrieve (e.g., ‘transcription’, ‘translation’, ‘binding’).

optional_mechanismbool, default=False

If True, returns None when mechanism not found. If False, raises KeyError when mechanism not found.

Returns:
Mechanism or None

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

Raises:
TypeError

If mechanism_type is not a string.

KeyError

If mechanism not found and optional_mechanism is False.

get_orphan()[source]

Create a copy of this monomer without a parent reference.

Returns a copy that retains position and direction but has no parent polymer. Useful for temporarily working with monomers outside their polymer context.

Returns:
OrderedMonomer

A copy of this monomer with parent set to None but position and direction preserved.

See also

get_removed

Create a fully detached copy.

remove

Remove this monomer from its parent in place.

Notes

This is a shallow copy of the monomer object itself, though the parent reference is explicitly cleared.

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_namestr

Name of the parameter to retrieve.

part_idstr, optional

Part identifier for the parameter lookup key.

mechanismstr, optional

Mechanism identifier for the parameter lookup key.

return_numericalbool, default=False

If True, returns the numerical value. If False, returns the Parameter object.

return_nonebool, default=False

If True, returns None when parameter not found. If False, raises ValueError when parameter not found.

check_mixturebool, default=True

If True, searches the mixture’s parameter database if not found in the component’s database.

Returns:
Parameter, Real, or None

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

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_removed()[source]

Create a fully detached copy of this monomer.

Returns a copy with all polymer-related attributes (parent, position, direction) cleared. Also removes ‘forward’ and ‘reverse’ attributes if present.

Returns:
OrderedMonomer

A copy of this monomer with no parent, position, or direction, and with directional attributes removed.

See also

get_orphan

Create a copy without parent but with position and direction.

remove

Remove this monomer from its parent in place.

Notes

This method is useful for creating completely independent copies of monomers that can be reused in different contexts without any polymer associations.

get_species() None[source]

Get the primary species associated with this component.

Returns:
None

Subclasses should override this method to return their primary Species object.

Notes

This is a placeholder that should be implemented by subclasses.

monomer_insert(parent: OrderedPolymer, position: int, direction=None)[source]

Insert this monomer into a polymer at a specific position.

Sets the monomer’s parent, position, and direction attributes to reflect its insertion into the polymer. Marks the monomer (or its polymer component if it is a complex species) as a polymer component.

Parameters:
parentOrderedPolymer

The polymer to insert this monomer into.

positionint

The position index where this monomer is being inserted.

directionstr, int, or None, optional

The direction for this monomer. If None, uses the monomer’s existing direction.

Raises:
ValueError

If position is None, or if parent is None.

remove()[source]

Remove this monomer from its parent polymer.

Clears the monomer’s parent, position, and direction attributes, effectively detaching it from any polymer structure.

Returns:
OrderedMonomer

Returns self for method chaining.

See also

get_removed

Create a fully detached copy of the monomer.

get_orphan

Create a copy with parent removed but position and direction preserved.

reverse()[source]

Reverse the orientation of this DNA part.

Flips the direction of the part between ‘forward’ and ‘reverse’.

Returns:
DNA_part

Returns self after reversing direction.

Notes

This method is typically called when a containing construct is reversed, ensuring all parts maintain proper relative orientation.

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:
attributeslist 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_dir(direction)[source]

Set the direction of the monomer and return self.

Convenience method for setting direction in a fluent interface style.

Parameters:
directionstr, int, or None

The direction to assign to this monomer.

Returns:
OrderedMonomer

Returns self for method chaining.

Examples

>>> monomer = bcp.OrderedMonomer().set_dir('forward')
>>> monomer.direction
'forward'
set_mixture(mixture) None[source]

Set the mixture containing this component.

Parameters:
mixtureMixture or None

The mixture object that contains this component and provides default mechanisms and parameters.

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

Convert various inputs into Species objects.

Parameters:
speciesSpecies, 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_typestr, optional

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

compartmentCompartment, optional

Compartment to assign to the species. Only used when creating new Species from strings.

attributeslist of str, optional

Attributes to assign to the species. Only used when creating new Species from strings.

Returns:
Species or list of Species

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

Raises:
ValueError

If the input cannot be converted to a valid Species.

subhash()[source]

Compute hash contribution from monomer properties.

Computes a hash value based on the monomer’s position, direction, and name (if present), excluding the parent reference.

Returns:
int

Hash value based on monomer-specific properties.

Notes

This method is used by __hash__ to compute the monomer’s hash contribution. It excludes the parent to avoid circular dependencies in hash computation.

unclone()[source]

Remove this part from its parent construct.

Detaches the part from any parent construct or assembly, resetting its position and parent references.

Returns:
DNA_part

Returns self after removal from parent.

See also

clone

Attach the part to a construct at a specific position.

Notes

This method calls the remove method from the OrderedMonomer base class to detach the part from its parent polymer structure.

After calling this method, the part becomes “orphaned” and can be attached to a different construct using clone.

update_parameters(parameter_file=None, parameters=None, parameter_database=None, overwrite_parameters=True)[source]

Update the parameter database with new parameters.

Parameters:
parameter_filestr, optional

Path to a CSV or TSV file containing parameters to load.

parametersdict, optional

Dictionary of parameters to add. Keys follow the format (mechanism, part_id, param_name).

parameter_databaseParameterDatabase, optional

Another parameter database to merge into component’s database.

overwrite_parametersbool, default=True

If True, new parameter values overwrite existing ones. If False, existing parameters are preserved.

update_reactions() List[Species][source]

Generate and return reactions associated with this component.

Returns:
list of Reaction

List of reaction objects generated by this component. This base implementation returns an empty list.

Notes

This method should be overridden by subclasses to return the actual reactions generated by the component during CRN compilation.

update_species() List[Species][source]

Generate and return species associated with this component.

Returns:
list of Species

List of species objects generated by this component. This base implementation returns an empty list.

Notes

This method should be overridden by subclasses to return the actual species generated by the component during CRN compilation.

class biocrnpyler.components.dna.construct.RNA_construct(parts_list, name=None, promoter=None, component_enumerators=None, length=0, **kwargs)[source]

RNA construct representing a functional transcript.

An RNA construct represents an RNA molecule that can be translated into proteins. Unlike DNA constructs, RNA constructs can only be linear (not circular) and primarily support translation rather than transcription. This class uses the ‘translation’ mechanism to generate protein products and related species/reactions during CRN compilation.

Parameters:
parts_listlist of list

List of parts in format [[part, direction], …] where parts represent functional RNA elements (RBS sites, coding sequences, etc.).

namestr, optional

Name of the RNA construct. If None, automatically generated.

promoterPromoter, optional

Reference to the promoter that produced this RNA transcript.

component_enumeratorslist, optional

List of enumerators for generating construct variants. Defaults to [TlExplorer()] which explores translational variants.

lengthint, default=0

Length of the RNA molecule in nucleotides.

**kwargs

Additional keyword arguments passed to parent constructors.

Attributes:
material_typestr

Always ‘rna’ for RNA constructs.

promoterPromoter or None

The promoter that controls transcription of this RNA.

lengthint

Length of the RNA transcript.

circularbool

Always False for RNA (RNA cannot be circular).

See also

Construct

Base class for all constructs.

DNA_construct

DNA version of constructs.

TlExplorer

Default enumerator for translational exploration.

RNA

Base class for RNA components.

Notes

RNA_constructs have several key characteristics:

  • Linear only: RNA molecules cannot be circular

  • Translation focus: Primarily generates protein products through translation mechanisms

  • RBS enumeration: Automatically identifies all ribosome binding sites and potential translation products

  • No transcription: RNA cannot be transcribed to produce other RNA

The default TlExplorer enumerator automatically explores all possible translational units in the RNA construct based on RBS positions.

Examples

Create an mRNA with RBS and coding sequence:

>>> rbs1 = bcp.RBS('RBS1')
>>> cds1 = bcp.CDS('GFP')
>>> parts = [[rbs1, 'forward'], [cds1, 'forward']]
>>> mrna = bcp.RNA_construct(
...     parts_list=parts,
...     name='mRNA_GFP'
... )

Create a polycistronic mRNA with multiple RBS-CDS pairs:

>>> rbs2 = bcp.RBS('RBS2')
>>> cds2 = bcp.CDS('RFP')
>>> strong_promoter = bcp.Promoter('pstrong')
>>> parts = [
...     [rbs1, 'forward'], [cds1, 'forward'],
...     [rbs2, 'forward'], [cds2, 'forward']
... ]
>>> polycistronic = bcp.RNA_construct(
...     parts_list=parts,
...     name='mRNA_operon',
...     promoter=strong_promoter
... )
__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:
obj2DNA_part

The part to search for in the construct.

Returns:
bool

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

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:
construct2Construct

The other construct to compare with.

Returns:
bool

True if constructs are equal, False otherwise.

See also

omnihash

Compute canonical hash accounting for rotation and direction.

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.

__getitem__(ii)[source]

Get a monomer or slice of monomers from the polymer.

Parameters:
iiint or slice

Index or slice to retrieve from the polymer.

Returns:
OrderedMonomer or tuple

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

__hash__()[source]

Return hash(self).

__len__()[source]

Return the number of monomers in the polymer.

Returns:
int

The number of monomers in the polymer sequence.

__setitem__(ii, val)[source]

Replace a monomer at a specific position.

Parameters:
iiint

Index at which to replace the monomer.

valOrderedMonomer

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:
attributestr

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:
mechanismMechanism

The mechanism object to add.

mech_typestr, optional

The mechanism type key. If None, uses the mechanism’s mechanism_type attribute.

overwritebool, default=False

If True, overwrites existing mechanisms with the same type. If False, raises ValueError for duplicate types.

optional_mechanismbool, 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:
mechanismsMechanism, 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.

overwritebool, default=False

If True, replaces any existing mechanisms with the same keys. If False, raises ValueError when keys already exist.

optional_mechanismbool, 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:
partOrderedMonomer

The monomer to append. A copy of this monomer will be added.

directionstr, 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:
list of Component

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

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> –> <[A:RNAP],B,C>

  • A component binding to <A,[B:RNAP],C> –> <[A:RNAP],[B:RNAP],C>

  • B component binding to <A,B,C> –> <A,[B:RNAP],C>

  • B component binding to <[A:RNAP],B,C> –> <[A:RNAP],[B:RNAP],C>

This ensures proper reaction enumeration for all binding combinations.

property compartment

Compartment or None: The compartment containing this component.

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:
constructConstruct

The construct to reverse.

Returns:
Construct

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

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:
positionint

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:
dirnamestr, int, or None

The direction to invert. Supported values:

  • ‘forward’ <–> ‘reverse’

  • 0 <–> 1

  • None -> None

Returns:
str, int, or None

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

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:
constructConstruct

The circular construct to hash.

Returns:
hashstr

String hash of the most alphabetically ordered permutation in either direction.

directionint

Direction of the best ordering: 1 for forward, -1 for reverse.

first_positionint

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_enumeratedset or list, optional

Collection of components already enumerated, used to prevent infinite recursion.

Returns:
list of Component

All new components and constructs generated, including:

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

  • Components for combinatorial binding states

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> –> <[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_enumeratedset or list, optional

Collection of constructs that have already been enumerated, used to prevent infinite recursion and duplicate enumeration.

Returns:
list of Construct

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

See also

TxExplorer

Default enumerator for DNA transcription exploration.

TlExplorer

Default enumerator for RNA translation exploration.

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.

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_positionint

The index of the part that should become the first position in the new construct.

Returns:
DNA_construct

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

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_typestr

The type identifier of the mechanism to retrieve (e.g., ‘transcription’, ‘translation’, ‘binding’).

optional_mechanismbool, default=False

If True, returns None when mechanism not found. If False, raises KeyError when mechanism not found.

Returns:
Mechanism or None

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

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_namestr

Name of the parameter to retrieve.

part_idstr, optional

Part identifier for the parameter lookup key.

mechanismstr, optional

Mechanism identifier for the parameter lookup key.

return_numericalbool, default=False

If True, returns the numerical value. If False, returns the Parameter object.

return_nonebool, default=False

If True, returns None when parameter not found. If False, raises ValueError when parameter not found.

check_mixturebool, default=True

If True, searches the mixture’s parameter database if not found in the component’s database.

Returns:
Parameter, Real, or None

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

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:
partDNA_part, optional

A specific DNA_part instance to find. Matches both type and name.

part_typetype, optional

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

namestr, optional

Find part(s) with this exact name.

indexint, optional

Return the part at this position in parts_list.

Returns:
DNA_part, list of DNA_part, or None

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

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:
partlistlist

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

Returns:
str

Hash string representing the ordered parts list.

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:
partDNA_part or OrderedMonomer

The part to generate a string identifier for.

Returns:
str

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

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:
Construct

A new construct object with reversed parts and directions.

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:
positionint

Index at which to insert the monomer. Must be between 0 and len(polymer) (inclusive).

partOrderedMonomer

The monomer to insert. A copy of this monomer will be added.

directionstr, 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:
constructConstruct

The linear construct to hash.

Returns:
hashstr

String hash of the most alphabetically ordered orientation.

directionint

Direction of the best ordering: 1 for forward, -1 for reverse.

first_positionint

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_listlist of Species

List of species that have position attributes, typically ComplexSpecies that can bind at specific locations.

Returns:
list of dict

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

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:
str

The generated construct name.

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_listslist of dict

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

backboneOrderedPolymerSpecies

The base polymer species serving as the template for creating bound variants.

Returns:
list of OrderedPolymerSpecies

List of polymer species representing all specified combinatorial binding states.

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:
constructConstruct

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

Returns:
hashstr

Canonical hash string with ‘circular’ or ‘linear’ suffix indicating construct topology.

directionint

Direction of the canonical form: 1 for forward, -1 for reverse.

first_positionint

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:
positionint

Index of the monomer to replace. Must be a valid position in the polymer.

partOrderedMonomer

The monomer to insert. A copy of this monomer will be added.

directionstr, 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:
Construct

Returns self after reversing the parts list and flipping directions.

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 <–> 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:
constructConstruct

The circular construct to hash. Should have circular=True.

Returns:
hashstr

String hash of the most alphabetically ordered permutation.

directionint

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

first_positionint

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:
attributeslist 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:
mixtureMixture

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:
speciesSpecies, 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_typestr, optional

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

compartmentCompartment, optional

Compartment to assign to the species. Only used when creating new Species from strings.

attributeslist of str, optional

Attributes to assign to the species. Only used when creating new Species from strings.

Returns:
Species or list of Species

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

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_namestr, optional

Name for the base species. If None, uses the construct’s name.

attributeslist 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_componentslist of Component

Components that generate binding complexes with the construct. Each is assumed to bind at only one position.

Returns:
list of OrderedPolymerSpecies

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

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_parametersbool, 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.

See also

omnihash

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

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.

update_reactions(norna=False)[source]

Generate reactions for the construct.

Parameters:
nornabool, default=False

If True, RNA-related reactions are excluded (used in some subclass implementations).

Returns:
list of Reaction

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

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 of Species

List containing the construct’s primary species representation.

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.