mRNA
AnnData-native analysis of bulk RNA-seq and processed expression microarrays.
mRNA is independent of cellscope and immune. Figures can be styled and exported
with atopos; all plots return native Matplotlib objects without implicit saving.
The distribution name is mRNA; the standard Python import is import mRNA as mr.
Install
Python 3.12 or newer. Python 3.12, 3.13, and 3.14 are covered by CI. This is an initial local release; install from this checkout rather than assuming a PyPI release exists:
uv venv --python 3.14
uv pip install -e '.[all,dev]'
Core dependencies include AnnData, NumPy, pandas, SciPy, and Formulaic. Optional
extras: deseq2, edge, limma, enrichment, activity, plot, and dev.
The tested contemporary baseline is PyDESeq2 0.5.4, pylimma 0.2.0, edgePython
0.2.6, GSEApy 1.3.1, and decoupler 2.2.0. See requirements-tested.txt for exact
versions used during local verification.
For manual PyPI releases with uv and Hatchling, see PUBLISHING.md
and scripts/release.py.
Data model
AnnData.obs: biological samples and their condition, batch, donor, or other covariates.AnnData.var: unique stable gene IDs, annotation, and explicitly sourced lengths.AnnData.layers['counts']: original nonnegative integer counts.AnnData.layers['cpm'/'tpm'/...]: derived representations, stored separately.AnnData.X: initial input or an explicitly selected active representation.AnnData.obsm: PCA/MDS coordinates and sample-level gene-set/activity scores.AnnData.obsp: sample correlations.AnnData.uns['mRNA']: results and serializable parameters/backend provenance.
Samples are rows and genes are columns. Derived layers preserve original counts.
Inputs require an explicit representation and metadata IDs must match exactly.
Analysis modifies AnnData unless copy=True is exposed and supplied. Filtered
data are returned as copies; views/backed data must be materialized explicitly.
Fitted native models are returned separately, not embedded into .h5ad.
Bulk workflow: log2(TPM + 1) exploration and count-based DE
The bulk example uses log2(TPM + 1) for PCA, sample correlations, expression
heatmaps, and sample-level gene-set scores. Differential expression uses the
original counts and each backend's normalization. ORA and preranked GSEA use
the differential-expression results rather than the TPM matrix.
import mRNA as mr
adata = mr.datasets.toy_counts()
mr.pp.qc(adata)
# Synthetic lengths are for this toy example; real data can supply quantified TPM.
mr.pp.tpm(adata, lengths="length", length_definition="synthetic example lengths")
mr.pp.log_transform(adata, layer="tpm", input_type="tpm", key_added="logtpm", base=2, pseudocount=1)
mr.tl.pca(adata, layer="logtpm", input_type="logtpm", n_components=5)
mr.tl.sample_correlation(adata, layer="logtpm", input_type="logtpm")
model = mr.tl.fit(
adata, design="~ batch + condition", method="deseq2", layer="counts", input_type="counts"
)
de = mr.tl.contrast(model, contrast=("condition", "treated", "control"))
gene_sets = {"example_up": list(adata.var_names[:15])}
mr.tl.ora(adata, gene_sets=gene_sets, resource_version="example-v1", direction="up")
mr.tl.gsea(
adata,
gene_sets=gene_sets,
resource_version="example-v1",
seed=0,
backend_options={"min_size": 5, "permutation_num": 100},
)
ax = mr.pl.volcano(adata)
mr.io.write(adata, "results/bulk.h5ad")
Swap method='edgepython' for TMM/QL GLM inference, or method='limma' for
TMM/voom followed by moderated t-tests. Counts-based limma requires the edge
extra as well as limma; all includes both. DESeq2 uses its own size factors.
Generic conversion of TPM/CPM into raw counts is not supported.
If TPM is already available as a DataFrame with samples in rows and genes in columns, import it directly without recalculating TPM or logging it twice:
adata_tpm = mr.io.from_frames(tpm, metadata, input_type="tpm")
mr.pp.log_transform(
adata_tpm, layer=None, input_type="tpm", key_added="logtpm", base=2, pseudocount=1
)
mr.tl.pca(adata_tpm, layer="logtpm", input_type="logtpm", n_components=5)
Here tpm and metadata are user-supplied DataFrames. A TPM-only dataset
supports expression exploration; the count-based DE engines require separately
available original counts. See examples/bulk_workflow.py for the complete
workflow with both representations.
Processed microarrays
adata = mr.datasets.toy_microarray()
model = mr.tl.fit(
adata, design="~ condition", method="limma", layer=None, input_type="log_expression"
)
de = mr.tl.contrast(model, contrast=("condition", "treated", "control"))
Raw CEL/RMA processing and FASTQ alignment/quantification are upstream stages. Quantifier import preserves estimated counts and effective lengths; estimated counts are not silently rounded into raw integer counts.
Designs, contrasts, and results
Use independent biological replicates; cells and technical libraries are not
independent bulk samples. Named comparisons require at least two samples in
each condition. Use ~ donor + condition for paired studies or
~ batch + condition for batch adjustment. Confounded/rank-deficient and
saturated designs are rejected. Random-effect models are not implemented.
Formulaic builds the same labeled design for all three adapters. Named contrasts
in interaction designs are marginal contrasts averaged over observed covariates.
Pass a numeric coefficient vector to request a specific simple effect. Reuse
tl.fit results for additional contrasts.
Canonical result fields: gene, log2_fold_change, statistic, p_value,
adj_p_value, method, contrast, status, reason, and change. Native
backend columns are retained. statistic_type and mean_expression_type
identify their different meanings/units. Filtered and untestable genes stay in
the table with missing statistics and an explanation. Backend independent
filtering may yield a missing adjusted p-value, which is preserved.
- PyDESeq2: Wald tests; optional
shrink_coefficientfor a positive single-coefficient contrast, with shrunken LFC and SE saved separately from unshrunken statistics. - edgePython: default QL, or
backend_options={'test': 'lrt'}at fitting time. TREAT is requested at contrast time withbackend_options={'lfc': threshold}. Signed sqrt(F/LR) is used for rankings; native F/LR is retained. TREAT does not report an F/LR statistic; its canonical statistic stays missing. Choose an explicit alternative ranking column for TREAT results. - pylimma: contrasts followed by empirical Bayes moderation. mRNA uses
john-mulvey/pylimma, not the different
python-limmadistribution that exports the same import namespace. Do not install both in one environment.
lfc_threshold controls result labeling, not the statistical null hypothesis.
No automated majority-vote combination of backend p-values is provided.
Annotation and functional scores
annotation.map_ids returns mapped/unmapped/ambiguous diagnostics without
duplicating the expression matrix. annotation.annotate adds var columns
and leaves stable gene IDs untouched. A custom table supports Ensembl, Entrez,
symbol, alias, or other identifiers through explicit column selection.
annotation.reference('human', release='legacy') and its mouse equivalent
expose archived atopos tables with their historical release labels. They are
not advertised as latest annotations; their gene-length derivation is unknown.
TPM/FPKM always require an explicit length definition. CPM requires no mapping.
Enrichment uses local GMT files or dictionaries with a required resource version
and content hash. ORA uses the tested-gene background and supports separate up/
down sets. GSEA uses the full finite fitted-gene ranking. gene_id_col='symbol'
can select mapped annotation; mapping loss is recorded and duplicate ranks
require an explicit policy. Do not provide a significance-filtered ranking.
tl.score_gene_sets stores ssGSEA/GSVA scores in obsm. tl.activity uses
decoupler 2.x and an explicit TF/pathway network. These are sample-level scores,
not integer count matrices. pp.remove_batch_effect produces an explicitly
exploratory layer; differential expression should model batch covariates.
Validation and scope
ruff check .
ruff format --check .
MPLBACKEND=Agg python -m pytest
python -m build
The tests cover data integrity, denominator/length handling, mapping ambiguity,
real optional backend calculations, effect direction, reusable contrasts,
enrichment backgrounds, gene-set scores, plots, and .h5ad round trips.
See DESIGN.md, VALIDATION.md, and the examples for details.
This first implementation targets the P0/P1 matrix-analysis workflow. Coexpression networks, deconvolution, repeated-measures random effects, differential splicing, cross-cohort meta-analysis, and survival/prediction modules remain explicit future extensions, rather than unvalidated wrappers.
Metadata
Release files for mRNA 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| mrna-0.1.0.tar.gz | 2.8 MB | Without provenance | Details for mrna-0.1.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| mrna-0.1.0-py3-none-any.whl | Python 3 | none | any | Details for mrna-0.1.0-py3-none-any.whl |
Total release size: 5.5 MB
Release files / mrna-0.1.0.tar.gz
| Download URL | mrna-0.1.0.tar.gz |
|---|---|
| Size | 2.8 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
462d90927d33fd917b5ad5e7cbcb54bc2e16ea1189bafa6d13f022b5f0bde254
|
|
BLAKE2b-256 checksum How to use checksums |
95d039343cc552760771a24830b15c69bf906f2a93c20563ebc87b6374159113
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.12.5 {"installer":{"name":"uv","version":"0.12.5","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Release files / mrna-0.1.0-py3-none-any.whl
| Download URL | mrna-0.1.0-py3-none-any.whl |
|---|---|
| Size | 2.6 MB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
9bdce1d5fb5ed9bf3c341e15bbcb213d75d04c4236cd1b81e3584ddb81307491
|
|
BLAKE2b-256 checksum How to use checksums |
93f35a43fcc17dc213bba11599a1605d0c30cde618ea93e9b6fce4cf60d9d133
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.12.5 {"installer":{"name":"uv","version":"0.12.5","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Security for mRNA 0.1.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.