afquery 0.2.2__tar.gz → 0.3.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {afquery-0.2.2 → afquery-0.3.0}/.github/workflows/ci.yml +1 -0
- afquery-0.3.0/.github/workflows/docs.yml +52 -0
- {afquery-0.2.2 → afquery-0.3.0}/.github/workflows/release.yml +29 -56
- {afquery-0.2.2 → afquery-0.3.0}/.gitignore +1 -0
- afquery-0.3.0/CONTRIBUTING.md +35 -0
- {afquery-0.2.2 → afquery-0.3.0}/PKG-INFO +1 -1
- afquery-0.3.0/benchmarks/.gitignore +20 -0
- afquery-0.3.0/benchmarks/INSTALL.md +141 -0
- afquery-0.3.0/benchmarks/README.md +172 -0
- afquery-0.3.0/benchmarks/Snakefile +103 -0
- afquery-0.3.0/benchmarks/capture_kit/.gitignore +15 -0
- afquery-0.3.0/benchmarks/capture_kit/01a_assign_samples.py +130 -0
- afquery-0.3.0/benchmarks/capture_kit/01b_write_manifests.py +86 -0
- afquery-0.3.0/benchmarks/capture_kit/02_build_databases.py +115 -0
- afquery-0.3.0/benchmarks/capture_kit/03_compute_metrics.py +312 -0
- afquery-0.3.0/benchmarks/capture_kit/04_classify_acmg.py +199 -0
- afquery-0.3.0/benchmarks/capture_kit/05_plot_figures.py +401 -0
- afquery-0.3.0/benchmarks/capture_kit/README.md +190 -0
- afquery-0.3.0/benchmarks/capture_kit/Snakefile +225 -0
- afquery-0.3.0/benchmarks/capture_kit/__init__.py +0 -0
- afquery-0.3.0/benchmarks/capture_kit/beds/SureSelect_v5.bed +5060 -0
- afquery-0.3.0/benchmarks/capture_kit/beds/SureSelect_v6.bed +5479 -0
- afquery-0.3.0/benchmarks/capture_kit/beds/SureSelect_v7.bed +4598 -0
- afquery-0.3.0/benchmarks/capture_kit/config.py +84 -0
- afquery-0.3.0/benchmarks/config.yaml +21 -0
- afquery-0.3.0/benchmarks/envs/benchmark.yaml +31 -0
- afquery-0.3.0/benchmarks/performance/.gitignore +17 -0
- afquery-0.3.0/benchmarks/performance/01_prepare_data.py +248 -0
- afquery-0.3.0/benchmarks/performance/02_query_scaling.py +188 -0
- afquery-0.3.0/benchmarks/performance/03_build.py +236 -0
- afquery-0.3.0/benchmarks/performance/04_annotate.py +190 -0
- afquery-0.3.0/benchmarks/performance/05_vs_bcftools.py +500 -0
- afquery-0.3.0/benchmarks/performance/06_plot.py +379 -0
- afquery-0.3.0/benchmarks/performance/README.md +162 -0
- afquery-0.3.0/benchmarks/performance/Snakefile +464 -0
- afquery-0.3.0/benchmarks/performance/collect_annotate.py +82 -0
- afquery-0.3.0/benchmarks/performance/collect_bcftools.py +33 -0
- afquery-0.3.0/benchmarks/performance/collect_build_perf.py +83 -0
- afquery-0.3.0/benchmarks/performance/collect_prepare.py +39 -0
- afquery-0.3.0/benchmarks/performance/collect_query_scaling.py +30 -0
- afquery-0.3.0/benchmarks/performance/config.py +90 -0
- afquery-0.3.0/benchmarks/performance/config_smoke.py +12 -0
- afquery-0.3.0/benchmarks/shared/__init__.py +1 -0
- afquery-0.3.0/benchmarks/shared/config.py +53 -0
- afquery-0.3.0/benchmarks/shared/rules/download_1kg.smk +138 -0
- afquery-0.3.0/benchmarks/shared/utils.py +104 -0
- afquery-0.3.0/docs/advanced/coverage-evidence.md +192 -0
- {afquery-0.2.2 → afquery-0.3.0}/docs/faq.md +13 -0
- {afquery-0.2.2 → afquery-0.3.0}/docs/getting-started/preprocessing.md +1 -0
- {afquery-0.2.2 → afquery-0.3.0}/docs/getting-started/understanding-output.md +7 -4
- {afquery-0.2.2 → afquery-0.3.0}/docs/guides/annotate-vcf.md +1 -0
- {afquery-0.2.2 → afquery-0.3.0}/docs/guides/create-database.md +39 -0
- {afquery-0.2.2 → afquery-0.3.0}/docs/guides/dump-export.md +7 -4
- {afquery-0.2.2 → afquery-0.3.0}/docs/guides/query.md +38 -4
- {afquery-0.2.2 → afquery-0.3.0}/docs/guides/update-database.md +22 -0
- {afquery-0.2.2 → afquery-0.3.0}/docs/guides/variant-info.md +1 -0
- {afquery-0.2.2 → afquery-0.3.0}/docs/reference/cli.md +24 -1
- {afquery-0.2.2 → afquery-0.3.0}/docs/reference/glossary.md +4 -0
- {afquery-0.2.2 → afquery-0.3.0}/docs/reference/python-api.md +24 -7
- {afquery-0.2.2 → afquery-0.3.0}/mkdocs.yml +4 -1
- {afquery-0.2.2 → afquery-0.3.0}/recipes/afquery/meta.yaml +5 -11
- {afquery-0.2.2 → afquery-0.3.0}/resources/normalize_vcf.sh +1 -1
- afquery-0.3.0/src/afquery/_version.py +24 -0
- {afquery-0.2.2 → afquery-0.3.0}/src/afquery/annotate.py +46 -22
- {afquery-0.2.2 → afquery-0.3.0}/src/afquery/cli.py +57 -8
- {afquery-0.2.2 → afquery-0.3.0}/src/afquery/database.py +39 -9
- {afquery-0.2.2 → afquery-0.3.0}/src/afquery/dump.py +32 -14
- {afquery-0.2.2 → afquery-0.3.0}/src/afquery/models.py +12 -2
- {afquery-0.2.2 → afquery-0.3.0}/src/afquery/preprocess/__init__.py +34 -3
- {afquery-0.2.2 → afquery-0.3.0}/src/afquery/preprocess/build.py +159 -21
- {afquery-0.2.2 → afquery-0.3.0}/src/afquery/preprocess/compact.py +28 -8
- {afquery-0.2.2 → afquery-0.3.0}/src/afquery/preprocess/ingest.py +47 -0
- {afquery-0.2.2 → afquery-0.3.0}/src/afquery/preprocess/synth.py +1 -1
- {afquery-0.2.2 → afquery-0.3.0}/src/afquery/preprocess/update.py +150 -26
- {afquery-0.2.2 → afquery-0.3.0}/src/afquery/query.py +205 -32
- {afquery-0.2.2 → afquery-0.3.0}/tests/conftest.py +17 -12
- {afquery-0.2.2 → afquery-0.3.0}/tests/test_haploid_stats.py +5 -2
- afquery-0.3.0/tests/test_no_coverage.py +299 -0
- {afquery-0.2.2 → afquery-0.3.0}/tests/test_preprocess.py +5 -1
- {afquery-0.2.2 → afquery-0.3.0}/tests/test_variant_info.py +78 -1
- afquery-0.2.2/.github/workflows/docs.yml +0 -38
- afquery-0.2.2/src/afquery/_version.py +0 -34
- {afquery-0.2.2 → afquery-0.3.0}/.dockerignore +0 -0
- {afquery-0.2.2 → afquery-0.3.0}/Dockerfile +0 -0
- {afquery-0.2.2 → afquery-0.3.0}/LICENSE +0 -0
- {afquery-0.2.2 → afquery-0.3.0}/README.md +0 -0
- {afquery-0.2.2 → afquery-0.3.0}/docs/advanced/benchmarking.md +0 -0
- {afquery-0.2.2 → afquery-0.3.0}/docs/advanced/debugging-results.md +0 -0
- {afquery-0.2.2 → afquery-0.3.0}/docs/advanced/filter-pass-tracking.md +0 -0
- {afquery-0.2.2 → afquery-0.3.0}/docs/advanced/multi-cohort-strategies.md +0 -0
- {afquery-0.2.2 → afquery-0.3.0}/docs/advanced/performance.md +0 -0
- {afquery-0.2.2 → afquery-0.3.0}/docs/advanced/pipeline-integration.md +0 -0
- {afquery-0.2.2 → afquery-0.3.0}/docs/advanced/ploidy-and-sex-chroms.md +0 -0
- {afquery-0.2.2 → afquery-0.3.0}/docs/assets/img/gap2_mixed_technologies.png +0 -0
- {afquery-0.2.2 → afquery-0.3.0}/docs/getting-started/concepts.md +0 -0
- {afquery-0.2.2 → afquery-0.3.0}/docs/getting-started/installation.md +0 -0
- {afquery-0.2.2 → afquery-0.3.0}/docs/getting-started/motivation.md +0 -0
- {afquery-0.2.2 → afquery-0.3.0}/docs/getting-started/quickstart.md +0 -0
- {afquery-0.2.2 → afquery-0.3.0}/docs/getting-started/tutorial.md +0 -0
- {afquery-0.2.2 → afquery-0.3.0}/docs/guides/manifest-format.md +0 -0
- {afquery-0.2.2 → afquery-0.3.0}/docs/guides/sample-filtering.md +0 -0
- {afquery-0.2.2 → afquery-0.3.0}/docs/index.md +0 -0
- {afquery-0.2.2 → afquery-0.3.0}/docs/reference/data-model.md +0 -0
- {afquery-0.2.2 → afquery-0.3.0}/docs/scripts/gen_gap2_figure.py +0 -0
- {afquery-0.2.2 → afquery-0.3.0}/docs/stylesheets/extra.css +0 -0
- {afquery-0.2.2 → afquery-0.3.0}/docs/troubleshooting.md +0 -0
- {afquery-0.2.2 → afquery-0.3.0}/docs/use-cases/acmg-use-cases.md +0 -0
- {afquery-0.2.2 → afquery-0.3.0}/docs/use-cases/clinical-prioritization.md +0 -0
- {afquery-0.2.2 → afquery-0.3.0}/docs/use-cases/cohort-stratification.md +0 -0
- {afquery-0.2.2 → afquery-0.3.0}/docs/use-cases/population-specific-af.md +0 -0
- {afquery-0.2.2 → afquery-0.3.0}/docs/use-cases/pseudo-controls.md +0 -0
- {afquery-0.2.2 → afquery-0.3.0}/docs/use-cases/sex-specific-af.md +0 -0
- {afquery-0.2.2 → afquery-0.3.0}/docs/use-cases/technology-integration.md +0 -0
- {afquery-0.2.2 → afquery-0.3.0}/examples/demo/README.md +0 -0
- {afquery-0.2.2 → afquery-0.3.0}/examples/demo/create_demo_data.py +0 -0
- {afquery-0.2.2 → afquery-0.3.0}/pyproject.toml +0 -0
- {afquery-0.2.2 → afquery-0.3.0}/src/afquery/__init__.py +0 -0
- {afquery-0.2.2 → afquery-0.3.0}/src/afquery/benchmark.py +0 -0
- {afquery-0.2.2 → afquery-0.3.0}/src/afquery/bitmaps.py +0 -0
- {afquery-0.2.2 → afquery-0.3.0}/src/afquery/capture.py +0 -0
- {afquery-0.2.2 → afquery-0.3.0}/src/afquery/cli.pyr +0 -0
- {afquery-0.2.2 → afquery-0.3.0}/src/afquery/constants.py +0 -0
- {afquery-0.2.2 → afquery-0.3.0}/src/afquery/ploidy.py +0 -0
- {afquery-0.2.2 → afquery-0.3.0}/src/afquery/preprocess/manifest.py +0 -0
- {afquery-0.2.2 → afquery-0.3.0}/src/afquery/preprocess/regions.py +0 -0
- {afquery-0.2.2 → afquery-0.3.0}/src/afquery/variant_info.py +0 -0
- {afquery-0.2.2 → afquery-0.3.0}/tests/data/annotate_input.vcf +0 -0
- {afquery-0.2.2 → afquery-0.3.0}/tests/data/annotate_multi_bucket.vcf +0 -0
- {afquery-0.2.2 → afquery-0.3.0}/tests/data/annotate_multi_chrom.vcf +0 -0
- {afquery-0.2.2 → afquery-0.3.0}/tests/data/beds/wes_kit_a.bed +0 -0
- {afquery-0.2.2 → afquery-0.3.0}/tests/data/beds/wes_kit_b.bed +0 -0
- {afquery-0.2.2 → afquery-0.3.0}/tests/data/expected_results.json +0 -0
- {afquery-0.2.2 → afquery-0.3.0}/tests/data/manifest.tsv +0 -0
- {afquery-0.2.2 → afquery-0.3.0}/tests/data/vcfs/S00.vcf +0 -0
- {afquery-0.2.2 → afquery-0.3.0}/tests/data/vcfs/S01.vcf +0 -0
- {afquery-0.2.2 → afquery-0.3.0}/tests/data/vcfs/S02.vcf +0 -0
- {afquery-0.2.2 → afquery-0.3.0}/tests/data/vcfs/S03.vcf +0 -0
- {afquery-0.2.2 → afquery-0.3.0}/tests/data/vcfs/S04.vcf +0 -0
- {afquery-0.2.2 → afquery-0.3.0}/tests/data/vcfs/S05.vcf +0 -0
- {afquery-0.2.2 → afquery-0.3.0}/tests/data/vcfs/S06.vcf +0 -0
- {afquery-0.2.2 → afquery-0.3.0}/tests/data/vcfs/S07.vcf +0 -0
- {afquery-0.2.2 → afquery-0.3.0}/tests/data/vcfs/S08.vcf +0 -0
- {afquery-0.2.2 → afquery-0.3.0}/tests/data/vcfs/S09.vcf +0 -0
- {afquery-0.2.2 → afquery-0.3.0}/tests/test_annotate.py +0 -0
- {afquery-0.2.2 → afquery-0.3.0}/tests/test_batch.py +0 -0
- {afquery-0.2.2 → afquery-0.3.0}/tests/test_benchmark.py +0 -0
- {afquery-0.2.2 → afquery-0.3.0}/tests/test_bitmaps.py +0 -0
- {afquery-0.2.2 → afquery-0.3.0}/tests/test_capture.py +0 -0
- {afquery-0.2.2 → afquery-0.3.0}/tests/test_cli.py +0 -0
- {afquery-0.2.2 → afquery-0.3.0}/tests/test_cli_docs_consistency.py +0 -0
- {afquery-0.2.2 → afquery-0.3.0}/tests/test_compact.py +0 -0
- {afquery-0.2.2 → afquery-0.3.0}/tests/test_constants.py +0 -0
- {afquery-0.2.2 → afquery-0.3.0}/tests/test_dump.py +0 -0
- {afquery-0.2.2 → afquery-0.3.0}/tests/test_info.py +0 -0
- {afquery-0.2.2 → afquery-0.3.0}/tests/test_pass_filter.py +0 -0
- {afquery-0.2.2 → afquery-0.3.0}/tests/test_ploidy.py +0 -0
- {afquery-0.2.2 → afquery-0.3.0}/tests/test_query.py +0 -0
- {afquery-0.2.2 → afquery-0.3.0}/tests/test_sample_filter.py +0 -0
- {afquery-0.2.2 → afquery-0.3.0}/tests/test_synth.py +0 -0
- {afquery-0.2.2 → afquery-0.3.0}/tests/test_synthetic_stats.py +0 -0
- {afquery-0.2.2 → afquery-0.3.0}/tests/test_update.py +0 -0
- {afquery-0.2.2 → afquery-0.3.0}/tests/test_update_metadata.py +0 -0
- {afquery-0.2.2 → afquery-0.3.0}/tests/test_warnings.py +0 -0
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
name: Deploy Documentation
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [master]
|
|
6
|
+
paths:
|
|
7
|
+
- 'docs/**'
|
|
8
|
+
- 'mkdocs.yml'
|
|
9
|
+
- 'src/**'
|
|
10
|
+
workflow_dispatch:
|
|
11
|
+
inputs:
|
|
12
|
+
bootstrap:
|
|
13
|
+
description: 'Wipe gh-pages before deploying (one-time when migrating from mkdocs gh-deploy to mike)'
|
|
14
|
+
type: boolean
|
|
15
|
+
default: false
|
|
16
|
+
|
|
17
|
+
permissions:
|
|
18
|
+
contents: write
|
|
19
|
+
|
|
20
|
+
concurrency:
|
|
21
|
+
group: pages
|
|
22
|
+
cancel-in-progress: false
|
|
23
|
+
|
|
24
|
+
jobs:
|
|
25
|
+
deploy:
|
|
26
|
+
runs-on: ubuntu-latest
|
|
27
|
+
steps:
|
|
28
|
+
- uses: actions/checkout@v4
|
|
29
|
+
with:
|
|
30
|
+
fetch-depth: 0
|
|
31
|
+
|
|
32
|
+
- uses: actions/setup-python@v5
|
|
33
|
+
with:
|
|
34
|
+
python-version: '3.11'
|
|
35
|
+
|
|
36
|
+
- name: Install docs dependencies
|
|
37
|
+
run: pip install -e ".[docs]"
|
|
38
|
+
|
|
39
|
+
- name: Configure git for mike
|
|
40
|
+
run: |
|
|
41
|
+
git config --global user.name "github-actions[bot]"
|
|
42
|
+
git config --global user.email "github-actions[bot]@users.noreply.github.com"
|
|
43
|
+
|
|
44
|
+
- name: Fetch gh-pages
|
|
45
|
+
run: git fetch origin gh-pages --depth=1 || true
|
|
46
|
+
|
|
47
|
+
- name: Bootstrap gh-pages (wipe old flat-deploy content)
|
|
48
|
+
if: ${{ inputs.bootstrap == true }}
|
|
49
|
+
run: mike delete --all --push --allow-empty
|
|
50
|
+
|
|
51
|
+
- name: Deploy dev docs with mike
|
|
52
|
+
run: mike deploy --push --update-aliases dev
|
|
@@ -127,66 +127,39 @@ jobs:
|
|
|
127
127
|
ghcr.io/${{ github.repository }}:${{ steps.version.outputs.version }}
|
|
128
128
|
ghcr.io/${{ github.repository }}:latest
|
|
129
129
|
|
|
130
|
-
# ── 6.
|
|
131
|
-
|
|
132
|
-
needs:
|
|
130
|
+
# ── 6. Versioned docs → gh-pages via mike (final releases only) ──────
|
|
131
|
+
docs:
|
|
132
|
+
needs: test
|
|
133
|
+
if: ${{ !contains(github.ref_name, 'rc') }}
|
|
133
134
|
runs-on: ubuntu-latest
|
|
134
|
-
|
|
135
|
+
permissions:
|
|
136
|
+
contents: write
|
|
135
137
|
steps:
|
|
136
|
-
-
|
|
137
|
-
run: echo "VERSION=${GITHUB_REF#refs/tags/v}" >> $GITHUB_ENV
|
|
138
|
-
|
|
139
|
-
- name: Fetch SHA256 from PyPI
|
|
140
|
-
run: |
|
|
141
|
-
SHA256=$(curl -s https://pypi.org/pypi/afquery/${VERSION}/json \
|
|
142
|
-
| jq -r '.urls[] | select(.packagetype=="sdist") | .digests.sha256')
|
|
143
|
-
echo "SHA256=${SHA256}" >> $GITHUB_ENV
|
|
144
|
-
|
|
145
|
-
- name: Get fork owner
|
|
146
|
-
env:
|
|
147
|
-
GH_TOKEN: ${{ secrets.GH_PAT }}
|
|
148
|
-
run: echo "FORK_USER=$(gh api user --jq .login)" >> $GITHUB_ENV
|
|
149
|
-
|
|
150
|
-
- name: Sync fork with upstream
|
|
151
|
-
env:
|
|
152
|
-
GH_TOKEN: ${{ secrets.GH_PAT }}
|
|
153
|
-
run: gh repo sync ${FORK_USER}/bioconda-recipes --source bioconda/bioconda-recipes --branch master
|
|
154
|
-
|
|
155
|
-
- name: Checkout afquery repo
|
|
156
|
-
uses: actions/checkout@v4
|
|
138
|
+
- uses: actions/checkout@v4
|
|
157
139
|
with:
|
|
158
|
-
|
|
140
|
+
fetch-depth: 0
|
|
159
141
|
|
|
160
|
-
-
|
|
161
|
-
uses: actions/checkout@v4
|
|
142
|
+
- uses: actions/setup-python@v5
|
|
162
143
|
with:
|
|
163
|
-
|
|
164
|
-
token: ${{ secrets.GH_PAT }}
|
|
165
|
-
path: bioconda-recipes
|
|
144
|
+
python-version: "3.11"
|
|
166
145
|
|
|
167
|
-
- name:
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
cp ../afquery-repo/recipes/afquery/meta.yaml recipes/afquery/meta.yaml
|
|
172
|
-
sed -i "s/^{% set version = .* %}/{% set version = \"${VERSION}\" %}/" recipes/afquery/meta.yaml
|
|
173
|
-
sed -i "s/sha256: .*/sha256: ${SHA256}/" recipes/afquery/meta.yaml
|
|
174
|
-
sed -i "s/^ number: .*/ number: 0/" recipes/afquery/meta.yaml
|
|
175
|
-
|
|
176
|
-
- name: Create pull request
|
|
177
|
-
working-directory: bioconda-recipes
|
|
178
|
-
env:
|
|
179
|
-
GH_TOKEN: ${{ secrets.GH_PAT }}
|
|
146
|
+
- name: Install docs dependencies
|
|
147
|
+
run: pip install -e ".[docs]"
|
|
148
|
+
|
|
149
|
+
- name: Configure git for mike
|
|
180
150
|
run: |
|
|
181
|
-
git config user.name "github-actions[bot]"
|
|
182
|
-
git config user.email "github-actions[bot]@users.noreply.github.com"
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
151
|
+
git config --global user.name "github-actions[bot]"
|
|
152
|
+
git config --global user.email "github-actions[bot]@users.noreply.github.com"
|
|
153
|
+
|
|
154
|
+
- name: Fetch gh-pages
|
|
155
|
+
run: git fetch origin gh-pages --depth=1 || true
|
|
156
|
+
|
|
157
|
+
- name: Extract version
|
|
158
|
+
id: version
|
|
159
|
+
run: echo "version=${GITHUB_REF_NAME#v}" >> $GITHUB_OUTPUT
|
|
160
|
+
|
|
161
|
+
- name: Deploy versioned docs and update latest alias
|
|
162
|
+
run: mike deploy --push --update-aliases ${{ steps.version.outputs.version }} latest
|
|
163
|
+
|
|
164
|
+
- name: Set default to latest
|
|
165
|
+
run: mike set-default --push latest
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# Contributing
|
|
2
|
+
|
|
3
|
+
## Documentation deployment
|
|
4
|
+
|
|
5
|
+
The published site at <https://dlopez-bioinfo.github.io/afquery/> is built with [MkDocs](https://www.mkdocs.org/) (Material theme) and versioned with [mike](https://github.com/jimporter/mike). Source content lives under `docs/` and is configured by `mkdocs.yml`.
|
|
6
|
+
|
|
7
|
+
### CI workflows
|
|
8
|
+
|
|
9
|
+
| Workflow | Trigger | What it does |
|
|
10
|
+
|---|---|---|
|
|
11
|
+
| `.github/workflows/docs.yml` | push to `master` (paths: `docs/**`, `mkdocs.yml`, `src/**`) and manual dispatch | `mike deploy --push --update-aliases dev` — publishes the working master under the `dev` alias |
|
|
12
|
+
| `.github/workflows/release.yml` (job `docs`) | push of a `v*` tag (non-`rc`) | `mike deploy --push --update-aliases <version> latest` followed by `mike set-default --push latest` — publishes the tagged version, points `latest` at it, and makes `latest` the site root |
|
|
13
|
+
|
|
14
|
+
### Cutting a release
|
|
15
|
+
|
|
16
|
+
Tag the commit with a [PEP 440](https://peps.python.org/pep-0440/)-compatible version prefixed with `v` (e.g. `v0.3.0`) and push the tag. The `release.yml` workflow handles PyPI, the GitHub release, the Docker image, and the versioned docs deploy. Pre-release tags (anything containing `rc`) skip Docker and docs publishing.
|
|
17
|
+
|
|
18
|
+
### Local preview
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
pip install -e ".[docs]"
|
|
22
|
+
|
|
23
|
+
# Plain build — no versioning, fastest iteration on content
|
|
24
|
+
mkdocs serve
|
|
25
|
+
|
|
26
|
+
# Versioned layout — only after running mike deploy locally at least once
|
|
27
|
+
mike deploy 0.0.0-test dev # writes to local gh-pages branch (no push)
|
|
28
|
+
mike serve # serves the gh-pages branch with version selector
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
To discard local mike state: `git branch -D gh-pages`.
|
|
32
|
+
|
|
33
|
+
### Migrating from a flat `mkdocs gh-deploy` (one-time)
|
|
34
|
+
|
|
35
|
+
When `gh-pages` still contains content from the previous flat deploy, the first `mike deploy` will leave the old root-level files in place. To wipe `gh-pages` clean before deploying, manually trigger the *Deploy Documentation* workflow with `bootstrap: true`. This runs `mike delete --all --push --allow-empty` before deploying, leaving only the versioned layout (`versions.json` + version subdirectories + redirector at root).
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# Benchmark data directories (large, external)
|
|
2
|
+
# Users create these as needed via config.py
|
|
3
|
+
|
|
4
|
+
# pycache
|
|
5
|
+
__pycache__/
|
|
6
|
+
*.pyc
|
|
7
|
+
.pytest_cache/
|
|
8
|
+
|
|
9
|
+
# benchmarking results
|
|
10
|
+
results
|
|
11
|
+
.snakemake
|
|
12
|
+
|
|
13
|
+
# Snakemake log directory
|
|
14
|
+
logs/
|
|
15
|
+
|
|
16
|
+
# Default data directory
|
|
17
|
+
.results/
|
|
18
|
+
|
|
19
|
+
# Local test run logs
|
|
20
|
+
smoke_test.log
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
# Installation Guide for AFQuery Benchmarks
|
|
2
|
+
|
|
3
|
+
This guide covers installing benchmark dependencies in your existing `afquery_bench` micromamba environment.
|
|
4
|
+
See [README.md](./README.md) for the recommended setup using `envs/benchmark.yaml`.
|
|
5
|
+
|
|
6
|
+
## Option 1: Using conda environment file (Recommended)
|
|
7
|
+
|
|
8
|
+
The easiest way is to create the pre-configured environment:
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
cd benchmarks/
|
|
12
|
+
micromamba env create -f envs/benchmark.yaml
|
|
13
|
+
micromamba activate afquery_bench
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
Then skip to [Running Benchmarks](#running-benchmarks).
|
|
17
|
+
|
|
18
|
+
## Option 2: Manual installation
|
|
19
|
+
|
|
20
|
+
If you prefer to install into an existing environment, install dependencies into your `snakemake` micromamba environment:
|
|
21
|
+
|
|
22
|
+
### Prerequisites
|
|
23
|
+
|
|
24
|
+
You must have:
|
|
25
|
+
- Snakemake ≥ 8 installed in a micromamba environment named `snakemake`
|
|
26
|
+
|
|
27
|
+
If not, install it:
|
|
28
|
+
```bash
|
|
29
|
+
micromamba install -n snakemake snakemake
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
### Install all dependencies at once
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
micromamba run -n snakemake mamba install \
|
|
36
|
+
-c bioconda -c conda-forge \
|
|
37
|
+
bcftools bedtools matplotlib numpy pandas scipy wget \
|
|
38
|
+
&& micromamba run -n snakemake pip install afquery
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
### Or step-by-step installation
|
|
42
|
+
|
|
43
|
+
#### 1. Bioinformatics tools
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
micromamba run -n snakemake mamba install \
|
|
47
|
+
-c bioconda -c conda-forge \
|
|
48
|
+
bcftools bedtools wget
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
#### 2. Python scientific libraries
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
micromamba run -n snakemake mamba install \
|
|
55
|
+
-c conda-forge \
|
|
56
|
+
numpy pandas scipy matplotlib
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
#### 3. AFQuery
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
micromamba run -n snakemake pip install afquery
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## Verification
|
|
66
|
+
|
|
67
|
+
Test that everything is installed:
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
# Test bcftools
|
|
71
|
+
micromamba run -n afquery_bench bcftools --version
|
|
72
|
+
|
|
73
|
+
# Test Python imports
|
|
74
|
+
micromamba run -n afquery_bench python -c "
|
|
75
|
+
import afquery
|
|
76
|
+
import numpy
|
|
77
|
+
import pandas
|
|
78
|
+
import scipy
|
|
79
|
+
import matplotlib
|
|
80
|
+
print('All dependencies OK!')
|
|
81
|
+
"
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
Expected output:
|
|
85
|
+
```
|
|
86
|
+
bcftools >=1.17
|
|
87
|
+
All dependencies OK!
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
## Running Benchmarks
|
|
91
|
+
|
|
92
|
+
Once dependencies are installed and the environment is active:
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
cd benchmarks/
|
|
96
|
+
micromamba activate afquery_bench
|
|
97
|
+
snakemake --cores 52 all
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
Or run with conda activation:
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
micromamba run -n afquery_bench snakemake --cores 52 all
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
See [README.md](./README.md) for more options (smoke test, dry-run, etc.).
|
|
107
|
+
|
|
108
|
+
## Troubleshooting
|
|
109
|
+
|
|
110
|
+
### `afquery` import fails
|
|
111
|
+
|
|
112
|
+
Verify the installation:
|
|
113
|
+
```bash
|
|
114
|
+
micromamba run -n afquery_bench pip show afquery
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
If not found, reinstall:
|
|
118
|
+
```bash
|
|
119
|
+
micromamba run -n afquery_bench pip install --upgrade afquery
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### Missing Python packages
|
|
123
|
+
|
|
124
|
+
Check installed packages:
|
|
125
|
+
```bash
|
|
126
|
+
micromamba run -n afquery_bench pip list | grep -E "numpy|pandas|scipy|matplotlib"
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
If any are missing, re-run the mamba install commands above.
|
|
130
|
+
|
|
131
|
+
### `bcftools` not found
|
|
132
|
+
|
|
133
|
+
Verify bcftools is installed:
|
|
134
|
+
```bash
|
|
135
|
+
micromamba run -n afquery_bench which bcftools
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
If not found, install it:
|
|
139
|
+
```bash
|
|
140
|
+
micromamba run -n afquery_bench mamba install -c bioconda bcftools
|
|
141
|
+
```
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
# AFQuery Benchmarking Suite
|
|
2
|
+
|
|
3
|
+
This directory contains benchmarking experiments for AFQuery.
|
|
4
|
+
|
|
5
|
+
## Benchmark Categories
|
|
6
|
+
|
|
7
|
+
### 1. [Performance Benchmarks](./performance/README.md)
|
|
8
|
+
|
|
9
|
+
Core performance characterization across 4 experiments:
|
|
10
|
+
|
|
11
|
+
- **Experiment 1:** Query latency scaling with sample count
|
|
12
|
+
- **Experiment 2:** Build time scaling with parallelism
|
|
13
|
+
- **Experiment 3:** VCF annotation throughput
|
|
14
|
+
- **Experiment 4:** AFQuery vs. bcftools comparison
|
|
15
|
+
|
|
16
|
+
Uses real 1000 Genomes data (chr22) and synthetic datasets (1K-50K samples).
|
|
17
|
+
|
|
18
|
+
### 2. [Capture Kit Benchmark](./capture_kit/README.md)
|
|
19
|
+
|
|
20
|
+
Capture kit mixing impact on allele frequency classification:
|
|
21
|
+
|
|
22
|
+
- Sample generation with three Agilent SureSelect kits (v5, v6, v7)
|
|
23
|
+
- Three mixing scenarios (balanced, skewed, extreme)
|
|
24
|
+
- ACMG classification discordance analysis with directional error decomposition (toward-pathogenic vs. toward-benign)
|
|
25
|
+
- Coverage overlap metrics
|
|
26
|
+
|
|
27
|
+
## Prerequisites
|
|
28
|
+
|
|
29
|
+
- micromamba with `snakemake` environment already set up (with Snakemake >= 8 and SLURM executor plugin)
|
|
30
|
+
- Benchmark dependencies installed in the `snakemake` environment (see Environment Setup section)
|
|
31
|
+
- `/usr/bin/time` (GNU time) for memory profiling -- should be available on most Linux systems
|
|
32
|
+
- ~200 GB disk space for all 1KG data and databases
|
|
33
|
+
|
|
34
|
+
## Environment Setup
|
|
35
|
+
|
|
36
|
+
All benchmark dependencies are installed in the `snakemake` micromamba environment.
|
|
37
|
+
|
|
38
|
+
### Install dependencies
|
|
39
|
+
|
|
40
|
+
The benchmark requires:
|
|
41
|
+
- External bioinformatics tools: bcftools >= 1.18, bedtools, bgzip/tabix
|
|
42
|
+
- Python packages: pandas, numpy, scipy, matplotlib
|
|
43
|
+
- AFQuery and its dependencies: pyroaring, pyarrow, duckdb, cyvcf2, pyranges, click, tqdm
|
|
44
|
+
|
|
45
|
+
Install them in your `snakemake` environment:
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
micromamba run -n snakemake mamba install \
|
|
49
|
+
-c bioconda -c conda-forge \
|
|
50
|
+
bcftools bedtools matplotlib numpy pandas scipy wget \
|
|
51
|
+
&& micromamba run -n snakemake \
|
|
52
|
+
pip install -e <path_to_afquery_repo>
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### Verify
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
micromamba run -n snakemake bcftools --version
|
|
59
|
+
micromamba run -n snakemake python -c "import afquery; print('OK')"
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## Running the Benchmarks
|
|
63
|
+
|
|
64
|
+
All commands below are run from the `benchmarks/` directory. Activate the `snakemake` environment first:
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
micromamba activate snakemake
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
Then use Snakemake with `--cores 52` to utilize all local CPU cores:
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
# Run everything (both benchmarks)
|
|
74
|
+
snakemake --cores 52 all
|
|
75
|
+
|
|
76
|
+
# Run individual benchmarks
|
|
77
|
+
snakemake --cores 52 performance_all
|
|
78
|
+
snakemake --cores 52 capture_kit_all
|
|
79
|
+
|
|
80
|
+
# Download 1KG data only (prerequisite for both)
|
|
81
|
+
snakemake --cores 52 download_1kg
|
|
82
|
+
|
|
83
|
+
# Dry run (preview what will execute)
|
|
84
|
+
snakemake --cores 52 --dry-run all
|
|
85
|
+
|
|
86
|
+
# Smoke test (fast validation with small parameter scales)
|
|
87
|
+
snakemake --cores 52 --config smoke_test=true all
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
### Smoke Test
|
|
91
|
+
|
|
92
|
+
The `smoke_test=true` flag reduces both pipelines to minimal scales for fast validation:
|
|
93
|
+
|
|
94
|
+
- **Performance:** 1 synthetic scale (1K), 1 1KG subset (500), 2 thread counts (1, 4), 1 rep
|
|
95
|
+
- **Capture kit:** 50 samples, balanced scenario only
|
|
96
|
+
|
|
97
|
+
This is useful for verifying pipeline logic without waiting for full-scale runs.
|
|
98
|
+
|
|
99
|
+
### Resuming after a failure
|
|
100
|
+
|
|
101
|
+
Snakemake uses output files to track completed steps. Re-running any command above will automatically skip steps whose outputs already exist and resume from the first incomplete step.
|
|
102
|
+
|
|
103
|
+
## Directory Structure
|
|
104
|
+
|
|
105
|
+
```
|
|
106
|
+
benchmarks/
|
|
107
|
+
├── Snakefile # Root pipeline (includes both benchmarks)
|
|
108
|
+
├── config.yaml # Global parameters (data_dir, threads, etc.)
|
|
109
|
+
├── envs/
|
|
110
|
+
│ └── benchmark.yaml # conda/micromamba environment spec
|
|
111
|
+
├── shared/
|
|
112
|
+
│ ├── __init__.py
|
|
113
|
+
│ ├── config.py # Common constants: DATA_DIR, 1KG paths, SEED
|
|
114
|
+
│ ├── utils.py # Common helpers: stats, time_ms, save_figure, WONG_COLORS
|
|
115
|
+
│ └── rules/
|
|
116
|
+
│ └── download_1kg.smk # Shared Snakemake rules: download + split 1KG
|
|
117
|
+
├── performance/
|
|
118
|
+
│ ├── Snakefile # Performance-specific rules
|
|
119
|
+
│ ├── config.py # Performance parameters (scales, reps, thread counts)
|
|
120
|
+
│ ├── config_smoke.py # Minimal config for quick smoke testing
|
|
121
|
+
│ ├── 01_prepare_data.py
|
|
122
|
+
│ ├── 02_query_scaling.py
|
|
123
|
+
│ ├── 03_build.py
|
|
124
|
+
│ ├── 04_annotate.py
|
|
125
|
+
│ ├── 05_vs_bcftools.py
|
|
126
|
+
│ ├── 06_plot.py
|
|
127
|
+
│ ├── collect_prepare.py # Aggregation scripts
|
|
128
|
+
│ ├── collect_query_scaling.py
|
|
129
|
+
│ ├── collect_build_perf.py
|
|
130
|
+
│ ├── collect_annotate.py
|
|
131
|
+
│ └── collect_bcftools.py
|
|
132
|
+
└── capture_kit/
|
|
133
|
+
├── Snakefile # Capture kit-specific rules
|
|
134
|
+
├── config.py # Capture kit parameters (scenarios, ACMG thresholds)
|
|
135
|
+
├── beds/ # Agilent SureSelect BED files (chr22, committed)
|
|
136
|
+
│ ├── SureSelect_v5.bed
|
|
137
|
+
│ ├── SureSelect_v6.bed
|
|
138
|
+
│ └── SureSelect_v7.bed
|
|
139
|
+
├── 01a_assign_samples.py # Subsample & assign technologies
|
|
140
|
+
├── 01b_write_manifests.py # Write AFQuery manifest TSVs
|
|
141
|
+
├── 02_build_databases.py
|
|
142
|
+
├── 03_compute_metrics.py
|
|
143
|
+
├── 04_classify_acmg.py
|
|
144
|
+
└── 05_plot_figures.py
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
## Configuration
|
|
148
|
+
|
|
149
|
+
Edit `config.yaml` to set the data directory and global parameters:
|
|
150
|
+
|
|
151
|
+
```yaml
|
|
152
|
+
data_dir: "/path/to/bench_data" # needs ~200 GB free
|
|
153
|
+
build_memory: "8GB" # DuckDB memory per worker
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
The data directory can also be set via the `AFQUERY_BENCH_DATA` environment variable.
|
|
157
|
+
|
|
158
|
+
## Known Limitations
|
|
159
|
+
|
|
160
|
+
- **Chromosome scope:** All benchmarks use only chromosome 22 (1000 Genomes Phase 3). Chr22 is one of the smallest autosomes (~51 Mb) and coverage patterns may not be representative of genome-wide behavior. The paper's methods section should discuss generalizability.
|
|
161
|
+
- **Synthetic data for scaling:** Query scaling experiments (1K-50K samples) use synthetic data. Allele frequency spectra and LD patterns differ from real population data.
|
|
162
|
+
- **Capture kits:** The capture kit benchmark uses only Agilent SureSelect kits (v5, v6, v7). Other vendors (Illumina, Roche) and custom panels are not evaluated.
|
|
163
|
+
|
|
164
|
+
## Reproducibility
|
|
165
|
+
|
|
166
|
+
All random seeds are fixed in `shared/config.py` (SEED = 42).
|
|
167
|
+
Re-running with the same configuration produces identical results within timing noise.
|
|
168
|
+
|
|
169
|
+
## References
|
|
170
|
+
|
|
171
|
+
- Weber LM et al. (2019). Essential guidelines for computational method benchmarking. *Genome Biology* 20:125. DOI: 10.1186/s13059-019-1738-8
|
|
172
|
+
- Auton A et al. (2015). A global reference for human genetic variation. *Nature* 526:68-74. DOI: 10.1038/nature15393
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
"""Unified benchmark pipeline for AFQuery.
|
|
2
|
+
|
|
3
|
+
Usage (run from benchmarks/ directory):
|
|
4
|
+
# All benchmarks
|
|
5
|
+
snakemake --cores 52 all
|
|
6
|
+
|
|
7
|
+
# Only performance benchmark
|
|
8
|
+
snakemake --cores 52 performance_all
|
|
9
|
+
|
|
10
|
+
# Only capture kit benchmark
|
|
11
|
+
snakemake --cores 52 capture_kit_all
|
|
12
|
+
|
|
13
|
+
# Only download 1KG data
|
|
14
|
+
snakemake --cores 52 download_1kg
|
|
15
|
+
|
|
16
|
+
# Dry run (preview rules to execute)
|
|
17
|
+
snakemake --cores 52 --dry-run all
|
|
18
|
+
|
|
19
|
+
# Smoke test (fast validation with small scales)
|
|
20
|
+
snakemake --cores 52 --config smoke_test=true all
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
import sys
|
|
24
|
+
from pathlib import Path
|
|
25
|
+
|
|
26
|
+
# Make shared/ importable from within Snakemake rules
|
|
27
|
+
_bench = Path(workflow.basedir)
|
|
28
|
+
sys.path.insert(0, str(_bench))
|
|
29
|
+
|
|
30
|
+
from shared.config import ( # noqa: E402
|
|
31
|
+
DATA_DIR,
|
|
32
|
+
ONEKG_DIR,
|
|
33
|
+
ONEKG_MANIFEST,
|
|
34
|
+
SEED,
|
|
35
|
+
)
|
|
36
|
+
|
|
37
|
+
# ---------------------------------------------------------------------------
|
|
38
|
+
# Global settings
|
|
39
|
+
# ---------------------------------------------------------------------------
|
|
40
|
+
configfile: "config.yaml"
|
|
41
|
+
|
|
42
|
+
# NOTE: conda env management is DISABLED. Dependencies are installed manually
|
|
43
|
+
# in the snakemake environment. Conda path normalization is no longer needed.
|
|
44
|
+
# if config.get("conda_env_file"):
|
|
45
|
+
# _conda_env = Path(config["conda_env_file"])
|
|
46
|
+
# if not _conda_env.is_absolute():
|
|
47
|
+
# config["conda_env_file"] = str((_bench / _conda_env).resolve())
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
# Guard: data_dir must be set
|
|
52
|
+
if not config.get("data_dir", "").strip():
|
|
53
|
+
raise WorkflowError(
|
|
54
|
+
"config.yaml: 'data_dir' is not set. "
|
|
55
|
+
"Edit config.yaml or pass --config data_dir=/path/to/data"
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
# Override DATA_DIR from config if provided
|
|
59
|
+
if config.get("data_dir"):
|
|
60
|
+
import shared.config as _sc
|
|
61
|
+
_sc._set_data_dir(Path(config["data_dir"]))
|
|
62
|
+
DATA_DIR = _sc.DATA_DIR
|
|
63
|
+
ONEKG_DIR = _sc.ONEKG_DIR
|
|
64
|
+
ONEKG_MANIFEST = _sc.ONEKG_MANIFEST
|
|
65
|
+
|
|
66
|
+
# Propagate the resolved DATA_DIR to all child processes via environment.
|
|
67
|
+
# Python scripts import shared.config fresh in each subprocess; without this
|
|
68
|
+
# they fall back to the default Path(".results") and cannot find pipeline outputs.
|
|
69
|
+
import os as _os
|
|
70
|
+
_os.environ["AFQUERY_BENCH_DATA"] = str(DATA_DIR.resolve())
|
|
71
|
+
if config.get("smoke_test"):
|
|
72
|
+
_os.environ["AFQUERY_BENCH_SMOKE"] = "1"
|
|
73
|
+
|
|
74
|
+
# Export constants to sub-Snakefiles via globals
|
|
75
|
+
workflow._globals = {} # not needed; sub-files access via import
|
|
76
|
+
|
|
77
|
+
# ---------------------------------------------------------------------------
|
|
78
|
+
# Create log directories before any rule runs (Snakemake does not auto-create
|
|
79
|
+
# log dirs, unlike output dirs).
|
|
80
|
+
# ---------------------------------------------------------------------------
|
|
81
|
+
onstart:
|
|
82
|
+
import os
|
|
83
|
+
for subdir in ["performance", "capture_kit"]:
|
|
84
|
+
os.makedirs(f"logs/{subdir}", exist_ok=True)
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
# ---------------------------------------------------------------------------
|
|
88
|
+
# Include sub-pipelines
|
|
89
|
+
# ---------------------------------------------------------------------------
|
|
90
|
+
include: "shared/rules/download_1kg.smk"
|
|
91
|
+
include: "performance/Snakefile"
|
|
92
|
+
include: "capture_kit/Snakefile"
|
|
93
|
+
|
|
94
|
+
# ---------------------------------------------------------------------------
|
|
95
|
+
# Top-level targets
|
|
96
|
+
# ---------------------------------------------------------------------------
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
rule all:
|
|
100
|
+
"""Run both benchmarks end-to-end."""
|
|
101
|
+
input:
|
|
102
|
+
rules.performance_all.output,
|
|
103
|
+
rules.capture_kit_all.output,
|