ferromic 0.1.4__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 (265) hide show
  1. ferromic-0.1.4/.cargo/config.toml +15 -0
  2. ferromic-0.1.4/.gitattributes +1 -0
  3. ferromic-0.1.4/.github/workflows/CI.yml +229 -0
  4. ferromic-0.1.4/.github/workflows/analysis_pipeline.yml +387 -0
  5. ferromic-0.1.4/.github/workflows/benchmarks.yml +207 -0
  6. ferromic-0.1.4/.github/workflows/fixer.yml +177 -0
  7. ferromic-0.1.4/.github/workflows/generate_supplementary_tables.yml +37 -0
  8. ferromic-0.1.4/.github/workflows/manual_run_vcf.yml +320 -0
  9. ferromic-0.1.4/.github/workflows/nextjs.yml +287 -0
  10. ferromic-0.1.4/.github/workflows/publish.yml +168 -0
  11. ferromic-0.1.4/.github/workflows/replicate_manuscript_statistics.yml +140 -0
  12. ferromic-0.1.4/.github/workflows/run_analysis.yml +304 -0
  13. ferromic-0.1.4/.github/workflows/rust.yml +132 -0
  14. ferromic-0.1.4/.github/workflows/upload_latest_manual_run_artifacts.yml +181 -0
  15. ferromic-0.1.4/.gitignore +43 -0
  16. ferromic-0.1.4/Cargo.lock +3379 -0
  17. ferromic-0.1.4/Cargo.toml +98 -0
  18. ferromic-0.1.4/Cross.toml +11 -0
  19. ferromic-0.1.4/LICENSE.md +4 -0
  20. ferromic-0.1.4/PKG-INFO +318 -0
  21. ferromic-0.1.4/README.md +286 -0
  22. ferromic-0.1.4/benches/pca.rs +90 -0
  23. ferromic-0.1.4/cds/README.md +62 -0
  24. ferromic-0.1.4/cds/axt_to_phy.py +1864 -0
  25. ferromic-0.1.4/cds/codeml_runner.py +266 -0
  26. ferromic-0.1.4/cds/combine_phy.py +334 -0
  27. ferromic-0.1.4/cds/finalize_results.py +87 -0
  28. ferromic-0.1.4/cds/generate_gha_matrix.py +202 -0
  29. ferromic-0.1.4/cds/iqtree_runner.py +110 -0
  30. ferromic-0.1.4/cds/omega_test.py +421 -0
  31. ferromic-0.1.4/cds/pipeline_lib.py +1661 -0
  32. ferromic-0.1.4/data/FST_data.tsv +181 -0
  33. ferromic-0.1.4/data/FigSX.inversion_r_plot.pdf +7253 -3
  34. ferromic-0.1.4/data/PGS_control_comparison.pdf +0 -0
  35. ferromic-0.1.4/data/PGS_control_volcano.pdf +0 -0
  36. ferromic-0.1.4/data/PGS_controls.tsv +11 -0
  37. ferromic-0.1.4/data/README.md +14 -0
  38. ferromic-0.1.4/data/Trajectory-12_47296118_A_G.tsv +102 -0
  39. ferromic-0.1.4/data/all_pop_phewas_tag.tsv +1098 -0
  40. ferromic-0.1.4/data/balanced_recurrence_results.tsv +293 -0
  41. ferromic-0.1.4/data/callset.tsv +400 -0
  42. ferromic-0.1.4/data/cds_emm_adjusted.tsv +5 -0
  43. ferromic-0.1.4/data/cds_emm_nocov.tsv +5 -0
  44. ferromic-0.1.4/data/cds_identical_proportions.tsv +766 -0
  45. ferromic-0.1.4/data/cds_pairwise_adjusted.tsv +7 -0
  46. ferromic-0.1.4/data/cds_pairwise_nocov.tsv +7 -0
  47. ferromic-0.1.4/data/chr17_inversion_tag_correlation.pdf +0 -0
  48. ferromic-0.1.4/data/chr17_inversion_tag_correlation_pvalue.pdf +0 -0
  49. ferromic-0.1.4/data/family_phewas.tsv +5 -0
  50. ferromic-0.1.4/data/fst_vs_inversion_edge_bp_cap100kb_grouped_median.pdf +0 -0
  51. ferromic-0.1.4/data/fst_vs_inversion_edge_bp_cap100kb_grouped_pooled.pdf +0 -0
  52. ferromic-0.1.4/data/fst_vs_inversion_edge_bp_cap40kb_grouped_pooled.pdf +0 -0
  53. ferromic-0.1.4/data/fst_vs_inversion_edge_proportion_cap40kb_grouped_pooled.pdf +0 -0
  54. ferromic-0.1.4/data/gene_inversion_direct_inverted.tsv +165 -0
  55. ferromic-0.1.4/data/imputation_results.tsv +159 -0
  56. ferromic-0.1.4/data/integrated_call_samples_v3.20250704.ALL.ped +3692 -0
  57. ferromic-0.1.4/data/inv_properties.tsv +294 -0
  58. ferromic-0.1.4/data/inversion_allele_frequency_differences.tsv +206925 -0
  59. ferromic-0.1.4/data/md5sum.txt +5 -0
  60. ferromic-0.1.4/data/output.csv +255 -0
  61. ferromic-0.1.4/data/passed_snvs.txt +138414 -0
  62. ferromic-0.1.4/data/per_inversion_frf_effects.tsv +60 -0
  63. ferromic-0.1.4/data/per_site_diversity_output.falsta.gz +0 -0
  64. ferromic-0.1.4/data/per_site_fst_output.falsta.gz +0 -0
  65. ferromic-0.1.4/data/phewas v2 - categories.tsv +97 -0
  66. ferromic-0.1.4/data/phewas_chr10_79542901-80217413.pdf +0 -0
  67. ferromic-0.1.4/data/phewas_chr12_46896694-46915975.pdf +0 -0
  68. ferromic-0.1.4/data/phewas_chr17_45585159-46292045.pdf +0 -0
  69. ferromic-0.1.4/data/phewas_chr4_33098066-33104924.pdf +0 -0
  70. ferromic-0.1.4/data/phewas_chr6_141866310-141898728.pdf +0 -0
  71. ferromic-0.1.4/data/phewas_chr6_167209001-167357782.pdf +0 -0
  72. ferromic-0.1.4/data/phewas_results.tsv +6535 -0
  73. ferromic-0.1.4/data/phy_metadata.tsv +1209 -0
  74. ferromic-0.1.4/data/phy_outputs.zip +3 -0
  75. ferromic-0.1.4/data/region_identical_proportions.tsv +184 -0
  76. ferromic-0.1.4/data/replicate_manuscript_statistics.txt +369 -0
  77. ferromic-0.1.4/data/significant_heritability_diseases.tsv +2291 -0
  78. ferromic-0.1.4/data/skipped_details.tsv +958 -0
  79. ferromic-0.1.4/data/spearman_decay_points.tsv +59 -0
  80. ferromic-0.1.4/data/tables.xlsx - Table S1.tsv +19 -0
  81. ferromic-0.1.4/data/tables.xlsx - Table S2.tsv +19 -0
  82. ferromic-0.1.4/data/tables.xlsx - Table S3.tsv +19 -0
  83. ferromic-0.1.4/data/tables.xlsx - Table S4.tsv +19 -0
  84. ferromic-0.1.4/data/vcf_list.txt +169262 -0
  85. ferromic-0.1.4/deny.toml +5 -0
  86. ferromic-0.1.4/imputation/README.md +106 -0
  87. ferromic-0.1.4/imputation/infer_dosage.py +519 -0
  88. ferromic-0.1.4/imputation/linked.py +780 -0
  89. ferromic-0.1.4/imputation/pack_models.py +123 -0
  90. ferromic-0.1.4/imputation/pls_patch.py +1114 -0
  91. ferromic-0.1.4/imputation/prepare_data_for_infer.py +321 -0
  92. ferromic-0.1.4/imputation/tagging_snp_inversion_dosages.py +395 -0
  93. ferromic-0.1.4/install.sh +47 -0
  94. ferromic-0.1.4/lambda/sims.py +399 -0
  95. ferromic-0.1.4/phewas/README.md +95 -0
  96. ferromic-0.1.4/phewas/__init__.py +1 -0
  97. ferromic-0.1.4/phewas/categories.py +733 -0
  98. ferromic-0.1.4/phewas/cli.py +94 -0
  99. ferromic-0.1.4/phewas/extra/README.md +29 -0
  100. ferromic-0.1.4/phewas/extra/__init__.py +3 -0
  101. ferromic-0.1.4/phewas/extra/categories_test.py +752 -0
  102. ferromic-0.1.4/phewas/extra/custom_control_followup.py +2449 -0
  103. ferromic-0.1.4/phewas/extra/family.py +578 -0
  104. ferromic-0.1.4/phewas/extra/h2.py +372 -0
  105. ferromic-0.1.4/phewas/extra/score.py +927 -0
  106. ferromic-0.1.4/phewas/iox.py +953 -0
  107. ferromic-0.1.4/phewas/logging_utils.py +123 -0
  108. ferromic-0.1.4/phewas/models.py +5272 -0
  109. ferromic-0.1.4/phewas/pheno.py +1188 -0
  110. ferromic-0.1.4/phewas/pipes.py +760 -0
  111. ferromic-0.1.4/phewas/run.py +1868 -0
  112. ferromic-0.1.4/phewas/testing.py +301 -0
  113. ferromic-0.1.4/phewas/tests/test_integration_pvalues.py +351 -0
  114. ferromic-0.1.4/phewas/tests/test_setup.sh +4 -0
  115. ferromic-0.1.4/phewas/tests/test_suite.py +3287 -0
  116. ferromic-0.1.4/phewas/tests/tests.py +10 -0
  117. ferromic-0.1.4/pyproject.toml +48 -0
  118. ferromic-0.1.4/rust-toolchain.toml +2 -0
  119. ferromic-0.1.4/scripts/README.md +68 -0
  120. ferromic-0.1.4/scripts/check_fixed_sites.py +305 -0
  121. ferromic-0.1.4/scripts/deduplicate.py +16 -0
  122. ferromic-0.1.4/scripts/dnds.py +1441 -0
  123. ferromic-0.1.4/scripts/download_phy_files.py +244 -0
  124. ferromic-0.1.4/scripts/find_figures_root.py +77 -0
  125. ferromic-0.1.4/scripts/generate_phewas_figures_json.py +201 -0
  126. ferromic-0.1.4/scripts/phy_to_fasta.py +192 -0
  127. ferromic-0.1.4/scripts/prepare_figures_manifest.py +145 -0
  128. ferromic-0.1.4/scripts/replicate_figures.py +1093 -0
  129. ferromic-0.1.4/src/README.md +23 -0
  130. ferromic-0.1.4/src/lib.rs +2270 -0
  131. ferromic-0.1.4/src/main.rs +363 -0
  132. ferromic-0.1.4/src/merge.rs +792 -0
  133. ferromic-0.1.4/src/parse.rs +1190 -0
  134. ferromic-0.1.4/src/pca.rs +1140 -0
  135. ferromic-0.1.4/src/process.rs +4768 -0
  136. ferromic-0.1.4/src/progress.rs +911 -0
  137. ferromic-0.1.4/src/pybenches/__init__.py +7 -0
  138. ferromic-0.1.4/src/pybenches/conftest.py +37 -0
  139. ferromic-0.1.4/src/pybenches/test_population_pca_benchmarks.py +709 -0
  140. ferromic-0.1.4/src/pybenches/test_population_statistics_benchmarks.py +855 -0
  141. ferromic-0.1.4/src/pytests/__init__.py +0 -0
  142. ferromic-0.1.4/src/pytests/test_diversity_integration.py +212 -0
  143. ferromic-0.1.4/src/pytests/test_ferromic.py +98 -0
  144. ferromic-0.1.4/src/pytests/test_hudson_fst_integration.py +152 -0
  145. ferromic-0.1.4/src/pytests/test_phewas_followup_merge.py +69 -0
  146. ferromic-0.1.4/src/run_vcf.rs +486 -0
  147. ferromic-0.1.4/src/stats.rs +4859 -0
  148. ferromic-0.1.4/src/tests/filter_tests.rs +246 -0
  149. ferromic-0.1.4/src/tests/full_integration_test.rs +248 -0
  150. ferromic-0.1.4/src/tests/hudson_fst_tests.rs +1419 -0
  151. ferromic-0.1.4/src/tests/interval_tests.rs +98 -0
  152. ferromic-0.1.4/src/tests/mnp_test.rs +41 -0
  153. ferromic-0.1.4/src/tests/partial_overlap_test.rs +102 -0
  154. ferromic-0.1.4/src/tests/sample_mapping_tests.rs +19 -0
  155. ferromic-0.1.4/src/tests/stats_tests.rs +1984 -0
  156. ferromic-0.1.4/src/tests.rs +1 -0
  157. ferromic-0.1.4/src/transcripts.rs +1458 -0
  158. ferromic-0.1.4/stats/CDS_identical_model.py +285 -0
  159. ferromic-0.1.4/stats/CDS_plots.py +1647 -0
  160. ferromic-0.1.4/stats/OR_matrix.py +485 -0
  161. ferromic-0.1.4/stats/PGS_control_plot.py +379 -0
  162. ferromic-0.1.4/stats/README.md +26 -0
  163. ferromic-0.1.4/stats/__init__.py +1 -0
  164. ferromic-0.1.4/stats/_inv_common.py +96 -0
  165. ferromic-0.1.4/stats/af_pi.py +272 -0
  166. ferromic-0.1.4/stats/category_figure.py +339 -0
  167. ferromic-0.1.4/stats/category_per_site.py +1266 -0
  168. ferromic-0.1.4/stats/category_per_site_normed.py +1384 -0
  169. ferromic-0.1.4/stats/category_utils.py +61 -0
  170. ferromic-0.1.4/stats/cds_differences.py +933 -0
  171. ferromic-0.1.4/stats/chr17_inversion_tag_correlation.py +366 -0
  172. ferromic-0.1.4/stats/dist_fst_by_type.py +348 -0
  173. ferromic-0.1.4/stats/distance_diversity.py +264 -0
  174. ferromic-0.1.4/stats/diversity_scatterplot.py +125 -0
  175. ferromic-0.1.4/stats/each_per_site.py +426 -0
  176. ferromic-0.1.4/stats/estimators_fst.py +366 -0
  177. ferromic-0.1.4/stats/events_rate_diversity.py +608 -0
  178. ferromic-0.1.4/stats/family_forest.py +172 -0
  179. ferromic-0.1.4/stats/forest.py +763 -0
  180. ferromic-0.1.4/stats/frf_violin.py +231 -0
  181. ferromic-0.1.4/stats/frf_volcano.py +198 -0
  182. ferromic-0.1.4/stats/fst_edge_decay.py +202 -0
  183. ferromic-0.1.4/stats/fst_violins.py +364 -0
  184. ferromic-0.1.4/stats/generate_tables.py +1069 -0
  185. ferromic-0.1.4/stats/imputation_plot.py +198 -0
  186. ferromic-0.1.4/stats/inv_dir_recur_model.py +1157 -0
  187. ferromic-0.1.4/stats/inv_dir_recur_violins.py +432 -0
  188. ferromic-0.1.4/stats/manhattan_phe.py +831 -0
  189. ferromic-0.1.4/stats/middle_vs_flank_fst.py +1381 -0
  190. ferromic-0.1.4/stats/middle_vs_flank_pi.py +1183 -0
  191. ferromic-0.1.4/stats/middle_vs_flank_pi_recurrence.py +1305 -0
  192. ferromic-0.1.4/stats/num_events_diversity.py +379 -0
  193. ferromic-0.1.4/stats/old/af_diffs.py +423 -0
  194. ferromic-0.1.4/stats/old/analyze_activations.py +1 -0
  195. ferromic-0.1.4/stats/old/ancient.py +1317 -0
  196. ferromic-0.1.4/stats/old/apobec3.py +301 -0
  197. ferromic-0.1.4/stats/old/bacon_correction.R +495 -0
  198. ferromic-0.1.4/stats/old/bacon_plot.py +118 -0
  199. ferromic-0.1.4/stats/old/best_tag.py +215 -0
  200. ferromic-0.1.4/stats/old/category_utils.py +61 -0
  201. ferromic-0.1.4/stats/old/conserve_chords.py +738 -0
  202. ferromic-0.1.4/stats/old/conserve_inv_dir.py +320 -0
  203. ferromic-0.1.4/stats/old/cross_violins.py +229 -0
  204. ferromic-0.1.4/stats/old/diversity_dir_inv.py +255 -0
  205. ferromic-0.1.4/stats/old/dnds_kde.py +640 -0
  206. ferromic-0.1.4/stats/old/fixed.py +496 -0
  207. ferromic-0.1.4/stats/old/freq_trajectory.py +278 -0
  208. ferromic-0.1.4/stats/old/frf_delta_strip_box.py +176 -0
  209. ferromic-0.1.4/stats/old/get_codes.py +1087 -0
  210. ferromic-0.1.4/stats/old/h2_OR_corr.py +140 -0
  211. ferromic-0.1.4/stats/old/inv_dir_recur.py +1203 -0
  212. ferromic-0.1.4/stats/old/inversion_phewas_report.py +677 -0
  213. ferromic-0.1.4/stats/old/inversion_table.py +304 -0
  214. ferromic-0.1.4/stats/old/length_distribution.py +39 -0
  215. ferromic-0.1.4/stats/old/manhattan_plot.py +524 -0
  216. ferromic-0.1.4/stats/old/matrix_plots.py +440 -0
  217. ferromic-0.1.4/stats/old/orientation_pcs.py +499 -0
  218. ferromic-0.1.4/stats/old/overall_groups_dnds.py +299 -0
  219. ferromic-0.1.4/stats/old/pairwise_matrix_test.py +1466 -0
  220. ferromic-0.1.4/stats/old/permute.py +522 -0
  221. ferromic-0.1.4/stats/old/phelist.py +85 -0
  222. ferromic-0.1.4/stats/old/phewas_repl.py +456 -0
  223. ferromic-0.1.4/stats/old/recur_conservation.py +993 -0
  224. ferromic-0.1.4/stats/old/region_descriptive.py +188 -0
  225. ferromic-0.1.4/stats/old/shuffle_coords.py +224 -0
  226. ferromic-0.1.4/stats/old/snv_list_acaf_download.py +1378 -0
  227. ferromic-0.1.4/stats/old/stats_table.py +474 -0
  228. ferromic-0.1.4/stats/old/tagged.py +662 -0
  229. ferromic-0.1.4/stats/old/vcf_snv_list.py +271 -0
  230. ferromic-0.1.4/stats/old/visualize_pca.py +222 -0
  231. ferromic-0.1.4/stats/old/wald_ci.py +176 -0
  232. ferromic-0.1.4/stats/overall_fst_by_type.py +1104 -0
  233. ferromic-0.1.4/stats/per_gene_cds_differences_jackknife.py +612 -0
  234. ferromic-0.1.4/stats/per_inversion_breakpoint_metric.py +2860 -0
  235. ferromic-0.1.4/stats/qq_plot.py +278 -0
  236. ferromic-0.1.4/stats/ranged_volcano.py +351 -0
  237. ferromic-0.1.4/stats/recur_breakpoint_tests.py +286 -0
  238. ferromic-0.1.4/stats/recur_diversity.py +399 -0
  239. ferromic-0.1.4/stats/regions_plot.py +149 -0
  240. ferromic-0.1.4/stats/replicate_manuscript_statistics.py +2373 -0
  241. ferromic-0.1.4/stats/replicate_manuscript_statistics.txt +369 -0
  242. ferromic-0.1.4/stats/replicate_spearman_raincloud.py +191 -0
  243. ferromic-0.1.4/stats/top_n_pi.py +167 -0
  244. ferromic-0.1.4/stats/volcano.py +439 -0
  245. ferromic-0.1.4/stats/volcano_shared.py +217 -0
  246. ferromic-0.1.4/web/figures-site/components/FigureGallery.tsx +103 -0
  247. ferromic-0.1.4/web/figures-site/components/SpecialGallery.tsx +159 -0
  248. ferromic-0.1.4/web/figures-site/data/README.md +45 -0
  249. ferromic-0.1.4/web/figures-site/data/figures.json +4 -0
  250. ferromic-0.1.4/web/figures-site/data/phewas-figures.json +22 -0
  251. ferromic-0.1.4/web/figures-site/data/special-figures.json +144 -0
  252. ferromic-0.1.4/web/figures-site/next-env.d.ts +5 -0
  253. ferromic-0.1.4/web/figures-site/next.config.mjs +14 -0
  254. ferromic-0.1.4/web/figures-site/package-lock.json +490 -0
  255. ferromic-0.1.4/web/figures-site/package.json +30 -0
  256. ferromic-0.1.4/web/figures-site/pages/_app.tsx +15 -0
  257. ferromic-0.1.4/web/figures-site/pages/index.tsx +74 -0
  258. ferromic-0.1.4/web/figures-site/pages/special/index.tsx +161 -0
  259. ferromic-0.1.4/web/figures-site/public/downloads/.gitkeep +0 -0
  260. ferromic-0.1.4/web/figures-site/public/figures/.gitkeep +0 -0
  261. ferromic-0.1.4/web/figures-site/public/figures/special/.gitkeep +0 -0
  262. ferromic-0.1.4/web/figures-site/styles/Gallery.module.css +142 -0
  263. ferromic-0.1.4/web/figures-site/styles/SpecialGallery.module.css +159 -0
  264. ferromic-0.1.4/web/figures-site/styles/globals.css +30 -0
  265. ferromic-0.1.4/web/figures-site/tsconfig.json +21 -0
@@ -0,0 +1,15 @@
1
+ [env]
2
+ SSL_CERT_FILE = { value = "/etc/ssl/certs/ca-certificates.crt", force = true }
3
+ SSL_CERT_DIR = { value = "/etc/ssl/certs", force = true }
4
+ OPENSSL_NO_PKG_CONFIG = { value = "1", force = true }
5
+
6
+ [target.s390x-unknown-linux-gnu.env]
7
+ OPENSSL_NO_ASM = "1"
8
+
9
+ # Allow unresolved Python symbols on macOS to be resolved at runtime by the
10
+ # interpreter when building the PyO3 extension module.
11
+ [target.x86_64-apple-darwin]
12
+ rustflags = ["-C", "link-arg=-undefined", "-C", "link-arg=dynamic_lookup"]
13
+
14
+ [target.aarch64-apple-darwin]
15
+ rustflags = ["-C", "link-arg=-undefined", "-C", "link-arg=dynamic_lookup"]
@@ -0,0 +1 @@
1
+ data/phy_outputs.zip filter=lfs diff=lfs merge=lfs -text
@@ -0,0 +1,229 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - main
7
+ - master
8
+ tags:
9
+ - '*'
10
+ paths:
11
+ - '**.rs'
12
+ - 'Cargo.toml'
13
+ pull_request:
14
+ paths:
15
+ - '**.rs'
16
+ - 'Cargo.toml'
17
+ workflow_dispatch:
18
+ inputs:
19
+ ci_targets:
20
+ description: Select which platforms to build
21
+ type: choice
22
+ default: default
23
+ options:
24
+ - default
25
+ - all
26
+
27
+ permissions:
28
+ contents: read
29
+
30
+ jobs:
31
+ linux:
32
+ runs-on: ${{ matrix.platform.runner }}
33
+ strategy:
34
+ matrix:
35
+ platform: >-
36
+ ${{ fromJson(
37
+ (startsWith(github.ref, 'refs/tags/') || (github.event_name == 'workflow_dispatch' && github.event.inputs.ci_targets == 'all'))
38
+ && '[{"runner":"ubuntu-22.04","target":"x86_64","openblas_target":"SANDYBRIDGE"},{"runner":"ubuntu-22.04","target":"x86","openblas_target":"ATOM"},{"runner":"ubuntu-22.04","target":"aarch64","openblas_target":"ARMV8"},{"runner":"ubuntu-22.04","target":"armv7","openblas_target":"ARMV7"},{"runner":"ubuntu-22.04","target":"ppc64le","openblas_target":"POWER9"}]'
39
+ || '[{"runner":"ubuntu-22.04","target":"x86_64","openblas_target":"SANDYBRIDGE"}]'
40
+ ) }}
41
+ steps:
42
+ - uses: actions/checkout@v4
43
+ - uses: actions/setup-python@v5
44
+ with:
45
+ python-version: 3.x
46
+ - name: Install Rust toolchain
47
+ uses: dtolnay/rust-toolchain@nightly
48
+ - name: Install build dependencies
49
+ if: ${{ matrix.platform.target == 'x86_64' }}
50
+ run: |
51
+ sudo apt-get update
52
+ sudo apt-get install -y build-essential gfortran perl wget
53
+ perl -MIPC::Cmd -e1 >/dev/null 2>&1 || (wget -O - https://cpanmin.us | perl - --notest IPC::Cmd)
54
+ - name: Cargo tests
55
+ if: ${{ matrix.platform.target == 'x86_64' }}
56
+ env:
57
+ OPENBLAS_TARGET: ${{ matrix.platform.openblas_target }}
58
+ run: cargo test --release
59
+ - name: Work around missing s390x assembler support
60
+ if: ${{ matrix.platform.target == 's390x' }}
61
+ run: |
62
+ echo "OPENSSL_NO_ASM=1" >> $GITHUB_ENV
63
+ echo "OPENSSL_SRC_CONFIGURE_ARGS=no-asm" >> $GITHUB_ENV
64
+ - name: Build wheels
65
+ uses: PyO3/maturin-action@v1
66
+ env:
67
+ OPENSSL_STATIC: 1
68
+ OPENSSL_VENDORED: 1
69
+ OPENBLAS_TARGET: ${{ matrix.platform.openblas_target }}
70
+ with:
71
+ target: ${{ matrix.platform.target }}
72
+ args: --release --out dist --find-interpreter
73
+ sccache: ${{ !startsWith(github.ref, 'refs/tags/') }}
74
+ manylinux: auto
75
+ rust-toolchain: nightly
76
+ before-script-linux: |
77
+ if command -v microdnf >/dev/null 2>&1; then
78
+ microdnf install -y gcc gcc-c++ gcc-gfortran make perl perl-IPC-Cmd wget
79
+ elif command -v dnf >/dev/null 2>&1; then
80
+ dnf install -y gcc gcc-c++ gcc-gfortran make perl perl-IPC-Cmd wget
81
+ elif command -v yum >/dev/null 2>&1; then
82
+ yum install -y gcc gcc-c++ gcc-gfortran make perl perl-IPC-Cmd wget
83
+ elif command -v apt-get >/dev/null 2>&1; then
84
+ apt-get update
85
+ apt-get install -y build-essential gfortran perl wget
86
+ elif command -v apk >/dev/null 2>&1; then
87
+ apk add --no-cache build-base gfortran perl perl-utils wget
88
+ fi
89
+ perl -MIPC::Cmd -e1 >/dev/null 2>&1 || (wget -O - https://cpanmin.us | perl - --notest IPC::Cmd)
90
+
91
+ - name: Upload wheels
92
+ uses: actions/upload-artifact@v4
93
+ with:
94
+ name: wheels-linux-${{ matrix.platform.target }}
95
+ path: dist
96
+
97
+ musllinux:
98
+ if: ${{ startsWith(github.ref, 'refs/tags/') || (github.event_name == 'workflow_dispatch' && github.event.inputs.ci_targets == 'all') }}
99
+ runs-on: ${{ matrix.platform.runner }}
100
+ strategy:
101
+ matrix:
102
+ platform: >-
103
+ ${{ fromJson('[{"runner":"ubuntu-22.04","target":"x86_64","openblas_target":"SANDYBRIDGE"},{"runner":"ubuntu-22.04","target":"x86","openblas_target":"ATOM"},{"runner":"ubuntu-22.04","target":"aarch64","openblas_target":"ARMV8"},{"runner":"ubuntu-22.04","target":"armv7","openblas_target":"ARMV7"}]') }}
104
+ steps:
105
+ - uses: actions/checkout@v4
106
+ - uses: actions/setup-python@v5
107
+ with:
108
+ python-version: 3.x
109
+ - name: Build wheels
110
+ uses: PyO3/maturin-action@v1
111
+ env:
112
+ OPENSSL_STATIC: 1
113
+ OPENSSL_VENDORED: 1
114
+ OPENBLAS_TARGET: ${{ matrix.platform.openblas_target }}
115
+ with:
116
+ target: ${{ matrix.platform.target }}
117
+ args: --release --out dist --find-interpreter
118
+ sccache: ${{ !startsWith(github.ref, 'refs/tags/') }}
119
+ manylinux: musllinux_1_2
120
+ rust-toolchain: nightly
121
+ before-script-linux: |
122
+ if command -v microdnf >/dev/null 2>&1; then
123
+ microdnf install -y gcc gcc-c++ gcc-gfortran make perl perl-IPC-Cmd wget
124
+ elif command -v dnf >/dev/null 2>&1; then
125
+ dnf install -y gcc gcc-c++ gcc-gfortran make perl perl-IPC-Cmd wget
126
+ elif command -v yum >/dev/null 2>&1; then
127
+ yum install -y gcc gcc-c++ gcc-gfortran make perl perl-IPC-Cmd wget
128
+ elif command -v apt-get >/dev/null 2>&1; then
129
+ apt-get update
130
+ apt-get install -y build-essential gfortran perl wget
131
+ elif command -v apk >/dev/null 2>&1; then
132
+ apk add --no-cache build-base gfortran perl perl-utils wget
133
+ fi
134
+ perl -MIPC::Cmd -e1 >/dev/null 2>&1 || (wget -O - https://cpanmin.us | perl - --notest IPC::Cmd)
135
+ - name: Upload wheels
136
+ uses: actions/upload-artifact@v4
137
+ with:
138
+ name: wheels-musllinux-${{ matrix.platform.target }}
139
+ path: dist
140
+
141
+ windows:
142
+ if: ${{ startsWith(github.ref, 'refs/tags/') || (github.event_name == 'workflow_dispatch' && github.event.inputs.ci_targets == 'all') }}
143
+ runs-on: ${{ matrix.platform.runner }}
144
+ strategy:
145
+ matrix:
146
+ platform: >-
147
+ ${{ fromJson('[{"runner":"windows-latest","target":"x64","vcpkg_triplet":"x64-windows"},{"runner":"windows-latest","target":"x86","vcpkg_triplet":"x86-windows"}]') }}
148
+ steps:
149
+ - uses: actions/checkout@v4
150
+ - uses: actions/setup-python@v5
151
+ with:
152
+ python-version: 3.x
153
+ architecture: ${{ matrix.platform.target }}
154
+ - name: Install OpenBLAS dependencies
155
+ shell: pwsh
156
+ run: |
157
+ $vcpkgRoot = Join-Path $Env:USERPROFILE "vcpkg"
158
+ if (-Not (Test-Path $vcpkgRoot)) {
159
+ git clone https://github.com/microsoft/vcpkg.git $vcpkgRoot
160
+ & (Join-Path $vcpkgRoot "bootstrap-vcpkg.bat") -disableMetrics
161
+ }
162
+ & (Join-Path $vcpkgRoot "vcpkg.exe") install openblas --triplet ${{ matrix.platform.vcpkg_triplet }}
163
+ "VCPKG_ROOT=$vcpkgRoot" | Out-File -FilePath $Env:GITHUB_ENV -Encoding utf8 -Append
164
+ "VCPKG_DEFAULT_TRIPLET=${{ matrix.platform.vcpkg_triplet }}" | Out-File -FilePath $Env:GITHUB_ENV -Encoding utf8 -Append
165
+ - name: Build wheels
166
+ uses: PyO3/maturin-action@v1
167
+ with:
168
+ target: ${{ matrix.platform.target }}
169
+ args: --release --out dist --find-interpreter
170
+ sccache: ${{ !startsWith(github.ref, 'refs/tags/') }}
171
+ rust-toolchain: nightly
172
+ - name: Upload wheels
173
+ uses: actions/upload-artifact@v4
174
+ with:
175
+ name: wheels-windows-${{ matrix.platform.target }}
176
+ path: dist
177
+
178
+ macos:
179
+ if: ${{ startsWith(github.ref, 'refs/tags/') || (github.event_name == 'workflow_dispatch' && github.event.inputs.ci_targets == 'all') }}
180
+ runs-on: ${{ matrix.platform.runner }}
181
+ strategy:
182
+ matrix:
183
+ platform: >-
184
+ ${{ fromJson('[{"runner":"macos-13","target":"x86_64"},{"runner":"macos-14","target":"aarch64"}]') }}
185
+ steps:
186
+ - uses: actions/checkout@v4
187
+ - uses: actions/setup-python@v5
188
+ with:
189
+ python-version: 3.x
190
+ - name: Build wheels
191
+ uses: PyO3/maturin-action@v1
192
+ with:
193
+ target: ${{ matrix.platform.target }}
194
+ args: --release --out dist --find-interpreter
195
+ sccache: ${{ !startsWith(github.ref, 'refs/tags/') }}
196
+ rust-toolchain: nightly
197
+ - name: Upload wheels
198
+ uses: actions/upload-artifact@v4
199
+ with:
200
+ name: wheels-macos-${{ matrix.platform.target }}
201
+ path: dist
202
+
203
+ release:
204
+ name: Release
205
+ runs-on: ubuntu-latest
206
+ if: ${{ startsWith(github.ref, 'refs/tags/') || github.event_name == 'workflow_dispatch' }}
207
+ needs: [linux, musllinux, windows, macos]
208
+ permissions:
209
+ # Use to sign the release artifacts
210
+ id-token: write
211
+ # Used to upload release artifacts
212
+ contents: write
213
+ # Used to generate artifact attestation
214
+ attestations: write
215
+ steps:
216
+ - uses: actions/download-artifact@v4
217
+ - name: Generate artifact attestation
218
+ uses: actions/attest-build-provenance@v1
219
+ with:
220
+ subject-path: 'wheels-*/*'
221
+ - name: Publish to PyPI
222
+ if: ${{ startsWith(github.ref, 'refs/tags/') }}
223
+ uses: PyO3/maturin-action@v1
224
+ env:
225
+ MATURIN_PYPI_TOKEN: ${{ secrets.PYPI_API_TOKEN }}
226
+ with:
227
+ command: upload
228
+ args: --non-interactive --skip-existing wheels-*/*
229
+ rust-toolchain: nightly
@@ -0,0 +1,387 @@
1
+ name: Analysis Pipeline
2
+
3
+ on:
4
+ workflow_dispatch:
5
+ inputs:
6
+ region_override:
7
+ description: 'Specific region (e.g., chr22:123-456). Leave empty for full run.'
8
+ required: false
9
+ type: string
10
+
11
+ jobs:
12
+ prep-and-matrix:
13
+ runs-on: ubuntu-latest
14
+ outputs:
15
+ regions: ${{ steps.set-matrix.outputs.regions }}
16
+ gene_batches: ${{ steps.set-matrix.outputs.gene_batches }}
17
+ cache_key: ${{ steps.calc-key.outputs.key }}
18
+ steps:
19
+ - name: Checkout code
20
+ uses: actions/checkout@v4
21
+ with:
22
+ lfs: false
23
+
24
+ - name: Create LFS file list
25
+ run: git lfs ls-files -l | cut -d' ' -f1 | sort > .lfs-assets-id
26
+
27
+ - name: Calculate Cache Key
28
+ id: calc-key
29
+ env:
30
+ THE_KEY: prep-results-v1-${{ runner.os }}-${{ hashFiles('cds/*.py', 'data/*.tsv', '.lfs-assets-id') }}
31
+ run: echo "key=$THE_KEY" >> $GITHUB_OUTPUT
32
+
33
+ - name: Check Output Cache
34
+ id: prep-cache
35
+ uses: actions/cache@v4
36
+ with:
37
+ path: |
38
+ combined_*.phy
39
+ outgroup_*.phy
40
+ key: ${{ steps.calc-key.outputs.key }}
41
+
42
+ - name: Set up Python
43
+ uses: actions/setup-python@v4
44
+ with:
45
+ python-version: '3.9'
46
+
47
+ - name: Install dependencies
48
+ run: pip install numpy pandas scipy statsmodels ete3 lxml requests tqdm
49
+
50
+ - name: Cache LFS
51
+ if: steps.prep-cache.outputs.cache-hit != 'true'
52
+ uses: actions/cache@v4
53
+ with:
54
+ path: .git/lfs
55
+ key: ${{ runner.os }}-lfs-${{ hashFiles('.lfs-assets-id') }}
56
+ restore-keys: |
57
+ ${{ runner.os }}-lfs-
58
+
59
+ - name: Pull LFS or Download Artifact
60
+ if: steps.prep-cache.outputs.cache-hit != 'true'
61
+ env:
62
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
63
+ run: |
64
+ if git lfs pull; then
65
+ echo "LFS pull successful"
66
+ else
67
+ echo "LFS pull failed. Falling back to artifact download."
68
+
69
+ set -euo pipefail
70
+ MANUAL_WORKFLOW_FILE="manual_run_vcf.yml"
71
+ api_root="https://api.github.com"
72
+ headers=(
73
+ -H "Authorization: Bearer $GH_TOKEN"
74
+ -H "Accept: application/vnd.github+json"
75
+ -H "X-GitHub-Api-Version: 2022-11-28"
76
+ )
77
+
78
+ echo "Finding latest successful run of $MANUAL_WORKFLOW_FILE..."
79
+ run_json="$(
80
+ curl -sS -L "${headers[@]}" \
81
+ "$api_root/repos/${{ github.repository }}/actions/workflows/${MANUAL_WORKFLOW_FILE}/runs?status=success&per_page=1"
82
+ )"
83
+ run_id="$(echo "$run_json" | jq '.workflow_runs[0].id')"
84
+
85
+ if [[ -z "$run_id" || "$run_id" == "null" ]]; then
86
+ echo "No successful Manual Run VCF Pipeline runs found." >&2
87
+ exit 1
88
+ fi
89
+ echo "Found Run ID: $run_id"
90
+
91
+ echo "Listing artifacts..."
92
+ artifact_json="$(
93
+ curl -sS -L "${headers[@]}" \
94
+ "$api_root/repos/${{ github.repository }}/actions/runs/$run_id/artifacts" \
95
+ )"
96
+
97
+ download_url=$(echo "$artifact_json" | jq -r '.artifacts[] | select(.name == "run-vcf-phy-outputs") | .archive_download_url')
98
+
99
+ if [[ -z "$download_url" || "$download_url" == "null" ]]; then
100
+ echo "Artifact 'run-vcf-phy-outputs' not found in run $run_id" >&2
101
+ exit 1
102
+ fi
103
+ echo "Found Artifact URL."
104
+
105
+ echo "Downloading artifact..."
106
+ curl -sS -L \
107
+ -H "Authorization: Bearer $GH_TOKEN" \
108
+ -H "Accept: application/vnd.github+json" \
109
+ -H "X-GitHub-Api-Version: 2022-11-28" \
110
+ "$download_url" > artifact.zip
111
+
112
+ echo "Extracting artifact..."
113
+ unzip -o artifact.zip
114
+
115
+ if [[ -f "phy_outputs.zip" ]]; then
116
+ mkdir -p data
117
+ mv phy_outputs.zip data/phy_outputs.zip
118
+ echo "Successfully restored data/phy_outputs.zip from artifact."
119
+ else
120
+ echo "Expected phy_outputs.zip inside the artifact, but not found."
121
+ ls -l
122
+ exit 1
123
+ fi
124
+
125
+ rm artifact.zip
126
+ fi
127
+
128
+ - name: Cache AXT file
129
+ if: steps.prep-cache.outputs.cache-hit != 'true'
130
+ uses: actions/cache@v4
131
+ with:
132
+ path: hg38.panTro6.net.axt.gz
133
+ key: axt-file-v1
134
+
135
+ - name: Unzip PHY files
136
+ if: steps.prep-cache.outputs.cache-hit != 'true'
137
+ run: |
138
+ unzip -o data/phy_outputs.zip
139
+ rm data/phy_outputs.zip
140
+ unzip -o '*.zip' || echo "No nested zip files found"
141
+ rm -f '*.zip'
142
+ ls -R
143
+ - name: Run AXT to PHY
144
+ if: steps.prep-cache.outputs.cache-hit != 'true'
145
+ run: |
146
+ python3 cds/axt_to_phy.py
147
+ ls outgroup_* || echo "No outgroup files found in root"
148
+ env:
149
+ AXT_WORKERS: 4
150
+
151
+ - name: Run Combine PHY
152
+ if: steps.prep-cache.outputs.cache-hit != 'true'
153
+ run: python3 cds/combine_phy.py
154
+
155
+ - name: Prepare Tools (Download & Zip)
156
+ run: |
157
+ # Create a temp python script to reuse pipeline_lib logic
158
+ cat <<EOF > prepare_tools.py
159
+ import os, sys
160
+ sys.path.append('cds')
161
+ import pipeline_lib as lib
162
+ lib.setup_external_tools(os.getcwd())
163
+ EOF
164
+ python3 prepare_tools.py
165
+
166
+ # Zip them up
167
+ zip -r tools.zip paml/ iqtree-3.0.1-Linux/
168
+
169
+ - name: Generate GHA Matrix
170
+ id: set-matrix
171
+ env:
172
+ REGION_INPUT: ${{ inputs.region_override }}
173
+ run: |
174
+ # Run the generator and capture JSON output
175
+ REGION_ARG=""
176
+ if [[ -n "$REGION_INPUT" ]]; then
177
+ REGION_ARG="--region-override $REGION_INPUT"
178
+ fi
179
+
180
+ JSON=$(python3 cds/generate_gha_matrix.py --batch-size 4 $REGION_ARG)
181
+
182
+ # Parse JSON to get regions and batches
183
+ REGIONS=$(echo "$JSON" | python3 -c "import sys, json; print(json.dumps(json.load(sys.stdin)['regions']))")
184
+ BATCHES=$(echo "$JSON" | python3 -c "import sys, json; print(json.dumps(json.load(sys.stdin)['gene_batches']))")
185
+
186
+ # Output to GHA environment
187
+ echo "regions=$REGIONS" >> $GITHUB_OUTPUT
188
+ echo "gene_batches=$BATCHES" >> $GITHUB_OUTPUT
189
+
190
+ - name: Upload Tools Artifact
191
+ uses: actions/upload-artifact@v4
192
+ with:
193
+ name: tools-zip
194
+ path: tools.zip
195
+
196
+ - name: Upload Combined PHY Artifacts
197
+ if: steps.prep-cache.outputs.cache-hit != 'true'
198
+ uses: actions/upload-artifact@v4
199
+ with:
200
+ name: combined-phy-files
201
+ path: |
202
+ combined_*.phy
203
+ retention-days: 3
204
+
205
+ iqtree-phase:
206
+ needs: prep-and-matrix
207
+ runs-on: ubuntu-latest
208
+ strategy:
209
+ fail-fast: false
210
+ max-parallel: 20
211
+ matrix:
212
+ region: ${{ fromJson(needs.prep-and-matrix.outputs.regions) }}
213
+ steps:
214
+ - name: Checkout code
215
+ uses: actions/checkout@v4
216
+
217
+ - name: Set up Python
218
+ uses: actions/setup-python@v4
219
+ with:
220
+ python-version: '3.9'
221
+
222
+ - name: Install dependencies
223
+ run: pip install numpy pandas scipy statsmodels ete3 lxml requests tqdm
224
+
225
+ - name: Download Tools
226
+ uses: actions/download-artifact@v4
227
+ with:
228
+ name: tools-zip
229
+
230
+ - name: Unzip Tools
231
+ run: unzip tools.zip
232
+
233
+ - name: Restore PHY Cache
234
+ uses: actions/cache/restore@v4
235
+ with:
236
+ path: |
237
+ combined_*.phy
238
+ outgroup_*.phy
239
+ key: ${{ needs.prep-and-matrix.outputs.cache_key }}
240
+ fail-on-cache-miss: true
241
+
242
+ - name: Calculate Input Hash
243
+ id: calc-hash
244
+ run: |
245
+ python3 -c "
246
+ import sys, glob, hashlib, os
247
+ sys.path.append('cds')
248
+ import pipeline_lib as lib
249
+
250
+ target_region = '${{ matrix.region }}'
251
+ files = glob.glob('combined_inversion_*.phy')
252
+ found = None
253
+ for f in files:
254
+ try:
255
+ if lib.parse_region_filename(f)['label'] == target_region:
256
+ found = f
257
+ break
258
+ except:
259
+ continue
260
+
261
+ if found:
262
+ print(f'Found file: {found}')
263
+ with open(found, 'rb') as f:
264
+ h = hashlib.sha256(f.read()).hexdigest()
265
+ print(f'Hash: {h}')
266
+ with open(os.environ['GITHUB_OUTPUT'], 'a') as fh:
267
+ fh.write(f'hash={h}\n')
268
+ else:
269
+ print(f'Error: Could not find file for region {target_region}')
270
+ sys.exit(1)
271
+ "
272
+
273
+ - name: Restore IQ-TREE Cache
274
+ uses: actions/cache@v4
275
+ id: iqtree-cache
276
+ with:
277
+ path: region_trees
278
+ key: iqtree-v1-${{ matrix.region }}-${{ steps.calc-hash.outputs.hash }}
279
+
280
+ - name: Run IQ-TREE
281
+ run: python3 cds/iqtree_runner.py
282
+ env:
283
+ TARGET_REGION: ${{ matrix.region }}
284
+
285
+ - name: Upload Region Tree
286
+ uses: actions/upload-artifact@v4
287
+ with:
288
+ name: region-tree-${{ matrix.region }}
289
+ path: |
290
+ region_trees/${{ matrix.region }}.treefile
291
+ region_trees/${{ matrix.region }}.FAILED
292
+ if-no-files-found: ignore
293
+ retention-days: 3
294
+
295
+ paml-phase:
296
+ needs: [prep-and-matrix, iqtree-phase]
297
+ runs-on: ubuntu-latest
298
+ strategy:
299
+ fail-fast: false
300
+ max-parallel: 20
301
+ matrix:
302
+ batch: ${{ fromJson(needs.prep-and-matrix.outputs.gene_batches) }}
303
+ steps:
304
+ - name: Checkout code
305
+ uses: actions/checkout@v4
306
+
307
+ - name: Set up Python
308
+ uses: actions/setup-python@v4
309
+ with:
310
+ python-version: '3.9'
311
+
312
+ - name: Install dependencies
313
+ run: pip install numpy pandas scipy statsmodels ete3 lxml requests tqdm
314
+
315
+ - name: Download Tools
316
+ uses: actions/download-artifact@v4
317
+ with:
318
+ name: tools-zip
319
+
320
+ - name: Unzip Tools
321
+ run: unzip tools.zip
322
+
323
+ - name: Restore PHY Cache
324
+ uses: actions/cache/restore@v4
325
+ with:
326
+ path: |
327
+ combined_*.phy
328
+ outgroup_*.phy
329
+ key: ${{ needs.prep-and-matrix.outputs.cache_key }}
330
+ fail-on-cache-miss: true
331
+
332
+ - name: Download All Region Trees
333
+ uses: actions/download-artifact@v4
334
+ with:
335
+ pattern: region-tree-*
336
+ merge-multiple: true
337
+ path: region_trees
338
+
339
+ - name: Run PAML (Batch)
340
+ run: python3 cds/codeml_runner.py
341
+ env:
342
+ GENE_BATCH: ${{ matrix.batch }}
343
+ # Optional: configure timeouts etc
344
+ PAML_TIMEOUT: 21100
345
+ REGION_OVERRIDE_FILTER: ${{ inputs.region_override }}
346
+ KEEP_PAML_OUT: 1
347
+
348
+ - name: Upload Partial Results
349
+ uses: actions/upload-artifact@v4
350
+ with:
351
+ name: paml-results-${{ strategy.job-index }}
352
+ path: |
353
+ partial_results_*.tsv
354
+ paml_runs/
355
+ retention-days: 3
356
+
357
+ finalize-phase:
358
+ needs: paml-phase
359
+ runs-on: ubuntu-latest
360
+ steps:
361
+ - name: Checkout code
362
+ uses: actions/checkout@v4
363
+
364
+ - name: Set up Python
365
+ uses: actions/setup-python@v4
366
+ with:
367
+ python-version: '3.9'
368
+
369
+ - name: Install dependencies
370
+ run: pip install numpy pandas scipy statsmodels ete3 lxml requests tqdm
371
+
372
+ - name: Download Partial Results
373
+ uses: actions/download-artifact@v4
374
+ with:
375
+ pattern: paml-results-*
376
+ merge-multiple: true
377
+
378
+ - name: Run Final Stats
379
+ run: python3 cds/finalize_results.py
380
+
381
+ - name: Upload Final Results
382
+ uses: actions/upload-artifact@v4
383
+ with:
384
+ name: full-paml-results
385
+ path: |
386
+ full_paml_results_*.tsv
387
+ retention-days: 3