Skip to content

Databases and Biopython

Motifs from public databases, and conversion to and from Biopython.

The database functions live in the universalmotif.databases module, used as um.databases.jaspar() and so on. They download what they need the first time and keep it in a cache, so later calls work offline. The conversion functions need the biopython extra:

pip install universalmotif[biopython]

Databases

jaspar

jaspar(
    collection: str = "CORE",
    tax_group: str | None = None,
    name: str | None = None,
    tax_id: int | None = None,
    tf_class: str | None = None,
    tf_family: str | None = None,
    data_type: str | None = None,
    release: int | None = None,
    all_versions: bool = False,
    metadata: bool = False,
    refresh: bool = False,
) -> list[Motif]

Count matrices from JASPAR, through its REST API.

The filters are those of the API: collection (such as "CORE", "UNVALIDATED" or "CNE"), tax_group (such as "vertebrates", "plants" or "insects"), name for the transcription factor, tax_id for the NCBI taxonomy ID of a species (9606 for human), tf_class, tf_family and data_type (such as "ChIP-seq" or "SELEX"). Text filters must match JASPAR's names exactly, and the API ignores filters it does not know, so a misspelt name gives the unfiltered set rather than an error. release picks a JASPAR release by year, the latest by default, and only the latest version of each matrix is returned unless all_versions.

Motifs are PCMs named by their matrix ID, with the transcription factor as the alternative name. The list of matrices does not say more than that, so with metadata each matrix's record is also fetched, one request per matrix the first time, which fills in the family, the species as the organism, and the class, taxonomic group, data type, UniProt IDs and PubMed IDs in extrainfo.

Downloads are cached, so asking for the latest release keeps returning the motifs of the first download until refresh is given.

Examples:

>>> import universalmotif as um
>>> motifs = um.databases.jaspar(tax_group="plants", name="ABF1")
>>> motifs[0].name, motifs[0].altname
('MA0570.3', 'ABF1')

hocomoco

hocomoco(
    version: int = 12,
    collection: str = "CORE",
    species: str | None = None,
    refresh: bool = False,
) -> list[Motif]

Count matrices from HOCOMOCO, for human and mouse transcription factors.

Version 12 has the collections "CORE", "INVIVO", "INVITRO" and "RSNP", each with motifs for human and mouse together, and species keeps only those built from "HUMAN" or "MOUSE" data. Version 11 has "CORE" and "FULL", with separate files for each species, so there species picks one and defaults to "HUMAN".

Motifs are PCMs named by their HOCOMOCO ID, such as AHR.H12CORE.0.P.B, with the transcription factor as the alternative name and its TFClass family as the family. The quality grade, A to D, and a few more details go in extrainfo.

Examples:

>>> import universalmotif as um
>>> motifs = um.databases.hocomoco()
>>> motifs[0].name, motifs[0].altname, motifs[0].family
('AHR.H12CORE.0.P.B', 'AHR', 'PAS')

cisbp

cisbp(
    species: str,
    family: str | Sequence[str] | None = None,
    inferred: bool = False,
    refresh: bool = False,
) -> list[Motif]

Motifs from CIS-BP for one species.

CIS-BP builds an archive of a species' motifs on request, which is downloaded and cached, and then read with read_cisbp_archive(). species is written as in CIS-BP, such as "Homo_sapiens", though spaces may be used instead of underscores. family keeps only motifs of some transcription factor families, such as "bZIP", and inferred adds the motifs CIS-BP assigns to a factor from similar factors, which by default are left out.

Examples:

>>> import universalmotif as um
>>> motifs = um.databases.cisbp("Arabidopsis thaliana", family="WRKY")
>>> motifs[0].family, motifs[0].organism
('WRKY', 'Arabidopsis thaliana')

read_cisbp_archive

read_cisbp_archive(
    path: str | PathLike[str],
    family: str | Sequence[str] | None = None,
    inferred: bool = False,
) -> list[Motif]

Read a CIS-BP download, either the zip archive from its bulk download page or the folder it unpacks to.

The archive needs TF_Information_all_motifs.txt, or TF_Information.txt, and the pwms_all_motifs folder of probability matrices. Motifs are PPMs named by their CIS-BP motif ID, with the transcription factors they belong to as the alternative name, the family and the species, and the experiment type and source in extrainfo. Motifs CIS-BP infers from similar factors are left out unless inferred, family keeps only some families, and motifs whose matrix file is empty are skipped.

Examples:

>>> import universalmotif as um
>>> motifs = um.databases.read_cisbp_archive("Arabidopsis_thaliana.zip")

cache_dir

cache_dir() -> Path

The directory downloads are kept in.

It is the UNIVERSALMOTIF_CACHE environment variable if that is set, and otherwise a universalmotif folder in the usual place for caches: ~/Library/Caches on macOS, %LOCALAPPDATA% on Windows, and $XDG_CACHE_HOME or ~/.cache elsewhere.

Examples:

>>> import os
>>> import universalmotif as um
>>> os.environ["UNIVERSALMOTIF_CACHE"] = "/tmp/motif-cache"
>>> um.databases.cache_dir().as_posix()
'/tmp/motif-cache'
>>> del os.environ["UNIVERSALMOTIF_CACHE"]

clear_cache

clear_cache() -> int

Delete every download in cache_dir(), returning the number of files removed.

Examples:

>>> import os, tempfile
>>> import universalmotif as um
>>> with tempfile.TemporaryDirectory() as tmp:
...     os.environ["UNIVERSALMOTIF_CACHE"] = tmp
...     um.databases.clear_cache()
0
>>> del os.environ["UNIVERSALMOTIF_CACHE"]

Biopython

to_biopython

to_biopython(motifs: Motif, jaspar: bool = ...) -> Any
to_biopython(
    motifs: Iterable[Motif], jaspar: bool = ...
) -> list[Any]
to_biopython(motifs, jaspar=False)

Convert motifs to Biopython's Bio.motifs.

Each motif becomes a Bio.motifs.Motif holding counts, from the motif's PCM with nsites, or 100 sites when it has none. The name, background and pseudocount come across, the pseudocount spread evenly over the letters as Biopython keeps one per letter. With jaspar, the motifs become Bio.motifs.jaspar.Motif instead, with the name as the matrix ID and the alternative name, family and organism filled in, as Biopython's JASPAR writer expects. Returns a motif for a motif and a list for a list.

Needs the biopython extra.

Examples:

>>> import universalmotif as um
>>> bio = um.to_biopython(um.example_motifs()[1])
>>> bio.name, bio.length, bio.consensus
('AP-1', 9, Seq('TTGACTCAG'))

from_biopython

from_biopython(motifs: Any) -> Motif | list[Motif]
from_biopython(motifs)

Convert motifs from Biopython's Bio.motifs.

Takes a Bio.motifs.Motif, or a list of them such as a Bio.motifs.Record read with Bio.motifs.parse(), and returns a motif or a list of motifs. Counts become a PCM, and frequencies that do not look like counts a PPM. The alphabet is DNA, RNA or amino acids when the motif's letters are exactly those, and a custom alphabet otherwise.

JASPAR motifs, including those from pyJASPAR, keep their matrix ID as the name, the transcription factor as the alternative name, the family as the family and the species as the organism, with the class, taxonomic group, data type and accession kept in extrainfo. MEME motifs keep their alternative ID and E-value. Background frequencies come across, and Biopython's per-letter pseudocounts become a single pseudocount, the sum of the per-letter ones.

Needs the biopython extra.

Examples:

>>> import universalmotif as um
>>> from Bio import motifs
>>> bio = motifs.create(["TGACTCA", "TGAGTCA", "TGACTAA"])
>>> bio.name = "AP-1"
>>> motif = um.from_biopython(bio)
>>> motif.name, motif.type, motif.consensus
('AP-1', 'PCM', 'TGASTMA')