Skip to content

Commit

Permalink
Actually update clap and make cli a default feature
Browse files Browse the repository at this point in the history
  • Loading branch information
jackh726 committed Jul 31, 2023
1 parent 18a3d84 commit 0335681
Show file tree
Hide file tree
Showing 12 changed files with 96 additions and 160 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ name = "verify"
required-features = ["cli"]

[features]
default = ["remote", "read", "write"]
default = ["remote", "read", "write", "cli"]
remote = ["attohttpc", "tempfile"]
cli = ["clap", "ryu", "ufmt"]
read = ["bytes"]
Expand Down
48 changes: 15 additions & 33 deletions src/bin/bedgraphtobigwig.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,14 @@ use std::path::PathBuf;

use bigtools::bed::indexer::index_chroms;
use bigtools::bedchromdata::{BedParserParallelStreamingIterator, BedParserStreamingIterator};
use clap::{App, Arg};
use clap::{Arg, Command};

use bigtools::bbi::BigWigWrite;
use bigtools::bbiwrite::InputSortType;
use bigtools::bed::bedparser::{parse_bedgraph, BedParser};

fn main() -> Result<(), Box<dyn Error>> {
let matches = App::new("BedGraphToBigWig")
let matches = Command::new("BedGraphToBigWig")
.about("Converts an input bedGraph to a bigWig. Can be multi-threaded for substantial speedups. Note that ~11 temporary files are created/maintained.")
.arg(Arg::new("bedgraph")
.help("The bedgraph to convert to a bigwig. Can use `-` or `stdin` to read from stdin.")
Expand All @@ -33,53 +33,35 @@ fn main() -> Result<(), Box<dyn Error>> {
.arg(Arg::new("nthreads")
.short('t')
.help("Set the number of threads to use. This tool will typically use ~225% CPU on a HDD. SDDs may be higher. (IO bound)")
.takes_value(true)
.num_args(1)
.default_value("6"))
.arg(Arg::new("nzooms")
.short('z')
.help("Set the maximum of zooms to create.")
.takes_value(true)
.num_args(1)
.default_value("10"))
.arg(Arg::new("uncompressed")
.short('u')
.help("Don't use compression."))
.arg(Arg::new("sorted")
.short('s')
.help("Sets whether the input is sorted. Can take `all`, `start`, or `none`. `all` means that the input bedGraph is sorted by chroms and start (`sort -k1,1 -k2,2n`). `start` means that the the chroms are out of order but the starts within a chrom is sorted. `none` means that the file is not sorted at all. `all` is default. `none` currently errors but may be supported in the future. Note that using a value other than `all` will not guarantee (though likely) support for third-party tools.")
.takes_value(true)
.num_args(1)
.default_value("all"))
.arg(Arg::new("parallel")
.short('p')
.help("Set whether to read and convert the bedGraph in parallel. Can take `auto` (default), `yes`, `no`. Ignored when input is stdin or when nthreads is `1`.")
.takes_value(true)
.num_args(1)
.default_value("auto"))
.get_matches();

let bedgraphpath = matches.value_of("bedgraph").unwrap().to_owned();
let chrom_map = matches.value_of("chromsizes").unwrap().to_owned();
let bigwigpath = matches.value_of("output").unwrap().to_owned();
let nthreads = {
let nthreads = matches.value_of("nthreads").unwrap();
match nthreads.parse() {
Ok(parsed) => parsed,
Err(_) => {
eprintln!("Invalid argument for `nthreads`: must be a positive number");
return Ok(());
}
}
};
let nzooms = {
let nzooms = matches.value_of("nzooms").unwrap();
match nzooms.parse() {
Ok(parsed) => parsed,
Err(_) => {
eprintln!("Invalid argument for `nzooms`: must be a positive number");
return Ok(());
}
}
};
let uncompressed = matches.is_present("uncompressed");
let input_sort_type = match matches.value_of("sorted") {
let bedgraphpath = matches.get_one::<String>("bedgraph").unwrap().to_owned();
let chrom_map = matches.get_one::<String>("chromsizes").unwrap().to_owned();
let bigwigpath = matches.get_one::<String>("output").unwrap().to_owned();
let nthreads = *matches.get_one::<usize>("nthreads").unwrap();
let nzooms = *matches.get_one::<u32>("nzooms").unwrap();
let uncompressed = matches.get_count("uncompressed") > 0;
let input_sort_type = match matches.get_one::<String>("sorted").map(String::as_ref) {
None => InputSortType::ALL,
Some("all") => InputSortType::ALL,
Some("start") => InputSortType::START,
Expand Down Expand Up @@ -132,8 +114,8 @@ fn main() -> Result<(), Box<dyn Error>> {
} else {
let infile = File::open(&bedgraphpath)?;
let large_file = infile.metadata()?.len() >= 200_000_000;
let parallel = matches.value_of("auto");
let parallel = match (nthreads, parallel) {
let parallel = matches.get_one::<String>("auto");
let parallel = match (nthreads, parallel.map(String::as_ref)) {
(1, _) | (_, None) | (_, Some("auto")) => large_file,
(_, Some("yes")) => true,
(_, Some("no")) => false,
Expand Down
44 changes: 14 additions & 30 deletions src/bin/bedtobigbed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@ use std::fs::File;
use std::io::{BufRead, BufReader};

use bigtools::bedchromdata::BedParserStreamingIterator;
use clap::{App, Arg};
use clap::{Arg, Command};

use bigtools::bbi::BigBedWrite;
use bigtools::bbiwrite::InputSortType;
use bigtools::bed::bedparser::BedParser;

fn main() -> Result<(), Box<dyn Error>> {
let matches = App::new("BedToBigBed")
let matches = Command::new("BedToBigBed")
.arg(Arg::new("bed")
.help("the n to convert to a bigbed")
.index(1)
Expand All @@ -30,50 +30,34 @@ fn main() -> Result<(), Box<dyn Error>> {
.arg(Arg::new("nthreads")
.short('t')
.help("Set the number of threads to use")
.takes_value(true)
.num_args(1)
.default_value("6"))
.arg(Arg::new("nzooms")
.short('z')
.help("Set the maximum of zooms to create.")
.takes_value(true)
.num_args(1)
.default_value("10"))
.arg(Arg::new("uncompressed")
.short('u')
.help("Don't use compression."))
.arg(Arg::new("sorted")
.short('s')
.help("Sets whether the input is sorted. Can take `all`, `start`, or `none`. `all` means that the input bedGraph is sorted by chroms and start (`sort -k1,1 -k2,2n`). `start` means that the the chroms are out of order but the starts within a chrom is sorted. `none` means that the file is not sorted at all. `all` is default. `none` currently errors but may be supported in the future. Note that using a value other than `all` will not guarantee (though likely) support for third-party tools.")
.takes_value(true)
.num_args(1)
.default_value("all"))
.arg(Arg::new("autosql")
.short('a')
.help("The path to an .as file containing the autosql that defines the fields in this bigBed")
.takes_value(true))
.num_args(1))
.get_matches();

let bedpath = matches.value_of("bed").unwrap().to_owned();
let chrom_map = matches.value_of("chromsizes").unwrap().to_owned();
let bigwigpath = matches.value_of("output").unwrap().to_owned();
let nthreads = {
let nthreads = matches.value_of("nthreads").unwrap();
let parsed = nthreads.parse();
if parsed.is_err() {
eprintln!("Invalid argument for `nthreads`: must be a positive number");
return Ok(());
}
parsed.unwrap()
};
let nzooms = {
let nzooms = matches.value_of("nzooms").unwrap();
let parsed = nzooms.parse();
if parsed.is_err() {
eprintln!("Invalid argument for `nzooms`: must be a positive number");
return Ok(());
}
parsed.unwrap()
};
let uncompressed = { matches.is_present("uncompressed") };
let input_sort_type = match matches.value_of("sorted") {
let bedpath = matches.get_one::<String>("bed").unwrap().to_owned();
let chrom_map = matches.get_one::<String>("chromsizes").unwrap().to_owned();
let bigwigpath = matches.get_one::<String>("output").unwrap().to_owned();
let nthreads = *matches.get_one::<usize>("nthreads").unwrap();
let nzooms = *matches.get_one::<u32>("nzooms").unwrap();
let uncompressed = { matches.get_count("uncompressed") > 0 };
let input_sort_type = match matches.get_one::<String>("sorted").map(String::as_ref) {
None => InputSortType::ALL,
Some("all") => InputSortType::ALL,
Some("start") => InputSortType::START,
Expand Down Expand Up @@ -118,7 +102,7 @@ fn main() -> Result<(), Box<dyn Error>> {
let infile = File::open(bedpath)?;
let mut vals_iter = BedParser::from_bed_file(infile);

let autosql = match matches.value_of("autosql") {
let autosql = match matches.get_one::<String>("autosql") {
None => {
use bigtools::utils::chromvalues::ChromValues;
let (_, mut group) = vals_iter.next_chrom().unwrap().unwrap();
Expand Down
20 changes: 6 additions & 14 deletions src/bin/bigbedtobed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use std::error::Error;
use std::fs::File;
use std::io::{self, Write};

use clap::{App, Arg};
use clap::{Arg, Command};

use futures::task::SpawnExt;

Expand Down Expand Up @@ -66,7 +66,7 @@ pub fn write_bed<R: Reopen + SeekableRead + Send + 'static>(
}

fn main() -> Result<(), Box<dyn Error>> {
let matches = App::new("BigBedToBedGraph")
let matches = Command::new("BigBedToBedGraph")
.about("Converts an input bigBed to a bed. Can be multi-threaded for substantial speedups. Note for roughly each core, one temporary file will be opened.")
.arg(Arg::new("bigbed")
.help("the bigbed to get convert to bed")
Expand All @@ -81,22 +81,14 @@ fn main() -> Result<(), Box<dyn Error>> {
.arg(Arg::new("nthreads")
.short('t')
.help("Set the number of threads to use. This tool will nearly always benefit from more cores (<= # chroms). Note: for parts of the runtime, the actual usage may be nthreads+1")
.takes_value(true)
.num_args(1)
.default_value("6"))
.get_matches();

let bigbedpath = matches.value_of("bigbed").unwrap().to_owned();
let bedpath = matches.value_of("bed").unwrap().to_owned();
let bigbedpath = matches.get_one::<String>("bigbed").unwrap().to_owned();
let bedpath = matches.get_one::<String>("bed").unwrap().to_owned();

let nthreads = {
let nthreads = matches.value_of("nthreads").unwrap();
let parsed = nthreads.parse();
if parsed.is_err() {
eprintln!("Invalid argument for `nthreads`: must be a positive number");
return Ok(());
}
parsed.unwrap()
};
let nthreads = *matches.get_one::<usize>("nthreads").unwrap();

let bigbed = BigBedRead::open_file(bigbedpath)?;
let bed = File::create(bedpath)?;
Expand Down
28 changes: 14 additions & 14 deletions src/bin/bigtools.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use std::fs::File;
use std::io::{self, BufReader, BufWriter, Write};

use bigtools::{BigWigRead, BigWigReadAttachError};
use clap::{App, Arg};
use clap::{Arg, Command};

use bigtools::bbi::{BigBedRead, BigBedReadAttachError};
use bigtools::utils::reopen::SeekableRead;
Expand Down Expand Up @@ -148,47 +148,47 @@ fn chromintersect(apath: String, bpath: String, outpath: String) -> io::Result<(
}

fn main() -> Result<(), BigBedReadAttachError> {
let matches = App::new("BigTools")
let matches = Command::new("BigTools")
.subcommand(
App::new("intersect")
Command::new("intersect")
.about("Intersect all entries of a bed with a bigBed")
.arg(
Arg::new("a")
.short('a')
.help("Each entry in this bed is compared against b for overlaps.")
.takes_value(true)
.num_args(1)
.required(true),
)
.arg(
Arg::new("b")
.short('b')
.help("Each entry in a will be compared against this bigBed for overlaps.")
.takes_value(true)
.num_args(1)
.required(true),
),
)
.subcommand(
App::new("chromintersect")
Command::new("chromintersect")
.about("Create a new file of the same type, containing only data from `a` with chromosomes from `b`")
.arg(
Arg::new("a")
.short('a')
.help("The file to take data from (currently supports: bed)")
.takes_value(true)
.num_args(1)
.required(true),
)
.arg(
Arg::new("b")
.short('b')
.help("The file to take reference chromosomes from (currently supports: bigWig or bigBed)")
.takes_value(true)
.num_args(1)
.required(true),
)
.arg(
Arg::new("out")
.short('o')
.help("The name of the output file (or - for stdout). Outputted in same format as `a`")
.takes_value(true)
.num_args(1)
.required(true),
),
)
Expand All @@ -198,8 +198,8 @@ fn main() -> Result<(), BigBedReadAttachError> {
Some(("intersect", matches)) => {
eprintln!("---BigTools intersect---");

let apath = matches.value_of("a").unwrap().to_owned();
let bpath = matches.value_of("b").unwrap().to_owned();
let apath = matches.get_one::<String>("a").unwrap().to_owned();
let bpath = matches.get_one::<String>("b").unwrap().to_owned();

let b = BigBedRead::open_file(bpath)?;

Expand All @@ -208,9 +208,9 @@ fn main() -> Result<(), BigBedReadAttachError> {
Some(("chromintersect", matches)) => {
eprintln!("---BigTools chromintersect---");

let apath = matches.value_of("a").unwrap().to_owned();
let bpath = matches.value_of("b").unwrap().to_owned();
let outpath = matches.value_of("out").unwrap().to_owned();
let apath = matches.get_one::<String>("a").unwrap().to_owned();
let bpath = matches.get_one::<String>("b").unwrap().to_owned();
let outpath = matches.get_one::<String>("out").unwrap().to_owned();

chromintersect(apath, bpath, outpath)?;
}
Expand Down
23 changes: 7 additions & 16 deletions src/bin/bigwigaverageoverbed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,14 @@ use bigtools::bed::indexer::index_chroms;
use bigtools::utils::chromvalues::ChromValues;
use bigtools::utils::reopen::{Reopen, SeekableRead};
use bigtools::utils::streaming_linereader::StreamingLineReader;
use clap::{App, Arg};
use clap::{Arg, Command};

use bigtools::bbi::BigWigRead;
use bigtools::utils::misc::{stats_for_bed_item, Name};
use crossbeam_channel::TryRecvError;

fn main() -> Result<(), Box<dyn Error + Send + Sync>> {
let matches = App::new("BigWigAverageOverBed")
let matches = Command::new("BigWigAverageOverBed")
.arg(Arg::new("bigwig")
.help("The input bigwig file")
.index(1)
Expand Down Expand Up @@ -43,9 +43,9 @@ fn main() -> Result<(), Box<dyn Error + Send + Sync>> {
)
.get_matches();

let bigwigpath = matches.value_of("bigwig").unwrap();
let bedinpath = matches.value_of("bedin").unwrap();
let bedoutpath = matches.value_of("output").unwrap();
let bigwigpath = matches.get_one::<String>("bigwig").unwrap();
let bedinpath = matches.get_one::<String>("bedin").unwrap();
let bedoutpath = matches.get_one::<String>("output").unwrap();

let mut inbigwig = BigWigRead::open_file(bigwigpath)?;
let outbed = File::create(bedoutpath)?;
Expand All @@ -54,7 +54,7 @@ fn main() -> Result<(), Box<dyn Error + Send + Sync>> {
let bedin = BufReader::new(File::open(bedinpath)?);
let mut bedstream = StreamingLineReader::new(bedin);

let name = match matches.value_of("namecol") {
let name = match matches.get_one::<String>("namecol").map(String::as_ref) {
Some("interval") => Name::Interval,
Some("none") => Name::None,
Some(col) => {
Expand All @@ -74,16 +74,7 @@ fn main() -> Result<(), Box<dyn Error + Send + Sync>> {
None => Name::Column(3),
};

let nthreads: usize = {
let nthreads = matches.value_of("nthreads").unwrap();
match nthreads.parse() {
Ok(parsed) => parsed,
Err(_) => {
eprintln!("Invalid argument for `nthreads`: must be a positive number");
return Ok(());
}
}
};
let nthreads: usize = *matches.get_one::<usize>("nthreads").unwrap();
let parallel = nthreads > 1;

if parallel {
Expand Down
Loading

0 comments on commit 0335681

Please sign in to comment.