circuitree.models.DimersGrammar

class circuitree.models.DimersGrammar(components: Iterable[str], regulators: Iterable[str], interactions: Iterable[str], max_interactions: int | None = None, max_interactions_per_promoter: int = 2, *args, **kwargs)

(Experimental) A grammar class for the design space of dimerizing TF networks. Intended to represent dimerizing regulatory networks such as the MultiFate system.

Each circuit consists of transcriptional components and regulators. Components are TFs that may be regulated by other TFs, while regulators are TFs that are never regulated themselves. Any pair of components or regulators could potentially form a dimer to regulate a third component. Therefore, each interaction in this circuit is a “triplet” of two monomer TFs and a target TF.

The state ID string for a circuit topology is similar to SimpleNetworkGrammar, with some modifications.

  • Components and regulators are represented by single uppercase characters

  • Interactions are represented by a 4-character string
    • Characters 1-2 (uppercase): the dimerizing species (components and/or regulators). Order does not matter.

    • Character 3 (lowercase): the type of regulation upon binding (for example, a for activation)

    • Character 4 (uppercase): the target of regulation (a component)

  • Multiple interactions are separated by underscores _

  • The state is a three-part string: <components>+<regulators>::<interactions>

  • A terminal assembly state is denoted with a leading asterisk *

For example, the state string *AB+R::ARiB_BBaB represents a system of three TFs, A, B, and R where A-R heterodimers inhibit transcription of B and B-B homodimers activate transcription of B. The asterisk * at the beginning means that the assembly process has finished.

The number of distinct dimers that can regulate a given component is limited using the max_interactions_per_promoter argument (default of 2), and the total number of interactions in the circuit is limited by the max_interactions argument (no limit by default).

__init__(components: Iterable[str], regulators: Iterable[str], interactions: Iterable[str], max_interactions: int | None = None, max_interactions_per_promoter: int = 2, *args, **kwargs)

Methods

__init__(components, regulators, interactions)

do_action(genotype, action)

Given a state and an action, return the new state that results.

get_actions(genotype)

Returns the actions that can be taken from a given state, or genotype.

get_genotype_parts(genotype)

Parses the state string (genotype) into its three parts: components, regulators, and interactions.

get_undo_actions(state)

(Experimental) Get all actions that can be undone from the given state.

get_unique_state(genotype)

Returns a unique representation of a given state.

has_pattern(state, pattern)

Checks if a given state contains a particular sub-pattern.

is_terminal(genotype)

Checks if the given assembly state (genotype) is a terminal state.

parse_genotype(genotype)

Parses a genotype string into its components, regulators, activation interactions, and inhibition interactions.

to_dict()

Convert the grammar to a dictionary that can be serialized to JSON.

undo_action(state, action)

(Experimental) Undo one action from the given state.

Attributes

dimer_options

List of possible dimers (two-character codes) of components and regulators.

edge_options

List-of-list of all possible 4-character interactions.

do_action(genotype: str, action: str) str

Given a state and an action, return the new state that results. Should be deterministic. The resulting state ID does not need to be unique (for example, it may not take symmetries into account).

Parameters:
  • state (Hashable) – The current state of the game.

  • action (Any) – The action to take.

Returns:

The new state.

Return type:

Hashable

get_actions(genotype: str) Iterable[str]

Returns the actions that can be taken from a given state, or genotype.

Possible actions include adding a new component/regulator, adding a new interaction between a dimer and a target component, or terminating the assembly process. Checks to make sure the necessary pieces are present and the circuit would remain fully connected after taking the action.

Parameters:

genotype (str) – The current state of the circuit assembly.

Returns:

A list of valid actions that can be taken. Each action is a 4-character code.

Return type:

Iterable[str]

static get_genotype_parts(genotype: str) tuple[str, str, str]

Parses the state string (genotype) into its three parts: components, regulators, and interactions.

Parameters:

genotype (str) – An assembly state.

Returns:

the components, regulators, and interactions in the state.

Return type:

tuple[str, str, str]

get_undo_actions(state: Hashable) Iterable[Any]

(Experimental) Get all actions that can be undone from the given state.

get_unique_state(genotype: str) str

Returns a unique representation of a given state.

This method is used to determine whether two state IDs represent the same topology, after accounting for

  • Reording of the interactions

  • Renaming of components and regulators (swapping labels)

For example, different sequences of actions may lead to different state IDs that are isomorphic mirror images, or “recolorings” of each other. This method picks the alphabetically first representation over all possible recolorings.

Parameters:

genotype (str) – The current state.

Returns:

The unique representation of the state.

Return type:

str

static has_pattern(state, pattern)

Checks if a given state contains a particular sub-pattern.

This method checks if the interactions in the given pattern are a subset of the interactions in the given state, taking into account all possible renamings of components and regulators. The pattern should be a string that contains only interactions (separated by underscores).

Parameters:
  • state (str) – The current state.

  • pattern (str) – The sub-pattern to search for.

Returns:

Whether the state contains the given pattern.

Return type:

bool

Raises:
  • ValueError – If the pattern is empty or contains components/regulators or if

  • the state does not contain both components and interactions.

static is_terminal(genotype: str) bool

Checks if the given assembly state (genotype) is a terminal state. A terminal state starts with an asterisk *.

Parameters:

genotype (str) – An assembly state.

Returns:

Whether the state is terminal.

Return type:

bool

static parse_genotype(genotype: str)

Parses a genotype string into its components, regulators, activation interactions, and inhibition interactions.

Parameters:

genotype (str) – The genotype string to parse.

Returns:

The components, regulators, activations, and inhibitions. Components and regulators are provided as strings. The activations and inhibitions are represented as NumPy arrays with three columns, the indices of the two monomers involved in the interaction and the index of the target TF. The indices are determined by concatenating components and regulators.

Return type:

tuple[str, str, np.ndarray, np.ndarray]

to_dict() dict

Convert the grammar to a dictionary that can be serialized to JSON. Useful for saving the grammar to a file or for transferring it over a network.

The __grammar_cls__ key is added to the dictionary to indicate the name of the class that should be used to re-instantiate the grammar.

Returns:

A dictionary representation of the grammar.

Return type:

dict

undo_action(state: Hashable, action: Any) Hashable

(Experimental) Undo one action from the given state.

property dimer_options

List of possible dimers (two-character codes) of components and regulators.

property edge_options

List-of-list of all possible 4-character interactions. The first level of the list is the triplet (which dimer regulating which target), and the second level is the nature of the regulation.