-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Tidies up the implementation of print_clonotypes in preparation for additional refactoring. * Replace mutable arguments with a return data structure. * Refactor orbit traversal to use Result and a struct. * Clean up field naming and remove needless level of Vec nesting. * Remove unused gex_low value. * Collect most gene_scan args to simplify calling. * Excise some of the gene_scan stuff into enclone proper. * Replace mutability with itertools. * Use an option for the loupe clonotype.
- Loading branch information
1 parent
1c48410
commit 9ff82a8
Showing
11 changed files
with
242 additions
and
342 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,121 +1,106 @@ | ||
// Copyright (c) 2021 10X Genomics, Inc. All rights reserved. | ||
|
||
use enclone_core::defs::EncloneControl; | ||
use enclone_core::{defs::GeneScanOpts, linear_condition::LinearCondition}; | ||
|
||
pub struct InSet { | ||
pub test: bool, | ||
pub control: bool, | ||
} | ||
|
||
pub fn gene_scan_test( | ||
ctl: &EncloneControl, | ||
opts: &GeneScanOpts, | ||
exact: bool, | ||
stats: &[(String, Vec<String>)], | ||
stats_orig: &[(String, Vec<String>)], | ||
nexacts: usize, | ||
n: usize, | ||
in_test: &mut Vec<bool>, | ||
in_control: &mut Vec<bool>, | ||
) { | ||
) -> Vec<InSet> { | ||
// See if we're in the test and control sets for gene scan (non-exact case). | ||
|
||
if let Some(ref scan_test) = ctl.gen_opt.gene_scan_test { | ||
if !ctl.gen_opt.gene_scan_exact { | ||
let x = scan_test; | ||
let means = x | ||
.var | ||
.iter() | ||
.take(x.n()) | ||
.map(|xn| { | ||
stats | ||
.iter() | ||
.find_map(|stat| { | ||
if stat.0 == *xn { | ||
Some( | ||
stat.1 | ||
.iter() | ||
.filter_map(|k| k.parse::<f64>().ok()) | ||
.sum::<f64>(), | ||
) | ||
} else { | ||
None | ||
} | ||
}) | ||
.unwrap_or_default() | ||
/ n as f64 | ||
}) | ||
.collect::<Vec<_>>(); | ||
|
||
in_test.push(x.satisfied(&means)); | ||
let x = ctl.gen_opt.gene_scan_control.as_ref().unwrap(); | ||
let means = x | ||
.var | ||
.iter() | ||
.take(x.n()) | ||
.map(|xn| { | ||
stats | ||
.iter() | ||
.find_map(|stat| { | ||
if stat.0 == *xn { | ||
Some( | ||
stat.1 | ||
.iter() | ||
.filter_map(|k| k.parse::<f64>().ok()) | ||
.sum::<f64>(), | ||
) | ||
} else { | ||
None | ||
} | ||
}) | ||
.unwrap_or_default() | ||
/ n as f64 | ||
}) | ||
.collect::<Vec<_>>(); | ||
in_control.push(x.satisfied(&means)); | ||
} | ||
} | ||
|
||
// See if we're in the test and control sets for gene scan (exact case). | ||
|
||
if ctl.gen_opt.gene_scan_test.is_some() && ctl.gen_opt.gene_scan_exact { | ||
let x = ctl.gen_opt.gene_scan_test.clone().unwrap(); | ||
for k in 0..nexacts { | ||
let mut means = Vec::<f64>::new(); | ||
for xn in x.var.iter().take(x.n()) { | ||
let mut vals = Vec::<f64>::new(); | ||
let mut count = 0; | ||
for stat in stats_orig { | ||
if stat.0 == *xn { | ||
if count == k { | ||
for k in &stat.1 { | ||
if let Ok(v) = k.parse::<f64>() { | ||
vals.push(v); | ||
if !exact { | ||
let in_set = |cond: &LinearCondition| { | ||
cond.satisfied( | ||
&cond | ||
.var | ||
.iter() | ||
.take(cond.n()) | ||
.map(|xn| { | ||
stats | ||
.iter() | ||
.find_map(|stat| { | ||
if stat.0 == *xn { | ||
Some( | ||
stat.1 | ||
.iter() | ||
.filter_map(|k| k.parse::<f64>().ok()) | ||
.sum::<f64>(), | ||
) | ||
} else { | ||
None | ||
} | ||
}) | ||
.unwrap_or_default() | ||
/ n as f64 | ||
}) | ||
.collect::<Vec<_>>(), | ||
) | ||
}; | ||
vec![InSet { | ||
test: in_set(&opts.test), | ||
control: in_set(&opts.control), | ||
}] | ||
} else { | ||
// See if we're in the test and control sets for gene scan (exact case). | ||
(0..nexacts) | ||
.map(|k| { | ||
let x = &opts.test; | ||
let mut means = Vec::<f64>::new(); | ||
for xn in x.var.iter().take(x.n()) { | ||
let mut vals = Vec::<f64>::new(); | ||
let mut count = 0; | ||
for stat in stats_orig { | ||
if stat.0 == *xn { | ||
if count == k { | ||
for k in &stat.1 { | ||
if let Ok(v) = k.parse::<f64>() { | ||
vals.push(v); | ||
} | ||
} | ||
break; | ||
} | ||
break; | ||
count += 1; | ||
} | ||
count += 1; | ||
} | ||
let n = vals.len() as f64; | ||
means.push(vals.into_iter().sum::<f64>() / n); | ||
} | ||
let n = vals.len() as f64; | ||
means.push(vals.into_iter().sum::<f64>() / n); | ||
} | ||
in_test.push(x.satisfied(&means)); | ||
let x = ctl.gen_opt.gene_scan_control.clone().unwrap(); | ||
let mut means = Vec::<f64>::new(); | ||
for xn in x.var.iter().take(x.n()) { | ||
let mut vals = Vec::<f64>::new(); | ||
let mut count = 0; | ||
for stat in stats_orig { | ||
if stat.0 == *xn { | ||
if count == k { | ||
for k in &stat.1 { | ||
if let Ok(v) = k.parse::<f64>() { | ||
vals.push(v); | ||
let in_test = x.satisfied(&means); | ||
let x = &opts.control; | ||
let mut means = Vec::<f64>::new(); | ||
for xn in x.var.iter().take(x.n()) { | ||
let mut vals = Vec::<f64>::new(); | ||
let mut count = 0; | ||
for stat in stats_orig { | ||
if stat.0 == *xn { | ||
if count == k { | ||
for k in &stat.1 { | ||
if let Ok(v) = k.parse::<f64>() { | ||
vals.push(v); | ||
} | ||
} | ||
break; | ||
} | ||
break; | ||
count += 1; | ||
} | ||
count += 1; | ||
} | ||
means.push(vals.into_iter().sum::<f64>() / n as f64); | ||
} | ||
let in_control = x.satisfied(&means); | ||
InSet { | ||
test: in_test, | ||
control: in_control, | ||
} | ||
means.push(vals.into_iter().sum::<f64>() / n as f64); | ||
} | ||
in_control.push(x.satisfied(&means)); | ||
} | ||
}) | ||
.collect() | ||
} | ||
} |
Oops, something went wrong.