Browse Source

DeletionDesc

Thomas 8 months ago
parent
commit
6b56b12960
2 changed files with 68 additions and 32 deletions
  1. 58 4
      src/variant/variant.rs
  2. 10 28
      src/variant/variant_collection.rs

+ 58 - 4
src/variant/variant.rs

@@ -339,6 +339,46 @@ impl VcfVariant {
             Err(anyhow::anyhow!("The alteration is not BND: {alt}"))
         }
     }
+
+    pub fn deletion_len(&self) -> Option<u32> {
+        if self.alteration_category() != AlterationCategory::DEL {
+            return None;
+        }
+
+        self.infos
+            .0
+            .iter()
+            .find_map(|i| {
+                if let Info::SVLEN(len) = i {
+                    Some(*len as u32)
+                } else {
+                    None
+                }
+            })
+            .or_else(|| {
+                if let (
+                    ReferenceAlternative::Nucleotides(nt),
+                    ReferenceAlternative::Nucleotide(_),
+                ) = (&self.reference, &self.alternative)
+                {
+                    Some(nt.len().saturating_sub(1) as u32)
+                } else {
+                    None
+                }
+            })
+    }
+
+    pub fn deletion_desc(&self) -> Option<DeletionDesc> {
+        if let Some(len) = self.deletion_len() {
+            Some(DeletionDesc {
+                contig: self.position.contig(),
+                start: self.position.position + 1,
+                end: self.position.position + len,
+            })
+        } else {
+            None
+        }
+    }
 }
 
 #[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, Hash)]
@@ -352,6 +392,23 @@ pub struct BNDDesc {
     pub added_nt: String,
 }
 
+#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, Hash)]
+pub struct DeletionDesc {
+    pub contig: String,
+    pub start: u32, // 1-based
+    pub end: u32,
+}
+
+impl DeletionDesc {
+    pub fn len(&self) -> u32 {
+        self.end.saturating_sub(self.start)
+    }
+
+    pub fn is_empty(&self) -> bool {
+        self.len() == 0
+    }
+}
+
 #[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, Hash, Encode, Decode)]
 pub enum AlterationCategory {
     SNV,
@@ -1102,7 +1159,6 @@ macro_rules! create_should_run {
     }};
 }
 
-
 /// Macro to initialize and box a list of solo-mode pipeline components that implement `ShouldRunTrait`.
 ///
 /// This is typically used for per-timepoint variant callers (e.g., `DeepVariant`),
@@ -1212,7 +1268,6 @@ macro_rules! create_should_run_normal_tumoral {
     }};
 }
 
-
 /// Executes each runner in the slice only if `should_run()` returns true.
 ///
 /// # Arguments
@@ -1243,7 +1298,7 @@ pub fn run_if_required(iterable: &mut [ShouldRunBox]) -> anyhow::Result<()> {
 pub trait RunnerVariants: Variants + Send + Sync + Label {}
 
 /// Blanket implementation for all compatible types.
-impl<T> RunnerVariants for T where T:  Variants + Send + Sync + Label {}
+impl<T> RunnerVariants for T where T: Variants + Send + Sync + Label {}
 
 pub type CallerBox = Box<dyn RunnerVariants + Send + Sync>;
 
@@ -1264,7 +1319,6 @@ macro_rules! init_somatic_callers {
     }};
 }
 
-
 /// Macro to initialize and box a list of **solo-mode variant callers** for specific timepoints,
 /// where each runner implements `RunnerVariants`.
 ///

+ 10 - 28
src/variant/variant_collection.rs

@@ -505,7 +505,10 @@ impl Variant {
     /// }
     /// ```
     pub fn insertion_length(&self) -> Option<u32> {
-        if !self.alteration_category().contains(&AlterationCategory::INS) {
+        if !self
+            .alteration_category()
+            .contains(&AlterationCategory::INS)
+        {
             return None;
         }
         self.vcf_variants
@@ -538,35 +541,14 @@ impl Variant {
             .max()
     }
 
-     pub fn deletion_length(&self) -> Option<u32> {
-        if !self.alteration_category().contains(&AlterationCategory::DEL) {
-            return None;
-        }
+    /// Returns the maximum deletion length among all VCF variants.
+    ///
+    /// Iterates over `vcf_variants`, extracts the `deletion_len` if present,
+    /// and returns the maximum value. Returns `None` if no deletion lengths are available.
+    pub fn deletion_length(&self) -> Option<u32> {
         self.vcf_variants
             .iter()
-            .filter_map(|v| {
-                v.infos
-                    .0
-                    .iter()
-                    .find_map(|i| {
-                        if let Info::SVLEN(len) = i {
-                            Some(*len as u32)
-                        } else {
-                            None
-                        }
-                    })
-                    .or_else(|| {
-                        if let (
-                            ReferenceAlternative::Nucleotides(nt),
-                            ReferenceAlternative::Nucleotide(_),
-                        ) = (&v.reference, &self.alternative)
-                        {
-                            Some(nt.len().saturating_sub(1) as u32)
-                        } else {
-                            None
-                        }
-                    })
-            })
+            .filter_map(|v| v.deletion_len())
             .max()
     }