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 aformula=override andreference="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_ancovaalso warns on confounded designs automatically.
pysaysuite.qpcr.qc— quality screens and efficiency-based cross-checks:genorm2— geNorm M reference selection, a 1:1 port ofctrlGene::geNorm2(D14).reference_stability,target_reference_correlation— reference QC.estimate_eff(amp, design=..., method="spline")— per-gene efficiency; the optionaldesign=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) andwell_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)
| File | Size | Uploaded | |
|---|---|---|---|
| pysaysuite-0.2.2.tar.gz | 489.8 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| 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 logRelease 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