diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml new file mode 100644 index 0000000..aa09f5c --- /dev/null +++ b/.github/workflows/publish.yml @@ -0,0 +1,35 @@ +name: Publish Python Package to PyPI + +on: + release: + types: [published] + workflow_dispatch: + +jobs: + Publish: + # prevents this action from running on forks + if: github.repository == 'open2c/assemblyinfo' + + runs-on: ubuntu-latest + permissions: + id-token: write + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Python + uses: actions/setup-python@v5 + with: + python-version: "3.x" + + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install build + + - name: Build + run: python -m build + + - name: Publish distribution 📦 to PyPI + uses: pypa/gh-action-pypi-publish@release/v1 diff --git a/README.md b/README.md index 87d582a..3b54041 100644 --- a/README.md +++ b/README.md @@ -1 +1,113 @@ -# assemblyinfo +# Assemblyinfo: Interact with assembly metadata in Python + +![CI](https://github.com/open2c/assemblyinfo/actions/workflows/ci.yml/badge.svg) +[![Docs status](https://readthedocs.org/projects/genomeinfo/badge/)](https://genomeinfo.readthedocs.io/en/latest/) +[![Slack](https://img.shields.io/badge/chat-slack-%233F0F3F?logo=slack)](https://bit.ly/open2c-slack) + +Assemblyinfo simplifies the management and analysis of genome assembly metadata in Python. + +This package provides: + +* Efficient tools for querying and manipulating assembly information datasets. +* Streamlined methods for importing, exporting, and converting between common chromosome formats. +* Utilities for retrieving assembly statistics across different versions or species. + +Read the [documentation](https://genomeinfo.readthedocs.io/en/latest/) for more information. + + +## Installation + +Bioframe is available on [PyPI](https://pypi.org/project/bioframe/): + +```sh +pip install assemblyinfo +``` + +## Basic operations on chromosome data + +Assemblyinfo offers a flexible and straigthforward interface to interact and perform basic queries. + +```python +import assemblyinfo + +db = assemblyinfo.connect() +hg38 = db.assembly_info("hg38", roles=["assembled"]) +``` + +Easily allows getting chromosome sizes: + +```text +hg38.chromsizes + +> name +> chr1 248956422 +> chr2 242193529 +> ... +``` + +chromosome equivalences: + +```text +hg38.chromeq + +> ncbi genbank refseq +> chr1 1 CM000663.2 NC_000001.11 +> chr2 2 CM000664.2 NC_000002.12 +> chr3 3 CM000665.2 NC_000003.12 +> ... +``` + +or assembly metadata: + +```text +hg38.metadata + +> {'assembly_level': 'Chromosome', + 'assembly_type': 'haploid-with-alt-loci', + 'bioproject': 'PRJNA168', + 'submitter': 'Genome Reference Consortium', + 'synonyms': ['GRCh38', 'hg38'], + 'taxid': '9606', + 'species': 'homo_sapiens', + 'common_name': 'human', + ... } +``` + +and more! + +# Request an assembly + +Feel free to open an issue and request a non-reference assembly! Current supported species are: + +```plaintext +['caenorhabditis_elegans', + 'homo_sapiens', + 'mus_musculus', + 'drosophila_melanogaster', + 'danio_rerio', + 'bos_taurus', + 'gallus_gallus', + 'canis_lupus_familiaris'] +``` + +You also can easily see which specific assemblies are supported by: + +```python +db = assemblyinfo.connect() +db.available_assemblies() +``` + +## Citing + +If you use ***assemblyinfo*** in your work, please refer to: + +```bibtex +@software{assemblyinfo_2024, + author = {Open2C}, + title = {assemblyinfo}, + year = {2024}, + publisher = {Github}, + version = {v0.0.1}, + url = {https://github.com/open2c/assemblyinfo} +} +``` diff --git a/assemblyinfo/core/assembly.py b/assemblyinfo/core/assembly.py index 1b5b9e1..f23dbb2 100644 --- a/assemblyinfo/core/assembly.py +++ b/assemblyinfo/core/assembly.py @@ -35,8 +35,8 @@ def chromeq(self) -> Dict[str, Dict[str, str]]: return pd.DataFrame(self.aliases).T def __repr__(self): - return (f"Assembly(assembly={self.assembly}", - f"species={self.species}", + return (f"Assembly(assembly={self.assembly}, " + f"species={self.species}, " f"common_name={self.common_name})") diff --git a/docs/tutorials/get_quick_stats.ipynb b/docs/tutorials/get_quick_stats.ipynb index 2d00e90..7b23297 100644 --- a/docs/tutorials/get_quick_stats.ipynb +++ b/docs/tutorials/get_quick_stats.ipynb @@ -7,63 +7,37 @@ "source": [ "# Get quick insights about the species you're working on!\n", "\n", - "Retrieve useful stats using GenomeInfo for desired species." + "Retrieve useful stats using AssemblyInfo for desired species." ] }, { "cell_type": "code", - "execution_count": 1, + "execution_count": 2, "id": "685ac1c1-bb6d-4b4e-a785-a101e09ee983", - "metadata": { - "collapsed": true, - "jupyter": { - "outputs_hidden": true - } - }, + "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "/home/alejandro/Documents/projects/forks/genomeinfo\n", "Defaulting to user installation because normal site-packages is not writeable\n", - "Obtaining file:///home/alejandro/Documents/projects/forks/genomeinfo\n", - " Installing build dependencies ... \u001b[?25ldone\n", - "\u001b[?25h Checking if build backend supports build_editable ... \u001b[?25ldone\n", - "\u001b[?25h Getting requirements to build editable ... \u001b[?25ldone\n", - "\u001b[?25h Installing backend dependencies ... \u001b[?25ldone\n", - "\u001b[?25h Preparing editable metadata (pyproject.toml) ... \u001b[?25ldone\n", - "\u001b[?25hRequirement already satisfied: numpy<2,>=1.10 in /usr/lib64/python3.11/site-packages (from genomeinfo==0.1.0) (1.24.3)\n", - "Requirement already satisfied: pandas>=1.3 in /home/alejandro/.local/lib/python3.11/site-packages (from genomeinfo==0.1.0) (1.5.3)\n", - "Requirement already satisfied: pyarrow>=5.0 in /home/alejandro/.local/lib/python3.11/site-packages (from genomeinfo==0.1.0) (16.1.0)\n", - "Requirement already satisfied: python-dateutil>=2.8.1 in /usr/lib/python3.11/site-packages (from pandas>=1.3->genomeinfo==0.1.0) (2.8.2)\n", - "Requirement already satisfied: pytz>=2020.1 in /usr/lib/python3.11/site-packages (from pandas>=1.3->genomeinfo==0.1.0) (2023.3.post1)\n", - "Requirement already satisfied: six>=1.5 in /usr/lib/python3.11/site-packages (from python-dateutil>=2.8.1->pandas>=1.3->genomeinfo==0.1.0) (1.16.0)\n", - "Building wheels for collected packages: genomeinfo\n", - " Building editable for genomeinfo (pyproject.toml) ... \u001b[?25ldone\n", - "\u001b[?25h Created wheel for genomeinfo: filename=genomeinfo-0.1.0-py2.py3-none-any.whl size=2327 sha256=53ce877682e61a6a75f45e4398587bc38f6925a3e3849f59b4be67452f75ddcc\n", - " Stored in directory: /tmp/pip-ephem-wheel-cache-pujs6iy3/wheels/4e/cb/e8/0baa7aa991848767127e29ea4738849dea6d2c9bd867edb942\n", - "Successfully built genomeinfo\n", - "Installing collected packages: genomeinfo\n", - " Attempting uninstall: genomeinfo\n", - " Found existing installation: genomeinfo 0.1.0\n", - " Uninstalling genomeinfo-0.1.0:\n", - " Successfully uninstalled genomeinfo-0.1.0\n", - "Successfully installed genomeinfo-0.1.0\n" + "Requirement already satisfied: assemblyinfo in /home/alejandro/.local/lib/python3.11/site-packages (0.0.1)\n", + "Requirement already satisfied: numpy<2,>=1.10 in /usr/lib64/python3.11/site-packages (from assemblyinfo) (1.24.3)\n", + "Requirement already satisfied: pandas>=1.3 in /home/alejandro/.local/lib/python3.11/site-packages (from assemblyinfo) (1.5.3)\n", + "Requirement already satisfied: pyarrow>=5.0 in /home/alejandro/.local/lib/python3.11/site-packages (from assemblyinfo) (16.1.0)\n", + "Requirement already satisfied: python-dateutil>=2.8.1 in /usr/lib/python3.11/site-packages (from pandas>=1.3->assemblyinfo) (2.8.2)\n", + "Requirement already satisfied: pytz>=2020.1 in /usr/lib/python3.11/site-packages (from pandas>=1.3->assemblyinfo) (2023.3.post1)\n", + "Requirement already satisfied: six>=1.5 in /usr/lib/python3.11/site-packages (from python-dateutil>=2.8.1->pandas>=1.3->assemblyinfo) (1.16.0)\n" ] } ], "source": [ - "# Assumming you are running this from your computer\n", - "# At this moment, GenomeInfo is not available in pypi yet\n", - "\n", - "%cd ../\n", - "!pip3 install -e ." + "!pip3 install assemblyinfo" ] }, { "cell_type": "code", - "execution_count": 46, + "execution_count": 3, "id": "e984df29-5550-49e1-8e0e-57871e4e409f", "metadata": {}, "outputs": [], @@ -72,47 +46,36 @@ "\n", "import matplotlib.pyplot as plt\n", "import pandas as pd\n", - "from genomeinfo import GenomeInfo" + "import assemblyinfo" ] }, { "cell_type": "code", - "execution_count": 47, + "execution_count": 4, "id": "c873247a-98d9-41e9-bd5e-6b0f2537b660", "metadata": {}, "outputs": [], "source": [ "# use the connect() method to retrieve our database!\n", "\n", - "db = GenomeInfo.connect()" + "db = assemblyinfo.connect()" ] }, { "cell_type": "code", - "execution_count": 48, + "execution_count": 8, "id": "ebb9df1d-dad9-45fd-973b-db76dd11df50", "metadata": {}, "outputs": [ { - "name": "stdout", - "output_type": "stream", - "text": [ - "Genome Information:\n", - "===================\n", - "Species:\n", - " - caenorhabditis_elegans, homo_sapiens, mus_musculus, drosophila_melanogaster, danio_rerio, bos_taurus, gallus_gallus, canis_lupus_familiaris\n", - "\n", - "Common Names:\n", - " - celegans, human, mouse, fruitfly, zebrafish, cow, chicken, dog\n", - "\n", - "Assemblies (UCSC):\n", - " - ce11, ce6, hg19, hg38, hg17, hg18, mm9, mm10, mm39, mm6, mm7, mm8, dm3, dm6, danRer6, danRer7, danRer10, danRer11, danRer5, bosTau9, galGal7, canFam4, hs1, canFam2, canFam3, canFam6, ROS_Cfam_1.0, galGal3, galGal4, galGal5, galGal6, canFam5\n", - "\n", - "Assemblies (NCBI):\n", - " - WS144, WBcel215, WBcel235, WS190, WS195, GRCh37, GRCh38, NCBI35, NCBI36, MGSCv37, GRCm38, GRCm39, MGSCv34, MGSCv35, MGSCv36, Release_5, Release_6, Release_6_plus_ISO1_MT, Zv8, Zv9, GRCz10, GRCz11, Zv7, ARS-UCD1.1, ARS-UCD1.2, ARS-UCD1.3, ARS-UCD2.0, bGalGal1.mat.broiler.GRCg7b, UU_Cfam_GSD_1.0, T2T-CHM13, ASM3317019v1, ASM3317019v2, CanFam2.0, CanFam3.1, Dog10K_Boxer_Tasha, ROS_Cfam_1.0, Gallus_gallus-2.1, Gallus_gallus-4.0, Gallus_gallus-5.0, GRCg6, GRCg6a, UMICH_Zoey_3.1, ASM2820141v1\n", - "\n", - "Please pick an entry and retrieve your desired data!\n" - ] + "data": { + "text/plain": [ + "'Genome Information:\\n===================\\nSpecies:\\n - caenorhabditis_elegans, homo_sapiens, mus_musculus, drosophila_melanogaster, danio_rerio, bos_taurus, gallus_gallus, canis_lupus_familiaris\\n\\nCommon Names:\\n - celegans, human, mouse, fruitfly, zebrafish, cow, chicken, dog\\n\\nAssemblies (UCSC):\\n - ce11, ce6, hg19, hg38, hg17, hg18, mm9, mm10, mm39, mm6, mm7, mm8, dm3, dm6, danRer6, danRer7, danRer10, danRer11, danRer5, bosTau9, galGal7, canFam4, hs1, canFam2, canFam3, canFam6, ROS_Cfam_1.0, galGal3, galGal4, galGal5, galGal6, canFam5\\n\\nAssemblies (NCBI):\\n - WS144, WBcel215, WBcel235, WS190, WS195, GRCh37, GRCh38, NCBI35, NCBI36, MGSCv37, GRCm38, GRCm39, MGSCv34, MGSCv35, MGSCv36, Release_5, Release_6, Release_6_plus_ISO1_MT, Zv8, Zv9, GRCz10, GRCz11, Zv7, ARS-UCD1.1, ARS-UCD1.2, ARS-UCD1.3, ARS-UCD2.0, bGalGal1.mat.broiler.GRCg7b, UU_Cfam_GSD_1.0, T2T-CHM13, ASM3317019v1, ASM3317019v2, CanFam2.0, CanFam3.1, Dog10K_Boxer_Tasha, ROS_Cfam_1.0, Gallus_gallus-2.1, Gallus_gallus-4.0, Gallus_gallus-5.0, GRCg6, GRCg6a, UMICH_Zoey_3.1, ASM2820141v1\\n\\nPlease pick an entry and retrieve your desired data!'" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" } ], "source": [ @@ -123,68 +86,37 @@ }, { "cell_type": "code", - "execution_count": 49, + "execution_count": 15, "id": "50d5bbfe-df27-44d7-9c7b-445822a2cace", "metadata": {}, "outputs": [], "source": [ - "# for this example, we are going to use the dog as our model!\n", + "# for this example, we are going to use one of the dog assemblies as our model!\n", "\n", - "df = db.get_db().set_index(\"common_name\").loc[\"dog\",:].reset_index()" + "df = db.assembly_info(\"canFam6\", roles=[\"assembled\"], units=[\"primary\"])" ] }, { "cell_type": "code", - "execution_count": 50, - "id": "4277e73e-a9e8-48df-a197-1ff2d958ebe6", + "execution_count": 26, + "id": "4df1036d-4ca5-4577-8157-a08d4e3b68c9", "metadata": {}, "outputs": [], "source": [ - "# here, we extract the scaffold-N50 in kb for each dog assembly\n", - "\n", - "n50 = [\n", - " (df.loc[idx, \"assembly\"], df.loc[idx, \"metadata\"].get('scaffold-N50')/1000)\n", - " for idx in df.index\n", - "]" - ] - }, - { - "cell_type": "code", - "execution_count": 51, - "id": "67bb18e1-f7e9-4914-aa80-479a4935afce", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[('UU_Cfam_GSD_1.0', 64299.765),\n", - " ('CanFam2.0', 45337.677),\n", - " ('CanFam3.1', 45876.61),\n", - " ('Dog10K_Boxer_Tasha', 63738.581),\n", - " ('ROS_Cfam_1.0', 64037.277),\n", - " ('UMICH_Zoey_3.1', 64204.256)]" - ] - }, - "execution_count": 51, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# let's have a look!\n", + "# we will extract the ungapped length of each assembled and primary chromosomes\n", "\n", - "n50" + "ungapped_lengths = df.seqinfo[\"all-ungapped-length\"]" ] }, { "cell_type": "code", - "execution_count": 52, + "execution_count": 28, "id": "97fb5b8f-26b0-415a-828c-800e4b9a0e12", "metadata": {}, "outputs": [ { "data": { - "image/png": "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", + "image/png": "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\n", "text/plain": [ "
" ] @@ -199,9 +131,8 @@ "# now, we are going to plot it!\n", "\n", "ax = (\n", - " pd.DataFrame(n50, columns=['assembly', 'n50'])\n", - " .set_index('assembly')\n", - " .plot(kind='bar', legend=False, title=\"Comparing Dog assemblies\")\n", + " ungapped_lengths\n", + " .plot(kind='bar', legend=False, title=\"Comparing unagpped lengths across chromosomes\")\n", ")\n", "\n", "plt.xticks(rotation=45, ha='right')\n", diff --git a/docs/tutorials/retrieve_chromosome_data.ipynb b/docs/tutorials/retrieve_chromosome_data.ipynb index f61c872..2139932 100644 --- a/docs/tutorials/retrieve_chromosome_data.ipynb +++ b/docs/tutorials/retrieve_chromosome_data.ipynb @@ -7,7 +7,7 @@ "source": [ "# Retrieve chromosome data using GenomeInfo!\n", "\n", - "Using GenomeInfo, we will retrieve the chromosome sizes from mm9!" + "Using AssemblyInfo, we will retrieve the chromosome sizes from mm9!" ] }, { @@ -15,10 +15,6 @@ "execution_count": 1, "id": "d9fb241d-6729-49f0-85a2-e5e4be69493c", "metadata": { - "collapsed": true, - "jupyter": { - "outputs_hidden": true - }, "scrolled": true }, "outputs": [ @@ -26,40 +22,19 @@ "name": "stdout", "output_type": "stream", "text": [ - "/home/alejandro/Documents/projects/forks/genomeinfo\n", "Defaulting to user installation because normal site-packages is not writeable\n", - "Obtaining file:///home/alejandro/Documents/projects/forks/genomeinfo\n", - " Installing build dependencies ... \u001b[?25ldone\n", - "\u001b[?25h Checking if build backend supports build_editable ... \u001b[?25ldone\n", - "\u001b[?25h Getting requirements to build editable ... \u001b[?25ldone\n", - "\u001b[?25h Installing backend dependencies ... \u001b[?25ldone\n", - "\u001b[?25h Preparing editable metadata (pyproject.toml) ... \u001b[?25ldone\n", - "\u001b[?25hRequirement already satisfied: numpy<2,>=1.10 in /usr/lib64/python3.11/site-packages (from genomeinfo==0.1.0) (1.24.3)\n", - "Requirement already satisfied: pandas>=1.3 in /home/alejandro/.local/lib/python3.11/site-packages (from genomeinfo==0.1.0) (1.5.3)\n", - "Requirement already satisfied: pyarrow>=5.0 in /home/alejandro/.local/lib/python3.11/site-packages (from genomeinfo==0.1.0) (16.1.0)\n", - "Requirement already satisfied: python-dateutil>=2.8.1 in /usr/lib/python3.11/site-packages (from pandas>=1.3->genomeinfo==0.1.0) (2.8.2)\n", - "Requirement already satisfied: pytz>=2020.1 in /usr/lib/python3.11/site-packages (from pandas>=1.3->genomeinfo==0.1.0) (2023.3.post1)\n", - "Requirement already satisfied: six>=1.5 in /usr/lib/python3.11/site-packages (from python-dateutil>=2.8.1->pandas>=1.3->genomeinfo==0.1.0) (1.16.0)\n", - "Building wheels for collected packages: genomeinfo\n", - " Building editable for genomeinfo (pyproject.toml) ... \u001b[?25ldone\n", - "\u001b[?25h Created wheel for genomeinfo: filename=genomeinfo-0.1.0-py2.py3-none-any.whl size=2327 sha256=53ce877682e61a6a75f45e4398587bc38f6925a3e3849f59b4be67452f75ddcc\n", - " Stored in directory: /tmp/pip-ephem-wheel-cache-xtzikhdz/wheels/4e/cb/e8/0baa7aa991848767127e29ea4738849dea6d2c9bd867edb942\n", - "Successfully built genomeinfo\n", - "Installing collected packages: genomeinfo\n", - " Attempting uninstall: genomeinfo\n", - " Found existing installation: genomeinfo 0.1.0\n", - " Uninstalling genomeinfo-0.1.0:\n", - " Successfully uninstalled genomeinfo-0.1.0\n", - "Successfully installed genomeinfo-0.1.0\n" + "Requirement already satisfied: assemblyinfo in /home/alejandro/.local/lib/python3.11/site-packages (0.0.1)\n", + "Requirement already satisfied: numpy<2,>=1.10 in /usr/lib64/python3.11/site-packages (from assemblyinfo) (1.24.3)\n", + "Requirement already satisfied: pandas>=1.3 in /home/alejandro/.local/lib/python3.11/site-packages (from assemblyinfo) (1.5.3)\n", + "Requirement already satisfied: pyarrow>=5.0 in /home/alejandro/.local/lib/python3.11/site-packages (from assemblyinfo) (16.1.0)\n", + "Requirement already satisfied: python-dateutil>=2.8.1 in /usr/lib/python3.11/site-packages (from pandas>=1.3->assemblyinfo) (2.8.2)\n", + "Requirement already satisfied: pytz>=2020.1 in /usr/lib/python3.11/site-packages (from pandas>=1.3->assemblyinfo) (2023.3.post1)\n", + "Requirement already satisfied: six>=1.5 in /usr/lib/python3.11/site-packages (from python-dateutil>=2.8.1->pandas>=1.3->assemblyinfo) (1.16.0)\n" ] } ], "source": [ - "# Assumming you are running this from your computer\n", - "# At this moment, GenomeInfo is not available in pypi yet\n", - "\n", - "%cd ../\n", - "!pip3 install -e ." + "!pip3 install assemblyinfo" ] }, { @@ -69,9 +44,7 @@ "metadata": {}, "outputs": [], "source": [ - "# import GenomeInfo from the package!\n", - "\n", - "from genomeinfo import GenomeInfo" + "import assemblyinfo" ] }, { @@ -83,61 +56,124 @@ "source": [ "# use the connect() method to retrieve our database!\n", "\n", - "db = GenomeInfo.connect()" + "db = assemblyinfo.connect()" ] }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 5, "id": "184c2be8-2419-42c5-8aa6-6479a8d33baa", "metadata": {}, "outputs": [ { - "name": "stdout", - "output_type": "stream", - "text": [ - "Genome Information:\n", - "===================\n", - "Species:\n", - " - caenorhabditis_elegans, homo_sapiens, mus_musculus, drosophila_melanogaster, danio_rerio, bos_taurus, gallus_gallus, canis_lupus_familiaris\n", - "\n", - "Common Names:\n", - " - celegans, human, mouse, fruitfly, zebrafish, cow, chicken, dog\n", - "\n", - "Assemblies (UCSC):\n", - " - ce11, ce6, hg19, hg38, hg17, hg18, mm9, mm10, mm39, mm6, mm7, mm8, dm3, dm6, danRer6, danRer7, danRer10, danRer11, danRer5, bosTau9, galGal7, canFam4, hs1, canFam2, canFam3, canFam6, ROS_Cfam_1.0, galGal3, galGal4, galGal5, galGal6, canFam5\n", - "\n", - "Assemblies (NCBI):\n", - " - WS144, WBcel215, WBcel235, WS190, WS195, GRCh37, GRCh38, NCBI35, NCBI36, MGSCv37, GRCm38, GRCm39, MGSCv34, MGSCv35, MGSCv36, Release_5, Release_6, Release_6_plus_ISO1_MT, Zv8, Zv9, GRCz10, GRCz11, Zv7, ARS-UCD1.1, ARS-UCD1.2, ARS-UCD1.3, ARS-UCD2.0, bGalGal1.mat.broiler.GRCg7b, UU_Cfam_GSD_1.0, T2T-CHM13, ASM3317019v1, ASM3317019v2, CanFam2.0, CanFam3.1, Dog10K_Boxer_Tasha, ROS_Cfam_1.0, Gallus_gallus-2.1, Gallus_gallus-4.0, Gallus_gallus-5.0, GRCg6, GRCg6a, UMICH_Zoey_3.1, ASM2820141v1\n", - "\n", - "Please pick an entry and retrieve your desired data!\n" - ] + "data": { + "text/plain": [ + "['WS144',\n", + " 'WBcel215',\n", + " 'WBcel235',\n", + " 'WS190',\n", + " 'WS195',\n", + " 'GRCh37',\n", + " 'GRCh38',\n", + " 'NCBI35',\n", + " 'NCBI36',\n", + " 'MGSCv37',\n", + " 'GRCm38',\n", + " 'GRCm39',\n", + " 'MGSCv34',\n", + " 'MGSCv35',\n", + " 'MGSCv36',\n", + " 'Release_5',\n", + " 'Release_6',\n", + " 'Release_6_plus_ISO1_MT',\n", + " 'Zv8',\n", + " 'Zv9',\n", + " 'GRCz10',\n", + " 'GRCz11',\n", + " 'Zv7',\n", + " 'ARS-UCD1.1',\n", + " 'ARS-UCD1.2',\n", + " 'ARS-UCD1.3',\n", + " 'ARS-UCD2.0',\n", + " 'bGalGal1.mat.broiler.GRCg7b',\n", + " 'UU_Cfam_GSD_1.0',\n", + " 'T2T-CHM13',\n", + " 'ASM3317019v1',\n", + " 'ASM3317019v2',\n", + " 'CanFam2.0',\n", + " 'CanFam3.1',\n", + " 'Dog10K_Boxer_Tasha',\n", + " 'ROS_Cfam_1.0',\n", + " 'Gallus_gallus-2.1',\n", + " 'Gallus_gallus-4.0',\n", + " 'Gallus_gallus-5.0',\n", + " 'GRCg6',\n", + " 'GRCg6a',\n", + " 'UMICH_Zoey_3.1',\n", + " 'ASM2820141v1',\n", + " ,\n", + " 'ce11',\n", + " 'ce6',\n", + " 'hg19',\n", + " 'hg38',\n", + " 'hg17',\n", + " 'hg18',\n", + " 'mm9',\n", + " 'mm10',\n", + " 'mm39',\n", + " 'mm6',\n", + " 'mm7',\n", + " 'mm8',\n", + " 'dm3',\n", + " 'dm6',\n", + " 'danRer6',\n", + " 'danRer7',\n", + " 'danRer10',\n", + " 'danRer11',\n", + " 'danRer5',\n", + " 'bosTau9',\n", + " 'galGal7',\n", + " 'canFam4',\n", + " 'hs1',\n", + " 'canFam2',\n", + " 'canFam3',\n", + " 'canFam6',\n", + " 'ROS_Cfam_1.0',\n", + " 'galGal3',\n", + " 'galGal4',\n", + " 'galGal5',\n", + " 'galGal6',\n", + " 'canFam5']" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" } ], "source": [ - "# you can easily see what's inside the database by just running .info()\n", + "# you can easily see whhich assemblies are available by running:\n", "\n", - "db.info()" + "db.available_assemblies()" ] }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 6, "id": "fd2eb51a-99fe-4050-86f7-deddc6161db2", "metadata": {}, "outputs": [], "source": [ - "# to get the chromosome sizes you just need to use .get_chromsizes()\n", + "# to get the chromosome sizes you just need to use extract the data using 'assembly_info()'\n", "# here, we are specifying that we want only assembled chromosomes to bypass\n", "# scaffolds or unplaced sequences\n", "\n", - "chromsizes = db.get_chromsizes('mm9', roles=[\"assembled\"])\n", - "chromosomes = list(chromsizes.index)" + "mm9 = db.assembly_info('mm9', roles=[\"assembled\"])" ] }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 8, "id": "7c4e2b61-6afd-4df3-817f-63a76b70bde8", "metadata": {}, "outputs": [ @@ -170,7 +206,7 @@ "Name: length, dtype: Int64" ] }, - "execution_count": 6, + "execution_count": 8, "metadata": {}, "output_type": "execute_result" } @@ -178,49 +214,7 @@ "source": [ "# let's check out the result!\n", "\n", - "chromsizes" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "id": "73139067-d320-4803-b2c4-8a44673018b7", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "['chr1',\n", - " 'chr2',\n", - " 'chr3',\n", - " 'chr4',\n", - " 'chr5',\n", - " 'chr6',\n", - " 'chr7',\n", - " 'chr8',\n", - " 'chr9',\n", - " 'chr10',\n", - " 'chr11',\n", - " 'chr12',\n", - " 'chr13',\n", - " 'chr14',\n", - " 'chr15',\n", - " 'chr16',\n", - " 'chr17',\n", - " 'chr18',\n", - " 'chr19',\n", - " 'chrX',\n", - " 'chrY',\n", - " 'chrM']" - ] - }, - "execution_count": 7, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "chromosomes" + "mm9.chromsizes" ] } ], diff --git a/docs/tutorials/translate_chromosome_names.ipynb b/docs/tutorials/translate_chromosome_names.ipynb index 8737b1f..dc4c7c5 100644 --- a/docs/tutorials/translate_chromosome_names.ipynb +++ b/docs/tutorials/translate_chromosome_names.ipynb @@ -20,40 +20,19 @@ "name": "stdout", "output_type": "stream", "text": [ - "/home/alejandro/Documents/projects/forks/genomeinfo\n", "Defaulting to user installation because normal site-packages is not writeable\n", - "Obtaining file:///home/alejandro/Documents/projects/forks/genomeinfo\n", - " Installing build dependencies ... \u001b[?25ldone\n", - "\u001b[?25h Checking if build backend supports build_editable ... \u001b[?25ldone\n", - "\u001b[?25h Getting requirements to build editable ... \u001b[?25ldone\n", - "\u001b[?25h Installing backend dependencies ... \u001b[?25ldone\n", - "\u001b[?25h Preparing editable metadata (pyproject.toml) ... \u001b[?25ldone\n", - "\u001b[?25hRequirement already satisfied: numpy<2,>=1.10 in /usr/lib64/python3.11/site-packages (from genomeinfo==0.1.0) (1.24.3)\n", - "Requirement already satisfied: pandas>=1.3 in /home/alejandro/.local/lib/python3.11/site-packages (from genomeinfo==0.1.0) (1.5.3)\n", - "Requirement already satisfied: pyarrow>=5.0 in /home/alejandro/.local/lib/python3.11/site-packages (from genomeinfo==0.1.0) (16.1.0)\n", - "Requirement already satisfied: python-dateutil>=2.8.1 in /usr/lib/python3.11/site-packages (from pandas>=1.3->genomeinfo==0.1.0) (2.8.2)\n", - "Requirement already satisfied: pytz>=2020.1 in /usr/lib/python3.11/site-packages (from pandas>=1.3->genomeinfo==0.1.0) (2023.3.post1)\n", - "Requirement already satisfied: six>=1.5 in /usr/lib/python3.11/site-packages (from python-dateutil>=2.8.1->pandas>=1.3->genomeinfo==0.1.0) (1.16.0)\n", - "Building wheels for collected packages: genomeinfo\n", - " Building editable for genomeinfo (pyproject.toml) ... \u001b[?25ldone\n", - "\u001b[?25h Created wheel for genomeinfo: filename=genomeinfo-0.1.0-py2.py3-none-any.whl size=2327 sha256=53ce877682e61a6a75f45e4398587bc38f6925a3e3849f59b4be67452f75ddcc\n", - " Stored in directory: /tmp/pip-ephem-wheel-cache-oyr80cjs/wheels/4e/cb/e8/0baa7aa991848767127e29ea4738849dea6d2c9bd867edb942\n", - "Successfully built genomeinfo\n", - "Installing collected packages: genomeinfo\n", - " Attempting uninstall: genomeinfo\n", - " Found existing installation: genomeinfo 0.1.0\n", - " Uninstalling genomeinfo-0.1.0:\n", - " Successfully uninstalled genomeinfo-0.1.0\n", - "Successfully installed genomeinfo-0.1.0\n" + "Requirement already satisfied: assemblyinfo in /home/alejandro/.local/lib/python3.11/site-packages (0.0.1)\n", + "Requirement already satisfied: numpy<2,>=1.10 in /usr/lib64/python3.11/site-packages (from assemblyinfo) (1.24.3)\n", + "Requirement already satisfied: pandas>=1.3 in /home/alejandro/.local/lib/python3.11/site-packages (from assemblyinfo) (1.5.3)\n", + "Requirement already satisfied: pyarrow>=5.0 in /home/alejandro/.local/lib/python3.11/site-packages (from assemblyinfo) (16.1.0)\n", + "Requirement already satisfied: python-dateutil>=2.8.1 in /usr/lib/python3.11/site-packages (from pandas>=1.3->assemblyinfo) (2.8.2)\n", + "Requirement already satisfied: pytz>=2020.1 in /usr/lib/python3.11/site-packages (from pandas>=1.3->assemblyinfo) (2023.3.post1)\n", + "Requirement already satisfied: six>=1.5 in /usr/lib/python3.11/site-packages (from python-dateutil>=2.8.1->pandas>=1.3->assemblyinfo) (1.16.0)\n" ] } ], "source": [ - "# Assumming you are running this from your computer\n", - "# At this moment, GenomeInfo is not available in pypi yet\n", - "\n", - "%cd ../\n", - "!pip3 install -e ." + "!pip3 install assemblyinfo" ] }, { @@ -63,9 +42,7 @@ "metadata": {}, "outputs": [], "source": [ - "# import GenomeInfo from the package!\n", - "\n", - "from genomeinfo import GenomeInfo" + "import assemblyinfo" ] }, { @@ -77,46 +54,35 @@ "source": [ "# use the connect() method to retrieve our database!\n", "\n", - "db = GenomeInfo.connect()" + "db = assemblyinfo.connect()" ] }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 5, "id": "6dc5c5dd-fcba-445e-ba90-853a429340c1", "metadata": {}, "outputs": [ { - "name": "stdout", - "output_type": "stream", - "text": [ - "Genome Information:\n", - "===================\n", - "Species:\n", - " - caenorhabditis_elegans, homo_sapiens, mus_musculus, drosophila_melanogaster, danio_rerio, bos_taurus, gallus_gallus, canis_lupus_familiaris\n", - "\n", - "Common Names:\n", - " - celegans, human, mouse, fruitfly, zebrafish, cow, chicken, dog\n", - "\n", - "Assemblies (UCSC):\n", - " - ce11, ce6, hg19, hg38, hg17, hg18, mm9, mm10, mm39, mm6, mm7, mm8, dm3, dm6, danRer6, danRer7, danRer10, danRer11, danRer5, bosTau9, galGal7, canFam4, hs1, canFam2, canFam3, canFam6, ROS_Cfam_1.0, galGal3, galGal4, galGal5, galGal6, canFam5\n", - "\n", - "Assemblies (NCBI):\n", - " - WS144, WBcel215, WBcel235, WS190, WS195, GRCh37, GRCh38, NCBI35, NCBI36, MGSCv37, GRCm38, GRCm39, MGSCv34, MGSCv35, MGSCv36, Release_5, Release_6, Release_6_plus_ISO1_MT, Zv8, Zv9, GRCz10, GRCz11, Zv7, ARS-UCD1.1, ARS-UCD1.2, ARS-UCD1.3, ARS-UCD2.0, bGalGal1.mat.broiler.GRCg7b, UU_Cfam_GSD_1.0, T2T-CHM13, ASM3317019v1, ASM3317019v2, CanFam2.0, CanFam3.1, Dog10K_Boxer_Tasha, ROS_Cfam_1.0, Gallus_gallus-2.1, Gallus_gallus-4.0, Gallus_gallus-5.0, GRCg6, GRCg6a, UMICH_Zoey_3.1, ASM2820141v1\n", - "\n", - "Please pick an entry and retrieve your desired data!\n" - ] + "data": { + "text/plain": [ + "'Genome Information for homo_sapiens:\\n===================\\nCommon Names:\\n - human\\n\\nAssemblies (UCSC):\\n - hg19, hg38, hg17, hg18, hs1\\n\\nAssemblies (NCBI):\\n - GRCh37, GRCh38, NCBI35, NCBI36, T2T-CHM13\\n\\n'" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" } ], "source": [ - "# you can easily see what's inside the database by just running .info()\n", + "# you can easily see what assemblies are available for each species using 'get_species_info()'\n", "\n", - "db.info()" + "db.get_species_info(\"homo_sapiens\")" ] }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 10, "id": "42c7b9fc-0312-4f25-b2c3-d4f166c2a03b", "metadata": {}, "outputs": [ @@ -150,20 +116,21 @@ " 'MT']" ] }, - "execution_count": 5, + "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "# if you only need GenomeInfo as wrapper to extract names of assembled chromosomes:\n", + "# if you only need AssemblyInfo as wrapper to extract names of assembled chromosomes:\n", "\n", - "db.get_chrom_eq(\"hg38\", roles=[\"assembled\"]).ncbi.tolist()" + "hg38 = db.assembly_info(\"hg38\", roles=[\"assembled\"], provider=\"ncbi\")\n", + "hg38.chromnames" ] }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 11, "id": "5cf13f48-4f7e-41dd-b7bf-414cfaff1eaf", "metadata": {}, "outputs": [ @@ -194,7 +161,7 @@ " 'MSCHRUN_CTG23']" ] }, - "execution_count": 6, + "execution_count": 11, "metadata": {}, "output_type": "execute_result" } @@ -202,12 +169,13 @@ "source": [ "# what if (for some strange reason) we need the names of unplaced sequences in mm10?\n", "\n", - "db.get_chrom_eq(\"mm10\", roles=[\"unplaced\"]).ncbi.tolist()" + "mm10 = db.assembly_info(\"mm10\", roles=[\"unplaced\"], provider=\"ncbi\")\n", + "mm10.chromnames" ] }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 12, "id": "88927824-be4d-404f-b754-32eac4d3a65b", "metadata": {}, "outputs": [ @@ -260,7 +228,7 @@ " 'chrUn_JH584304']" ] }, - "execution_count": 7, + "execution_count": 12, "metadata": {}, "output_type": "execute_result" } @@ -268,7 +236,8 @@ "source": [ "# now unplace and unlocalized sequences, but in UCSC format?\n", "\n", - "db.get_chrom_eq(\"mm10\", roles=[\"unplaced\", \"unlocalized\"]).name.tolist()" + "mm10 = db.assembly_info(\"mm10\", roles=[\"unplaced\", \"unlocalized\"], provider=\"ucsc\")\n", + "mm10.chromnames" ] } ],