def penalize_solution(best_solution: SSMSolution, config: SSMConfig, fw_opt_temp, rv_opt_temp, flanks: SSMFlankingSequences): """ Computes primer dimer penalty. The penalty consists of following penalties: - hairpin penalty - h**o dimer penalty - hetero dimer penalty (this is applied for each combinations of primer pairs with the rest) Each component is computed with help of primer3 library. It is weighted squared error by corresponding weights from config. Than all errors are added together and we return square error of this errors. :param best_solution: :param config: :param fw_opt_temp: :param rv_opt_temp: :return: """ for pair in best_solution.result: fw_sequence = pair.fw_primer.normal_order_sequence rw_sequence = pair.rw_primer.normal_order_sequence temp_cfg = config.temperature_config fw_hairpin_tm = primer3.calcHairpinTm(fw_sequence, temp_cfg.k, temp_cfg.mg, temp_cfg.dntp) rw_hairpin_tm = primer3.calcHairpinTm(rw_sequence, temp_cfg.k, temp_cfg.mg, temp_cfg.dntp) fw_homodimer_tm = primer3.calcHomodimerTm(fw_sequence, temp_cfg.k, temp_cfg.mg, temp_cfg.dntp) rw_homodimer_tm = primer3.calcHomodimerTm(rw_sequence, temp_cfg.k, temp_cfg.mg, temp_cfg.dntp) fw_hairpin_err = (best_solution.forward_temp - fw_hairpin_tm)**2 rw_hairpin_err = (best_solution.reverse_temp - rw_hairpin_tm)**2 fw_homodimer_err = (fw_opt_temp - fw_homodimer_tm)**2 rw_homodimer_err = (rv_opt_temp - rw_homodimer_tm)**2 heterodimer_err = compute_heterodimer_err(pair, config, flanks) penalty = math.sqrt( config.hairpin_temperature_weight * fw_hairpin_err + config.hairpin_temperature_weight * rw_hairpin_err + config.primer_dimer_temperature_weight * fw_homodimer_err + config.primer_dimer_temperature_weight * rw_homodimer_err + config.primer_dimer_temperature_weight * heterodimer_err) pair.non_optimality += penalty
def primer3_filter_withRprimer(sequence, rprimer, mintm=37, maxhtm=35, dtm=10): primer3ft = False tm = primer3.calcTm(sequence) fseq = rprimer + sequence htmF = primer3.calcHairpinTm(fseq) rseq = rprimer + revcom(sequence) htmR = primer3.calcHairpinTm(rseq) if tm < mintm: primer3ft = True if htmF > maxhtm: primer3ft = True if (tm-htmF) < dtm: primer3ft = True if htmR > maxhtm: primer3ft = True if (tm-htmR) < dtm: primer3ft = True # print(sequence, tm, htm, dtm) return primer3ft
def is_good_primer(primer): # ref1. http://www.premierbiosoft.com/tech_notes/PCR_Primer_Design.html seq = ''.join([i[1] for i in primer]) if re.search(poly, seq) is not None: return False, 0, 'Poly(NNNNN) structure found' if re.search(tandem, seq) is not None: return False, 0, 'Tandom(NN*5) exist' # no more 3 ambiguous base if len(re.findall(ambiguous_base, seq)) >= ambiguous_base_n: return False, 0, 'More than 3 ambiguous base' # primer3.setGlobals seems have no effect on calcTm, so I have to replace all # ambiguous base to A to get an approximate value. Othervise calcTm() will # generate -99999 if there is ambiguous base. pure_seq = re.sub(ambiguous_base, 'A', seq) tm = primer3.calcTm(pure_seq) hairpin_tm = primer3.calcHairpinTm(pure_seq) homodimer_tm = primer3.calcHomodimerTm(pure_seq) if max(tm, hairpin_tm, homodimer_tm) != tm: return False, 0, 'Hairpin or homodimer found' return True, tm, 'Ok'
def primer3_cal(sequence, mintm=37, maxhtm=37, dtm=10): primer3ft = True tm = primer3.calcTm(sequence) htm = primer3.calcHairpinTm(sequence) if tm < mintm: primer3ft = False if htm > maxhtm: primer3ft = False if (tm-htm) > dtm: primer3ft = False return (sequence, primer3ft)
def primer3filter(seq, min_TM=37, max_HTM=35, min_diff_TM=10): # Calculate TM = primer3.calcTm(seq) HTM = primer3.calcHairpinTm(seq) # If melting temperature is too low, filter out if TM < min_TM: return "melting temp too low" # If hairpin melting temperature is too high, filter out elif HTM > max_HTM: return "hairpin melting temp too high" # If melting temperature and hairpin melting temperature # are too close together, filter out elif (TM - HTM) < min_diff_TM: return "difference between melting temp and hairpin melting temp too small" # If sequence will make a good probe, return false (do not filter) else: return False
def primer3_filter(sequence, mintm=37, maxhtm=35, dtm=10): primer3ft = False tm = primer3.calcTm(sequence) htm = primer3.calcHairpinTm(sequence) if tm < mintm: primer3ft = True if htm > maxhtm: primer3ft = True if (tm-htm) < dtm: primer3ft = True # print(sequence, tm, htm, dtm) return primer3ft
def primer3_filter(line, min_TM, max_HTM, min_diff_TM): # Get sequence from line passed to function sequence = line.split('\t')[9] # Calculate TM = primer3.calcTm(sequence) HTM = primer3.calcHairpinTm(sequence) # If melting temperature is too low, filter out if TM < min_TM: return True # If hairpin melting temperature is too high, filter out elif HTM > max_HTM: return True # If melting temperature and hairpin melting temperature # are too close together, filter out elif (TM - HTM) < min_diff_TM: return True # If sequence will make a good probe, return false (do not filter) else: return False