Thomas 10 months ago
parent
commit
d52909b2f9
2 changed files with 62 additions and 2 deletions
  1. 4 2
      src/lib.rs
  2. 58 0
      src/variant/variant.rs

+ 4 - 2
src/lib.rs

@@ -703,8 +703,10 @@ mod tests {
         variants.data.iter()
             .filter(|v| v.alteration_category().contains(&AlterationCategory::BND))
             .for_each(|v| {
-            println!("{}", [v.position.contig(), (v.position.position + 1).to_string(), v.reference.to_string(), v.alternative.to_string(), v.annotations.iter().filter(|a| matches!(a, Annotation::Callers(..)))
-                .map(|a| a.to_string()).collect::<Vec<String>>().join(";")].join("\t"))
+            println!("{:?} {}", 
+                v.vcf_variants.iter().map(|v| v.bnd_desc()).collect::<Vec<_>>(), 
+                v.annotations.iter().filter(|a| matches!(a, Annotation::Callers(..))).map(|a| a.to_string()).collect::<Vec<String>>().join(";")
+            )
         });
         Ok(())
 

+ 58 - 0
src/variant/variant.rs

@@ -196,6 +196,64 @@ impl VcfVariant {
             },
         }
     }
+
+    pub fn bnd_desc(&self) -> anyhow::Result<BNDDesc> {
+        let alt = self.alternative.to_string();
+        if self.alteration_category() == AlterationCategory::BND {
+            let b_sens = alt.contains('[');
+
+            let a_sens = if b_sens {
+                !alt.starts_with('[')
+            } else {
+                !alt.starts_with(']')
+            };
+
+            let parts: Vec<&str> = alt
+                .split(&['[', ']', ':'])
+                .filter(|v| !v.is_empty())
+                .collect();
+
+            if parts.len() != 3 {
+                return Err(anyhow::anyhow!("Failed to parse parts: {parts:?}"));
+            }
+
+            let (nt, b_contig, b_position) = if a_sens {
+                (parts[0], parts[1], parts[2])
+            } else {
+                (parts[2], parts[0], parts[1])
+            };
+
+            let added_nt = if nt.len() > 1 {
+                nt[1..].to_string()
+            } else {
+                nt.to_string()
+            };
+
+            Ok(BNDDesc {
+                a_contig: self.position.contig(),
+                a_position: self.position.position + 1,
+                a_sens,
+                b_contig: b_contig.to_string(),
+                b_position: b_position
+                    .parse()
+                    .map_err(|e| anyhow::anyhow!("Failed to parse: {b_position}\n{e}"))?,
+                b_sens,
+                added_nt,
+            })
+        } else {
+            Err(anyhow::anyhow!("The alteration is not BND: {alt}"))
+        }
+    }
+}
+#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, Hash)]
+pub struct BNDDesc {
+    pub a_contig: String,
+    pub a_position: u32, // 1-based
+    pub a_sens: bool,
+    pub b_contig: String,
+    pub b_position: u32, // 1-based
+    pub b_sens: bool,
+    pub added_nt: String,
 }
 
 #[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, Hash)]