diff --git a/Cargo.lock b/Cargo.lock index 0e3fd5c..e3e8f1c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -293,7 +293,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "wham" -version = "0.9.2" +version = "0.9.4" dependencies = [ "GSL 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/Cargo.toml b/Cargo.toml index 70efc95..9b6eb87 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "wham" -version = "0.9.3" +version = "0.9.4" authors = ["D. Bauer "] description = "An implementation of the weighted histogram analysis method" license = "GPL-3.0" diff --git a/src/cli.yml b/src/cli.yml index 4d60b74..040ce34 100644 --- a/src/cli.yml +++ b/src/cli.yml @@ -86,3 +86,13 @@ args: help: Number of bayesian bootstrapping runs for error analysis by assigning random weights (defaults to 0). takes_value: true required: false + - start: + long: start + help: Skip rows in timeseries with an index smaller than this value (defaults to 0) + takes_value: true + required: false + - end: + long: end + help: Skip rows in timeseries with an index larger than this value (defaults to 1e+20) + takes_value: true + required: false diff --git a/src/io.rs b/src/io.rs index 320b63d..5eb1cf7 100644 --- a/src/io.rs +++ b/src/io.rs @@ -101,7 +101,7 @@ fn flat_index(indeces: &Vec, lengths: &Vec) -> usize { } // returns true if the values are inside the histogram boundaries defined by cfg -fn is_in_hist_boundaries(values: &Vec, cfg: &Config) -> bool { +fn is_in_hist_boundaries(values: &[f64], cfg: &Config) -> bool { for dimen in 0..cfg.dimens { if values[dimen] < cfg.hist_min[dimen] || values[dimen] > cfg.hist_max[dimen] { return false @@ -110,6 +110,14 @@ fn is_in_hist_boundaries(values: &Vec, cfg: &Config) -> bool { true } +// returns true given time in inside the time boundaries defined by cfg +fn is_in_time_boundaries(time: f64, cfg: &Config) -> bool { + if cfg.start <= time && time <= cfg.end { + return true + } + false +} + // parse a timeseries file into a histogram fn read_window_file(window_file: &str, cfg: &Config) -> Result { let f = File::open(window_file) @@ -143,15 +151,15 @@ fn read_window_file(window_file: &str, cfg: &Config) -> Result { bail!(format!("Wrong number of columns in line {} of window file {}. Empty Line?.", linecount, window_file)); } - let mut values: Vec = vec![f64::NAN; cfg.dimens]; + let mut values: Vec = vec![f64::NAN; cfg.dimens+1]; for i in 0..values.len() { - values[i] = split[i+1].parse::() + values[i] = split[i].parse::() .chain_err(|| format!("Failed to parse line {} of window file {}.", linecount, window_file))?; } - if is_in_hist_boundaries(&values, cfg) { + if is_in_hist_boundaries(&values[1..], cfg) && is_in_time_boundaries(values[0], cfg) { let bin_indeces = (0..cfg.dimens).map(|dimen: usize| { - let val = values[dimen]; + let val = values[dimen+1]; ((val - cfg.hist_min[dimen]) / bin_width[dimen]) as usize }).collect(); let index = flat_index(&bin_indeces, &cfg.num_bins); @@ -203,6 +211,8 @@ mod tests { cyclic: false, output: "qwert".to_string(), bootstrap: 0, + start: 0.0, + end: 1e+20 } } diff --git a/src/lib.rs b/src/lib.rs index 9d9cccc..ffe8bd5 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -38,6 +38,8 @@ pub struct Config { pub cyclic: bool, pub output: String, pub bootstrap: usize, + pub start: f64, + pub end: f64, } impl fmt::Display for Config { diff --git a/src/main.rs b/src/main.rs index ca520ed..f0732e0 100644 --- a/src/main.rs +++ b/src/main.rs @@ -30,7 +30,11 @@ fn cli() -> Result { .split(',').map(|x| { x.parse().unwrap() }).collect(); let bootstrap: usize = matches.value_of("bootstrap").unwrap_or("0").parse() .chain_err(|| "Cannot parse bootstrap iteration.")?; - + let start: f64 = matches.value_of("start").unwrap_or("0").parse() + .chain_err(|| "Cannot parse start time.")?; + let end: f64 = matches.value_of("end").unwrap_or("1e+20").parse() + .chain_err(|| "Cannot parse end time.")?; + if num_bins.len() != hist_max.len() || num_bins.len() != hist_max.len() { eprintln!("Input dimensions do not match (min: {}, max: {}, bins: {})", hist_min.len(), hist_max.len(), num_bins.len()); @@ -41,7 +45,7 @@ fn cli() -> Result { Ok(wham::Config{metadata_file, hist_min, hist_max, num_bins, dimens, verbose, tolerance, max_iterations, temperature, cyclic, output, - bootstrap}) + bootstrap, start, end}) } fn main() { diff --git a/tests/integration.rs b/tests/integration.rs index 0e4422f..bd331f9 100644 --- a/tests/integration.rs +++ b/tests/integration.rs @@ -16,21 +16,6 @@ mod integration { assert!(out.contains(expected_error)); } - #[test] - fn data_out_of_bonds() { - let output = Command::new("./target/debug/wham") - .args(&["--bins", "100", "--min", "2.0", "--max", "3.0", "-T", "300"]) - .args(&["-f", "example/1d/metadata.dat"]) - .args(&["-o", "/dev/null"]) - .output() - .expect("failed to execute process"); - let output = String::from_utf8_lossy(&output.stderr); - println!("{}", output); - assert!(output.to_string().contains( - "No data points in histogram boundaries" - )); - } - #[test] fn unparseable_bias_pos() { let output = Command::new("./target/debug/wham") @@ -107,6 +92,25 @@ mod integration { )); } + #[test] + fn skip_rows() { + let output = Command::new("./target/debug/wham") + .args(&["--bins", "100", "--max", "3.14", "--min", "-3.14", "-T", "300", "--cyclic"]) + .args(&["-f", "example/1d/metadata.dat"]) + .args(&["-o", "/tmp/wham_test_1d.out"]) + .args(&["--start", "50", "--end", "60"]) + .args(&["-v"]) + .output() + .expect("failed to execute process"); + + let output = String::from_utf8_lossy(&output.stdout); + println!("{}", output); + assert!(output.to_string().contains( + "25 windows, 12489 datapoints" + )); + } + + #[test] fn wham_1d() {; Command::new("./target/debug/wham")