Known Limitations and Gotchas¶
Most CREDTOOLS runs fail for simple reasons: a placeholder in loci_list.txt,
an LD file that was never created, or an external tool that is not on PATH.
This page lists the current traps so you can check them before starting a long
run.
Read this before a genome-wide run
Run the first locus end to end before launching hundreds of loci. It is much cheaper to find a schema or environment problem on one locus.
Current Limits¶
| Area | What happens now | What to do |
|---|---|---|
| VCF LD extraction | credtools chunk --ld-format vcf is accepted by the CLI, but VCF LD extraction is not implemented. |
Use PLINK .bed/.bim/.fam references and keep --ld-format plink. |
| Custom chunks | --custom-chunks reads chr, start, and end, then assigns the internal ancestry label custom. This may not match your real population labels. |
For now, prefer an explicit loci_list.txt when you already know the regions. |
| Auto-created sample size | chunk can write sample_size=50000 as a placeholder in loci_list.txt. |
Replace it with the real cohort sample size before meta, qc, finemap, or pipeline. |
| Auto-created cohort label | chunk may set cohort equal to the ancestry label. |
Edit cohort if you need study-level labels such as UKBB, MVP, or BBJ. |
| Direct chunk input | Passing raw file paths to chunk skips LD extraction because no ld_ref is available. |
Use a population config with ld_ref, run credtools prepare with a genotype config, or provide pre-generated LD files yourself. |
| ABF without LD | The ABF method itself can run without LD in Python, but the current CLI locus loader expects {prefix}.ld or {prefix}.ld.npz and a matching {prefix}.ldmap. |
Use the Python API for a true no-LD ABF run, or provide LD files for CLI workflows. |
| FINEMAP MAF | FINEMAP requires a MAF column after CREDTOOLS loads the locus. |
Make sure EAF is present so CREDTOOLS can derive MAF, or provide MAF in prepared inputs. |
| Multi-input tools | susiex, multisusie, and mesusie analyze all rows in a locus together. |
Keep rows for the same locus_id aligned to the same chromosome, start, and end. |
The loci_list.txt Check¶
Before running pipeline, open the generated loci list:
Check these columns first:
| Column | Check |
|---|---|
sample_size |
not the placeholder 50000 unless that is really correct |
popu |
matches the population label you want in output files |
cohort |
matches the study or cohort name you want in reports |
prefix |
points to files that actually exist |
Use a quick file check:
prefix=$(awk 'NR==2 {print $8}' work/chunks/loci_list.txt)
ls "${prefix}.sumstats.gz" "${prefix}.ld.npz" "${prefix}.ldmap.gz"
If this fails, fix the input files before running the full pipeline.
Custom Regions¶
Custom region files use this shape:
At the moment, this path is best for region discovery and manual inspection,
not for a fully automatic LD-prepared pipeline. If you already know the regions
and want a reliable production run, make a loci_list.txt directly:
locus_id chr start end popu cohort sample_size prefix
chr1_1000000_1500000 1 1000000 1500000 EUR UKBB 400000 data/EUR_UKBB_chr1_1000000_1500000
That direct loci list is the most explicit handoff into qc, finemap, and
pipeline.
Empty Results Are Not Always Errors¶
Most fine-mapping wrappers check whether any variant passes
--significant-threshold before doing expensive work. If no variant passes,
the result can be a valid empty credible set:
n_cs = 0- all PIPs set to zero
- no lead SNPs
This usually means the locus did not pass the significance threshold used for fine-mapping. It is different from a tool crash.
Native convergence metadata¶
The multi-ancestry wrappers expose a Boolean in their native CredibleSet result:
| Tool | Source of converged |
|---|---|
| Python SuSiE | Finite objective and 0 <= new - old < tol. |
| MultiSuSiE | The fit's converged field: guarded ELBO criterion, after the initial effect-zeroing period. The wrapper uses float64 inference. |
| SuSiEx | The native .cs file: FAIL means False; NULL or a valid, nonempty CS table means True. A missing, empty or malformed file raises an error. |
| MESuSiE | Actual adapter stopping plus two finite computed ELBO values satisfying 0 <= new - old < tol. The requested tolerance is honored. |
MESuSiE's initial -Inf and unused trailing NA entries are not computed
observations. Fewer than two computed values, internal missing values,
NaN/infinite values or a nonfinite difference produce False rather than a
default True. From v0.9.7, negative increments no longer count as convergence
in Python SuSiE, MultiSuSiE or the MESuSiE adapter. A substantial decrease is
warned about; a nonfinite computed objective fails the fit. This matches the
nonnegative ELBO convergence rule in recent susieR, not an absolute-difference
rule. It does not promise that all earlier ELBO steps were monotone.
MESuSiE defaults to covariance EM and retains the original Gaussian model.
From v0.9.8, the EM adapter evaluates the marginal likelihood with Cholesky
log determinants and computes multivariate posterior moments by latent
square-root conditioning, avoiding direct determinants and subtractive
posterior covariance cancellation. It rejects substantive negative prior
eigenvalues; only eigensolver-scale negative roundoff may be clipped to zero.
This does not project or repair LD. The native optimizer mode retains the
installed package's arithmetic as an explicit sensitivity control.
The R wrapper writes mesusie_status.tsv and mesusie_elbo.tsv
in its temporary directory; iteration counts and status are carried in the
native CredibleSet and its mesusie_runtime parameters. Inner EM updates
that exhaust the budget are counted separately and do not imply inner
convergence. The validated five-population INS comparison used fixed L=5;
order stability is not a claim about the true number of causal signals,
global optimality or validity under LD mismatch.
Runtime provenance also records gaussian_numerics (cholesky_latent or
native), blas_library, and requested OpenBLAS/thread environment values.
These are diagnostic settings, not a measurement of actual kernel dispatch or
thread use; absent environment values are explicitly labeled unset.
From v0.9.8, the EM kernel caches data invariant within each single-effect update and streams configuration-level sufficient moments using log-scaled weights. It reuses a Cholesky factor for the small covariance solves and log determinant; dimensions above five use generic Armadillo operations. No SNPs or configurations are pruned, and float64, the inner iteration/tolerance settings, eigenvalue floor, independent likelihood guard (absolute tolerance 1e-6) and outer stopping policy are unchanged. Algebraic equivalence does not imply bitwise equality: tests compare covariance/likelihood against the frozen v0.9.7 kernel, and application validation must also check PIPs, CS membership and convergence. Compilation overhead can dominate tiny fits, so compute-only benchmarks must not be read as cold-start wall-time guarantees.
For cross-host reproducibility on heterogeneous OpenBLAS CPUs, controlled
comparisons use one thread and a common supported OPENBLAS_CORETYPE (for
example, Nehalem). Thread count alone does not fix CPU-specific dispatch.
This is a testing/launch setting, not a global environment mutation or an
automatic backend setting imposed on users.
CS/PIP parsing and the existing empty_on_nonconvergence behavior are unchanged.
A corrected False may therefore activate that pre-existing setting for MESuSiE;
with the setting disabled, the native PIPs and CS remain available. These are
native-wrapper flags: this change does not add CLI output columns or repair
metadata propagation through later purity filtering/combination.
First Run Checklist¶
- Run one locus with
--log-file first_locus.log. - Confirm
pips.txt.gzandcredible_sets_summary.txt.gzare written. - Confirm
run_summary.loghasFailed: 0. - Plot one locus with
credtools plot. - Only then scale to all loci.