diff --git a/Cargo.toml b/Cargo.toml index d4364e0..b970551 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "umgap" -version = "0.3.1" +version = "0.3.2" authors = ["Felix Van der Jeugt ", "Stijn Seghers ", "Niels De Graef ", diff --git a/src/args.rs b/src/args.rs index a0f7902..11d4f94 100644 --- a/src/args.rs +++ b/src/args.rs @@ -5,6 +5,7 @@ use std::path::PathBuf; use std::str::FromStr; use rank::Rank; +use taxon::TaxonId; /// A reading frame #[allow(missing_docs)] @@ -162,9 +163,9 @@ pub enum Opt { #[structopt(name = "taxonomy")] Taxonomy(Taxonomy), - /// Snap taxa to a specified rank. - #[structopt(name = "snaprank")] - SnapRank(SnapRank), + /// Snap taxa to a specified rank or one of the specified taxa. + #[structopt(name = "snaptaxon")] + SnapTaxon(SnapTaxon), /// Interleaves a number of FASTQ files into a single FASTA output. #[structopt(name = "fastq2fasta")] @@ -443,12 +444,16 @@ pub struct FastqToFasta { pub input: Vec, } -/// Snap taxa to a specified rank. +/// Snap taxa to a specified rank or one of the specified taxa. #[derive(Debug, StructOpt)] -pub struct SnapRank { - /// The rank to show - #[structopt(short = "r", long = "rank", default_value = "species")] - pub rank: Rank, +pub struct SnapTaxon { + /// The rank to snap towards. + #[structopt(short = "r", long = "rank")] + pub rank: Option, + + /// A taxon to snap towards (allow multiple times). + #[structopt(short = "t", long = "taxons")] + pub taxons: Vec, /// Include invalidated taxa #[structopt(short = "i", long = "invalid")] diff --git a/src/main.rs b/src/main.rs index db2fe6b..3eb3b88 100644 --- a/src/main.rs +++ b/src/main.rs @@ -65,7 +65,7 @@ quick_main!(|| -> Result<()> { args::Opt::Uniq(args) => uniq(args), args::Opt::FastqToFasta(args) => fastq2fasta(args), args::Opt::Taxonomy(args) => taxonomy(args), - args::Opt::SnapRank(args) => snaprank(args), + args::Opt::SnapTaxon(args) => snaptaxon(args), args::Opt::JsonTree(args) => jsontree(args), args::Opt::SeedExtend(args) => seedextend(args), args::Opt::Report(args) => report(args), @@ -483,18 +483,21 @@ fn taxonomy(args: args::Taxonomy) -> Result<()> { Ok(()) } -fn snaprank(args: args::SnapRank) -> Result<()> { +fn snaptaxon(args: args::SnapTaxon) -> Result<()> { let taxons = taxon::read_taxa_file(&args.taxon_file)?; - if args.rank == rank::Rank::NoRank { + if args.rank.map(|r| r == rank::Rank::NoRank).unwrap_or(false) { return Err(ErrorKind::InvalidInvocation("Snap to an actual rank.".into()).into()); } // Parsing the taxons - let tree = taxon::TaxonTree::new(&taxons); - let by_id = taxon::TaxonList::new(taxons); - let snapping = tree.filter_ancestors(|tid| - by_id.get(tid).map(|t| t.rank == args.rank && (args.invalid || t.valid)).unwrap_or(false) - ); + let tree = taxon::TaxonTree::new(&taxons); + let by_id = taxon::TaxonList::new(taxons); + let snapping = tree.filter_ancestors(|tid| { + args.taxons.contains(&tid) || + by_id.get(tid) + .map(|t| (args.invalid || t.valid) && args.rank.map(|r| t.rank == r).unwrap_or(false)) + .unwrap_or(false) + }); // Read and count taxon ranks let stdin = io::stdin();