瀏覽代碼

variants json stats

Your Name 1 年之前
父節點
當前提交
da66982258
共有 11 個文件被更改,包括 272 次插入61 次删除
  1. 38 27
      Cargo.lock
  2. 8 8
      Cargo.toml
  3. 0 0
      af_data_rivoalen.tsv
  4. 1 1
      src/annotations/pangolin.rs
  5. 5 1
      src/annotations/vep.rs
  6. 1 1
      src/config.rs
  7. 4 1
      src/in_out/vcf_reader.rs
  8. 20 5
      src/in_out/vcf_writer.rs
  9. 1 1
      src/lib.rs
  10. 129 16
      src/variants.rs
  11. 65 0
      thomas@10.115.34.27

+ 38 - 27
Cargo.lock

@@ -178,9 +178,9 @@ dependencies = [
 
 [[package]]
 name = "bit-vec"
-version = "0.7.0"
+version = "0.8.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d2c54ff287cfc0a34f38a6b832ea1bd8e448a330b3e40a50859e6488bee07f22"
+checksum = "5e764a1d40d510daf35e07be9eb06e75770908c27d411ee6c92109c9840eaaf7"
 
 [[package]]
 name = "bitflags"
@@ -1086,15 +1086,15 @@ dependencies = [
 
 [[package]]
 name = "noodles-bam"
-version = "0.66.0"
+version = "0.67.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "69ab4109074a07e6066cc0ba46db7e1c2ffc8f3e12d1c7aeb9811e6ff37e67c6"
+checksum = "53bc69bd00891e3e1c5faffe4f55d00c94d9e53d4bdbe63ec8c7e2b881f3bc85"
 dependencies = [
  "bstr",
  "byteorder",
  "bytes",
  "indexmap",
- "noodles-bgzf",
+ "noodles-bgzf 0.33.0",
  "noodles-core",
  "noodles-csi",
  "noodles-sam",
@@ -1112,6 +1112,18 @@ dependencies = [
  "flate2",
 ]
 
+[[package]]
+name = "noodles-bgzf"
+version = "0.33.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3b50aaa8f0a3c8a0b738b641a6d1a78d9fd30a899ab2d398779ee3c4eb80f1c1"
+dependencies = [
+ "byteorder",
+ "bytes",
+ "crossbeam-channel",
+ "flate2",
+]
+
 [[package]]
 name = "noodles-core"
 version = "0.15.0"
@@ -1123,14 +1135,14 @@ dependencies = [
 
 [[package]]
 name = "noodles-csi"
-version = "0.37.0"
+version = "0.38.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e4bc8001c54f1d8e47e1ac6041a5f27edc99b68bacea3fade9c89059de285aea"
+checksum = "a69e79dbc09bd0cb86d29469ed29066e9a163bce6640527b343bdea458144618"
 dependencies = [
  "bit-vec",
  "byteorder",
  "indexmap",
- "noodles-bgzf",
+ "noodles-bgzf 0.33.0",
  "noodles-core",
 ]
 
@@ -1143,31 +1155,31 @@ dependencies = [
  "bstr",
  "bytes",
  "memchr",
- "noodles-bgzf",
+ "noodles-bgzf 0.32.0",
  "noodles-core",
 ]
 
 [[package]]
 name = "noodles-fasta"
-version = "0.42.0"
+version = "0.43.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d60db7c4c514211598f2d7eb38e499e3b42d3eb690779fd0b36f224650c75c82"
+checksum = "0634eec06d20e899a5d99922c40fa5186064d8c675c78690a461ccbb2edc60d1"
 dependencies = [
  "bstr",
  "bytes",
  "memchr",
- "noodles-bgzf",
+ "noodles-bgzf 0.33.0",
  "noodles-core",
 ]
 
 [[package]]
 name = "noodles-gff"
-version = "0.35.0"
+version = "0.37.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "adef59012090b5694b58cad0e4426cd18af404803f942d02e664af607d89ee28"
+checksum = "8750c06d43f2066ea511a874ed5736470c883f2e39cd0f60f28dd4530d4591b4"
 dependencies = [
  "indexmap",
- "noodles-bgzf",
+ "noodles-bgzf 0.33.0",
  "noodles-core",
  "noodles-csi",
  "percent-encoding",
@@ -1175,43 +1187,42 @@ dependencies = [
 
 [[package]]
 name = "noodles-sam"
-version = "0.63.0"
+version = "0.64.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "460564b59da27a291616ea9f515e8eda8624a5d64b214423fcf1f1819b05cd78"
+checksum = "72da678e9332b32a916f8c5d5a7c4324da11891bc7148077744566981acaf00c"
 dependencies = [
  "bitflags",
  "bstr",
  "indexmap",
  "lexical-core",
  "memchr",
- "noodles-bgzf",
+ "noodles-bgzf 0.33.0",
  "noodles-core",
  "noodles-csi",
 ]
 
 [[package]]
 name = "noodles-tabix"
-version = "0.43.0"
+version = "0.44.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "545e16e229b7f8734b0a2a36bd4c98a5b70128663b16b5201ddadc0d09c28d4a"
+checksum = "263e63f58871224d0cd30ffc4a8531fb4f8f8ec686807febde8e19a69673fe01"
 dependencies = [
- "bit-vec",
  "byteorder",
  "indexmap",
- "noodles-bgzf",
+ "noodles-bgzf 0.33.0",
  "noodles-core",
  "noodles-csi",
 ]
 
 [[package]]
 name = "noodles-vcf"
-version = "0.62.0"
+version = "0.65.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c6f64c43315f757fe42ae014cf83996698cc9e47388080db165d0eb7b5f74092"
+checksum = "37459769faa61c655a2f0cfc1f068c69dbaf92eb648250bd7a7e544b6c6664d0"
 dependencies = [
  "indexmap",
  "memchr",
- "noodles-bgzf",
+ "noodles-bgzf 0.33.0",
  "noodles-core",
  "noodles-csi",
  "noodles-tabix",
@@ -1340,10 +1351,10 @@ dependencies = [
  "indicatif-log-bridge",
  "log",
  "noodles-bam",
- "noodles-bgzf",
+ "noodles-bgzf 0.33.0",
  "noodles-core",
  "noodles-csi",
- "noodles-fasta 0.42.0",
+ "noodles-fasta 0.43.0",
  "noodles-gff",
  "noodles-sam",
  "noodles-tabix",

+ 8 - 8
Cargo.toml

@@ -26,14 +26,14 @@ rust-htslib = "0.47.0"
 uuid = { version = "1.10.0", features = ["serde", "v4"] }
 prettytable-rs = "^0.10"
 noodles-core = "0.15.0"
-noodles-gff = "0.35.0"
-noodles-bgzf = "0.32.0"
-noodles-csi = "0.37.0"
-noodles-fasta = "0.42.0"
-noodles-sam = "0.63.0"
-noodles-bam = "0.66.0"
-noodles-vcf = "0.62.0"
-noodles-tabix = "0.43.0"
+noodles-gff = "0.37.0"
+noodles-bgzf = "0.33.0"
+noodles-csi = "0.38.0"
+noodles-fasta = "0.43.0"
+noodles-sam = "0.64.0"
+noodles-bam = "0.67.0"
+noodles-vcf = "0.65.0"
+noodles-tabix = "0.44.0"
 rayon = "1.10.0"
 serde_rusqlite = "0.35.0"
 dashmap = { version = "6.0.1", features = ["rayon", "serde"] }

文件差異過大導致無法顯示
+ 0 - 0
af_data_rivoalen.tsv


+ 1 - 1
src/annotations/pangolin.rs

@@ -23,7 +23,7 @@ pub struct Pangolin {
 pub fn run_pangolin(in_path: &str) -> Result<String> {
     let tmp_file = format!("/tmp/{}", Uuid::new_v4());
 
-    let bin_dir = "/home/prom/.local/bin";
+    let bin_dir = "/data/miniconda3/bin";
     let ref_fa = "/data/ref/hs1/hs1_simple_chr.fa";
     let db = "/data/ref/hs1/gencode.v44.liftedTohs1.db";
 

+ 5 - 1
src/annotations/vep.rs

@@ -201,7 +201,9 @@ pub fn vep_chunk(data: &mut [Variant]) -> Result<()> {
         )?;
     }
 
-    run_vep(&in_vcf, &out_vep)?;
+    if let Err(err) = run_vep(&in_vcf, &out_vep) {
+        panic!("{err}");
+    };
 
     // read the results in txt file, parse and add to HashMap
     let mut reader_vep = ReaderBuilder::new()
@@ -261,6 +263,7 @@ pub fn vep_chunk(data: &mut [Variant]) -> Result<()> {
     Ok(())
 }
 
+// VEP need plugin Downstream and SpliceRegion /home/prom/.vep/Plugins
 fn run_vep(in_path: &str, out_path: &str) -> Result<()> {
     let bin_dir = "/data/tools/ensembl-vep";
     let dir_cache = "/data/ref/hs1/vepcache/";
@@ -300,6 +303,7 @@ fn run_vep(in_path: &str, out_path: &str) -> Result<()> {
     reader
         .lines()
         .map_while(Result::ok)
+        // .inspect(|y| println!("{y}"))
         .filter(|line| line.contains("error"))
         .for_each(|line| warn!("{}", line));
 

+ 1 - 1
src/config.rs

@@ -30,7 +30,7 @@ impl ::std::default::Default for Config {
             gff_path: "/data/ref/hs1/features_not_in_vep.gff.gz".to_string(),
             min_loh_diff: 0.25,
             deepvariant_loh_pval: 0.001,
-            min_mrd_depth: 6,
+            min_mrd_depth: 4,
             min_diversity: 1.6,
             vep_chunk_size: 1_000,
             max_gnomad_af: 0.01,

+ 4 - 1
src/in_out/vcf_reader.rs

@@ -85,7 +85,10 @@ pub fn read_vcf(
             if source == &VCFSource::Sniffles && row.reference == base_n && row.alt.len() > 1 {
                 row.pos -= 1;
             }
-            Variant::from_vcfrow(row, source.clone(), variant_type.clone()).unwrap()
+            let mut v = Variant::from_vcfrow(row, source.clone(), variant_type.clone()).unwrap();
+            v.get_depth();
+            v.get_n_alt();
+            v
         })
         .filter(|v| {
             for cd in v.callers_data.iter() {

+ 20 - 5
src/in_out/vcf_writer.rs

@@ -1,4 +1,4 @@
-use log::info;
+use log::{info, warn};
 use noodles_bgzf as bgzf;
 use noodles_csi::{self as csi};
 use noodles_tabix as tabix;
@@ -6,7 +6,9 @@ use vcf::variant::io::Write;
 use vcf::variant::record_buf::AlternateBases;
 use vcf::variant::RecordBuf;
 
+use std::fs;
 use std::io::BufRead;
+use std::path::Path;
 use std::{fs::File, io};
 
 use crate::in_out::get_reader;
@@ -143,8 +145,10 @@ pub fn write_vcf(path: &str, data: &mut [Variant], dict_file: &str) -> Result<()
     // let index_file = File::create(&format!("{}.csi", path)).expect("error creating index file");
     // let mut writer = csi::Writer::new(index_file);
     // csi::write(&format!("{}.csi", path), &index)?;
-    let index = vcf::index(path)?;
-    tabix::write(&format!("{}.tbi", path), &index)?;
+    // let index = noodles_vcf::io::reader::Builder::default().build_from_path(path)?;
+    let index = noodles_vcf::index(path)?;
+
+    tabix::write(format!("{}.tbi", path), &index)?;
 
     // writer.write_index(&index)?;
 
@@ -247,8 +251,19 @@ impl VariantWritter {
         // std::mem::swap(&mut idx, &mut self.indexer);
         // // std::mem::replace(&mut self.indexer, Indexer::default());
         // let index = idx.build();
-        let index = vcf::index(&self.path)?;
-        tabix::write(&format!("{}.tbi", &self.path), &index)?;
+        let index_path = format!("{}.tbi", &self.path);
+        if Path::new(&index_path).exists() {
+            fs::remove_file(&index_path)?;
+        }
+        match vcf::index(&self.path) {
+            std::result::Result::Ok(index) => {
+                if let Err(err) = tabix::write(&index_path, &index) {
+                    warn!("Can't write VCF index {index_path} {err}");
+                }
+            },
+            Err(err) => warn!("Can't write VCF index {index_path} {err}"),
+        }
+        
 
         Ok(())
     }

+ 1 - 1
src/lib.rs

@@ -28,7 +28,7 @@ mod tests {
 
     #[test]
     fn load_from_vcf() -> Result<()> {
-        let name = "PASSARD";
+        let name = "CONSIGNY";
 
         let logger =
             env_logger::Builder::from_env(env_logger::Env::default().default_filter_or("info"))

+ 129 - 16
src/variants.rs

@@ -33,7 +33,7 @@ use csv::ReaderBuilder;
 use dashmap::DashMap;
 use hashbrown::HashMap;
 use indicatif::{MultiProgress, ParallelProgressIterator};
-use log::info;
+use log::{info, warn};
 use noodles_core::{region::Region, Position};
 use noodles_fasta::indexed_reader::Builder as FastaBuilder;
 use noodles_gff as gff;
@@ -541,15 +541,19 @@ impl Variants {
         info!("Writing VCF {}", path);
 
         let mut to_write = sort_variants(self.get_cat(cat), &self.cfg.dict_file)?;
+        if to_write.is_empty() {
+            warn!("No variants to write");
+            return Ok(());
+        }
         let pg = self.mp.add(new_pg_speed(to_write.len() as u64));
         pg.set_message("Writing VCF");
 
         let mut w = VariantWritter::new(path, &self.cfg.dict_file)?;
         for row in to_write.iter_mut() {
-            w.write_variant(row)?;
+            w.write_variant(row).context(format!("Error writing VCF row {:#?}", row))?;
             pg.inc(1);
         }
-        w.write_index_finish()?;
+        w.write_index_finish().context(format!("Can't write index for {}", path))?;
         Ok(())
     }
 
@@ -591,7 +595,11 @@ impl Variants {
         self.data
             .par_chunks_mut(self.cfg.vep_chunk_size)
             .progress_with(pg)
-            .for_each(|chunks| vep_chunk(chunks).unwrap());
+            .for_each(|chunks| {
+                if let Err(err) = vep_chunk(chunks) {
+                    panic!("{err}");
+                }
+            });
     }
 
     /// sort_variants TODO
@@ -641,7 +649,9 @@ impl Variants {
                     .map(gff::Reader::new)
                     .unwrap();
 
-                let index = noodles_csi::read(format!("{}.csi", gff_path)).unwrap();
+                let index = noodles_csi::read(format!("{}.csi", gff_path))
+                    .context("Can't load csi index")
+                    .unwrap();
 
                 for v in chunk.iter_mut() {
                     let start = Position::try_from(v.position as usize).unwrap();
@@ -1056,9 +1066,22 @@ impl Variants {
         Ok(())
     }
 
+    pub fn stats_json(&self, path: &str) -> Result<()> {
+        let variants_stats = self.stats()?;
+        let all_stats = AllStats {
+            variants_stats,
+            vcf_stats: self.stats_vcf.clone(),
+            bam_stats: self.stats_bam.clone(),
+            n_variants: self.data.len(),
+        };
+        let s = serde_json::to_string(&all_stats)?;
+        fs::write(path, s)?;
+        Ok(())
+    }
+
     pub fn save_bytes(&self, path: &str) -> Result<()> {
         let serialized = pot::to_vec(&self.data)?;
-        let mut w = noodles_bgzf::writer::Builder::default().build_with_writer(File::create(path)?);
+        let mut w = noodles_bgzf::writer::Builder::default().build_from_writer(File::create(path)?);
         w.write_all(&serialized)?;
         Ok(())
     }
@@ -1110,6 +1133,14 @@ impl Stat {
     }
 }
 
+#[derive(Debug, Clone, Serialize)]
+pub struct AllStats {
+    pub variants_stats: Vec<Stat>,
+    pub vcf_stats: StatsVCF,
+    pub bam_stats: StatsBAM,
+    pub n_variants: usize,
+}
+
 #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, ToSchema)]
 pub struct Variant {
     pub contig: String,
@@ -1746,6 +1777,29 @@ pub fn run_pipe(name: &str, multi: &MultiProgress) -> Result<()> {
         cfg.longreads_results_dir
     );
 
+    let report_data_dir = format!(
+        "{}/{name}/diag/report/data",
+        cfg.longreads_results_dir
+    );
+    if !std::path::Path::new(&report_data_dir).exists() {
+        fs::create_dir_all(&report_data_dir)?;
+    }
+
+    let stats_path = format!(
+        "{}/{name}_variants_stats.json",
+        report_data_dir
+    );
+
+    let af_init_path = format!(
+        "{}/{name}_variants_af_init.csv",
+        report_data_dir
+    );
+
+    let af_final_path = format!(
+        "{}/{name}_variants_af_final.csv",
+        report_data_dir
+    );
+
     let sources = vec![
         (
             deepvariant_diag_vcf.as_str(),
@@ -1780,14 +1834,15 @@ pub fn run_pipe(name: &str, multi: &MultiProgress) -> Result<()> {
     ];
     let mut variants = Variants::from_vcfs(name.to_string(), sources, &cfg, multi.clone())?;
 
+    write_af_data(&variants, &af_init_path).context("Can't write initial AF data")?;
+    
     variants.vcf_filters();
-    variants.write_vcf_cat(&loh_path, &VariantCategory::LOH)?;
+    variants.write_vcf_cat(&loh_path, &VariantCategory::LOH).context("Can't write LOH")?;
     variants.bam_filters(&mrd_bam);
 
     let constits = variants.get_cat(&VariantCategory::Constit);
     let constits = Variants::from_vec(name.to_string(), multi, constits);
     constits.save_bytes(&bytes_constit_path)?;
-
     variants.keep_somatics_un();
     info!("Variants retained: {}", variants.len());
 
@@ -1802,7 +1857,7 @@ pub fn run_pipe(name: &str, multi: &MultiProgress) -> Result<()> {
     variants.sort()?;
     info!("Variants retained: {}", variants.len());
     variants.vep();
-    variants.pangolin()?;
+    // variants.pangolin()?;
 
     variants.annotate_gff_feature(&cfg.gff_path)?;
 
@@ -1810,14 +1865,15 @@ pub fn run_pipe(name: &str, multi: &MultiProgress) -> Result<()> {
     variants.filter_snp()?;
 
     variants.save_bytes(&bytes_path)?;
-    // variants.stats()?;
-    //
-    // if std::path::Path::new(&db_path).exists() {
-    //     crate::sql::variants_sql::remove_variants_names(&db_path, &name)?;
-    // }
-    //
+    variants.stats_json(&stats_path).context("Can't write stats")?;
+
+    write_af_data(&variants, &af_final_path).context("Can't write final AF data")?;
+
+    if std::path::Path::new(&db_path).exists() {
+        fs::remove_file(&db_path)?;
+        // crate::sql::variants_sql::remove_variants_names(&db_path, name)?;
+    }
     variants.save_sql(&db_path)?;
-    variants.stats_sql(&db_path)?;
     info!("Variants : {}", variants.len());
 
     Ok(())
@@ -1842,3 +1898,60 @@ pub fn run_pipe(name: &str, multi: &MultiProgress) -> Result<()> {
 //
 //     cluster_id
 // }
+
+fn write_af_data(variants: &Variants, path: &str) -> anyhow::Result<()> {
+    info!("Writing AF data into {path}");
+    let af_data: DashMap<u32, DashMap<u32, u32>> = DashMap::new();
+    variants.data.par_iter().for_each(|v| {
+        af_data
+            .entry(v.depth.unwrap())
+            .or_default()
+            .entry(v.n_alt.unwrap())
+            .and_modify(|count| *count += 1)
+            .or_insert(1);
+    });
+
+    write_dashmap_to_tsv(&af_data, path)?;
+    Ok(())
+}
+
+fn write_dashmap_to_tsv(
+    af_data: &DashMap<u32, DashMap<u32, u32>>,
+    filename: &str,
+) -> anyhow::Result<()> {
+    let mut writer = csv::Writer::from_path(filename)?;
+
+    // Find the maximum second key to determine the number of columns
+    let max_second_key = af_data
+        .iter()
+        .flat_map(|entry| {
+            entry
+                .value()
+                .iter()
+                .map(|inner_entry| *inner_entry.key())
+                .collect::<Vec<_>>()
+        })
+        .max()
+        .unwrap_or(0);
+
+    // Write header
+    let mut header = vec!["depth".to_string()];
+    header.extend((0..=max_second_key).map(|i| format!("n_alt_{}", i)));
+    writer.write_record(&header)?;
+
+    // Write data rows
+    for entry in af_data.iter() {
+        let depth = *entry.key();
+        let inner_map = entry.value();
+
+        let mut row = vec![depth.to_string()];
+        for i in 0..=max_second_key {
+            let count = inner_map.get(&i).map(|v| *v).unwrap_or(0).to_string();
+            row.push(count);
+        }
+        writer.write_record(&row)?;
+    }
+
+    writer.flush()?;
+    Ok(())
+}

+ 65 - 0
thomas@10.115.34.27

@@ -0,0 +1,65 @@
+depth,n_alt_0,n_alt_1,n_alt_2,n_alt_3,n_alt_4,n_alt_5,n_alt_6,n_alt_7,n_alt_8,n_alt_9,n_alt_10,n_alt_11,n_alt_12,n_alt_13,n_alt_14,n_alt_15,n_alt_16,n_alt_17,n_alt_18,n_alt_19,n_alt_20,n_alt_21,n_alt_22,n_alt_23,n_alt_24,n_alt_25,n_alt_26,n_alt_27,n_alt_28,n_alt_29,n_alt_30,n_alt_31,n_alt_32,n_alt_33,n_alt_34,n_alt_35,n_alt_36,n_alt_37,n_alt_38,n_alt_39,n_alt_40,n_alt_41,n_alt_42,n_alt_43,n_alt_44,n_alt_45,n_alt_46,n_alt_47,n_alt_48,n_alt_49,n_alt_50,n_alt_51,n_alt_52,n_alt_53,n_alt_54,n_alt_55,n_alt_56,n_alt_57,n_alt_58
+27,0,0,0,16,19,14,12,5,13,16,9,17,11,9,11,13,7,4,3,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+19,0,0,24,97,78,88,92,80,72,69,79,48,45,11,18,6,5,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+67,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+2,0,0,926,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+45,0,0,0,0,0,0,0,0,0,1,0,2,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+6,0,0,315,270,133,64,55,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+50,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+4,0,0,486,307,188,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+9,0,0,184,204,173,107,67,23,21,10,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+17,0,1,31,111,109,105,128,103,107,76,71,67,19,5,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+40,0,0,0,1,2,0,0,0,1,1,2,1,0,0,1,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+44,0,0,0,0,0,0,0,0,1,0,1,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+182,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
+10,0,0,164,248,199,142,92,37,27,7,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+3,0,0,537,383,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+7,0,0,266,278,188,87,43,34,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+48,0,0,0,0,0,0,0,0,1,1,1,1,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+165,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+25,0,0,4,37,29,26,21,23,20,14,16,21,29,15,22,7,10,3,2,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+15,0,1,64,141,149,150,131,117,98,56,42,31,10,3,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+47,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+62,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
+8,0,0,223,214,176,102,63,20,13,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+54,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+34,0,0,0,3,4,2,2,5,4,5,3,0,1,0,0,2,1,0,0,1,5,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+11,0,0,129,200,161,164,104,92,44,13,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+23,0,0,12,57,38,44,54,38,47,39,37,32,31,17,18,10,9,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+21,0,1,10,72,63,46,64,44,67,42,41,54,42,30,26,13,1,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+49,0,0,0,0,0,0,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+29,0,0,0,14,11,14,3,10,7,2,6,6,12,6,12,1,5,5,3,4,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+35,0,0,0,2,2,0,3,1,0,1,2,4,1,2,2,2,2,0,0,0,2,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+24,0,0,10,41,31,31,28,34,35,40,38,29,27,27,17,12,5,4,3,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+31,0,0,0,3,9,3,8,6,13,10,1,2,6,3,6,4,2,4,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+68,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+43,0,0,0,0,1,0,1,0,1,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+12,0,0,111,172,178,163,134,91,57,19,7,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+22,0,0,15,62,43,58,51,46,42,60,59,47,31,23,20,14,2,2,3,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+30,0,0,0,7,6,9,6,3,12,7,6,4,6,5,4,7,5,2,4,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+58,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+20,0,0,17,81,70,61,75,69,72,83,59,60,39,25,16,6,4,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+42,0,0,0,0,1,0,0,0,2,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+39,0,0,0,0,1,3,5,1,1,0,0,2,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+52,0,0,0,0,0,0,0,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+57,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+32,0,0,0,5,3,10,1,4,3,5,3,1,2,5,6,2,2,1,3,3,1,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+33,0,0,0,3,3,4,5,3,4,6,1,2,1,3,2,3,1,1,0,2,6,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+38,0,0,0,0,1,0,2,2,1,0,1,0,2,0,0,0,0,0,1,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+28,0,0,0,12,11,11,8,9,11,8,11,12,19,9,5,5,4,6,2,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+26,0,0,0,26,20,25,16,21,22,23,19,23,18,17,8,9,7,8,1,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+53,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+64,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+18,0,0,23,109,84,94,95,111,88,89,89,53,30,9,5,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+79,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+13,0,1,102,138,152,163,187,110,62,32,25,6,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+46,0,0,0,0,0,0,1,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+59,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+37,0,0,0,1,1,4,1,2,3,2,0,0,2,2,1,0,2,2,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+55,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+16,0,0,45,124,125,122,132,114,118,88,44,26,7,10,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+5,0,0,301,218,117,118,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+36,0,0,0,1,1,4,2,3,3,1,1,1,0,0,0,3,2,2,1,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+14,0,0,68,151,156,193,138,117,78,48,29,16,3,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+41,0,0,0,1,0,1,0,0,0,0,3,0,1,0,1,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0

部分文件因文件數量過多而無法顯示