Skip to content

Results, annotation, plots

Tables and annotation (pystreme.results)

pystreme.results

Results as tables: motif summaries, per-peak site tables, and database annotation of discovered motifs. DESIGNDOC.md Phase 5 ("summary DataFrame output").

pandas is imported lazily so the core package (scan/fit) has no dependency on it; these functions raise a clear error if it is missing.

summary

summary(motifs, order: str = 'round')

One row per motif: the numbers you would put in a table or a figure legend. holdout_logp is the significance to quote (see discovery.Motif); train_logp is the selected, optimistic one. Works on fit() output, a single discover() result, or any mix. order="pvalue" sorts the rows most significant first (see sort_by_pvalue); the default keeps discovery order.

sites_frame

sites_frame(motif)

One row per primary sequence the motif was scored on: the interval (as extracted, i.e. the fixed-width window), the best site's score, genomic start, strand and offset from the window center, and whether it clears the motif's threshold (passing; passing.sum() is motif.n_sites). Needs the intervals fit/discover attach to the motif (Motif.intervals).

annotate

annotate(motifs, database, top: int = 3, min_overlap: int = 5)

Rank every motif in a MEME-format database (a path, or an already-parsed {name: MemeMotif} dict) against each discovered motif by compare_pwms, and return the top hits per motif as a DataFrame (query, rank, target, score, mean per-column correlation, offset, orientation, overlap).

This is an in-process ranking in Tomtom's Pearson metric, not Tomtom: no p-value/E-value (which needs Tomtom's null distribution over the whole database). Use it to name what fit found -- e.g. against HOCOMOCO v12 core (H12CORE_meme_format.meme) -- and keep scripts/validate_streme.py (real Tomtom) for validation claims.

compare_pwms

compare_pwms(query: ndarray, target: ndarray, min_overlap: int = 5) -> tuple[float, int, str, int]

Best alignment of query to target (both (4, w) probability matrices) in Tomtom's Pearson flavour: the score of an alignment is the sum of per-column Pearson correlations over the overlapping columns (so longer, consistently similar overlaps score higher, and a perfect match scores its width), maximized over all offsets with at least min_overlap overlapping columns and over both orientations of the query. Returns (score, offset, orientation, overlap) where offset is the target column the query's first column aligns to (negative: the query starts before the target) and orientation is "+" or "-" (query reverse-complemented).

Figures (pystreme.plot)

pystreme.plot

Logos and positional histograms for discovered motifs. DESIGNDOC.md Phase 5 ("logo plotting via logomaker; positional histogram plots").

matplotlib and logomaker are imported lazily: the core package never needs them. Every function returns the matplotlib Axes it drew on so figures can be composed further.

logo(motif, ax=None, title: str | None = None)

Information-content sequence logo of motif.pwm (a Motif, a meme_io.MemeMotif, or a bare (4, w) array) via logomaker.

positions

positions(motif, ax=None, bins: int = 40, title: str | None = None, shade_below_logp: float = np.log(0.05))

Histogram of the motif's passing-site centers relative to the sequence center (Motif.positions, §2.7), with the central window that won the CentriMo-style test shaded (only when that test is significant, central_logp < shade_below_logp) and its log p in the title. Sites at every offset with equal frequency means no positional signal; a spike at 0 is what a directly bound, well-summited factor looks like.

report

report(motifs, figsize_per_row: tuple[float, float] = (9.0, 2.2), annotation=None, order: str = 'pvalue')

One row per motif: logo on the left, positional histogram on the right. Returns the matplotlib Figure.

annotation puts a database match in each logo's title: the DataFrame from results.annotate (its rank-1 hit per motif) or a {motif name: label} dict. order is "pvalue" (default: most significant first, by holdout_logp, or log_pvalue where there is no hold-out) or "round" (discovery order, as fit returned them -- only roughly monotone in p, since each round is the best of what is left after erasing and the hold-out re-test is noisy). Names keep their round prefix either way.

MEME format I/O (pystreme.meme_io)

pystreme.meme_io

MEME minimal motif format: reader and writer.

Reader loads JASPAR/CIS-BP PWMs for validation (L1) and for scanning with known motifs. Writer (to_meme) makes pystreme output consumable by Tomtom, FIMO, and gimmemotifs (DESIGNDOC.md, Goals §1.4 and Non-goals §1). Phase 1.

Format reference: https://meme-suite.org/meme/doc/meme-format.html Only the minimal subset pystreme needs is implemented: a background line and one letter-probability matrix per motif, alphabet ACGT.

MemeMotif dataclass

read_meme

read_meme(path) -> dict[str, MemeMotif]

Parse a MEME minimal motif format file into {name: MemeMotif}.

write_meme

write_meme(motifs: dict[str, ndarray] | list[MemeMotif], path, background: ndarray | None = None)

Write motifs to MEME minimal motif format.

motifs is either {name: (4, w) probability array} or a list of MemeMotif. background is a length-4 ACGT frequency array; uniform by default.