Example #1
0
    def check_recombination(self):
        epc = EditProposalCreator(self.control_sample.primary_base_calls,
                                  use_ctrl_trace=True,
                                  sanger_object=self.control_sample)

        if len(self.donor_odn) > len(
                self.control_sample.primary_base_calls) * 0.75:
            self.warnings.append(
                "Large Donor of {} bp compared to control sequence of {} bp".
                format(len(self.donor_odn),
                       len(self.control_sample.primary_base_calls)))

            #int((len(re.split("(-+)", alignment[0])) - 3) / 2)

        try:
            cutsite = self.guide_targets[0].cutsite
            hr_proposal, changed_bases, odn_start_pos, aln = epc.homologous_recombination_proposal(
                cutsite=cutsite, donor_sequence=self.donor_odn)

            self.recombined_seq = hr_proposal.sequence
            self.recombination_changed_bases = changed_bases
            self.odn_start_pos = odn_start_pos
            self.donor_alignment = aln

            n_splits = int(
                (len(re.split("(-+)", aln.all_aligned_seqs[0])) - 3) / 2)
            if n_splits > 0:
                self.warnings.append(
                    "{} donor integration sites".format(n_splits + 1))

        except Exception as e:
            self.warnings.append(
                "Could not analyze homologous recombination case: {}".format(
                    e))
            self.donor_odn = None
Example #2
0
    def check_recombination(self):
        epc = EditProposalCreator(self.control_sample.primary_base_calls,
                                  use_ctrl_trace=True,
                                  sanger_object=self.control_sample)
        try:
            cutsite = self.guide_targets[0].cutsite
            hr_proposal, changed_bases, odn_start_pos, aln = epc.homologous_recombination_proposal(
                cutsite=cutsite, donor_sequence=self.donor_odn)

            self.recombined_seq = hr_proposal.sequence
            self.recombination_changed_bases = changed_bases
            self.odn_start_pos = odn_start_pos
            self.donor_alignment = aln

        except Exception as e:
            self.warnings.append(
                "Could not analyze homologous recombination case: {}".format(
                    e))
            self.donor_odn = None
Example #3
0
def test_human_readable_sequence_single_edit_proposal():
    wt_basecalls = 'ACTGCCTGCACCTGTCCCCATAGAAATCCGCTTTACGGAGAGTCACTAGACTAGGACCCCCATAAATTTCACGACAGGGACTAGACCTTGACTGGATA'
    epc = EditProposalCreator(wt_basecalls, use_ctrl_trace=False)
    proposal = epc.single_cut_edit_proposal(27, 'g1', del_before=4)

    # test default padding
    seq = proposal.human_readable_sequence()
    assert seq == 'TGCCTGCACCTGTCCCCATAG----|CCGCTTTACGGAGAGTCACTAGACTAGGACCCCCATAAATTTCACGACAG'

    # test custom padding
    seq = proposal.human_readable_sequence(bp_before_cutsite=10, bp_after_cutsite=15)
    assert seq == 'CCATAG----|CCGCTTTACGGAGAG'

    # test passing in out of bounds padding values (should default to returning the entire proposed sequence)
    seq = proposal.human_readable_sequence(bp_before_cutsite=500, bp_after_cutsite=500)
    assert seq == 'ACTGCCTGCACCTGTCCCCATAG----|CCGCTTTACGGAGAGTCACTAGACTAGGACCCCCATAAATTTCACGACAGGGACTAGACCTTGACTGGAT'

    # test passing in inf values (should return the the entire proposed sequence)
    seq = proposal.human_readable_sequence(bp_before_cutsite=float('inf'), bp_after_cutsite=float('inf'))
    assert seq == 'ACTGCCTGCACCTGTCCCCATAG----|CCGCTTTACGGAGAGTCACTAGACTAGGACCCCCATAAATTTCACGACAGGGACTAGACCTTGACTGGAT'
Example #4
0
def test_human_readable_sequence_multiplex_proposal():
    wt_basecalls = ('CCCATAAATCCGCTTTACAGTCACTAGACTAGGACCAATTTCACGACAGGGACTAGACCTTGCTGGATAGCACCTGTCCCCATAGAAATGGCTATGGA'
                    'AAGCCTTTGGGTTATTTGCGGCACCTGTCCCCATAGAAATGGCTATGGAAAGCCTTTGGGTTATTTGCG')
    epc = EditProposalCreator(wt_basecalls, use_ctrl_trace=False)

    # test close together dropout default padding
    close_together_dropout_proposal = epc.multiplex_proposal(30, 50, 'g1', 'g2', dropout=True)
    seq = close_together_dropout_proposal.human_readable_sequence()
    assert seq == 'AAATCCGCTTTACAGTCACTAGACT|--------------------|GACTAGACCTTGCTGGATAGCACCTGTCCC'

    # test far apart dropout default padding
    far_apart_dropout_proposal = epc.multiplex_proposal(30, 90, 'g1', 'g2', dropout=True)
    seq = far_apart_dropout_proposal.human_readable_sequence()
    assert seq == ('AAATCCGCTTTACAGTCACTAGACT|------------------------------------------------------------|GCTATGGAAAGC'
                    'CTTTGGGTTATTT')

    # test far apart insertion default padding
    far_apart_dropout_proposal = epc.multiplex_proposal(30, 90, 'g1', 'g2', dropout=False, cut1_ins=2, cut2_ins=4)
    seq = far_apart_dropout_proposal.human_readable_sequence()
    assert seq == ('ATCCGCTTTACAGTCACTAGACTnn|AGGACCAATTTCACGACAGGGACTAGACCTTGCTGGATAGCACCTGTCCCCATAGAAATGnnnn|GCTATGGA'
                    'AAGCCTTTGGGTTATTT')
Example #5
0
def test_generated_trace():
    seq = "ATNCG"

    epc = EditProposalCreator(seq, use_ctrl_trace=False)

    expected_trace = {'A':[], 'T':[], 'C':[], 'G':[]}
    for base in seq:
        if base == 'N':
            for color in expected_trace.keys():
                expected_trace[color].append(0.25)
        else:
            for color in epc.base_order:
                if color == base:
                    expected_trace[color].append(0.97)
                else:
                    expected_trace[color].append(0.01)
    assert epc.wt_trace == expected_trace
Example #6
0
def test_single_cut():
    wt_basecalls = "GCACCTGTCCCCATAGAAAT"
    epc = EditProposalCreator(wt_basecalls, use_ctrl_trace=False)

    proposal = epc.single_cut_edit_proposal(10, "test", del_before=4)
    assert proposal.sequence == "GCACCTCCATAGAAAT"

    del_after_proposal = epc.single_cut_edit_proposal(10, "test", del_after=3)
    assert del_after_proposal.sequence == "GCACCTGTCCTAGAAAT"

    ins_proposal = epc.single_cut_edit_proposal(6, "test", insertion=2)
    assert ins_proposal.sequence.upper() == "GCACCTNNGTCCCCATAGAAAT"

    bad_config = epc.single_cut_edit_proposal(2, "bad", del_before=5)
    assert bad_config.sequence == "ACCTGTCCCCATAGAAAT"
Example #7
0
def test_multiplex_cut():
    wt_basecalls = "GCACCTGTCCCCATAGAAATGGCTATGGAAAGCCTTTGGGTTATTTGCG"
    "GCACCTGTCC-CCATAGAAATGGCTATGGAAAGCCT-TTGGGTTATTTGCG"
    epc = EditProposalCreator(wt_basecalls, use_ctrl_trace=False)

    dropout_proposal = epc.multiplex_proposal(10, 35, "test1", "test2", dropout=True)
    assert dropout_proposal.sequence == "GCACCTGTCCTTGGGTTATTTGCG"
    assert dropout_proposal.summary.startswith('-25:md')

    dropout_ins_proposal = epc.multiplex_proposal(10, 35, "test1", "test2", dropout=True, cut1_ins=2, cut2_ins=3)
    assert dropout_ins_proposal.sequence == "GCACCTGTCCnnTTGGGTTATTTGCG"

    indep_cut = epc.multiplex_proposal(10, 35, "test1", "test2", cut1_del=(4, 0), cut2_del=(0, 3))
    assert indep_cut.sequence == "GCACCTCCATAGAAATGGCTATGGAAAGCCTGGTTATTTGCG"
    assert indep_cut.summary.startswith('-7:m-4[test1]')

    indep_cut2 = epc.multiplex_proposal(10, 35, "test1", "test2", cut1_del=(-4, 0), cut2_del=(3, 0))
    assert indep_cut2.sequence == "GCACCTGTCCCCATAGAAATGGCTATGGAAAGTTGGGTTATTTGCG"
Example #8
0
    def _generate_edit_proposals(self):
        epc = EditProposalCreator(self.control_sample.primary_base_calls,
                                  use_ctrl_trace=True,
                                  sanger_object=self.control_sample)
        proposals = []

        # only consider HR for first guide_target
        # we have already run homologous_recombination_proposal earlier, so no need to catch exceptions
        if self.donor_odn is not None:
            cutsite = self.guide_targets[0].cutsite

            hr_proposal, changed_bases, odn_start_pos, aln = epc.homologous_recombination_proposal(
                cutsite=cutsite, donor_sequence=self.donor_odn)
            proposals.append(hr_proposal)

        # single cut cases
        for guide_target in self.guide_targets:
            cutsite = guide_target.cutsite
            # deletion case
            deletion_befores = list(range(self.indel_max_size + 1))
            deletion_afters = list(range(self.indel_max_size + 1))

            for deletion_before in deletion_befores:
                for deletion_after in deletion_afters:
                    ep = epc.single_cut_edit_proposal(
                        cutsite,
                        guide_target.label,
                        del_before=deletion_before,
                        del_after=deletion_after)
                    proposals.append(ep)

            insertions = list(range(self.indel_max_size))
            for insertion in insertions:
                ep = epc.single_cut_edit_proposal(cutsite,
                                                  guide_target.label,
                                                  insertion=insertion)
                proposals.append(ep)

        # multiplex case
        # we limit the deletion sizes here
        deletion_befores = list(range(5))
        deletion_afters = list(range(5))

        insertions = list(range(3))

        for combo in combinations(self.guide_targets, 2):
            guide1 = min(combo, key=lambda x: x.cutsite)
            guide2 = max(combo, key=lambda x: x.cutsite)
            cutsite1 = guide1.cutsite
            cutsite2 = guide2.cutsite
            if cutsite1 == cutsite2:
                print("Warning: cutsite1 == cutsite2")
                continue
            label1 = guide1.label
            label2 = guide2.label

            for cut1_before in deletion_befores:
                for cut1_after in deletion_afters:
                    for cut2_before in deletion_befores:
                        for cut2_after in deletion_afters:
                            independent_cut = epc.multiplex_proposal(
                                cutsite1,
                                cutsite2,
                                label1,
                                label2,
                                cut1_del=(cut1_before, cut1_after),
                                cut2_del=(cut2_before, cut2_after))
                            if independent_cut:
                                proposals.append(independent_cut)

            # dropout case
            for cut1_before in deletion_befores:
                for cut2_after in deletion_afters:
                    dropout = epc.multiplex_proposal(cutsite1,
                                                     cutsite2,
                                                     label1,
                                                     label2,
                                                     cut1_del=(cut1_before, 0),
                                                     cut2_del=(0, cut2_after),
                                                     dropout=True)
                    if dropout:
                        proposals.append(dropout)
            for insertion1 in insertions:
                for insertion2 in insertions:
                    cut_and_insert = epc.multiplex_proposal(
                        cutsite1,
                        cutsite2,
                        label1,
                        label2,
                        cut1_ins=insertion1,
                        cut2_ins=insertion2)
                    if cut_and_insert:
                        proposals.append(cut_and_insert)
            # dropout insertion case
            for insertion in insertions:
                dropout_and_insert = epc.multiplex_proposal(cutsite1,
                                                            cutsite2,
                                                            label1,
                                                            label2,
                                                            cut1_ins=insertion,
                                                            dropout=True)
                if dropout_and_insert:
                    proposals.append(dropout_and_insert)

        self.proposals = proposals
Example #9
0
    def _generate_edit_proposals(self):
        epc = EditProposalCreator(self.control_sample.primary_base_calls,
                                  use_ctrl_trace=True,
                                  sanger_object=self.control_sample)
        proposals = []

        if self.donor_odn is not None:
            cutsite = self.guide_targets[0].cutsite

            hr_proposal, changed_bases, odn_start_pos, aln = epc.homologous_recombination_proposal(
                cutsite=cutsite, donor_sequence=self.donor_odn)
            proposals.append(hr_proposal)

        # single cut cases
        for guide_target in self.guide_targets:
            cutsite = guide_target.cutsite

            # deletion case
            deletion_befores = list(range(self.indel_max_size + 1))
            deletion_afters = list(range(self.indel_max_size + 1))

            for deletion_before in deletion_befores:
                for deletion_after in deletion_afters:
                    indel_size = -(deletion_before + deletion_after)
                    if self._should_skip_proposal(indel_size):
                        continue
                    ep = epc.single_cut_edit_proposal(
                        cutsite,
                        guide_target.label,
                        del_before=deletion_before,
                        del_after=deletion_after)
                    proposals.append(ep)

            insertions = list(range(self.indel_max_size + 1))

            for insertion in insertions:
                if self._should_skip_proposal(insertion):
                    continue
                ep = epc.single_cut_edit_proposal(cutsite,
                                                  guide_target.label,
                                                  insertion=insertion)
                proposals.append(ep)

        # multiplex case
        # we limit the deletion sizes here
        deletion_befores = list(range(5))
        deletion_afters = list(range(5))

        insertions = list(range(3))

        for combo in combinations(self.guide_targets, 2):
            guide1 = min(combo, key=lambda x: x.cutsite)
            guide2 = max(combo, key=lambda x: x.cutsite)
            cutsite1 = guide1.cutsite
            cutsite2 = guide2.cutsite
            if cutsite1 == cutsite2:
                print("Warning: cutsite1 == cutsite2")
                continue
            label1 = guide1.label
            label2 = guide2.label

            for cut1_before in deletion_befores:
                for cut1_after in deletion_afters:
                    for cut2_before in deletion_befores:
                        for cut2_after in deletion_afters:
                            independent_cut = epc.multiplex_proposal(
                                cutsite1,
                                cutsite2,
                                label1,
                                label2,
                                cut1_del=(cut1_before, cut1_after),
                                cut2_del=(cut2_before, cut2_after))
                            if independent_cut:
                                proposals.append(independent_cut)

            # dropout case
            for cut1_before in deletion_befores:
                for cut2_after in deletion_afters:
                    dropout = epc.multiplex_proposal(cutsite1,
                                                     cutsite2,
                                                     label1,
                                                     label2,
                                                     cut1_del=(cut1_before, 0),
                                                     cut2_del=(0, cut2_after),
                                                     dropout=True)
                    if dropout:
                        proposals.append(dropout)
            for insertion1 in insertions:
                for insertion2 in insertions:
                    cut_and_insert = epc.multiplex_proposal(
                        cutsite1,
                        cutsite2,
                        label1,
                        label2,
                        cut1_ins=insertion1,
                        cut2_ins=insertion2)
                    if cut_and_insert:
                        proposals.append(cut_and_insert)
            # dropout insertion case
            for insertion in insertions:
                dropout_and_insert = epc.multiplex_proposal(cutsite1,
                                                            cutsite2,
                                                            label1,
                                                            label2,
                                                            cut1_ins=insertion,
                                                            dropout=True)
                if dropout_and_insert:
                    proposals.append(dropout_and_insert)

        #removing degenerate proposals
        seen = []
        self.proposals = list(
            filter(
                lambda x: seen.append(x.sequence) is None
                if x.sequence not in seen else False, proposals))
Example #10
0
def test_wt_proposal():
    wt_basecalls = "GCACCTGTCCCCGGGGAAAT"
    epc = EditProposalCreator(wt_basecalls, use_ctrl_trace=False)

    proposal = epc.single_cut_edit_proposal(10, "test")
    assert proposal.sequence == "GCACCTGTCCCCGGGGAAAT"
Example #11
0
def test_bad_multiplex():
    wt_basecalls = "GCACCTGTCCCCATAGAAATGGCTATGGAAAGCCTTTGGGTTATTTGCG"
    epc = EditProposalCreator(wt_basecalls, use_ctrl_trace=False)
    with pytest.raises(Exception):
        epc.multiplex_proposal(20, 10, "test1", "test2", dropout=True)
Example #12
0
def test_req_ctrl_trace():
    with pytest.raises(Exception):
        epc = EditProposalCreator("ATCG", use_ctrl_trace=True)