From af1c5d6e97b4e533af488a5b7c41ff956c9bee33 Mon Sep 17 00:00:00 2001 From: Malte Benedikt Kuehl Date: Fri, 13 Sep 2024 20:24:13 +0200 Subject: [PATCH] More consistent comment capitalisation, code example, rsem gene level transcript map requirement bug fix and submodule documentation --- README.md | 57 +- docs/source/example.ipynb | 3490 ++++++++--------- pytximport/__init__.py | 5 +- pytximport/_cli.py | 62 +- pytximport/core/__init__.py | 2 + pytximport/core/_tximport.py | 81 +- pytximport/definitions/__init__.py | 2 +- pytximport/importers/__init__.py | 6 +- pytximport/importers/_read_kallisto.py | 18 +- pytximport/importers/_read_rsem.py | 6 +- pytximport/importers/_read_salmon.py | 10 +- pytximport/importers/_read_tsv.py | 10 +- pytximport/utils/__init__.py | 6 +- pytximport/utils/_biotype_filters.py | 20 + .../utils/_convert_abundance_to_counts.py | 6 +- .../utils/_convert_transcripts_to_genes.py | 24 +- .../utils/_create_transcript_gene_map.py | 22 +- pytximport/utils/_filter_by_biotype.py | 14 +- .../utils/_get_median_length_over_isoform.py | 6 +- .../utils/_remove_transcript_version.py | 2 +- .../_replace_transcript_ids_with_names.py | 10 +- pytximport/utils/_summarize_rsem_gene_data.py | 2 +- test/test_cli.py | 16 +- test/test_correctness.py | 28 +- test/test_export.py | 32 +- test/test_kallisto.py | 10 +- test/test_rsem.py | 24 +- test/test_salmon.py | 10 +- ...ene_map.py => test_transcript_gene_map.py} | 2 +- test/test_transcript_level.py | 8 +- 30 files changed, 2035 insertions(+), 1956 deletions(-) rename test/{test_transcriptome_to_gene_map.py => test_transcript_gene_map.py} (97%) diff --git a/README.md b/README.md index fc58941..74ac83c 100755 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ # pytximport +
+ [![Version](https://img.shields.io/pypi/v/pytximport)](https://pypi.org/project/pytximport/) [![License](https://img.shields.io/pypi/l/pytximport)](https://github.com/complextissue/pytximport) ![GitHub Actions Workflow Status](https://img.shields.io/github/actions/workflow/status/complextissue/pytximport/ci.yml) @@ -11,7 +13,7 @@ [![Code Style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black) [![pre-commit](https://img.shields.io/badge/pre--commit-enabled-brightgreen?logo=pre-commit&logoColor=white)](https://github.com/pre-commit/pre-commit) -`pytximport` is a Python package for efficient gene count estimation based on transcript quantification files produced by pseudoalignment/quasi-mapping tools such as `kallisto` or `salmon`. `pytximport` is a port of the popular [tximport Bioconductor R package](https://bioconductor.org/packages/release/bioc/html/tximport.html). +`pytximport` is a Python package for efficient (gene-)count estimation from transcript quantification files produced by pseudoalignment/quasi-mapping tools such as `salmon`, `kallisto`, `rsem` and others. `pytximport` is a port of the popular [tximport Bioconductor R package](https://bioconductor.org/packages/release/bioc/html/tximport.html). ## Installation @@ -32,10 +34,14 @@ You can either import the `tximport` function in your Python files: ```python from pytximport import tximport +from pytximport.utils import create_transcript_gene_map + +transcript_gene_map = create_transcript_gene_map(species="human") + results = tximport( file_paths, - "salmon", - transcript_gene_mapping, + data_type="salmon", + transcript_gene_map=transcript_gene_map, ) ``` @@ -47,17 +53,16 @@ pytximport -i ./sample_1.sf -i ./sample_2.sf -t salmon -m ./tx2gene_map.tsv -o . Common options are: -- `-i`: The input files. -- `-t`: The input type, e.g., `salmon`, `kallisto` or `tsv`. -- `-m`: The map to match transcript ids to their gene ids. Expected column names are `transcript_id` and `gene_id`. -- `-o`: The output path. -- `-c`: The count transform to apply. Leave out for none, other options include `scaled_tpm`, `length_scaled_tpm` and `dtu_scaled_tpm`. -- `-gl`: Whether the input is already gene-level counts. Provide this flag when importing gene counts from RSEM. -- `-tx`: Whether to return transcript-level counts without gene summarization. -- `-id`: The column name containing the transcript ids, in case it differs from the typical naming standards for the configured input file type. -- `-counts`: The column name containing the transcript counts, in case it differs from the typical naming standards for the configured input file type. -- `-length`: The column name containing the transcript lenghts, in case it differs from the typical naming standards for the configured input file type. -- `-tpm`: The column name containing the transcript abundance, in case it differs from the typical naming standards for the configured input file type. +- `-i`: The path to an quantification file. To provide multiple input files, use `-i input1.sf -i input2.sf ...`. +- `-t`: The type of quantification file, e.g. `salmon`, `kallisto` and others. +- `-m`: The path to the transcript to gene map. Either a tab-separated (.tsv) or comma-separated (.csv) file. Expected column names are `transcript_id` and `gene_id`. +- `-o`: The output path to save the resulting counts to. +- `-of`: The format of the output file. Either `csv` or `h5ad`. +- `-ow`: Provide this flag to overwrite an existing file at the output path. +- `-c`: The method to calculate the counts from the abundance. Leave empty to use counts. For differential gene expression analysis, we recommend using `length_scaled_tpm`. For differential transcript expression analysis, we recommend using `scaled_tpm`. For differential isoform usage analysis, we recommend using `dtu_scaled_tpm`. +- `-ir`: Provide this flag to make use of inferential replicates. Will use the median of the inferential replicates. +- `-gl`: Provide this flag when importing gene-level counts from RSEM files. +- `-tx`: Provide this flag to return transcript-level instead of gene-summarized data. Incompatible with gene-level input and `counts_from_abundance=length_scaled_tpm`. - `--help`: Display all configuration options. ## Documentation @@ -66,7 +71,7 @@ Detailled documentation is made available at: [https://pytximport.readthedocs.io ## Development status -`pytximport` is still in development and has not yet reached version 1.0.0 in the [SemVer](https://semver.org/) versioning scheme. While it should work for most use cases and we regularly compare outputs against the R implementation, expect breaking changes. If you encounter any problems, please open a GitHub issue. If you are a Python developer, we welcome pull requests implementing missing features, adding more extensive unit tests and bug fixes. +`pytximport` is still in development and has not yet reached version 1.0.0 in the [SemVer](https://semver.org/) versioning scheme. While it should work for almost all use cases and we regularly compare outputs against the R implementation, breaking changes between minor versions may occur. If you encounter any problems, please open a GitHub issue. If you are a Python developer, we welcome pull requests implementing missing features, adding more extensive unit tests and bug fixes. ## Motivation @@ -77,8 +82,8 @@ The `tximport` package has become a main stay in the bulk RNA sequencing communi Please cite both the original publication as well as this Python implementation: -- Charlotte Soneson, Michael I. Love, Mark D. Robinson. Differential analyses for RNA-seq: transcript-level estimates improve gene-level inferences, F1000Research, 4:1521, December 2015. doi: 10.12688/f1000research.7563.1 - Kuehl, M., & Puelles, V. (2024). pytximport: Gene count estimation from transcript quantification files in Python (Version 0.9.0) [Computer software]. https://github.com/complextissue/pytximport +- Charlotte Soneson, Michael I. Love, Mark D. Robinson. Differential analyses for RNA-seq: transcript-level estimates improve gene-level inferences, F1000Research, 4:1521, December 2015. doi: 10.12688/f1000research.7563.1 ## License @@ -88,15 +93,19 @@ The software is provided under the GNU General Public License version 3. Please Generally, outputs from `pytximport` correspond to the outputs from `tximport` within the accuracy allowed by multiple floating point operations and small implementation differences in its dependencies when using the same configuration. If you observe larger discrepancies, please open an issue. -While the outputs are roughly identical for the same configuration, there remain some differences between the packages: +While the outputs are identical within floating point tolerance for the same configuration, there remain some differences between the packages: + +Features unique to `pytximport`: +- Generating transcript-to-gene maps, either from a BioMart server or an `annotation.gtf` file. Use `create_transcript_gene_map` or `create_transcript_gene_map_from_annotation` from `pytximport.utils`. +- Command line interface. Type `pytximport --help` into your terminal to explore all options. +- `AnnData`-support, enabling seamless integration with the `scverse`. +- Saving outputs directly to file (use the `output_path` argument). +- Removing transcript versions from **both** the quantification files and the transcript-to-gene map when `ignore_transcript_version` is provided. +- Post-hoc biotype-filtering. Set `biotype_filter` to a whitelist of possible biotypes contained within the bar-separated values of your transcript ids. + +Features unique to `tximport` -- `pytximport` can be used from the command line. -- `pytximport` supports `AnnData` format outputs (set `output_type` to `anndata`), enabling seamless integration with the `scverse`. -- Argument order and argument defaults may differ between the implementations. -- Additional features: - - When `ignore_transcript_version` is set, the transcript version will not only be scrapped from the quantization file but also from the provided transcript to gene mapping. - - When `biotype_filter` is set, all transcripts that do not contain any of the provided biotypes will be removed prior to all other steps. - - When `output_path` is configured, a count matrix will be saved as a .csv file. +Argument order and argument defaults may differ between the implementations. ## Building the documentation locally diff --git a/docs/source/example.ipynb b/docs/source/example.ipynb index c6733fe..8fe6360 100644 --- a/docs/source/example.ipynb +++ b/docs/source/example.ipynb @@ -1,1754 +1,1742 @@ { - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Vignette" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "This vignette extends the [vignette for the R-version of tximport](https://bioconductor.org/packages/release/bioc/vignettes/tximport/inst/doc/tximport.html). If you are unfamiliar with `tximport` or curious about the motivation behind it, please check it out." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "If you are looking for a full-featured end-to-end workflow for Pythonic bulk RNA-sequencing analysis, check out our [Snakemake workflow](https://github.com/complextissue/snakemake-bulk-rna-seq-workflow/) based on pytximport." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Creating your transcript to gene map\n", - "\n", - "Here, we will show you how to generate a transcript-to-gene mapping based on the Ensembl reference or a gene transfer format file." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Build it from Ensembl" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "This example requires `pybiomart` which is installed together with `pytximport`. Providing a host is optional, for a list of available archives that correspond to Ensembl releases, please consult [https://www.ensembl.org/info/website/archives/index.html](https://www.ensembl.org/info/website/archives/index.html). By default, the transcript ids will be mapped to the `ensembl_gene_id` field. If you prefer to use gene names, choose `external_gene_name`. Be aware that not all proposed transcripts have been assigned a name yet and thus will not be included if you use gene names. The first time you run this function, it may take a few seconds to download the data." - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
transcript_idgene_id
0ENST00000387314MT-TF
1ENST00000389680MT-RNR1
2ENST00000387342MT-TV
3ENST00000387347MT-RNR2
4ENST00000386347MT-TL1
\n", - "
" - ], - "text/plain": [ - " transcript_id gene_id\n", - "0 ENST00000387314 MT-TF\n", - "1 ENST00000389680 MT-RNR1\n", - "2 ENST00000387342 MT-TV\n", - "3 ENST00000387347 MT-RNR2\n", - "4 ENST00000386347 MT-TL1" - ] - }, - "execution_count": 1, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "from pytximport.utils import create_transcript_gene_map\n", - "\n", - "transcript_gene_map_human = create_transcript_gene_map(\n", - " \"human\", target_field=\"external_gene_name\"\n", - ")\n", - "transcript_gene_map_human.head(5)" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
transcript_idgene_id
0ENSMUST00000082387ENSMUSG00000064336
1ENSMUST00000082388ENSMUSG00000064337
2ENSMUST00000082389ENSMUSG00000064338
3ENSMUST00000082390ENSMUSG00000064339
4ENSMUST00000082391ENSMUSG00000064340
\n", - "
" - ], - "text/plain": [ - " transcript_id gene_id\n", - "0 ENSMUST00000082387 ENSMUSG00000064336\n", - "1 ENSMUST00000082388 ENSMUSG00000064337\n", - "2 ENSMUST00000082389 ENSMUSG00000064338\n", - "3 ENSMUST00000082390 ENSMUSG00000064339\n", - "4 ENSMUST00000082391 ENSMUSG00000064340" - ] - }, - "execution_count": 2, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "transcript_gene_map_mouse = create_transcript_gene_map(species=\"mouse\")\n", - "transcript_gene_map_mouse.head(5)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Use a gene transfer format file" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "If you already have an annotation file in .gtf format (e.g. from the GENCODE or Ensembl references), you can use the `create_transcript_gene_map_from_annotation` function contained in `pytximport.utils` to generate a transcript to gene map. Using an annotation file is considered best practice, as it ensures that your annotation and alignment reference are the same if you download them from the same source, e.g., an Ensembl release.\n", - "\n", - "Set `target_field` to `gene_name` to map transcript ids to gene names instead of gene ids. If the transcript does not have a corresponding gene name in the annotation file, it will be mapped to the gene id." - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
transcript_idgene_id
0ENST00000424215ENSG00000228037
1ENST00000511072PRDM16
2ENST00000607632PRDM16
3ENST00000378391PRDM16
4ENST00000514189PRDM16
\n", - "
" - ], - "text/plain": [ - " transcript_id gene_id\n", - "0 ENST00000424215 ENSG00000228037\n", - "1 ENST00000511072 PRDM16\n", - "2 ENST00000607632 PRDM16\n", - "3 ENST00000378391 PRDM16\n", - "4 ENST00000514189 PRDM16" - ] - }, - "execution_count": 3, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "from pytximport.utils import create_transcript_gene_map_from_annotation\n", - "\n", - "transcript_gene_map_from_gtf = create_transcript_gene_map_from_annotation(\n", - " \"../../test/data/annotation.gtf\",\n", - " target_field=\"gene_name\",\n", - ")\n", - "transcript_gene_map_from_gtf.head(5)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Map transcript names to gene names" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "You can also optionally map transcript names to either gene names or gene ids if your data requires it." - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
transcript_idgene_id
0MT-TF-201MT-TF
1MT-RNR1-201MT-RNR1
2MT-TV-201MT-TV
3MT-RNR2-201MT-RNR2
4MT-TL1-201MT-TL1
\n", - "
" - ], - "text/plain": [ - " transcript_id gene_id\n", - "0 MT-TF-201 MT-TF\n", - "1 MT-RNR1-201 MT-RNR1\n", - "2 MT-TV-201 MT-TV\n", - "3 MT-RNR2-201 MT-RNR2\n", - "4 MT-TL1-201 MT-TL1" - ] - }, - "execution_count": 4, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "transcript_name_gene_map_human = create_transcript_gene_map(\n", - " \"human\",\n", - " source_field=\"external_transcript_name\",\n", - " target_field=\"external_gene_name\",\n", - ")\n", - "transcript_name_gene_map_human.head(5)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Importing transcript quantification files\n", - "\n", - "You can easily import quantification files from tools like `salmon` with `pytximport`." - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": {}, - "outputs": [], - "source": [ - "import numpy as np\n", - "import pandas as pd\n", - "from pytximport import tximport" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "Reading quantification files: 2it [00:00, 122.91it/s]\n" - ] - }, - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "
<xarray.Dataset> Size: 60kB\n",
-                            "Dimensions:    (gene_id: 496, file: 2, file_path: 2)\n",
-                            "Coordinates:\n",
-                            "  * gene_id    (gene_id) <U18 36kB 'ENSMUSG00000083355' ... 'ENSMUSG00000067713'\n",
-                            "  * file_path  (file_path) <U43 344B '../../test/data/salmon/multiple/Sample_...\n",
-                            "Dimensions without coordinates: file\n",
-                            "Data variables:\n",
-                            "    abundance  (gene_id, file) float64 8kB 0.08291 0.0 0.09854 ... 0.4618 0.0\n",
-                            "    counts     (gene_id, file) float64 8kB 1.005 0.0 1.086 ... 1.957 6.208 0.0\n",
-                            "    length     (gene_id, file) float64 8kB 509.1 509.1 445.8 ... 564.6 564.6
" - ], - "text/plain": [ - " Size: 60kB\n", - "Dimensions: (gene_id: 496, file: 2, file_path: 2)\n", - "Coordinates:\n", - " * gene_id (gene_id) \n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
transcript_idtranscript_name
0ENST00000387314MT-TF-201
1ENST00000389680MT-RNR1-201
2ENST00000387342MT-TV-201
3ENST00000387347MT-RNR2-201
4ENST00000386347MT-TL1-201
\n", - "" - ], - "text/plain": [ - " transcript_id transcript_name\n", - "0 ENST00000387314 MT-TF-201\n", - "1 ENST00000389680 MT-RNR1-201\n", - "2 ENST00000387342 MT-TV-201\n", - "3 ENST00000387347 MT-RNR2-201\n", - "4 ENST00000386347 MT-TL1-201" - ] - }, - "execution_count": 9, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "transcript_name_map_human = create_transcript_gene_map(\n", - " \"human\", target_field=\"external_transcript_name\"\n", - ")\n", - "transcript_name_map_human.head(5)" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
../../test/data/salmon/quant.sf
HOXC8-2014486.940412
UGT3A2-2011307.314695
HOXC9-201886.909534
HOXC4-202749.069369
HOXC12-201544.817685
\n", - "
" - ], - "text/plain": [ - " ../../test/data/salmon/quant.sf\n", - "HOXC8-201 4486.940412\n", - "UGT3A2-201 1307.314695\n", - "HOXC9-201 886.909534\n", - "HOXC4-202 749.069369\n", - "HOXC12-201 544.817685" - ] - }, - "execution_count": 10, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "txi = replace_transcript_ids_with_names(txi, transcript_name_map_human)\n", - "pd.DataFrame(txi.X.T, index=txi.var.index, columns=txi.obs.index).sort_values(\n", - " by=txi.obs.index[0],\n", - " ascending=False,\n", - ").head(5)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The same data summarized to genes:" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "Reading quantification files: 1it [00:00, 353.86it/s]\n" - ] - }, - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
../../test/data/salmon/quant.sf
HOXC84486.940412
UGT3A21506.597257
HOXC41152.964133
HOXC9886.909534
HOXC12544.817685
\n", - "
" - ], - "text/plain": [ - " ../../test/data/salmon/quant.sf\n", - "HOXC8 4486.940412\n", - "UGT3A2 1506.597257\n", - "HOXC4 1152.964133\n", - "HOXC9 886.909534\n", - "HOXC12 544.817685" - ] - }, - "execution_count": 11, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "txi = tximport(\n", - " [\"../../test/data/salmon/quant.sf\"],\n", - " \"salmon\",\n", - " transcript_gene_map_human,\n", - " counts_from_abundance=\"scaled_tpm\",\n", - " output_type=\"xarray\",\n", - " return_transcript_data=False,\n", - ")\n", - "pd.DataFrame(\n", - " txi[\"counts\"], index=txi.coords[\"gene_id\"], columns=txi.coords[\"file_path\"]\n", - ").sort_values(\n", - " by=txi.coords[\"file_path\"].data[0],\n", - " ascending=False,\n", - ").head(5)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Note that the top transcript corresponds to the top expressed gene in this case." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Exporting AnnData files" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "`pytximport` integrates well with other packages from the `scverse` through its `AnnData` export option." - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "Reading quantification files: 1it [00:00, 327.94it/s]\n" - ] - }, - { - "data": { - "text/plain": [ - "AnnData object with n_obs × n_vars = 1 × 10\n", - " uns: 'counts_from_abundance'\n", - " obsm: 'length', 'abundance'" - ] - }, - "execution_count": 12, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "txi_ad = tximport(\n", - " [\"../../test/data/salmon/quant.sf\"],\n", - " \"salmon\",\n", - " transcript_gene_map_human,\n", - " output_type=\"anndata\",\n", - " # the output can optionally be saved to a file by uncommenting the following lines\n", - " # output_format=\"h5ad\",\n", - " # output_path=\"txi_ad.h5ad\",\n", - ")\n", - "txi_ad" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Use from the command line\n", - "\n", - "You can run `pytximport` from the command line, too. Available options can be viewed via the `pytximport --help` command." - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2024-09-11 16:11:35,057: Starting the import.\n", - "Reading quantification files: 1it [00:00, 276.56it/s]\n", - "2024-09-11 16:11:35,286: Converting transcript-level expression to gene-level expression.\n", - "2024-09-11 16:11:35,525: Matching gene_ids.\n", - "2024-09-11 16:11:35,657: Creating gene abundance.\n", - "2024-09-11 16:11:35,812: Creating gene counts.\n", - "2024-09-11 16:11:35,812: Creating lengths.\n", - "2024-09-11 16:11:35,816: Replacing missing lengths.\n", - "2024-09-11 16:11:35,822: Creating gene expression dataset.\n", - "2024-09-11 16:11:35,825: Saving the gene-level expression to: ../../test/data/salmon/quant.h5ad.\n", - "2024-09-11 16:11:35,837: Finished the import in 0.78 seconds.\n" - ] - } - ], - "source": [ - "!pytximport -i ../../test/data/salmon/quant.sf -t \"salmon\" -m ../../test/data/gencode.v46.metadata.HGNC.tsv --output_type \"anndata\" --output_format \"h5ad\" --output_path_overwrite -o ../../test/data/salmon/quant.h5ad" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Inferential replicates" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "`pytximport` can handle bootstraping replicates provided by `salmon` and `kallisto`. When `inferential_replicate_transformer` is set, the provided function is used to recalculate the counts and abundances for each sample based on the bootstraps." - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "Reading quantification files: 4it [00:01, 2.84it/s]\n", - "WARNING:root:Not all transcripts are present in the mapping. 31380 out of 253181 missing. Removing the missing transcripts.\n" - ] - }, - { - "data": { - "text/plain": [ - "AnnData object with n_obs × n_vars = 4 × 40768\n", - " uns: 'counts_from_abundance', 'inferential_replicates'\n", - " obsm: 'length', 'abundance', 'variance'" - ] - }, - "execution_count": 14, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "result = tximport(\n", - " [\n", - " \"../../test/data/fabry_disease/SRR16504309_wt/\",\n", - " \"../../test/data/fabry_disease/SRR16504310_wt/\",\n", - " \"../../test/data/fabry_disease/SRR16504311_ko/\",\n", - " \"../../test/data/fabry_disease/SRR16504312_ko/\",\n", - " ],\n", - " \"salmon\",\n", - " transcript_gene_map_human,\n", - " inferential_replicates=True,\n", - " inferential_replicate_variance=True, # whether to calculate the variance of the inferential replicates\n", - " inferential_replicate_transformer=lambda x: np.median(x, axis=1),\n", - " counts_from_abundance=\"length_scaled_tpm\",\n", - ")\n", - "result" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Downstream analysis with PyDESeq2\n", - "\n", - "The output from `pytximport` can easily be used for downstream analysis with `PyDESeq2`. For more information on `PyDESeq2`, please consult its [documentation](https://pydeseq2.readthedocs.io/en/latest/)." - ] - }, - { - "cell_type": "code", - "execution_count": 15, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Note: you may need to restart the kernel to use updated packages.\n" - ] - } - ], - "source": [ - "%pip install pydeseq2 decoupler adjustText omnipath tqdm ipywidgets seaborn -q" - ] - }, - { - "cell_type": "code", - "execution_count": 16, - "metadata": {}, - "outputs": [], - "source": [ - "from pydeseq2.dds import DeseqDataSet\n", - "from pydeseq2.default_inference import DefaultInference\n", - "from pydeseq2.ds import DeseqStats\n", - "import decoupler as dc" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Load the .csv file generated by `pytximport` via the `output_path` argument or create it directly from the output of `pytximport`. In this case, we are working with the salmon quantification files from a public bulk RNA sequencing dataset: [Podocyte injury in Fabry nephropathy](https://www.ebi.ac.uk/ena/browser/view/PRJNA773084)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Round count estimates (required by PyDESeq2) and add the corresponding metadata." - ] - }, - { - "cell_type": "code", - "execution_count": 17, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "AnnData object with n_obs × n_vars = 4 × 40768\n", - " obs: 'condition'\n", - " uns: 'counts_from_abundance', 'inferential_replicates'\n", - " obsm: 'length', 'abundance', 'variance'" - ] - }, - "execution_count": 17, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "result.X = result.X.round().astype(int)\n", - "result.obs[\"condition\"] = [\"Control\", \"Control\", \"Disease\", \"Disease\"]\n", - "result" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Filter genes with low counts out." - ] - }, - { - "cell_type": "code", - "execution_count": 18, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "AnnData object with n_obs × n_vars = 4 × 14714\n", - " obs: 'condition'\n", - " uns: 'counts_from_abundance', 'inferential_replicates'\n", - " obsm: 'length', 'abundance', 'variance'" - ] - }, - "execution_count": 18, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "result = result[:, result.X.max(axis=0) > 10].copy()\n", - "result" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Now perform your `PyDESeq2` analysis." - ] - }, - { - "cell_type": "code", - "execution_count": 19, - "metadata": {}, - "outputs": [], - "source": [ - "dds = DeseqDataSet(\n", - " adata=result,\n", - " design_factors=\"condition\",\n", - " refit_cooks=True,\n", - " inference=DefaultInference(n_cpus=8),\n", - " quiet=True,\n", - ")" - ] - }, - { - "cell_type": "code", - "execution_count": 20, - "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "/Users/au734063/.pyenv/versions/3.9.16/lib/python3.9/site-packages/pydeseq2/dds.py:490: UserWarning: As the residual degrees of freedom is less than 3, the distribution of log dispersions is especially asymmetric and likely to be poorly estimated by the MAD.\n", - " self.fit_dispersion_prior()\n" - ] - } - ], - "source": [ - "dds.deseq2()" - ] - }, - { - "cell_type": "code", - "execution_count": 21, - "metadata": {}, - "outputs": [], - "source": [ - "stat_result = DeseqStats(dds, contrast=(\"condition\", \"Disease\", \"Control\"), quiet=True)" - ] - }, - { - "cell_type": "code", - "execution_count": 22, - "metadata": {}, - "outputs": [], - "source": [ - "%%capture\n", - "stat_result.summary()\n", - "stat_result.lfc_shrink()" - ] - }, - { - "cell_type": "code", - "execution_count": 23, - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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kkRERERERJQBq9sREZFOkUgkqFWrlup9fqUrcRIRkSZBFEVR20F8TrGxsbCwsEBMTAzMzc21HQ4REREREWlJdnMDfrVFRERERESUAZMkIiIiIiKiDJgkERGRTklISEDJkiVRsmRJJCQkaDucLOlKnEREpImFG4iISKeIoogHDx6o3udXuhInERFp4kgSERERERFRBkySiIiIiIiIMmCSRERERERElAGTJCIiIiIiogyYJBEREREREWXA6nZERKRTBEFAxYoVVe/zK12Jk4iINDFJIiIinWJiYoKrV69qO4yP0pU4iYhIE6fbERERERERZcAkiYiIiIiIKAMmSUREpFMSEhLg4uICFxcXJCQkaDucLOlKnEREpIlrkoiISKeIoohr166p3udXuhInERFp4kgSERERERFRBkySiIiIiIiIMmCSRERERERElAGTJCIiIiIiogyYJBEREREREWXA6nZERKRTBEFAiRIlVO/zK12Jk4iINDFJIiIinWJiYoKIiAhth/FRuhInERFp4nQ7IiIiIiKiDJgkERERERERZcAkiYiIdEpiYiJq166N2rVrIzExUdvhZElX4iQiIk1ck0RERDpFqVQiLCxM9T6/0pU4iYhIE0eSiIiIiIiIMmCSRERERERElAGTJCIiIiIiogzyTZI0d+5cCIKAYcOGqY4lJSXBz88PhQoVgkwmQ/v27fHs2TPtBUlERERERAVevkiS/vvvP6xZswZVqlRROz58+HD89ddf2LJlC44ePYqnT5+iXbt2WoqSiIiIiIi+BlpPkuLj49G9e3f8/PPPsLKyUh2PiYlBYGAgFi9ejCZNmqBmzZoICgrCqVOncObMGS1GTERE2la4cGEULlxY22F8lK7ESURE6rSeJPn5+aFly5bw9PRUO37u3DmkpqaqHS9fvjwcHR1x+vTpLx0mERHlE6ampnjx4gVevHgBU1NTbYeTJV2Jk4iINGl1n6SQkBCcP38e//33n8a5qKgoGBgYwNLSUu24ra0toqKisuwzOTkZycnJqp9jY2PzLF4iIiIiIir4tDaS9OjRI/z4449Yv349jIyM8qzfOXPmwMLCQvVycHDIs76JiIiIiKjg01qSdO7cOTx//hw1atSAVCqFVCrF0aNHsWzZMkilUtja2iIlJQXR0dFq1z179gx2dnZZ9jt+/HjExMSoXo8ePfrMT0JE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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "dc.plot_volcano_df(\n", - " stat_result.results_df,\n", - " x=\"log2FoldChange\",\n", - " y=\"padj\",\n", - " sign_thr=0.01,\n", - " top=20,\n", - " figsize=(10, 5),\n", - ")" - ] - }, - { - "cell_type": "code", - "execution_count": 24, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Running ulm on mat with 1 samples and 14714 targets for 660 sources.\n" - ] - }, - { - "data": { - "image/png": "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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "collectri = dc.get_collectri(organism=\"human\", split_complexes=False)\n", - "mat = stat_result.results_df[[\"stat\"]].T.rename(index={\"stat\": \"disease.vs.control\"})\n", - "tf_acts, tf_pvals = dc.run_ulm(mat=mat, net=collectri, verbose=True)\n", - "dc.plot_barplot(\n", - " acts=tf_acts, contrast=\"disease.vs.control\", top=10, vertical=False, figsize=(5, 3)\n", - ")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "We can also evaluate known pathways." - ] - }, - { - "cell_type": "code", - "execution_count": 25, - "metadata": {}, - "outputs": [], - "source": [ - "progeny = dc.get_progeny(top=500)\n", - "pathway_acts, pathway_pvals = dc.run_mlm(mat=mat, net=progeny, min_n=5)" - ] - }, - { - "cell_type": "code", - "execution_count": 26, - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "dc.plot_barplot(\n", - " acts=pathway_acts,\n", - " contrast=\"disease.vs.control\",\n", - " top=40,\n", - " vertical=False,\n", - " figsize=(5, 3),\n", - ")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Please refer to the `PyDESeq2` and the `decoupler` documentation for additional analyses." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "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.9.16" - } + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Vignette" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This vignette extends the [vignette for the R-version of tximport](https://bioconductor.org/packages/release/bioc/vignettes/tximport/inst/doc/tximport.html). If you are unfamiliar with `tximport` or curious about the motivation behind it, please check it out." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "If you are looking for a full-featured end-to-end workflow for Pythonic bulk RNA-sequencing analysis, check out our [Snakemake workflow](https://github.com/complextissue/snakemake-bulk-rna-seq-workflow/) based on pytximport." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Creating your transcript to gene map\n", + "\n", + "Here, we will show you how to generate a transcript-to-gene mapping based on the Ensembl reference or a gene transfer format file." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Build it from Ensembl" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This example requires `pybiomart` which is installed together with `pytximport`. Providing a host is optional, for a list of available archives that correspond to Ensembl releases, please consult [https://www.ensembl.org/info/website/archives/index.html](https://www.ensembl.org/info/website/archives/index.html). By default, the transcript ids will be mapped to the `ensembl_gene_id` field. If you prefer to use gene names, choose `external_gene_name`. Be aware that not all proposed transcripts have been assigned a name yet and thus will not be included if you use gene names. The first time you run this function, it may take a few seconds to download the data." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
transcript_idgene_id
0ENST00000387314MT-TF
1ENST00000389680MT-RNR1
2ENST00000387342MT-TV
3ENST00000387347MT-RNR2
4ENST00000386347MT-TL1
\n", + "
" + ], + "text/plain": [ + " transcript_id gene_id\n", + "0 ENST00000387314 MT-TF\n", + "1 ENST00000389680 MT-RNR1\n", + "2 ENST00000387342 MT-TV\n", + "3 ENST00000387347 MT-RNR2\n", + "4 ENST00000386347 MT-TL1" + ] + }, + "execution_count": 1, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "from pytximport.utils import create_transcript_gene_map\n", + "\n", + "transcript_gene_map_human = create_transcript_gene_map(\n", + " species=\"human\",\n", + " target_field=\"external_gene_name\",\n", + ")\n", + "transcript_gene_map_human.head(5)" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
transcript_idgene_id
0ENSMUST00000082387ENSMUSG00000064336
1ENSMUST00000082388ENSMUSG00000064337
2ENSMUST00000082389ENSMUSG00000064338
3ENSMUST00000082390ENSMUSG00000064339
4ENSMUST00000082391ENSMUSG00000064340
\n", + "
" + ], + "text/plain": [ + " transcript_id gene_id\n", + "0 ENSMUST00000082387 ENSMUSG00000064336\n", + "1 ENSMUST00000082388 ENSMUSG00000064337\n", + "2 ENSMUST00000082389 ENSMUSG00000064338\n", + "3 ENSMUST00000082390 ENSMUSG00000064339\n", + "4 ENSMUST00000082391 ENSMUSG00000064340" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "transcript_gene_map_mouse = create_transcript_gene_map(species=\"mouse\")\n", + "transcript_gene_map_mouse.head(5)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Use a gene transfer format file" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "If you already have an annotation file in .gtf format (e.g. from the GENCODE or Ensembl references), you can use the `create_transcript_gene_map_from_annotation` function contained in `pytximport.utils` to generate a transcript to gene map. Using an annotation file is considered best practice, as it ensures that your annotation and alignment reference are the same if you download them from the same source, e.g., an Ensembl release.\n", + "\n", + "Set `target_field` to `gene_name` to map transcript ids to gene names instead of gene ids. If the transcript does not have a corresponding gene name in the annotation file, it will be mapped to the gene id." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
transcript_idgene_id
0ENST00000424215ENSG00000228037
1ENST00000511072PRDM16
2ENST00000607632PRDM16
3ENST00000378391PRDM16
4ENST00000514189PRDM16
\n", + "
" + ], + "text/plain": [ + " transcript_id gene_id\n", + "0 ENST00000424215 ENSG00000228037\n", + "1 ENST00000511072 PRDM16\n", + "2 ENST00000607632 PRDM16\n", + "3 ENST00000378391 PRDM16\n", + "4 ENST00000514189 PRDM16" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "from pytximport.utils import create_transcript_gene_map_from_annotation\n", + "\n", + "transcript_gene_map_from_gtf = create_transcript_gene_map_from_annotation(\n", + " \"../../test/data/annotation.gtf\",\n", + " target_field=\"gene_name\",\n", + ")\n", + "transcript_gene_map_from_gtf.head(5)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Map transcript names to gene names" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "You can also optionally map transcript names to either gene names or gene ids if your data requires it." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
transcript_idgene_id
0MT-TF-201MT-TF
1MT-RNR1-201MT-RNR1
2MT-TV-201MT-TV
3MT-RNR2-201MT-RNR2
4MT-TL1-201MT-TL1
\n", + "
" + ], + "text/plain": [ + " transcript_id gene_id\n", + "0 MT-TF-201 MT-TF\n", + "1 MT-RNR1-201 MT-RNR1\n", + "2 MT-TV-201 MT-TV\n", + "3 MT-RNR2-201 MT-RNR2\n", + "4 MT-TL1-201 MT-TL1" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "transcript_name_gene_map_human = create_transcript_gene_map(\n", + " \"human\",\n", + " source_field=\"external_transcript_name\",\n", + " target_field=\"external_gene_name\",\n", + ")\n", + "transcript_name_gene_map_human.head(5)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Importing transcript quantification files\n", + "\n", + "You can easily import quantification files from tools like `salmon` with `pytximport`." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "import pandas as pd\n", + "from pytximport import tximport" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Reading quantification files: 2it [00:00, 259.44it/s]\n" + ] }, - "nbformat": 4, - "nbformat_minor": 2 + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "
<xarray.Dataset> Size: 60kB\n",
+       "Dimensions:    (gene_id: 496, file: 2, file_path: 2)\n",
+       "Coordinates:\n",
+       "  * gene_id    (gene_id) <U18 36kB 'ENSMUSG00000083355' ... 'ENSMUSG00000067713'\n",
+       "  * file_path  (file_path) <U43 344B '../../test/data/salmon/multiple/Sample_...\n",
+       "Dimensions without coordinates: file\n",
+       "Data variables:\n",
+       "    abundance  (gene_id, file) float64 8kB 0.08291 0.0 0.09854 ... 0.4618 0.0\n",
+       "    counts     (gene_id, file) float64 8kB 1.005 0.0 1.086 ... 1.957 6.208 0.0\n",
+       "    length     (gene_id, file) float64 8kB 509.1 509.1 445.8 ... 564.6 564.6
" + ], + "text/plain": [ + " Size: 60kB\n", + "Dimensions: (gene_id: 496, file: 2, file_path: 2)\n", + "Coordinates:\n", + " * gene_id (gene_id) \n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
transcript_idtranscript_name
0ENST00000387314MT-TF-201
1ENST00000389680MT-RNR1-201
2ENST00000387342MT-TV-201
3ENST00000387347MT-RNR2-201
4ENST00000386347MT-TL1-201
\n", + "" + ], + "text/plain": [ + " transcript_id transcript_name\n", + "0 ENST00000387314 MT-TF-201\n", + "1 ENST00000389680 MT-RNR1-201\n", + "2 ENST00000387342 MT-TV-201\n", + "3 ENST00000387347 MT-RNR2-201\n", + "4 ENST00000386347 MT-TL1-201" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "transcript_name_map_human = create_transcript_gene_map(\"human\", target_field=\"external_transcript_name\")\n", + "transcript_name_map_human.head(5)" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
../../test/data/salmon/quant.sf
HOXC8-2014486.940412
UGT3A2-2011307.314695
HOXC9-201886.909534
HOXC4-202749.069369
HOXC12-201544.817685
\n", + "
" + ], + "text/plain": [ + " ../../test/data/salmon/quant.sf\n", + "HOXC8-201 4486.940412\n", + "UGT3A2-201 1307.314695\n", + "HOXC9-201 886.909534\n", + "HOXC4-202 749.069369\n", + "HOXC12-201 544.817685" + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "txi = replace_transcript_ids_with_names(txi, transcript_name_map_human)\n", + "pd.DataFrame(txi.X.T, index=txi.var.index, columns=txi.obs.index).sort_values(\n", + " by=txi.obs.index[0],\n", + " ascending=False,\n", + ").head(5)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The same data summarized to genes:" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Reading quantification files: 1it [00:00, 356.26it/s]\n" + ] + }, + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
../../test/data/salmon/quant.sf
HOXC84486.940412
UGT3A21506.597257
HOXC41152.964133
HOXC9886.909534
HOXC12544.817685
\n", + "
" + ], + "text/plain": [ + " ../../test/data/salmon/quant.sf\n", + "HOXC8 4486.940412\n", + "UGT3A2 1506.597257\n", + "HOXC4 1152.964133\n", + "HOXC9 886.909534\n", + "HOXC12 544.817685" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "txi = tximport(\n", + " [\"../../test/data/salmon/quant.sf\"],\n", + " \"salmon\",\n", + " transcript_gene_map_human,\n", + " counts_from_abundance=\"scaled_tpm\",\n", + " output_type=\"xarray\",\n", + " return_transcript_data=False,\n", + ")\n", + "pd.DataFrame(txi[\"counts\"], index=txi.coords[\"gene_id\"], columns=txi.coords[\"file_path\"]).sort_values(\n", + " by=txi.coords[\"file_path\"].data[0],\n", + " ascending=False,\n", + ").head(5)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Note that the top transcript corresponds to the top expressed gene in this case." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Exporting AnnData files" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "`pytximport` integrates well with other packages from the `scverse` through its `AnnData` export option." + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Reading quantification files: 1it [00:00, 334.47it/s]\n" + ] + }, + { + "data": { + "text/plain": [ + "AnnData object with n_obs × n_vars = 1 × 10\n", + " uns: 'counts_from_abundance'\n", + " obsm: 'length', 'abundance'" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "txi_ad = tximport(\n", + " [\"../../test/data/salmon/quant.sf\"],\n", + " \"salmon\",\n", + " transcript_gene_map_human,\n", + " output_type=\"anndata\",\n", + " # the output can optionally be saved to a file by uncommenting the following lines\n", + " # output_format=\"h5ad\",\n", + " # output_path=\"txi_ad.h5ad\",\n", + ")\n", + "txi_ad" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Use from the command line\n", + "\n", + "You can run `pytximport` from the command line, too. Available options can be viewed via the `pytximport --help` command." + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Usage: pytximport [OPTIONS]\n", + "Try 'pytximport --help' for help.\n", + "\n", + "Error: No such option: --output_type (Possible options: --data_type, --output_format, --output_path)\n" + ] + } + ], + "source": [ + "!pytximport -i ../../test/data/salmon/quant.sf -t \"salmon\" -m ../../test/data/gencode.v46.metadata.HGNC.tsv --output_type \"anndata\" --output_format \"h5ad\" --output_path_overwrite -o ../../test/data/salmon/quant.h5ad" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Inferential replicates" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "`pytximport` can handle bootstraping replicates provided by `salmon` and `kallisto`. When `inferential_replicate_transformer` is set, the provided function is used to recalculate the counts and abundances for each sample based on the bootstraps." + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Reading quantification files: 4it [00:01, 2.71it/s]\n", + "WARNING:root:Not all transcripts are present in the mapping. 31380 out of 253181 missing. Removing the missing transcripts.\n" + ] + }, + { + "data": { + "text/plain": [ + "AnnData object with n_obs × n_vars = 4 × 40768\n", + " uns: 'counts_from_abundance', 'inferential_replicates'\n", + " obsm: 'length', 'abundance', 'variance'" + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "result = tximport(\n", + " [\n", + " \"../../test/data/fabry_disease/SRR16504309_wt/\",\n", + " \"../../test/data/fabry_disease/SRR16504310_wt/\",\n", + " \"../../test/data/fabry_disease/SRR16504311_ko/\",\n", + " \"../../test/data/fabry_disease/SRR16504312_ko/\",\n", + " ],\n", + " \"salmon\",\n", + " transcript_gene_map_human,\n", + " inferential_replicates=True,\n", + " inferential_replicate_variance=True, # whether to calculate the variance of the inferential replicates\n", + " inferential_replicate_transformer=lambda x: np.median(x, axis=1),\n", + " counts_from_abundance=\"length_scaled_tpm\",\n", + ")\n", + "result" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Downstream analysis with PyDESeq2\n", + "\n", + "The output from `pytximport` can easily be used for downstream analysis with `PyDESeq2`. For more information on `PyDESeq2`, please consult its [documentation](https://pydeseq2.readthedocs.io/en/latest/)." + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Note: you may need to restart the kernel to use updated packages.\n" + ] + } + ], + "source": [ + "%pip install pydeseq2 decoupler adjustText omnipath tqdm ipywidgets seaborn -q" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [], + "source": [ + "from pydeseq2.dds import DeseqDataSet\n", + "from pydeseq2.default_inference import DefaultInference\n", + "from pydeseq2.ds import DeseqStats\n", + "import decoupler as dc" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Load the .csv file generated by `pytximport` via the `output_path` argument or create it directly from the output of `pytximport`. In this case, we are working with the salmon quantification files from a public bulk RNA sequencing dataset: [Podocyte injury in Fabry nephropathy](https://www.ebi.ac.uk/ena/browser/view/PRJNA773084)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Round count estimates (required by PyDESeq2) and add the corresponding metadata." + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "AnnData object with n_obs × n_vars = 4 × 40768\n", + " obs: 'condition'\n", + " uns: 'counts_from_abundance', 'inferential_replicates'\n", + " obsm: 'length', 'abundance', 'variance'" + ] + }, + "execution_count": 17, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "result.X = result.X.round().astype(int)\n", + "result.obs[\"condition\"] = [\"Control\", \"Control\", \"Disease\", \"Disease\"]\n", + "result" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Filter genes with low counts out." + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "AnnData object with n_obs × n_vars = 4 × 14714\n", + " obs: 'condition'\n", + " uns: 'counts_from_abundance', 'inferential_replicates'\n", + " obsm: 'length', 'abundance', 'variance'" + ] + }, + "execution_count": 18, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "result = result[:, result.X.max(axis=0) > 10].copy()\n", + "result" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now perform your `PyDESeq2` analysis." + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": {}, + "outputs": [], + "source": [ + "dds = DeseqDataSet(\n", + " adata=result,\n", + " design_factors=\"condition\",\n", + " refit_cooks=True,\n", + " inference=DefaultInference(n_cpus=8),\n", + " quiet=True,\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/Users/au734063/.pyenv/versions/3.9.16/lib/python3.9/site-packages/pydeseq2/dds.py:490: UserWarning: As the residual degrees of freedom is less than 3, the distribution of log dispersions is especially asymmetric and likely to be poorly estimated by the MAD.\n", + " self.fit_dispersion_prior()\n" + ] + } + ], + "source": [ + "dds.deseq2()" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": {}, + "outputs": [], + "source": [ + "stat_result = DeseqStats(dds, contrast=(\"condition\", \"Disease\", \"Control\"), quiet=True)" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": {}, + "outputs": [], + "source": [ + "%%capture\n", + "stat_result.summary()\n", + "stat_result.lfc_shrink()" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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kkRERERERJQBq9sREZFOkUgkqFWrlup9fqUrcRIRkSZBFEVR20F8TrGxsbCwsEBMTAzMzc21HQ4REREREWlJdnMDfrVFRERERESUAZMkIiIiIiKiDJgkERGRTklISEDJkiVRsmRJJCQkaDucLOlKnEREpImFG4iISKeIoogHDx6o3udXuhInERFp4kgSERERERFRBkySiIiIiIiIMmCSRERERERElAGTJCIiIiIiogyYJBEREREREWXA6nZERKRTBEFAxYoVVe/zK12Jk4iINDFJIiIinWJiYoKrV69qO4yP0pU4iYhIE6fbERERERERZcAkiYiIiIiIKAMmSUREpFMSEhLg4uICFxcXJCQkaDucLOlKnEREpIlrkoiISKeIoohr166p3udXuhInERFp4kgSERERERFRBkySiIiIiIiIMmCSRERERERElAGTJCIiIiIiogyYJBEREREREWXA6nZERKRTBEFAiRIlVO/zK12Jk4iINDFJIiIinWJiYoKIiAhth/FRuhInERFp4nQ7IiIiIiKiDJgkERERERERZcAkiYiIdEpiYiJq166N2rVrIzExUdvhZElX4iQiIk1ck0RERDpFqVQiLCxM9T6/0pU4iYhIE0eSiIiIiIiIMmCSRERERERElAGTJCIiIiIiogzyTZI0d+5cCIKAYcOGqY4lJSXBz88PhQoVgkwmQ/v27fHs2TPtBUlERERERAVevkiS/vvvP6xZswZVqlRROz58+HD89ddf2LJlC44ePYqnT5+iXbt2WoqSiIiIiIi+BlpPkuLj49G9e3f8/PPPsLKyUh2PiYlBYGAgFi9ejCZNmqBmzZoICgrCqVOncObMGS1GTERE2la4cGEULlxY22F8lK7ESURE6rSeJPn5+aFly5bw9PRUO37u3DmkpqaqHS9fvjwcHR1x+vTpLx0mERHlE6ampnjx4gVevHgBU1NTbYeTJV2Jk4iINGl1n6SQkBCcP38e//33n8a5qKgoGBgYwNLSUu24ra0toqKisuwzOTkZycnJqp9jY2PzLF4iIiIiIir4tDaS9OjRI/z4449Yv349jIyM8qzfOXPmwMLCQvVycHDIs76JiIiIiKjg01qSdO7cOTx//hw1atSAVCqFVCrF0aNHsWzZMkilUtja2iIlJQXR0dFq1z179gx2dnZZ9jt+/HjExMSoXo8ePfrMT0JE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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "dc.plot_volcano_df(\n", + " stat_result.results_df,\n", + " x=\"log2FoldChange\",\n", + " y=\"padj\",\n", + " sign_thr=0.01,\n", + " top=20,\n", + " figsize=(10, 5),\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Running ulm on mat with 1 samples and 14714 targets for 660 sources.\n" + ] + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAbgAAAEuCAYAAAD89QftAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjkuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8hTgPZAAAACXBIWXMAAA9hAAAPYQGoP6dpAAAwrElEQVR4nO3deXxM5/4H8M+ZkBHZRMUSIkGtRZOGpuq21pvGdquK1lax5FdK7Wt7fzeirgjqorbatbdEtapVrVJpg6JSGloEqS1EFK0ktolknt8fOvMzMUnOyJw5M2c+79freb06c87M95kp8/XskhBCgIiISGN0aleAiIhICUxwRESkSUxwRESkSUxwRESkSUxwRESkSUxwRESkSUxwRESkSUxwRESkSeXUroAjGY1GZGVlwdfXF5IkqV0dIqIyE0IgLy8PQUFB0OnK3ma5e/cu8vPzZd/v6emJChUqlDmuEtwqwWVlZSE4OFjtahAR2V1mZiZq1apVpve4e/cugrx88CcKZb+mevXqOHv2rFMmObdKcL6+vgDu/0Hw8/NTuTZERGWXm5uL4OBg8+9bWeTn5+NPFOID73qoKJXeGrwtjHgt+zfk5+czwanN1C3p5+fHBEdEmmLPYRdvz3LwljxKjykKgVt2C2t3bpXgiIiodDoPCTpd6QlTZ3TuuQxMcEREZEEqL0GSkeAkJ09wLrVM4NKlS+jfvz8ee+wxeHl5oVmzZvjpp5/UrhYRkaboykmyizNzmRbcn3/+idatW6Ndu3b4+uuvERgYiNOnTyMgIEDtqhERaYpWWnAuk+ASExMRHByMNWvWmJ+rU6eOijUiItImnYcEnYeMMbhC505wLtNF+cUXX6BFixbo1asXqlativDwcKxYsaLE1xgMBuTm5loUIiIqmeQhyS7OzGUS3JkzZ7B06VLUr18f33zzDYYPH45Ro0Zh3bp1xb4mISEB/v7+5sJF3kREpfMor5NdnJkkhBBqV0IOT09PtGjRAvv27TM/N2rUKKSmpmL//v1WX2MwGGAwGMyPTQsic3JyuA6OiBSzrXxDxWN0uXcSwP3fNX9/f7v8rpnea0dYOLw9Sl8Hd6uwEFFpPzvtb6rLjMHVqFEDTZo0sXiucePG+PTTT4t9jV6vh16vV7pqRESaInsMDs7dRekyCa5169Y4efKkxXOnTp1CSEiISjUiItImSeIsSocaO3Ysnn32WcycORO9e/fGwYMHsXz5cixfvlztqhERaYrkAVktOMnJB7ice4TwAS1btsRnn32GDRs2oGnTpnjnnXcwf/589OvXT+2qERFpilZmUbpMCw4Aunbtiq5du6pdDSJyAcmhzRWP0f7cUcVjqEHS6SDJOFtOzj1qcqkER0REypN0MsfgZNyjJiY4IlJMSuMwxWO0OZGmeAx3I3sWpWCCIyIiF6Lz8ICuXOnr4HROvoyaCY6IiCywi5KIiDRJdhcl18ERkZoORD6teIxnfjyoeAxyHLbgiEi2H1tFKh4jcv+Piscg98BlAkREpElswRG5mEPtWiseI+K7HxSPQaQ0JjgiItIkJjiiR5AW9ZziMcJ27FE8BpGW3U9wcsbgmODIiiPRzyse48ntu50uNhE5P0knb5mAVMgER0RELkRXTuZOJkajA2rz6JjgiIjIAsfgiIhIk5jgiIhIk7jQm4iINEkrLTjnTr9ERORwphacnPKoZs2aBUmSMGbMGPtVvAi24IiIyJIk3S9y7nsEqampeP/999G8efNHer1cbMEREZEFSZLM3ZQllkdIcDdv3kS/fv2wYsUKBAQEKFD7/8cER0REFmztoszNzbUoBoOh2PceMWIEunTpgo4dOyr+OdhFSUREFmQv9C68v9A7ODjY4vm4uDhMmzbtofuTkpJw+PBhpKam2qWepWGCIyIiC5JO3gxJ6a8+wMzMTPj5+Zmf1+v1D92bmZmJ0aNHY+fOnahQoYLd6loSJjgiIrJg6zIBPz8/iwRnzaFDh/D777/jqaeeMj9XWFiI3bt3Y9GiRTAYDPDwKL3VaAsmOCIisqTT3S9y7pOpQ4cO+OWXXyyeGzRoEBo1aoTJkyfbPbkBLjzJxBFrKIiI3JEkSbKLXL6+vmjatKlF8fb2xmOPPYamTZsq8jlcsgXnqDUURETuiFt1qeTBNRQzZsxQuzpERJrjqK26vv/++zK9vjTOnX6tsGUNhcFgeGh9BhERlULS/f84XElFcu4U4lItOFvXUCQkJCA+Pl7hWhERaYzMFhy42bJ9mNZQfPTRR7LXUEydOhU5OTnmkpmZqXAtiYhcn+ThIbs4M5dpwT3KGgq9Xm91wSERERWPk0wcTI01FERE7kgr58G5TIIzraF4kNJrKIiI3JIkyZtA8ojH5TiKyyQ4IiJyDLbgnIDSayiIiNySAlt1qcGlExwREdmf3G24HuXAU0digiMiIkuSzBYcF3oTEZEr4RgcERFpk4fH/SLnPifGBEdERBYkSQdJRvejnHvUxARHRESWdJK8fSbZRUlERK6EW3UREZE2SZK8XUq4TICIiFyKTpK50JsJjoiIXAlbcEREpEUcgyMiIm2SdDJPE2CCIyIiFyLp5J3WLem40JuIiFwJ18EREZEmsYuSiIg0ibMoiYhIk3jgKRERaRK7KImISJM4yYSIiDRJkmS24Jw7wTl3+5KIiBzPNMlETpEpISEBLVu2hK+vL6pWrYru3bvj5MmTCn4IJjgiIirKNMlETpEpJSUFI0aMwIEDB7Bz507cu3cPUVFRuHXrlmIfg12URERkSedxv8i5T6bt27dbPF67di2qVq2KQ4cO4fnnn7e1hrIwwRERkSVJZuvsr3G63Nxci6f1ej30en2JL83JyQEAVK5c+dHqKIPLdFGq0X9LROSWbByDCw4Ohr+/v7kkJCSU+PZGoxFjxoxB69at0bRpU8U+hsu04Ez9ty1btkRBQQHeeustREVF4fjx4/D29la7ekRE2mHjOrjMzEz4+fmZny6t9TZixAj8+uuv2Lt3b5mqWRqXSXBq9N8SEbklG7fq8vPzs0hwJRk5ciS+/PJL7N69G7Vq1SpLLUvlMgmuKDn9twaDAQaDwfy4aD8xERFZocBWXUIIvPnmm/jss8/w/fffo06dOmWooDwuMwb3ILn9twkJCRb9wsHBwQ6sJRGRaxKSJLvINWLECPz3v//F+vXr4evri+zsbGRnZ+POnTuKfQ6XTHCm/tukpKQS75s6dSpycnLMJTMz00E1JCJyYaadTEot8hPc0qVLkZOTg7Zt26JGjRrmsnHjRsU+hst1UdrSfytnqioRERWhwGbLQogyVOjRuEyCU6P/lojIHQmdB4SMRdxy7lGTyyS4ESNGYP369fj888/N/bcA4O/vDy8vL5VrR0SkIRo58NRlxuDU6L8lInJLCuxFqQaXacGp0X9LROSO5M6QtGUWpRpcJsEREZGD8ERvIiLSIiHpIGQkLzn3qIkJjoiILGlkkgkTHBERWRCQ2YJz8nmKTHBERGRJIy04m9NvXFwczp8/r0RdiIjICQidzrzYu+Ti3C04m2v3+eefo169eujQoQPWr19vsVs/ERFpgKx9KGXOtFSRzbVLS0tDamoqnnjiCYwePRrVq1fH8OHDkZqaqkT9iIjIwQQk2cWZPVL6DQ8Px8KFC5GVlYVVq1bh4sWLaN26NZo3b44FCxaYz2ojIiLXY1omIKc4szLVTgiBe/fuIT8/H0IIBAQEYNGiRQgODuYWWkRErspduygB4NChQxg5ciRq1KiBsWPHIjw8HCdOnEBKSgpOnz6Nf//73xg1apS960pERA6gxIGnarB5mUCzZs2Qnp6OqKgorFq1Ct26dYOHh+WRCX369MHo0aPtVkkiInIct93JpHfv3hg8eDBq1qxZ7D1VqlSB0WgsU8WIiEgl7roOzjTWVtSdO3cwffp0u1SKiIhUJHeCiZO34GyuXXx8PG7evPnQ87dv30Z8fLxdKkVEROoxSh6yizOzuYtSCAHJSrP0yJEjqFy5sl0qRUREKpIgs4tS8ZqUiewEFxAQAEmSIEkSGjRoYJHkCgsLcfPmTQwbNkyRShIRkeMI6GRtpKyZzZbnz58PIQQGDx6M+Ph4+Pv7m695enoiNDQUrVq1UqSSRETkOG53ovfAgQMBAHXq1MGzzz6L8uXLK1YpIiJSj1stE8jNzYWfnx+A+9t03blzB3fu3LF6r+k+IiJyTXL3mXT2vShlJbiAgABcvnwZVatWRaVKlaxOMjFNPiksLLR7JYmIyHHcqgWXnJxsniGZnJxsNcEREZE2uNUYXJs2bcz/3bZtW6XqQkRETkArXZQ2ty/r16+PadOm4fTp00rUh4iIVOa2x+W88cYb2LZtGxo1aoSWLVtiwYIFyM7OVqJuRESkAiNk7mQC23cyWbx4MUJDQ1GhQgVERkbi4MGDCnyC+2xOcGPHjkVqaipOnDiBzp07Y/HixQgODkZUVBQ++OADJepowZFfDhGRO1LqRO+NGzdi3LhxiIuLw+HDh/Hkk0/ihRdewO+//67I53jk9mWDBg0QHx+PU6dOYc+ePbh69SoGDRpkz7o9xNFfDhGRO7o/yUROF6VtCW7evHmIjY3FoEGD0KRJEyxbtgwVK1bE6tWrFfkcZepAPXjwIMaMGYOXXnoJp06dQq9evexVL6sc/eUQEbkjW1twubm5FsVgMDz0nvn5+Th06BA6duxofk6n06Fjx47Yv3+/Ip/D5gR36tQpxMXFoUGDBmjdujVOnDiBxMREXLlyBUlJSUrUEcCjfTkGg+GhL56IiEpm64newcHB8Pf3N5eEhISH3vPatWsoLCxEtWrVLJ6vVq2aYvM4bD5NwDS5ZMSIEXj11VcfqqxSSvpy0tPTrb4mISGhxCN8/tYtxa51tGbv1jZWn39y+27FYxdHzdhhO/aoFjviux9Uix25/0fVYj/zo3rj1G1OpKkWu/25o6rF7nLvpGqx7UEICULIWCbw1z2ZmZkWu1jp9XrF6mYLmxPcyZMnUb9+fSXqYndTp07FuHHjzI9zc3MRHBysYo2IiFyBvNMETJ2Afn5+pW7TWKVKFXh4eODKlSsWz1+5cgXVq1d/1IrKqJ0N1Epuj/Ll6PV68xcv538AEREpM4vS09MTERER2LVrl/k5o9GIXbt2KXYSjawEV7lyZVy7dg3A/X0pK1euXGxRihpfDhGRO1JqmcC4ceOwYsUKrFu3DidOnMDw4cNx69YtxWbgy+qi/M9//gNfX1/zf6u1F+W4ceMwcOBAtGjRAk8//TTmz5+v6JdDROSOjNDBKKP9I+eeB73yyiu4evUq/vWvfyE7OxthYWHYvn27YnM5ZCU401lwABATE6NIReRw9JdDROSObJ1kYouRI0di5MiRj1Itm9k8Bufh4WF1YfX169fh4WH7ti22GjlyJM6fPw+DwYAff/wRkZGRisckInInSnVROprNsyiFEFafNxgM8PT0LHOFiIhIXVo5TUB2glu4cCEAQJIkrFy5Ej4+PuZrhYWF2L17Nxo1amT/GhIRkUO5XYL7z3/+A+B+C27ZsmUW3ZGenp4IDQ3FsmXL7F9DIiJyKAGZY3BaSXBnz54FALRr1w6bN29GQECAYpUiIiL1GCHBKCN5yblHTTaPwX333XdK1IOIiJyEVroobZ5F+fLLLyMxMfGh52fPnq34aQJERKQ80zIBOcWZ2Zzgdu/ejc6dOz/0fKdOnbB7t3qb+BIRkX0YhQSj0Mkozp3gbO6ivHnzptXlAOXLl+dxNEREGuC2XZTNmjXDxo0bH3o+KSkJTZo0sUuliIhIPVrporS5Bfe///u/6NGjB3777Te0b98eALBr1y6sX78en3zyid0rSEREjiUAGGXe58xsTnDdunXDli1bMHPmTHzyySfw8vLCk08+ieTkZEVPEyAiIsdQci9KR7I5wQFAly5d0KVLFwD3DxHdsGEDJkyYgEOHDqGwsNCuFSQiIsdy2zE4k927d2PgwIEICgrCu+++i/bt2+PAgQP2rBsREanALcfgsrOzsXbtWqxatQq5ubno3bs3DAYDtmzZwgkmREQa4XYtuG7duqFhw4Y4evQo5s+fj6ysLLz33ntK1o2IiFRgFPKLM5Pdgvv6668xatQoDB8+HPXr11eyTkREpCLTQm459zkz2bXbu3cv8vLyEBERgcjISCxatAjXrl1Tsm5ERKQCIeQXZyY7wT3zzDNYsWIFLl++jNdffx1JSUkICgqC0WjEzp07kZeXp2Q9iYjIQUynCcgpzszm9qW3tzcGDx6MvXv34pdffsH48eMxa9YsVK1aFf/4xz+UqCMRETmQVmZRlqkDtWHDhpg9ezYuXryIDRs22KtORESkIq10UT7SQu+iPDw80L17d3Tv3t0eb0dERCrSyjIBuyQ4IiLSDrlLADSzTICIiNyE3PE1Jx+DY4IjIiILcsfX3GIMjoiItEPuEgDNLRNQw7lz5zBkyBDUqVMHXl5eqFevHuLi4pCfn6921YiINMdolGQXZ+YSLbj09HQYjUa8//77ePzxx/Hrr78iNjYWt27dwty5c9WuHhGRpnCSiQNFR0cjOjra/Lhu3bo4efIkli5dygRHRGRnWhmDc4kuSmtycnJKPUHcYDAgNzfXohARUclM6+DkFCXYa1jKJVpwRWVkZOC9994rtfWWkJCA+Ph4B9WKiEgbjJDZRalQfHsNS6nagpsyZQokSSqxpKenW7zm0qVLiI6ORq9evRAbG1vi+0+dOhU5OTnmkpmZqeTHISLSBLW36oqOjsaaNWsQFRWFunXr4h//+AcmTJiAzZs32/Q+qrbgxo8fj5iYmBLvqVu3rvm/s7Ky0K5dOzz77LNYvnx5qe+v1+uh1+vLWk0iIrdi6xhc0eEfJX575QxLFaVqggsMDERgYKCsey9duoR27dohIiICa9asgU7nssOHREROzSgkGGXsUmK6Jzg42OL5uLg4TJs2zW71kTssVZRLjMFdunQJbdu2RUhICObOnYurV6+ar1WvXl3FmhERaY+tLbjMzEz4+fmZny+u9TZlyhQkJiaW+J4nTpxAo0aNzI9tGZYqyiUS3M6dO5GRkYGMjAzUqlXL4ppw9nmqREQuxmgECmXMIDH+dY+fn59FgiuO0sNSRblEgouJiSn1SyEiIvuQe5iprQeeOnpYyiUSHBEROY7aC73tNSzFBEdERBbU3qrLXsNSnIpIREQW1F4HFxMTAyGE1WILtuCIiMiC2l2U9sIER0REFtTuorQXJjgiIrLAFhwREWmS0fj/a9xKu8+ZMcEREZEFJjgiItIktY/LsRcmOCIisiB3Sr6zb5XIBEdERBY4yYSIiDRJyByDE07eR8kER0REFtiCIyIiTeJCbyIi0iS24IiISJOEUUDIaJ7JuUdNTHBERGShUOaJ3nLuURMTHBERWTAaBYwyWmdy7lETExwREVngGBwREWkSExwREWmSUQgYZWQvOfeoiQmOiIgsCKO8XUq4kwkREbkUAZmbLYMtOCIiciHci5KIiDRJK8fl6NSugK0MBgPCwsIgSRLS0tLUrg4RkeaY9qKUU5yZyyW4SZMmISgoSO1qEBFplrFQyC7OzKUS3Ndff40dO3Zg7ty5aleFiEizTDuZyCnOzGXG4K5cuYLY2Fhs2bIFFStWlPUag8EAg8Fgfpybm6tU9YiININjcA4khEBMTAyGDRuGFi1ayH5dQkIC/P39zSU4OFjBWhIRaYNpHZyc4sxUTXBTpkyBJEkllvT0dLz33nvIy8vD1KlTbXr/qVOnIicnx1wyMzMV+iRERNph2slETnFmqnZRjh8/HjExMSXeU7duXSQnJ2P//v3Q6/UW11q0aIF+/fph3bp1Vl+r1+sfeg0REZVMK12Uqia4wMBABAYGlnrfwoULMWPGDPPjrKwsvPDCC9i4cSMiIyOVrCIRkdtxpuNyDAYDIiMjceTIEfz8888ICwuT/VqXmGRSu3Zti8c+Pj4AgHr16qFWrVpqVImISLOc6TQB09KwI0eO2Pxal5hkQkREjiOEgDDKKApnuLIuDXOJFlxRoaGhTt/3S0TkqoyFRhQWlj5F0vjXPUWXYNlj/sOjLA0rii04IiKyIKv19lcBgODgYIslWQkJCWWL/4hLw4pyyRYcEREpR+4+k6Z7MjMz4efnZ36+uNbblClTkJiYWOJ7njhxAjt27HikpWFFMcEREZGFB1tnpd0HAH5+fhYJrjhKLw0rigmOiIgsKLUOztFLw5jgiIjIgtEob42bnENRH4W9loYxwRERkQXuZEJERJpk6xic0h51aRgTHBERWXC2BPeomOCIiMhCoVHeQu9CpQbh7IQJjoiILHAMjoiINEnIPE2AXZRERORSOAZHRESaxC5KIiLSJGE0QsiYQCLnHjUxwRERkQVnOtG7LJjgiIjIArsoiYhIkzjJhIiINKnQWAhdYaGs+5wZExwREVkQRnmtM+Hcc0yY4IiIyBK7KImISJM4yYSIiDTJaDTCKGONm5x71MQER0REFthFSUREmiSEEULGDBI596hJp3YFbLFt2zZERkbCy8sLAQEB6N69u9pVIiLSHFMLTk5xZi7Tgvv0008RGxuLmTNnon379igoKMCvv/5apvfcu7WNnWpHRKQhcpMXE1zZFRQUYPTo0ZgzZw6GDBlifr5JkyYq1oqISJuMwgijjO5HOfeoySW6KA8fPoxLly5Bp9MhPDwcNWrUQKdOnUptwRkMBuTm5loUIiIqmbGwEMYCGUXGbidqcokEd+bMGQDAtGnT8M9//hNffvklAgIC0LZtW/zxxx/Fvi4hIQH+/v7mEhwc7KgqExG5LK2Mwama4KZMmQJJkkos6enp5rUWb7/9Nl5++WVERERgzZo1kCQJmzZtKvb9p06dipycHHPJzMx01EcjInJZplmUcoozU3UMbvz48YiJiSnxnrp16+Ly5csALMfc9Ho96tatiwsXLhT7Wr1eD71eb5e6EhG5C6NR3llvTr7OW90EFxgYiMDAwFLvi4iIgF6vx8mTJ/G3v/0NAHDv3j2cO3cOISEhSleTiMit8ERvB/Lz88OwYcMQFxeH4OBghISEYM6cOQCAXr16qVw7IiJt4U4mDjZnzhyUK1cOAwYMwJ07dxAZGYnk5GQEBASoXTUiIk3Ryk4mLpPgypcvj7lz52Lu3LlqV4WISNPYgnNBpqMduB6OiLTC9Htmz6NrCvLzZI2vFRbcsltMJbhVgsvLywMArocjIs3Jy8uDv79/md7D09MT1atXx0+7est+TfXq1eHp6VmmuEqRhLOfWGdHRqMRWVlZ8PX1hSRJNr02NzcXwcHByMzMhJ+fn0I1ZGzGZmzGto0QAnl5eQgKCoJOV/alzXfv3kV+fr7s+z09PVGhQoUyx1WCW7XgdDodatWqVab38PPzc/hfAMZmbMZm7JKUteX2oAoVKjhtwrKVS2zVRUREZCsmOCIi0iQmOJn0ej3i4uJU2fqLsRmbsRmbbOdWk0yIiMh9sAVHRESaxARHRESaxARHRESaxARHRESaxARHRESaxARnxe+//17qPXv27HFATchZ3LhxA4sWLVK7Gppy4sQJrFmzBunp6QCA9PR0DB8+HIMHD0ZycrLKtSMtYIKzomnTpvjkk0+sXrtz5w5GjRqFDh06KBY/KysLEyZMsHrqQU5ODiZOnIgrV64oFr84v/32G9q3b+/wuCYFBQW4cOGCQ2Pu2rULffv2RY0aNRAXF+fQ2CZXrlzB9OnTVYmtlO3btyMsLAwTJkxAeHg4tm/fjueffx4ZGRk4f/48oqKi3DLJqf13TGuY4KyYPHkyXnvtNfTp0wd//vmn+fk9e/agWbNm2L59O7777jvF4s+bNw+5ublW96Xz9/dHXl4e5s2bp1j84ty8eRMpKSkOj2ty7Ngx1KlTR/E4mZmZmD59OurUqYOoqChIkoTPPvsM2dnZise2Jjs7G/Hx8arEVuoHd/r06Zg4cSKuX7+ONWvWoG/fvoiNjcXOnTuxa9cuTJw4EbNmzbJ7XLnUSjRq/x3TGi70Lsbx48cxcOBAXLp0CQsXLsSePXuwZMkSDB8+HImJifDy8lIsdtOmTbFs2TL87W9/s3p93759iI2NxbFjx+wad+HChSVev3TpEubOnYvCwkK7xpXryJEjeOqppxSJf+/ePWzZsgUrV67Enj17EB0djb59+6JPnz44cuQImjRpYveYJkePHi3xenp6Ovr06aPK967Ud+7v749Dhw7h8ccfh9FohF6vx8GDBxEeHg4A+PXXX9GxY0fV/lGh1Od29r9jWuNWpwnYokmTJjhw4AD69euHV155BRUrVsS3336LNm3aKB777NmzqF27drHXa9WqhXPnztk97pgxY1CjRo1iz3ay5QiNR/HUU0+VeP3OnTuKxa5ZsyYaNWqE/v37IykpCQEBAQCAPn36KBbTJCwsDJIkWT2w0vS8rcc7ySXnB1cpps+k0+lQoUIFix3xfX19kZOTo1hstT632n/H3A0TXDHu3buHuLg4bN68Ga+88gq2b9+OmTNnol69emU+cqc0Xl5eOHfuXLFJ7ty5c4q0IENCQpCYmIjeva0fdpiWloaIiAi7xzU5fvw4Xn311WK7IS9fvoxTp04pErugoACSJEGSJHh4eCgSoziVK1fG7Nmzix3XPXbsGLp166ZIbLV+cENDQ3H69GnUq1cPALB//36LP+8XLlxAjRo1FIkNqPe51f475m6Y4KxIS0vDgAEDcOvWLXzzzTdo164dLl26hNjYWDRt2hTvvvsuhgwZolj8yMhIfPjhh3j++eetXv/ggw/w9NNP2z1uREQEDh06VOxfvuJaGfbStGlTREZGYvjw4Vavp6WlYcWKFYrEzsrKwqeffopVq1Zh9OjR6NSpE/r3769Yy+lBERERyMrKQkhIiNXrN27cUOx7V+sHd/jw4RbdcE2bNrW4/vXXXys6BqbW51b775jbEfQQT09PERsbK/Ly8h66tmLFCuHn5yc6deqkWPzk5GTh4eEhxo8fL7Kzs83PZ2dni3HjxgkPDw+xa9cuu8c9duyYSE1NLfZ6fn6+OHfunN3jmowaNUqMHj262OsZGRmibdu2isV/MM7bb78tatWqJSRJEn379hU7duwQBQUFisTbvHmz+PDDD4u9/scff4i1a9cqEvvll18WkyZNKvZ6WlqakCRJkdhqUutzq/13zN0wwVnx1VdflXj93LlzomPHjorWYdmyZUKv1wudTicqVaokAgIChE6nE3q9XixZskTR2HRfYWGh+Oqrr8TLL78sPD09xWOPPaZ2lexOrR9cnU4nrly5Yvf3lYuJxj1wFqUTysrKQlBQEC5evIhNmzYhIyMDQgg0aNAAPXv2VHQM8MCBA9i6dSvy8/PRoUMHREdHKxbLlVy9ehUffvghxo0b5/DYJ06cwKpVqzB37lyHx1aKTqdDdnY2qlatqnZVSMtUTrBO6dSpU+LVV18VOTk5D127ceOG6NOnj/jtt98Ui1+pUiXx0UcfKfb+xdm0aZPQ6XTC29tbVKpUSeh0OjFnzhyHxR8wYIDIzc01P05LSxP5+fkOi+9Mbt68KVauXClatWolJEkSTzzxhCJxdu3aJe7du6fIe5dEkiRVW3CluXPnjiJ/9sPCwkR4eHipheyDLTgr/ud//geVKlXC7NmzrV6fPHkycnNzsXTpUkXiL1myBJMnT0Z0dDTef/99VK5cWZE4RUVERKBly5ZYvHgxPDw8kJCQgDlz5uCPP/5wSHwPDw9cvnzZ/K96Pz8/pKWloW7dug6JXxIl1+A96IcffsCqVavw8ccf486dOxg7diyGDh2KRo0aKRKv6Hf+zDPP4NNPP0XNmjUViWei0+kwY8YM+Pj4lHjfqFGjFKvD1atX8eOPP8LT0xMdOnSAh4cH7t27hyVLliAhIQEFBQW4du2aXWPKXbCv1q45mqN2hnVGDRo0EAcPHiz2+k8//SQaNGigaB3OnDkj2rVrJ6pVqya++OILRWOZeHt7i9OnT5sfGwwGUa5cOYf9S7vov+p9fHwUbSnbQsnJFleuXBGJiYmiYcOGonr16mLs2LEiNTVVlCtXThw7dkyRmCZqfeeSJIng4GARGhpabKlTp45i8ffs2SP8/f2FJElCp9OJp59+Whw7dkzUr19fNG7cWCxdulTcvn1bsfjkGFwmYMWFCxdKHBuoUqUKMjMzFa1DnTp1kJycjEWLFqFHjx5o3LgxypWz/N91+PBhu8a8ffu2xfZgnp6eqFChAm7evKn5sZIePXqUeD0nJ0exJQMhISHo2bMnFixYgL///e/Q6dxjB72ffvpJtT9X//znP9G5c2e89dZbWLduHd5991289NJLmDlzJnr27KlobI5zOw4TnBX+/v747bffil2XlJGRYXWfSHs7f/48Nm/ejICAALz44osPJTglrFy50qLbqKCgAGvXrkWVKlXMzynZbXT8+HHz9kxCCKSnp+PmzZsW9zRv3tzucbdu3Yq///3vqFatmtXrSnZNhoSEYO/evahduzZCQkIU6460xrS4vbjHSsZV0y+//IIlS5agSZMmmD59OubNm4fZs2fjxRdfVDTuJ598gldeeQVeXl4oX7485s2bh8TEREyYMEHRuO6KY3BW9O7dG/fu3cNnn31m9fqLL74IT09PbNq0SbE6rFixAuPHj0fHjh3x/vvvIzAwULFYJqGhoaX+8EiShDNnzigSX6fTydqySolk07x5c4wePbrYBfymhb9KJTrT2NumTZvQoEED9O/fH5MmTcLRo0fRuHFjRWIC97/zpk2bmv/xdPToUTRq1OihHT7s3VtQ2ixKo9GIr776Cl27drVr3OLi+/r6Ii0tzbyzilLUHud2N0xwVvz8889o1aoVunbtikmTJqFhw4YA7m96O3v2bGzbtg379u0rde/ERxUdHY0ff/wRCxYswGuvvaZIDGd0/vx5WfcV17Iui0GDBqFixYpYvHix1esnTpxA586dcfbsWbvHftDNmzexYcMGrFmzBgcOHECbNm3Qt29fdO/eXZF/5Kg16SE+Ph4TJ05ExYoVLZ7PyMjA6tWrsXbtWly9ehX37t2za1wTnU6H5ORk8wSuZ599Fh9//PFDS3Ds3Vvg4+ODtLQ0PP744wDubwnm7e2NS5cuaX4YQBUqjv85ta1bt4rAwECh0+nMRZIkERgYKD7//HNFY3fs2FFcvHhR0RjW7Nu3T2zdutXiuXXr1onQ0FARGBgoYmNjxd27dx1eL0e4e/euuHXrliqx4+PjrcY+fvy4GD9+vKhataooV66cCjVzjNu3b4t169aJ5557Tuh0OtGmTRuxdOlSi1187M00uUSSpIeK6XmdTqdI3KKTtpxpMpXWsAVXgjt37mD79u3mhdYNGzZEVFSUokflAEBMTIysiQarV6+2a9zo6Gi0a9cOkydPBnB/nOKpp55CTEwMGjdujDlz5uD111/HtGnT7Bq3KKPRaPXzG41GXLx4scSTFlxR0an6RRUUFOCLL74odSKMPaWkpODWrVto1aqV+WQFe0tNTcXKlSuRlJSEevXqoV+/fpg8eTKOHj2q6PFEgHq9BdaWR0yePBkTJ0502Di3O2GCs2L//v24fv26Rf//unXrMG3aNNy6dQvdu3fHe++9B71er0h8nU6HkJAQhIeHl7jxanFjhI+qRo0a2Lp1K1q0aAEAePvtt5GSkoK9e/cCADZt2oS4uDgcP37crnFNcnNzMXToUGzduhV+fn54/fXXERcXZ97d/8qVKwgKClJkHOxf//oXpkyZYu4y+/PPPxX7YS9KzV09EhMTcfPmTbzzzjsA7k/s6dSpE3bs2AEAqFq1Knbt2oUnnnjCrnGbN2+O3Nxc9O3bF/369TO/f/ny5RU/f09Nao9zux0VW49OKzo6WsyaNcv8+OjRo6J8+fJi6NCh4t133xXVq1cXcXFxisV/4403REBAgAgLCxMLFiwQ169fVyzWg/R6vbhw4YL5cevWrcWMGTPMj8+ePSt8fHwUiz9q1CjRoEEDsWnTJrFixQoREhIiunTpIgwGgxDi/mbTSq1FK7o3oq+vr8O6jSRJEr///rtDYhUVHh4ukpKSzI8//vhj4eXlJfbu3SuuX78uunTpInr16mX3uJ6enmLAgAFix44dwmg0mp93xNo/kwd3Ktq2bZv4/PPPzeXLL790SB1IWUxwVlSvXt1iI9a33npLtG7d2vz4448/Fo0bN1a0Dnfv3hXr168XHTt2FBUrVhS9evUS27dvt/gxsLfatWuLlJQUIcT9Rd5eXl7i22+/NV8/evSoCAgIUDT+d999Z3589epV8fTTT4uoqChx9+5dkZ2drci4iBDqLjKXJMm8oXZJRQmVKlUSx48fNz+OiYkRAwYMMD/ev3+/qFWrlt3jXrx4UcyYMUPUq1dPBAUFifHjx4vDhw+L8uXLOyTBbd26VYSFhZkf+/j4PDQOt2nTJrvHdedxbjVwHZwVf/75p8V6qJSUFHTq1Mn8uGXLloov9Nbr9ejTpw/69OmD8+fPY+3atXjjjTdQUFCAY8eOlbrF0aPo3LkzpkyZgsTERGzZsgUVK1bEc889Z75+9OhRRadRX7161WLMo0qVKvj222/xwgsvoHPnzli5cqVisdUWHx9vcaK1oxQUFFh0te/fvx9jxowxPw4KCrL7dlXA/RPU3377bbz99ttITk7G6tWr0bp1a/O6y6FDh6JBgwZ2j2uyfPlyvPnmmxbPZWRkmLeFmz17NlavXm33Rd/x8fFo166defjjl19+wZAhQyzGuYOCghQf53YbamdYZ6R2S6aoCxcuiPj4eFGnTh1Rs2ZNq+fU2cPVq1fFc889JyRJEr6+vmLz5s0W19u3by/eeustRWILIUTDhg3Ftm3bHno+Ly9PtGrVSjz55JOKteB0Op3IyMgQOTk54saNG8LX11ccOXJE5OTkWBQlqLnx8JNPPinWrFkjhBDi/PnzQpIkixbUDz/8IGrWrGn3uCkpKQ9t8nzjxg2xePFiERERISRJEs2aNbN7XJPQ0FCRnp5ufly0xX706FERGBho97jO0DvkTpjgrBg2bJho1aqV2L17txg3bpx47LHHzONAQgjx3//+V7Ro0ULROjzYRVmhQgXRs2dPsW3bNlFYWKhoXCHu/9BYO9zz+vXrFt+DvY0cOVL07NnT6rXc3FwRGRmpaBdl0SUh1h4rQc2z0ZYvXy68vb3F4MGDRZMmTUSrVq0srr/zzjuia9eudo9b2mf++eefxZtvvmn3uCZ6vV6cPXvW/Dg1NdXi5IozZ84IT09PReKqOc7tbthFacU777yDHj16oE2bNvDx8cG6dessdnZYvXo1oqKiFIv/xhtvICkpCcHBwRg8eDA2bNhgMYVYacV1lSl9qsH06dORlZVl9Zqvry927txp9x01TL777jtF3lcO8dcOLWqIjY2Fh4cHtm7diueff/6hBd1ZWVkYNGiQ3eOKUiZvh4WFYeHChXaPa1K5cmVkZGQgNDQUAMwzh01Onz6tyJ/3atWq4ezZswgODkZ+fj4OHz5ssdg+Ly8P5cuXt3tcd8VlAiXIycmBj4+PeZq6yR9//AEfH5+HtjOyF51Oh9q1ayM8PLzEH77NmzcrEl8tnTt3xoYNG8wJdtasWRg2bBgqVaoEALh+/Tqee+45xZYpqGXQoEGyEpy91z0C95dmyGHvvVd1Oh2uXLnikC3orHn11Vdx+/ZtfPHFF1avd+3aFd7e3ti4caNd4w4fPhxHjhwxj3OvW7cOWVlZ5t+Sjz76CPPnz0dqaqpd47orJjgnFBMTI+sHb82aNQ6ojeOUdh6ckuvg1PqhB9Rb92iKLefPmr2/c51Oh06dOpW6llSpf8SZtuPr1q0bJk2aZJ7QcvLkSSQmJiq2Hd+1a9fQo0cP7N2719w79NJLL5mvd+jQAc888wz+/e9/2zWuu2IXpRNau3at2lVQRdEfd0f+26tSpUol/tALBTd6Hj58ODZs2ICzZ89i0KBB6N+/v8MOuX2wa1YIYZ6tqvSBp8D9bmeldwUqTnh4ODZu3IihQ4c+lEQDAgKQlJSkyF6zVapUwe7du4vtHdq0aZMiM6TdFVtw5DSs7fB+5MgRh7Tgvv/+e1ktmTZt2tg9NgAYDAZs3rwZq1evxr59+9ClSxcMGTIEUVFRDh2fK/qdK0XN3VsedPv2bXzzzTc4ffo0AKB+/fqIioqCt7e3qvUi+2ALjpyGtbPIHPXjrtTJEHKpse5RTWqfB/fgeO9LL73kNuO97oYJjpyGEAIxMTHmcZm7d+9i2LBh5n9NGwwGxWKX1kVpouTBpyYPnovniHhqULvj6JtvvrH48zRz5kz07t3bnOAKCgpw8uRJlWpH9sIER05j4MCBFo/79+//0D1KnY+n5lgUYNlFuXfvXnTt2hWLFi1CdHS0rJMl7MkRrasZM2bg4MGDFhuaf/DBB4iLi3PIhuZqjveS4zDBkdNQc1Zo0bE1Dw8PPPPMM4qPRQHqrnssegRP0Vazib1nM+7evRseHh7csooUxQRHpLJly5ahdu3aqFu3LlJSUpCSkmL1PiWmzBdd1G+t1ayEI0eOYMaMGebHSUlJiIyMxIoVKwAAwcHBiIuLUyzBqTneS47DBEekstdee021H1e1Ws1qb2iu5ngvOQ4THFExHJV03HHdo9pbVqk53kuOwwRHBPXGotyV2kczaW0XILKOCY4I6o1FuSu1NzQn98CdTIhINWptaE7ugQmOiIg0ybErSImIiByECY6IiDSJCY6IiDSJCY6IiDSJCY6IiDSJCY6IiDSJCY6IiDSJCY6IiDTp/wDBl/fAaoPISgAAAABJRU5ErkJggg==", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "collectri = dc.get_collectri(organism=\"human\", split_complexes=False)\n", + "mat = stat_result.results_df[[\"stat\"]].T.rename(index={\"stat\": \"disease.vs.control\"})\n", + "tf_acts, tf_pvals = dc.run_ulm(mat=mat, net=collectri, verbose=True)\n", + "dc.plot_barplot(acts=tf_acts, contrast=\"disease.vs.control\", top=10, vertical=False, figsize=(5, 3))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can also evaluate known pathways." + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": {}, + "outputs": [], + "source": [ + "progeny = dc.get_progeny(top=500)\n", + "pathway_acts, pathway_pvals = dc.run_mlm(mat=mat, net=progeny, min_n=5)" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "dc.plot_barplot(\n", + " acts=pathway_acts,\n", + " contrast=\"disease.vs.control\",\n", + " top=40,\n", + " vertical=False,\n", + " figsize=(5, 3),\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Please refer to the `PyDESeq2` and the `decoupler` documentation for additional analyses." + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "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.9.16" + } + }, + "nbformat": 4, + "nbformat_minor": 2 } diff --git a/pytximport/__init__.py b/pytximport/__init__.py index 95e7703..fb81918 100755 --- a/pytximport/__init__.py +++ b/pytximport/__init__.py @@ -18,5 +18,8 @@ from ._version import __version__ from .core import tximport -# allow users to import the tximport function as pytximport as well +# Allow users to import the tximport function as pytximport as well pytximport = tximport + +create_transcript_gene_map = utils.create_transcript_gene_map +create_transcript_gene_map_from_annotation = utils.create_transcript_gene_map_from_annotation diff --git a/pytximport/_cli.py b/pytximport/_cli.py index 513c530..c7e4acc 100644 --- a/pytximport/_cli.py +++ b/pytximport/_cli.py @@ -3,6 +3,7 @@ from logging import basicConfig import click +import numpy as np from .core import tximport @@ -14,7 +15,7 @@ "--file-paths", type=click.Path(exists=False), multiple=True, - help="The paths to the quantification files.", + help="The path to an quantification file. To provide multiple input files, use `-i input1.sf -i input2.sf ...`.", required=True, ) @click.option( @@ -22,7 +23,7 @@ "--data_type", "--data-type", type=click.Choice(["kallisto", "salmon", "sailfish", "oarfish", "piscem", "stringtie", "rsem", "tsv"]), - help="The type of quantification file.", + help="The type of quantification files.", required=True, ) @click.option( @@ -30,29 +31,44 @@ "--transcript_gene_map", "--transcript-gene-map", type=click.Path(exists=True), - help="The path to the transcript to gene mapping file.", + help=( + "The path to the transcript to gene map. Either a tab-separated (.tsv) or comma-separated (.csv) file. " + "Expected column names are `transcript_id` and `gene_id`." + ), ) @click.option( "-c", "--counts_from_abundance", "--counts-from-abundance", type=click.Choice(["scaled_tpm", "length_scaled_tpm", "dtu_scaled_tpm"]), - help="The type of counts to convert to.", + help=( + "The method to calculate the counts from the abundance. Leave empty to use counts. " + "For differential gene expression analysis, we recommend using `length_scaled_tpm`. " + "For differential transcript expression analysis, we recommend using `scaled_tpm`. " + "For differential isoform usage analysis, we recommend using `dtu_scaled_tpm`." + ), ) @click.option( "-o", "--output_path", "--save-path", type=click.Path(), - help="The path to save the gene-level expression to.", + help="The output path to save the resulting counts to.", required=True, ) +@click.option( + "-of", + "--output_format", + "--output-format", + type=click.Choice(["csv", "h5ad"]), + help="The format of the output file.", +) @click.option( "-ow", "--output_path_overwrite", "--save-path-overwrite", is_flag=True, - help="Whether to overwrite the save path.", + help="Provide this flag to overwrite an existing file at the output path.", ) @click.option( "--ignore_after_bar", @@ -73,27 +89,23 @@ "--gene_level", "--gene-level", is_flag=True, - help="Whether the input data are gene-level counts. Provide this flag when importing gene counts from RSEM files.", + help="Provide this flag when importing gene-level counts from RSEM files.", ) @click.option( "-tx", "--return_transcript_data", "--return-transcript-data", is_flag=True, - help="Whether to return transcript-level instead of gene-summarized data.", + help=( + "Provide this flag to return transcript-level instead of gene-summarized data. " + "Incompatible with gene-level input and `counts_from_abundance=length_scaled_tpm`." + ), ) @click.option( "-ir" "--inferential_replicates", "--inferential-replicates", is_flag=True, - help="Whether to make use of inferential replicates.", -) -@click.option( - "-irv", - "-inferential_replicate_variance", - "--inferential-replicate-variance", - is_flag=True, - help="Whether to calculate the variance from the inferential replicates.", + help="Provide this flag to make use of inferential replicates. Will use the median of the inferential replicates.", ) @click.option( "-id", @@ -129,26 +141,16 @@ is_flag=True, help="Whether the existence of the files is optional.", ) -@click.option( - "--output_type", - "--output-type", - type=click.Choice(["xarray", "anndata"]), - help="The type of output to return.", -) -@click.option( - "--output_format", - "--output-format", - type=click.Choice(["csv", "h5ad"]), - help="The format of the output file.", -) def cli( # type: ignore **kwargs, ) -> None: """Convert transcript-level expression to gene-level expression.""" - # add return_data to the kwargs with a default value of False + # Add return_data to the kwargs with a default value of False kwargs["return_data"] = False + kwargs["output_type"] = "anndata" + kwargs["inferential_replicate_transformer"] = lambda x: np.median(x, axis=1) - # set the logging level + # Set the logging level basicConfig(level=25, format="%(asctime)s: %(message)s") tximport(**kwargs) # type: ignore diff --git a/pytximport/core/__init__.py b/pytximport/core/__init__.py index fb73d78..1dee54c 100644 --- a/pytximport/core/__init__.py +++ b/pytximport/core/__init__.py @@ -1,3 +1,5 @@ """Expose the functions in the core module.""" from ._tximport import tximport + +pytximport = tximport diff --git a/pytximport/core/_tximport.py b/pytximport/core/_tximport.py index 30e6b8a..9c99a8a 100644 --- a/pytximport/core/_tximport.py +++ b/pytximport/core/_tximport.py @@ -40,7 +40,7 @@ def tximport( custom_importer: Optional[Callable] = None, existence_optional: bool = False, read_length: Optional[int] = None, - # arguments exclusive to the pytximport implementation + # Arguments exclusive to the pytximport implementation output_type: Literal["xarray", "anndata"] = "anndata", output_format: Literal["csv", "h5ad"] = "csv", output_path: Optional[Union[str, Path]] = None, @@ -50,6 +50,19 @@ def tximport( ) -> Union[xr.Dataset, ad.AnnData, None]: """Import transcript-level quantification files and convert them to gene-level expression estimates. + Basic usage: + + .. code-block:: python + + from pytximport import tximport + + txi = tximport( + ["quant_1.sf", "quant_2.sf"], + data_type="salmon", + transcript_gene_map="transcript_to_gene_map.tsv", + counts_from_abundance="length_scaled_tpm", + ) + Args: file_paths (List[Union[str, Path]]): The paths to the quantification files. data_type (Literal["kallisto", "salmon", "sailfish", "oarfish", "piscem", "stringtie", "rsem", "tsv"]): The type @@ -73,8 +86,7 @@ def tximport( return_transcript_data (bool, optional): Whether to return the transcript-level expression. Defaults to False. inferential_replicates (bool, optional): Whether to parse and include inferential replicates in the output. If you want to recalculate the counts from inferential replicates, please set this option to True and - provide a `inferential_replicate_transformer`. - Defaults to False. + provide a `inferential_replicate_transformer`. Defaults to False. inferential_replicate_transformer (Optional[Callable], optional): A custom function to transform the inferential replicates. Defaults to None. inferential_replicate_variance (bool, optional): Whether to return the variance of the inferential replicates. @@ -96,18 +108,19 @@ def tximport( output_path_overwrite (bool, optional): Whether to overwrite the save path if it already exists. Defaults to False. return_data (bool, optional): Whether to return the gene-level expression. Defaults to True. - biotype_filter (List[str], optional): Filter the transcripts by biotype, including only those provided. - Defaults to None. + biotype_filter (List[str], optional): Filter the transcripts by biotype, including only those provided. Enables + post-hoc filtering of the data based on the biotype of the transcripts. Assumes that the biotype is present + in the transcript_id of the data, bar-separated. Defaults to None. Returns: Union[xr.Dataset, ad.AnnData, None]: The estimated gene-level or transcript-level expression data if `return_data` is True, else None. """ - # start a timer + # Start a timer log(25, "Starting the import.") start_time = time() - # needed for faster groupby operations + # Needed for faster groupby operations xr.set_options(use_flox=True) assert data_type in [ @@ -121,7 +134,7 @@ def tximport( "tsv", ], "Only kallisto, salmon/sailfish, oarfish, piscem, stringtie, RSEM and tsv quantification files are supported." - # read the transcript to gene mapping + # Read the transcript to gene mapping if isinstance(transcript_gene_map, str) or isinstance(transcript_gene_map, Path): transcript_gene_map = Path(transcript_gene_map) if not transcript_gene_map.exists(): @@ -136,12 +149,12 @@ def tximport( raise ValueError(f"Could not read the transcript to gene mapping: {exception}") if transcript_gene_map is not None: - # assert that transcript_id and gene_id are present in the mapping + # Assert that transcript_id and gene_id are present in the mapping assert isinstance(transcript_gene_map, pd.DataFrame), "The mapping must be a DataFrame." assert "transcript_id" in transcript_gene_map.columns, "The mapping does not contain a `transcript_id` column." assert "gene_id" in transcript_gene_map.columns, "The mapping does not contain a `gene_id` column." - # check whether the mapping contains duplicates + # Check whether the mapping contains duplicates if transcript_gene_map.duplicated(subset=["transcript_id", "gene_id"]).any(): warning("The transcript to gene mapping contains duplicates. Removing duplicates.") transcript_gene_map = transcript_gene_map.drop_duplicates( @@ -149,16 +162,16 @@ def tximport( keep="first", ) - # assert that return_transcript_data is True if transcript_gene_map is None + # Assert that return_transcript_data is True if transcript_gene_map is None if transcript_gene_map is None: assert ( - return_transcript_data and not gene_level - ), "A transcript to gene mapping must be provided when summarizing to genes." + return_transcript_data or gene_level + ), "A transcript to gene mapping must be provided when summarizing transcripts to genes." if gene_level and data_type != "rsem": raise ValueError("Gene-level imports are only available for RSEM quantification files.") - # match the data type with the required importer + # Match the data type with the required importer importer: Callable importer_kwargs: Dict[str, Any] = {} @@ -178,7 +191,7 @@ def tximport( importer_kwargs["gene_level"] = gene_level importer = read_rsem elif data_type == "oarfish": - # use the default column names if not provided + # Use the default column names if not provided id_column = "tname" if id_column is None else id_column counts_column = "num_reads" if counts_column is None else counts_column length_column = "len" if length_column is None else length_column @@ -205,7 +218,7 @@ def tximport( importer = read_tsv elif data_type == "tsv": - # check that all of id_column counts_column length_column abundance_column are provided + # Check that all of id_column counts_column length_column abundance_column are provided if any( [ id_column is None, @@ -222,11 +235,11 @@ def tximport( else: raise ValueError("The input file type is not supported.") - # overwrite the importer if a custom importer is provided + # Overwrite the importer if a custom importer is provided if custom_importer is not None: importer = custom_importer - # create the importer kwargs based on the provided column names + # Create the importer kwargs based on the provided column names importer_kwargs.update( { "id_column": id_column, @@ -236,13 +249,13 @@ def tximport( } ) - # list is required to create a copy so that the original dictionary can be changed + # List is required to create a copy so that the original dictionary can be changed for key, value in list(importer_kwargs.items()): if value is None: del importer_kwargs[key] if data_type in ["salmon", "sailfish", "kallisto"] and inferential_replicates: - # add information about the inferential replicates to the importer kwargs + # Add information about the inferential replicates to the importer kwargs if data_type == "salmon": importer_kwargs["aux_dir_name"] = "aux_info" elif data_type == "sailfish": @@ -256,7 +269,7 @@ def tximport( transcript_data: Optional[xr.Dataset] = None file_paths_missing_idx: List[int] = [] - # iterate through the files, unless they are RSEM gene level counts + # Iterate through the files, unless they are RSEM gene level counts if not (gene_level and data_type == "rsem"): for file_idx, file_path in tqdm(enumerate(file_paths), desc="Reading quantification files"): try: @@ -269,7 +282,7 @@ def tximport( else: raise exception - # the check for transcript_data is needed in case the import of the first file fails + # The check for transcript_data is needed in case the import of the first file fails if file_idx == 0 or transcript_data is None: empty_array = np.zeros((len(transcript_data_sample["transcript_id"]), len(file_paths))) @@ -301,7 +314,7 @@ def tximport( }, ) - # add the transcript-level expression to the array + # Add the transcript-level expression to the array transcript_data["abundance"].loc[{"file": file_idx}] = transcript_data_sample["abundance"] transcript_data["counts"].loc[{"file": file_idx}] = transcript_data_sample["counts"] transcript_data["length"].loc[{"file": file_idx}] = transcript_data_sample["length"] @@ -320,11 +333,11 @@ def tximport( ]["variance"] if inferential_replicate_transformer is not None: - # use the provided function to recompute the counts based on the inferential replicates + # Use the provided function to recompute the counts based on the inferential replicates transcript_data["counts"].loc[{"file": file_idx}] = inferential_replicate_transformer( transcript_data_sample["inferential_replicates"]["replicates"], ) - # recompute the abundance + # Recompute the abundance transcript_data["abundance"].loc[{"file": file_idx}] = convert_counts_to_tpm( transcript_data["counts"].loc[{"file": file_idx}].data, transcript_data["length"].loc[{"file": file_idx}].data, @@ -355,7 +368,7 @@ def tximport( ) if data_type == "stringtie" and read_length is not None: - # we need to convert the coverage to counts + # We need to convert the coverage to counts # TODO: add a unit test that checks for agreement with tximport transcript_data["counts"] = transcript_data["counts"] * transcript_data["length"] / read_length @@ -366,15 +379,15 @@ def tximport( result: Union[xr.Dataset, ad.AnnData] if return_transcript_data: - # return the transcript-level expression if requested + # Return the transcript-level expression if requested if ignore_after_bar: - # change the transcript_id to only include the part before the bar for the coords + # Change the transcript_id to only include the part before the bar for the coords transcript_data.coords["transcript_id"] = [ transcript_id.split("|")[0] for transcript_id in transcript_data.coords["transcript_id"].values ] if ignore_transcript_version: - # remove the transcript version + # Remove the transcript version transcript_data, transcript_gene_map, _ = remove_transcript_version( transcript_data, transcript_gene_map, @@ -397,7 +410,7 @@ def tximport( counts_from_abundance = "length_scaled_tpm" length_key = "median_isoform_length" - # convert the transcript counts to the desired count type + # Convert the transcript counts to the desired count type log(25, "Recreating transcript counts from abundances.") transcript_data["counts"] = convert_abundance_to_counts( transcript_data["counts"], @@ -412,13 +425,13 @@ def tximport( result = transcript_data if ignore_after_bar: - # change the transcript_id to only include the part before the bar for the coords + # Change the transcript_id to only include the part before the bar for the coords transcript_data.coords["gene_id"] = [ gene_id.split("|")[0] for gene_id in transcript_data.coords["gene_id"].values ] if ignore_transcript_version: - # remove the transcript version + # Remove the transcript version transcript_data, _, _ = remove_transcript_version( transcript_data, id_column="gene_id", @@ -426,7 +439,7 @@ def tximport( result_index = "gene_id" else: - # convert to gene-level expression + # Convert to gene-level expression log(25, "Converting transcript-level expression to gene-level expression.") if counts_from_abundance == "dtu_scaled_tpm": raise ValueError("The `dtu_scaled_tpm` option is not supported for gene-level expression.") @@ -519,7 +532,7 @@ def tximport( df_gene_data.sort_index(inplace=True) df_gene_data.to_csv(output_path, index=True, header=True, quoting=2) - # end the timer + # End the timer end_time = time() log(25, f"Finished the import in {end_time - start_time:.2f} seconds.") diff --git a/pytximport/definitions/__init__.py b/pytximport/definitions/__init__.py index 435253c..080b054 100644 --- a/pytximport/definitions/__init__.py +++ b/pytximport/definitions/__init__.py @@ -1,4 +1,4 @@ -"""Type definitions for the tximport package.""" +"""Type definitions for internal use in `pytximport`.""" from typing import Any, List, Optional, TypedDict diff --git a/pytximport/importers/__init__.py b/pytximport/importers/__init__.py index b6757c2..ebdbb2e 100644 --- a/pytximport/importers/__init__.py +++ b/pytximport/importers/__init__.py @@ -1,4 +1,8 @@ -"""Expose the functions in the utils module.""" +"""Importing functions for different transcript quantification tools. + +Functions contained within this module are primarily destined for internal use but are exposed for advanced users who +may want to use them directly. +""" from ._read_kallisto import read_inferential_replicates_kallisto, read_kallisto from ._read_rsem import read_rsem diff --git a/pytximport/importers/_read_kallisto.py b/pytximport/importers/_read_kallisto.py index 2930f74..a22b1be 100644 --- a/pytximport/importers/_read_kallisto.py +++ b/pytximport/importers/_read_kallisto.py @@ -78,23 +78,23 @@ def read_kallisto( if not file_path.exists(): raise ImportError(f"The file does not exist: {file_path}") - # read the quantification file + # Read the quantification file if file_path.suffix == ".h5": with File(file_path, "r") as f: - # get the transcript-level expression + # Get the transcript-level expression transcript_ids = f.file[id_column][:].astype(str) counts = f.file[counts_column][:] length = f.file[length_column][:] - # get the abundance if it was specified, else it will be calculated + # Get the abundance if it was specified, else it will be calculated if abundance_column is not None: abundance = f.file[abundance_column][:] elif file_path.suffix == ".tsv": - # read the quantification file as a tsv, tab separated and the first line is the column names + # Read the quantification file as a tsv, tab separated and the first line is the column names transcript_data = pd.read_table(file_path, header=0) - # check that the columns are in the table + # Check that the columns are in the table assert id_column in transcript_data.columns, f"Could not find the transcript id column `{id_column}`." assert counts_column in transcript_data.columns, f"Could not find the counts column `{counts_column}`." assert length_column in transcript_data.columns, f"Could not find the length column `{length_column}`." @@ -109,19 +109,19 @@ def read_kallisto( ), f"Could not find the abundance column `{abundance_column}`." abundance = transcript_data[abundance_column].astype("float64").values - # check that the length of the counts, length, and abundances are the same + # Check that the length of the counts, length, and abundances are the same assert ( len(transcript_ids) == len(counts) == len(length) ), "The transcript ids, counts and length have different length." - # calculate the transcript-level TPM if the abundance was not included + # Calculate the transcript-level TPM if the abundance was not included if abundance_column is None: warning("Abundance column not provided, calculating TPM.") abundance = convert_counts_to_tpm(counts, length) else: assert len(transcript_ids) == len(abundance), "The transcript ids and abundance have different length." - # create a DataFrame with the transcript-level expression + # Create a DataFrame with the transcript-level expression transcripts = TranscriptData( transcript_id=transcript_ids, counts=counts, @@ -134,5 +134,5 @@ def read_kallisto( file_path, ) - # return the transcript-level expression + # Return the transcript-level expression return transcripts diff --git a/pytximport/importers/_read_rsem.py b/pytximport/importers/_read_rsem.py index b2c2164..ce00324 100644 --- a/pytximport/importers/_read_rsem.py +++ b/pytximport/importers/_read_rsem.py @@ -8,7 +8,7 @@ def read_rsem( file_path: Union[str, Path], - id_column: str = "transcript_id", # or "gene_id" for gene-level quantification + id_column: str = "transcript_id", # Or "gene_id" for gene-level quantification counts_column: str = "expected_count", length_column: str = "effective_length", abundance_column: str = "TPM", @@ -31,7 +31,7 @@ def read_rsem( file_path = Path(file_path) if file_path.is_dir(): - # add quant.sf to the file path + # Add quant.sf to the file path if gene_level: file_paths = list(file_path.glob("*.genes.results.gz")) file_identifier = "genes.results.gz" @@ -47,7 +47,7 @@ def read_rsem( file_path = file_paths[0] - # check that we are importing a .sf file + # Check that we are importing a .sf file if not file_path.suffix == ".gz": raise ImportError("Only .gz files are supported.") diff --git a/pytximport/importers/_read_salmon.py b/pytximport/importers/_read_salmon.py index 799287f..02b2b2c 100644 --- a/pytximport/importers/_read_salmon.py +++ b/pytximport/importers/_read_salmon.py @@ -76,12 +76,12 @@ def read_inferential_replicates_salmon( expected_n = target_count * bootstrap_count try: - # try to read as floats + # Try to read as floats with gzip.open(bootstrap_path, "rb") as f: bootstrap_data = np.frombuffer(f.read(), dtype=np.float64, count=expected_n) assert len(bootstrap_data) == expected_n except (AssertionError, ValueError): - # try to read as integers + # Try to read as integers with gzip.open(bootstrap_path, "rb") as f: bootstrap_data = np.frombuffer(f.read(), dtype=np.int32, count=expected_n) @@ -114,14 +114,14 @@ def read_salmon( file_path = Path(file_path) if file_path.is_dir(): - # add quant.sf to the file path + # Add quant.sf to the file path file_path = file_path / "quant.sf" - # check that we are importing a .sf file + # Check that we are importing a .sf file if not file_path.suffix == ".sf" and not file_path.suffix == ".gz": raise ImportError("Only .sf and .gz files are supported.") - # unzip the file if it is compressed + # Unzip the file if it is compressed if file_path.suffix == ".gz": try: with gzip.open(file_path, "rt") as f: diff --git a/pytximport/importers/_read_tsv.py b/pytximport/importers/_read_tsv.py index abba597..0054b5c 100644 --- a/pytximport/importers/_read_tsv.py +++ b/pytximport/importers/_read_tsv.py @@ -27,12 +27,12 @@ def parse_dataframe( Returns: TranscriptData: The transcript-level expression. """ - # check that the columns are in the table + # Check that the columns are in the table assert id_column in transcript_dataframe.columns, f"Could not find the transcript id column `{id_column}`." assert counts_column in transcript_dataframe.columns, f"Could not find the counts column `{counts_column}`." assert length_column in transcript_dataframe.columns, f"Could not find the length column `{length_column}`." - # calculate the transcript-level TPM if the abundance was not included + # Calculate the transcript-level TPM if the abundance was not included if abundance_column is None: warning("Abundance column not provided, calculating TPM.", UserWarning) abundance = convert_counts_to_tpm( @@ -45,7 +45,7 @@ def parse_dataframe( ), f"Could not find the abundance column `{abundance_column}`." abundance = transcript_dataframe[abundance_column].astype("float64").values - # create a DataFrame with the transcript-level expression + # Create a DataFrame with the transcript-level expression transcripts = TranscriptData( transcript_id=transcript_dataframe[id_column].values, counts=transcript_dataframe[counts_column].astype("float64").values, @@ -54,7 +54,7 @@ def parse_dataframe( inferential_replicates=None, ) - # return the transcript-level expression + # Return the transcript-level expression return transcripts @@ -83,7 +83,7 @@ def read_tsv( if not file_path.exists(): raise ImportError(f"The file does not exist: {file_path}") - # read the quantification file as a tsv, tab separated and the first line is the column names + # Read the quantification file as a tsv, tab separated and the first line is the column names if file_path.suffix == ".gz": transcript_dataframe = pd.read_table(file_path, header=0, compression="gzip", sep="\t") else: diff --git a/pytximport/utils/__init__.py b/pytximport/utils/__init__.py index 147a2fb..5a1dac1 100644 --- a/pytximport/utils/__init__.py +++ b/pytximport/utils/__init__.py @@ -1,4 +1,8 @@ -"""Expose the functions in the utils module.""" +"""Utility functions for converting data, creating maps and filtering data. + +Most functions contained within this module are primarily destined for internal use but are exposed for advanced users +who may want to use them directly. +""" from . import _biotype_filters as biotype_filters from ._convert_abundance_to_counts import convert_abundance_to_counts diff --git a/pytximport/utils/_biotype_filters.py b/pytximport/utils/_biotype_filters.py index 0e43672..1313c3a 100644 --- a/pytximport/utils/_biotype_filters.py +++ b/pytximport/utils/_biotype_filters.py @@ -1,3 +1,23 @@ +"""Collections of biotype filters for use with the `biotype_filter` option of `pytximport`. + +You can also pass your own list of biotypes to filter by. For example: + +.. code-block:: python + + from pytximport import tximport + + txi = tximport( + file_paths, + data_type, + transcript_gene_map, + counts_from_abundance, + biotype_filter=["protein_coding", "nonsense_mediated_decay"], + ) + +For a list of all biotypes, refer to GENCODE's biotype documentation: https://www.gencodegenes.org/pages/biotypes.html +If you use a different reference/annotation, available biotypes may differ. +""" + from typing import List GENCODE_PROTEIN_CODING: List[str] = [ diff --git a/pytximport/utils/_convert_abundance_to_counts.py b/pytximport/utils/_convert_abundance_to_counts.py index bcdf776..5339a89 100644 --- a/pytximport/utils/_convert_abundance_to_counts.py +++ b/pytximport/utils/_convert_abundance_to_counts.py @@ -22,17 +22,17 @@ def convert_abundance_to_counts( DataArray: The transcript-level expression data with the counts. """ if counts_from_abundance == "scaled_tpm": - # set the counts to the TPM + # Set the counts to the TPM log(25, "Setting the counts to scaled TPM.") counts_transformed = abundance elif counts_from_abundance == "length_scaled_tpm": - # convert the TPM to counts and scale by the gene length across samples + # Convert the TPM to counts and scale by the gene length across samples log(25, "Setting counts to length scaled TPM.") counts_transformed = abundance * length.mean(axis=1) else: raise ValueError("The count transform must be 'scaled_tpm' or 'length_scaled_tpm'.") - # scale the counts from abundance to the original sequencing depth of each sample + # Scale the counts from abundance to the original sequencing depth of each sample column_counts = counts.sum(axis=0) new_counts = counts_transformed.sum(axis=0) ratio = column_counts / new_counts diff --git a/pytximport/utils/_convert_transcripts_to_genes.py b/pytximport/utils/_convert_transcripts_to_genes.py index b860695..02b891f 100644 --- a/pytximport/utils/_convert_transcripts_to_genes.py +++ b/pytximport/utils/_convert_transcripts_to_genes.py @@ -38,12 +38,12 @@ def convert_transcripts_to_genes( transcript_ids = transcript_data.coords["transcript_id"].values if ignore_after_bar: - # ignore the part of the transcript ID after the bar + # Ignore the part of the transcript ID after the bar transcript_ids = [transcript_id.split("|")[0] for transcript_id in transcript_ids] transcript_data.coords["transcript_id"] = transcript_ids if ignore_transcript_version: - # ignore the transcript version in both the data and the transcript gene map + # Ignore the transcript version in both the data and the transcript gene map transcript_data, transcript_gene_map, transcript_ids = remove_transcript_version( transcript_data, transcript_gene_map, @@ -52,25 +52,25 @@ def convert_transcripts_to_genes( unique_transcripts = list(set(transcript_ids)) - # avoid duplicates in the mapping + # Avoid duplicates in the mapping transcripts_duplicated = transcript_gene_map["transcript_id"].duplicated() assert not any(transcripts_duplicated), "The mapping contains duplicates." - # check that at least one transcript is present in the mapping + # Check that at least one transcript is present in the mapping assert any(transcript_gene_map["transcript_id"].isin(unique_transcripts)), ( "No transcripts are present in the mapping. " "Please make sure you are using the correct mapping and that the transcript IDs match the mapping. " "Adjust the `ignore_after_bar` and `ignore_transcript_version` parameters if necessary." ) - # check whether there are any missing transcripts, and if so, warn the user and remove them + # Check whether there are any missing transcripts, and if so, warn the user and remove them if not set(unique_transcripts).issubset(set(transcript_gene_map["transcript_id"])): warning( "Not all transcripts are present in the mapping." + f" {len(set(unique_transcripts) - set(transcript_gene_map['transcript_id']))}" + f" out of {len(unique_transcripts)} missing. Removing the missing transcripts." ) - # remove the missing transcripts by only keeping the data for the transcripts present in the mapping + # Remove the missing transcripts by only keeping the data for the transcripts present in the mapping transcript_ids_intersect = list(set(unique_transcripts).intersection(set(transcript_gene_map["transcript_id"]))) transcript_ids_intersect_boolean = np.isin(transcript_ids, transcript_ids_intersect) transcript_data = transcript_data.isel( @@ -80,20 +80,20 @@ def convert_transcripts_to_genes( transcript_ids = transcript_data.coords["transcript_id"].values transcript_gene_map = transcript_gene_map[transcript_gene_map["transcript_id"].isin(transcript_ids_intersect)] - # add the corresponding gene to the transcript-level expression + # Add the corresponding gene to the transcript-level expression log(25, "Matching gene_ids.") transcript_gene_dict = transcript_gene_map.set_index("transcript_id")["gene_id"].to_dict() gene_ids_raw = transcript_data["transcript_id"].to_series().map(transcript_gene_dict).values gene_ids = np.repeat(gene_ids_raw, transcript_data["abundance"].shape[1]) - # remove the transcript_id coordinate + # Remove the transcript_id coordinate transcript_data = transcript_data.drop_vars("transcript_id") transcript_data = transcript_data.assign_coords(gene_id=gene_ids_raw) - # rename the first dimension to gene + # Rename the first dimension to gene transcript_data = transcript_data.rename({"transcript_id": "gene_id"}) - # get the unique genes but keep the order + # Get the unique genes but keep the order unique_genes = list(pd.Series(gene_ids).unique()) log(25, "Creating gene abundance.") @@ -132,7 +132,7 @@ def convert_transcripts_to_genes( average_gene_length = average_transcript_length_across_samples.groupby("gene_id").mean() length = replace_missing_average_transcript_length(length, average_gene_length) - # convert the counts to the desired count type + # Convert the counts to the desired count type if counts_from_abundance is not None: log(25, "Recreating gene counts from abundances.") counts_gene = convert_abundance_to_counts( @@ -142,7 +142,7 @@ def convert_transcripts_to_genes( counts_from_abundance, ) - # convert to gene-level expression + # Convert to gene-level expression log(25, "Creating gene expression dataset.") data_vars = { "abundance": abundance_gene, diff --git a/pytximport/utils/_create_transcript_gene_map.py b/pytximport/utils/_create_transcript_gene_map.py index ebc54af..30bed42 100644 --- a/pytximport/utils/_create_transcript_gene_map.py +++ b/pytximport/utils/_create_transcript_gene_map.py @@ -21,6 +21,18 @@ def create_transcript_gene_map( since not all transcripts may have the respective variable. While this does not typically affect well defined transcripts, be aware of this possible source of bias. + Basic example: + + .. code-block:: python + + from pytximport.utils import create_transcript_gene_map + + transcript_gene_map = create_transcript_gene_map( + species="human", + host="https://may2024.archive.ensembl.org/", # Use a specific Ensembl release + target_field="external_gene_name", + ) + Args: species (Literal["human", "mouse"], optional): The species to use. Defaults to "human". host (str, optional): The host to use. Defaults to "http://www.ensembl.org". @@ -81,13 +93,13 @@ def create_transcript_gene_map_from_annotation( warning("The field argument is deprecated. Please use the source_field and target_field arguments instead.") for chunk in pd.read_csv(file_path, sep="\t", chunksize=chunk_size, header=None, comment="#"): - # see: https://www.ensembl.org/info/website/upload/gff.html + # See: https://www.ensembl.org/info/website/upload/gff.html chunk.columns = ["seqname", "source", "feature", "start", "end", "score", "strand", "frame", "attribute"] - # each attribute line looks like this: + # Each attribute line looks like this: # gene_id ""; transcript_id ""; gene_name ""; gene_source ""; gene_biotype ""; # transcript_name ""; transcript_source ""; - # however, we are only interested in the gene_id, gene_name, and transcript_id + # We are only interested in the gene_id, gene_name, and transcript_id attribute_columns = [ "transcript_id", "transcript_name", @@ -97,7 +109,7 @@ def create_transcript_gene_map_from_annotation( ] for column in attribute_columns: chunk[column] = chunk["attribute"].apply( - # adopted from https://gist.github.com/rf-santos/22f521c62ca2f85ac9582bf0d91e4054 + # Adopted from https://gist.github.com/rf-santos/22f521c62ca2f85ac9582bf0d91e4054 lambda x: (re.findall(rf'{column} "([^"]*)"', x)[0] if rf'{column} "' in x else "") ) @@ -110,7 +122,7 @@ def create_transcript_gene_map_from_annotation( ] ) - # replace the gene_name with the gene_id where the gene_name is "" + # Replace the gene_name with the gene_id where the gene_name is "" transcript_gene_map["gene_name"] = np.where( transcript_gene_map["gene_name"] == "", transcript_gene_map["gene_id"], diff --git a/pytximport/utils/_filter_by_biotype.py b/pytximport/utils/_filter_by_biotype.py index 6fe182d..598f535 100644 --- a/pytximport/utils/_filter_by_biotype.py +++ b/pytximport/utils/_filter_by_biotype.py @@ -12,6 +12,10 @@ def filter_by_biotype( ) -> xr.Dataset: """Filter the transcripts by biotype. + This function filters the transcripts by biotype. The biotype is assumed to be present in the transcript_id + separated by a bar. The biotype is checked against the biotype_filter and the transcripts that match the biotype + are kept. This function is provided mainly for internal use if `biotype_filter` is provided to the main function. + Args: transcript_data (xr.Dataset): The transcript-level expression data from multiple samples. biotype_filter (List[str]): The biotypes to filter the transcripts by. @@ -22,14 +26,14 @@ def filter_by_biotype( """ transcript_ids = transcript_data.coords[id_column].values - # this only works if the transcript_id contains the biotype as one of the bar-separated fields + # This only works if the transcript_id contains the biotype as one of the bar-separated fields assert any( "|" in transcript_id for transcript_id in transcript_ids ), "The transcript_id does not contain the biotype." transcript_id_fields = [transcript_id.split("|") for transcript_id in transcript_ids] - # iterate through the biotypes and mark a transcript to be kept if a biotype is a match + # Iterate through the biotypes and mark a transcript to be kept if a biotype is a match transcript_keep_boolean = np.zeros(len(transcript_id_fields)) for biotype in biotype_filter: @@ -38,10 +42,10 @@ def filter_by_biotype( [(biotype in transcript_id_field) for transcript_id_field in transcript_id_fields], ) - # check that at least one transcript is protein-coding + # Check that at least one transcript is protein-coding assert any(transcript_keep_boolean), "No transcripts with the desired biotype are present in the data." - # calculate the total abundance before filtering + # Calculate the total abundance before filtering total_abundance = transcript_data["abundance"].sum(axis=0) transcript_data = transcript_data.isel( @@ -54,7 +58,7 @@ def filter_by_biotype( ) transcript_ids = transcript_data.coords[id_column].values - # recalculate the abundance for each sample + # Recalculate the abundance for each sample log(25, "Recalculating the abundance after filtering by biotype.") new_abundance = transcript_data["abundance"].sum(axis=0) ratio = total_abundance / new_abundance diff --git a/pytximport/utils/_get_median_length_over_isoform.py b/pytximport/utils/_get_median_length_over_isoform.py index e3774b8..12f725a 100644 --- a/pytximport/utils/_get_median_length_over_isoform.py +++ b/pytximport/utils/_get_median_length_over_isoform.py @@ -21,18 +21,18 @@ def get_median_length_over_isoform( """ assert "length" in transcript_data.data_vars, "The transcript data does not contain a `length` variable." - # get the gene ids for each transcript + # Get the gene ids for each transcript transcript_gene_dict = transcript_gene_map.set_index("transcript_id")["gene_id"].to_dict() gene_ids = transcript_data["transcript_id"].to_series().map(transcript_gene_dict).values - # check that no gene ids is nan + # Check that no gene ids is nan assert not any(pd.isna(gene_ids)), "Not all transcript ids could be mapped to gene ids. Please check the mapping." transcript_data_copy = transcript_data.drop_vars("transcript_id") transcript_data_copy = transcript_data_copy.assign_coords(gene_id=gene_ids) transcript_data_copy = transcript_data_copy.rename({"transcript_id": "gene_id"}) - # get the row mean across samples for each transcript + # Get the row mean across samples for each transcript average_transcript_length_across_samples = transcript_data_copy["length"].mean(axis=1) median_gene_length = average_transcript_length_across_samples.groupby("gene_id").median().to_dataframe() diff --git a/pytximport/utils/_remove_transcript_version.py b/pytximport/utils/_remove_transcript_version.py index ad07b05..165b824 100644 --- a/pytximport/utils/_remove_transcript_version.py +++ b/pytximport/utils/_remove_transcript_version.py @@ -22,7 +22,7 @@ def remove_transcript_version( Tuple[xr.Dataset, pd.DataFrame, List[str]]: The transcript data, the transcript target map, and the transcript ids. """ - # ignore the transcript version in both the data and the transcript gene map + # Ignore the transcript version in both the data and the transcript gene map if transcript_ids is None: transcript_ids = transcript_data.coords[id_column].values # type: ignore diff --git a/pytximport/utils/_replace_transcript_ids_with_names.py b/pytximport/utils/_replace_transcript_ids_with_names.py index ed3377e..bd2974d 100644 --- a/pytximport/utils/_replace_transcript_ids_with_names.py +++ b/pytximport/utils/_replace_transcript_ids_with_names.py @@ -22,19 +22,19 @@ def replace_transcript_ids_with_names( Returns: Union[ad.AnnData, xr.Dataset]: The transcript-level expression data with the transcript names. """ - # read the transcript to gene mapping + # Read the transcript to gene mapping if isinstance(transcript_name_map, str) or isinstance(transcript_name_map, Path): transcript_name_map = pd.read_table(transcript_name_map, header=0) transcript_name_map = transcript_name_map.drop_duplicates() - # assert that transcript_id and transcript_name are present in the mapping + # Assert that transcript_id and transcript_name are present in the mapping if transcript_name_map is not None: assert "transcript_id" in transcript_name_map.columns, "The mapping does not contain a `transcript_id` column." assert ( "transcript_name" in transcript_name_map.columns ), "The mapping does not contain a `transcript_name` column." - # check whether the transcript_data is an AnnData object and convert it to a DataFrame + # Check whether the transcript_data is an AnnData object and convert it to a DataFrame return_as_anndata = False if isinstance(transcript_data, ad.AnnData): return_as_anndata = True @@ -50,13 +50,13 @@ def replace_transcript_ids_with_names( }, ) - # remove the transcript version + # Remove the transcript version transcript_data, transcript_name_map, _ = remove_transcript_version(transcript_data, transcript_name_map) transcript_name_dict = transcript_name_map.set_index("transcript_id")["transcript_name"].to_dict() transcript_names = transcript_data["transcript_id"].to_series().map(transcript_name_dict).values - # replace the transcript_id with the transcript_name + # Replace the transcript_id with the transcript_name transcript_data.coords["transcript_id"] = transcript_names if return_as_anndata: diff --git a/pytximport/utils/_summarize_rsem_gene_data.py b/pytximport/utils/_summarize_rsem_gene_data.py index 26983c5..b3cedde 100644 --- a/pytximport/utils/_summarize_rsem_gene_data.py +++ b/pytximport/utils/_summarize_rsem_gene_data.py @@ -39,7 +39,7 @@ def summarize_rsem_gene_data( raise exception if file_idx == 0 or transcript_data is None: - # since the files are parsed with the generic importer, the gene id column is called "transcript_id" + # Since the files are parsed with the generic importer, the gene id column is called "transcript_id" empty_array = np.zeros((len(transcript_data_sample["transcript_id"]), len(file_paths))) abundance = xr.DataArray(data=empty_array.copy(), dims=["gene_id", "file"]) diff --git a/test/test_cli.py b/test/test_cli.py index 5e1826b..adfc690 100644 --- a/test/test_cli.py +++ b/test/test_cli.py @@ -13,10 +13,10 @@ def test_cli( """Test the cli function.""" file_paths = " -i ".join([str(file) for file in salmon_multiple_files]) - # timestamp + # Timestamp current_time = int(time()) - # check whether the current directory can be written to + # Check whether the current directory can be written to if not os.access(os.getcwd(), os.W_OK): raise PermissionError("The current directory cannot be written to.") @@ -27,19 +27,19 @@ def test_cli( os.system(command) # nosec - # check that the output file was created + # Check that the output file was created assert os.path.exists(f"./pytximport_cli_test_{current_time}.csv"), "Output file was not created." - # remove the temporary file + # Remove the temporary file os.system(f"rm ./pytximport_cli_test_{current_time}.csv") # nosec - # test saving as h5ad - command_ad = f"{command.replace('.csv', '.h5ad')} --output_type anndata --output_format h5ad" + # Test saving as h5ad + command_ad = f"{command.replace('.csv', '.h5ad')} --output_format h5ad" os.system(command_ad) # nosec - # check that the output file was created + # Check that the output file was created assert os.path.exists(f"./pytximport_cli_test_{current_time}.h5ad"), "AnnData output file was not created." - # remove the temporary file + # Remove the temporary file os.system(f"rm ./pytximport_cli_test_{current_time}.h5ad") # nosec diff --git a/test/test_correctness.py b/test/test_correctness.py index af14eb2..7809fa4 100644 --- a/test/test_correctness.py +++ b/test/test_correctness.py @@ -39,7 +39,7 @@ def test_correctness( columns=result.coords["file_path"], ).sort_index() - # load in the comparison data generated with the R package tximport + # Load in the comparison data generated with the R package tximport if counts_from_abundance is None: df_result_tximport = pd.read_csv( fabry_directory / "counts_tximport_no.csv", @@ -59,10 +59,10 @@ def test_correctness( header=0, ) - # since tximport does not use the file path as column, use the columns from the comparison data + # Since tximport does not use the file path as column, use the columns from the comparison data df_result.columns = df_result_tximport.columns - # check that the data is the same + # Check that the data is the same pd.testing.assert_frame_equal(df_result, df_result_tximport) @@ -96,7 +96,7 @@ def test_correctness_transcript_level( columns=result.coords["file_path"], ).sort_index() - # load in the comparison data generated with the R package tximport + # Load in the comparison data generated with the R package tximport if counts_from_abundance == "dtu_scaled_tpm": df_result_tximport = pd.read_csv( data_directory / "salmon" / "counts_tximport_dtuScaledTPM.csv", @@ -110,13 +110,13 @@ def test_correctness_transcript_level( header=0, ).sort_index() - # remove the transcript version from the index since tximport does not remove it + # Remove the transcript version from the index since tximport does not remove it df_result_tximport.index = df_result_tximport.index.str.split(".").str[0] - # since tximport does not use the file path as column, use the columns from the comparison data + # Since tximport does not use the file path as column, use the columns from the comparison data df_result.columns = df_result_tximport.columns - # check that the data is the same + # Check that the data is the same pd.testing.assert_frame_equal(df_result, df_result_tximport) @@ -148,20 +148,20 @@ def test_correctness_gene_level( columns=result.coords["file_path"], ).sort_index() - # load in the comparison data generated with the R package tximport + # Load in the comparison data generated with the R package tximport df_result_tximport = pd.read_csv( data_directory / "rsem" / "counts_tximport_no.csv", index_col=0, header=0, ).sort_index() - # remove the transcript version from the index since tximport does not remove it + # Remove the transcript version from the index since tximport does not remove it df_result_tximport.index = df_result_tximport.index.str.split(".").str[0] - # since tximport does not use the file path as column, use the columns from the comparison data + # Since tximport does not use the file path as column, use the columns from the comparison data df_result.columns = df_result_tximport.columns - # check that the data is the same + # Check that the data is the same pd.testing.assert_frame_equal(df_result, df_result_tximport) @@ -200,7 +200,7 @@ def test_correctness_inferential_replicates( ).sort_index() df_result.index = df_result.index.str.split(".").str[0] - # load in the comparison data generated with the R package tximport + # Load in the comparison data generated with the R package tximport if return_transcript_data: prefix = "_transcripts" else: @@ -214,8 +214,8 @@ def test_correctness_inferential_replicates( df_result_tximport.index = df_result_tximport.index.str.split(".").str[0] df_result_tximport = df_result_tximport.sort_index() - # since tximport does not use the file path as column, use the columns from the comparison data + # Since tximport does not use the file path as column, use the columns from the comparison data df_result.columns = df_result_tximport.columns - # check that the data is the same + # Check that the data is the same pd.testing.assert_frame_equal(df_result, df_result_tximport) diff --git a/test/test_export.py b/test/test_export.py index f531e65..9576066 100644 --- a/test/test_export.py +++ b/test/test_export.py @@ -16,23 +16,25 @@ def test_export( if not os.access(os.getcwd(), os.W_OK): raise PermissionError("The current directory cannot be written to.") - current_time = int(time()) + for output_type in ["anndata", "xarray"]: + current_time = int(time()) - _ = tximport( - salmon_multiple_files, - "salmon", - transcript_gene_mapping_path_mouse, - output_format="csv", - output_path=f"./pytximport_cli_test_{int(time())}.csv", - ) + _ = tximport( + salmon_multiple_files, + "salmon", + transcript_gene_mapping_path_mouse, + output_type=output_type, + output_format="csv", + output_path=f"./pytximport_cli_test_{int(time())}.csv", + ) - # check that the output file was created - assert os.path.exists(f"./pytximport_cli_test_{current_time}.csv"), "Output file was not created." + # Check that the output file was created + assert os.path.exists(f"./pytximport_cli_test_{current_time}.csv"), "Output file was not created." - # remove the temporary file - os.system(f"rm ./pytximport_cli_test_{current_time}.csv") # nosec + # Remove the temporary file + os.system(f"rm ./pytximport_cli_test_{current_time}.csv") # nosec - # test saving as h5ad + # Test saving as h5ad _ = tximport( salmon_multiple_files, "salmon", @@ -42,8 +44,8 @@ def test_export( output_path=f"./pytximport_cli_test_{current_time}.h5ad", ) - # check that the output file was created + # Check that the output file was created assert os.path.exists(f"./pytximport_cli_test_{current_time}.h5ad"), "AnnData output file was not created." - # remove the temporary file + # Remove the temporary file os.system(f"rm ./pytximport_cli_test_{current_time}.h5ad") # nosec diff --git a/test/test_kallisto.py b/test/test_kallisto.py index 40b4adf..ffe7432 100644 --- a/test/test_kallisto.py +++ b/test/test_kallisto.py @@ -29,10 +29,10 @@ def test_kallisto( counts_from_abundance=counts_from_abundance, # type: ignore ) - # check that the result is an xarray dataset + # Check that the result is an xarray dataset assert isinstance(result, xr.Dataset) - # check that the counts.data are all positive + # Check that the counts.data are all positive assert (result["counts"].data >= 0).all() @@ -49,7 +49,7 @@ def test_multiple_kallisto( for existence_optional in [True, False]: if existence_optional: kallisto_multiple_files_original = kallisto_multiple_files.copy() - # add a non-existent file + # Add a non-existent file kallisto_multiple_files = kallisto_multiple_files + [ kallisto_multiple_files.pop(0).with_name("non_existent_file.tsv") ] @@ -72,8 +72,8 @@ def test_multiple_kallisto( if existence_optional: kallisto_multiple_files = kallisto_multiple_files_original - # check that the result is an xarray dataset + # Check that the result is an xarray dataset assert isinstance(result, xr.Dataset) - # check that the counts.data are all positive + # Check that the counts.data are all positive assert (result["counts"].data >= 0).all() diff --git a/test/test_rsem.py b/test/test_rsem.py index e0fb9cd..7ab5041 100644 --- a/test/test_rsem.py +++ b/test/test_rsem.py @@ -25,7 +25,7 @@ def test_rsem( for existence_optional in [True, False]: if existence_optional: rsem_files_original = rsem_files.copy() - # add a non-existent file + # Add a non-existent file rsem_files = rsem_files + [rsem_files[-1].with_name("non_existent_file.genes.results.gz")] if gene_level and counts_from_abundance is not None: @@ -54,14 +54,30 @@ def test_rsem( existence_optional=existence_optional, ) - # check that the result is an xarray dataset + # Check that the result is an xarray dataset assert isinstance(result, xr.Dataset) - # check that the counts.data are all positive + # Check that the counts.data are all positive assert (result["counts"].data >= 0).all() - # check that the gene_id coordinates do not contain any "." + # Check that the gene_id coordinates do not contain any "." assert not any("." in gene_id for gene_id in result.coords["gene_id"].values) if existence_optional: rsem_files = rsem_files_original + + # Test gene level without transcript_gene_map + result = tximport( + rsem_files, + "rsem", + transcript_gene_map=None, + counts_from_abundance=None, + gene_level=True, + output_type="xarray", + ) + + # Check that the result is an xarray dataset + assert isinstance(result, xr.Dataset) + + # Check that the counts.data are all positive + assert (result["counts"].data >= 0).all() diff --git a/test/test_salmon.py b/test/test_salmon.py index 16e1bfb..ecc1fda 100644 --- a/test/test_salmon.py +++ b/test/test_salmon.py @@ -32,7 +32,7 @@ def test_salmon( counts_from_abundance=counts_from_abundance, # type: ignore ) - # check that the result is an xarray dataset + # Check that the result is an xarray dataset if output_type == "xarray": assert isinstance(result, xr.Dataset) counts = result["counts"].data @@ -40,7 +40,7 @@ def test_salmon( assert isinstance(result, ad.AnnData) counts = result.X - # check that the counts.data are all positive + # Check that the counts.data are all positive assert (counts >= 0).all() @@ -58,7 +58,7 @@ def test_multiple_salmon( for existence_optional in [True, False]: if existence_optional: salmon_multiple_files_original = salmon_multiple_files.copy() - # add a non-existent file + # Add a non-existent file salmon_multiple_files = salmon_multiple_files + [ salmon_multiple_files.pop(0).with_name("non_existent_file.sf") ] @@ -78,8 +78,8 @@ def test_multiple_salmon( if existence_optional: salmon_multiple_files = salmon_multiple_files_original - # check that the result is an xarray dataset + # Check that the result is an xarray dataset assert isinstance(result, xr.Dataset) - # check that the counts.data are all positive + # Check that the counts.data are all positive assert (result["counts"].data >= 0).all() diff --git a/test/test_transcriptome_to_gene_map.py b/test/test_transcript_gene_map.py similarity index 97% rename from test/test_transcriptome_to_gene_map.py rename to test/test_transcript_gene_map.py index afec05e..518313e 100644 --- a/test/test_transcriptome_to_gene_map.py +++ b/test/test_transcript_gene_map.py @@ -39,7 +39,7 @@ def test_transcript_to_gene_map_from_gtf_annotation( assert isinstance(df_transcript_to_gene, pd.DataFrame), "The output is not a DataFrame." if use_gene_name: - # check that not all gene ids start with ENSG + # Check that not all gene ids start with ENSG assert ( not df_transcript_to_gene["gene_id"].str.startswith("ENSG").all() ), "All gene ids start with ENSG." diff --git a/test/test_transcript_level.py b/test/test_transcript_level.py index 439a365..1f3db1f 100644 --- a/test/test_transcript_level.py +++ b/test/test_transcript_level.py @@ -33,19 +33,19 @@ def test_salmon_transcript_level( assert isinstance(result, ad.AnnData) counts = result.X - # check that the counts.data are all positive + # Check that the counts.data are all positive assert (counts >= 0).all() # replace the transcript ids with the transcript names result = replace_transcript_ids_with_names(result, transcript_name_mapping_human) - # check that the result is an AnnData object + # Check that the result is an AnnData object assert isinstance(result, ad.AnnData) - # check that the var names don't start with ENST + # Check that the var names don't start with ENST assert result.var_names.str.startswith("ENST").sum() == 0 - # check that the var names are not nan or the string "nan" or empty + # Check that the var names are not nan or the string "nan" or empty assert ( result.var_names.isna().sum() == 0 and (result.var_names == "nan").sum() == 0