Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update materials for IWBDA 2022 #16

Merged
merged 4 commits into from
Oct 19, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions 2022/IWBDA22/sbol3-workshop/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
sbol3==1.0.1
sbol-utilities==1.0a16
tyto==1.2.1
notebook==6.4.12
149 changes: 70 additions & 79 deletions 2022/IWBDA22/sbol3-workshop/tutorial_answer_key.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,17 @@
"source": [
"# IWBDA 2022 SBOL 3 Tutorial\n",
"\n",
"October 2022\n",
"### October 2022\n",
"This tutorial code goes with the slides at:\n",
"\n",
"https://github.com/SynBioDex/Community-Media/blob/master/2022/IWBDA22/pySBOL3-IWBDA-2022.pptx"
"https://github.com/SynBioDex/Community-Media/blob/master/2022/IWBDA22/sbol3-workshop/pySBOL3-IWBDA-2022.pptx"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Import the module"
"Import the modules"
]
},
{
Expand All @@ -25,7 +25,10 @@
"metadata": {},
"outputs": [],
"source": [
"from sbol3 import *"
"from sbol3 import *\n",
"from sbol_utilities.calculate_sequences import compute_sequence\n",
"from sbol_utilities.component import *\n",
"import tyto"
]
},
{
Expand All @@ -52,12 +55,12 @@
"# Slide 26: GFP expression cassette\n",
"Construct a simple part and add it to the Document.\n",
"\n",
"Component\n",
"identity: iGEM#I13504\n",
"name: \"iGEM 2016 interlab reporter\"\n",
"description: \"GFP expression cassette used for 2016 iGEM interlab\"\n",
"type: SBO:0000251 (DNA)\n",
"role: SO:0000804 (Engineered Region)\n",
"Component \n",
"identity: iGEM#I13504 \n",
"name: \"iGEM 2016 interlab reporter\" \n",
"description: \"GFP expression cassette used for 2016 iGEM interlab\" \n",
"type: SBO:0000251 (DNA) \n",
"role: SO:0000804 (Engineered Region) \n",
"\n",
"Which properties are required? Which properties behave as lists?"
]
Expand All @@ -71,7 +74,7 @@
"i13504 = Component('i13504', SBO_DNA)\n",
"i13504.name = 'iGEM 2016 interlab reporter'\n",
"i13504.description = 'GFP expression cassette used for 2016 iGEM interlab study'\n",
"i13504.roles.append(SO_NS + '0000804')"
"i13504.roles.append(tyto.SO.engineered_region)"
]
},
{
Expand All @@ -95,15 +98,13 @@
"metadata": {},
"source": [
"# Slide 28: expression cassette parts\n",
"Here we will create a part-subpart hierarchy.\n",
"Here we will create a part-subpart hierarchy. We will also start using (SBOL-Utilities)[https://github.com/synbiodex/sbol-utilities] to make it easier to create parts and to assemble those parts into a hierarchy.\n",
"\n",
"First, create the RBS component...\n",
"\n",
"Component \n",
"identity: B0034 \n",
"name: RBS (Elowitz 1999) \n",
"type: SBO:0000251 (DNA) \n",
"role: SO:0000139 (Ribosome Entry Site) \n"
"name: RBS (Elowitz 1999)"
]
},
{
Expand All @@ -112,9 +113,7 @@
"metadata": {},
"outputs": [],
"source": [
"b0034 = Component('B0034', SBO_DNA)\n",
"b0034.name = 'RBS (Elowitz 1999)'\n",
"b0034.roles = [SO_NS + '0000139']"
"b0034, b0034_seq = doc.add(rbs('B0034', sequence='aaagaggagaaa', name='RBS (Elowitz 1999)'))"
]
},
{
Expand All @@ -124,9 +123,7 @@
"Next, create the GFP component\n",
"\n",
"identity: E0040 \n",
"name: GFP \n",
"type: SBO:0000251 (DNA) \n",
"role: SO:0000316 (CDS) "
"name: GFP"
]
},
{
Expand All @@ -135,9 +132,8 @@
"metadata": {},
"outputs": [],
"source": [
"e0040 = Component('E0040', SBO_DNA)\n",
"e0040.name = 'GFP'\n",
"e0040.roles = [SO_NS + '0000316']"
"e0040_sequence = 'atgcgtaaaggagaagaacttttcactggagttgtcccaattcttgttgaattagatggtgatgttaatgggcacaaattttctgtcagtggagagggtgaaggtgatgcaacatacggaaaacttacccttaaatttatttgcactactggaaaactacctgttccatggccaacacttgtcactactttcggttatggtgttcaatgctttgcgagatacccagatcatatgaaacagcatgactttttcaagagtgccatgcccgaaggttatgtacaggaaagaactatatttttcaaagatgacgggaactacaagacacgtgctgaagtcaagtttgaaggtgatacccttgttaatagaatcgagttaaaaggtattgattttaaagaagatggaaacattcttggacacaaattggaatacaactataactcacacaatgtatacatcatggcagacaaacaaaagaatggaatcaaagttaacttcaaaattagacacaacattgaagatggaagcgttcaactagcagaccattatcaacaaaatactccaattggcgatggccctgtccttttaccagacaaccattacctgtccacacaatctgccctttcgaaagatcccaacgaaaagagagaccacatggtccttcttgagtttgtaacagctgctgggattacacatggcatggatgaactatacaaataataa'\n",
"e0040, _ = doc.add(cds('E0040', sequence=e0040_sequence, name='GFP'))"
]
},
{
Expand All @@ -147,9 +143,7 @@
"Finally, create the terminator\n",
"\n",
"identity: B0015 \n",
"name: double terminator \n",
"type: SBO:0000251 (DNA) \n",
"role: SO:0000141 (Terminator) "
"name: double terminator"
]
},
{
Expand All @@ -158,16 +152,15 @@
"metadata": {},
"outputs": [],
"source": [
"b0015 = Component('B0015', SBO_DNA)\n",
"b0015.name = 'double terminator'\n",
"b0015.roles = [SO_NS + '0000141']"
"b0015_sequence = 'ccaggcatcaaataaaacgaaaggctcagtcgaaagactgggcctttcgttttatctgttgtttgtcggtgaacgctctctactagagtcacactggctcaccttcgggtgggcctttctgcgtttata'\n",
"b0015, _ = doc.add(terminator('B0015', sequence=b0015_sequence, name='double terminator'))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Now construct the part-subpart hierarchy"
"Now construct the part-subpart hierarchy and order the parts: RBS before CDS, CDS before terminator"
]
},
{
Expand All @@ -176,23 +169,19 @@
"metadata": {},
"outputs": [],
"source": [
"doc.add(b0034)\n",
"doc.add(e0040)\n",
"doc.add(b0015)\n",
"i13504.features.append(SubComponent(b0034))\n",
"i13504.features.append(SubComponent(e0040))\n",
"i13504.features.append(SubComponent(b0015))"
"order(b0034, e0040, i13504)\n",
"order(e0040, b0015, i13504)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Slide 30: Location of a SubComponent\n",
"# Slide 30: Location of a SubComponent\n",
"\n",
"Here we add base coordinates to SubCompnents.\n",
"Here we add base coordinates to SubComponents.\n",
"\n",
"But first, assign a sequence to the BBa_I13504 device \n",
"But first, use `compute_sequence` to get the full sequence for the BBa_I13504 device \n",
"\n",
"See http://parts.igem.org/Part:BBa_I13504"
]
Expand All @@ -203,23 +192,16 @@
"metadata": {},
"outputs": [],
"source": [
"i13504_seq = Sequence('i13504_seq')\n",
"i13504_seq.elements = 'aaagaggagaaatactagatgcgtaaaggagaagaacttttcactggagttgtcccaattcttgttgaattagatggtgatgttaatgggcacaaattttctgtcagtggagagggtgaaggtgatgcaacatacggaaaacttacccttaaatttatttgcactactggaaaactacctgttccatggccaacacttgtcactactttcggttatggtgttcaatgctttgcgagatacccagatcatatgaaacagcatgactttttcaagagtgccatgcccgaaggttatgtacaggaaagaactatatttttcaaagatgacgggaactacaagacacgtgctgaagtcaagtttgaaggtgatacccttgttaatagaatcgagttaaaaggtattgattttaaagaagatggaaacattcttggacacaaattggaatacaactataactcacacaatgtatacatcatggcagacaaacaaaagaatggaatcaaagttaacttcaaaattagacacaacattgaagatggaagcgttcaactagcagaccattatcaacaaaatactccaattggcgatggccctgtccttttaccagacaaccattacctgtccacacaatctgccctttcgaaagatcccaacgaaaagagagaccacatggtccttcttgagtttgtaacagctgctgggattacacatggcatggatgaactatacaaataataatactagagccaggcatcaaataaaacgaaaggctcagtcgaaagactgggcctttcgttttatctgttgtttgtcggtgaacgctctctactagagtcacactggctcaccttcgggtgggcctttctgcgtttata'\n",
"i13504_seq.encoding = IUPAC_DNA_ENCODING\n",
"i13504.sequences = [i13504_seq]"
"i13504_seq = compute_sequence(i13504)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Add a Range to the B0015 SubComponent. The base coordinates for B0015 are as follows:\n",
"\n",
"Range \n",
"start: 746 \n",
"end: 875 \n",
"`compute_sequence` added `Range`s to the subcomponents. Check one of those ranges to see that the values are what we expect.\n",
"\n",
"pySBOL3 does not yet have an easy way to locate features based on arbitrary criteria so we have to loop over the list to find the B0015 SubComponent we are looking for"
"The expected range of the terminator is (733, 861)."
]
},
{
Expand All @@ -228,11 +210,9 @@
"metadata": {},
"outputs": [],
"source": [
"for f in i13504.features:\n",
" if f.instance_of == b0015.identity:\n",
" print(f)\n",
" f.locations.append(Range(i13504_seq, 746, 875))\n",
" "
"b0015_subcomponent = next(f for f in i13504.features if f.instance_of == b0015.identity)\n",
"b0015_range = b0015_subcomponent.locations[0]\n",
"print(f'Range of {b0015.display_name}: ({b0015_range.start}, {b0015_range.end})')"
]
},
{
Expand All @@ -242,11 +222,10 @@
"# Slide 32: GFP production from expression cassette\n",
"In this example, we will create a system representation that includes DNA, proteins, and interactions.\n",
"\n",
"First, create the system representation. We use the SBO term \"functional entity\" to represent a system.\n",
"First, create the system representation. `functional_component` creates this for us.\n",
"\n",
"Component\n",
"identity: i13504_system \n",
"type: SBO:0000236 (functional entity) "
"Component \n",
"identity: i13504_system"
]
},
{
Expand All @@ -255,15 +234,16 @@
"metadata": {},
"outputs": [],
"source": [
"i13504_system = Component('i13504_system', SBO_NS + '0000236' )\n",
"i13504_system = functional_component('i13504_system')\n",
"doc.add(i13504_system)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The system has two physical subcomponents, the expression construct and the expressed GFP protein. We already created the expression construct. Now create the GFP protein."
"The system has two physical subcomponents, the expression construct and the expressed GFP protein. We already created the expression construct. Now create the GFP protein.\n",
"`ed_protein` creates an \"externally defined protein\""
]
},
{
Expand All @@ -272,8 +252,7 @@
"metadata": {},
"outputs": [],
"source": [
"gfp_protein = Component('GFP', SBO_PROTEIN)\n",
"doc.add(gfp_protein)"
"gfp = add_feature(i13504_system, ed_protein('https://www.fpbase.org/protein/gfpmut3/', name='GFP'))"
]
},
{
Expand All @@ -289,10 +268,7 @@
"metadata": {},
"outputs": [],
"source": [
"i13504_subcomponent = SubComponent(i13504)\n",
"gfp_subcomponent = SubComponent(gfp_protein)\n",
"i13504_system.features.append(i13504_subcomponent)\n",
"i13504_system.features.append(gfp_subcomponent)"
"i13504_subcomponent = add_feature(i13504_system, i13504)"
]
},
{
Expand All @@ -308,13 +284,7 @@
"metadata": {},
"outputs": [],
"source": [
"e0040_subcomponent = None\n",
"for f in i13504.features:\n",
" if f.instance_of == e0040.identity:\n",
" e0040_subcomponent = f\n",
"if e0040_subcomponent is None:\n",
" raise Exception()\n",
" \n",
"e0040_subcomponent = next(f for f in i13504.features if f.instance_of == e0040.identity)\n",
"e0040_reference = ComponentReference(i13504_subcomponent, e0040_subcomponent)\n",
"i13504_system.features.append(e0040_reference)"
]
Expand Down Expand Up @@ -343,10 +313,31 @@
"metadata": {},
"outputs": [],
"source": [
"genetic_production = Interaction([SBO_NS + '0000589'])\n",
"template = Participation([SBO_NS + '0000645'], e0040_reference)\n",
"product = Participation([SBO_NS + '0000011'], gfp_subcomponent)\n",
"i13504_system.interactions.append(genetic_production)\n"
"add_interaction(tyto.SBO.genetic_production,\n",
" participants={gfp: tyto.SBO.product, e0040_reference: tyto.SBO.template})"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Validate the document\n",
"`Document.validate` returns a validation report. If the report is empty, the document is valid."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"report = doc.validate()\n",
"if report:\n",
" print('Document is not valid')\n",
" print(f'Document has {len(report.errors)} errors')\n",
" print(f'Document has {len(report.warnings)} warnings')\n",
"else:\n",
" print('Document is valid')"
]
},
{
Expand All @@ -362,7 +353,7 @@
"metadata": {},
"outputs": [],
"source": [
"doc.write('i13504.nt', file_format=NTRIPLES)"
"doc.write('i13504.nt', file_format=SORTED_NTRIPLES)"
]
}
],
Expand Down