--- a +++ b/singlecellmultiomics/fragment/scartrace.py @@ -0,0 +1,67 @@ +from singlecellmultiomics.utils.sequtils import reverse_complement +from singlecellmultiomics.fragment import Fragment + +class ScarTraceFragment(Fragment): + """ + Fragment definition for ScarTrace + """ + + def __init__(self, reads,scartrace_r1_primers=None, **kwargs): + Fragment.__init__(self, reads, **kwargs) + self.scartrace_r1_primers = scartrace_r1_primers + assert scartrace_r1_primers is not None, 'please supply primer sequences' + + # remove the set_umi function + def set_umi(self, **kwargs): + pass + + def is_valid(self): + """ Check if R1 starts with the defined primers and if R2 and R1 are mapped + + Returns: + bool + """ + if not self.has_R1() or not self.has_R2(): + if not self.has_R1(): + self.set_meta('fr','no_R1', as_set=True) + if not self.has_R2(): + self.set_meta('fr','no_R2', as_set=True) + return False + + if self[0].is_unmapped or self[1].is_unmapped: + self.set_meta('fr','unmapped_mate', as_set=True) + return False + + r1_seq = self.get_R1().seq + + if self.get_R1().is_reverse: + r1_seq = reverse_complement(r1_seq) + + if any( r1_seq.startswith(primer) for primer in self.scartrace_r1_primers ): + # Good + return True + + self.set_meta('fr','primer_not_matching', as_set=True) + # Bad + return False + + + + + # Replace the equality function + def __eq__(self, other): # other can also be a Molecule! + # Make sure fragments map to the same strand, cheap comparisons + if self.sample != other.sample: + return False + + if self.strand != other.strand: + return False + + if min(abs(self.span[1] - + other.span[1]), abs(self.span[2] - + other.span[2])) > self.assignment_radius: + return False + + # Sample matches and starting position is within the defined span + # radius + return True