biocrnpyler.core.polymer

Polymer support module.

The classes OrderedPolymer and OrderedMonomer are data structures used to represent Polymers and their associated components.

These classes are used by ChemicalReactionNetwork species as well as certain components such as DNA_construct.

Classes

MonomerCollection(monomers)

Collection of ordered monomers without any particular structure.

NamedPolymer(parts, name[, ...])

An OrderedPolymer with an associated name and circularity flag.

OrderedMonomer([direction, position, parent])

A unit that belongs to an OrderedPolymer.

OrderedPolymer(parts[, default_direction])

A polymer made up of OrderedMonomers with a specific order.

class biocrnpyler.core.polymer.MonomerCollection(monomers)[source]

Collection of ordered monomers without any particular structure.

A base container class that holds a collection of OrderedMonomer objects without imposing any ordering or structural constraints. This class serves as a parent class for more structured polymer representations like OrderedPolymer.

Parameters:
monomerslist of OrderedMonomer

List of OrderedMonomer objects to include in the collection. Each monomer is copied and linked to this collection as its parent.

Attributes:
monomerstuple of OrderedMonomer

Tuple containing copies of the input monomers, with each monomer’s parent set to this collection.

See also

OrderedPolymer

A polymer with ordered monomers and directionality.

OrderedMonomer

A unit that can belong to a MonomerCollection.

Notes

Monomers are stored as a tuple (immutable) to prevent direct modification. Each monomer is copied during initialization to ensure the collection maintains its own references.

Examples

Create a collection of monomers:

>>> mon1 = bcp.OrderedMonomer()
>>> mon2 = bcp.OrderedMonomer()
>>> collection = bcp.MonomerCollection([mon1, mon2])
>>> len(collection.monomers)
2
class biocrnpyler.core.polymer.NamedPolymer(parts, name, default_direction=None, circular=False)[source]

An OrderedPolymer with an associated name and circularity flag.

Extends OrderedPolymer to include a name identifier and optional circular topology flag. Commonly used to represent named biological constructs like plasmids, chromosomes, or specific DNA/RNA sequences.

Parameters:
partslist or tuple

Sequence of parts to add to the polymer. See OrderedPolymer for format details.

namestr

Name identifier for the polymer.

default_directionstr, int, or None, optional

Default direction for monomers when not explicitly specified.

circularbool, default=False

If True, indicates the polymer has circular topology (e.g., a plasmid). If False, the polymer is linear.

Attributes:
namestr

Name identifier for the polymer.

circularbool

Flag indicating circular (True) or linear (False) topology.

polymertuple of OrderedMonomer

Ordered tuple of monomers in this polymer (inherited).

default_directionstr, int, or None

Default direction for monomers (inherited).

See also

OrderedPolymer

Base class for ordered polymer structures.

OrderedMonomer

A unit that belongs to an OrderedPolymer.

Notes

The circular attribute is primarily informational and does not automatically enforce circular topology constraints in polymer operations. Subclasses or external code must handle circular semantics as needed.

Examples

Create a linear named polymer:

>>> mon1 = bcp.OrderedMonomer()
>>> mon2 = bcp.OrderedMonomer()
>>> polymer = bcp.NamedPolymer(
...     parts=[mon1, mon2],
...     name='my_construct',
...     default_direction='forward'
... )
>>> polymer.name
'my_construct'
>>> polymer.circular
False

Create a circular polymer (plasmid):

>>> plasmid = bcp.NamedPolymer(
...     parts=[mon1, mon2],
...     name='pUC19',
...     circular=True
... )
>>> plasmid.circular
True
__contains__(item)[source]

Check if a monomer is in the polymer.

Parameters:
itemOrderedMonomer

The monomer to search for.

Returns:
bool

True if the monomer is in the polymer, False otherwise.

__eq__(other)[source]

Check equality with another OrderedPolymer.

Two polymers are equal if they have the same length and each corresponding pair of monomers has the same direction, position, and type.

Parameters:
otherOrderedPolymer

The polymer to compare with.

Returns:
bool

True if polymers are equal, False otherwise.

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

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]

Callback method invoked whenever the polymer structure changes.

This method is called after operations that modify the polymer, such as insert, replace, delpart, or reverse. Subclasses can override this to implement custom behavior when the polymer is modified.

Notes

The base implementation does nothing. Override in subclasses to add functionality like name regeneration, validation, or notifications.

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

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.

reverse()[source]

Reverse the order and directions of all monomers in the polymer.

Reverses the polymer sequence and inverts the direction of each monomer. Updates all monomer positions to reflect their new locations. Calls the changed callback after reversal.

Notes

This operation modifies the polymer in place. All monomers have their directions inverted using direction_invert and their positions updated to match the reversed sequence.

Examples

>>> mon1 = bcp.OrderedMonomer()
>>> mon2 = bcp.OrderedMonomer()
>>> polymer = bcp.OrderedPolymer(
...     parts=[[mon1, 'forward'], [mon2, 'reverse']]
... )
>>> polymer.reverse()
>>> polymer[0].direction
'forward'
>>> polymer[1].direction
'reverse'
class biocrnpyler.core.polymer.OrderedMonomer(direction=None, position=None, parent=None)[source]

A unit that belongs to an OrderedPolymer.

Represents a single monomer unit within a polymer structure. Each monomer tracks its position in the polymer, its directional orientation, and maintains a reference to its parent polymer. This class is used as a base for representing DNA parts, RNA components, amino acids, and other polymer building blocks.

Parameters:
directionstr, int, or None, optional

Directional orientation of the monomer in the polymer. Common values include ‘forward’, ‘reverse’, 0, 1, or None. Default is None.

positionint or None, optional

Index position of the monomer within its parent polymer. Must be non-None if the monomer belongs to a polymer. Default is None.

parentMonomerCollection or None, optional

Reference to the parent MonomerCollection or OrderedPolymer containing this monomer. Default is None.

Attributes:
directionstr, int, or None

Directional orientation of the monomer.

positionint or None

Position index within the parent polymer.

parentMonomerCollection or None

Reference to the parent collection or polymer.

is_polymer_componentbool

Flag indicating whether this monomer is part of a polymer structure. Set to True when inserted into a polymer.

See also

OrderedPolymer

A polymer made up of OrderedMonomers.

MonomerCollection

Base class for monomer collections.

Notes

OrderedMonomers are deep-copied when inserted into polymers to ensure independence. Use get_orphan to create a copy without a parent reference, or get_removed to create a fully detached copy.

The is_polymer_component flag and find_polymer_component method support scenarios where monomers may be nested within complex species.

Examples

Create a standalone monomer:

>>> monomer = bcp.OrderedMonomer(direction='forward')
>>> monomer.direction
'forward'
>>> monomer.parent is None
True

Add a monomer to a polymer:

>>> polymer = bcp.OrderedPolymer(parts=[])
>>> monomer = bcp.OrderedMonomer()
>>> polymer.append(monomer, direction='forward')
>>> polymer[0].position
0
>>> polymer[0].parent is polymer
True
__eq__(other)[source]

Check equality with another OrderedMonomer.

Two monomers are equal if they have the same direction, position, and parent.

Parameters:
otherOrderedMonomer

The monomer to compare with.

Returns:
bool

True if monomers are equal, False otherwise.

__hash__()[source]

Compute hash value for this monomer.

Returns:
int

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

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

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.

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

class biocrnpyler.core.polymer.OrderedPolymer(parts, default_direction=None)[source]

A polymer made up of OrderedMonomers with a specific order.

Represents a linear sequence of monomers where each monomer has a defined position and direction. This class extends MonomerCollection to provide ordered, directional polymer structures commonly used to represent DNA constructs, RNA sequences, and protein chains.

Parameters:
partslist or tuple

Sequence of parts to add to the polymer. Each element can be:

  • An OrderedMonomer object (uses existing direction)

  • A list/tuple [OrderedMonomer, direction] specifying monomer and its direction explicitly

default_directionstr or int, optional

Default direction for monomers when not explicitly specified. Common values include ‘forward’, ‘reverse’, 0, 1, or None.

Attributes:
polymertuple of OrderedMonomer

Ordered tuple of monomers in this polymer. Alias for monomers property inherited from MonomerCollection.

default_directionstr, int, or None

Default direction assigned to monomers lacking explicit direction.

See also

NamedPolymer

An OrderedPolymer with an associated name.

OrderedMonomer

A unit that belongs to an OrderedPolymer.

MonomerCollection

Base class for monomer collections.

Notes

Directions indicate the orientation of monomers in the polymer:

  • ‘forward’ or 0: Standard/positive orientation

  • ‘reverse’ or 1: Inverted/negative orientation

  • None: No specified orientation

The polymer tuple is immutable, but monomers can be added via insert, append, or replace methods. Direct assignment to positions uses __setitem__ which calls replace.

All monomers are deep-copied when added to ensure the polymer maintains independent references. This prevents external modifications from affecting the polymer structure.

Examples

Create a polymer from monomers:

>>> mon1 = bcp.OrderedMonomer()
>>> mon2 = bcp.OrderedMonomer()
>>> polymer = bcp.OrderedPolymer(
...     parts=[mon1, mon2],
...     default_direction='forward'
... )
>>> len(polymer)
2

Create a polymer with explicit directions:

>>> polymer = bcp.OrderedPolymer(
...     parts=[[mon1, 'forward'], [mon2, 'reverse']]
... )
>>> polymer[0].direction
'forward'
>>> polymer[1].direction
'reverse'
__contains__(item)[source]

Check if a monomer is in the polymer.

Parameters:
itemOrderedMonomer

The monomer to search for.

Returns:
bool

True if the monomer is in the polymer, False otherwise.

__eq__(other)[source]

Check equality with another OrderedPolymer.

Two polymers are equal if they have the same length and each corresponding pair of monomers has the same direction, position, and type.

Parameters:
otherOrderedPolymer

The polymer to compare with.

Returns:
bool

True if polymers are equal, False otherwise.

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

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]

Callback method invoked whenever the polymer structure changes.

This method is called after operations that modify the polymer, such as insert, replace, delpart, or reverse. Subclasses can override this to implement custom behavior when the polymer is modified.

Notes

The base implementation does nothing. Override in subclasses to add functionality like name regeneration, validation, or notifications.

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

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.

reverse()[source]

Reverse the order and directions of all monomers in the polymer.

Reverses the polymer sequence and inverts the direction of each monomer. Updates all monomer positions to reflect their new locations. Calls the changed callback after reversal.

Notes

This operation modifies the polymer in place. All monomers have their directions inverted using direction_invert and their positions updated to match the reversed sequence.

Examples

>>> mon1 = bcp.OrderedMonomer()
>>> mon2 = bcp.OrderedMonomer()
>>> polymer = bcp.OrderedPolymer(
...     parts=[[mon1, 'forward'], [mon2, 'reverse']]
... )
>>> polymer.reverse()
>>> polymer[0].direction
'forward'
>>> polymer[1].direction
'reverse'