瀏覽代碼

ok graph + clean

Your Name 1 年之前
父節點
當前提交
c3b25da303
共有 4 個文件被更改,包括 152 次插入260 次删除
  1. 89 53
      Cargo.lock
  2. 1 0
      Cargo.toml
  3. 1 116
      src/counts.rs
  4. 61 91
      src/lib.rs

+ 89 - 53
Cargo.lock

@@ -107,9 +107,9 @@ dependencies = [
 
 [[package]]
 name = "anyhow"
-version = "1.0.86"
+version = "1.0.88"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da"
+checksum = "4e1496f8fb1fbf272686b8d37f523dab3e4a7443300055e74cdaa449f3114356"
 
 [[package]]
 name = "approx"
@@ -193,7 +193,7 @@ dependencies = [
  "regex",
  "rustc-hash 1.1.0",
  "shlex",
- "syn 2.0.75",
+ "syn 2.0.77",
 ]
 
 [[package]]
@@ -281,9 +281,9 @@ dependencies = [
 
 [[package]]
 name = "cc"
-version = "1.1.13"
+version = "1.1.18"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "72db2f7947ecee9b03b510377e8bb9077afa27176fdbff55c51027e976fdcc48"
+checksum = "b62ac837cdb5cb22e10a256099b4fc502b1dfe560cb282963a974d7abd80e476"
 dependencies = [
  "jobserver",
  "libc",
@@ -420,9 +420,9 @@ dependencies = [
 
 [[package]]
 name = "critical-section"
-version = "1.1.2"
+version = "1.1.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7059fff8937831a9ae6f0fe4d658ffabf58f2ca96aa9dec1c889f936f705f216"
+checksum = "f64009896348fc5af4222e9cf7d7d82a95a256c634ebcf61c53e4ea461422242"
 
 [[package]]
 name = "crossbeam-channel"
@@ -491,9 +491,9 @@ dependencies = [
 
 [[package]]
 name = "curl-sys"
-version = "0.4.74+curl-8.9.0"
+version = "0.4.75+curl-8.10.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8af10b986114528fcdc4b63b6f5f021b7057618411046a4de2ba0f0149a097bf"
+checksum = "2a4fd752d337342e4314717c0d9b6586b059a120c80029ebe4d49b11fec7875e"
 dependencies = [
  "cc",
  "libc",
@@ -531,7 +531,7 @@ dependencies = [
  "proc-macro2",
  "quote",
  "strsim",
- "syn 2.0.75",
+ "syn 2.0.77",
 ]
 
 [[package]]
@@ -542,14 +542,14 @@ checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806"
 dependencies = [
  "darling_core",
  "quote",
- "syn 2.0.75",
+ "syn 2.0.77",
 ]
 
 [[package]]
 name = "dashmap"
-version = "6.0.1"
+version = "6.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "804c8821570c3f8b70230c2ba75ffa5c0f9a4189b9a432b6656c536712acae28"
+checksum = "5041cc499144891f3790297212f32a74fb938e5136a14943f338ef9e0ae276cf"
 dependencies = [
  "cfg-if",
  "crossbeam-utils",
@@ -595,7 +595,7 @@ checksum = "d150dea618e920167e5973d70ae6ece4385b7164e0d799fe7c122dd0a5d912ad"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.75",
+ "syn 2.0.77",
 ]
 
 [[package]]
@@ -606,7 +606,7 @@ checksum = "67e77553c4162a157adbf834ebae5b415acbecbeafc7a74b0e886657506a7611"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.75",
+ "syn 2.0.77",
 ]
 
 [[package]]
@@ -649,7 +649,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.75",
+ "syn 2.0.77",
 ]
 
 [[package]]
@@ -738,9 +738,9 @@ dependencies = [
 
 [[package]]
 name = "flate2"
-version = "1.0.32"
+version = "1.0.33"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9c0596c1eac1f9e04ed902702e9878208b336edc9d6fddc8a48387349bab3666"
+checksum = "324a1be68054ef05ad64b861cc9eaf1d623d2d8cb25b4bf2cb9cdd902b4bf253"
 dependencies = [
  "crc32fast",
  "miniz_oxide",
@@ -832,7 +832,7 @@ checksum = "cdc6457c0eb62c71aac4bc17216026d8410337c4126773b9c5daba343f17964f"
 dependencies = [
  "atomic-polyfill",
  "hash32",
- "rustc_version 0.4.0",
+ "rustc_version 0.4.1",
  "serde",
  "spin",
  "stable_deref_trait",
@@ -973,9 +973,9 @@ dependencies = [
 
 [[package]]
 name = "indicatif-log-bridge"
-version = "0.2.2"
+version = "0.2.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2963046f28a204e3e3fd7e754fd90a6235da05b5378f24707ff0ec9513725ce3"
+checksum = "63703cf9069b85dbe6fe26e1c5230d013dee99d3559cd3d02ba39e099ef7ab02"
 dependencies = [
  "indicatif",
  "log",
@@ -1084,9 +1084,9 @@ dependencies = [
 
 [[package]]
 name = "libz-sys"
-version = "1.1.19"
+version = "1.1.20"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fdc53a7799a7496ebc9fd29f31f7df80e83c9bda5299768af5f9e59eeea74647"
+checksum = "d2d16453e800a8cf6dd2fc3eb4bc99b786a9b90c663b8559a5b1a041bf89e472"
 dependencies = [
  "cc",
  "cmake",
@@ -1217,7 +1217,7 @@ checksum = "254a5372af8fc138e36684761d3c0cdb758a4410e938babcff1c860ce14ddbfc"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.75",
+ "syn 2.0.77",
 ]
 
 [[package]]
@@ -1353,9 +1353,9 @@ dependencies = [
 
 [[package]]
 name = "openssl-src"
-version = "300.3.1+3.3.1"
+version = "300.3.2+3.3.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7259953d42a81bf137fbbd73bd30a8e1914d6dce43c2b90ed575783a22608b91"
+checksum = "a211a18d945ef7e648cc6e0058f4c548ee46aab922ea203e0d30e966ea23647b"
 dependencies = [
  "cc",
 ]
@@ -1388,6 +1388,14 @@ dependencies = [
  "num-traits",
 ]
 
+[[package]]
+name = "pandora_lib_graph"
+version = "0.1.0"
+source = "git+https://git.t0m4.fr/Thomas/pandora_lib_graph.git#87ea889f2c132fc0c162cf01fb2383a0667c4ef1"
+dependencies = [
+ "pandora_lib_scan 0.1.0 (git+https://git.t0m4.fr/Thomas/pandora_lib_scan.git)",
+]
+
 [[package]]
 name = "pandora_lib_pileup"
 version = "0.1.0"
@@ -1406,6 +1414,34 @@ dependencies = [
 [[package]]
 name = "pandora_lib_scan"
 version = "0.1.0"
+dependencies = [
+ "anyhow",
+ "crossbeam-channel",
+ "csv",
+ "dashmap",
+ "env_logger",
+ "flate2",
+ "indicatif",
+ "indicatif-log-bridge",
+ "log",
+ "num-format",
+ "ordered-float",
+ "pandora_lib_graph",
+ "pandora_lib_pileup",
+ "plotly",
+ "postcard",
+ "rayon",
+ "rust-htslib",
+ "serde",
+ "serde_json",
+ "statrs",
+ "uuid",
+]
+
+[[package]]
+name = "pandora_lib_scan"
+version = "0.1.0"
+source = "git+https://git.t0m4.fr/Thomas/pandora_lib_scan.git#6daa641b3b51905189137d4653bb8602421ec5f0"
 dependencies = [
  "anyhow",
  "crossbeam-channel",
@@ -1508,7 +1544,7 @@ dependencies = [
  "darling",
  "proc-macro2",
  "quote",
- "syn 2.0.75",
+ "syn 2.0.77",
 ]
 
 [[package]]
@@ -1533,9 +1569,9 @@ checksum = "da544ee218f0d287a911e9c99a39a8c9bc8fcad3cb8db5959940044ecfc67265"
 
 [[package]]
 name = "postcard"
-version = "1.0.9"
+version = "1.0.10"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "20ee10b999a00ca189ac2cb99f5db1ca71fb7371e3d5f493b879ca95d2a67220"
+checksum = "5f7f0a8d620d71c457dd1d47df76bb18960378da56af4527aaa10f515eee732e"
 dependencies = [
  "cobs",
  "embedded-io 0.4.0",
@@ -1576,9 +1612,9 @@ checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0"
 
 [[package]]
 name = "quote"
-version = "1.0.36"
+version = "1.0.37"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7"
+checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af"
 dependencies = [
  "proc-macro2",
 ]
@@ -1651,9 +1687,9 @@ dependencies = [
 
 [[package]]
 name = "redox_syscall"
-version = "0.5.3"
+version = "0.5.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2a908a6e00f1fdd0dfd9c0eb08ce85126f6d8bbda50017e74bc4a4b7d4a926a4"
+checksum = "0884ad60e090bf1345b93da0a5de8923c93884cd03f40dfcfddd3b4bee661853"
 dependencies = [
  "bitflags",
 ]
@@ -1729,7 +1765,7 @@ dependencies = [
  "rinja_parser",
  "rustc-hash 2.0.0",
  "serde",
- "syn 2.0.75",
+ "syn 2.0.77",
 ]
 
 [[package]]
@@ -1788,9 +1824,9 @@ dependencies = [
 
 [[package]]
 name = "rustc_version"
-version = "0.4.0"
+version = "0.4.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366"
+checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92"
 dependencies = [
  "semver 1.0.23",
 ]
@@ -1836,22 +1872,22 @@ checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b"
 
 [[package]]
 name = "serde"
-version = "1.0.208"
+version = "1.0.210"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cff085d2cb684faa248efb494c39b68e522822ac0de72ccf08109abde717cfb2"
+checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a"
 dependencies = [
  "serde_derive",
 ]
 
 [[package]]
 name = "serde_derive"
-version = "1.0.208"
+version = "1.0.210"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "24008e81ff7613ed8e5ba0cfaf24e2c2f1e5b8a0495711e44fcd4882fca62bcf"
+checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.75",
+ "syn 2.0.77",
 ]
 
 [[package]]
@@ -1874,7 +1910,7 @@ checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.75",
+ "syn 2.0.77",
 ]
 
 [[package]]
@@ -1904,7 +1940,7 @@ dependencies = [
  "darling",
  "proc-macro2",
  "quote",
- "syn 2.0.75",
+ "syn 2.0.77",
 ]
 
 [[package]]
@@ -1992,7 +2028,7 @@ dependencies = [
  "proc-macro2",
  "quote",
  "rustversion",
- "syn 2.0.75",
+ "syn 2.0.77",
 ]
 
 [[package]]
@@ -2014,9 +2050,9 @@ dependencies = [
 
 [[package]]
 name = "syn"
-version = "2.0.75"
+version = "2.0.77"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f6af063034fc1935ede7be0122941bafa9bacb949334d090b77ca98b5817c7d9"
+checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -2040,7 +2076,7 @@ checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.75",
+ "syn 2.0.77",
 ]
 
 [[package]]
@@ -2118,9 +2154,9 @@ checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75"
 
 [[package]]
 name = "unicode-ident"
-version = "1.0.12"
+version = "1.0.13"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
+checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe"
 
 [[package]]
 name = "unicode-normalization"
@@ -2203,7 +2239,7 @@ dependencies = [
  "once_cell",
  "proc-macro2",
  "quote",
- "syn 2.0.75",
+ "syn 2.0.77",
  "wasm-bindgen-shared",
 ]
 
@@ -2225,7 +2261,7 @@ checksum = "afc340c74d9005395cf9dd098506f7f44e38f2b4a21c6aaacf9a105ea5e1e836"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.75",
+ "syn 2.0.77",
  "wasm-bindgen-backend",
  "wasm-bindgen-shared",
 ]
@@ -2412,7 +2448,7 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.75",
+ "syn 2.0.77",
 ]
 
 [[package]]
@@ -2432,7 +2468,7 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.75",
+ "syn 2.0.77",
 ]
 
 [[package]]

+ 1 - 0
Cargo.toml

@@ -15,6 +15,7 @@ rust-htslib = "0.47.0"
 uuid = { version = "1.10.0", features = ["v4"] }
 # pandora_lib_variants = { git = "https://git.t0m4.fr/Thomas/pandora_lib_variants.git" }
 pandora_lib_pileup = { git = "https://git.t0m4.fr/Thomas/pandora_lib_pileup.git" }
+pandora_lib_graph = { git = "https://git.t0m4.fr/Thomas/pandora_lib_graph.git" }
 indicatif-log-bridge = "0.2.2"
 serde = { version = "1.0.*", default-features = false }
 postcard = { version = "1.0.8", features = ["alloc"] }

+ 1 - 116
src/counts.rs

@@ -190,42 +190,6 @@ impl Counts {
         }
     }
 
-    pub fn cumulative_coverage(
-        &self,
-        contig: &str, /* , median_len: f64 */
-    ) -> anyhow::Result<Vec<(u32, f64)>> {
-        if let Some(ccounts) = self.data.get(contig) {
-            let n_reads: Vec<u32> = ccounts.iter().map(|c| c.n_reads).collect();
-            if ccounts.is_empty() {
-                anyhow::bail!("No counts for {contig}")
-            }
-            let mut ccounts = ccounts.clone();
-            ccounts.sort_by_key(|c| c.n_reads);
-            let n_counts = ccounts.len();
-            let per = |x: f64| (x * (n_counts - 1) as f64).round() as usize;
-
-            let median = ccounts.get(per(0.5)).unwrap();
-
-            let index_95 = (0.99 * (n_counts - 1) as f64).round() as usize;
-            let v = ccounts.get(index_95).unwrap();
-            println!("99% {}", v.n_reads);
-            println!("99% {:?}", self.calculate_percentiles(contig, &[0.99])?);
-
-            let cov99 = ccounts.get(index_95).unwrap().n_reads;
-            // let mut last_start = 0;
-            let mut all_frac = vec![(0, 1.0)];
-            for i in 1..=cov99 {
-                let n_sup = ccounts.iter().filter(|c| c.n_reads >= i).count() as f64;
-                let frac = n_sup / n_counts as f64;
-                all_frac.push((i, frac));
-            }
-
-            Ok(all_frac)
-        } else {
-            anyhow::bail!("No {contig} in counts")
-        }
-    }
-
     pub fn nd_reads(&self, contig: &str) -> anyhow::Result<ND> {
         if let Some(ccounts) = self.data.get(contig) {
             Ok(ND::new(ccounts.iter().map(|c| c.n_reads).collect()))
@@ -237,7 +201,7 @@ impl Counts {
 
 use statrs::{
     distribution::{ContinuousCDF, Normal},
-    statistics::{Distribution, Statistics},
+    statistics::Distribution,
 };
 
 pub struct ND {
@@ -269,13 +233,6 @@ impl ND {
 
         // Fit normal distribution
         let fitted_normal = Self::fit_normal(&data);
-        // let fitted_normal = Self::fit_normal_with_outlier_removal(self, 2);
-
-        // let mean = data.iter().map(|&x| x as f64).sum::<f64>() / n as f64;
-        // let variance = data.iter().map(|&x| (x as f64 - mean).powi(2)).sum::<f64>() / n as f64;
-        // let std_dev = variance.sqrt();
-        //
-        // let fitted_normal = Normal::new(mean, std_dev).unwrap();
 
         Self {
             data,
@@ -305,68 +262,6 @@ impl ND {
         Normal::new(mean, std_dev).unwrap()
     }
 
-    fn fit_normal_with_outlier_removal(
-        data: Vec<u32>,
-        max_iterations: usize,
-        z_score_threshold: f64,
-        removal_percentage: f64,
-    ) -> Normal {
-        let mut current_data = data.clone();
-
-        for _ in 0..max_iterations {
-            // Calculate mean and standard deviation
-            let mean = current_data.iter().map(|&x| x as f64).mean();
-            let std_dev = current_data.iter().map(|&x| x as f64).std_dev();
-
-            // Identify outliers
-            let z_scores: Vec<f64> = current_data
-                .iter()
-                .map(|&x| (x as f64 - mean).abs() / std_dev)
-                .collect();
-
-            let outliers: Vec<bool> = z_scores.iter().map(|&z| z > z_score_threshold).collect();
-
-            // If no outliers, break
-            if !outliers.iter().any(|&x| x) {
-                break;
-            }
-
-            // Remove a percentage of the worst outliers
-            let num_to_remove = (current_data.len() as f64 * removal_percentage).round() as usize;
-            let mut indexed_z_scores: Vec<(usize, f64)> =
-                z_scores.into_iter().enumerate().collect();
-            indexed_z_scores.sort_by(|a, b| b.1.partial_cmp(&a.1).unwrap());
-
-            let indices_to_remove: Vec<usize> = indexed_z_scores
-                .iter()
-                .take(num_to_remove)
-                .map(|&(index, _)| index)
-                .collect();
-
-            current_data = current_data
-                .into_iter()
-                .enumerate()
-                .filter(|(i, _)| !indices_to_remove.contains(i))
-                .map(|(_, v)| v)
-                .collect();
-
-            println!(
-                "Iteration complete: {} points remaining",
-                current_data.len()
-            );
-        }
-
-        // Update the CDF with the cleaned data
-        // self.data = current_data;
-        // self.update_distribution();
-
-        // Return the fitted normal distribution
-        let data_wo_zero: Vec<f64> = data.iter().filter(|v| **v > 0).map(|v| *v as f64).collect();
-        let mean = data_wo_zero.clone().mean();
-        let std_dev = data_wo_zero.std_dev();
-        Normal::new(mean, std_dev).unwrap()
-    }
-
     pub fn pdf(&self, x: f64) -> f64 {
         let epsilon = 1e-6; // Small value for numerical differentiation
         let cdf_x = self.fitted_normal.cdf(x);
@@ -414,16 +309,6 @@ impl ND {
             .sum::<usize>();
         count as f64 / self.total_count as f64
     }
-    // pub fn proportion_under(&self, x: u32) -> f64 {
-    //     self.distribution
-    //         .range(..x)
-    //         .next_back()
-    //         .map_or(0.0, |(_, &prob)| prob)
-    // }
-    //
-    // pub fn proportion_above(&self, x: u32) -> f64 {
-    //     1.0 - self.cdf(x)
-    // }
 
     pub fn fitted_proportion_under(&self, x: f64) -> f64 {
         self.fitted_normal.cdf(x)

+ 61 - 91
src/lib.rs

@@ -303,48 +303,12 @@ pub fn par_whole_scan(dict_file: &str, bam_path: &str, out_dir: &str) -> anyhow:
     Ok(())
 }
 
-// pub fn mrd_count_ratio(mrd_bam: &str, count_file: &str) -> anyhow::Result<()> {
-//     let count_file = File::open(count_file)?;
-//     let reader = BufReader::new(count_file);
-//     let mut tumoral_counts = Vec::new();
-//     for line in reader.lines() {
-//         let line_split: Vec<&str> = line?.split("\t").collect();
-//         let pos = *line_split.get(0).context("Can't parse the tsv file")?;
-//         let (contig, pos) = pos.split_once(':').context("Can't parse the tsv file")?;
-//         let (start, end) = pos.split_once('-').context("Can't parse the tsv file")?;
-//         let start: u32 = start.parse()?;
-//         let end: u32 = end.parse()?;
-//         let n: u32 = line_split
-//             .get(1)
-//             .context("Can't parse the tsv file")?
-//             .parse::<u32>()?;
-//         tumoral_counts.push((contig.to_string(), start, end, n));
-//     }
-//
-//     let ratios: Vec<(usize, String, u32, u32, u32, u32, Option<f64>)> = tumoral_counts
-//         .par_iter()
-//         .enumerate()
-//         .map(|(i, (contig, start, end, n))| {
-//             let bin = Bin::new(mrd_bam, contig, *start, *end - *start + 1).unwrap();
-//             let n_mrd = bin.n_reads() as u32;
-//             let r = if n_mrd == 0 {
-//                 None
-//             } else {
-//                 Some((*n as f64 / n_mrd as f64).log10())
-//             };
-//             (i, contig.to_string(), *start, *end, *n, n_mrd, r)
-//         })
-//         .collect();
-//
-//     // filter_outliers_modified_z_score_with_indices(ratios.par_iter().map(|(_, _, _, _, _, _, r)))
-//     Ok(())
-// }
-
 #[cfg(test)]
 mod tests {
 
-    use counts::{ranges_over, ranges_under, Counts};
-    use plotly::{color::NamedColor, common::Marker, Bar, Plot, Scatter};
+    use counts::{ranges_between, ranges_over, ranges_under, Counts};
+    use pandora_lib_graph::cytoband::{svg_chromosome, AdditionalRect, RectPosition};
+    use plotly::{common::Marker, Bar, Plot};
     use rust_htslib::bam::Reader;
 
     use super::*;
@@ -377,9 +341,6 @@ mod tests {
         let bam_path = format!("/data/longreads_basic_pipe/{id}/diag/{id}_diag_hs1.bam");
         let out_dir = format!("/data/longreads_basic_pipe/{id}/diag/scan");
         par_whole_scan("/data/ref/hs1/chm13v2.0.dict", &bam_path, &out_dir).unwrap();
-        // let bam_path = format!("/data/longreads_basic_pipe/{id}/mrd/{id}_mrd_hs1.bam");
-        // let out_dir = format!("/data/longreads_basic_pipe/{id}/mrd/scan");
-        // par_whole_scan("/data/ref/hs1/chm13v2.0.dict", &bam_path, &out_dir).unwrap();
     }
 
     #[test]
@@ -448,10 +409,11 @@ mod tests {
     fn load() -> anyhow::Result<()> {
         init();
         info!("loading");
-        let count_file = "/data/longreads_basic_pipe/ROBIN/diag/scan/chr1_counts.tsv";
+        let contig = "chr22";
+        let count_file = &format!("/data/longreads_basic_pipe/ROBIN/diag/scan/{contig}_counts.tsv");
         let counts = Counts::from_files(vec![count_file]);
 
-        let chr1_nd_reads = counts.nd_reads("chr1")?;
+        let chr1_nd_reads = counts.nd_reads(contig)?;
         println!(
             "Percentiles: 1% {}, 50% {}, 99% {}",
             chr1_nd_reads.percentile(1.0).unwrap(),
@@ -460,12 +422,61 @@ mod tests {
         );
         println!("< 6x: {:.2}%", chr1_nd_reads.proportion_under(6) * 100.0);
         println!("> 15x: {:.2}%", chr1_nd_reads.proportion_above(15) * 100.0);
-        let d = counts.get("chr1")?;
-        
-        let all_ranges = ranges_over(&d, 6, 10);
-        println!("Ranges over 1 : {:?}", all_ranges.len());
-        let all_ranges = ranges_under(&d, 6, 10);
-        println!("Ranges under 1 : {:?}", all_ranges.len());
+        let d = counts.get(contig)?;
+
+        let tol = 20;
+
+        let under_6_rects: Vec<AdditionalRect> = ranges_under(&d, 6, tol)
+            .iter()
+            .filter(|(s, e)| e > s)
+            // .filter(|(s, e)| e - s > tol)
+            .map(|(start, end)| AdditionalRect {
+                start: *start as u32 * 1000,
+                end: *end as u32 * 1000,
+                color: String::from("red"),
+                position: RectPosition::Below(0),
+            })
+            .collect();
+
+        let over_6_rects: Vec<AdditionalRect> = ranges_between(&d, 6, 15, tol)
+            .iter()
+            .filter(|(s, e)| e > s)
+            // .filter(|(s, e)| e - s > tol)
+            .map(|(start, end)| AdditionalRect {
+                start: *start as u32 * 1000,
+                end: *end as u32 * 1000,
+                color: String::from("green"),
+                position: RectPosition::Below(1),
+            })
+            .collect();
+
+        let over15: Vec<AdditionalRect> = ranges_over(&d, 15, tol)
+            .iter()
+            .filter(|(s, e)| e > s)
+            // .filter(|(s, e)| e - s > tol)
+            .map(|(start, end)| AdditionalRect {
+                start: *start as u32 * 1000,
+                end: *end as u32 * 1000,
+                color: String::from("blue"),
+                position: RectPosition::Below(2),
+            })
+            .collect();
+
+        let mut all = Vec::new();
+        all.extend(under_6_rects);
+        all.extend(over_6_rects);
+        all.extend(over15);
+
+        svg_chromosome(
+            contig,
+            1000,
+            50,
+            "/data/ref/hs1/cytoBandMapped.bed",
+            "/data/chr1.svg",
+            &all,
+            &Vec::new(),
+        )
+        .unwrap();
 
         let mut plot = Plot::new();
 
@@ -497,50 +508,9 @@ mod tests {
 
         plot.add_trace(bars);
 
-        // let trace = Scatter::new(
-        //     data.iter().map(|(x, _)| *x).collect::<Vec<f64>>(),
-        //     data.iter().map(|(_, y)| *y).collect::<Vec<f64>>(),
-        // );
-        // plot.add_trace(trace);
-        //
         plot.use_local_plotly();
-
         plot.write_image("/data/test2.svg", plotly::ImageFormat::SVG, 800, 600, 1.0);
 
-        // plot.write_html("out.html");
         Ok(())
     }
-
-    // #[test]
-    // fn phasing() -> anyhow::Result<()> {
-    //     let id = "SALICETTO";
-    //     let min_records = 2;
-    //
-    //     let logger =
-    //         env_logger::Builder::from_env(env_logger::Env::default().default_filter_or("info"))
-    //             .build();
-    //     let multi = MultiProgress::new();
-    //     LogWrapper::new(multi.clone(), logger).try_init().unwrap();
-    //
-    //     let config = PhaserConfig::new(id, "/data/longreads_basic_pipe", min_records, 0.33);
-    //     phase(config, multi)
-    // }
-    //
-    // #[test]
-    // fn load_phase() -> anyhow::Result<()> {
-    //     init();
-    //     let id = "SALICETTO";
-    //     let contig = "chr7";
-    //     let phases_dir = format!("/data/longreads_basic_pipe/{id}/diag/phases");
-    //     let phase_path = format!("{phases_dir}/{id}_{contig}_phases.postcard.gz");
-    //     let p = load_phases(&phase_path)?;
-    //     info!("{} phases", p.len());
-    //
-    //     for phase in p {
-    //         if let Some(phase_id) = &phase.id {
-    //             info!("{}\t{}", phase_id, phase.mean_vaf());
-    //         }
-    //     }
-    //     Ok(())
-    // }
 }