From 15877cec522ea73819e1cdae7a905b9e6a3d7705 Mon Sep 17 00:00:00 2001 From: Manuel Lera-Ramirez Date: Wed, 15 Jan 2025 16:07:31 +0000 Subject: [PATCH] closes #333 --- README.md | 12 +- docs/README.md | 2 +- docs/cookbook/cookbook.ipynb | 2 +- docs/getting_started.md | 2 +- docs/notebooks/CRISPR.ipynb | 2 +- docs/notebooks/Dseq.ipynb | 2 +- docs/notebooks/Dseq_Features.ipynb | 2 +- docs/notebooks/Example_CRISPR.ipynb | 544 ++++++------- docs/notebooks/Example_Gibson.ipynb | 2 +- docs/notebooks/Example_Restriction.ipynb | 2 +- docs/notebooks/Gibson.ipynb | 2 +- docs/notebooks/Importing_Seqs.ipynb | 2 +- docs/notebooks/PCR.ipynb | 2 +- docs/notebooks/Restrict_Ligate_Cloning.ipynb | 2 +- docs/notebooks/readme_example.ipynb | 734 +++++++++--------- pyproject.toml | 14 +- scripts/conda-build/meta (copy).yaml | 6 +- scripts/conda-build/meta (copy2).yaml | 6 +- scripts/conda-build/meta2.yaml | 6 +- .../files_for_annotation_function/post.md | 2 +- src/pydna/__init__.py | 8 +- src/pydna/dseqrecord.py | 6 +- src/pydna/utils.py | 2 +- tests/test_module_amplify.py | 2 +- tests/test_module_dseq.py | 8 +- tests/test_module_dseqrecord.py | 2 +- tests/test_module_utils.py | 4 +- 27 files changed, 691 insertions(+), 689 deletions(-) diff --git a/README.md b/README.md index 5def6106..951a5c6c 100755 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ # ![icon](docs/_static/pydna.resized.png) pydna -| [![Tests & Coverage](https://github.com/BjornFJohansson/pydna/actions/workflows/pydna_test_and_coverage_workflow.yml/badge.svg?branch=dev_bjorn)](https://github.com/BjornFJohansson/pydna/actions/workflows/pydna_test_and_coverage_workflow.yml) | [![codecov](https://codecov.io/gh/BjornFJohansson/pydna/branch/master/graph/badge.svg)](https://codecov.io/gh/BjornFJohansson/pydna/branch/master) | [![PyPI version](https://badge.fury.io/py/pydna.svg)](https://badge.fury.io/py/pydna) | [![Google group : pydna](https://img.shields.io/badge/Google%20Group-pydna-blue.svg)](https://groups.google.com/g/pydna) | -| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | -| [![Documentation Status](https://github.com/BjornFJohansson/pydna/actions/workflows/publish-docs.yml/badge.svg)](https://github.com/BjornFJohansson/pydna/actions/workflows/publish-docs.yml) | [![GitHub issues](https://img.shields.io/github/issues/BjornFJohansson/pydna.svg)](https://github.com/BjornFJohansson/pydna/issues) | [![Anaconda-Server Badge2](https://anaconda.org/bjornfjohansson/pydna/badges/license.svg)](https://anaconda.org/bjornfjohansson/pydna) | [![GitHub stars](https://img.shields.io/github/stars/BjornFJohansson/pydna.svg)](https://github.com/BjornFJohansson/pydna/stargazers) | +| [![Tests & Coverage](https://github.com/pydna-group/pydna/actions/workflows/pydna_test_and_coverage_workflow.yml/badge.svg?branch=dev_bjorn)](https://github.com/pydna-group/pydna/actions/workflows/pydna_test_and_coverage_workflow.yml) | [![codecov](https://codecov.io/gh/BjornFJohansson/pydna/branch/master/graph/badge.svg)](https://codecov.io/gh/BjornFJohansson/pydna/branch/master) | [![PyPI version](https://badge.fury.io/py/pydna.svg)](https://badge.fury.io/py/pydna) | [![Google group : pydna](https://img.shields.io/badge/Google%20Group-pydna-blue.svg)](https://groups.google.com/g/pydna) | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------- | +| [![Documentation Status](https://github.com/pydna-group/pydna/actions/workflows/publish-docs.yml/badge.svg)](https://github.com/pydna-group/pydna/actions/workflows/publish-docs.yml) | [![GitHub issues](https://img.shields.io/github/issues/BjornFJohansson/pydna.svg)](https://github.com/pydna-group/pydna/issues) | [![Anaconda-Server Badge2](https://anaconda.org/bjornfjohansson/pydna/badges/license.svg)](https://anaconda.org/bjornfjohansson/pydna) | [![GitHub stars](https://img.shields.io/github/stars/BjornFJohansson/pydna.svg)](https://github.com/pydna-group/pydna/stargazers) | @@ -487,7 +487,7 @@ supported python versions. ### Building the documentation locally 📚 Documentation is built using [Sphinx](http://www.sphinx-doc.org/) from [docstrings](https://www.python.org/dev/peps/pep-0257/) -using a GitHub [action](https://github.com/BjornFJohansson/pydna/actions/workflows/publish-docs.yml). +using a GitHub [action](https://github.com/pydna-group/pydna/actions/workflows/publish-docs.yml). The [numpy](https://www.numpy.org) [docstring format](https://numpy.org/doc/stable/dev/howto-docs.html#docstring-intro) is used. Below the commands to run a local sphinx server that auto-updated when files are changed. @@ -505,7 +505,7 @@ More info about how to contribute to the documentation can be found [here](docs/ ## Release process 🚀 -See the [releases](https://github.com/BjornFJohansson/pydna/releases) for changes and releases. +See the [releases](https://github.com/pydna-group/pydna/releases) for changes and releases. The build workflow builds a PyPI packages using poetry. This workflow is triggered by publishing a Github release manually from the Github web interface. @@ -535,4 +535,4 @@ In Cold Spring Harbor Laboratory (p. 2021.01.17.427048). [DOI](https://doi.org/1 [An Automated Protein Synthesis Pipeline with Transcriptic and Snakemake](http://blog.booleanbiotech.com/transcriptic_protein_synthesis_pipeline.html) -and other projects on [github](https://github.com/BjornFJohansson/pydna/network/dependents?package_id=UGFja2FnZS01MjQ2MjYzNQ%3D%3D) +and other projects on [github](https://github.com/pydna-group/pydna/network/dependents?package_id=UGFja2FnZS01MjQ2MjYzNQ%3D%3D) diff --git a/docs/README.md b/docs/README.md index fa6f252b..3975d263 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,7 +1,7 @@ # Documentation Documentation is built using [Sphinx](http://www.sphinx-doc.org/) from [docstrings](https://www.python.org/dev/peps/pep-0257/) -using a GitHub [action](https://github.com/BjornFJohansson/pydna/actions/workflows/publish-docs.yml). +using a GitHub [action](https://github.com/pydna-group/pydna/actions/workflows/publish-docs.yml). The [numpy](www.numpy.org) [docstring format](https://numpy.org/doc/stable/dev/howto-docs.html#docstring-intro) is used. Below the commands to run a local sphinx server that auto-updated when files are changed. diff --git a/docs/cookbook/cookbook.ipynb b/docs/cookbook/cookbook.ipynb index ab8748be..6605dcc3 100644 --- a/docs/cookbook/cookbook.ipynb +++ b/docs/cookbook/cookbook.ipynb @@ -21,7 +21,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "\n", + "\n", " \"Open\n", "" ] diff --git a/docs/getting_started.md b/docs/getting_started.md index c5f6c7fc..961e3959 100644 --- a/docs/getting_started.md +++ b/docs/getting_started.md @@ -2,7 +2,7 @@ The best way to get started is to follow our tutorial notebooks, you can find them in the -repository folder [docs/notebooks](https://github.com/BjornFJohansson/pydna/tree/main/docs/notebooks) and +repository folder [docs/notebooks](https://github.com/pydna-group/pydna/tree/master/docs/notebooks) and are reproduced here so they can serve as documentation. You can run the notebooks locally, but also on the browser using Google Colab, simply click in the badge of diff --git a/docs/notebooks/CRISPR.ipynb b/docs/notebooks/CRISPR.ipynb index 6fdd7525..7c223dbd 100644 --- a/docs/notebooks/CRISPR.ipynb +++ b/docs/notebooks/CRISPR.ipynb @@ -33,7 +33,7 @@ "if 'google.colab' in sys.modules:\n", " %%capture\n", " # Install the current development version of pydna (comment to install pip version)\n", - " !pip install git+https://github.com/BjornFJohansson/pydna@dev_bjorn\n", + " !pip install git+https://github.com/pydna-group/pydna@dev_bjorn\n", " # Install pip version instead (uncomment to install)\n", " # !pip install pydna\n" ] diff --git a/docs/notebooks/Dseq.ipynb b/docs/notebooks/Dseq.ipynb index ce4a1401..1073ef34 100644 --- a/docs/notebooks/Dseq.ipynb +++ b/docs/notebooks/Dseq.ipynb @@ -28,7 +28,7 @@ "if 'google.colab' in sys.modules:\n", " %%capture\n", " # Install the current development version of pydna (comment to install pip version)\n", - " !pip install git+https://github.com/BjornFJohansson/pydna@dev_bjorn\n", + " !pip install git+https://github.com/pydna-group/pydna@dev_bjorn\n", " # Install pip version instead (uncomment to install)\n", " # !pip install pydna\n" ] diff --git a/docs/notebooks/Dseq_Features.ipynb b/docs/notebooks/Dseq_Features.ipynb index 8dd0c903..68d36576 100644 --- a/docs/notebooks/Dseq_Features.ipynb +++ b/docs/notebooks/Dseq_Features.ipynb @@ -35,7 +35,7 @@ "if 'google.colab' in sys.modules:\n", " %%capture\n", " # Install the current development version of pydna (comment to install pip version)\n", - " !pip install git+https://github.com/BjornFJohansson/pydna@dev_bjorn\n", + " !pip install git+https://github.com/pydna-group/pydna@dev_bjorn\n", " # Install pip version instead (uncomment to install)\n", " # !pip install pydna\n" ] diff --git a/docs/notebooks/Example_CRISPR.ipynb b/docs/notebooks/Example_CRISPR.ipynb index f3cb4254..6251d842 100644 --- a/docs/notebooks/Example_CRISPR.ipynb +++ b/docs/notebooks/Example_CRISPR.ipynb @@ -1,273 +1,273 @@ { - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Implementation of Oligonucleotide-based CRISPR-Cas9 toolbox for efficient engineering of Komagataella phaffii \n", - "\n", - "\n", - "In this example we wanted to give a real life intuition on how to use the module in practice. \n", - "\n", - "For this purpose we have chosen to use the oligonucleotide-based CRISPR-Cas9 toolbox that i described \n", - "here by Strucko et al 2024, in the industrially relevant K. phaffi production organism: \n", - "\n", - "https://academic.oup.com/femsyr/article/doi/10.1093/femsyr/foae026/7740463?login=false " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "\n", - " \"Open\n", - "" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "execution_count": null, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "from IPython.display import Image\n", - "Image(url=\"https://oup.silverchair-cdn.com/oup/backfile/Content_public/Journal/femsyr/24/10.1093_femsyr_foae026/1/m_foae026fig3.jpeg?Expires=1730974846&Signature=iBKvkhkUn1823IljQ~1uFEnKO0VqWrwiXADvCwQLz6Yv8yDEAFkgt~tsLrXKFTmGYIq3ZINcj5a5yNgs4cP4NeCvRcQh7Ad~1ZejIwNrjqw51CJhGcZWPzz~NDr93QVLZZd2Re41cJNFKFmEu756KxrHQxwKTQe2QPMPfiKBvhvo8J28PERj3vNjZ3LQRsFp9qUPpdsZEyWIiNY92jsuy448YyuaGCgaC2ExGDLeuArTEJmq8gtb0QnTPV0dEdtoxIfZpgavdvO~QyqikjCLj6hebUYU1lH7StuS8oqCQE82CXO0IUcjYF6m2Lb0evXhqdLDQe90M-NrKjzNRmBA0A__&Key-Pair-Id=APKAIE5G5CRDK6RD3PGA\")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Figure 1. oligo assisted repair in K. phaffi. " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "\n", - "- Basically we can make two cuts in the genome, and repair it with an oligo (Figure 1A, 1B).\n", - "\n", - "\n", - "- We can start by loading in our target. Here we have integrated LAC12 in our K. phaffi strain but want to knock it out. \n", - "\n", - "\n", - "- Let's see how this can be implemented in pydna\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Install pydna (only when running on Colab)\n", - "import sys\n", - "if 'google.colab' in sys.modules:\n", - " %%capture\n", - " # Install the current development version of pydna (comment to install pip version)\n", - " !pip install git+https://github.com/BjornFJohansson/pydna@dev_bjorn\n", - " # Install pip version instead (uncomment to install)\n", - " # !pip install pydna\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Import the gene we are going to work with" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Dseqrecord\n", - "circular: False\n", - "size: 7127\n", - "ID: X06997.1\n", - "Name: X06997\n", - "Description: Kluyveromyces lactis LAC12 gene for lactose permease\n", - "Number of features: 8\n", - "/molecule_type=DNA\n", - "/topology=linear\n", - "/data_file_division=PLN\n", - "/date=25-JUL-2016\n", - "/accessions=['X06997']\n", - "/sequence_version=1\n", - "/keywords=['lactose permease', 'unidentified reading frame']\n", - "/source=Kluyveromyces lactis\n", - "/organism=Kluyveromyces lactis\n", - "/taxonomy=['Eukaryota', 'Fungi', 'Dikarya', 'Ascomycota', 'Saccharomycotina', 'Saccharomycetes', 'Saccharomycetales', 'Saccharomycetaceae', 'Kluyveromyces']\n", - "/references=[Reference(title='Primary structure of the lactose permease gene from the yeast Kluyveromyces lactis. Presence of an unusual transcript structure', ...), Reference(title='Direct Submission', ...)]\n", - "/comment=the sequence submitted starts from the 5'end of LAC4 gene but goes\n", - "to the opposite direction; therefore, base number 1 is -1199 of\n", - "LAC4 gene; for LAC4 gene seq. see\n", - "Mol. Cell. Biol. (1987)7,4369-4376.\n", - "Dseq(-7127)\n", - "GCGA..TTCG\n", - "CGCT..AAGC\n" - ] - } - ], - "source": [ - "from pydna.dseqrecord import Dseqrecord\n", - "from pydna.crispr import cas9, protospacer\n", - "from pydna.genbank import Genbank\n", - "\n", - "# initalize your favourite gene\n", - "gb = Genbank(\"myself@email.com\") # Tell Genbank who you are!\n", - "gene = gb.nucleotide(\"X06997\") # Kluyveromyces lactis LAC12 gene for lactose permease that have been integrated into K. phaffi\n", - "target_dseq = Dseqrecord(gene)\n", - "print(target_dseq)\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Next we have chosen some guides and can add them to our cas9 enzymes and simulate the cuts." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "cutting with guide 1: (Dseqrecord(-135), Dseqrecord(-6992))\n", - "cutting with guide 2: (Dseqrecord(-6793), Dseqrecord(-334))\n" - ] - } - ], - "source": [ - "\n", - "# Choose guides\n", - "guides = [\"CCCTAAGTCCTTTGAAGATT\", \"TATTATTTTGAGGTGCTTTA\"]\n", - "\n", - "# Create an enzyme object with the protospacer\n", - "enzyme = cas9(guides[0])\n", - "\n", - "# Simulate the cut with enzyme1\n", - "print('cutting with guide 1:', target_dseq.cut(enzyme))\n", - "\n", - "# Create an enzyme from the protospacer\n", - "enzyme2 = cas9(guides[1])\n", - "\n", - "# Simulate the cut with enzyme2\n", - "print('cutting with guide 2:', target_dseq.cut(enzyme2))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "With these guides I would be able to generate a stable KO with a repair 60/90mer oligo." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "My repair oligo for this experiment : AGGTGAACACACTCTGATGTAGTGCAGTCCCTAAGTCCTTTGAAGTTACGGACTCCTCGACCGATGCCCTTGAGAGCCTTCAACCCAGTC \n", - "My repair oligo for this experiment length : 90 \n" - ] - } - ], - "source": [ - "repair_oligo = target_dseq.cut(enzyme)[0][-45:]+target_dseq.cut(enzyme2)[-1][:45]\n", - "repair_oligo.name = 'My repair oligo for this experiment'\n", - "print(f'{repair_oligo.name} : {repair_oligo.seq} ')\n", - "print(f'{repair_oligo.name} length : {len(repair_oligo.seq)} ')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The final edit gene would look like this in a case of homologous recombination. \n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
name|45\n",
-       "     \\/\n",
-       "     /\\\n",
-       "     45|My repair oligo for this experiment|45\n",
-       "                                            \\/\n",
-       "                                            /\\\n",
-       "                                            45|name
" - ], - "text/plain": [ - "Contig(-469)" - ] - }, - "execution_count": null, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "from pydna.assembly import Assembly\n", - "\n", - "my_KO = Assembly((target_dseq.cut(enzyme)[0],repair_oligo, target_dseq.cut(enzyme2)[-1]), limit = 20 )\n", - "my_assembly_KO, *rest = my_KO.assemble_linear()\n", - "my_assembly_KO" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": ".venv", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.12.3" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Implementation of Oligonucleotide-based CRISPR-Cas9 toolbox for efficient engineering of Komagataella phaffii \n", + "\n", + "\n", + "In this example we wanted to give a real life intuition on how to use the module in practice. \n", + "\n", + "For this purpose we have chosen to use the oligonucleotide-based CRISPR-Cas9 toolbox that i described \n", + "here by Strucko et al 2024, in the industrially relevant K. phaffi production organism: \n", + "\n", + "https://academic.oup.com/femsyr/article/doi/10.1093/femsyr/foae026/7740463?login=false " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + " \"Open\n", + "" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "execution_count": null, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "from IPython.display import Image\n", + "Image(url=\"https://oup.silverchair-cdn.com/oup/backfile/Content_public/Journal/femsyr/24/10.1093_femsyr_foae026/1/m_foae026fig3.jpeg?Expires=1730974846&Signature=iBKvkhkUn1823IljQ~1uFEnKO0VqWrwiXADvCwQLz6Yv8yDEAFkgt~tsLrXKFTmGYIq3ZINcj5a5yNgs4cP4NeCvRcQh7Ad~1ZejIwNrjqw51CJhGcZWPzz~NDr93QVLZZd2Re41cJNFKFmEu756KxrHQxwKTQe2QPMPfiKBvhvo8J28PERj3vNjZ3LQRsFp9qUPpdsZEyWIiNY92jsuy448YyuaGCgaC2ExGDLeuArTEJmq8gtb0QnTPV0dEdtoxIfZpgavdvO~QyqikjCLj6hebUYU1lH7StuS8oqCQE82CXO0IUcjYF6m2Lb0evXhqdLDQe90M-NrKjzNRmBA0A__&Key-Pair-Id=APKAIE5G5CRDK6RD3PGA\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Figure 1. oligo assisted repair in K. phaffi. " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + "- Basically we can make two cuts in the genome, and repair it with an oligo (Figure 1A, 1B).\n", + "\n", + "\n", + "- We can start by loading in our target. Here we have integrated LAC12 in our K. phaffi strain but want to knock it out. \n", + "\n", + "\n", + "- Let's see how this can be implemented in pydna\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Install pydna (only when running on Colab)\n", + "import sys\n", + "if 'google.colab' in sys.modules:\n", + " %%capture\n", + " # Install the current development version of pydna (comment to install pip version)\n", + " !pip install git+https://github.com/pydna-group/pydna@dev_bjorn\n", + " # Install pip version instead (uncomment to install)\n", + " # !pip install pydna\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Import the gene we are going to work with" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Dseqrecord\n", + "circular: False\n", + "size: 7127\n", + "ID: X06997.1\n", + "Name: X06997\n", + "Description: Kluyveromyces lactis LAC12 gene for lactose permease\n", + "Number of features: 8\n", + "/molecule_type=DNA\n", + "/topology=linear\n", + "/data_file_division=PLN\n", + "/date=25-JUL-2016\n", + "/accessions=['X06997']\n", + "/sequence_version=1\n", + "/keywords=['lactose permease', 'unidentified reading frame']\n", + "/source=Kluyveromyces lactis\n", + "/organism=Kluyveromyces lactis\n", + "/taxonomy=['Eukaryota', 'Fungi', 'Dikarya', 'Ascomycota', 'Saccharomycotina', 'Saccharomycetes', 'Saccharomycetales', 'Saccharomycetaceae', 'Kluyveromyces']\n", + "/references=[Reference(title='Primary structure of the lactose permease gene from the yeast Kluyveromyces lactis. Presence of an unusual transcript structure', ...), Reference(title='Direct Submission', ...)]\n", + "/comment=the sequence submitted starts from the 5'end of LAC4 gene but goes\n", + "to the opposite direction; therefore, base number 1 is -1199 of\n", + "LAC4 gene; for LAC4 gene seq. see\n", + "Mol. Cell. Biol. (1987)7,4369-4376.\n", + "Dseq(-7127)\n", + "GCGA..TTCG\n", + "CGCT..AAGC\n" + ] + } + ], + "source": [ + "from pydna.dseqrecord import Dseqrecord\n", + "from pydna.crispr import cas9, protospacer\n", + "from pydna.genbank import Genbank\n", + "\n", + "# initalize your favourite gene\n", + "gb = Genbank(\"myself@email.com\") # Tell Genbank who you are!\n", + "gene = gb.nucleotide(\"X06997\") # Kluyveromyces lactis LAC12 gene for lactose permease that have been integrated into K. phaffi\n", + "target_dseq = Dseqrecord(gene)\n", + "print(target_dseq)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Next we have chosen some guides and can add them to our cas9 enzymes and simulate the cuts." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "cutting with guide 1: (Dseqrecord(-135), Dseqrecord(-6992))\n", + "cutting with guide 2: (Dseqrecord(-6793), Dseqrecord(-334))\n" + ] + } + ], + "source": [ + "\n", + "# Choose guides\n", + "guides = [\"CCCTAAGTCCTTTGAAGATT\", \"TATTATTTTGAGGTGCTTTA\"]\n", + "\n", + "# Create an enzyme object with the protospacer\n", + "enzyme = cas9(guides[0])\n", + "\n", + "# Simulate the cut with enzyme1\n", + "print('cutting with guide 1:', target_dseq.cut(enzyme))\n", + "\n", + "# Create an enzyme from the protospacer\n", + "enzyme2 = cas9(guides[1])\n", + "\n", + "# Simulate the cut with enzyme2\n", + "print('cutting with guide 2:', target_dseq.cut(enzyme2))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "With these guides I would be able to generate a stable KO with a repair 60/90mer oligo." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "My repair oligo for this experiment : AGGTGAACACACTCTGATGTAGTGCAGTCCCTAAGTCCTTTGAAGTTACGGACTCCTCGACCGATGCCCTTGAGAGCCTTCAACCCAGTC \n", + "My repair oligo for this experiment length : 90 \n" + ] + } + ], + "source": [ + "repair_oligo = target_dseq.cut(enzyme)[0][-45:]+target_dseq.cut(enzyme2)[-1][:45]\n", + "repair_oligo.name = 'My repair oligo for this experiment'\n", + "print(f'{repair_oligo.name} : {repair_oligo.seq} ')\n", + "print(f'{repair_oligo.name} length : {len(repair_oligo.seq)} ')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The final edit gene would look like this in a case of homologous recombination. \n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
name|45\n",
+                            "     \\/\n",
+                            "     /\\\n",
+                            "     45|My repair oligo for this experiment|45\n",
+                            "                                            \\/\n",
+                            "                                            /\\\n",
+                            "                                            45|name
" + ], + "text/plain": [ + "Contig(-469)" + ] + }, + "execution_count": null, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "from pydna.assembly import Assembly\n", + "\n", + "my_KO = Assembly((target_dseq.cut(enzyme)[0],repair_oligo, target_dseq.cut(enzyme2)[-1]), limit = 20 )\n", + "my_assembly_KO, *rest = my_KO.assemble_linear()\n", + "my_assembly_KO" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": ".venv", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.12.3" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} \ No newline at end of file diff --git a/docs/notebooks/Example_Gibson.ipynb b/docs/notebooks/Example_Gibson.ipynb index 490148b8..f99f4f31 100755 --- a/docs/notebooks/Example_Gibson.ipynb +++ b/docs/notebooks/Example_Gibson.ipynb @@ -32,7 +32,7 @@ "if 'google.colab' in sys.modules:\n", " %%capture\n", " # Install the current development version of pydna (comment to install pip version)\n", - " !pip install git+https://github.com/BjornFJohansson/pydna@dev_bjorn\n", + " !pip install git+https://github.com/pydna-group/pydna@dev_bjorn\n", " # Install pip version instead (uncomment to install)\n", " # !pip install pydna\n" ] diff --git a/docs/notebooks/Example_Restriction.ipynb b/docs/notebooks/Example_Restriction.ipynb index b50edcec..91406719 100755 --- a/docs/notebooks/Example_Restriction.ipynb +++ b/docs/notebooks/Example_Restriction.ipynb @@ -36,7 +36,7 @@ "if 'google.colab' in sys.modules:\n", " %%capture\n", " # Install the current development version of pydna (comment to install pip version)\n", - " !pip install git+https://github.com/BjornFJohansson/pydna@dev_bjorn\n", + " !pip install git+https://github.com/pydna-group/pydna@dev_bjorn\n", " # Install pip version instead (uncomment to install)\n", " # !pip install pydna\n" ] diff --git a/docs/notebooks/Gibson.ipynb b/docs/notebooks/Gibson.ipynb index 5bba334b..0a739436 100644 --- a/docs/notebooks/Gibson.ipynb +++ b/docs/notebooks/Gibson.ipynb @@ -37,7 +37,7 @@ "if 'google.colab' in sys.modules:\n", " %%capture\n", " # Install the current development version of pydna (comment to install pip version)\n", - " !pip install git+https://github.com/BjornFJohansson/pydna@dev_bjorn\n", + " !pip install git+https://github.com/pydna-group/pydna@dev_bjorn\n", " # Install pip version instead (uncomment to install)\n", " # !pip install pydna\n" ] diff --git a/docs/notebooks/Importing_Seqs.ipynb b/docs/notebooks/Importing_Seqs.ipynb index b606c5ab..16f079fb 100755 --- a/docs/notebooks/Importing_Seqs.ipynb +++ b/docs/notebooks/Importing_Seqs.ipynb @@ -39,7 +39,7 @@ "if 'google.colab' in sys.modules:\n", " %%capture\n", " # Install the current development version of pydna (comment to install pip version)\n", - " !pip install git+https://github.com/BjornFJohansson/pydna@dev_bjorn\n", + " !pip install git+https://github.com/pydna-group/pydna@dev_bjorn\n", " # Install pip version instead (uncomment to install)\n", " # !pip install pydna\n" ] diff --git a/docs/notebooks/PCR.ipynb b/docs/notebooks/PCR.ipynb index 1ecfe0b4..81c48079 100755 --- a/docs/notebooks/PCR.ipynb +++ b/docs/notebooks/PCR.ipynb @@ -37,7 +37,7 @@ "if 'google.colab' in sys.modules:\n", " %%capture\n", " # Install the current development version of pydna (comment to install pip version)\n", - " !pip install git+https://github.com/BjornFJohansson/pydna@dev_bjorn\n", + " !pip install git+https://github.com/pydna-group/pydna@dev_bjorn\n", " # Install pip version instead (uncomment to install)\n", " # !pip install pydna\n" ] diff --git a/docs/notebooks/Restrict_Ligate_Cloning.ipynb b/docs/notebooks/Restrict_Ligate_Cloning.ipynb index 978469e5..55fc35f7 100644 --- a/docs/notebooks/Restrict_Ligate_Cloning.ipynb +++ b/docs/notebooks/Restrict_Ligate_Cloning.ipynb @@ -34,7 +34,7 @@ "if 'google.colab' in sys.modules:\n", " %%capture\n", " # Install the current development version of pydna (comment to install pip version)\n", - " !pip install git+https://github.com/BjornFJohansson/pydna@dev_bjorn\n", + " !pip install git+https://github.com/pydna-group/pydna@dev_bjorn\n", " # Install pip version instead (uncomment to install)\n", " # !pip install pydna\n" ] diff --git a/docs/notebooks/readme_example.ipynb b/docs/notebooks/readme_example.ipynb index 022a4076..68992ece 100644 --- a/docs/notebooks/readme_example.ipynb +++ b/docs/notebooks/readme_example.ipynb @@ -1,369 +1,369 @@ { - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## README Example\n", - "\n", - "This notebook contains the example shown in the README file.\n", - "\n", - "\n", - " \"Open\n", - "" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Install pydna (only when running on Colab)\n", - "import sys\n", - "if 'google.colab' in sys.modules:\n", - " %%capture\n", - " # Install the current development version of pydna (comment to install pip version)\n", - " !pip install git+https://github.com/BjornFJohansson/pydna@dev_bjorn\n", - " # Install pip version instead (uncomment to install)\n", - " # !pip install pydna" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "Dseqrecord(-60)\n", - "\u001b[48;5;11mATGCAAACAGTAATGATGGATGACATTCAAAGCACTGATTCTATTGCTGAAAAAGATAAT\u001b[0m\n", - "TACGTTTGTCATTACTACCTACTGTAAGTTTCGTGACTAAGATAACGACTTTTTCTATTA" - ] - }, - "execution_count": null, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "from pydna.dseqrecord import Dseqrecord\n", - "# Let's create a DNA sequence record, and add a feature to it\n", - "dsr = Dseqrecord(\"ATGCAAACAGTAATGATGGATGACATTCAAAGCACTGATTCTATTGCTGAAAAAGATAAT\")\n", - "dsr.add_feature(x=0, y=60,type=\"gene\", label=\"my_gene\") # We add a feature to highlight the sequence as a gene\n", - "dsr.figure()\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "LOCUS name 60 bp DNA linear UNK 01-JAN-1980\n", - "DEFINITION description.\n", - "ACCESSION id\n", - "VERSION id\n", - "KEYWORDS .\n", - "SOURCE .\n", - " ORGANISM .\n", - " .\n", - "FEATURES Location/Qualifiers\n", - " misc 1..60\n", - " /type=\"gene\"\n", - " /label=\"my_gene\"\n", - "ORIGIN\n", - " 1 atgcaaacag taatgatgga tgacattcaa agcactgatt ctattgctga aaaagataat\n", - "//\n" - ] - } - ], - "source": [ - "# This is how it would look as a genbank file\n", - "print(dsr.format(\"genbank\"))" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "forward primer: ATGCAAACAGTAATGATGGA\n", - "reverse primer: ATTATCTTTTTCAGCAATAGAATCA\n" - ] + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## README Example\n", + "\n", + "This notebook contains the example shown in the README file.\n", + "\n", + "\n", + " \"Open\n", + "" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Install pydna (only when running on Colab)\n", + "import sys\n", + "if 'google.colab' in sys.modules:\n", + " %%capture\n", + " # Install the current development version of pydna (comment to install pip version)\n", + " !pip install git+https://github.com/pydna-group/pydna@dev_bjorn\n", + " # Install pip version instead (uncomment to install)\n", + " # !pip install pydna" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Dseqrecord(-60)\n", + "\u001b[48;5;11mATGCAAACAGTAATGATGGATGACATTCAAAGCACTGATTCTATTGCTGAAAAAGATAAT\u001b[0m\n", + "TACGTTTGTCATTACTACCTACTGTAAGTTTCGTGACTAAGATAACGACTTTTTCTATTA" + ] + }, + "execution_count": null, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "from pydna.dseqrecord import Dseqrecord\n", + "# Let's create a DNA sequence record, and add a feature to it\n", + "dsr = Dseqrecord(\"ATGCAAACAGTAATGATGGATGACATTCAAAGCACTGATTCTATTGCTGAAAAAGATAAT\")\n", + "dsr.add_feature(x=0, y=60,type=\"gene\", label=\"my_gene\") # We add a feature to highlight the sequence as a gene\n", + "dsr.figure()\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "LOCUS name 60 bp DNA linear UNK 01-JAN-1980\n", + "DEFINITION description.\n", + "ACCESSION id\n", + "VERSION id\n", + "KEYWORDS .\n", + "SOURCE .\n", + " ORGANISM .\n", + " .\n", + "FEATURES Location/Qualifiers\n", + " misc 1..60\n", + " /type=\"gene\"\n", + " /label=\"my_gene\"\n", + "ORIGIN\n", + " 1 atgcaaacag taatgatgga tgacattcaa agcactgatt ctattgctga aaaagataat\n", + "//\n" + ] + } + ], + "source": [ + "# This is how it would look as a genbank file\n", + "print(dsr.format(\"genbank\"))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "forward primer: ATGCAAACAGTAATGATGGA\n", + "reverse primer: ATTATCTTTTTCAGCAATAGAATCA\n" + ] + }, + { + "data": { + "text/plain": [ + "5ATGCAAACAGTAATGATGGA...TGATTCTATTGCTGAAAAAGATAAT3\n", + " |||||||||||||||||||||||||\n", + " 3ACTAAGATAACGACTTTTTCTATTA5\n", + "5ATGCAAACAGTAATGATGGA3\n", + " ||||||||||||||||||||\n", + "3TACGTTTGTCATTACTACCT...ACTAAGATAACGACTTTTTCTATTA5" + ] + }, + "execution_count": null, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Now let's design primers to amplify it\n", + "from pydna.design import primer_design\n", + "# limit is the minimum length of the primer, target_tm is the desired melting temperature of the primer\n", + "amplicon = primer_design(dsr, limit=13, target_tm=55)\n", + "# Let's print the primers, and a figure that shows where they align with the template sequence\n", + "print(\"forward primer:\", amplicon.forward_primer.seq)\n", + "print(\"reverse primer:\", amplicon.reverse_primer.seq)\n", + "amplicon.figure()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + " 5ATGCAAACAGTAATGATGGA...TGATTCTATTGCTGAAAAAGATAAT3\n", + " |||||||||||||||||||||||||\n", + " 3ACTAAGATAACGACTTTTTCTATTACCTAGGtttt5\n", + "5ccccGGATCCATGCAAACAGTAATGATGGA3\n", + " ||||||||||||||||||||\n", + " 3TACGTTTGTCATTACTACCT...ACTAAGATAACGACTTTTTCTATTA5" + ] + }, + "execution_count": null, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Let's say we don't want to just amplify it, but we want to add restriction sites to it!\n", + "\n", + "from pydna.amplify import pcr\n", + "# We add the restriction sites to the primers\n", + "forward_primer = \"ccccGGATCC\" + amplicon.forward_primer\n", + "reverse_primer = \"ttttGGATCC\" + amplicon.reverse_primer\n", + "\n", + "# We do the PCR\n", + "pcr_product = pcr(forward_primer, reverse_primer, dsr)\n", + "# The PCR product is of class `Amplicon`, a subclass of `Dseqrecord`.\n", + "# When doing a figure, it shows where primers anneal.\n", + "pcr_product.figure()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Dseqrecord(-80)\n", + "ccccGGATCC\u001b[48;5;11mATGCAAACAGTAATGATGGATGACATTCAAAGCACTGATTCTATTGCTGAAAAAGATAAT\u001b[0mGGATCCaaaa\n", + "ggggCCTAGGTACGTTTGTCATTACTACCTACTGTAAGTTTCGTGACTAAGATAACGACTTTTTCTATTACCTAGGtttt" + ] + }, + "execution_count": null, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# If we want to see the sequence more clearly, we can turn it into a `Dseqrecord`\n", + "pcr_product = Dseqrecord(pcr_product)\n", + "pcr_product.figure()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Dseqrecord(-9)\n", + "\u001b[48;5;11m\u001b[0mccccG \n", + "ggggCCTAG\n", + "\n", + "Dseqrecord(-70)\n", + "GATCC\u001b[48;5;11mATGCAAACAGTAATGATGGATGACATTCAAAGCACTGATTCTATTGCTGAAAAAGATAAT\u001b[0mG \n", + " GTACGTTTGTCATTACTACCTACTGTAAGTTTCGTGACTAAGATAACGACTTTTTCTATTACCTAG\n", + "\n", + "Dseqrecord(-9)\n", + "\u001b[48;5;11m\u001b[0mGATCCaaaa\n", + " Gtttt\n" + ] + } + ], + "source": [ + "from Bio.Restriction import BamHI # cuts GGATCC\n", + "# a, payload, c are the cut fragments\n", + "a, payload, c = pcr_product.cut (BamHI)\n", + "print(a.figure())\n", + "print()\n", + "print (payload.figure())\n", + "print()\n", + "print(c.figure())\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Dseqrecord(o50)\n", + "\u001b[48;5;11m\u001b[0maatgtttttccctCCCGGGcaaaatAGATCTtgctatgcatcatcgatct\n", + "ttacaaaaagggaGGGCCCgttttaTCTAGAacgatacgtagtagctaga" + ] + }, + "execution_count": null, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# We create a circular vector to insert the amplicon into\n", + "vector = Dseqrecord(\"aatgtttttccctCCCGGGcaaaatAGATCTtgctatgcatcatcgatct\", circular=True, name=\"vect\")\n", + "vector.figure()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Dseqrecord(o116)\n", + "aatgtttttccctCCCGGGcaaaatAGATCC\u001b[48;5;11mATGCAAACAGTAATGATGGATGACATTCAAAGCACTGATTCTATTGCTGAAAAAGATAAT\u001b[0mGGATCTtgctatgcatcatcgatct\n", + "ttacaaaaagggaGGGCCCgttttaTCTAGGTACGTTTGTCATTACTACCTACTGTAAGTTTCGTGACTAAGATAACGACTTTTTCTATTACCTAGAacgatacgtagtagctaga" + ] + }, + "execution_count": null, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "from Bio.Restriction import BglII # cuts AGATCT\n", + "linear_vector_bgl = vector.cut(BglII)[0] # Linearize the vector at BglII (produces only one fragment)\n", + "\n", + "# Ligate the fragment of interest to the vector, and call looped() to circularize it\n", + "# synced is used to place the origin coordinate (0) in the same place for rec_vector and vector\n", + "rec_vector= (linear_vector_bgl + payload).looped().synced(vector)\n", + "rec_vector.figure()\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + " -|fragment_A|13\n", + "| \\/\n", + "| /\\\n", + "| 13|fragment_B|13\n", + "| \\/\n", + "| /\\\n", + "| 13|fragment_C|13\n", + "| \\/\n", + "| /\\\n", + "| 13-\n", + "| |\n", + " --------------------------------------------" + ] + }, + "execution_count": null, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Let's simulate a Gibson assembly\n", + "from pydna.assembly import Assembly\n", + "\n", + "fragments = [\n", + " Dseqrecord('aatgtttttccctCACTACGtgctatgcatcat', name=\"fragment_A\"),\n", + " Dseqrecord('tgctatgcatcatCTATGGAcactctaataatg', name=\"fragment_B\"),\n", + " Dseqrecord('cactctaataatgTTACATAaatgtttttccct', name=\"fragment_C\"),\n", + "]\n", + "\n", + "# limit is the min. homology length between fragments in the assembly\n", + "asm = Assembly(fragments, limit=10)\n", + "\n", + "# From the assembly object, which can generate all possible products, get a circular\n", + "product, *rest = asm.assemble_circular()\n", + "\n", + "# We can print a figure that shows the overlaps between fragments\n", + "product.figure()\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Dseqrecord(o60)\n", + "\u001b[48;5;11m\u001b[0maatgtttttccctCACTACGtgctatgcatcatCTATGGAcactctaataatgTTACATA\n", + "ttacaaaaagggaGTGATGCacgatacgtagtaGATACCTgtgagattattacAATGTAT" + ] + }, + "execution_count": null, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Or show the final sequence:\n", + "Dseqrecord(product).figure()" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": ".venv", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.12.6" + } }, - { - "data": { - "text/plain": [ - "5ATGCAAACAGTAATGATGGA...TGATTCTATTGCTGAAAAAGATAAT3\n", - " |||||||||||||||||||||||||\n", - " 3ACTAAGATAACGACTTTTTCTATTA5\n", - "5ATGCAAACAGTAATGATGGA3\n", - " ||||||||||||||||||||\n", - "3TACGTTTGTCATTACTACCT...ACTAAGATAACGACTTTTTCTATTA5" - ] - }, - "execution_count": null, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# Now let's design primers to amplify it\n", - "from pydna.design import primer_design\n", - "# limit is the minimum length of the primer, target_tm is the desired melting temperature of the primer\n", - "amplicon = primer_design(dsr, limit=13, target_tm=55)\n", - "# Let's print the primers, and a figure that shows where they align with the template sequence\n", - "print(\"forward primer:\", amplicon.forward_primer.seq)\n", - "print(\"reverse primer:\", amplicon.reverse_primer.seq)\n", - "amplicon.figure()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - " 5ATGCAAACAGTAATGATGGA...TGATTCTATTGCTGAAAAAGATAAT3\n", - " |||||||||||||||||||||||||\n", - " 3ACTAAGATAACGACTTTTTCTATTACCTAGGtttt5\n", - "5ccccGGATCCATGCAAACAGTAATGATGGA3\n", - " ||||||||||||||||||||\n", - " 3TACGTTTGTCATTACTACCT...ACTAAGATAACGACTTTTTCTATTA5" - ] - }, - "execution_count": null, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# Let's say we don't want to just amplify it, but we want to add restriction sites to it!\n", - "\n", - "from pydna.amplify import pcr\n", - "# We add the restriction sites to the primers\n", - "forward_primer = \"ccccGGATCC\" + amplicon.forward_primer\n", - "reverse_primer = \"ttttGGATCC\" + amplicon.reverse_primer\n", - "\n", - "# We do the PCR\n", - "pcr_product = pcr(forward_primer, reverse_primer, dsr)\n", - "# The PCR product is of class `Amplicon`, a subclass of `Dseqrecord`.\n", - "# When doing a figure, it shows where primers anneal.\n", - "pcr_product.figure()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "Dseqrecord(-80)\n", - "ccccGGATCC\u001b[48;5;11mATGCAAACAGTAATGATGGATGACATTCAAAGCACTGATTCTATTGCTGAAAAAGATAAT\u001b[0mGGATCCaaaa\n", - "ggggCCTAGGTACGTTTGTCATTACTACCTACTGTAAGTTTCGTGACTAAGATAACGACTTTTTCTATTACCTAGGtttt" - ] - }, - "execution_count": null, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# If we want to see the sequence more clearly, we can turn it into a `Dseqrecord`\n", - "pcr_product = Dseqrecord(pcr_product)\n", - "pcr_product.figure()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Dseqrecord(-9)\n", - "\u001b[48;5;11m\u001b[0mccccG \n", - "ggggCCTAG\n", - "\n", - "Dseqrecord(-70)\n", - "GATCC\u001b[48;5;11mATGCAAACAGTAATGATGGATGACATTCAAAGCACTGATTCTATTGCTGAAAAAGATAAT\u001b[0mG \n", - " GTACGTTTGTCATTACTACCTACTGTAAGTTTCGTGACTAAGATAACGACTTTTTCTATTACCTAG\n", - "\n", - "Dseqrecord(-9)\n", - "\u001b[48;5;11m\u001b[0mGATCCaaaa\n", - " Gtttt\n" - ] - } - ], - "source": [ - "from Bio.Restriction import BamHI # cuts GGATCC\n", - "# a, payload, c are the cut fragments\n", - "a, payload, c = pcr_product.cut (BamHI)\n", - "print(a.figure())\n", - "print()\n", - "print (payload.figure())\n", - "print()\n", - "print(c.figure())\n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "Dseqrecord(o50)\n", - "\u001b[48;5;11m\u001b[0maatgtttttccctCCCGGGcaaaatAGATCTtgctatgcatcatcgatct\n", - "ttacaaaaagggaGGGCCCgttttaTCTAGAacgatacgtagtagctaga" - ] - }, - "execution_count": null, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# We create a circular vector to insert the amplicon into\n", - "vector = Dseqrecord(\"aatgtttttccctCCCGGGcaaaatAGATCTtgctatgcatcatcgatct\", circular=True, name=\"vect\")\n", - "vector.figure()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "Dseqrecord(o116)\n", - "aatgtttttccctCCCGGGcaaaatAGATCC\u001b[48;5;11mATGCAAACAGTAATGATGGATGACATTCAAAGCACTGATTCTATTGCTGAAAAAGATAAT\u001b[0mGGATCTtgctatgcatcatcgatct\n", - "ttacaaaaagggaGGGCCCgttttaTCTAGGTACGTTTGTCATTACTACCTACTGTAAGTTTCGTGACTAAGATAACGACTTTTTCTATTACCTAGAacgatacgtagtagctaga" - ] - }, - "execution_count": null, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "from Bio.Restriction import BglII # cuts AGATCT\n", - "linear_vector_bgl = vector.cut(BglII)[0] # Linearize the vector at BglII (produces only one fragment)\n", - "\n", - "# Ligate the fragment of interest to the vector, and call looped() to circularize it\n", - "# synced is used to place the origin coordinate (0) in the same place for rec_vector and vector\n", - "rec_vector= (linear_vector_bgl + payload).looped().synced(vector)\n", - "rec_vector.figure()\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - " -|fragment_A|13\n", - "| \\/\n", - "| /\\\n", - "| 13|fragment_B|13\n", - "| \\/\n", - "| /\\\n", - "| 13|fragment_C|13\n", - "| \\/\n", - "| /\\\n", - "| 13-\n", - "| |\n", - " --------------------------------------------" - ] - }, - "execution_count": null, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# Let's simulate a Gibson assembly\n", - "from pydna.assembly import Assembly\n", - "\n", - "fragments = [\n", - " Dseqrecord('aatgtttttccctCACTACGtgctatgcatcat', name=\"fragment_A\"),\n", - " Dseqrecord('tgctatgcatcatCTATGGAcactctaataatg', name=\"fragment_B\"),\n", - " Dseqrecord('cactctaataatgTTACATAaatgtttttccct', name=\"fragment_C\"),\n", - "]\n", - "\n", - "# limit is the min. homology length between fragments in the assembly\n", - "asm = Assembly(fragments, limit=10)\n", - "\n", - "# From the assembly object, which can generate all possible products, get a circular\n", - "product, *rest = asm.assemble_circular()\n", - "\n", - "# We can print a figure that shows the overlaps between fragments\n", - "product.figure()\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "Dseqrecord(o60)\n", - "\u001b[48;5;11m\u001b[0maatgtttttccctCACTACGtgctatgcatcatCTATGGAcactctaataatgTTACATA\n", - "ttacaaaaagggaGTGATGCacgatacgtagtaGATACCTgtgagattattacAATGTAT" - ] - }, - "execution_count": null, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# Or show the final sequence:\n", - "Dseqrecord(product).figure()" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": ".venv", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.12.6" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} + "nbformat": 4, + "nbformat_minor": 2 +} \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml index e474b013..fa4c5b63 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,5 +1,8 @@ [project] -authors = ["Björn F. Johansson"] +authors = [ + {name = "Björn F. Johansson", email = "bjornjobb@gmail.com"}, + {name = "Manuel Lera-Ramirez", email = "manulera14@gmail.com"} +] classifiers = [ "Development Status :: 4 - Beta", "Environment :: Console", @@ -21,16 +24,15 @@ dynamic = ["version"] name = "pydna" readme = "README.md" [tool.poetry.urls] -Changelog = "https://github.com/BjornFJohansson/pydna/blob/master/docs/CHANGELOG.md#changelog" +Changelog = "https://github.com/pydna-group/pydna/blob/master/docs/CHANGELOG.md#changelog" [tool.poetry] -authors = ["BjornFJohansson "] description = "Representing double stranded DNA and functions for simulating cloning and homologous recombination between DNA molecules." -documentation = "https://pydna.readthedocs.io/?badge=latest" -homepage = "https://github.com/BjornFJohansson/pydna#-pydna" +documentation = "https://pydna-group.github.io/pydna" +homepage = "https://github.com/pydna-group/pydna#-pydna" license = "BSD" name = "pydna" readme = "README.md" -repository = "https://github.com/BjornFJohansson/pydna/tree/dev_bjorn" +repository = "https://github.com/pydna-group/pydna/tree/master" version = "6.0.0-a.24.post.17+b7b559bd66" [tool.poetry.dependencies] appdirs = ">=1.4.4" diff --git a/scripts/conda-build/meta (copy).yaml b/scripts/conda-build/meta (copy).yaml index bba4f2eb..59817340 100755 --- a/scripts/conda-build/meta (copy).yaml +++ b/scripts/conda-build/meta (copy).yaml @@ -46,14 +46,14 @@ test: - src - src/pydna about: - home: https://github.com/BjornFJohansson/pydna + home: https://github.com/pydna-group/pydna license: BSD-3-Clause license_family: BSD license_file: LICENSE.txt summary: Representing double stranded DNA and simulating cloning, homologous recombination, Gibson assembly, Gel electrophoresis etc. description: Representing double stranded DNA and simulating cloning, homologous recombination, Gibson assembly, Gel electrophoresis etc. - doc_url: https://pydna.readthedocs.io - dev_url: https://github.com/BjornFJohansson/pydna + doc_url: https://pydna-group.github.io/pydna + dev_url: https://github.com/pydna-group/pydna extra: maintainers: - "Björn Johansson " diff --git a/scripts/conda-build/meta (copy2).yaml b/scripts/conda-build/meta (copy2).yaml index 0cd73f41..be76e2d2 100755 --- a/scripts/conda-build/meta (copy2).yaml +++ b/scripts/conda-build/meta (copy2).yaml @@ -48,14 +48,14 @@ test: - src - src/pydna about: - home: https://github.com/BjornFJohansson/pydna + home: https://github.com/pydna-group/pydna license: BSD-3-Clause license_family: BSD license_file: LICENSE.txt summary: Representing double stranded DNA and simulating cloning, homologous recombination, Gibson assembly, Gel electrophoresis etc. description: Representing double stranded DNA and simulating cloning, homologous recombination, Gibson assembly, Gel electrophoresis etc. - doc_url: https://pydna.readthedocs.io - dev_url: https://github.com/BjornFJohansson/pydna + doc_url: https://pydna-group.github.io/pydna + dev_url: https://github.com/pydna-group/pydna extra: maintainers: - "Björn Johansson " diff --git a/scripts/conda-build/meta2.yaml b/scripts/conda-build/meta2.yaml index bba4f2eb..59817340 100755 --- a/scripts/conda-build/meta2.yaml +++ b/scripts/conda-build/meta2.yaml @@ -46,14 +46,14 @@ test: - src - src/pydna about: - home: https://github.com/BjornFJohansson/pydna + home: https://github.com/pydna-group/pydna license: BSD-3-Clause license_family: BSD license_file: LICENSE.txt summary: Representing double stranded DNA and simulating cloning, homologous recombination, Gibson assembly, Gel electrophoresis etc. description: Representing double stranded DNA and simulating cloning, homologous recombination, Gibson assembly, Gel electrophoresis etc. - doc_url: https://pydna.readthedocs.io - dev_url: https://github.com/BjornFJohansson/pydna + doc_url: https://pydna-group.github.io/pydna + dev_url: https://github.com/pydna-group/pydna extra: maintainers: - "Björn Johansson " diff --git a/scripts/features/files_for_annotation_function/post.md b/scripts/features/files_for_annotation_function/post.md index ca2aaeaf..6b4b2dfe 100644 --- a/scripts/features/files_for_annotation_function/post.md +++ b/scripts/features/files_for_annotation_function/post.md @@ -2,7 +2,7 @@ genocad.com seems still down But I managed to download the supplementary files from the [paper](https://www.ncbi.nlm.nih.gov/pubmed/25925571). -I put them [here](https://github.com/BjornFJohansson/pydna/tree/py3dev/scripts/files_for_annotation_function) +I put them [here](https://github.com/pydna-group/pydna/tree/py3dev/scripts/files_for_annotation_function) A number of sbol files seems to hold most or all of the data: diff --git a/src/pydna/__init__.py b/src/pydna/__init__.py index 6c6a09f3..98706826 100644 --- a/src/pydna/__init__.py +++ b/src/pydna/__init__.py @@ -16,7 +16,7 @@ Pydna is a python package providing code for simulation of the creation of recombinant DNA molecules using `molecular biology `_ -techniques. Development of pydna happens in this Github `repository `_. +techniques. Development of pydna happens in this Github `repository `_. Provided: 1. PCR simulation @@ -87,7 +87,7 @@ The doctrings are also used to provide an automaticly generated reference manual available online at -`read the docs `_. +`read the docs `_. Docstrings can be explored using `IPython `_, an advanced Python shell with @@ -112,7 +112,7 @@ ----------------- The pydna source code is -`available on Github `_. +`available on Github `_. How to get more help -------------------- @@ -121,7 +121,7 @@ `Google group `_ for pydna, this is the preferred location for help. If you find bugs in pydna itself, open an issue at the -`Github repository `_. +`Github repository `_. Examples of pydna in use ------------------------ diff --git a/src/pydna/dseqrecord.py b/src/pydna/dseqrecord.py index cfeb2815..83d848fd 100644 --- a/src/pydna/dseqrecord.py +++ b/src/pydna/dseqrecord.py @@ -806,7 +806,7 @@ def __getitem__(self, sl): if not self.circular or sl_start < sl_stop: # TODO: special case for sl_end == 0 in circular sequences - # related to https://github.com/BjornFJohansson/pydna/issues/161 + # related to https://github.com/pydna-group/pydna/issues/161 if self.circular and sl.stop == 0: sl = slice(sl.start, len(self.seq), sl.step) answer.features = super().__getitem__(sl).features @@ -1283,7 +1283,7 @@ def cut(self, *enzymes): def apply_cut(self, left_cut, right_cut): dseq = self.seq.apply_cut(left_cut, right_cut) - # TODO: maybe remove depending on https://github.com/BjornFJohansson/pydna/issues/161 + # TODO: maybe remove depending on https://github.com/pydna-group/pydna/issues/161 if left_cut == right_cut: # Not really a cut, but to handle the general case @@ -1292,7 +1292,7 @@ def apply_cut(self, left_cut, right_cut): else: # The features that span the origin if shifting with left_cut, but that do not cross # the cut site should be included, and if there is a feature within the cut site, it should - # be duplicated. See https://github.com/BjornFJohansson/pydna/issues/180 for a practical example. + # be duplicated. See https://github.com/pydna-group/pydna/issues/180 for a practical example. # # Let's say we are going to open a circular plasmid like below (| inidicate cuts, numbers indicate # features) diff --git a/src/pydna/utils.py b/src/pydna/utils.py index b42d4696..e4ff465d 100644 --- a/src/pydna/utils.py +++ b/src/pydna/utils.py @@ -94,7 +94,7 @@ def shift_location(original_location, shift, lim): # in which consecutive parts do not have any bases between them. # This type of feature is generated to represent a feature that # spans the origin of a circular sequence. See more details in - # https://github.com/BjornFJohansson/pydna/issues/195 + # https://github.com/pydna-group/pydna/issues/195 if len(part) == 0: newparts.append(_sl(new_start, new_start, strand)) diff --git a/tests/test_module_amplify.py b/tests/test_module_amplify.py index 0fa15014..3344043c 100644 --- a/tests/test_module_amplify.py +++ b/tests/test_module_amplify.py @@ -784,7 +784,7 @@ def test_shifts(): def test_annotation(): """ Test that annotations are correctly added to the amplicon in primers with tails - https://github.com/BjornFJohansson/pydna/issues/279 + https://github.com/pydna-group/pydna/issues/279 """ from pydna.amplify import pcr from pydna.dseqrecord import Dseqrecord diff --git a/tests/test_module_dseq.py b/tests/test_module_dseq.py index aaf8e2a2..504ac13d 100644 --- a/tests/test_module_dseq.py +++ b/tests/test_module_dseq.py @@ -544,7 +544,7 @@ def test_dseq(): assert obj.cut(rb) == obj.cut(BamHI, BglII) == obj.cut(BglII, BamHI) obj = Dseq("ggatccAGATCT", circular=True) - # TODO: address this test change Related to https://github.com/BjornFJohansson/pydna/issues/78 + # TODO: address this test change Related to https://github.com/pydna-group/pydna/issues/78 assert obj.cut(rb) == obj.cut(BamHI, BglII) == obj.cut(BglII, BamHI) obj = Dseq("AGATCTggatcc", circular=True) @@ -578,7 +578,7 @@ def test_Dseq_slicing2(): from Bio.Restriction import BamHI, EcoRI, KpnI a = Dseq("aaGGATCCnnnnnnnnnGAATTCccc", circular=True) - # TODO: address this test change Related to https://github.com/BjornFJohansson/pydna/issues/78 + # TODO: address this test change Related to https://github.com/pydna-group/pydna/issues/78 assert a.cut( EcoRI, @@ -608,7 +608,7 @@ def test_Dseq___getitem__(): assert s[9:1] == Dseq("") assert t[9:1] == Dseq("") - # Indexing of full circular molecule (https://github.com/BjornFJohansson/pydna/issues/161) + # Indexing of full circular molecule (https://github.com/pydna-group/pydna/issues/161) s = Dseq("GGATCC", circular=True) str_seq = str(s) for shift in range(len(s)): @@ -742,7 +742,7 @@ def test_misc(): a, b = x.cut(NotI) z = (a + b).looped() - # TODO: address this test change Related to https://github.com/BjornFJohansson/pydna/issues/78 + # TODO: address this test change Related to https://github.com/pydna-group/pydna/issues/78 assert z.shifted(-6) == x diff --git a/tests/test_module_dseqrecord.py b/tests/test_module_dseqrecord.py index 6cf61f11..07d44e2a 100644 --- a/tests/test_module_dseqrecord.py +++ b/tests/test_module_dseqrecord.py @@ -1893,7 +1893,7 @@ def test___getitem__(): assert len(seqRecord[2:20].features) == 1 assert len(seqRecord[13:8].features) == 1 - # Indexing of full circular molecule (https://github.com/BjornFJohansson/pydna/issues/161) + # Indexing of full circular molecule (https://github.com/pydna-group/pydna/issues/161) s = Dseqrecord("GGATCC", circular=True) str_seq = str(s.seq) for shift in range(len(s)): diff --git a/tests/test_module_utils.py b/tests/test_module_utils.py index 6a25d74f..55f10dcf 100644 --- a/tests/test_module_utils.py +++ b/tests/test_module_utils.py @@ -468,7 +468,7 @@ def test_shift_location(): # TODO: more tests here - # Shifting of locations should be reversible (https://github.com/BjornFJohansson/pydna/issues/195) + # Shifting of locations should be reversible (https://github.com/pydna-group/pydna/issues/195) for strand in (1, -1, None): loc = SimpleLocation(0, 2, strand) assert shift_location(shift_location(loc, 1, 6), -1, 6) == loc @@ -483,7 +483,7 @@ def test_shift_location(): assert shift_location(loc, -1, 6) == SimpleLocation(5, 6, strand) + SimpleLocation(0, 3, strand) # Shifting ignoring the sequence length - # See https://github.com/BjornFJohansson/pydna/issues/281 + # See https://github.com/pydna-group/pydna/issues/281 for strand in (1, -1, None): loc = SimpleLocation(4, 6, strand) assert shift_location(loc, 1000, None) == SimpleLocation(1004, 1006, strand)