variant_caller.py
def call_variant(self, genomePositionInfo, correct_probability = 0.8, use_read_quality = False):
        """ Chooses variant and updates genomePositionInfo dictionary with chosen variant genotype, alts field, more

        Parameters
        ----------
        genomePositionInfo: dictionary
            All info about one pileup position
        correct_probability: float
            Probability that one nucleotide in a read is correct
        use_read_quality: bool
            Whether to use correct_probability estimate calculated using read qualities
        """
        if use_read_quality:
            correct_probability = genomePositionInfo['average_quality']
        variant_count = { (base, 'SNV'): genomePositionInfo[base] for base in {'A', 'G', 'C', 'T'} }
        
        # Treat insertions and deletitions the same as SNVs
        if 'insertions' in genomePositionInfo:
            for insertion_string, insertion_count in genomePositionInfo['insertions']:
                variant_count[(insertion_string, 'INS')] = insertion_count
        if 'deletitions' in genomePositionInfo:
            for deletition_string, deletition_count in genomePositionInfo['deletitions']:
                variant_count[(deletition_string, 'DEL')] = deletition_count
        
        # Only keep two most likely bases
        
        candidate_variants = sorted(variant_count, key=variant_count.get, reverse=True)[:2]
        candidate_variant_count = [(variant, variant_count[variant]) for variant in candidate_variants]

        # Check if no candidate variant exists:
        if candidate_variant_count[0][1] == 0:
            genomePositionInfo['vaf'] = 1
            genomePositionInfo['genotype'] = (0, 0)
            genomePositionInfo['alts'] = '.'
            return

        # Check if only one option exists and skip calculations
        if candidate_variant_count[1][1] == 0:
            most_probable_variant = [candidate_variant_count[0][0]]
            confidence = 1
        else:
            most_probable_variant, confidence = self.__calculate_most_probable_variant__(candidate_variant_count, correct_probability)

        ref_variant_present = len([variant[0] for variant in most_probable_variant if (variant[0] == genomePositionInfo['ref_base'] and variant[1] == 'SNV')]) > 0

        alt_variants = [variant[0] for variant in most_probable_variant if variant[0] != genomePositionInfo['ref_base']]

        """
        After calling the variants, we need to store them in the vcf format.
        That means determining the ref_base field, alts field and genotype.

        |------------------------------------------------------------|
        |                    Table for some SNVs                     |
        |------------------------------------------------------------|
        |original ref|called variants|ref in vcf|alts in vcf|genotype|
        |------------------------------------------------------------|
        |     G      |       G       |     G    |     .     |   0/0  |
        |     G      |       T       |     G    |     T     |   1/1  |
        |     G      |      G,T      |     G    |     T     |   0/1  |
        |     G      |      A,T      |     G    |    A,T    |   1/2  |
        --------------------------------------------------------------
        """

        genomePositionInfo['vaf'] = confidence
        if len(alt_variants) == 0:
            genomePositionInfo['genotype'] = (0, 0)
            genomePositionInfo['alts'] = '.'
            return
        if ref_variant_present:
            genomePositionInfo['genotype'] = (0, 1)
        else:
            if len(alt_variants) == 1:
                genomePositionInfo['genotype'] = (1, 1)
            else:
                genomePositionInfo['genotype'] = (1, 2)

        # Extract variant types to diversify INDELs from SNVs
        alt_variant_types = [variant[1] for variant in most_probable_variant if variant[0] != genomePositionInfo['ref_base']]

        """
        Insertions and deletitions require some extra work when writing to alt and ref_base field, 
        given that we might want to change ref_base if we have deletitions, or store insertions as
        ref_base + insertion. Some examples of INDEL storing in vcf:

        |------------------------------------------------------------|
        |                    Table for some INDELS                   |
        |------------------------------------------------------------|
        |original ref|called variants|ref in vcf|alts in vcf|genotype|
        |------------------------------------------------------------|
        |     G      |     CTC IN    |     G    |    GCTC   |   1/1  |
        |     G      |     CTC DEL   |   GCTC   |     G     |   1/1  |
        |     G      |AC DEL, ACA DEL|   GACA   |    GA,G   |   1/2  |
        |     G      | TC DEL, AC IN |   GTC    |  G,GTCAC  |   1/2  |
        --------------------------------------------------------------
        """
        for position in range(len(alt_variants)):
            if alt_variant_types[position] == 'INS':
                alt_variants[position] = genomePositionInfo['ref_base'] + alt_variants[position]

        longest_deletition_string = ''
        for position in range(len(alt_variants)):
            if alt_variant_types[position] == 'DEL':
                if len(alt_variants[position]) > len(longest_deletition_string):
                    longest_deletition_string = alt_variants[position]

        for position in range(len(alt_variants)):
            if alt_variant_types[position] != 'DEL':
                alt_variants[position] += longest_deletition_string
            else:
                shorter_deletition_len = len(alt_variants[position])
                alt_variants[position] = genomePositionInfo['ref_base'] + longest_deletition_string[shorter_deletition_len:]
        genomePositionInfo['ref_base'] = genomePositionInfo['ref_base'] + longest_deletition_string

        genomePositionInfo['alts'] = alt_variants
 Chooses variant and updates genomePositionInfo dictionary with chosen variant genotype, alts field, more

        Parameters
        ----------
        genomePositionInfo: dictionary
            All info about one pileup position
        correct_probability: float
            Probability that one nucleotide in a read is correct
        use_read_quality: bool
            Whether to use correct_probability estimate calculated using read qualities
        
Chooses variant and updates genomePositionInfo dictionary with chosen variant genotype, alts field, more
Parameters

dictionary
All info about one pileup position
correct_probability: float
Probability that one nucleotide in a read is correct
use_read_quality: bool
Whether to use correct_probability estimate calculated using read qualities
Chooses variant and updates genomePositionInfo dictionary with chosen variant genotype alts field more Parameters dictionary All info about one pileup position correct_probability : float Probability that one nucleotide in a read is correct use_read_quality : bool Whether to use correct_probability estimate calculated using read qualities
def call_variant(self, genomePositionInfo, correct_probability = 0.8, use_read_quality = False):
        if use_read_quality:
            correct_probability = genomePositionInfo['average_quality']
        variant_count = { (base, 'SNV'): genomePositionInfo[base] for base in {'A', 'G', 'C', 'T'} }
        if 'insertions' in genomePositionInfo:
            for insertion_string, insertion_count in genomePositionInfo['insertions']:
                variant_count[(insertion_string, 'INS')] = insertion_count
        if 'deletitions' in genomePositionInfo:
            for deletition_string, deletition_count in genomePositionInfo['deletitions']:
                variant_count[(deletition_string, 'DEL')] = deletition_count
        candidate_variants = sorted(variant_count, key=variant_count.get, reverse=True)[:2]
        candidate_variant_count = [(variant, variant_count[variant]) for variant in candidate_variants]
        if candidate_variant_count[0][1] == 0:
            genomePositionInfo['vaf'] = 1
            genomePositionInfo['genotype'] = (0, 0)
            genomePositionInfo['alts'] = '.'
            return
        if candidate_variant_count[1][1] == 0:
            most_probable_variant = [candidate_variant_count[0][0]]
            confidence = 1
        else:
            most_probable_variant, confidence = self.__calculate_most_probable_variant__(candidate_variant_count, correct_probability)
        ref_variant_present = len([variant[0] for variant in most_probable_variant if (variant[0] == genomePositionInfo['ref_base'] and variant[1] == 'SNV')]) > 0
        alt_variants = [variant[0] for variant in most_probable_variant if variant[0] != genomePositionInfo['ref_base']]
        genomePositionInfo['vaf'] = confidence
        if len(alt_variants) == 0:
            genomePositionInfo['genotype'] = (0, 0)
            genomePositionInfo['alts'] = '.'
            return
        if ref_variant_present:
            genomePositionInfo['genotype'] = (0, 1)
        else:
            if len(alt_variants) == 1:
                genomePositionInfo['genotype'] = (1, 1)
            else:
                genomePositionInfo['genotype'] = (1, 2)
        alt_variant_types = [variant[1] for variant in most_probable_variant if variant[0] != genomePositionInfo['ref_base']]
        for position in range(len(alt_variants)):
            if alt_variant_types[position] == 'INS':
                alt_variants[position] = genomePositionInfo['ref_base'] + alt_variants[position]
        longest_deletition_string = ''
        for position in range(len(alt_variants)):
            if alt_variant_types[position] == 'DEL':
                if len(alt_variants[position]) > len(longest_deletition_string):
                    longest_deletition_string = alt_variants[position]
        for position in range(len(alt_variants)):
            if alt_variant_types[position] != 'DEL':
                alt_variants[position] += longest_deletition_string
            else:
                shorter_deletition_len = len(alt_variants[position])
                alt_variants[position] = genomePositionInfo['ref_base'] + longest_deletition_string[shorter_deletition_len:]
        genomePositionInfo['ref_base'] = genomePositionInfo['ref_base'] + longest_deletition_string
        genomePositionInfo['alts'] = alt_variants
def call_variant ( self , genomePositionInfo , correct_probability = 0.8 , use_read_quality = False ) : if use_read_quality : correct_probability = genomePositionInfo [ 'average_quality' ] variant_count = { ( base , 'SNV' ) : genomePositionInfo [ base ] for base in { 'A' , 'G' , 'C' , 'T' } } if 'insertions' in genomePositionInfo : for insertion_string , insertion_count in genomePositionInfo [ 'insertions' ] : variant_count [ ( insertion_string , 'INS' ) ] = insertion_count if 'deletitions' in genomePositionInfo : for deletition_string , deletition_count in genomePositionInfo [ 'deletitions' ] : variant_count [ ( deletition_string , 'DEL' ) ] = deletition_count candidate_variants = sorted ( variant_count , key = variant_count . get , reverse = True ) [ : 2 ] candidate_variant_count = [ ( variant , variant_count [ variant ] ) for variant in candidate_variants ] if candidate_variant_count [ 0 ] [ 1 ] == 0 : genomePositionInfo [ 'vaf' ] = 1 genomePositionInfo [ 'genotype' ] = ( 0 , 0 ) genomePositionInfo [ 'alts' ] = '.' return if candidate_variant_count [ 1 ] [ 1 ] == 0 : most_probable_variant = [ candidate_variant_count [ 0 ] [ 0 ] ] confidence = 1 else : most_probable_variant , confidence = self . __calculate_most_probable_variant__ ( candidate_variant_count , correct_probability ) ref_variant_present = len ( [ variant [ 0 ] for variant in most_probable_variant if ( variant [ 0 ] == genomePositionInfo [ 'ref_base' ] and variant [ 1 ] == 'SNV' ) ] ) > 0 alt_variants = [ variant [ 0 ] for variant in most_probable_variant if variant [ 0 ] != genomePositionInfo [ 'ref_base' ] ] """
        After calling the variants, we need to store them in the vcf format.
        That means determining the ref_base field, alts field and genotype.

        |------------------------------------------------------------|
        |                    Table for some SNVs                     |
        |------------------------------------------------------------|
        |original ref|called variants|ref in vcf|alts in vcf|genotype|
        |------------------------------------------------------------|
        |     G      |       G       |     G    |     .     |   0/0  |
        |     G      |       T       |     G    |     T     |   1/1  |
        |     G      |      G,T      |     G    |     T     |   0/1  |
        |     G      |      A,T      |     G    |    A,T    |   1/2  |
        --------------------------------------------------------------
        """ genomePositionInfo [ 'vaf' ] = confidence if len ( alt_variants ) == 0 : genomePositionInfo [ 'genotype' ] = ( 0 , 0 ) genomePositionInfo [ 'alts' ] = '.' return if ref_variant_present : genomePositionInfo [ 'genotype' ] = ( 0 , 1 ) else : if len ( alt_variants ) == 1 : genomePositionInfo [ 'genotype' ] = ( 1 , 1 ) else : genomePositionInfo [ 'genotype' ] = ( 1 , 2 ) alt_variant_types = [ variant [ 1 ] for variant in most_probable_variant if variant [ 0 ] != genomePositionInfo [ 'ref_base' ] ] """
        Insertions and deletitions require some extra work when writing to alt and ref_base field, 
        given that we might want to change ref_base if we have deletitions, or store insertions as
        ref_base + insertion. Some examples of INDEL storing in vcf:

        |------------------------------------------------------------|
        |                    Table for some INDELS                   |
        |------------------------------------------------------------|
        |original ref|called variants|ref in vcf|alts in vcf|genotype|
        |------------------------------------------------------------|
        |     G      |     CTC IN    |     G    |    GCTC   |   1/1  |
        |     G      |     CTC DEL   |   GCTC   |     G     |   1/1  |
        |     G      |AC DEL, ACA DEL|   GACA   |    GA,G   |   1/2  |
        |     G      | TC DEL, AC IN |   GTC    |  G,GTCAC  |   1/2  |
        --------------------------------------------------------------
        """ for position in range ( len ( alt_variants ) ) : if alt_variant_types [ position ] == 'INS' : alt_variants [ position ] = genomePositionInfo [ 'ref_base' ] + alt_variants [ position ] longest_deletition_string = '' for position in range ( len ( alt_variants ) ) : if alt_variant_types [ position ] == 'DEL' : if len ( alt_variants [ position ] ) > len ( longest_deletition_string ) : longest_deletition_string = alt_variants [ position ] for position in range ( len ( alt_variants ) ) : if alt_variant_types [ position ] != 'DEL' : alt_variants [ position ] += longest_deletition_string else : shorter_deletition_len = len ( alt_variants [ position ] ) alt_variants [ position ] = genomePositionInfo [ 'ref_base' ] + longest_deletition_string [ shorter_deletition_len : ] genomePositionInfo [ 'ref_base' ] = genomePositionInfo [ 'ref_base' ] + longest_deletition_string genomePositionInfo [ 'alts' ] = alt_variants
Chooses variant and updates genomePositionInfo dictionary with chosen variant genotype, alts field, more
Parameters
Chooses variant and updates genomePositionInfo dictionary with chosen variant genotype alts field more Parameters
""" Chooses variant and updates genomePositionInfo dictionary with chosen variant genotype, alts field, more

        Parameters
        ----------
        genomePositionInfo: dictionary
            All info about one pileup position
        correct_probability: float
            Probability that one nucleotide in a read is correct
        use_read_quality: bool
            Whether to use correct_probability estimate calculated using read qualities
        """ # Treat insertions and deletitions the same as SNVs # Only keep two most likely bases # Check if no candidate variant exists: # Check if only one option exists and skip calculations """
        After calling the variants, we need to store them in the vcf format.
        That means determining the ref_base field, alts field and genotype.

        |------------------------------------------------------------|
        |                    Table for some SNVs                     |
        |------------------------------------------------------------|
        |original ref|called variants|ref in vcf|alts in vcf|genotype|
        |------------------------------------------------------------|
        |     G      |       G       |     G    |     .     |   0/0  |
        |     G      |       T       |     G    |     T     |   1/1  |
        |     G      |      G,T      |     G    |     T     |   0/1  |
        |     G      |      A,T      |     G    |    A,T    |   1/2  |
        --------------------------------------------------------------
        """ # Extract variant types to diversify INDELs from SNVs """
        Insertions and deletitions require some extra work when writing to alt and ref_base field, 
        given that we might want to change ref_base if we have deletitions, or store insertions as
        ref_base + insertion. Some examples of INDEL storing in vcf:

        |------------------------------------------------------------|
        |                    Table for some INDELS                   |
        |------------------------------------------------------------|
        |original ref|called variants|ref in vcf|alts in vcf|genotype|
        |------------------------------------------------------------|
        |     G      |     CTC IN    |     G    |    GCTC   |   1/1  |
        |     G      |     CTC DEL   |   GCTC   |     G     |   1/1  |
        |     G      |AC DEL, ACA DEL|   GACA   |    GA,G   |   1/2  |
        |     G      | TC DEL, AC IN |   GTC    |  G,GTCAC  |   1/2  |
        --------------------------------------------------------------
        """
self
genomePositionInfo
correct_probability
use_read_quality