From 70bc17e9f4045bdb44dd22ba3b3b2bf185124f10 Mon Sep 17 00:00:00 2001 From: David Bianchi Date: Tue, 19 Aug 2025 09:23:32 -0500 Subject: [PATCH 01/10] Move hard coded vars to command line args and update constants --- Primer_Design_SDM.py | 82 ++++++++++++++++++++++++++++---------------- 1 file changed, 53 insertions(+), 29 deletions(-) diff --git a/Primer_Design_SDM.py b/Primer_Design_SDM.py index d064059..c9ee222 100644 --- a/Primer_Design_SDM.py +++ b/Primer_Design_SDM.py @@ -12,6 +12,7 @@ import re import math from pathlib import Path +import argparse # Design primers in 96-well format for Site-directed mutagenesis. One mutation at a time for this script. @@ -25,39 +26,42 @@ ### INPUTS ########################### ###################################### -CODON_TABLE_FILE = 'Primer_Design/Codon_Table_Standard.csv' +#CODON_TABLE_FILE = 'Primer_Design/Codon_Table_Standard.csv' #ORF_FILE = 'Phytase_II.txt' # This file has intentional mistakes to test the script -ORF_FILE = 'Primer_Design/HMT.txt' ## Change input ORF filename -MUTATION_LIST_FILE = 'Primer_Design/HMT_Plate2.csv' ## Change input mutation csv filename. column name should be "Mutations" +#ORF_FILE = 'Primer_Design/HMT.txt' ## Change input ORF filename +#MUTATION_LIST_FILE = 'Primer_Design/HMT_Plate2.csv' ## Change input mutation csv filename. column name should be "Mutations" ### OUTPUTS ########################### ###################################### -BASE_DIR = Path.cwd() -print(BASE_DIR) -OUTPUT_DIR = 'Primer_Design/Primers_HMT_Plate2' # Change output folder -PRIMER_OUTPUT_FILE = 'HMT_Designed_primers.csv' # Change output file 1 -Forward_Primers_FILE = 'HMT_Forward_Primers_Plate2.csv' # Change output file 2 -Reverse_Primers_FILE = 'HMT_Reverse_Primers_Plate2.csv' # Change output file 3 +#BASE_DIR = Path.cwd() +#print(BASE_DIR) +#OUTPUT_DIR = 'Primer_Design/Primers_HMT_Plate2' # Change output folder +#PRIMER_OUTPUT_FILE = 'HMT_Designed_primers.csv' # Change output file 1 +#Forward_Primers_FILE = 'HMT_Forward_Primers_Plate2.csv' # Change output file 2 +#Reverse_Primers_FILE = 'HMT_Reverse_Primers_Plate2.csv' # Change output file 3 # Create the full path to the file ########################### ###################################### -Output_Path = BASE_DIR / OUTPUT_DIR / PRIMER_OUTPUT_FILE -Output_Path.parent.mkdir(parents=True, exist_ok=True) -Output_Path_Fwd = BASE_DIR / OUTPUT_DIR / Forward_Primers_FILE -Output_Path_Rev = BASE_DIR / OUTPUT_DIR / Reverse_Primers_FILE +def process_outputs(output_dir,primer_output_file,fwd_primers_file,rev_primers_file): + base_dir=Path.cwd() + Output_Path = base_dir / output_dir / primer_output_file + Output_Path.parent.mkdir(parents=True, exist_ok=True) + Output_Path_Fwd = base_dir / output_dir / fwd_primers_file + Output_Path_Rev = base_dir / output_dir / rev_primers_file + return Output_Path, Output_Path_Fwd, Output_Path_Rev ###################################### ###################################### -def remind_user_to_check_constants(): +def remind_user_to_check_constants(mut_file,out_path,orf_file,codon_file): """Reminds the user to review constants and make changes if needed.""" print("\n⚠️ Reminder: Please check the following constants: \n") - print(f" - MUTATION_FILE: {MUTATION_LIST_FILE}\n") - print(f" - PRIMER_OUTPUT: {Output_Path}\n") - print(f" - ORF_FILE: {ORF_FILE}\n") - print(f" - CODON_TABLE: {CODON_TABLE_FILE}\n") + print(f" - MUTATION_FILE: {mut_file}\n") + print(f" - PRIMER_OUTPUT: {out_path}\n") + print(f" - ORF_FILE: {orf_file}\n") + print(f" - CODON_TABLE: {codon_file}\n") print("Modify these and more relevant values at the top of the script if necessary.\n") @@ -71,11 +75,11 @@ def find_repeated_kmers(seq, k=16): if repeats: print(f'\nWarning: {repeats} repeats of {k}bp or more in the ORF. This will affect PCR & SDM.') -def read_orf_and_mutation_list(): +def read_orf_and_mutation_list(orf_file,mutation_list_file,codon_table_file): """Read the ORF sequence, mutation list, and codon table.""" - orf_seq = Seq(Path(ORF_FILE).read_text().strip()) - mutation_list = pd.read_csv(MUTATION_LIST_FILE) - codon_table = pd.read_csv(CODON_TABLE_FILE) + orf_seq = Seq(Path(orf_file).read_text().strip()) + mutation_list = pd.read_csv(mutation_list_file) + codon_table = pd.read_csv(codon_table_file) return orf_seq, mutation_list, codon_table @@ -146,7 +150,7 @@ def create_primer_order_file(primers): return pd.DataFrame(primer_order, columns=['Name', 'Sequence', 'Tm', 'GC', 'Length']) -def separate_primers_by_type(primers): +def separate_primers_by_type(primers, out_path_fwd, out_path_rev): """Separate forward and reverse primers into different CSV files.""" # Create forward and reverse primer DataFrames safely @@ -161,8 +165,8 @@ def separate_primers_by_type(primers): rev_primers.loc[:, 'Well'] = wells[:len(rev_primers)] # Save to CSV files - fwd_primers.to_csv(Output_Path_Fwd, index=False) - rev_primers.to_csv(Output_Path_Rev, index=False) + fwd_primers.to_csv(out_path_fwd, index=False) + rev_primers.to_csv(out_path_rev, index=False) print("\nPrimers separated for IDT order in 96-well plate.") @@ -176,10 +180,30 @@ def Validate_primer_length(primer_length): if __name__ == '__main__': start_time = time.time() - remind_user_to_check_constants() + + parser = argparse.ArgumentParser() + # MUTATION_LIST_FILE = 'Primer_Design/HMT_Plate2.csv' + parser.add_argument('-m', '--Mutation_List', default='Primer_Design/HMT_Plate2.csv', help="Mutation list filename") + # 'Primer_Design/Primers_HMT_Plate2' + parser.add_argument('-o', '--Output_Directory', default='Primer_Design/Primers_HMT_Plate2', help="Output directory") + # 'HMT_Designed_primers.csv' + parser.add_argument('-f', '--Primer_Output_File', default='HMT_Designed_primers.csv', help="Primer output file") + # 'HMT_Forward_Primers_Plate2.csv' + parser.add_argument('-fwd', '--Forward_Primers_File', default='HMT_Forward_Primers_Plate2.csv', help="Forward primers file") + # Reverse_Primers_FILE = 'HMT_Reverse_Primers_Plate2.csv + parser.add_argument('-rev', '--Reverse_Primers_File', default='HMT_Reverse_Primers_Plate2.csv', help="Reverse primers file") + + # CODON_TABLE_FILE = 'Primer_Design/Codon_Table_Standard.csv' + parser.add_argument('-c', '--Codon_Table_File', default='Primer_Design/Codon_Table_Standard.csv', help="Code Table file") + # ORF_FILE = 'Primer_Design/HMT.txt' + parser.add_argument('-orf', '--ORF_File', default='Primer_Design/HMT.txt', help="Open Reading Frame file") + + out_path, path_fwd, path_rev = process_outputs(parser.Output_Directory,parser.Primer_Output_File,parser.Forward_Primers_File,parser.Reverse_Primers_File) + + remind_user_to_check_constants(parser.Mutation_List,parser.Output_Directory,parser.ORF_File) print(f'Working Directory: {os.getcwd()} \nProcessing...') - orf_seq, mutations, codon_table = read_orf_and_mutation_list() + orf_seq, mutations, codon_table = read_orf_and_mutation_list(parser.ORF_File,parser.Mutation_List,parser.Codon_Table_File) find_repeated_kmers(orf_seq) #check if provided mutations align with translation @@ -189,7 +213,7 @@ def Validate_primer_length(primer_length): Validate_primer_length(primers["Length"].tolist()) primer_order = create_primer_order_file(primers) - primer_order.to_csv(Output_Path, index=False) + primer_order.to_csv(out_path, index=False) - separate_primers_by_type(primer_order) + separate_primers_by_type(primer_order,path_fwd,path_rev) print(f"\nFinished in {time.time() - start_time:.6f} seconds.") From c1b410e5cb2070bef5c575e2a9bc847f583fbc5e Mon Sep 17 00:00:00 2001 From: David Bianchi Date: Tue, 19 Aug 2025 16:47:54 -0500 Subject: [PATCH 02/10] added argparser elements for CLI --- Primer_Design_SDM.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/Primer_Design_SDM.py b/Primer_Design_SDM.py index c9ee222..34dfe4d 100644 --- a/Primer_Design_SDM.py +++ b/Primer_Design_SDM.py @@ -57,7 +57,7 @@ def process_outputs(output_dir,primer_output_file,fwd_primers_file,rev_primers_f def remind_user_to_check_constants(mut_file,out_path,orf_file,codon_file): """Reminds the user to review constants and make changes if needed.""" - print("\n⚠️ Reminder: Please check the following constants: \n") + print("\n⚠️ Reminder: Please check the following constants: \n") print(f" - MUTATION_FILE: {mut_file}\n") print(f" - PRIMER_OUTPUT: {out_path}\n") print(f" - ORF_FILE: {orf_file}\n") @@ -198,12 +198,14 @@ def Validate_primer_length(primer_length): # ORF_FILE = 'Primer_Design/HMT.txt' parser.add_argument('-orf', '--ORF_File', default='Primer_Design/HMT.txt', help="Open Reading Frame file") - out_path, path_fwd, path_rev = process_outputs(parser.Output_Directory,parser.Primer_Output_File,parser.Forward_Primers_File,parser.Reverse_Primers_File) + args = parser.parse_args() - remind_user_to_check_constants(parser.Mutation_List,parser.Output_Directory,parser.ORF_File) + out_path, path_fwd, path_rev = process_outputs(args.Output_Directory,args.Primer_Output_File,args.Forward_Primers_File,args.Reverse_Primers_File) + + remind_user_to_check_constants(args.Mutation_List,args.Output_Directory,args.ORF_File) print(f'Working Directory: {os.getcwd()} \nProcessing...') - orf_seq, mutations, codon_table = read_orf_and_mutation_list(parser.ORF_File,parser.Mutation_List,parser.Codon_Table_File) + orf_seq, mutations, codon_table = read_orf_and_mutation_list(args.ORF_File,args.Mutation_List,args.Codon_Table_File) find_repeated_kmers(orf_seq) #check if provided mutations align with translation From 2efc3fb224ea6e6cbba7ab6b5d8d6a1d314fa944 Mon Sep 17 00:00:00 2001 From: David Bianchi Date: Tue, 19 Aug 2025 16:49:48 -0500 Subject: [PATCH 03/10] Add default standard codon file --- Primer_Design_SDM.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Primer_Design_SDM.py b/Primer_Design_SDM.py index 34dfe4d..aa6f20b 100644 --- a/Primer_Design_SDM.py +++ b/Primer_Design_SDM.py @@ -202,7 +202,7 @@ def Validate_primer_length(primer_length): out_path, path_fwd, path_rev = process_outputs(args.Output_Directory,args.Primer_Output_File,args.Forward_Primers_File,args.Reverse_Primers_File) - remind_user_to_check_constants(args.Mutation_List,args.Output_Directory,args.ORF_File) + remind_user_to_check_constants(args.Mutation_List,args.Output_Directory,args.ORF_File,args.Codon_Table_File) print(f'Working Directory: {os.getcwd()} \nProcessing...') orf_seq, mutations, codon_table = read_orf_and_mutation_list(args.ORF_File,args.Mutation_List,args.Codon_Table_File) From 349ae9da3aca98e53063f015bcce31211d003362 Mon Sep 17 00:00:00 2001 From: David Bianchi Date: Tue, 19 Aug 2025 17:03:22 -0500 Subject: [PATCH 04/10] Updates for deprecated GC and Tm calculation modules and help text tweaks --- Primer_Design_SDM.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Primer_Design_SDM.py b/Primer_Design_SDM.py index aa6f20b..9177390 100644 --- a/Primer_Design_SDM.py +++ b/Primer_Design_SDM.py @@ -2,7 +2,7 @@ from Bio import SeqUtils from Bio.Seq import Seq from Bio.SeqRecord import SeqRecord -from primer3 import calcTm +from primer3 import calc_tm # as calcTm - calcTm is deprecated import pandas as pd from itertools import combinations @@ -57,12 +57,12 @@ def process_outputs(output_dir,primer_output_file,fwd_primers_file,rev_primers_f def remind_user_to_check_constants(mut_file,out_path,orf_file,codon_file): """Reminds the user to review constants and make changes if needed.""" - print("\n⚠️ Reminder: Please check the following constants: \n") + print("\n⚠️ Reminder: Please check the following inputs for correctness: \n") print(f" - MUTATION_FILE: {mut_file}\n") print(f" - PRIMER_OUTPUT: {out_path}\n") print(f" - ORF_FILE: {orf_file}\n") print(f" - CODON_TABLE: {codon_file}\n") - print("Modify these and more relevant values at the top of the script if necessary.\n") + print("Modify these and other relevant values in CLI arguments if necessary. Run with -h for help.\n") def find_repeated_kmers(seq, k=16): @@ -115,9 +115,9 @@ def design_primers(orf_seq, mutations, codon_table): mutated_seq = orf_seq[:pos * 3] + new_codon + orf_seq[(pos + 1) * 3:] primer = extract_primer(mutated_seq, pos * 3) - tm = int(math.ceil(calcTm(str(primer), dv_conc=2, tm_method='santalucia', salt_corrections_method='owczarzy'))) + tm = int(math.ceil(calc_tm(str(primer), dv_conc=2, tm_method='santalucia', salt_corrections_method='owczarzy'))) - primers.append((mutation, primer, tm, int(SeqUtils.GC(primer)), len(primer))) + primers.append((mutation, primer, tm, int(SeqUtils.gc_fraction(primer)), len(primer))) #SeqUtils.GC is deprecated after Biopython 1.82 return pd.DataFrame(primers, columns=['Name', 'Sequence', 'Tm', 'GC', 'Length']) From 4000b0784faa111fc1c047e5f80200eeed421877 Mon Sep 17 00:00:00 2001 From: David Bianchi Date: Tue, 19 Aug 2025 17:06:20 -0500 Subject: [PATCH 05/10] Multiply GC percentage by 100 and round for percentage representation --- Primer_Design_SDM.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Primer_Design_SDM.py b/Primer_Design_SDM.py index 9177390..e1ce7cd 100644 --- a/Primer_Design_SDM.py +++ b/Primer_Design_SDM.py @@ -117,7 +117,7 @@ def design_primers(orf_seq, mutations, codon_table): primer = extract_primer(mutated_seq, pos * 3) tm = int(math.ceil(calc_tm(str(primer), dv_conc=2, tm_method='santalucia', salt_corrections_method='owczarzy'))) - primers.append((mutation, primer, tm, int(SeqUtils.gc_fraction(primer)), len(primer))) #SeqUtils.GC is deprecated after Biopython 1.82 + primers.append((mutation, primer, tm, int(SeqUtils.gc_fraction(primer)*100.0), len(primer))) #SeqUtils.GC is deprecated after Biopython 1.82 return pd.DataFrame(primers, columns=['Name', 'Sequence', 'Tm', 'GC', 'Length']) From 548fad2113b86284c46654ab072a2bc38a4c84f9 Mon Sep 17 00:00:00 2001 From: David Bianchi Date: Tue, 19 Aug 2025 22:04:07 -0500 Subject: [PATCH 06/10] update help messages text --- Primer_Design_SDM.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Primer_Design_SDM.py b/Primer_Design_SDM.py index e1ce7cd..7686eec 100644 --- a/Primer_Design_SDM.py +++ b/Primer_Design_SDM.py @@ -183,20 +183,20 @@ def Validate_primer_length(primer_length): parser = argparse.ArgumentParser() # MUTATION_LIST_FILE = 'Primer_Design/HMT_Plate2.csv' - parser.add_argument('-m', '--Mutation_List', default='Primer_Design/HMT_Plate2.csv', help="Mutation list filename") + parser.add_argument('-m', '--Mutation_List', default='Primer_Design/HMT_Plate2.csv', help="List of Mutation Names mapped to well positions") # 'Primer_Design/Primers_HMT_Plate2' parser.add_argument('-o', '--Output_Directory', default='Primer_Design/Primers_HMT_Plate2', help="Output directory") # 'HMT_Designed_primers.csv' - parser.add_argument('-f', '--Primer_Output_File', default='HMT_Designed_primers.csv', help="Primer output file") + parser.add_argument('-f', '--Primer_Output_File', default='HMT_Designed_primers.csv', help="Output file for primers assoc. characteristic data") # 'HMT_Forward_Primers_Plate2.csv' - parser.add_argument('-fwd', '--Forward_Primers_File', default='HMT_Forward_Primers_Plate2.csv', help="Forward primers file") + parser.add_argument('-fwd', '--Forward_Primers_File', default='HMT_Forward_Primers_Plate2.csv', help="Output file for Forward primers") # Reverse_Primers_FILE = 'HMT_Reverse_Primers_Plate2.csv - parser.add_argument('-rev', '--Reverse_Primers_File', default='HMT_Reverse_Primers_Plate2.csv', help="Reverse primers file") + parser.add_argument('-rev', '--Reverse_Primers_File', default='HMT_Reverse_Primers_Plate2.csv', help="Output file for Reverse primers") # CODON_TABLE_FILE = 'Primer_Design/Codon_Table_Standard.csv' - parser.add_argument('-c', '--Codon_Table_File', default='Primer_Design/Codon_Table_Standard.csv', help="Code Table file") + parser.add_argument('-c', '--Codon_Table_File', default='Primer_Design/Codon_Table_Standard.csv', help="Codon Translation Table Mapping File") # ORF_FILE = 'Primer_Design/HMT.txt' - parser.add_argument('-orf', '--ORF_File', default='Primer_Design/HMT.txt', help="Open Reading Frame file") + parser.add_argument('-orf', '--ORF_File', default='Primer_Design/HMT.txt', help="File containing Open Reading Frame Sequence") args = parser.parse_args() From afc73b2a5097864f53bfbe9c3132aa9791340773 Mon Sep 17 00:00:00 2001 From: David Bianchi Date: Tue, 26 Aug 2025 22:49:06 -0500 Subject: [PATCH 07/10] updated dependency requirments for initial version --- requirements.txt | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 requirements.txt diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..7afc736 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,8 @@ +biopython==1.83 +numpy==1.24.4 +pandas==2.0.3 +primer3-py==2.2.0 +python-dateutil==2.9.0.post0 +pytz==2025.2 +six==1.17.0 +tzdata==2025.2 From d11789ef8bd1481225d5848886e85371b298e05d Mon Sep 17 00:00:00 2001 From: David Bianchi Date: Tue, 26 Aug 2025 23:24:58 -0500 Subject: [PATCH 08/10] Added ability to use an NCBI Provided Codon Translation table by NCBI ID as CLI --- Primer_Design_SDM.py | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/Primer_Design_SDM.py b/Primer_Design_SDM.py index 7686eec..8c74e1c 100644 --- a/Primer_Design_SDM.py +++ b/Primer_Design_SDM.py @@ -2,6 +2,7 @@ from Bio import SeqUtils from Bio.Seq import Seq from Bio.SeqRecord import SeqRecord +from Bio.Data import CodonTable from primer3 import calc_tm # as calcTm - calcTm is deprecated import pandas as pd @@ -55,13 +56,13 @@ def process_outputs(output_dir,primer_output_file,fwd_primers_file,rev_primers_f ###################################### ###################################### -def remind_user_to_check_constants(mut_file,out_path,orf_file,codon_file): +def remind_user_to_check_constants(mut_file,out_path,orf_file,codon_file_id): """Reminds the user to review constants and make changes if needed.""" print("\n⚠️ Reminder: Please check the following inputs for correctness: \n") print(f" - MUTATION_FILE: {mut_file}\n") print(f" - PRIMER_OUTPUT: {out_path}\n") print(f" - ORF_FILE: {orf_file}\n") - print(f" - CODON_TABLE: {codon_file}\n") + print(f" - CODON_TABLE: {CodonTable.unambiguous_dna_by_id[int(codon_file_id)]}\n") print("Modify these and other relevant values in CLI arguments if necessary. Run with -h for help.\n") @@ -75,12 +76,12 @@ def find_repeated_kmers(seq, k=16): if repeats: print(f'\nWarning: {repeats} repeats of {k}bp or more in the ORF. This will affect PCR & SDM.') -def read_orf_and_mutation_list(orf_file,mutation_list_file,codon_table_file): +def read_orf_and_mutation_list(orf_file,mutation_list_file,codon_table_file_id): """Read the ORF sequence, mutation list, and codon table.""" orf_seq = Seq(Path(orf_file).read_text().strip()) mutation_list = pd.read_csv(mutation_list_file) - codon_table = pd.read_csv(codon_table_file) - return orf_seq, mutation_list, codon_table + #codon_table = CodonTable.unambiguous_dna_by_id[codon_table_file_id].tolist() #pd.read_csv(codon_table_file) + return orf_seq, mutation_list #, codon_table def validate_position(amino_acid_pos, protein_len): @@ -101,7 +102,7 @@ def validate_mutations(mutation_list, orf_seq): sys.exit(f'ERROR: at null value in csv file. Format the csv file.') -def design_primers(orf_seq, mutations, codon_table): +def design_primers(orf_seq, mutations, codon_table_id): """Main primer design function.""" primers = [] @@ -110,7 +111,12 @@ def design_primers(orf_seq, mutations, codon_table): validate_position(pos + 1, len(orf_seq) // 3) original_aa, target_aa = mutation[0], mutation[-1] - codons = codon_table[codon_table['SingleLetter'] == target_aa]['Codon'].tolist() + #print(target_aa) + codon_table = CodonTable.unambiguous_dna_by_id[int(codon_table_id)].forward_table + #print(codon_table) + codons = [key for key, value in codon_table.items() if value == target_aa] + #codons = (target_aa.translate(table=int(codon_table_id))).tolist() + #codons = codon_table[codon_table['SingleLetter'] == target_aa]['Codon'].tolist() new_codon = find_optimal_codon(orf_seq, pos, codons) mutated_seq = orf_seq[:pos * 3] + new_codon + orf_seq[(pos + 1) * 3:] @@ -194,7 +200,9 @@ def Validate_primer_length(primer_length): parser.add_argument('-rev', '--Reverse_Primers_File', default='HMT_Reverse_Primers_Plate2.csv', help="Output file for Reverse primers") # CODON_TABLE_FILE = 'Primer_Design/Codon_Table_Standard.csv' - parser.add_argument('-c', '--Codon_Table_File', default='Primer_Design/Codon_Table_Standard.csv', help="Codon Translation Table Mapping File") + #parser.add_argument('-c', '--Codon_Table_File', default='Primer_Design/Codon_Table_Standard.csv', help="Codon Translation Table Mapping File") + + parser.add_argument('-c','--NCBI_Codon_Table_Value', default=1,help="NCBI Codon Translation Table ID Value") # ORF_FILE = 'Primer_Design/HMT.txt' parser.add_argument('-orf', '--ORF_File', default='Primer_Design/HMT.txt', help="File containing Open Reading Frame Sequence") @@ -202,16 +210,16 @@ def Validate_primer_length(primer_length): out_path, path_fwd, path_rev = process_outputs(args.Output_Directory,args.Primer_Output_File,args.Forward_Primers_File,args.Reverse_Primers_File) - remind_user_to_check_constants(args.Mutation_List,args.Output_Directory,args.ORF_File,args.Codon_Table_File) + remind_user_to_check_constants(args.Mutation_List,args.Output_Directory,args.ORF_File,args.NCBI_Codon_Table_Value)#args.Codon_Table_File) print(f'Working Directory: {os.getcwd()} \nProcessing...') - orf_seq, mutations, codon_table = read_orf_and_mutation_list(args.ORF_File,args.Mutation_List,args.Codon_Table_File) + orf_seq, mutations = read_orf_and_mutation_list(args.ORF_File,args.Mutation_List,args.NCBI_Codon_Table_Value) find_repeated_kmers(orf_seq) #check if provided mutations align with translation validate_mutations(mutations['Mutations'].tolist(), orf_seq) - primers = design_primers(orf_seq, mutations, codon_table) + primers = design_primers(orf_seq, mutations, args.NCBI_Codon_Table_Value) Validate_primer_length(primers["Length"].tolist()) primer_order = create_primer_order_file(primers) From a2d16504c852bd65428780e829079c8b3c111bc4 Mon Sep 17 00:00:00 2001 From: David Bianchi Date: Wed, 27 Aug 2025 11:07:34 -0500 Subject: [PATCH 09/10] Clean up extraneous comments etc. --- Primer_Design_SDM.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Primer_Design_SDM.py b/Primer_Design_SDM.py index 8c74e1c..3574b2a 100644 --- a/Primer_Design_SDM.py +++ b/Primer_Design_SDM.py @@ -110,12 +110,10 @@ def design_primers(orf_seq, mutations, codon_table_id): pos = int(re.search(r'\d+', mutation).group()) - 1 validate_position(pos + 1, len(orf_seq) // 3) + # Get all possible translation table combinations for the aa resiudes in question original_aa, target_aa = mutation[0], mutation[-1] - #print(target_aa) codon_table = CodonTable.unambiguous_dna_by_id[int(codon_table_id)].forward_table - #print(codon_table) codons = [key for key, value in codon_table.items() if value == target_aa] - #codons = (target_aa.translate(table=int(codon_table_id))).tolist() #codons = codon_table[codon_table['SingleLetter'] == target_aa]['Codon'].tolist() new_codon = find_optimal_codon(orf_seq, pos, codons) From 4d0baf4252f7f8d4882040def824ef18084df073 Mon Sep 17 00:00:00 2001 From: David Bianchi Date: Fri, 12 Sep 2025 16:16:06 -0500 Subject: [PATCH 10/10] Add setup and package version instructions --- README.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/README.md b/README.md index 530fb95..86c54ac 100644 --- a/README.md +++ b/README.md @@ -24,6 +24,13 @@ This repository contains a set of Python scripts designed for efficient primer d - Python 3.x - Libraries: `pandas`, `itertools`, `collections`, `pathlib`, `os`, `sys`, `time` +### Setup and Package Versions +We recommend using a python virtual environment or conda environment to manage python package versions + +To setup with the appropriate versions, run the command: + +#### pip install requirements.txt + ### Reference
If you use this tool, please cite us: