synbio-buildcompiler 0.0b1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Genetic Logic Lab
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,79 @@
1
+ Metadata-Version: 2.4
2
+ Name: synbio_buildcompiler
3
+ Version: 0.0b1
4
+ Summary: BuildCompiler is a package to decouple the design and build stages
5
+ Author-email: Gonzalo Vidal <gonzalo.vidalpena@colorado.edu>, Ryan Greer <ryan.greer@colorado.edu>
6
+ Maintainer-email: Ryan Greer <ryan.greer@colorado.edu>
7
+ Project-URL: Homepage, https://github.com/MyersResearchGroup/BuildCompiler
8
+ Project-URL: Bug Tracker, https://github.com/MyersResearchGroup/BuildCompiler/issues
9
+ Keywords: SBOL,genetic,automation,build,synthetic biology
10
+ Classifier: Programming Language :: Python :: 3
11
+ Classifier: License :: OSI Approved :: MIT License
12
+ Classifier: Operating System :: OS Independent
13
+ Requires-Python: >=3.10
14
+ Description-Content-Type: text/markdown
15
+ License-File: LICENSE
16
+ Requires-Dist: sbol2
17
+ Requires-Dist: biopython
18
+ Requires-Dist: pydna
19
+ Provides-Extra: test
20
+ Requires-Dist: pytest<5.0.0; extra == "test"
21
+ Requires-Dist: pytest-cov[all]; extra == "test"
22
+ Dynamic: license-file
23
+
24
+ # BuildCompiler
25
+ BuildCompiler is an open-source tool that bridges the Design and Build stages of the DBTL cycle by compiling SBOL-encoded genetic designs into executable DNA assembly and transformation workflows.
26
+
27
+ It was developed to support build functionality in comand line and cloud workflows in [SynBioSuite](https://synbiosuite.org), based off the [SBOL Best Practices](https://github.com/SynBioDex/SBOL-examples/tree/main/SBOL/best-practices/BP011/).
28
+
29
+ <img src="https://github.com/MyersResearchGroup/BuildCompiler/blob/main/images/buildcompiler_logo.png#gh-light-mode-only" alt="BuildCompiler light logo" width="300"/>
30
+ <img src="https://github.com/MyersResearchGroup/BuildCompiler/blob/main/images/buildcompiler_logo.png#gh-dark-mode-only" alt="BuildCompiler night logo" width="300"/>
31
+
32
+ ![PyPI - Version](https://img.shields.io/pypi/v/sbol2build)
33
+ [![Documentation Status](https://readthedocs.org/projects/sbol2build/badge/?version=latest)](https://sbol2build.readthedocs.io/en/latest/?badge=latest)
34
+ ![PyPI - Python Version](https://img.shields.io/pypi/pyversions/sbol2build)
35
+ ![PyPI - License](https://img.shields.io/pypi/l/sbol2build)
36
+ ![gh-action badge](https://github.com/MyersResearchGroup/sbol2build/workflows/Python%20package/badge.svg)
37
+
38
+ ## Installing BuildCompiler:
39
+ ```pip install buildcompiler```
40
+
41
+ ## Documentation
42
+
43
+ Please visit the documentation with API reference and tutorials at Read the Docs: [sbol2build.rtfd.io](https://sbol2build.readthedocs.io)
44
+
45
+ ## Environment Setup
46
+
47
+ If you are interested in contributing to **BuildCompiler**, please set up your local development environment with the same tools used in CI and linting.
48
+
49
+ ### 1. Install [uv](https://docs.astral.sh/uv/)
50
+
51
+ `uv` manages all Python dependencies (including dev tools) with a lockfile for reproducibility.
52
+
53
+ #### Linux/Bash
54
+ ```bash
55
+ curl -LsSf https://astral.sh/uv/install.sh | sh
56
+ ```
57
+ #### Mac OSX with Homebrew
58
+ ```bash
59
+ brew install uv
60
+ ```
61
+ ### 2. Sync dependencies
62
+ ```bash
63
+ uv sync --all-groups
64
+ ```
65
+ This will create a virtual environment with the dependiencies. Activate using:
66
+ ```bash
67
+ source .venv/bin/activate
68
+ ```
69
+
70
+ ### 3. Install pre-commit hooks
71
+ We use pre-commit to automatically run the Ruff linter before every commit.
72
+ Install and enable the hooks with:
73
+ ```bash
74
+ uv run pre-commit install
75
+ ```
76
+
77
+
78
+ #### Running tests:
79
+ `uv run python -m unittest discover -s tests`
@@ -0,0 +1,56 @@
1
+ # BuildCompiler
2
+ BuildCompiler is an open-source tool that bridges the Design and Build stages of the DBTL cycle by compiling SBOL-encoded genetic designs into executable DNA assembly and transformation workflows.
3
+
4
+ It was developed to support build functionality in comand line and cloud workflows in [SynBioSuite](https://synbiosuite.org), based off the [SBOL Best Practices](https://github.com/SynBioDex/SBOL-examples/tree/main/SBOL/best-practices/BP011/).
5
+
6
+ <img src="https://github.com/MyersResearchGroup/BuildCompiler/blob/main/images/buildcompiler_logo.png#gh-light-mode-only" alt="BuildCompiler light logo" width="300"/>
7
+ <img src="https://github.com/MyersResearchGroup/BuildCompiler/blob/main/images/buildcompiler_logo.png#gh-dark-mode-only" alt="BuildCompiler night logo" width="300"/>
8
+
9
+ ![PyPI - Version](https://img.shields.io/pypi/v/sbol2build)
10
+ [![Documentation Status](https://readthedocs.org/projects/sbol2build/badge/?version=latest)](https://sbol2build.readthedocs.io/en/latest/?badge=latest)
11
+ ![PyPI - Python Version](https://img.shields.io/pypi/pyversions/sbol2build)
12
+ ![PyPI - License](https://img.shields.io/pypi/l/sbol2build)
13
+ ![gh-action badge](https://github.com/MyersResearchGroup/sbol2build/workflows/Python%20package/badge.svg)
14
+
15
+ ## Installing BuildCompiler:
16
+ ```pip install buildcompiler```
17
+
18
+ ## Documentation
19
+
20
+ Please visit the documentation with API reference and tutorials at Read the Docs: [sbol2build.rtfd.io](https://sbol2build.readthedocs.io)
21
+
22
+ ## Environment Setup
23
+
24
+ If you are interested in contributing to **BuildCompiler**, please set up your local development environment with the same tools used in CI and linting.
25
+
26
+ ### 1. Install [uv](https://docs.astral.sh/uv/)
27
+
28
+ `uv` manages all Python dependencies (including dev tools) with a lockfile for reproducibility.
29
+
30
+ #### Linux/Bash
31
+ ```bash
32
+ curl -LsSf https://astral.sh/uv/install.sh | sh
33
+ ```
34
+ #### Mac OSX with Homebrew
35
+ ```bash
36
+ brew install uv
37
+ ```
38
+ ### 2. Sync dependencies
39
+ ```bash
40
+ uv sync --all-groups
41
+ ```
42
+ This will create a virtual environment with the dependiencies. Activate using:
43
+ ```bash
44
+ source .venv/bin/activate
45
+ ```
46
+
47
+ ### 3. Install pre-commit hooks
48
+ We use pre-commit to automatically run the Ruff linter before every commit.
49
+ Install and enable the hooks with:
50
+ ```bash
51
+ uv run pre-commit install
52
+ ```
53
+
54
+
55
+ #### Running tests:
56
+ `uv run python -m unittest discover -s tests`
@@ -0,0 +1,45 @@
1
+ [build-system]
2
+ requires = ["setuptools>=61.0"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "synbio_buildcompiler"
7
+ version = "0.0.b1"
8
+ description = "BuildCompiler is a package to decouple the design and build stages"
9
+ readme = "README.md"
10
+ requires-python = ">=3.10"
11
+ license = {file = "LICENSE.md"}
12
+ keywords = ["SBOL", "genetic", "automation", "build", "synthetic biology"]
13
+ authors = [
14
+ { name="Gonzalo Vidal", email="gonzalo.vidalpena@colorado.edu" },
15
+ { name="Ryan Greer", email="ryan.greer@colorado.edu" }
16
+ ]
17
+ maintainers = [
18
+ { name = "Ryan Greer", email = "ryan.greer@colorado.edu" }
19
+ ]
20
+ classifiers = [
21
+ "Programming Language :: Python :: 3",
22
+ "License :: OSI Approved :: MIT License",
23
+ "Operating System :: OS Independent",
24
+ ]
25
+
26
+ dependencies = [
27
+ "sbol2",
28
+ "biopython",
29
+ "pydna"
30
+ ]
31
+
32
+ [project.optional-dependencies]
33
+ test = [
34
+ "pytest < 5.0.0",
35
+ "pytest-cov[all]"
36
+ ]
37
+
38
+ [project.urls]
39
+ "Homepage" = "https://github.com/MyersResearchGroup/BuildCompiler"
40
+ "Bug Tracker" = "https://github.com/MyersResearchGroup/BuildCompiler/issues"
41
+
42
+ [dependency-groups]
43
+ dev = [
44
+ "ruff>=0.14.0",
45
+ ]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1 @@
1
+ from .sbol2build import * # noqa: F403
@@ -0,0 +1,346 @@
1
+ import sbol2
2
+ import itertools
3
+ from typing import Dict, List, Union
4
+ from .constants import FUSION_SITES
5
+
6
+
7
+ class MocloPlasmid:
8
+ def __init__(
9
+ self, name: str, definition: sbol2.ComponentDefinition, doc: sbol2.document
10
+ ):
11
+ self.definition = definition
12
+ self.fusion_sites = self.match_fusion_sites(doc)
13
+ self.name = name + "".join(f"_{s}" for s in self.fusion_sites)
14
+
15
+ def match_fusion_sites(self, doc: sbol2.document) -> List[str]:
16
+ fusion_site_definitions = extract_fusion_sites(self.definition, doc)
17
+ fusion_sites = []
18
+ for site in fusion_site_definitions:
19
+ sequence_obj = doc.getSequence(site.sequences[0])
20
+ sequence = sequence_obj.elements
21
+
22
+ for key, seq in FUSION_SITES.items():
23
+ if seq == sequence.upper():
24
+ fusion_sites.append(key)
25
+
26
+ fusion_sites.sort()
27
+ return fusion_sites
28
+
29
+ def __repr__(self) -> str:
30
+ return (
31
+ f"MocloPlasmid:\n"
32
+ f" Name: {self.name}\n"
33
+ f" Definition: {self.definition.identity}\n"
34
+ f" Fusion Sites: {self.fusion_sites or 'Not found'}"
35
+ )
36
+
37
+ def __eq__(self, other):
38
+ if not isinstance(other, MocloPlasmid):
39
+ return False
40
+ return self.definition == other.definition
41
+
42
+ def __hash__(self):
43
+ return hash(self.definition)
44
+
45
+
46
+ def extract_fusion_sites(
47
+ plasmid: sbol2.ComponentDefinition, doc: sbol2.Document
48
+ ) -> List[sbol2.ComponentDefinition]:
49
+ """
50
+ Returns all fusion site component definitions from a plasmid.
51
+
52
+ Args:
53
+ plasmid: :class:`sbol2.ComponentDefinition` representing the plasmid.
54
+ doc: :class:`sbol2.Document` containing component definitions.
55
+
56
+ Returns:
57
+ A list of fusion site component definitions.
58
+ """
59
+ fusion_sites = []
60
+ for component in plasmid.components:
61
+ definition = doc.getComponentDefinition(component.definition)
62
+ if "http://identifiers.org/so/SO:0001953" in definition.roles:
63
+ fusion_sites.append(definition)
64
+
65
+ return fusion_sites
66
+
67
+
68
+ def extract_design_parts(
69
+ design: sbol2.ComponentDefinition, doc: sbol2.Document
70
+ ) -> List[sbol2.ComponentDefinition]:
71
+ """
72
+ Returns definitions of parts in a design in sequential order.
73
+
74
+ Args:
75
+ design: :class:`sbol2.ComponentDefinition` to extract parts from.
76
+ doc: :class:`sbol2.Document` containing all component definitions.
77
+
78
+ Returns:
79
+ A list of component definitions in sequential order.
80
+ """
81
+ component_list = [c for c in design.getInSequentialOrder()]
82
+ return [
83
+ doc.getComponentDefinition(component.definition) for component in component_list
84
+ ]
85
+
86
+
87
+ def copy_sequences(component_definition, target_doc, collection_doc):
88
+ """Copy all sequences referenced by a ComponentDefinition into target_doc."""
89
+ subdefinitions = extract_design_parts(component_definition, collection_doc)
90
+
91
+ for seq_uri in component_definition.sequences:
92
+ seq_obj = component_definition.doc.find(seq_uri)
93
+ if seq_obj is not None:
94
+ seq_obj.copy(target_doc)
95
+
96
+ for subdefinition in subdefinitions:
97
+ print(subdefinition.displayId)
98
+ subdefinition.copy(target_doc)
99
+ for seq_uri in subdefinition.sequences:
100
+ seq_obj = component_definition.doc.find(seq_uri)
101
+ if seq_obj is not None:
102
+ seq_obj.copy(target_doc)
103
+
104
+
105
+ def extract_combinatorial_design_parts(
106
+ design: sbol2.ComponentDefinition, doc: sbol2.Document, plasmid_doc
107
+ ) -> Dict[str, List[sbol2.ComponentDefinition]]:
108
+ """
109
+ Extracts and returns a mapping of component definitions from a combinatorial design, in order.
110
+ Variants of combinatinatorial components are entered in a list corresponding to the URI of the component in the abstract design.
111
+
112
+ Args:
113
+ design:
114
+ The :class:`sbol2.ComponentDefinition` representing the top-level design
115
+ from which to extract parts.
116
+ doc:
117
+ The primary :class:`sbol2.Document` containing the base component definitions
118
+ and combinatorial derivations.
119
+ plasmid_doc:
120
+ An additional :class:`sbol2.Document` used to resolve component variants
121
+ (plasmid-specific variants referenced by combinatorial derivations).
122
+
123
+ Returns:
124
+ Dict[str, List[sbol2.ComponentDefinition]]:
125
+ A dictionary mapping component identities to lists
126
+ of variable component definitions.
127
+
128
+ - Sequential design components map to lists containing a single definition.
129
+ - Combinatorial variable components map to lists of variant definitions.
130
+ """
131
+ component_list = [c for c in design.getInSequentialOrder()]
132
+ component_dict = {
133
+ component.identity: [doc.getComponentDefinition(component.definition)]
134
+ for component in component_list
135
+ }
136
+
137
+ for deriv in doc.combinatorialderivations:
138
+ for component in deriv.variableComponents:
139
+ component_dict[component.variable] = [
140
+ plasmid_doc.getComponentDefinition(var) for var in component.variants
141
+ ]
142
+
143
+ return component_dict
144
+
145
+
146
+ def extract_toplevel_definition(doc: sbol2.Document) -> sbol2.ComponentDefinition:
147
+ return doc.componentDefinitions[0]
148
+
149
+
150
+ def enumerate_design_variants(component_dict):
151
+ """
152
+ Given a dict mapping variable component identities to lists of ComponentDefinitions,
153
+ generate all possible design combinations as lists of ComponentDefinitions
154
+ (in consistent order of keys).
155
+ """
156
+ keys = list(component_dict.keys())
157
+ variant_lists = [component_dict[k] for k in keys]
158
+
159
+ # Cartesian product across all variant lists
160
+ all_variants = list(itertools.product(*variant_lists))
161
+
162
+ all_variants = [list(combo) for combo in all_variants]
163
+
164
+ return all_variants
165
+
166
+
167
+ def construct_plasmid_dict(
168
+ part_list: List[sbol2.ComponentDefinition], plasmid_collection: sbol2.Document
169
+ ) -> Dict[str, List[MocloPlasmid]]:
170
+ """
171
+ Builds a mapping from part display IDs to lists of compatible MoCloPlasmid objects.
172
+
173
+ For each part in the given list, this function searches the provided plasmid
174
+ collection for plasmids that contain the part as a component.
175
+ Each matching plasmid is wrapped in a `MocloPlasmid` object and added to the
176
+ dictionary under the part's display ID.
177
+
178
+ Args:
179
+ part_list:
180
+ List of :class:`sbol2.ComponentDefinition` objects representing
181
+ the parts to match.
182
+ plasmid_collection:
183
+ The :class:`sbol2.Document` containing plasmids to search through.
184
+
185
+ Returns:
186
+ Dict[str, List[MocloPlasmid]]:
187
+ A dictionary mapping each part display ID to a list of corresponding
188
+ `MocloPlasmid` objects found in the collection.
189
+ """
190
+ plasmid_dict = {}
191
+ for part in part_list:
192
+ for plasmid in plasmid_collection.componentDefinitions:
193
+ if "http://identifiers.org/so/SO:0000637" in plasmid.roles:
194
+ for component in plasmid.components:
195
+ if (
196
+ component.definition == str(part)
197
+ ): # TODO make sure this is not a composite plasmid, i.e. plasmid just contains singular part of interest
198
+ fusion_sites = [
199
+ site.name
200
+ for site in extract_fusion_sites(
201
+ plasmid, plasmid_collection
202
+ )
203
+ ]
204
+ print(
205
+ f"found: {component.definition} in {plasmid} with {fusion_sites}"
206
+ ) # TODO switch to logger for backend tracing?
207
+ plasmid_dict.setdefault(part.displayId, [])
208
+
209
+ componentName = plasmid_collection.getComponentDefinition(
210
+ component.definition
211
+ ).name
212
+
213
+ plasmid_dict[part.displayId].append(
214
+ MocloPlasmid(componentName, plasmid, plasmid_collection)
215
+ )
216
+
217
+ return plasmid_dict
218
+
219
+
220
+ def get_compatible_plasmids(
221
+ plasmid_dict: Dict[str, List[MocloPlasmid]], backbone: MocloPlasmid
222
+ ) -> List[MocloPlasmid]:
223
+ """
224
+ Returns a list of MocloPlasmid objects that can form a compatible assembly
225
+ with the given backbone plasmid. The function selects one plasmid from each
226
+ entry in the dictionary, ensuring that adjacent plasmids have matching MoClo fusion sites,
227
+ and that the first and last plasmids are compatible with the backbone.
228
+
229
+ Args:
230
+ plasmid_dict: A dictionary mapping assembly positions or categories to lists
231
+ of MocloPlasmid objects.
232
+ backbone: The backbone MocloPlasmid whose fusion sites define compatibility.
233
+
234
+ Returns:
235
+ A list of compatible MocloPlasmid objects forming a sequential assembly.
236
+ """
237
+ selected_plasmids = []
238
+ match_to = backbone
239
+ match_idx = 0
240
+
241
+ for i, key in enumerate(plasmid_dict):
242
+ for plasmid in plasmid_dict[key]:
243
+ if (
244
+ i == len(plasmid_dict) - 1
245
+ and plasmid.fusion_sites[0] == match_to.fusion_sites[match_idx]
246
+ and plasmid.fusion_sites[1] == backbone.fusion_sites[1]
247
+ ):
248
+ print(
249
+ f"matched final component {plasmid.name} with {match_to.name} and {backbone.name} on fusion sites ({plasmid.fusion_sites[0]}, {plasmid.fusion_sites[1]})!"
250
+ )
251
+ selected_plasmids.append(plasmid)
252
+ break
253
+ elif (
254
+ i < len(plasmid_dict) - 1
255
+ and plasmid.fusion_sites[0] == match_to.fusion_sites[match_idx]
256
+ ): # TODO add error handling if no compatible plasmid found
257
+ print(
258
+ f"matched {plasmid.name} with {match_to.name} on fusion site {plasmid.fusion_sites[0]}!"
259
+ )
260
+ selected_plasmids.append(plasmid)
261
+ match_to = plasmid
262
+ match_idx = 1
263
+ break
264
+ # TODO edge case where second fusion site does not match terminator fusion site will not be caught by current logic
265
+ # 10/14: rethink implementation, will likely need to be different for combinatorial designs
266
+
267
+ return selected_plasmids
268
+
269
+
270
+ def translate_abstract_to_plasmids(
271
+ abstract_design: Union[sbol2.ComponentDefinition, sbol2.CombinatorialDerivation],
272
+ plasmid_collection: sbol2.Collection,
273
+ acceptor_backbone: sbol2.Document,
274
+ ) -> List[MocloPlasmid]:
275
+ """
276
+ Translates an abstract SBOLCanvas design into a set of compatible MoClo plasmid assemblies.
277
+
278
+ Takes an abstract design, identifies the appropriate component
279
+ definitions and combinatorial derivations, and produces all possible plasmid
280
+ combinations that can be assembled using the provided backbone and plasmid
281
+ collection.
282
+
283
+ Args:
284
+ abstract_design_doc:
285
+ The :class:`sbol2.Document` representing the abstract genetic design.
286
+ May include either a single component definition (generic design) or
287
+ one or more combinatorial derivations (combinatorial design).
288
+ plasmid_collection:
289
+ The :class:`sbol2.Document` containing the available MoClo plasmid
290
+ components used for matching and assembly.
291
+ backbone_doc:
292
+ The :class:`sbol2.Document` defining the backbone plasmid into which
293
+ parts are assembled.
294
+
295
+ Returns:
296
+ List[MocloPlasmid]:
297
+ - For combinatorial designs: a list of unique compatible plasmids
298
+ (`MocloPlasmid` objects) representing all enumerated design variants.
299
+ - For generic designs: a list of compatible plasmids for the single
300
+ design instance.
301
+ """
302
+ backbone_def = extract_toplevel_definition(acceptor_backbone)
303
+
304
+
305
+ backbone_plasmid = MocloPlasmid(backbone_def.displayId, backbone_def, acceptor_backbone)
306
+
307
+ # combinatorial design
308
+ if len(abstract_design.combinatorialderivations) > 0:
309
+ abstract_design_def = abstract_design.getComponentDefinition(
310
+ abstract_design.combinatorialderivations[0].masterTemplate
311
+ )
312
+
313
+ combinatorial_part_dict = extract_combinatorial_design_parts(
314
+ abstract_design_def, abstract_design , plasmid_collection
315
+ )
316
+ enumerated_part_list = enumerate_design_variants(combinatorial_part_dict)
317
+
318
+ seen = set()
319
+ ordered_unique_plasmids = []
320
+
321
+ for design in enumerated_part_list:
322
+ plasmid_dict = construct_plasmid_dict(design, plasmid_collection)
323
+ compatible_plasmids = get_compatible_plasmids(
324
+ plasmid_dict, backbone_plasmid
325
+ )
326
+
327
+ for plasmid in compatible_plasmids:
328
+ if plasmid not in seen:
329
+ seen.add(plasmid)
330
+ ordered_unique_plasmids.append(plasmid)
331
+
332
+ return ordered_unique_plasmids
333
+
334
+ # generic design
335
+ else:
336
+ abstract_design_def = extract_toplevel_definition(abstract_design)
337
+
338
+ ordered_part_definitions = extract_design_parts(
339
+ abstract_design_def, abstract_design
340
+ )
341
+
342
+ plasmid_dict = construct_plasmid_dict(
343
+ ordered_part_definitions, plasmid_collection
344
+ )
345
+
346
+ return get_compatible_plasmids(plasmid_dict, backbone_plasmid)
@@ -0,0 +1,49 @@
1
+ import sbol2
2
+ from typing import Union, List
3
+ import zipfile
4
+ from buildcompiler.abstract_translator import translate_abstract_to_plasmids
5
+ from buildcompiler.sbol2build import golden_gate_assembly_plan
6
+ from buildcompiler.robotutils import assembly_plan_RDF_to_JSON, run_opentrons_script_with_json_to_zip
7
+
8
+
9
+ # function which input is an abstract design and output build specifications by creating an assembly plan, and a zip file with a run_sbol2assembly.py, an automated_assembly_log.txt, assemblyplan_output.JSON, and assembly_protocol.xlsx
10
+
11
+ def assembly_compiler(document: sbol2.Document,
12
+ abstract_design: str,
13
+ plasmids_collection: str,
14
+ plasmid_acceptor_backbone: str,
15
+ files_path: str) -> zipfile.ZipFile:
16
+ """
17
+ Compiles an abstract design into build specifications.
18
+
19
+ Args:
20
+ abstract_design (Union[sbol2.Component, sbol2.CombinatorialDerivation]): The abstract design to be compiled.
21
+ specifications (sbol2.Component): The component to store the build specifications.
22
+ Returns:
23
+ zipfile.ZipFile: A zip file containing the build specifications and assembly plan.
24
+ """
25
+ restriction_enzyme = "BsaI"
26
+ # Translate abstract design to plasmids
27
+ list_of_plasmids = translate_abstract_to_plasmids(abstract_design_doc = abstract_design,
28
+ plasmid_collection = plasmids_collection,
29
+ backbone_doc= plasmid_acceptor_backbone)
30
+
31
+
32
+
33
+ # Create assembly plan
34
+ assembly_plan = golden_gate_assembly_plan(name = "Assembly_Plan",
35
+ parts_in_backbone= list_of_plasmids,
36
+ plasmid_acceptor_backbone= plasmid_acceptor_backbone,
37
+ restriction_enzyme= restriction_enzyme,
38
+ document= document)
39
+
40
+ # Generate build specifications JSON
41
+ build_specs_JSON = assembly_plan_RDF_to_JSON(assembly_plan)
42
+
43
+ # Create zip file with required files
44
+ zip_file = run_opentrons_script_with_json_to_zip(opentrons_script_path= files_path + "/run_sbol2assembly_libre.py",
45
+ json_file_path= files_path + "/assemblyplan_output.json",
46
+ zip_name= "buildcompiler.zip",
47
+ overwrite= True)
48
+
49
+ return assembly_plan, zip_file
@@ -0,0 +1,15 @@
1
+ FUSION_SITES = {
2
+ "A": "GGAG",
3
+ "B": "TACT",
4
+ "C": "AATG",
5
+ "D": "AGGT",
6
+ "E": "GCTT",
7
+ "F": "CGCT",
8
+ "G": "TGCC",
9
+ "H": "ACTA",
10
+ }
11
+
12
+ DNA_TYPES = { # TODO see about restricting dna types to only accept dna
13
+ "http://www.biopax.org/release/biopax-level3.owl#Dna",
14
+ "http://www.biopax.org/release/biopax-level3.owl#DnaRegion",
15
+ }