S4-dispatched per-region fine-mapping entry point that
replaces the deprecated univariateAnalysisPipeline,
multivariateAnalysisPipeline, rssAnalysisPipeline,
and susieRssPipeline pipelines. Accepts:
a
QtlDatasetfor individual-level cohort fits (per-context / per-trait univariate SuSiE; joint multi-trait or multi-context mvSuSiE; joint multi-trait fSuSiE per context);a
MultiStudyQtlDatasetwhich recurses through each embeddedQtlDatasetper study and processes the optional embeddedQtlSumStatsvia the sumstat method;a
QtlSumStatsfor per-trait SuSiE-RSS fits and per-(study, trait) multi-context mvSuSiE-RSS fits;a
GwasSumStatsfor per-(study, LD-block) SuSiE-RSS fine-mapping (used byqtlEnrichmentPipelinedownstream).
Method tokens are unified across input classes; auto-dispatch picks the individual-level vs RSS implementation based on the input class. The supported tokens are:
susiesusieR::susiewithunmappable_effects = "none"on individual-level input;susieR::susie_rss(same) on RSS.susieInfunmappable_effects = "inf"variant of the same.susieAshunmappable_effects = "ash"variant of the same.serSingle-effect regression via
susieR::susie_seron summary statistics (z,n); LD-free (noR, noL), so distinct fromsusiewithL = 1. Sumstat input only (QtlSumStats/GwasSumStats, or the sumstat side of aMultiStudyQtlDataset); rejected on individual-levelQtlDataset.mvsusiemvsusieR::mvsusieon individual- level input (requires multi-trait OR multi-context Y),mvsusieR::mvsusie_rsson sumstat input (requires multi-context within a single (study, trait) group). Errors onGwasSumStatsinput.fsusiefsusieR::susiFjoint multi-trait fit per context. Individual-level only; errors on any SumStats input.mrmashAlways rejected here.
mr.mashis a TWAS weight-oriented method and lives intwasWeightsPipeline.
Usage
fineMappingPipeline(data, ...)
# S4 method for class 'QtlDataset'
fineMappingPipeline(
data,
methods,
contexts = NULL,
traitId = NULL,
region = NULL,
cisWindow = NULL,
genotypeFilterParam = GenotypeFilterParam(),
jointRegions = FALSE,
jointSpecification = NULL,
initializeWithSusieInf = TRUE,
credibleSetParam = CredibleSetParam(),
fineMappingResult = NULL,
crossValidationParam = CrossValidationParam(),
residualizationParam = ResidualizationParam(),
signalScreenParam = SignalScreenParam(),
usePCA = FALSE,
nPCs = 10L,
seed = NULL,
mrmashPrior = NULL,
dataDrivenPriorWeightsCutoff = 1e-10,
naAction = c("drop", "impute"),
verbose = 1,
fitRetention = c("slim", "full"),
dataType = NULL
)
# S4 method for class 'MultiStudyQtlDataset'
fineMappingPipeline(
data,
methods,
contexts = NULL,
traitId = NULL,
region = NULL,
cisWindow = NULL,
genotypeFilterParam = GenotypeFilterParam(),
panelFilterParam = PanelFilterParam(),
jointRegions = FALSE,
jointSpecification = NULL,
initializeWithSusieInf = TRUE,
credibleSetParam = CredibleSetParam(),
fineMappingResult = NULL,
mrmashPrior = NULL,
dataDrivenPriorWeightsCutoff = 1e-10,
crossValidationParam = CrossValidationParam(),
residualizationParam = ResidualizationParam(),
signalScreenParam = SignalScreenParam(),
susieRssParam = SusieRssParam(),
usePCA = FALSE,
nPCs = 10L,
seed = NULL,
naAction = c("drop", "impute"),
verbose = 1,
fitRetention = c("slim", "full"),
dataType = NULL
)
# S4 method for class 'QtlSumStats'
fineMappingPipeline(
data,
methods,
contexts = NULL,
traitId = NULL,
jointSpecification = NULL,
initializeWithSusieInf = TRUE,
credibleSetParam = CredibleSetParam(),
fineMappingResult = NULL,
mrmashPrior = NULL,
dataDrivenPriorWeightsCutoff = 1e-10,
verbose = 1,
fitRetention = c("slim", "full"),
susieRssParam = SusieRssParam(),
panelFilterParam = PanelFilterParam(),
crossValidationParam = CrossValidationParam(),
residualizationParam = ResidualizationParam(),
dataType = NULL
)
# S4 method for class 'GwasSumStats'
fineMappingPipeline(
data,
methods,
initializeWithSusieInf = TRUE,
credibleSetParam = CredibleSetParam(),
fineMappingResult = NULL,
verbose = 1,
fitRetention = c("slim", "full"),
susieRssParam = SusieRssParam(),
panelFilterParam = PanelFilterParam(),
crossValidationParam = CrossValidationParam(),
residualizationParam = ResidualizationParam(),
dataType = NULL
)Arguments
- data
A
QtlDataset,MultiStudyQtlDataset,QtlSumStats, orGwasSumStats.- ...
Reserved for future per-method arguments.
- methods
Method specification. Accepts either:
A character vector of method tokens, e.g.
c("susie", "susieInf", "mvsusie")(any subset ofc("susie", "susieInf", "susieAsh", "mvsusie", "fsusie"), subject to per-class compatibility).A
FineMappingMethodsParamrecord keyed by method token, where each value is a list of per-method kwargs to splice into the underlying fitter, e.g.FineMappingMethodsParam(susie = list(L = 1, refine = FALSE), mvsusie = list(max_iter = 500)). Each entry is checked against the engine that receives it. Mirrors the convention oftwasWeightsPipeline'smethodsargument. User-supplied kwargs override the capability-table defaults and any base / chained args set by the pipeline (e.g. you can overridemodel_initeven when fitting from a susieInf chain).
- contexts
Optional context selection;
NULL(the default) uses every context. A character vector applies to every study: a context no study has is an error, and one only some studies lack is skipped for those, with a warning. A list keyed by study name picks each study's contexts separately (list(A = "liver")); studies it does not name keep all of theirs.- traitId
Optional trait selection;
NULL(the default) uses every trait, or those overlappingregionwhen one is given. A character vector applies to every study. A list keyed by study name picks each study's traits separately (list(A = "ENSG1")), and a study's entry may itself be a list keyed by context (list(A = list(brain = "ENSG1"))). Studies and contexts the list does not name keep all of their traits. A joint fit spanning a study's contexts uses every trait selected in any of them, minus the (context, trait) pairs a per-context entry leaves out.- region
Optional variant window for QtlDataset trait selection: a
GRanges, a"chr:start-end"string, or a one-row data.frame withchrom/start/end. Mutually exclusive withtraitId.- cisWindow
For QtlDataset: cis-window (bp) around each trait's genomic position when extracting variants. Required when
traitIdis supplied. Mutually exclusive withregion.- genotypeFilterParam
Per-call overrides of the
QtlDataset's own filters, built withGenotypeFilterParam. A field left unset keeps the dataset's construct-time value, soGenotypeFilterParam(mafCutoff = 0)pins the cutoff at zero whileGenotypeFilterParam()changes nothing. Applies to theQtlDatasetmethod only.- jointRegions
For QtlDataset with a multi-range
region:FALSE(default) fits each range independently and merges the per-range results into one entry per (study, context, trait, method) – the mergedsusieFitis a named list of per-region fits and credible-set labels are renumbered to stay unique.TRUEconcatenates the ranges' genotypes into one joint fit. Ignored for a single-range / cis (traitId+cisWindow) request.- jointSpecification
Optional joint-fit specification saying which axes
mvsusie/fsusiefit across. When NULL (the default) they fit across traits if the input has two or more, else across contexts. Otherwise give a character vector of axes (one spec) or a list of specs. A spec is a character vector drawn from"study","context"and"trait", orlist(axes = <axes>, scope = <named list>), wherescope(keysstudy,context,trait) limits the fit to the listed values, each of which must exist indata. A list-form spec always goes inside the outer list, even on its own. Other methods run per (study, context, trait) as usual. The"study"axis needs summary statistics: it is rejected on aQtlDataset, and on aMultiStudyQtlDatasetonly the summary-statistics studies take part.- initializeWithSusieInf
Logical. When
susieInfis inmethodsalongsidesusieand/orsusieAsh, whether the SuSiE-inf fit initialises the chained downstream method(s). DefaultTRUE. A choice between methods rather than a property of the credible sets, which is why it stands alone.- credibleSetParam
How credible sets are built and reported, built with
CredibleSetParam:coverage(default0.95),secondaryCoverage(c(0.7, 0.5)),signalCutoff(the PIP cutoff for top-loci selection,0.025),minAbsCorr(0.8) andmedianAbsCorr(NULL) for purity — a set is kept if it passes either, OR-logic — andincludeAllCs.perCsColumnsadds the per-set variant-level columns totopLoci.maxNumSingleEffectsbounds how many credible sets can exist (default10) andmaxNumSingleEffectsGreedythe greedy loop of the SuSiE-inf refinement.Most fields are read by
postprocessFinemappingFits, so a stored fit can be re-summarized under different settings without refitting.maxNumSingleEffects/maxNumSingleEffectsGreedyare the exception: they are seeded onto each SuSiE-family token's own arguments, so changing them needs a refit.- fineMappingResult
Optional existing
QtlFineMappingResultorGwasFineMappingResultto use as a resume cache; tuples already present are not refit.- crossValidationParam
Cross-validation settings, built with
CrossValidationParam:folds(default0, no CV),numThreadsfor the per-fold refits, andsamplePartitionto reuse a fixed partition across methods. Whenfolds > 1each method is refit on every fold's training samples and used to predict the held-out ones; the partition, the out-of-fold predictions and the metrics are stored on eachFineMappingRow'scvResultslot.fitFullData = FALSEkeeps only that: each row carries itscvResultand no full-data fit, variants or top loci. AfineMappingResultresume cache is only reused where it carries what the run asks for – a full-data fit unless the run is cross-validation-only, and acvResultwhen the run cross-validates – and the other tuples are refit.Cross-validation holds out samples, so it is not possible on
QtlSumStats/GwasSumStatsinput. Those methods accept the argument and error if it is set, rather than accepting it and quietly returning results that were never cross-validated.maxVariantsandweightMethodsare honoured bytwasWeightsPipelineonly and are ignored here.- residualizationParam
Covariate residualization settings, built with
ResidualizationParam:phenotypeCovariatesandgenotypeCovariatesname which covariates to regress out (NULL, the default, uses every available one), andresidualizePhenotype/residualizeGenotypeturn each side off.Only meaningful for
QtlDataset/MultiStudyQtlDatasetinput. AQtlSumStats/GwasSumStatsrun has no covariates to regress out, so the bundle is ignored there rather than refused — unlikecrossValidationParam, which errors. Residualization is on by default, so refusing a non-default value would reject the default bundle; CV is off by default, so a non-default value there is an explicit request for something the input cannot do.The marginal univariate effects stored on each
FineMappingRowobey the same choice as the SuSiE fit itself — they are computed against the same residualizedX/Y.- signalScreenParam
Individual-level single-effect (SER) pre-screen applied to each residualized
(X, y)block before a full fit, built withSignalScreenParam. A susie model withL = 1is fit and the block is skipped unless the chosen metric exceeds its cutoff:pip— the maximum PIP. A negative cutoff uses the adaptive3 / nVariantsthreshold.absZ— the maximum marginal|z|, which needs no fit.bf/logBf— the maximum per-variant Bayes factor or log Bayes factor from theL = 1fit.
Only one metric may be enabled, which
SignalScreenParamenforces when you build it. Unset (the default) screens nothing. The summary-statistics analog lives insummaryStatsQc.- usePCA
Logical (length 1). Individual-level data only: a
QtlDataset, or theQtlDatasetcomponents of aMultiStudyQtlDataset. WhenTRUE(defaultFALSE), each multi-trait context's PCA-reduced phenotype is fine-mapped with univariate SuSiE on its top principal components (ports the legacyfsusie.Rsusie_on_top_pc). Each PC becomes a pseudo-trait row keyedtrait = "topPC\{i\}",method = "susie". Single-trait contexts have no PCA and are skipped.- nPCs
Integer (length 1). Individual-level data only. Caps the number of top principal components fine-mapped per context when
usePCA = TRUE(default10). The effective count ismin(nPCs, usable traits).- seed
Optional integer. When non-NULL,
withr::local_seed(seed)is called at the start of the call for reproducible fits; the global RNG state is restored on return. DefaultNULL(no seeding).- mrmashPrior
Optional
TwasWeightsfrom a previous mr.mashtwasWeightsPipelinerun, mined for the mvSuSiE data-driven prior: the retainedmrmashfits supply the prior mixture, and their cross-validation payload supplies honest per-fold priors.NULLuses the canonical prior instead.- dataDrivenPriorWeightsCutoff
Numeric or
NULL. Cutoff below which data-driven prior weights are zeroed;NULLdisables the cutoff.- naAction
Character. How to handle missing values in the extracted phenotype/genotype data.
- verbose
Verbosity (0 silent, 1 default). Default
1.- fitRetention
How much of each fit the
susieFitslot keeps:"slim"(default) a trimmed view, or"full"the wholesusie()return, sosusieFit()and non-default-coveragecredibleSets()queries can read the full posterior matrices. The per-varianttopLocitable is fully populated either way — its per-credible-set columns are governed bycredibleSetParam'sperCsColumns, not by this.- dataType
Optional assay / modality label for the phenotype the fit was run on (
"bulk_rnaseq","methylation"), recorded as a per-row provenance column and published byexportToBed/exportToVcf.NULL(default) omits the column. It cannot be derived — the input carries the values, not what they measure.- panelFilterParam
LD-reference-panel filters for the summary-statistics and GWAS methods, built with
PanelFilterParam. See Panel filters on the RSS path above.- susieRssParam
Summary-statistics solver settings for
QtlSumStats/GwasSumStatsinput, built withSusieRssParam:serFallback(defaultFALSE) — after each multi-effect SuSiE-RSS fit, read susieR's finite-sample R diagnostics and, whenfit$R_finite_diagnostics$R_reliability_flagisTRUE, report the single-effect (ser_model) result for that region instead.keepFullFit(default"fallback") — which pre-fallback multi-effect fits to retain: only the regions that fell back,"all", or"none". Meaningful only withserFallback. The retained fit and the decision are read viasusieFit(res)$multiEffectFit,$R_reliability_flagand$serFallbackUsed.rFinite— finite-sample size for susieR'sR_finitecorrection.NULL(default) uses susieR's own, except when a finite/EB mode is active (serFallbackorrMismatch != "none"), where it falls back to the LD panel'snSamples(ldReference).rMismatch(default"none") — LD-mismatch correction forwarded asR_mismatch: also"eb"or"eb_mix".control— options forsusieR::susie_rss_control(), built withSusieRssControlOptions. This was a bare named list, which meant a misspelled option was dropped silently; the constructor checks the names against that function's live formals.
Value
A QtlFineMappingResult keyed by (study, context,
trait, method) – for GwasSumStats input, a
GwasFineMappingResult keyed by (study, method) and range.
The ldReference slot is set automatically: NULL
for individual-level (QtlDataset / all-individual-level
MultiStudyQtlDataset) fits, the input's ldReference for RSS-derived
fits.
Chained initialisation
When susieInf is requested alongside
susie and/or susieAsh and
initializeWithSusieInf = TRUE (the default), the SuSiE-inf fit
is computed
first and used as initialisation
for the SuSiE / SuSiE-ash fits, mirroring the legacy
univariateAnalysisPipeline / susieRssPipeline chained init
behaviour. SuSiE-inf is dropped from the final result when the caller did
not explicitly request it (only used as init).
QC contract
All QtlSumStats and GwasSumStats inputs
must have been QC'd via summaryStatsQc; the pipeline errors
on inputs where length(qcInfo(x)) == 0L. summaryStatsQc
also drops variants absent from the ldReference, so by the time
per-entry processing runs every variant is guaranteed to be present in the
LD panel and a local LD matrix can be built with
extractBlockGenotypes + computeLd("sample").
Optional resume cache
Supplying fineMappingResult of an
existing fine-mapping result skips re-fitting any (study,
context, trait, method) tuple that already has a matching row; cached
entries are merged with the newly-fit entries in the returned collection.
Intentional behaviours dropped from the pre-stub pipelines
The four pre-stub pipelines (univariateAnalysisPipeline /
multivariateAnalysisPipeline / rssAnalysisPipeline /
susieRssPipeline) carried several behaviours that are
deliberately not ported here:
TWAS weights computation (
twasWeights = TRUEpath): lives intwasWeightsPipelinenow.Filtering knobs (now
genotypeFilterParam/panelFilterParam,ldReferenceMetaFile): individual- level QC lives on theQtlDatasetconstructor; sumstat QC lives insummaryStatsQc(). No filtering happens inside this pipeline.Diagnostic re-analysis paths (
singleEffect/bayesianConditionalRegressionreanalysis on the RSS path): these are not exposed as dedicated method tokens. Callers who want a single-effect fit can request it via per-method kwargs, e.g.methods = FineMappingMethodsParam(susie = list(L = 1))methodsparameter).loadRssDataand explicitldReferenceMetaFilearguments: the newQtlSumStats/GwasSumStatscarry the (already-QC'd) sumstats andldReferencedirectly.Verbose
methodNamesuffixing (e.g."susie_rss_NO_QC","susie_rss_SLALOM_RAISS_imputed"): the method column on the returned collection carries the bare token ("susie","susieInf","mvsusie", ...) only. QC provenance is recorded on the sumstats'qcInfo.An entry that
summaryStatsQc(pipCutoffToSkip = ...)screened out (recorded asqcInfo$entryAudit[[i]]$pipScreenSkipped, and emptied to 0 variants) is skipped, not fit: it produces no row and a message with the screen reason. An all-screened collection yields a valid empty result rather than an error.
Panel filters on the RSS path
On QtlSumStats /
GwasSumStats input there is no genotype matrix to filter, so
panelFilterParam's mafCutoff / macCutoff /
imissCutoff are measured against the LD reference panel
instead: a variant whose panel genotypes fall below the cutoffs is
dropped before the z-scores and LD matrix are built. The thresholds mean
the same thing as genotypeFilterParam's on the QtlDataset
path (MAC is converted to a MAF equivalent and the stricter of the two
applies), so one number carries across input types. The defaults filter
nothing.
This discards observed variants, unlike
summaryStatsQc(raissParam = ...), which only bounds which variants
RAISS will impute. Use it when the panel cannot support the LD estimate a
rare variant would need.
The genotype scale
Individual-level genotypes reach every fit centred and scaled to unit
variance, so a posterior effect — which is the prediction weight — is
on the standardized scale, and the published
weight_standardized records it. That scaling belongs to the
QtlDataset accessors, not to this pipeline: it is
residualizedGenotypes that applies it, governed by
ResidualizationParam(scaleResiduals = ) per call with the
dataset's own scaleResiduals slot as the default. One
mechanism, one place, shared with twasWeightsPipeline and
colocboostPipeline. An RSS fit needs nothing done: its
likelihood is written in standardized units already.
It is what makes weights comparable across methods. Measured through
pecotmr's own entry points, every TWAS method returns coefficients on the
scale of the X it was given, and the DPR samplers are not even
scale-equivariant — a uniform rescale of X changes their fit
rather than just its units. One input scale removes the question, and it
is the scale the LD correlations and z-scores behind a TWAS Z are already
on.
Examples
data(qtlDatasetExample)
fineMappingPipeline(qtlDatasetExample, methods = "susie", cisWindow = 1e6)
#> Fitting susie for (context='brain', trait='ENSG_example') ...
#> QtlFineMappingResult: 1 entries
#> 1 studies, 1 contexts, 1 traits, 1 methods
#> LD reference: NULL (individual-level fit)