From aed3abc26bee38a03cca3a541e948cd22ce29227 Mon Sep 17 00:00:00 2001 From: Cj Jiang Date: Mon, 1 Jul 2024 13:20:35 +1000 Subject: [PATCH 1/3] feat: min_coverage_breadth fix: outdated tests replaced keep_if_any_meets_coverage with min_coverage_breadth, which allows specifying frequency of pools that need to meet coverage requirement. (renamed min_coverage to min_coverage_depth for clarity) made tests up to date with new flags --- src/base/pileup.rs | 48 ++++++++------------ src/base/structs_and_traits.rs | 4 +- src/base/sync.rs | 14 ++++-- src/base/vcf.rs | 30 ++++++++++-- src/gp/cv.rs | 5 +- src/gwas/correlation_test.rs | 5 +- src/gwas/gwalpha.rs | 5 +- src/gwas/ols.rs | 2 +- src/imputation/adaptive_ld_knn_imputation.rs | 5 +- src/imputation/filtering_missing.rs | 5 +- src/imputation/mean_imputation.rs | 5 +- src/main.rs | 14 +++--- src/popgen/gudmc.rs | 5 +- src/tables/chisq_test.rs | 5 +- src/tables/fisher_exact_test.rs | 5 +- 15 files changed, 102 insertions(+), 55 deletions(-) diff --git a/src/base/pileup.rs b/src/base/pileup.rs index d788a0e..0f4bd7b 100644 --- a/src/base/pileup.rs +++ b/src/base/pileup.rs @@ -2,7 +2,6 @@ use crate::base::*; use ndarray::prelude::*; -use std::collections::HashSet; use std::fs::{File, OpenOptions}; use std::io::{self, prelude::*, BufReader, BufWriter, Error, ErrorKind, SeekFrom}; use std::str; @@ -267,39 +266,32 @@ impl Filter for PileupLine { } } - if filter_stats.keep_if_any_meets_coverage { - // At least 1 pool needs to have been covered min_coverage times - let mut met_coverage_requirement = false; - for c in &self.coverages { - if c >= &filter_stats.min_coverage { - met_coverage_requirement = true; - break; - } - } - if !met_coverage_requirement{ - return Err(Error::new(ErrorKind::Other, "Filtered out.")); - } + // Coverage depth and breadth requirement + let min_coverage_breadth = (filter_stats.min_coverage_breadth * filter_stats.pool_sizes.len() as f64).ceil() as u32; + let pools_covered = self.coverages.iter() + .filter(|&&c| c >= filter_stats.min_coverage_depth) + .take(min_coverage_breadth as usize) + .count(); - } else { - // All the pools need to have been covered at least min_coverage times - for c in &self.coverages { - if c < &filter_stats.min_coverage { - return Err(Error::new(ErrorKind::Other, "Filtered out.")); - } - } + if pools_covered != min_coverage_breadth as usize { + return Err(Error::new(ErrorKind::Other, "Filtered out.")); } // Remove monoallelic loci (each loci must have coverage of at least 2 alleles) if filter_stats.remove_monoallelic { - let mut covered_alleles = HashSet::new(); + let mut unique_alleles = Vec::new(); - for pool in &self.read_codes{ - for read in pool{ - covered_alleles.insert(read); + 'outer: for pool in &self.read_codes { + for &read in pool { + if !unique_alleles.contains(&read) { + unique_alleles.push(read); + if unique_alleles.len() == 2 { + break 'outer; + } + } } } - - if covered_alleles.len() < 2{ + if unique_alleles.len() < 2 { return Err(Error::new(ErrorKind::Other, "Filtered out.")); } } @@ -591,10 +583,10 @@ mod tests { let filter_stats = FilterStats { remove_ns: true, remove_monoallelic: false, - keep_if_any_meets_coverage: false, keep_lowercase_reference: false, max_base_error_rate: 0.005, - min_coverage: 1, + min_coverage_depth: 1, + min_coverage_breadth: 1.0, min_allele_frequency: 0.0, max_missingness_rate: 0.0, pool_sizes: vec![0.2, 0.2, 0.2, 0.2, 0.2], diff --git a/src/base/structs_and_traits.rs b/src/base/structs_and_traits.rs index 77fae15..8c47953 100644 --- a/src/base/structs_and_traits.rs +++ b/src/base/structs_and_traits.rs @@ -69,10 +69,10 @@ pub struct FileSyncPhen { pub struct FilterStats { pub remove_ns: bool, pub remove_monoallelic: bool, - pub keep_if_any_meets_coverage: bool, pub keep_lowercase_reference: bool, pub max_base_error_rate: f64, - pub min_coverage: u64, + pub min_coverage_depth: u64, + pub min_coverage_breadth: f64, pub min_allele_frequency: f64, pub max_missingness_rate: f64, pub pool_sizes: Vec, diff --git a/src/base/sync.rs b/src/base/sync.rs index 581ec34..e66c7e7 100644 --- a/src/base/sync.rs +++ b/src/base/sync.rs @@ -224,12 +224,12 @@ impl Filter for LocusCounts { sum_coverage .iter() .fold(sum_coverage[0], |min, &x| if x < min { x } else { min }); - if min_sum_coverage < filter_stats.min_coverage as f64 { + if min_sum_coverage < filter_stats.min_coverage_depth as f64 { return Err(Error::new(ErrorKind::Other, "Filtered out.")); } // // TODO: convert loci failing the minimum coverage threshold into missing instead of omitting the entire locus // for i in 0..self.matrix.nrows() { - // if sum_coverage[i] < filter_stats.min_coverage as f64 { + // if sum_coverage[i] < filter_stats.min_coverage_depth as f64 { // for j in 0..self.matrix.ncols() { // self.matrix[(i, j)] = f64::NAN as u64; // } @@ -1569,8 +1569,11 @@ mod tests { let frequencies = *(counts.to_frequencies().unwrap()); let filter_stats = FilterStats { remove_ns: true, + remove_monoallelic: false, + keep_lowercase_reference: false, max_base_error_rate: 0.005, - min_coverage: 1, + min_coverage_depth: 1, + min_coverage_breadth: 1.0, min_allele_frequency: 0.005, max_missingness_rate: 0.0, pool_sizes: vec![20., 20., 20., 20., 20.], @@ -1675,8 +1678,11 @@ mod tests { // let phen = file_phen.lparse().unwrap(); // let filter_stats = FilterStats { // remove_ns: true, + // remove_monoallelic: false, + // keep_lowercase_reference: false, // max_base_error_rate: 0.005, - // min_coverage: 0, + // min_coverage_depth: 0, + // min_coverage_breadth: 1.0, // min_allele_frequency: 0.0001, // max_missingness_rate: 0.2, // pool_sizes: phen.pool_sizes, diff --git a/src/base/vcf.rs b/src/base/vcf.rs index ddfe3e8..a5cb182 100644 --- a/src/base/vcf.rs +++ b/src/base/vcf.rs @@ -115,13 +115,29 @@ impl Filter for VcfLine { /// - removing the entire locus if the locus is fixed, i.e. only 1 allele was found or retained after filterings /// Note that we are not removing alleles per locus if they fail the minimum allele frequency threshold, only if all alleles fail this threshold, i.e. when the locus is close to being fixed fn filter(&mut self, filter_stats: &FilterStats) -> io::Result<&mut Self> { - // All the pools needs be have been covered at least min_coverage times + // Coverage depth and breadth requirement + let min_coverage_breadth = (filter_stats.min_coverage_breadth * filter_stats.pool_sizes.len() as f64).ceil() as u32; + let mut pools_covered = 0; for i in 0..self.allele_depths.len() { let c = &self.allele_depths[i].iter().fold(0, |sum, x| sum + x); - if c < &filter_stats.min_coverage { + if c >= &filter_stats.min_coverage_depth { + pools_covered += 1; + } + if pools_covered == min_coverage_breadth { + break; + } + } + if pools_covered != min_coverage_breadth { + return Err(Error::new(ErrorKind::Other, "Filtered out.")); + } + + // Remove monoallelic loci (each loci must have coverage of at least 2 alleles) + if filter_stats.remove_monoallelic { + if self.alternative_alleles.len() == 0 { return Err(Error::new(ErrorKind::Other, "Filtered out.")); } } + // Filter by minimum allele frequency, //// First convert the counts per pool into frequencies let allele_frequencies = match self.to_frequencies() { @@ -509,16 +525,22 @@ mod tests { ); let filter_stats_1 = FilterStats { remove_ns: true, + remove_monoallelic: false, + keep_lowercase_reference: false, max_base_error_rate: 0.005, - min_coverage: 1, + min_coverage_depth: 1, + min_coverage_breadth: 1.0, min_allele_frequency: 0.0, max_missingness_rate: 0.0, pool_sizes: vec![0.2; 10], }; let filter_stats_2 = FilterStats { remove_ns: true, + remove_monoallelic: false, + keep_lowercase_reference: false, max_base_error_rate: 0.005, - min_coverage: 10, + min_coverage_depth: 10, + min_coverage_breadth: 1.0, min_allele_frequency: 0.0, max_missingness_rate: 0.0, pool_sizes: vec![0.2; 10], diff --git a/src/gp/cv.rs b/src/gp/cv.rs index 6a5658e..f1d2ad5 100644 --- a/src/gp/cv.rs +++ b/src/gp/cv.rs @@ -444,8 +444,11 @@ mod tests { let n_threads = 2; let filter_stats = FilterStats { remove_ns: true, + remove_monoallelic: false, + keep_lowercase_reference: false, max_base_error_rate: 0.005, - min_coverage: 1, + min_coverage_depth: 1, + min_coverage_breadth: 1.0, min_allele_frequency: 0.005, max_missingness_rate: 0.0, pool_sizes: vec![0.2, 0.2, 0.2, 0.2, 0.2], diff --git a/src/gwas/correlation_test.rs b/src/gwas/correlation_test.rs index 0685e29..3b4493f 100644 --- a/src/gwas/correlation_test.rs +++ b/src/gwas/correlation_test.rs @@ -148,8 +148,11 @@ mod tests { Array2::from_shape_vec((5, 2), vec![1, 9, 2, 8, 3, 7, 4, 6, 5, 5]).unwrap(); let filter_stats = FilterStats { remove_ns: true, + remove_monoallelic: false, + keep_lowercase_reference: false, max_base_error_rate: 0.005, - min_coverage: 1, + min_coverage_depth: 1, + min_coverage_breadth: 1.0, min_allele_frequency: 0.005, max_missingness_rate: 0.0, pool_sizes: vec![20.0, 20.0, 20.0, 20.0, 20.0], diff --git a/src/gwas/gwalpha.rs b/src/gwas/gwalpha.rs index 44e52f4..2e9af66 100644 --- a/src/gwas/gwalpha.rs +++ b/src/gwas/gwalpha.rs @@ -416,8 +416,11 @@ mod tests { .reversed_axes(); let filter_stats = FilterStats { remove_ns: true, + remove_monoallelic: false, + keep_lowercase_reference: false, max_base_error_rate: 0.005, - min_coverage: 1, + min_coverage_depth: 1, + min_coverage_breadth: 1.0, min_allele_frequency: 0.005, max_missingness_rate: 0.0, pool_sizes: vec![20.0, 20.0, 20.0, 20.0, 20.0], diff --git a/src/gwas/ols.rs b/src/gwas/ols.rs index c4ed796..f1ddfb5 100644 --- a/src/gwas/ols.rs +++ b/src/gwas/ols.rs @@ -549,7 +549,7 @@ mod tests { // let filter_stats = FilterStats { // remove_ns: true, // max_base_error_rate: 0.005, - // min_coverage: 1, + // min_coverage_depth: 1, // min_allele_frequency: 0.005, // pool_sizes: vec![20.0, 20.0, 20.0, 20.0, 20.0], // }; diff --git a/src/imputation/adaptive_ld_knn_imputation.rs b/src/imputation/adaptive_ld_knn_imputation.rs index 04b3e1c..63e801e 100644 --- a/src/imputation/adaptive_ld_knn_imputation.rs +++ b/src/imputation/adaptive_ld_knn_imputation.rs @@ -497,8 +497,11 @@ mod tests { let file_sync_phen = *(file_sync, file_phen).lparse().unwrap(); let filter_stats = FilterStats { remove_ns: true, + remove_monoallelic: false, + keep_lowercase_reference: false, max_base_error_rate: 0.005, - min_coverage: 1, + min_coverage_depth: 1, + min_coverage_breadth: 1.0, min_allele_frequency: 0.005, max_missingness_rate: 0.0, pool_sizes: vec![20., 20., 20., 20., 20.], diff --git a/src/imputation/filtering_missing.rs b/src/imputation/filtering_missing.rs index 8545c16..49bbc1a 100644 --- a/src/imputation/filtering_missing.rs +++ b/src/imputation/filtering_missing.rs @@ -255,8 +255,11 @@ mod tests { //////////////////////////////////////////////////////////////////////////////////////////////////////// let filter_stats = FilterStats { remove_ns: false, + remove_monoallelic: false, + keep_lowercase_reference: false, max_base_error_rate: 1.0, - min_coverage: 0, + min_coverage_depth: 0, + min_coverage_breadth: 1.0, min_allele_frequency: 0.000001, max_missingness_rate: 0.0, pool_sizes: vec![20., 20., 20., 20., 20.], diff --git a/src/imputation/mean_imputation.rs b/src/imputation/mean_imputation.rs index 3d7e023..1b9bc3a 100644 --- a/src/imputation/mean_imputation.rs +++ b/src/imputation/mean_imputation.rs @@ -182,8 +182,11 @@ mod tests { let file_sync_phen = *(file_sync, file_phen).lparse().unwrap(); let filter_stats = FilterStats { remove_ns: true, + remove_monoallelic: false, + keep_lowercase_reference: false, max_base_error_rate: 0.005, - min_coverage: 1, + min_coverage_depth: 1, + min_coverage_breadth: 1.0, min_allele_frequency: 0.005, max_missingness_rate: 0.0, pool_sizes: vec![20., 20., 20., 20., 20.], diff --git a/src/main.rs b/src/main.rs index 4e24203..346f705 100644 --- a/src/main.rs +++ b/src/main.rs @@ -40,9 +40,12 @@ struct Args { /// Maximum base sequencing error rate #[clap(long, default_value_t = 0.01)] max_base_error_rate: f64, - /// Minimum depth of coverage (loci with at least one pool below this threshold will be omitted) + /// Minimum breadth of coverage (loci with less than this proportion of pools below min_coverage_depth will be omitted) + #[clap(long, default_value_t = 1.0)] + min_coverage_breadth: f64, + /// Minimum depth of coverage (loci with less than min_coverage_breadth pools below this threshold will be omitted) #[clap(long, default_value_t = 1)] - min_coverage: u64, + min_coverage_depth: u64, /// Minimum allele frequency (per locus, alleles which fail to pass this threshold will be omitted allowing control over multiallelic loci) #[clap(long, default_value_t = 0.001)] min_allele_frequency: f64, @@ -55,9 +58,6 @@ struct Args { /// Keep ambiguous reads during SNP filtering, i.e. keep them coded as Ns #[clap(long, action)] keep_ns: bool, - /// Keep loci if any population meets min_coverage, verses only keeping if ALL loci meet coverage (default) - #[clap(long, action)] - keep_if_any_meets_coverage: bool, /// Remove monoallelic loci (each loci must have coverage of at least 2 alleles) #[clap(long, action)] remove_monoallelic: bool, @@ -196,10 +196,10 @@ fn main() { let filter_stats = base::FilterStats { remove_ns: !args.keep_ns, remove_monoallelic: args.remove_monoallelic, - keep_if_any_meets_coverage: args.keep_if_any_meets_coverage, keep_lowercase_reference: args.keep_lowercase_reference, max_base_error_rate: args.max_base_error_rate, - min_coverage: args.min_coverage, + min_coverage_breadth: args.min_coverage_breadth, + min_coverage_depth: args.min_coverage_depth, min_allele_frequency: args.min_allele_frequency, max_missingness_rate: args.max_missingness_rate, pool_sizes: phen.pool_sizes.clone(), diff --git a/src/popgen/gudmc.rs b/src/popgen/gudmc.rs index 655c4e8..820263a 100644 --- a/src/popgen/gudmc.rs +++ b/src/popgen/gudmc.rs @@ -484,8 +484,11 @@ mod tests { let file_sync_phen = *(file_sync, file_phen).lparse().unwrap(); let filter_stats = FilterStats { remove_ns: false, + remove_monoallelic: false, + keep_lowercase_reference: false, max_base_error_rate: 0.01, - min_coverage: 1, + min_coverage_depth: 1, + min_coverage_breadth: 1.0, min_allele_frequency: 0.001, max_missingness_rate: 0.0, pool_sizes: vec![42.0, 42.0, 42.0, 42.0, 42.0], diff --git a/src/tables/chisq_test.rs b/src/tables/chisq_test.rs index bd6d453..fe49bb3 100644 --- a/src/tables/chisq_test.rs +++ b/src/tables/chisq_test.rs @@ -67,8 +67,11 @@ mod tests { }; let filter_stats = FilterStats { remove_ns: true, + remove_monoallelic: false, + keep_lowercase_reference: false, max_base_error_rate: 0.01, - min_coverage: 1, + min_coverage_depth: 1, + min_coverage_breadth: 1.0, min_allele_frequency: 0.005, max_missingness_rate: 0.0, pool_sizes: vec![0.2, 0.2, 0.2, 0.2], diff --git a/src/tables/fisher_exact_test.rs b/src/tables/fisher_exact_test.rs index fb8f185..226f952 100644 --- a/src/tables/fisher_exact_test.rs +++ b/src/tables/fisher_exact_test.rs @@ -148,8 +148,11 @@ mod tests { Array2::from_shape_vec((3, 2), vec![0, 3, 1, 5, 2, 6]).unwrap(); let filter_stats = FilterStats { remove_ns: true, + remove_monoallelic: false, + keep_lowercase_reference: false, max_base_error_rate: 0.005, - min_coverage: 1, + min_coverage_depth: 1, + min_coverage_breadth: 1.0, min_allele_frequency: 0.005, max_missingness_rate: 0.0, pool_sizes: vec![0.2, 0.2, 0.2], From df94c0db675686dc0f60be45143cf342be00d81a Mon Sep 17 00:00:00 2001 From: Cj Jiang Date: Mon, 1 Jul 2024 13:37:14 +1000 Subject: [PATCH 2/3] fix: additional github tests --- src/imputation/adaptive_ld_knn_imputation.rs | 2 +- src/imputation/mean_imputation.rs | 2 +- src/main.rs | 10 +++++----- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/imputation/adaptive_ld_knn_imputation.rs b/src/imputation/adaptive_ld_knn_imputation.rs index 63e801e..c24dc2f 100644 --- a/src/imputation/adaptive_ld_knn_imputation.rs +++ b/src/imputation/adaptive_ld_knn_imputation.rs @@ -613,7 +613,7 @@ mod tests { // --phen-pool-size-col 1 \ // --phen-value-col 2 \ // --min-allele-frequency 0.0001 \ -// --min-coverage 0 \ +// --min-coverage-depth 0 \ // --min-quality 0.01 \ // --max-missingness-rate 0.2 \ // --min-depth-set-to-missing 5 \ diff --git a/src/imputation/mean_imputation.rs b/src/imputation/mean_imputation.rs index 1b9bc3a..1f0041e 100644 --- a/src/imputation/mean_imputation.rs +++ b/src/imputation/mean_imputation.rs @@ -266,7 +266,7 @@ mod tests { // --phen-pool-size-col 1 \ // --phen-value-col 2 \ // --min-allele-frequency 0.0001 \ -// --min-coverage 0 \ +// --min-coverage-depth 0 \ // --min-quality 0.01 \ // --max-missingness-rate 0.75 \ // --min-depth-set-to-missing 5 \ diff --git a/src/main.rs b/src/main.rs index 346f705..f0a4058 100644 --- a/src/main.rs +++ b/src/main.rs @@ -157,13 +157,13 @@ struct Args { /// ## Examples /// ```shell /// cargo run -- pileup2sync -f ./tests/test.pileup -p ./tests/test.csv -/// cargo run -- fisher_exact_test -f ./tests/test.sync -p ./tests/test.csv --n-threads 32 --min-coverage 10 --min-allele-frequency 0.01 -/// cargo run -- chisq_test -f ./tests/test.sync -p ./tests/test.csv --n-threads 32 --min-coverage 10 --min-allele-frequency 0.01 -/// cargo run -- pearson_corr -f ./tests/test.sync -p ./tests/test.csv --phen-delim , --phen-name-col 0 --phen-value-col 2,3 --n-threads 32 --min-coverage 10 --min-allele-frequency 0.01 +/// cargo run -- fisher_exact_test -f ./tests/test.sync -p ./tests/test.csv --n-threads 32 --min-coverage-depth 10 --min-allele-frequency 0.01 +/// cargo run -- chisq_test -f ./tests/test.sync -p ./tests/test.csv --n-threads 32 --min-coverage-depth 10 --min-allele-frequency 0.01 +/// cargo run -- pearson_corr -f ./tests/test.sync -p ./tests/test.csv --phen-delim , --phen-name-col 0 --phen-value-col 2,3 --n-threads 32 --min-coverage-depth 10 --min-allele-frequency 0.01 /// cargo run -- fst -f ./tests/test.sync -p ./tests/test.csv --phen-delim , --phen-name-col 0 --phen-value-col 2,3 --n-threads 32 /// cargo run -- heterozygosity -f ./tests/test.sync -p ./tests/test.csv --phen-delim , --phen-name-col 0 --phen-value-col 2,3 --n-threads 32 -/// cargo run -- ols_iter -f ./tests/test.sync -p ./tests/test.csv --phen-delim , --phen-name-col 0 --phen-value-col 2,3 --n-threads 32 --min-coverage 10 --min-allele-frequency 0.01 -/// cargo run -- mle_iter -f ./tests/test.sync -p ./tests/test.csv --phen-delim , --phen-name-col 0 --phen-value-col 2,3 --n-threads 32 --min-coverage 10 --min-allele-frequency 0.01 +/// cargo run -- ols_iter -f ./tests/test.sync -p ./tests/test.csv --phen-delim , --phen-name-col 0 --phen-value-col 2,3 --n-threads 32 --min-coverage-depth 10 --min-allele-frequency 0.01 +/// cargo run -- mle_iter -f ./tests/test.sync -p ./tests/test.csv --phen-delim , --phen-name-col 0 --phen-value-col 2,3 --n-threads 32 --min-coverage-depth 10 --min-allele-frequency 0.01 /// cargo run -- gwalpha -f ./tests/test.sync -p ./tests/test.py --n-threads 32 --gwalpha-method ML /// cargo run -- sync2csv -f ./tests/test.sync -p ./tests/test.csv --phen-delim , --phen-name-col 0 --phen-value-col 2,3 --n-threads 32 --keep-p-minus-1 /// # cargo run -- genomic_prediction_cross_validation -f ./tests/test_MORE_POOLS.sync -p ./tests/test_MORE_POOLS.csv --phen-delim , --phen-name-col 0 --phen-value-col 2,3 --n-threads 32 From 3b43690a6ab3dedcfdf9e529027508bc2f710f54 Mon Sep 17 00:00:00 2001 From: Cj Jiang <115382069+cjdjpj@users.noreply.github.com> Date: Mon, 1 Jul 2024 14:10:02 +1000 Subject: [PATCH 3/3] update rust.yml with min_coverage_depth --- .github/workflows/rust.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 5980df8..ef36794 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -24,18 +24,18 @@ jobs: run: | cargo run -- pileup2sync -f ./tests/test.pileup -p ./tests/test.csv cargo run -- pileup2sync -f ./tests/test.pileup -p ./tests/test.csv --n-threads 2 --max-base-error-rate 0.0001 - cargo run -- pileup2sync -f ./tests/test.pileup -p ./tests/test.csv --n-threads 2 --max-base-error-rate 0.0001 --min-coverage 10 - cargo run -- pileup2sync -f ./tests/test.pileup -p ./tests/test.csv --n-threads 2 --max-base-error-rate 0.0001 --min-coverage 10 --min-allele-frequency 0.01 + cargo run -- pileup2sync -f ./tests/test.pileup -p ./tests/test.csv --n-threads 2 --max-base-error-rate 0.0001 --min-coverage-depth 10 + cargo run -- pileup2sync -f ./tests/test.pileup -p ./tests/test.csv --n-threads 2 --max-base-error-rate 0.0001 --min-coverage-depth 10 --min-allele-frequency 0.01 cargo run -- fisher_exact_test -f ./tests/test.sync -p ./tests/test.csv --n-threads 2 - cargo run -- fisher_exact_test -f ./tests/test.sync -p ./tests/test.csv --n-threads 2 --min-coverage 10 --min-allele-frequency 0.01 + cargo run -- fisher_exact_test -f ./tests/test.sync -p ./tests/test.csv --n-threads 2 --min-coverage-depth 10 --min-allele-frequency 0.01 cargo run -- chisq_test -f ./tests/test.sync -p ./tests/test.csv --n-threads 2 - cargo run -- chisq_test -f ./tests/test.sync -p ./tests/test.csv --n-threads 2 --min-coverage 10 --min-allele-frequency 0.01 + cargo run -- chisq_test -f ./tests/test.sync -p ./tests/test.csv --n-threads 2 --min-coverage-depth 10 --min-allele-frequency 0.01 cargo run -- pearson_corr -f ./tests/test.sync -p ./tests/test.csv --phen-delim , --phen-name-col 0 --phen-value-col 2,3 --n-threads 2 - cargo run -- pearson_corr -f ./tests/test.sync -p ./tests/test.csv --phen-delim , --phen-name-col 0 --phen-value-col 2,3 --n-threads 2 --min-coverage 10 --min-allele-frequency 0.01 + cargo run -- pearson_corr -f ./tests/test.sync -p ./tests/test.csv --phen-delim , --phen-name-col 0 --phen-value-col 2,3 --n-threads 2 --min-coverage-depth 10 --min-allele-frequency 0.01 cargo run -- ols_iter -f ./tests/test.sync -p ./tests/test.csv --phen-delim , --phen-name-col 0 --phen-value-col 2,3 --n-threads 2 - cargo run -- ols_iter -f ./tests/test.sync -p ./tests/test.csv --phen-delim , --phen-name-col 0 --phen-value-col 2,3 --n-threads 2 --min-coverage 10 --min-allele-frequency 0.01 + cargo run -- ols_iter -f ./tests/test.sync -p ./tests/test.csv --phen-delim , --phen-name-col 0 --phen-value-col 2,3 --n-threads 2 --min-coverage-depth 10 --min-allele-frequency 0.01 cargo run -- mle_iter -f ./tests/test.sync -p ./tests/test.csv --phen-delim , --phen-name-col 0 --phen-value-col 2,3 --n-threads 2 - cargo run -- mle_iter -f ./tests/test.sync -p ./tests/test.csv --phen-delim , --phen-name-col 0 --phen-value-col 2,3 --n-threads 2 --min-coverage 10 --min-allele-frequency 0.01 + cargo run -- mle_iter -f ./tests/test.sync -p ./tests/test.csv --phen-delim , --phen-name-col 0 --phen-value-col 2,3 --n-threads 2 --min-coverage-depth 10 --min-allele-frequency 0.01 cargo run -- gwalpha -f ./tests/test.sync -p ./tests/test.py --n-threads 2 --gwalpha-method LS cargo run -- gwalpha -f ./tests/test.sync -p ./tests/test.py --n-threads 2 --gwalpha-method ML cargo run -- sync2csv -f ./tests/test.sync -p ./tests/test.csv --phen-delim , --phen-name-col 0 --phen-value-col 2,3 --n-threads 2