Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Hierarchical Multiple Testing

Applies hierarchical multiple-testing correction to the per-gene cis-QTL results from TensorQTL and assembles the survivors into one consolidated object.

Overview

A cis scan reports a p-value for every variant against every molecular phenotype, which is not yet a result: the variants within a gene’s window are correlated and the genes are many, so raw p-values overstate significance twice over.

The correction is hierarchical, in three steps: local adjustment of the p-values of all cis variants within each gene, global adjustment of the minimum adjusted p-value across genes, then selection of the xQTLs whose locally adjusted p-value falls below the threshold (the eigenMT-BH procedure of Huang et al. 2018, NAR 46(22):e133). The survivors are packaged as a QtlSumStats object with a regional FDR table, and the intermediate TensorQTL files are reorganised into an archive folder for book-keeping or deletion.

The same default workflow handles three flavours of upstream result: the genetic (cis) effect shown below, the interaction effect - run on *.cis_qtl_top_assoc.txt.gz with --maf-cutoff 0 --cis-window 0 and the interaction p/q-value patterns - and quantile QTL.

When to run it. Immediately after TensorQTL, before fine-mapping. Nothing downstream reads the raw scan directory directly.

Input

The workflow is pointed at a directory rather than at files: it globs --cwd for the three TensorQTL products below using --regional-pattern, --qtl-pattern and --n-variants-suffix. output/tensorqtl_cis is one directory in that shape.

  • --cwd: the TensorQTL working directory holding the scan output. Three kinds of file are picked up from it.

    The per-gene regional result, matched by --regional-pattern (default cis_qtl[.]regional[.]tsv[.]gz$). Example output/tensorqtl_cis/protocol_example.chr22_chr22.cis_qtl.regional.tsv.gz, 21 columns and 201 rows:

    chrom  pos       n_variants  beta_shape1  beta_shape2  true_df    p_true_df             variant_id
    22     11797697  6           0.9833031    5.6122484    30.858135  0.0676042590649028    chr22:11797697_C_T
    22     15838003  46          0.98497593   26.038029    30.771364  0.007232871450238482  chr22:15838003_CTTTC...

    The full variant-level pairs file, matched by --qtl-pattern (default cis_qtl[.]pairs[.]tsv[.]gz$). Example output/tensorqtl_cis/protocol_example.chr22_chr22.cis_qtl.pairs.tsv.gz, 15 columns and 18319 rows:

    chrom  pos       molecular_trait_id  variant_id          tss_distance  tes_distance  af           pvalue
    22     10685239  ENSG00000283047     chr22:10685239_C_T  -254148       -276098       0.059322033  0.572662489372593
    22     10761227  ENSG00000283047     chr22:10761227_G_A  -178160       -200110       0.15254237   0.752156227936135

    The recounted variant tallies, matched by --n-variants-suffix (default cis_n_variants_stats[.]tsv[.]gz$). Example output/tensorqtl_cis/protocol_example.chr22_chr22.maf_0.01_window_1000000_cis_n_variants_stats.tsv.gz, 4 columns and 201 rows:

    chrom  molecular_trait_object_id  n_variants  n_variants_filtered
    chr22  ENSG00000063515            44          44
    chr22  ENSG00000075234            111         111
  • --output-dir: where the consolidated object and the regional FDR table are written. Required.

  • --modular-script-dir: the code/script directory holding the pecotmr_integration wrappers. Required.

  • --maf-cutoff and --cis-window: 0.01 and 1000000 by default. When either is non-zero the variant counts are recomputed from the full pairs file before Bonferroni correction, which matters because a correction taken over too wide a window, or over many low-frequency variants, overstates the number of independent tests. Set both to 0 to skip the recount and use the counts as given.

  • --pvalue-cutoff: 0.05 by default. Pairs above it are dropped before assembly to keep the object small; the per-gene minimum variant is always retained so the Bonferroni minimum stays exact.

  • --fdr-threshold: 0.05 by default, the threshold for the global significance call.

  • --study, --context, --genome: labels stamped onto the assembled QtlSumStats object, study / context / hg38 by default.

  • --af-col, --pvalue-col, --molecular-id-col: the column names to read, af / pvalue / molecular_trait_object_id by default.

  • --[no-]enable-archive: off by default. When on, the bulky TensorQTL intermediates are moved out of the working directory for book-keeping or deletion.

Output

  • {output-dir}/{cwd basename}.qtl_association_postprocessing.rds - the consolidated QtlSumStats object holding the surviving xQTLs together with the --study, --context and --genome labels. This is the only file named in the workflow’s output: statement.

  • {output-dir}/{cwd basename}.qtl_association_postprocessing.cis_regional.fdr.tsv.gz - the per-gene regional FDR table.

Both are named from the basename of --cwd, so the example below writes tensorqtl_cis.qtl_association_postprocessing.rds and tensorqtl_cis.qtl_association_postprocessing.cis_regional.fdr.tsv.gz into output/qtlpp.

No example output ships for this step. The *.cis_regional.*.fdr.gz and *_regional_significance.* files sitting alongside the inputs in output/tensorqtl_cis were written by an earlier version of this interface and carry names the workflow no longer produces.

Minimal Working Example

The workflow globs --cwd for its inputs rather than taking file arguments, so it is pointed straight at the TensorQTL scan directory.

Timing: TBD (on toy dataset)

Command Interface

usage: sos run pipeline/qtl_association_postprocessing.ipynb
               [workflow_name | -t targets] [options] [workflow_options]
  workflow_name:        Single or combined workflows defined in this script
  targets:              One or more targets to generate
  options:              Single-hyphen sos parameters (see "sos run -h" for details)
  workflow_options:     Double-hyphen workflow-specific parameters

Workflows:
  default

Global Workflow Options:
  --cwd . (as path)
  --modular-script-dir VAL (as path, required)
                        code/script dir that holds the pecotmr_integration
                        wrappers
  --output-dir VAL (as path, required)
  --sub-dir . (as path)
  --study study
                        labels for the assembled QtlSumStats
  --context context
  --genome hg38
  --maf-cutoff 0.01 (as float)
  --cis-window 1000000 (as int)
  --af-col af
  --pvalue-col pvalue
  --molecular-id-col 'molecular_trait_object_id'
  --pvalue-cutoff 0.05 (as float)
                        drop pairs with p above this before assembling (keeps
                        the object small; the per-gene min variant is always
                        retained so the Bonferroni min is exact)
  --fdr-threshold 0.05 (as float)
  --regional-pattern 'cis_qtl[.]regional[.]tsv[.]gz$'
                        list.files() regex patterns to locate the inputs in the
                        work dir
  --qtl-pattern 'cis_qtl[.]pairs[.]tsv[.]gz$'
  --n-variants-suffix 'cis_n_variants_stats[.]tsv[.]gz$'
  --[no-]enable-archive (default to False)

Sections
  default:

Workflow implementation

The cells below are the unmodified SoS workflow definition that the example above calls.

References
  1. Huang, Q. Q., Ritchie, S. C., Brozynska, M., & Inouye, M. (2018). Power, false discovery rate and Winner’s Curse in eQTL studies. Nucleic Acids Research, 46(22), e133–e133. 10.1093/nar/gky780