panicle 0.1.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.
Files changed (97) hide show
  1. panicle-0.1.0/CHANGELOG.md +60 -0
  2. panicle-0.1.0/LICENSE +21 -0
  3. panicle-0.1.0/MANIFEST.in +29 -0
  4. panicle-0.1.0/PKG-INFO +295 -0
  5. panicle-0.1.0/README.md +255 -0
  6. panicle-0.1.0/docs/README.md +183 -0
  7. panicle-0.1.0/docs/api_reference.md +582 -0
  8. panicle-0.1.0/docs/images/farmcpu_comparison_plots.png +0 -0
  9. panicle-0.1.0/docs/images/trait3_methods_comparison.png +0 -0
  10. panicle-0.1.0/docs/output_files.md +417 -0
  11. panicle-0.1.0/docs/quickstart.md +273 -0
  12. panicle-0.1.0/examples/01_basic_gwas.py +80 -0
  13. panicle-0.1.0/examples/02_mlm_with_structure.py +93 -0
  14. panicle-0.1.0/examples/04_with_covariates.py +111 -0
  15. panicle-0.1.0/examples/05_reading_results.py +267 -0
  16. panicle-0.1.0/examples/06_farmcpu_resampling.py +86 -0
  17. panicle-0.1.0/examples/EXAMPLE_DATA.md +101 -0
  18. panicle-0.1.0/examples/README.md +185 -0
  19. panicle-0.1.0/examples/example_covariates.csv +739 -0
  20. panicle-0.1.0/examples/example_phenotypes.csv +739 -0
  21. panicle-0.1.0/panicle/__init__.py +48 -0
  22. panicle-0.1.0/panicle/association/__init__.py +10 -0
  23. panicle-0.1.0/panicle/association/blink.py +1506 -0
  24. panicle-0.1.0/panicle/association/farmcpu.py +1222 -0
  25. panicle-0.1.0/panicle/association/farmcpu_resampling.py +383 -0
  26. panicle-0.1.0/panicle/association/glm.py +69 -0
  27. panicle-0.1.0/panicle/association/glm_fwl_qr.py +630 -0
  28. panicle-0.1.0/panicle/association/lrt.py +118 -0
  29. panicle-0.1.0/panicle/association/mlm.py +803 -0
  30. panicle-0.1.0/panicle/association/mlm_loco.py +303 -0
  31. panicle-0.1.0/panicle/cli/__init__.py +0 -0
  32. panicle-0.1.0/panicle/cli/utils.py +120 -0
  33. panicle-0.1.0/panicle/core/__init__.py +1 -0
  34. panicle-0.1.0/panicle/core/mvp.py +543 -0
  35. panicle-0.1.0/panicle/data/__init__.py +0 -0
  36. panicle-0.1.0/panicle/data/converters.py +10 -0
  37. panicle-0.1.0/panicle/data/io_utils.py +263 -0
  38. panicle-0.1.0/panicle/data/load_genotype_hapmap.py +262 -0
  39. panicle-0.1.0/panicle/data/load_genotype_plink.py +232 -0
  40. panicle-0.1.0/panicle/data/load_genotype_vcf.py +932 -0
  41. panicle-0.1.0/panicle/data/loaders.py +788 -0
  42. panicle-0.1.0/panicle/matrix/__init__.py +0 -0
  43. panicle-0.1.0/panicle/matrix/kinship.py +241 -0
  44. panicle-0.1.0/panicle/matrix/kinship_loco.py +338 -0
  45. panicle-0.1.0/panicle/matrix/pca.py +339 -0
  46. panicle-0.1.0/panicle/pipelines/__init__.py +0 -0
  47. panicle-0.1.0/panicle/pipelines/gwas.py +1216 -0
  48. panicle-0.1.0/panicle/py.typed +0 -0
  49. panicle-0.1.0/panicle/tools/__init__.py +1 -0
  50. panicle-0.1.0/panicle/tools/convert_genotype.py +107 -0
  51. panicle-0.1.0/panicle/utils/__init__.py +0 -0
  52. panicle-0.1.0/panicle/utils/compression.py +93 -0
  53. panicle-0.1.0/panicle/utils/data_types.py +653 -0
  54. panicle-0.1.0/panicle/utils/effective_tests.py +831 -0
  55. panicle-0.1.0/panicle/utils/memmap_utils.py +478 -0
  56. panicle-0.1.0/panicle/utils/perf.py +143 -0
  57. panicle-0.1.0/panicle/utils/stats.py +143 -0
  58. panicle-0.1.0/panicle/visualization/__init__.py +0 -0
  59. panicle-0.1.0/panicle/visualization/manhattan.py +1116 -0
  60. panicle-0.1.0/panicle.egg-info/PKG-INFO +295 -0
  61. panicle-0.1.0/panicle.egg-info/SOURCES.txt +95 -0
  62. panicle-0.1.0/panicle.egg-info/dependency_links.txt +1 -0
  63. panicle-0.1.0/panicle.egg-info/entry_points.txt +2 -0
  64. panicle-0.1.0/panicle.egg-info/requires.txt +17 -0
  65. panicle-0.1.0/panicle.egg-info/top_level.txt +1 -0
  66. panicle-0.1.0/pyproject.toml +66 -0
  67. panicle-0.1.0/scripts/calc_gblup_sorghum.py +101 -0
  68. panicle-0.1.0/scripts/debug_kinship.py +126 -0
  69. panicle-0.1.0/scripts/generate_performance_dataset.py +1330 -0
  70. panicle-0.1.0/scripts/plot_spats_vs_gblup.py +89 -0
  71. panicle-0.1.0/scripts/profile_manhattan_plot.py +27 -0
  72. panicle-0.1.0/scripts/profile_qq_plot.py +27 -0
  73. panicle-0.1.0/scripts/run_GWAS.py +219 -0
  74. panicle-0.1.0/scripts/run_farmcpu_v2.py +89 -0
  75. panicle-0.1.0/setup.cfg +4 -0
  76. panicle-0.1.0/tests/test_association_stats.py +94 -0
  77. panicle-0.1.0/tests/test_blink_and_farmcpu_unit.py +183 -0
  78. panicle-0.1.0/tests/test_blink_helpers.py +115 -0
  79. panicle-0.1.0/tests/test_cli_utils.py +67 -0
  80. panicle-0.1.0/tests/test_convert_genotype.py +143 -0
  81. panicle-0.1.0/tests/test_dynamic_int8_writer.py +45 -0
  82. panicle-0.1.0/tests/test_effective_tests.py +156 -0
  83. panicle-0.1.0/tests/test_farmcpu_resampling.py +156 -0
  84. panicle-0.1.0/tests/test_gwas_pipeline_integration.py +387 -0
  85. panicle-0.1.0/tests/test_load_genotype_plink_more.py +138 -0
  86. panicle-0.1.0/tests/test_loaders_genotype.py +109 -0
  87. panicle-0.1.0/tests/test_loaders_vcf_plink_hapmap.py +195 -0
  88. panicle-0.1.0/tests/test_loco_kinship.py +98 -0
  89. panicle-0.1.0/tests/test_lrt.py +32 -0
  90. panicle-0.1.0/tests/test_matrix_utils.py +89 -0
  91. panicle-0.1.0/tests/test_memmap_utils.py +72 -0
  92. panicle-0.1.0/tests/test_mlm_and_glm_paths.py +207 -0
  93. panicle-0.1.0/tests/test_mvp_core.py +133 -0
  94. panicle-0.1.0/tests/test_pca_additional.py +111 -0
  95. panicle-0.1.0/tests/test_stats_utils.py +60 -0
  96. panicle-0.1.0/tests/test_vcf_genotype_parsing.py +102 -0
  97. panicle-0.1.0/tests/test_visualization.py +175 -0
@@ -0,0 +1,60 @@
1
+ # Changelog
2
+
3
+ All notable changes to PANICLE will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [0.1.0] - 2026-01-25
9
+
10
+ ### Changed
11
+ - **Package rebranded from pyMVP to PANICLE** (Python Algorithms for Nucleotide-phenotype Inference and Chromosome-wide Locus Evaluation)
12
+ - All `MVP_*` functions renamed to `PANICLE_*` (e.g., `MVP_GLM` → `PANICLE_GLM`)
13
+ - Package name changed from `pymvp` to `panicle` in imports
14
+ - Cache file extensions changed from `.pymvp.*` to `.panicle.*`
15
+ - CLI command renamed from `pymvp-cache-genotype` to `panicle-cache-genotype`
16
+
17
+ ### Added
18
+ - Initial public release of PANICLE
19
+ - Core GWAS methods: GLM, MLM, FarmCPU, BLINK
20
+ - **Hybrid MLM method** combining Wald test screening with LRT refinement
21
+ - 2-3% runtime overhead vs standard MLM
22
+ - Orders of magnitude p-value improvement for significant associations
23
+ - High-level `GWASPipeline` API for streamlined workflows
24
+ - Multiple genotype format support:
25
+ - VCF/BCF with automatic binary caching (~26x faster loading)
26
+ - PLINK binary format (.bed/.bim/.fam)
27
+ - HapMap format
28
+ - CSV/TSV matrices
29
+ - Automatic population structure correction:
30
+ - Step-wise PCA calculation
31
+ - VanRaden kinship matrix computation
32
+ - Effective tests calculation for accurate Bonferroni correction
33
+ - Parallel execution of multiple GWAS methods
34
+ - Comprehensive visualization:
35
+ - Manhattan plots with decimated rendering
36
+ - QQ plots with genomic inflation factor
37
+ - Results comparison plots
38
+ - Command-line interface via `scripts/run_GWAS.py`
39
+ - Binary genotype caching tool: `panicle-cache-genotype`
40
+
41
+ ### Documentation
42
+ - Complete API reference for all classes and functions
43
+ - Quick start guide with 6 common scenarios
44
+ - Output file format specifications
45
+ - 5 runnable example scripts demonstrating different workflows
46
+ - Interactive Jupyter notebook for Hybrid MLM demonstration
47
+ - PDF report generator for publication-ready results
48
+ - Detailed algorithm documentation for Hybrid MLM method
49
+
50
+ ### Performance
51
+ - Vectorized VCF loading with cyvcf2 optimization
52
+ - Binary caching for instant subsequent loads (~1.5s)
53
+ - Numba JIT acceleration for computationally intensive operations
54
+ - 2-4x faster than R-based rMVP implementation
55
+
56
+ ### Dependencies
57
+ - Core: numpy, scipy, pandas, h5py, tables, statsmodels, scikit-learn, matplotlib, seaborn, tqdm, numba
58
+ - Optional: cyvcf2 (VCF support), bed-reader (PLINK support)
59
+
60
+ [0.1.0]: https://github.com/jschnable/PANICLE/releases/tag/v0.1.0
panicle-0.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 James Schnable
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,29 @@
1
+ # Include documentation
2
+ include README.md
3
+ include LICENSE
4
+ include CHANGELOG.md
5
+
6
+ # Include documentation directory
7
+ recursive-include docs *.md *.pdf *.ipynb *.png *.jpg
8
+ prune docs/__pycache__
9
+
10
+ # Include example scripts
11
+ recursive-include examples *.py *.md *.csv *.txt
12
+ prune examples/__pycache__
13
+
14
+ # Include scripts
15
+ recursive-include scripts *.py
16
+ prune scripts/__pycache__
17
+
18
+ # Exclude test data and large files
19
+ exclude sorghum_data/*
20
+ exclude sorghum_results*/*
21
+ exclude .gitignore
22
+
23
+ # Exclude development files
24
+ global-exclude *.pyc
25
+ global-exclude *.pyo
26
+ global-exclude __pycache__
27
+ global-exclude .DS_Store
28
+ global-exclude *.npy
29
+ global-exclude *.npz
panicle-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,295 @@
1
+ Metadata-Version: 2.4
2
+ Name: panicle
3
+ Version: 0.1.0
4
+ Summary: PANICLE: Python Algorithms for Nucleotide-phenotype Inference and Chromosome-wide Locus Evaluation - A comprehensive GWAS pipeline with Numba JIT acceleration
5
+ Author-email: "James C. Schnable" <james.schnable@gmail.com>
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/jschnable/PANICLE
8
+ Project-URL: Repository, https://github.com/jschnable/PANICLE
9
+ Project-URL: Documentation, https://github.com/jschnable/PANICLE/tree/master/docs
10
+ Project-URL: Issues, https://github.com/jschnable/PANICLE/issues
11
+ Project-URL: Changelog, https://github.com/jschnable/PANICLE/blob/master/CHANGELOG.md
12
+ Keywords: GWAS,genomics,bioinformatics,genetics,SNP,association,QTL,phenotype
13
+ Classifier: Development Status :: 3 - Alpha
14
+ Classifier: Intended Audience :: Science/Research
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3.9
17
+ Classifier: Programming Language :: Python :: 3.10
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Programming Language :: Python :: 3.13
21
+ Classifier: Topic :: Scientific/Engineering :: Bio-Informatics
22
+ Requires-Python: >=3.9
23
+ Description-Content-Type: text/markdown
24
+ License-File: LICENSE
25
+ Requires-Dist: numpy>=1.19.0
26
+ Requires-Dist: scipy>=1.6.0
27
+ Requires-Dist: pandas>=1.2.0
28
+ Requires-Dist: h5py>=3.0.0
29
+ Requires-Dist: matplotlib>=3.3.0
30
+ Requires-Dist: numba>=0.50.0
31
+ Requires-Dist: cyvcf2>=0.30.0
32
+ Provides-Extra: plink
33
+ Requires-Dist: bed-reader>=1.0.0; extra == "plink"
34
+ Provides-Extra: parallel
35
+ Requires-Dist: joblib>=1.0.0; extra == "parallel"
36
+ Provides-Extra: all
37
+ Requires-Dist: bed-reader>=1.0.0; extra == "all"
38
+ Requires-Dist: joblib>=1.0.0; extra == "all"
39
+ Dynamic: license-file
40
+
41
+ # PANICLE: Python Algorithms for Nucleotide-phenotype Inference and Chromosome-wide Locus Evaluation
42
+
43
+ [![Python 3.9+](https://img.shields.io/badge/python-3.9+-blue.svg)](https://www.python.org/downloads/)
44
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
45
+
46
+ PANICLE is a **Python package for Genome Wide Association Studies (GWAS)**. It implements GLM, MLM, FarmCPU, and BLINK. PANICLE seeks to achieve speeds comparable or better to other implementations while supporting multiple input data formats, providing multiple quality of life features (native effect marker number testing, leave one chromosome out MLM, calculation of resampling model inclusion probabilities, etc), and allowing modern GWAS algorithms to be natively integrated into python-based data analysis pipelines and ecosystems.
47
+
48
+ ## Key Features
49
+
50
+ * **Multiple Algorithms**: GLM, MLM, FarmCPU, BLINK
51
+ * **Supported Genotype Formats**: VCF/BCF, PLINK, HapMap, CSV/TSV with optional caching of genotype data in binary during initial run (speeds future data loading dramatically).
52
+ * **Robustness**: Graceful handling of missing data.
53
+
54
+ ## Installation
55
+
56
+ Requires Python 3.9+.
57
+
58
+ ```bash
59
+ git clone https://github.com/jschnable/PANICLE.git
60
+ cd PANICLE
61
+ pip install -e .
62
+ ```
63
+
64
+ *Optional dependencies for VCF/PLINK support:*
65
+ ```bash
66
+ pip install -e .[all]
67
+ ```
68
+
69
+ ### Dependencies
70
+
71
+ **Core dependencies** (installed automatically):
72
+ - `numpy` ≥1.19.0
73
+ - `scipy` ≥1.6.0
74
+ - `pandas` ≥1.2.0
75
+ - `h5py` ≥3.0.0 (HDF5 support)
76
+ - `matplotlib` ≥3.3.0 (plotting)
77
+ - `numba` ≥0.50.0 (JIT compilation for performance)
78
+ - `cyvcf2` ≥0.30.0 (fast VCF/BCF parsing)
79
+
80
+ **Optional dependencies**:
81
+ - `bed-reader` ≥1.0.0 — PLINK .bed/.bim/.fam format support (`pip install panicle[plink]`)
82
+ - `joblib` ≥1.0.0 — Parallel processing for LOCO methods (`pip install panicle[parallel]`)
83
+
84
+ ## CLI Usage (Quick Start)
85
+
86
+ The `run_GWAS.py` script provides a command-line interface for batch processing.
87
+
88
+ ```bash
89
+ python scripts/run_GWAS.py \
90
+ --phenotype data/phenotype.csv \
91
+ --genotype data/genotypes.vcf.gz \
92
+ --traits Trait1,Trait2 \
93
+ --methods GLM,MLM,FarmCPU,BLINK \
94
+ --n-pcs 5 \
95
+ --compute-effective-tests \
96
+ --outputs manhattan qq significant_marker_pvalues \
97
+ --outputdir ./results
98
+ ```
99
+
100
+ For a small demo dataset included in the repo, see `examples/EXAMPLE_DATA.md` and try:
101
+ ```bash
102
+ python scripts/run_GWAS.py \
103
+ --phenotype examples/example_phenotypes.csv \
104
+ --genotype examples/example_genotypes.vcf.gz \
105
+ --traits PlantHeight \
106
+ --methods GLM \
107
+ --outputdir ./results
108
+ ```
109
+
110
+ ### Parameters
111
+
112
+ | Argument | Description | Default |
113
+ | :--- | :--- | :--- |
114
+ | **`--phenotype`** | Path to phenotype CSV/TSV (must contain ID column). | **Required** |
115
+ | **`--phenotype-id-column`** | ID column name in phenotype file. | ID |
116
+ | **`--genotype`** | Path to genotype VCF/BCF/CSV. | **Required** |
117
+ | **`--map`** | Optional map file (SNP, CHROM, POS). Recommended for numeric CSV/TSV and LOCO methods. | None |
118
+ | **`--format`** | Genotype format override: `vcf`, `plink`, `hapmap`, `csv`, `tsv`, `numeric`. | Auto |
119
+ | **`--traits`** | Comma-separated list of columns to analyze. | All numeric |
120
+ | **`--methods`** | GWAS methods: `GLM`, `MLM`, `FarmCPU`, `BLINK`, `FarmCPUResampling`. | GLM,MLM,FarmCPU,BLINK |
121
+ | **`--n-pcs`** | Number of Principal Components for population structure. | 3 |
122
+ | **`--compute-effective-tests`** | Calculate Effective SNP Number (Me) and use it for Bonferroni correction. | False |
123
+ | **`--alpha`** | Significance level (e.g., 0.05). Threshold = `alpha / Me` (or `M`). | 0.05 |
124
+ | **`--significance`** | Fixed p-value threshold (overrides Bonferroni). | None |
125
+ | **`--n-eff`** | Effective number of markers (overrides Me). | None |
126
+ | **`--covariates`** | External covariate file. | None |
127
+ | **`--covariate-columns`** | Comma-separated covariate column names. | All except ID |
128
+ | **`--covariate-id-column`** | ID column name in covariate file. | ID |
129
+ | **`--max-iterations`** | Max iterations for FarmCPU/BLINK. | 10 |
130
+ | **`--max-genotype-dosage`** | Max dosage (e.g., 2 for diploid). | 2.0 |
131
+ | **`--outputdir`** | Output directory. | ./GWAS_results |
132
+ | **`--outputs`** | Outputs to generate: `all_marker_pvalues`, `significant_marker_pvalues`, `manhattan`, `qq` (see [docs/output_files.md](docs/output_files.md)). | All |
133
+
134
+ Other useful filters:
135
+ - `--max-missing` (default 1.0), `--min-maf` (default 0.0)
136
+ - `--drop-monomorphic` / `--keep-monomorphic`
137
+ - `--snps-only`, `--no-split-multiallelic`
138
+
139
+ ## Python API Usage
140
+
141
+ Integrate PANICLE into scripts or Jupyter Notebooks is via the `GWASPipeline` class.
142
+
143
+ ```python
144
+ from panicle.pipelines.gwas import GWASPipeline
145
+
146
+ # 1. Initialize
147
+ pipeline = GWASPipeline(output_dir="./results")
148
+
149
+ # 2. Load Data (Auto-caches for speed)
150
+ pipeline.load_data(
151
+ phenotype_file="data/phenotype.csv",
152
+ genotype_file="data/genotype.vcf.gz",
153
+ map_file="data/genotype.map", # Optional unless format lacks positions
154
+ trait_columns=["Height", "Yield"],
155
+ loader_kwargs={'compute_effective_tests': True} # Enable Me calculation
156
+ )
157
+
158
+ # 3. Pre-process
159
+ pipeline.align_samples()
160
+ pipeline.compute_population_structure(n_pcs=5)
161
+
162
+ # 4. Run Analysis (runs in parallel by default)
163
+ pipeline.run_analysis(
164
+ methods=['GLM', 'MLM', 'FARMCPU', 'BLINK'],
165
+ alpha=0.05
166
+ )
167
+ ```
168
+
169
+ ## Input Formats
170
+
171
+ ### Phenotype & Covariates
172
+ CSV or TSV files with an **ID column** and numeric columns for traits/covariates. PANICLE auto-detects ID columns named `ID`, `id`, `IID`, `sample`, `Sample`, `Taxa`, `taxa`, `Genotype`, `genotype`, `Accession`, `accession` (if multiple, it uses the leftmost). If none match, it uses the first column. Use `--phenotype-id-column` (or `--covariate-id-column`) to specify a custom ID column name.
173
+
174
+ ### Genotype
175
+ * **VCF/BCF**: `.vcf`, `.vcf.gz`, `.bcf` (Preferred for performance).
176
+ * **CSV/TSV**: Numeric matrix (rows=samples, cols=markers) + genetic map file with `SNP`, `CHROM`, and `POS` columns (case-insensitive aliases like `Chr`, `Pos` are accepted).
177
+ * **PLINK**: `.bed` + `.bim` + `.fam`.
178
+ * **HapMap**: `.hmp.txt`.
179
+
180
+ **Performance notes:** VCF is typically the slowest format on the first run, but PANICLE caches parsed marker data so subsequent loads are competitive with other formats. BCF is roughly ~2x faster than VCF on the first run, and PLINK/bed is roughly ~4x faster than VCF on the first run (exact speedups depend on marker count, sample size, and hardware).
181
+
182
+ ## Tips
183
+
184
+ 1. **Effective Tests**: Use `--compute-effective-tests` to calculate a less stringent, more accurate Bonferroni threshold based on marker linkage (`Me`).
185
+ 2. **Genotype Subsetting**: If you align or filter samples manually, use `GenotypeMatrix.subset_individuals(...)` to preserve pre-imputed fast paths.
186
+
187
+ ## Documentation & Examples
188
+
189
+ ### Documentation
190
+
191
+ Detailed documentation is available in the [`docs/`](docs/) directory:
192
+
193
+ - **[Quick Start Guide](docs/quickstart.md)** - Get up and running in 5 minutes
194
+ - **[API Reference](docs/api_reference.md)** - Complete API documentation for all functions and classes
195
+ - **[Output Files](docs/output_files.md)** - Understanding result file formats and columns
196
+
197
+ ### Interactive Tutorial
198
+
199
+ - **[Sorghum GWAS Tutorial](docs/sorghum_gwas_tutorial.ipynb)** - Jupyter notebook with complete GWAS workflow
200
+
201
+ ### Example Scripts
202
+
203
+ The [`examples/`](examples/) directory contains runnable example scripts with included test data:
204
+
205
+ | Example | Description |
206
+ |---------|-------------|
207
+ | [01_basic_gwas.py](examples/01_basic_gwas.py) | Simplest GWAS with GLM |
208
+ | [02_mlm_with_structure.py](examples/02_mlm_with_structure.py) | MLM with population structure correction |
209
+ | [03_hybrid_mlm.py](examples/03_hybrid_mlm.py) | Hybrid MLM (Wald + LRT) for accurate p-values |
210
+ | [04_with_covariates.py](examples/04_with_covariates.py) | Including external covariates |
211
+ | [05_reading_results.py](examples/05_reading_results.py) | Analyzing and visualizing results |
212
+
213
+ Run any example:
214
+ ```bash
215
+ cd examples
216
+ python 01_basic_gwas.py
217
+ ```
218
+
219
+ ## Algorithms
220
+
221
+ ### GLM
222
+
223
+ General Linear Model for fast single-marker association testing. Uses the Frisch-Waugh-Lovell (FWL) theorem combined with QR decomposition for computational efficiency. The algorithm residualizes the phenotype and genotypes against the covariate matrix (PCs + intercept), then computes per-marker regression statistics in vectorized batches. GLM is the fastest GWAS method but may generate overly optimistic significance values.
224
+
225
+ ### MLM
226
+
227
+ Mixed Linear Model accounting for population structure and cryptic relatedness via a kinship matrix.
228
+
229
+ **Key design decisions:**
230
+ - **LOCO by default**: Leave-One-Chromosome-Out kinship avoids proximal contamination (testing a marker against a kinship matrix that includes that marker), increasing power to detect true associations.
231
+ - **Eigenspace transformation**: Data is transformed via eigendecomposition of the kinship matrix, converting the correlated mixed model into an equivalent weighted least squares problem.
232
+ - **REML variance components**: Heritability (h²) is estimated using Brent's method optimization of the REML likelihood.
233
+
234
+ **MLM_Hybrid** extends MLM with a two-phase approach: (1) fast Wald screening of all markers, (2) Likelihood Ratio Test (LRT) refinement for markers passing a screening threshold (default p < 1e-4). LRT re-estimates variance components per marker, providing more accurate p-values but would be slow to run for many millions of markers.
235
+
236
+ ### FarmCPU
237
+
238
+ Fixed and random model Circulating Probability Unification. FarmCPU iteratively alternates between a fixed-effect model (GLM) and random-effect model to identify associated markers while controlling for polygenic background. FarmCPU can often detect more independent loci linked to variation in the same trait since it controls for the impact of each significant signal when determining the significance of other signals.
239
+
240
+ This means FarmCPU will NOT give the "towers" most of us expect from classical manhattan plots which are the result of many different markers in LD with the same causal variant. Instead it will identify only one marker since once the effect of this marker is controlled for the significance of any markers in LD with that marker decline to baseline levels.
241
+
242
+ FarmCPU Citation: Liu, X., Huang, M., Fan, B., Buckler, E. S., & Zhang, Z. (2016). Iterative usage of fixed and random effect models for powerful and efficient genome-wide association studies. _PLoS genetics_, _12_(2), e1005767.
243
+
244
+ ### BLINK
245
+
246
+ Bayesian-information and Linkage-disequilibrium Iteratively Nested Keyway. BLINK builds on FarmCPU's iterative framework but uses BIC-based model selection to optimize the pseudo-QTN set. Like FarmCPU, BLINK can often identify larger numbers of independent causal variants from the same phenotype/genotype set than GLM or MLM. Like FarmCPU, it will typically identify only one significant marker per causal variant and lacks the expected "towers" in manhattan plots caused by groups of markers that are all in LD.
247
+
248
+ Blink Citation: Huang, M., Liu, X., Zhou, Y., Summers, R. M., & Zhang, Z. (2019). BLINK: a package for the next level of genome-wide association studies with both individuals and markers in the millions. _Gigascience_, _8_(2), giy154.
249
+
250
+ ### Effective Marker Number Estimates
251
+
252
+ PANICLE includes a python-based based implementation of the effective marker number estimation method implemented in GEC. Accounts for linkage disequilibrium between markers to provide a less conservative multiple testing correction than standard Bonferroni.
253
+
254
+ GEC citation: Li MX, Yeung JM, Cherny SS, Sham PC. Evaluating the effective numbers of independent tests and significant p-value thresholds in commercial genotyping arrays and public imputation reference datasets. Hum Genet. 2012 May;131(5):747-56.
255
+
256
+ ## Benchmarks
257
+
258
+ Benchmarks based on traits measured from 862 samples, each scored for 5,751,024 markers and run on an Apple M4 CPU (cached VCF).
259
+
260
+ ### Data Loading
261
+
262
+ | Step | Time |
263
+ |---------------------|---------|
264
+ | Genotype loading | 1.34s |
265
+ | Phenotype loading | 0.005s |
266
+ | Sample alignment | 11.12s |
267
+ | PCA (3 components) | 2.08s |
268
+ | **Total** | **14.55s** |
269
+
270
+ *Note: First run with a given genetic marker file requires substantial time for parsing (≈9 minutes for 5M markers scored for 1000 individuals); subsequent runs use binary cache and load in seconds.*
271
+
272
+ ### Analysis Times (5.75M markers, 862 samples; excludes data loading/result writing)
273
+
274
+ | Method | Time | Notes |
275
+ |-------------|---------|-------------------------------------------|
276
+ | GLM | 8.94s | ~643K markers/second |
277
+ | MLM | 28.18s | LOCO kinship precompute +15.95s = 44.13s total |
278
+ | MLM_Hybrid | 30.67s | Includes LOCO kinship reuse |
279
+ | FarmCPU | 41.90s | 10 max iterations |
280
+ | BLINK | 60.81s | 10 max iterations |
281
+
282
+ ### Scaling by Marker Count (862 samples; includes cached load, alignment, PCA, kinship where relevant)
283
+
284
+ | Markers | GLM | MLM | MLM_Hybrid | FarmCPU | BLINK |
285
+ |------------|---------|---------|------------|----------|---------|
286
+ | 50,000 | 12.09s | 12.86s | 12.37s | 12.29s | 12.42s |
287
+ | 500,000 | 12.78s | 15.72s | 15.03s | 14.66s | 15.74s |
288
+ | 5,000,000 | 19.49s | 47.12s | 45.63s | 46.37s | 58.60s |
289
+
290
+ ## License
291
+
292
+ Distributed under the MIT license. See [LICENSE](LICENSE).
293
+
294
+ ---
295
+ **Disclaimer:** This is an independent Python implementation of algorithms developed by others. Any errors are mine alone. -James
@@ -0,0 +1,255 @@
1
+ # PANICLE: Python Algorithms for Nucleotide-phenotype Inference and Chromosome-wide Locus Evaluation
2
+
3
+ [![Python 3.9+](https://img.shields.io/badge/python-3.9+-blue.svg)](https://www.python.org/downloads/)
4
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
5
+
6
+ PANICLE is a **Python package for Genome Wide Association Studies (GWAS)**. It implements GLM, MLM, FarmCPU, and BLINK. PANICLE seeks to achieve speeds comparable or better to other implementations while supporting multiple input data formats, providing multiple quality of life features (native effect marker number testing, leave one chromosome out MLM, calculation of resampling model inclusion probabilities, etc), and allowing modern GWAS algorithms to be natively integrated into python-based data analysis pipelines and ecosystems.
7
+
8
+ ## Key Features
9
+
10
+ * **Multiple Algorithms**: GLM, MLM, FarmCPU, BLINK
11
+ * **Supported Genotype Formats**: VCF/BCF, PLINK, HapMap, CSV/TSV with optional caching of genotype data in binary during initial run (speeds future data loading dramatically).
12
+ * **Robustness**: Graceful handling of missing data.
13
+
14
+ ## Installation
15
+
16
+ Requires Python 3.9+.
17
+
18
+ ```bash
19
+ git clone https://github.com/jschnable/PANICLE.git
20
+ cd PANICLE
21
+ pip install -e .
22
+ ```
23
+
24
+ *Optional dependencies for VCF/PLINK support:*
25
+ ```bash
26
+ pip install -e .[all]
27
+ ```
28
+
29
+ ### Dependencies
30
+
31
+ **Core dependencies** (installed automatically):
32
+ - `numpy` ≥1.19.0
33
+ - `scipy` ≥1.6.0
34
+ - `pandas` ≥1.2.0
35
+ - `h5py` ≥3.0.0 (HDF5 support)
36
+ - `matplotlib` ≥3.3.0 (plotting)
37
+ - `numba` ≥0.50.0 (JIT compilation for performance)
38
+ - `cyvcf2` ≥0.30.0 (fast VCF/BCF parsing)
39
+
40
+ **Optional dependencies**:
41
+ - `bed-reader` ≥1.0.0 — PLINK .bed/.bim/.fam format support (`pip install panicle[plink]`)
42
+ - `joblib` ≥1.0.0 — Parallel processing for LOCO methods (`pip install panicle[parallel]`)
43
+
44
+ ## CLI Usage (Quick Start)
45
+
46
+ The `run_GWAS.py` script provides a command-line interface for batch processing.
47
+
48
+ ```bash
49
+ python scripts/run_GWAS.py \
50
+ --phenotype data/phenotype.csv \
51
+ --genotype data/genotypes.vcf.gz \
52
+ --traits Trait1,Trait2 \
53
+ --methods GLM,MLM,FarmCPU,BLINK \
54
+ --n-pcs 5 \
55
+ --compute-effective-tests \
56
+ --outputs manhattan qq significant_marker_pvalues \
57
+ --outputdir ./results
58
+ ```
59
+
60
+ For a small demo dataset included in the repo, see `examples/EXAMPLE_DATA.md` and try:
61
+ ```bash
62
+ python scripts/run_GWAS.py \
63
+ --phenotype examples/example_phenotypes.csv \
64
+ --genotype examples/example_genotypes.vcf.gz \
65
+ --traits PlantHeight \
66
+ --methods GLM \
67
+ --outputdir ./results
68
+ ```
69
+
70
+ ### Parameters
71
+
72
+ | Argument | Description | Default |
73
+ | :--- | :--- | :--- |
74
+ | **`--phenotype`** | Path to phenotype CSV/TSV (must contain ID column). | **Required** |
75
+ | **`--phenotype-id-column`** | ID column name in phenotype file. | ID |
76
+ | **`--genotype`** | Path to genotype VCF/BCF/CSV. | **Required** |
77
+ | **`--map`** | Optional map file (SNP, CHROM, POS). Recommended for numeric CSV/TSV and LOCO methods. | None |
78
+ | **`--format`** | Genotype format override: `vcf`, `plink`, `hapmap`, `csv`, `tsv`, `numeric`. | Auto |
79
+ | **`--traits`** | Comma-separated list of columns to analyze. | All numeric |
80
+ | **`--methods`** | GWAS methods: `GLM`, `MLM`, `FarmCPU`, `BLINK`, `FarmCPUResampling`. | GLM,MLM,FarmCPU,BLINK |
81
+ | **`--n-pcs`** | Number of Principal Components for population structure. | 3 |
82
+ | **`--compute-effective-tests`** | Calculate Effective SNP Number (Me) and use it for Bonferroni correction. | False |
83
+ | **`--alpha`** | Significance level (e.g., 0.05). Threshold = `alpha / Me` (or `M`). | 0.05 |
84
+ | **`--significance`** | Fixed p-value threshold (overrides Bonferroni). | None |
85
+ | **`--n-eff`** | Effective number of markers (overrides Me). | None |
86
+ | **`--covariates`** | External covariate file. | None |
87
+ | **`--covariate-columns`** | Comma-separated covariate column names. | All except ID |
88
+ | **`--covariate-id-column`** | ID column name in covariate file. | ID |
89
+ | **`--max-iterations`** | Max iterations for FarmCPU/BLINK. | 10 |
90
+ | **`--max-genotype-dosage`** | Max dosage (e.g., 2 for diploid). | 2.0 |
91
+ | **`--outputdir`** | Output directory. | ./GWAS_results |
92
+ | **`--outputs`** | Outputs to generate: `all_marker_pvalues`, `significant_marker_pvalues`, `manhattan`, `qq` (see [docs/output_files.md](docs/output_files.md)). | All |
93
+
94
+ Other useful filters:
95
+ - `--max-missing` (default 1.0), `--min-maf` (default 0.0)
96
+ - `--drop-monomorphic` / `--keep-monomorphic`
97
+ - `--snps-only`, `--no-split-multiallelic`
98
+
99
+ ## Python API Usage
100
+
101
+ Integrate PANICLE into scripts or Jupyter Notebooks is via the `GWASPipeline` class.
102
+
103
+ ```python
104
+ from panicle.pipelines.gwas import GWASPipeline
105
+
106
+ # 1. Initialize
107
+ pipeline = GWASPipeline(output_dir="./results")
108
+
109
+ # 2. Load Data (Auto-caches for speed)
110
+ pipeline.load_data(
111
+ phenotype_file="data/phenotype.csv",
112
+ genotype_file="data/genotype.vcf.gz",
113
+ map_file="data/genotype.map", # Optional unless format lacks positions
114
+ trait_columns=["Height", "Yield"],
115
+ loader_kwargs={'compute_effective_tests': True} # Enable Me calculation
116
+ )
117
+
118
+ # 3. Pre-process
119
+ pipeline.align_samples()
120
+ pipeline.compute_population_structure(n_pcs=5)
121
+
122
+ # 4. Run Analysis (runs in parallel by default)
123
+ pipeline.run_analysis(
124
+ methods=['GLM', 'MLM', 'FARMCPU', 'BLINK'],
125
+ alpha=0.05
126
+ )
127
+ ```
128
+
129
+ ## Input Formats
130
+
131
+ ### Phenotype & Covariates
132
+ CSV or TSV files with an **ID column** and numeric columns for traits/covariates. PANICLE auto-detects ID columns named `ID`, `id`, `IID`, `sample`, `Sample`, `Taxa`, `taxa`, `Genotype`, `genotype`, `Accession`, `accession` (if multiple, it uses the leftmost). If none match, it uses the first column. Use `--phenotype-id-column` (or `--covariate-id-column`) to specify a custom ID column name.
133
+
134
+ ### Genotype
135
+ * **VCF/BCF**: `.vcf`, `.vcf.gz`, `.bcf` (Preferred for performance).
136
+ * **CSV/TSV**: Numeric matrix (rows=samples, cols=markers) + genetic map file with `SNP`, `CHROM`, and `POS` columns (case-insensitive aliases like `Chr`, `Pos` are accepted).
137
+ * **PLINK**: `.bed` + `.bim` + `.fam`.
138
+ * **HapMap**: `.hmp.txt`.
139
+
140
+ **Performance notes:** VCF is typically the slowest format on the first run, but PANICLE caches parsed marker data so subsequent loads are competitive with other formats. BCF is roughly ~2x faster than VCF on the first run, and PLINK/bed is roughly ~4x faster than VCF on the first run (exact speedups depend on marker count, sample size, and hardware).
141
+
142
+ ## Tips
143
+
144
+ 1. **Effective Tests**: Use `--compute-effective-tests` to calculate a less stringent, more accurate Bonferroni threshold based on marker linkage (`Me`).
145
+ 2. **Genotype Subsetting**: If you align or filter samples manually, use `GenotypeMatrix.subset_individuals(...)` to preserve pre-imputed fast paths.
146
+
147
+ ## Documentation & Examples
148
+
149
+ ### Documentation
150
+
151
+ Detailed documentation is available in the [`docs/`](docs/) directory:
152
+
153
+ - **[Quick Start Guide](docs/quickstart.md)** - Get up and running in 5 minutes
154
+ - **[API Reference](docs/api_reference.md)** - Complete API documentation for all functions and classes
155
+ - **[Output Files](docs/output_files.md)** - Understanding result file formats and columns
156
+
157
+ ### Interactive Tutorial
158
+
159
+ - **[Sorghum GWAS Tutorial](docs/sorghum_gwas_tutorial.ipynb)** - Jupyter notebook with complete GWAS workflow
160
+
161
+ ### Example Scripts
162
+
163
+ The [`examples/`](examples/) directory contains runnable example scripts with included test data:
164
+
165
+ | Example | Description |
166
+ |---------|-------------|
167
+ | [01_basic_gwas.py](examples/01_basic_gwas.py) | Simplest GWAS with GLM |
168
+ | [02_mlm_with_structure.py](examples/02_mlm_with_structure.py) | MLM with population structure correction |
169
+ | [03_hybrid_mlm.py](examples/03_hybrid_mlm.py) | Hybrid MLM (Wald + LRT) for accurate p-values |
170
+ | [04_with_covariates.py](examples/04_with_covariates.py) | Including external covariates |
171
+ | [05_reading_results.py](examples/05_reading_results.py) | Analyzing and visualizing results |
172
+
173
+ Run any example:
174
+ ```bash
175
+ cd examples
176
+ python 01_basic_gwas.py
177
+ ```
178
+
179
+ ## Algorithms
180
+
181
+ ### GLM
182
+
183
+ General Linear Model for fast single-marker association testing. Uses the Frisch-Waugh-Lovell (FWL) theorem combined with QR decomposition for computational efficiency. The algorithm residualizes the phenotype and genotypes against the covariate matrix (PCs + intercept), then computes per-marker regression statistics in vectorized batches. GLM is the fastest GWAS method but may generate overly optimistic significance values.
184
+
185
+ ### MLM
186
+
187
+ Mixed Linear Model accounting for population structure and cryptic relatedness via a kinship matrix.
188
+
189
+ **Key design decisions:**
190
+ - **LOCO by default**: Leave-One-Chromosome-Out kinship avoids proximal contamination (testing a marker against a kinship matrix that includes that marker), increasing power to detect true associations.
191
+ - **Eigenspace transformation**: Data is transformed via eigendecomposition of the kinship matrix, converting the correlated mixed model into an equivalent weighted least squares problem.
192
+ - **REML variance components**: Heritability (h²) is estimated using Brent's method optimization of the REML likelihood.
193
+
194
+ **MLM_Hybrid** extends MLM with a two-phase approach: (1) fast Wald screening of all markers, (2) Likelihood Ratio Test (LRT) refinement for markers passing a screening threshold (default p < 1e-4). LRT re-estimates variance components per marker, providing more accurate p-values but would be slow to run for many millions of markers.
195
+
196
+ ### FarmCPU
197
+
198
+ Fixed and random model Circulating Probability Unification. FarmCPU iteratively alternates between a fixed-effect model (GLM) and random-effect model to identify associated markers while controlling for polygenic background. FarmCPU can often detect more independent loci linked to variation in the same trait since it controls for the impact of each significant signal when determining the significance of other signals.
199
+
200
+ This means FarmCPU will NOT give the "towers" most of us expect from classical manhattan plots which are the result of many different markers in LD with the same causal variant. Instead it will identify only one marker since once the effect of this marker is controlled for the significance of any markers in LD with that marker decline to baseline levels.
201
+
202
+ FarmCPU Citation: Liu, X., Huang, M., Fan, B., Buckler, E. S., & Zhang, Z. (2016). Iterative usage of fixed and random effect models for powerful and efficient genome-wide association studies. _PLoS genetics_, _12_(2), e1005767.
203
+
204
+ ### BLINK
205
+
206
+ Bayesian-information and Linkage-disequilibrium Iteratively Nested Keyway. BLINK builds on FarmCPU's iterative framework but uses BIC-based model selection to optimize the pseudo-QTN set. Like FarmCPU, BLINK can often identify larger numbers of independent causal variants from the same phenotype/genotype set than GLM or MLM. Like FarmCPU, it will typically identify only one significant marker per causal variant and lacks the expected "towers" in manhattan plots caused by groups of markers that are all in LD.
207
+
208
+ Blink Citation: Huang, M., Liu, X., Zhou, Y., Summers, R. M., & Zhang, Z. (2019). BLINK: a package for the next level of genome-wide association studies with both individuals and markers in the millions. _Gigascience_, _8_(2), giy154.
209
+
210
+ ### Effective Marker Number Estimates
211
+
212
+ PANICLE includes a python-based based implementation of the effective marker number estimation method implemented in GEC. Accounts for linkage disequilibrium between markers to provide a less conservative multiple testing correction than standard Bonferroni.
213
+
214
+ GEC citation: Li MX, Yeung JM, Cherny SS, Sham PC. Evaluating the effective numbers of independent tests and significant p-value thresholds in commercial genotyping arrays and public imputation reference datasets. Hum Genet. 2012 May;131(5):747-56.
215
+
216
+ ## Benchmarks
217
+
218
+ Benchmarks based on traits measured from 862 samples, each scored for 5,751,024 markers and run on an Apple M4 CPU (cached VCF).
219
+
220
+ ### Data Loading
221
+
222
+ | Step | Time |
223
+ |---------------------|---------|
224
+ | Genotype loading | 1.34s |
225
+ | Phenotype loading | 0.005s |
226
+ | Sample alignment | 11.12s |
227
+ | PCA (3 components) | 2.08s |
228
+ | **Total** | **14.55s** |
229
+
230
+ *Note: First run with a given genetic marker file requires substantial time for parsing (≈9 minutes for 5M markers scored for 1000 individuals); subsequent runs use binary cache and load in seconds.*
231
+
232
+ ### Analysis Times (5.75M markers, 862 samples; excludes data loading/result writing)
233
+
234
+ | Method | Time | Notes |
235
+ |-------------|---------|-------------------------------------------|
236
+ | GLM | 8.94s | ~643K markers/second |
237
+ | MLM | 28.18s | LOCO kinship precompute +15.95s = 44.13s total |
238
+ | MLM_Hybrid | 30.67s | Includes LOCO kinship reuse |
239
+ | FarmCPU | 41.90s | 10 max iterations |
240
+ | BLINK | 60.81s | 10 max iterations |
241
+
242
+ ### Scaling by Marker Count (862 samples; includes cached load, alignment, PCA, kinship where relevant)
243
+
244
+ | Markers | GLM | MLM | MLM_Hybrid | FarmCPU | BLINK |
245
+ |------------|---------|---------|------------|----------|---------|
246
+ | 50,000 | 12.09s | 12.86s | 12.37s | 12.29s | 12.42s |
247
+ | 500,000 | 12.78s | 15.72s | 15.03s | 14.66s | 15.74s |
248
+ | 5,000,000 | 19.49s | 47.12s | 45.63s | 46.37s | 58.60s |
249
+
250
+ ## License
251
+
252
+ Distributed under the MIT license. See [LICENSE](LICENSE).
253
+
254
+ ---
255
+ **Disclaimer:** This is an independent Python implementation of algorithms developed by others. Any errors are mine alone. -James