Skip to main content

pySaySuite

python asSay Suite for quick, robust and reproducible assay analyses in python.

Installation (general)

The package can be obtained from PyPI:

pip install pySaySuite

qPCR module

Standardized, reproducible qPCR differential-expression analysis for the lab. One canonical, tested implementation of the ANCOVA / multivariable-linear-model method of

Hampton et al., Analyzing qPCR data: better practices to facilitate rigor and reproducibility, Biochem. Biophys. Rep. 44 (2025) 102356.

The statistical method is theirs; this package ports it to Python for Applied Biosystems ViiA 7 / QuantStudio exports.

Details

The module is qPCR-focused and reproduces the published better practices paper 1:1 (Tables 3 & 4 ANCOVA to 3 dp, geNorm conclusion, GAPDH–MMP10 correlation, and the amplification efficiencies 1.53/1.57 to ~1e-6 against the qpcR R oracle). The whole analysis is a short, curated set of functions in two modules:

  • pysaysuite.qpcr.core — the headline pipeline:
    • read_plates({name: path}, kind="results"|"amplification", batch_map=None) — ingest QuantStudio/ViiA 7 exports into a tidy long table, retaining plate identity (D9).
    • assign_group(long, group) — configurable sample→group assignment (prefix-dict / callable / layout table), flagging unmatched samples instead of silently grouping them.
    • build_wide(long, ...) — collapse technical replicates to mean CT; flag noisy replicate groups (wide.attrs["noisy_replicates"], D11).
    • run_ancova(wide, targets, refs, ...) — per-target ANCOVA on raw CT, returning a tidy coefficient DataFrame (one row per model term). Supports a formula= override and reference="gmean" (default) / a gene name / "separate" (D3); BH-FDR across the panel (D5) and an observations-per-parameter guard (D8).
    • check_identifiability(...) — Group⊥plate separability (D6); run_ancova also warns on confounded designs automatically.
  • pysaysuite.qpcr.qc — quality screens and efficiency-based cross-checks:
    • genorm2 — geNorm M reference selection, a 1:1 port of ctrlGene::geNorm2 (D14).
    • reference_stability, target_reference_correlation — reference QC.
    • estimate_eff(amp, design=..., method="spline") — per-gene efficiency; the optional design= metadata join restricts the screen to real sample wells (drops NTC/water), which is what makes the published 1.53/1.57 reproduce exactly. Two estimators are kept and never conflated (D15): well_efficiency_spline (qpcR-faithful) and well_efficiency (a robust, baseline-subtracted LinRegPCR screen).
    • run_ancova_efficiency — ANCOVA on efficiency-weighted CT (robustness variant).
    • pfaffl_compare — Pfaffl / 2^-ΔΔCt efficiency-corrected cross-check (D7).
  • pysaysuite.qpcr.plot / pysaysuite.qpcr.report — figures (forest, efficiency, reference stability, diagnostics, covariate, Pfaffl) and the methods-stamp / output writers (D10).
  • pysaysuite.Config — typed analysis config, loadable from TOML.
  • pysaysuite.core — intentionally empty for now; a shared cross-assay layer is premature with only the qPCR module present (each assay's input differs), and is deferred until a second assay lands (D12).

The headline functions are also re-exported at the top level: from pysaysuite import read_plates, build_wide, run_ancova, genorm2, estimate_eff, ....

Quickstart

import pysaysuite as ps

# 1. Ingest QuantStudio exports (one entry per plate) and assign groups.
long = ps.read_plates({"Plate1": "plate1.xls", "Plate2": "plate2.xls"})
long = ps.assign_group(long, {"N": "Control", "T": "Case"})   # by sample-name prefix

# 2. Reference-gene QC and selection.
wide = ps.build_wide(long)
stability = ps.genorm2(wide, ["RNU48", "U6", "GAPDH"])         # geNorm M ranking

# 3. Headline differential expression (ANCOVA on raw CT, geometric-mean reference).
result = ps.run_ancova(wide, targets=["MIR-21", "MIR-331"], refs=["RNU48", "U6"])
groups = result[result["is_group_effect"]]                    # one row per target
print(groups[["target", "estimate", "p_value", "p_fdr", "direction"]])

# 4. (Optional) efficiency screen + Pfaffl cross-check.
amp  = ps.read_plates({"Plate1": "plate1.xls"}, kind="amplification")
eff  = ps.estimate_eff(amp, design=long[["well"]].drop_duplicates())
xchk = ps.pfaffl_compare(wide, ["MIR-21"], ["RNU48", "U6"], eff, result)

run_ancova returns a tidy table with columns target, term, estimate, se, t, p_value, is_group_effect, p_fdr, direction, n, n_params, obs_per_param, r2_adj; the analysis parameters for the methods stamp live in result.attrs["params"].

Reproduce the paper, 1:1

docs/qpcr_examples/qpcr_paper_replication_pysaysuite.ipynb runs the package end-to-end on Hampton et al.'s own data (docs/qpcr_examples/data/) and asserts, in-notebook, that every result matches the published values: Tables 3 & 4 (ANCOVA), the geNorm conclusion, the GAPDH–MMP10 correlation, and the GAPDH/MMP10 amplification efficiencies. Execute it with:

conda run -n pysaysuite jupyter nbconvert --to notebook --execute --inplace \
  docs/testfiles/qpcr_paper_replication_pysaysuite.ipynb

Install (for development)

The package is developed in its own conda environment:

conda create -n pysaysuite python=3.12 -y
conda activate pysaysuite
pip install -e ".[dev]"

Release files for pysaysuite 0.2.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for pysaysuite 0.2.2
File Size Uploaded
pysaysuite-0.2.2.tar.gz 489.8 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for pysaysuite 0.2.2
File Interpreter ABI Platform
pysaysuite-0.2.2-py3-none-any.whl Python 3 none any Details

Total release size: 525.1 kB

Release files / pysaysuite-0.2.2.tar.gz

Download URL pysaysuite-0.2.2.tar.gz
Size 489.8 kB
Tags Source
SHA-256 checksum
How to use checksums
e3af1d2e9878d77d5af4f0d207fc2b12eb52450f7f48bed818c360a9a747a602
BLAKE2b-256 checksum
How to use checksums
8fa41de072976c6cfd17064ebaec1e98e5b76cbccf6e594db415ec3df2875fba
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jun 2, 2026.

Transparency log

Release files / pysaysuite-0.2.2-py3-none-any.whl

Download URL pysaysuite-0.2.2-py3-none-any.whl
Size 35.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
70bf57824884a139d1e6b1fc18032a4b8dfb2e1d023b097c6ccd41123e48faf1
BLAKE2b-256 checksum
How to use checksums
93c59f81ccc28942ced9e941ebfe2fa6b9587703c22138ee14516bba44d2a15c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jun 2, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.2.2 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page