ultraplex/__main__.py
def three_p_demultiplex(read, d, add_umi, linked_bcds, linked_bcds_no_N, min_score, keep_barcodes,
                        reverse_complement=False):
    """
	read is a dnaio read
	d is the relevant match dictionary
	length is the length of the 3' barcodes (it assumes they're all the same)
	"""

    if reverse_complement:  # if it's paired end reverse complement the reverse read
        sequence = rev_c(read.sequence)
        qualities = read.qualities[::-1]  # just reverse - can't complement qualities!
    else:
        sequence = read.sequence
        qualities = read.qualities

    # find the positions of the non-N characters relative to 3' end
    # TODO precalculate these for faster operation - make a dict of positions for each 5' bacordes linked 3' barcodes
    bc_length_reference = len(linked_bcds[0])  # can use [0] because non-N guaranteed to be consistent
    non_N_poses = [a - bc_length_reference for a, b in enumerate(linked_bcds[0]) if b != "N"]  # all negative

    seq_length = len(sequence)
    positions_to_extract = [x + seq_length for x in non_N_poses]

    umi = ""  # initialise

    if min(positions_to_extract) >= 0:  # ensure long enough

        bc = ''.join(sequence[a] for a in positions_to_extract)

        if "dont_build" == d:
            assigned = score_barcode_for_dict(bc, linked_bcds_no_N, min_score, Ns_removed=True)
        else:
            assigned = d[bc]

        if reverse_complement:  # the sequence that will be removed
            to_remove = read.sequence[0:len(assigned)]
        else:
            # then it's not paired end, so we don't care
            to_remove = None

        if not assigned == "no_match":  # ie there is a match - then we need to trim
            bc_length = len(assigned)
            # add to umi
            umi_poses = [a - bc_length for a, b in enumerate(assigned) if b == 'N']
            umi_positions_to_extract = [x + seq_length for x in umi_poses]

            # check it's long enough to contain UMIs, or that there are no UMIs
            long_enough = False  # assume false
            if len(umi_poses) > 0:
                if min(umi_positions_to_extract) >= 0:
                    long_enough = True
            if len(umi_poses) == 0:
                long_enough = True

            if long_enough:
                umi = ''.join(sequence[a] for a in umi_positions_to_extract)
                length = len(assigned)
                if not keep_barcodes:
                    sequence = sequence[0:(len(read) - length)]
                    qualities = qualities[0:(len(read.qualities) - length)]
            else:  # barcode assigned, but read too short to contain full umi
                assigned = "no_match"

    else:  # read was too short for barcode to be extracted
        assigned = "no_match"
        to_remove = None

    if add_umi:
        if "rbc:" in read.name:
            read.name = read.name + umi
        else:
            read.name = read.name + "rbc:" + umi

    if reverse_complement:
        # spin back round
        read.sequence = rev_c(sequence)
        read.qualities = qualities[::-1]
    else:
        read.sequence = sequence
        read.qualities = qualities

    return read, assigned, umi, to_remove

	read is a dnaio read
	d is the relevant match dictionary
	length is the length of the 3' barcodes (it assumes they're all the same)
	
read is a dnaio read
d is the relevant match dictionary
length is the length of the 3' barcodes (it assumes they're all the same)
read is a dnaio read d is the relevant match dictionary length is the length of the 3 ' barcodes ( it assumes they ' re all the same )
def three_p_demultiplex(read, d, add_umi, linked_bcds, linked_bcds_no_N, min_score, keep_barcodes,
                        reverse_complement=False):
    if reverse_complement:  
        sequence = rev_c(read.sequence)
        qualities = read.qualities[::-1]  
    else:
        sequence = read.sequence
        qualities = read.qualities
    bc_length_reference = len(linked_bcds[0])  
    non_N_poses = [a - bc_length_reference for a, b in enumerate(linked_bcds[0]) if b != "N"]  
    seq_length = len(sequence)
    positions_to_extract = [x + seq_length for x in non_N_poses]
    umi = ""  
    if min(positions_to_extract) >= 0:  
        bc = ''.join(sequence[a] for a in positions_to_extract)
        if "dont_build" == d:
            assigned = score_barcode_for_dict(bc, linked_bcds_no_N, min_score, Ns_removed=True)
        else:
            assigned = d[bc]
        if reverse_complement:  
            to_remove = read.sequence[0:len(assigned)]
        else:
            to_remove = None
        if not assigned == "no_match":  
            bc_length = len(assigned)
            umi_poses = [a - bc_length for a, b in enumerate(assigned) if b == 'N']
            umi_positions_to_extract = [x + seq_length for x in umi_poses]
            long_enough = False  
            if len(umi_poses) > 0:
                if min(umi_positions_to_extract) >= 0:
                    long_enough = True
            if len(umi_poses) == 0:
                long_enough = True
            if long_enough:
                umi = ''.join(sequence[a] for a in umi_positions_to_extract)
                length = len(assigned)
                if not keep_barcodes:
                    sequence = sequence[0:(len(read) - length)]
                    qualities = qualities[0:(len(read.qualities) - length)]
            else:  
                assigned = "no_match"
    else:  
        assigned = "no_match"
        to_remove = None
    if add_umi:
        if "rbc:" in read.name:
            read.name = read.name + umi
        else:
            read.name = read.name + "rbc:" + umi
    if reverse_complement:
        read.sequence = rev_c(sequence)
        read.qualities = qualities[::-1]
    else:
        read.sequence = sequence
        read.qualities = qualities
    return read, assigned, umi, to_remove
def three_p_demultiplex ( read , d , add_umi , linked_bcds , linked_bcds_no_N , min_score , keep_barcodes , reverse_complement = False ) : if reverse_complement : sequence = rev_c ( read . sequence ) qualities = read . qualities [ : : - 1 ] else : sequence = read . sequence qualities = read . qualities bc_length_reference = len ( linked_bcds [ 0 ] ) non_N_poses = [ a - bc_length_reference for a , b in enumerate ( linked_bcds [ 0 ] ) if b != "N" ] seq_length = len ( sequence ) positions_to_extract = [ x + seq_length for x in non_N_poses ] umi = "" if min ( positions_to_extract ) >= 0 : bc = '' . join ( sequence [ a ] for a in positions_to_extract ) if "dont_build" == d : assigned = score_barcode_for_dict ( bc , linked_bcds_no_N , min_score , Ns_removed = True ) else : assigned = d [ bc ] if reverse_complement : to_remove = read . sequence [ 0 : len ( assigned ) ] else : to_remove = None if not assigned == "no_match" : bc_length = len ( assigned ) umi_poses = [ a - bc_length for a , b in enumerate ( assigned ) if b == 'N' ] umi_positions_to_extract = [ x + seq_length for x in umi_poses ] long_enough = False if len ( umi_poses ) > 0 : if min ( umi_positions_to_extract ) >= 0 : long_enough = True if len ( umi_poses ) == 0 : long_enough = True if long_enough : umi = '' . join ( sequence [ a ] for a in umi_positions_to_extract ) length = len ( assigned ) if not keep_barcodes : sequence = sequence [ 0 : ( len ( read ) - length ) ] qualities = qualities [ 0 : ( len ( read . qualities ) - length ) ] else : assigned = "no_match" else : assigned = "no_match" to_remove = None if add_umi : if "rbc:" in read . name : read . name = read . name + umi else : read . name = read . name + "rbc:" + umi if reverse_complement : read . sequence = rev_c ( sequence ) read . qualities = qualities [ : : - 1 ] else : read . sequence = sequence read . qualities = qualities return read , assigned , umi , to_remove
read is a dnaio read
d is the relevant match dictionary
length is the length of the 3' barcodes (it assumes they're all the same)
read is a dnaio read d is the relevant match dictionary length is the length of the 3 ' barcodes ( it assumes they ' re all the same )
"""
	read is a dnaio read
	d is the relevant match dictionary
	length is the length of the 3' barcodes (it assumes they're all the same)
	""" # if it's paired end reverse complement the reverse read
 # just reverse - can't complement qualities!
 # find the positions of the non-N characters relative to 3' end
 # TODO precalculate these for faster operation - make a dict of positions for each 5' bacordes linked 3' barcodes
 # can use [0] because non-N guaranteed to be consistent
 # all negative
 # initialise
 # ensure long enough
 # the sequence that will be removed
 # then it's not paired end, so we don't care
 # ie there is a match - then we need to trim
 # add to umi
 # check it's long enough to contain UMIs, or that there are no UMIs
 # assume false
 # barcode assigned, but read too short to contain full umi
 # read was too short for barcode to be extracted
 # spin back round

read
d
add_umi
linked_bcds
linked_bcds_no_N
min_score
keep_barcodes
reverse_complement