aoutools.prs

This submodule contains all tools related to polygenic risk score (prs) calculations.

aoutools.prs.calculate_pgs(*, vds, output_path, pgs, build='GRCh38', config=None, user_agent=None)[source]

Downloads specified PGS Catalog scoring files and calculates PRS.

This function automates a controlled workflow:

  1. Download: Fetches scoring files from the PGS Catalog for a specific

    list of PGS IDs.

  2. Read: Parses the downloaded scoring files into Hail Tables.

  3. Calculate: Computes the Polygenic Risk Score(s) for each downloaded

    file and exports a single CSV file.

Notes

This function does not accept EFO traits or PGP publication IDs to prevent the unexpected download of a large number of scoring files, which may overwhelm the storage or computational resources of a typical workspace.

Parameters:
  • vds (hail.vds.VariantDataset) – A Hail VariantDataset containing the genotype data to be scored.

  • output_path (str) – A GCS path (e.g., ‘gs://bucket/results.csv’) for the output file.

  • pgs (str or iterable of str) – One or more PGS Catalog ID(s) (e.g., “PGS000771”) to download. This argument is required.

  • build (str, optional) – The genome build for harmonized scores (“GRCh37” or “GRCh38”). Defaults to “GRCh38”.

  • config (PRSConfig, optional) – A configuration object for calculation parameters.

  • user_agent (str, optional) – A custom user agent string for PGS Catalog API requests.

Returns:

The output path if results are successfully written; otherwise, None.

Return type:

str or None

Raises:
  • ValueError – If the output_path is not a valid GCS path, or if a downloaded scoring file is empty, malformed, or contains duplicate variants.

  • TypeError – If config.samples_to_keep is an unsupported type.

  • Exception – If the download process fails due to network issues, invalid PGS IDs, or other errors from the underlying pgscatalog-download tool.

aoutools.prs.calculate_prs(weights_table, vds, output_path, config=None)[source]

Calculates a Polygenic Risk Score (PRS) and exports the result to a file.

This function is the main entry point for the PRS calculation workflow. It processes a weights table in chunks, using a filter_intervals approach to select variants from the VDS for each chunk. Partial results are then converted to Pandas DataFrames and aggregated to produce the final score file.

Notes

Multi-allelic variants in the VDS are always split before scoring. Splitting puts each allele in its minimal representation, which lets a simple variant in the weights table match a complex one in the VDS: a weights row for chr1:10075251 A/G matches VDS alleles [‘AGGGC’, ‘A’, ‘GGGGC’], because ‘AGGGC’ -> ‘GGGGC’ minimizes to [‘A’, ‘G’] at that same locus.

Minimal representation can also move a variant’s locus, when the two alleles share a leading base: [‘GG’, ‘G’, ‘GT’] at chr1:1001 minimizes its SNP allele to [‘G’, ‘T’] at chr1:1002. Hail will not relocate a row, so such a variant raises rather than being scored. That is deliberate. No variant of this shape exists in All of Us – 0 of 6,001,424 ALT alleles measured – so the exception is a tripwire against a future change in variant representation, not a crash risk. See TODO.md, Finding 5.

Effect alleles may be given in either orientation, and are resolved per row against the VDS’s own REF/ALT. The PGS Catalog does not harmonize the effect allele onto the ALT, so a file mixing both is the normal case.

Parameters:
  • weights_table (hail.Table) –

    A Hail table containing variant weights. Must contain the following columns:

    • chr: str

    • pos: int32

    • effect_allele: str

    • noneffect_allele: str

    • A column for the effect weight (float64), specified by weight_col_name.

  • vds (hail.vds.VariantDataset) – A Hail VariantDataset containing both variant and sample data.

  • output_path (str) – A GCS path (starting with ‘gs://’) to write the final comma-separated output file.

  • config (PRSConfig, optional) – A configuration object for all optional parameters. If not provided, default settings will be used. See the PRSConfig class for details on all available settings.

Returns:

The output path if results are successfully written; otherwise, None. The output file is a comma-separated text file with:

  • A sample ID column (as configured in config.sample_id_col)

  • prs: The calculated PRS value

  • n_matched (optional): The number of variants used to calculate the score, included if config.include_n_matched is True.

Return type:

str or None

Raises:
  • ValueError – If output_path is not a valid GCS path, or if the weights_table is empty after validation.

  • TypeError – If the config.samples_to_keep argument is of an unsupported type.

See also

PRSConfig

A configuration class that holds parameters for PRS calculation.

aoutools.prs.calculate_prs_batch(weights_tables_map, vds, output_path, config=None)[source]

Calculates multiple Polygenic Risk Scores (PRS) concurrently using a memory-efficient, per-score annotation approach.

This function performs a batch PRS calculation on a Hail VariantDataset, using chunked aggregation and optional sample filtering.

Parameters:
  • weights_tables_map (dict[str, hl.Table]) – A dictionary mapping score names to their corresponding PRS weights tables.

  • vds (hl.vds.VariantDataset) – A Hail VariantDataset containing both variant and sample data.

  • output_path (str) – A GCS path (starting with ‘gs://’) to write the final comma-separated output file.

  • config (PRSConfig, optional) – A configuration object for all optional parameters. If not provided, default settings will be used. See the PRSConfig class for details on all available settings.

Returns:

The path to the final PRS result file if successful; otherwise, None if no valid variants were found.

Return type:

Optional[str]

Raises:
  • ValueError – If output_path is not a valid GCS path, or if the weights_table is empty after validation.

  • TypeError – If the config.samples_to_keep argument is of an unsupported type.

See also

PRSConfig

A configuration class that holds parameters for PRS calculation.

aoutools.prs.download_pgs(*, outdir, pgs=None, efo=None, pgp=None, build='GRCh38', efo_include_children=True, overwrite_existing_file=True, user_agent=None)[source]

Download PGS Catalog scoring files to a local directory or GCS bucket.

This function detects if the output path is local or GCS (gs://). If GCS, it downloads files to a temp directory then uploads to GCS.

Parameters:
  • outdir (str or pathlib.Path) – Local directory or GCS bucket path (e.g., ‘gs://my-bucket/path’).

  • pgs (str or iterable of str, optional) – PGS Catalog ID(s) (e.g., “PGS000194”).

  • efo (str or iterable of str, optional) – EFO term(s) (e.g., “EFO_0004611”).

  • pgp (str or iterable of str, optional) – PGP publication ID(s).

  • build (str, optional) – Genome build (“GRCh37” or “GRCh38”), default “GRCh38”.

  • efo_include_children (bool, default True) – Whether to include descendant EFO terms.

  • overwrite_existing_file (bool, default True) –

    Re-download a scoring file that is already present in outdir.

    With the default (True), re-running a cell that already downloaded its files simply fetches them again and replaces them. This is safe: the file for a given PGS Catalog ID never changes, so the new copy is identical to the old one. Pass False to make an already-present file an error instead – but note that because the downloads run concurrently, that error aborts the whole batch, not just the score whose file was present.

  • user_agent (str, optional) – Custom user agent string.

Returns:

The PGS Catalog score file(s) saved to the specified output path.

Return type:

None

Raises:
  • FileNotFoundError – If local output directory does not exist.

  • ValueError – If none of pgs, efo, or pgp are provided.

  • Exception – On download or upload failure.

Notes

The first call in a session provisions an isolated Python virtual environment and pip installs pgscatalog.core into it, to avoid a tenacity version conflict between pgscatalog.core and dsub. Consequently the first call:

  • requires network access and a writable home directory, and

  • incurs a one-time setup delay while the environment is built.

Subsequent calls reuse the cached environment and skip this step. The environment lives at ~/.aoutools/pgscatalog_env by default; set the AOUTOOLS_PGS_ENV_DIR environment variable (before the first call) to relocate it. To force a rebuild, delete that directory. See the “Using the download_pgs function” how-to guide for details.

aoutools.prs.read_prs_weights(file_path, header, column_map, delimiter=',', comment='#', keep_other_cols=False, validate_alleles=False, **kwargs)[source]

Reads a file containing variant effect weights for PRS calculation.

This function requires an active Hail-enabled environment. It uses a flexible column_map dictionary to handle various input file formats. After standardizing the required columns, the function performs several validation checks, filtering out variants with missing weights, invalid alleles (if validate_alleles=True), or raising an error for duplicates.

If a local file path is provided, it is automatically copied to a temporary directory in your GCS bucket for Hail access.

Parameters:
  • file_path (str) – A path to the weight file (local or gs://).

  • header (bool) – If True, column_map values should be strings (column names). If False, column_map values should be 1-based integers (column indices).

  • column_map (dict) – A dictionary mapping standard names to user-defined names or indices. Must contain the keys: ‘chr’, ‘pos’, ‘effect_allele’, ‘noneffect_allele’, and ‘weight’. Example for header=True: {‘chr’: ‘CHR’, ‘pos’: ‘BP’, …} Example for header=False: {‘chr’: 1, ‘pos’: 2, …}

  • delimiter (str, default ',') – A field delimiter.

  • comment (str or list[str], default '#') – A character, or list of characters, that denote comment lines to be ignored.

  • keep_other_cols (bool, default False) – If True, all columns not specified in column_map are preserved.

  • validate_alleles (bool, default False) – If True, validates that allele columns contain only ACGT characters.

  • **kwargs (dict, optional) – Other keyword arguments to pass directly to hail.import_table, such as missing or min_partitions.

Returns:

A Hail Table with standardized columns ready for PRS calculation.

Return type:

hail.Table

Raises:
  • ValueError – If column_map is missing required keys, if the input file is empty, or if duplicate variants are found in the weights file.

  • TypeError – If the value types in column_map do not match the header setting (e.g., strings for header=True, integers for header=False).

  • FileNotFoundError – If a local file_path is provided and the file does not exist.

aoutools.prs.read_prscs(file_path, **kwargs)[source]

Read a header-less weights file with the fixed PRS-CS column layout.

Deprecated since version 0.1.3: The name suggests this reader is tied to the PRS-CS tool, but it only applies one fixed column layout. Call read_prs_weights() directly with header=False and the column map shown below. read_prscs will be removed in a future release.

This function assumes a header-less, tab-separated file with the following columns:

  1. Chromosome

  2. Variant ID

  3. Base Position

  4. Effect Allele (A1)

  5. Non-Effect Allele (A2)

  6. Posterior Effect Size (weight)

Note: The second column (Variant ID) is not loaded by default, as it is not required for the core functionality. To preserve this and any other columns, set keep_other_cols=True when calling this function.

Parameters:
  • file_path (str) – A path to the weights file.

  • **kwargs – Other optional arguments to pass to read_prs_weights, such as keep_other_cols or validate_alleles.

Returns:

A processed Hail Table of the weights.

Return type:

hail.Table

class aoutools.prs.PRSConfig(chunk_size=20000, samples_to_keep=None, weight_col_name='weight', log_transform_weight=False, include_n_matched=False, sample_id_col='person_id', detailed_timings=False)[source]

A configuration class for Polygenic Risk Score (PRS) calculation.

chunk_size

The number of variants to include in each processing chunk.

Type:

int, default 20000

samples_to_keep

A collection of sample IDs to keep. Accepts a Hail Table, or a Python list, set, tuple of strings or integers, or a single string or integer. If None, all samples are retained.

Type:

hl.Table | Sequence[str] | Sequence[int] | str | int, optional

weight_col_name

The column name in weights table that contains effect sizes or weights.

Type:

str, default ‘weight’

log_transform_weight

If True, applies a natural log transformation to the weight column. Useful when weights are odds ratios (OR), since PRS assumes additive effects on the log-odds scale.

Type:

bool, default False

include_n_matched

If True, adds a column ‘n_matched’ with the number of variants matched between weights table and VDS. This option has a performance cost and should be used only when necessary.

Type:

bool, default False

sample_id_col

The column name to use for sample IDs in the final output table.

Type:

str, default ‘person_id’

detailed_timings

If True, adds a per-stage timing breakdown to the INFO log, useful for diagnosing performance issues. This is independent of the log level: use it to profile, and separately lower the aoutools logger to DEBUG if you want step-by-step detail.

Type:

bool, default False