def _format_report_body(self): body = '' body += self._PCR_Simulation.format_quantity_explanation() #PCR products by hit body += hr(' histogram of all possible PCR products ', symbol='=') if len(self._PCR_Simulation.hits()) == 1: #all products histogram hit = self._PCR_Simulation.hits()[0] body += self._PCR_Simulation.per_hit_header(hit) body += self._PCR_Simulation.per_hit_histogram(hit) body += '\n' body += hr(' electrophorogram of all possible PCR products ', symbol='=') body += self._PCR_Simulation.per_hit_electrophoresis(hit) else: products = self._PCR_Simulation.products().items() products.sort(key=lambda (d): max(p.quantity for p in d[1].values()), reverse=True) #all products histogram body += self._PCR_Simulation.all_products_histogram(products) body += '\n\n\n' #per hit histogram and phoresis body += hr( ' histograms and electrophorograms of PCR products of each hit ', symbol='=') body += self._PCR_Simulation.all_graphs_grouped_by_hit(products) return body #end def #end class
def _format_report_body(self): body = '' body += self._PCR_Simulation.format_quantity_explanation() #PCR products by hit body += hr(' histogram of all possible PCR products ', symbol='=') if len(self._PCR_Simulation.hits()) == 1: #all products histogram hit = self._PCR_Simulation.hits()[0] body += self._PCR_Simulation.per_hit_header(hit) body += self._PCR_Simulation.per_hit_histogram(hit) body += '\n' body += hr(' electrophorogram of all possible PCR products ', symbol='=') body += self._PCR_Simulation.per_hit_electrophoresis(hit) else: products = self._PCR_Simulation.products().items() products.sort(key=lambda(d): max(p.quantity for p in d[1].values()), reverse=True) #all products histogram body += self._PCR_Simulation.all_products_histogram(products) body += '\n\n\n' #per hit histogram and phoresis body += hr(' histograms and electrophorograms of PCR products of each hit ', symbol='=') body += self._PCR_Simulation.all_graphs_grouped_by_hit(products) return body #end def #end class
def _format_str(self, full=True): """If 'full', for single sequence output self-dimers and hairpins. For two sequences output only cross-dimers If not 'full', for single sequence output COUNTS and min dG of self-dimers and hairpins. For two sequences output the same only for cross-dimers""" if full: format_dimers = self._format_dimers format_hairpins = self._format_hairpins else: format_dimers = self._format_dimers_short format_hairpins = self._format_hairpins_short string = '\n' if self._seq2: string += hr(' %s vs %s cross-dimers ' % (self._seq_rec1.id, self._seq_rec2.id), symbol='=') dimers = self._cross_dimers.values() dimers.sort(key=lambda(s): s.dG) string += format_dimers(dimers, self._seq1, self._seq2) else: string += hr(' %s: %s ' % (self._seq_rec1.id, str(self._seq1)), symbol='=') string += hr(' self-dimers ') dimers = self._seq1_dimers.values() dimers.sort(key=lambda(s): s.dG) string += format_dimers(dimers, self._seq1, self._seq1) string += hr(' hairpins ') hairpins = self._seq1_hairpins.values() hairpins.sort(key=lambda(s): s.dG) string += format_hairpins(hairpins, self._seq1) string += hr('',symbol='=') return string
def _format_primers_report_header(self): header_string = '' header_string += time_hr() header_string += wrap_text( 'For each degenerate primer provided, a set ' 'of unambiguous primers is generated. ' 'For each such set the minimum, maximum and ' 'mean melting temperatures are calculated. ' 'For each primer in each set stable self-' 'dimers and hairpins are predicted. ' 'For every possible combination of two ' 'unambiguous primers cross-dimers are also ' 'predicted. If an unambiguous primer is ' 'provided, it is treated as a set with a ' 'single element.\n\n') header_string += hr(' PCR conditions ') header_string += TD_Functions.format_PCR_conditions( self._primers) + '\n' header_string += hr(' primers and their melting temperatures ') for primer in self._primers: header_string += repr(primer) + '\n' #warning if len(self._primers) > 1: if abs(self._primers[0].Tm_min - self._primers[1].Tm_min) >= 5: header_string += '\nWarning: lowest melting temperatures of sense and antisense primes \n' header_string += ' differ more then by 5C\n' header_string += '\n' return header_string
def _format_primers_report_header(self): header_string = '' header_string += time_hr() header_string += wrap_text('For each degenerate primer provided, a set ' 'of unambiguous primers is generated. ' 'For each such set the minimum, maximum and ' 'mean melting temperatures are calculated. ' 'For each primer in each set stable self-' 'dimers and hairpins are predicted. ' 'For every possible combination of two ' 'unambiguous primers cross-dimers are also ' 'predicted. If an unambiguous primer is ' 'provided, it is treated as a set with a ' 'single element.\n\n') header_string += hr(' PCR conditions ') header_string += TD_Functions.format_PCR_conditions(self._primers)+'\n' header_string += hr(' primers and their melting temperatures ') for primer in self._primers: header_string += repr(primer) + '\n' #warning if len(self._primers) > 1: if abs(self._primers[0].Tm_min - self._primers[1].Tm_min) >= 5: header_string += '\nWarning: lowest melting temperatures of sense and antisense primes \n' header_string += ' differ more then by 5C\n' header_string += '\n' return header_string
def worker(hit_products): hit = hit_products[0] graphs = self.per_hit_histogram(hit) graphs += self.per_hit_header(hit) graphs += hr(' electrophorogram of PCR products ') graphs += self.per_hit_electrophoresis(hit) graphs += hr('') graphs += '\n\n' return graphs
def worker(hit): prod_string = hr(' %s ' % hit, '*') prod_string += hr(' %d products have been found ' % len(self._products[hit]), '*') products = self._products[hit].values() products.sort(key=lambda x: x.start) for pi, product in enumerate(products): prod_string += hr(' product %d ' % (pi+1), '=') prod_string += product.pretty_print(with_name=False, include_fwd_3_mismatch=self._with_exonuclease) prod_string += hr('', '=') prod_string += hr('', '*') return prod_string
def worker(hit): prod_string = hr(' %s ' % hit, '*') prod_string += hr( ' %d products have been found ' % len(self._products[hit]), '*') products = self._products[hit].values() products.sort(key=lambda x: x.start) for pi, product in enumerate(products): prod_string += hr(' product %d ' % (pi + 1), '=') prod_string += product.pretty_print( with_name=False, include_fwd_3_mismatch=self._with_exonuclease) prod_string += hr('', '=') prod_string += hr('', '*') return prod_string
def print_structures(self, full=True): strings = [] for i, primer in enumerate(self._primers): structs = self._print_structures(self._self[i], full) if structs: strings.append(hr(' secondary structures of %s primers ' % primer.id, '#')) strings.append(structs) if self._cross: cross_structs = self._print_structures(self._cross, full) if cross_structs: strings.append(hr(' cross-dimers ', '#')) strings.append(cross_structs) if strings: strings.insert(0, hr(' stable secondary structures ', symbol='#')) else: strings.append(hr(' no stable secondary structures found ', symbol='#')) return ''.join(strings)
def pretty_print(self, with_name=True, include_fwd_3_mismatch=True): rep = Region.pretty_print(self, with_name=with_name) rep += '\n' rep += 'concentration: %s\n' % tdf.format_concentration(self.quantity) rep += 'number of cycles: %d\n' % self.cycles rep += '\n' rep += hr(' forward annealing site ') rep += self.fwd_template.pretty_print(with_name=False) rep += '\n' rep += hr(' reverse annealing site ') rep += self.rev_template.pretty_print(with_name=False) rep += '\n' rep += hr(' forward primers ') rep += self._rep_primers(self.fwd_primers, lambda p: p.print_most_stable(include_fwd_3_mismatch)) rep += '\n' rep += hr(' reverse primers ') rep += self._rep_primers(self.rev_primers, lambda p: p.print_most_stable(include_fwd_3_mismatch)) return rep
def format_report_header(self): header_string = '' header_string += hr(' PCR conditions ') if self._with_exonuclease: header_string += "DNA polymerase HAS 3'-5'-exonuclease activity.\n" else: header_string += "DNA polymerase doesn't have 3'-5'-exonuclease activity.\n" header_string += 'Speed of DNA polymerase is considered to be 1 kbs/min\n\n' header_string += 'Minimum amplicon size: %d\n' % self._min_amplicon header_string += 'Maximum amplicon size: %d\n' % self._max_amplicon header_string += 'Elongation time: %s\n' % timedelta(minutes=self._elongation_time) header_string += 'Maximum cycles: %d\n' % self._num_cycles header_string += '\n' header_string += tdf.format_PCR_conditions(self._primers, self._polymerase)+'\n' header_string += hr(' primers and their melting temperatures ') for primer in self._primers: header_string += repr(primer) + '\n' header_string += '\n' return header_string
def print_structures(self, full=True): strings = [] for i, primer in enumerate(self._primers): structs = self._print_structures(self._self[i], full) if structs: strings.append( hr(' secondary structures of %s primers ' % primer.id, '#')) strings.append(structs) if self._cross: cross_structs = self._print_structures(self._cross, full) if cross_structs: strings.append(hr(' cross-dimers ', '#')) strings.append(cross_structs) if strings: strings.insert(0, hr(' stable secondary structures ', symbol='#')) else: strings.append( hr(' no stable secondary structures found ', symbol='#')) return ''.join(strings)
def write_products_report(self): if not self._have_results: return #open report file ipcr_products = self._open_report('BLAST PCR products', self._PCR_products_filename) ipcr_products.write(time_hr()) for record_name in self._PCR_Simulations: ipcr_products.write(hr(' query ID: %s ' % record_name, symbol='#')) ipcr_products.write(self._PCR_Simulations[record_name].format_products_report()) ipcr_products.close() print '\nThe list of BLAST PCR products was written to:\n ',self._PCR_products_filename self._add_report('BLAST PCR products', self._PCR_products_filename)
def format_report_header(self): header_string = '' header_string += hr(' PCR conditions ') if self._with_exonuclease: header_string += "DNA polymerase HAS 3'-5'-exonuclease activity.\n" else: header_string += "DNA polymerase doesn't have 3'-5'-exonuclease activity.\n" header_string += 'Speed of DNA polymerase is considered to be 1 kbs/min\n\n' header_string += 'Minimum amplicon size: %d\n' % self._min_amplicon header_string += 'Maximum amplicon size: %d\n' % self._max_amplicon header_string += 'Elongation time: %s\n' % timedelta( minutes=self._elongation_time) header_string += 'Maximum cycles: %d\n' % self._num_cycles header_string += '\n' header_string += tdf.format_PCR_conditions(self._primers, self._polymerase) + '\n' header_string += hr(' primers and their melting temperatures ') for primer in self._primers: header_string += repr(primer) + '\n' header_string += '\n' return header_string
def _format_report_body(self): body = '' for record_name in self._PCR_Simulations: body += hr(' query ID: %s ' % record_name, symbol='#') if len(self._PCR_Simulations[record_name].hits()) == 1: #all products histogram hit = self._PCR_Simulations[record_name].hits()[0] body += hr(' histogram of all possible PCR products ', symbol='=') body += self._PCR_Simulations[record_name].per_hit_header(hit) body += self._PCR_Simulations[record_name].per_hit_histogram(hit) body += '\n' body += hr(' electrophorogram of all possible PCR products ', symbol='=') body += self._PCR_Simulations[record_name].per_hit_electrophoresis(hit) else: #all products histogram body += hr(' histogram of all possible PCR products ', symbol='=') body += self._PCR_Simulations[record_name].all_products_histogram() body += '\n\n\n' #per hit histogram and phoresis body += hr(' histograms and electrophorograms of PCR products of each hit ', symbol='=') body += self._PCR_Simulations[record_name].all_graphs_grouped_by_hit() return body
def write_products_report(self): if not self._have_results: return #open report file ipcr_products = self._open_report('iPCR products', self._PCR_products_filename) ipcr_products.write(time_hr()) if self._PCR_Simulation: ipcr_products.write(self._PCR_Simulation.format_products_report()) else: ipcr_products.write(hr(' No PCR products have been found ', symbol='!')) ipcr_products.close() print '\nThe list of PCR products was written to:\n %s' % self._PCR_products_filename self._add_report('iPCR products', self._PCR_products_filename) #end def #end class
def pretty_print(self, with_name=True, include_fwd_3_mismatch=True): rep = Region.pretty_print(self, with_name=with_name) rep += '\n' rep += 'concentration: %s\n' % tdf.format_concentration( self.quantity) rep += 'number of cycles: %d\n' % self.cycles rep += '\n' rep += hr(' forward annealing site ') rep += self.fwd_template.pretty_print(with_name=False) rep += '\n' rep += hr(' reverse annealing site ') rep += self.rev_template.pretty_print(with_name=False) rep += '\n' rep += hr(' forward primers ') rep += self._rep_primers( self.fwd_primers, lambda p: p.print_most_stable(include_fwd_3_mismatch)) rep += '\n' rep += hr(' reverse primers ') rep += self._rep_primers( self.rev_primers, lambda p: p.print_most_stable(include_fwd_3_mismatch)) return rep
def format_quantity_explanation(self): expl_string = '' expl_string += hr(' estimation of PCR products concentrations ') expl_string += 'The value of the objective function of at the solution ' + \ '(the lower the better):\n %e\n' % \ self._max_objective_value expl_string += wrap_text('This value shows "distance" to the solution of ' 'the system of equilibrium equations which were used ' 'to calculate concentrations of PCR products.\n\n') expl_string += wrap_text(('Products with concentration less than %.2f%% ' 'of the concentration of the most abundant ' 'product or less than initial DNA concentration ' 'are not shown.' '\n\n') % (self._min_quantity_factor*100)) expl_string += wrap_text('Boundaries of a product and it\'s length do ' 'not include primers.\n\n') expl_string += '\n' return expl_string
def write_products_report(self): if not self._have_results: return #open report file ipcr_products = self._open_report('iPCR products', self._PCR_products_filename) ipcr_products.write(time_hr()) if self._PCR_Simulation: ipcr_products.write(self._PCR_Simulation.format_products_report()) else: ipcr_products.write( hr(' No PCR products have been found ', symbol='!')) ipcr_products.close() print '\nThe list of PCR products was written to:\n %s' % self._PCR_products_filename self._add_report('iPCR products', self._PCR_products_filename) #end def #end class
def write_report(self): if not self._have_results: return #open report file report = self._open_report(self._PCR_report_suffix, self._PCR_report_filename) if not report: return #header report.write(time_hr()) report.write(self._format_header()) #if no PCR products have been found if not self._have_results: report.write(hr(' No PCR products have been found ', symbol='!')) report.close() return #report body report.write(self._format_report_body()) report.close() print '\n%s report was written to:\n %s' % (self._PCR_report_suffix, self._PCR_report_filename) report_name = self._PCR_report_suffix.replace('_', ' ').replace('-', ' ') self._add_report(report_name, self._PCR_report_filename)
def format_quantity_explanation(self): expl_string = '' expl_string += hr(' estimation of PCR products concentrations ') expl_string += 'The value of the objective function of at the solution ' + \ '(the lower the better):\n %e\n' % \ self._max_objective_value expl_string += wrap_text( 'This value shows "distance" to the solution of ' 'the system of equilibrium equations which were used ' 'to calculate concentrations of PCR products.\n\n') expl_string += wrap_text( ('Products with concentration less than %.2f%% ' 'of the concentration of the most abundant ' 'product or less than initial DNA concentration ' 'are not shown.' '\n\n') % (self._min_quantity_factor * 100)) expl_string += wrap_text('Boundaries of a product and it\'s length do ' 'not include primers.\n\n') expl_string += '\n' return expl_string
def write_report(self): if not self._have_results: return #open report file report = self._open_report(self._PCR_report_suffix, self._PCR_report_filename) if not report: return #header report.write(time_hr()) report.write(self._format_header()) #if no PCR products have been found if not self._have_results: report.write(hr(' No PCR products have been found ', symbol='!')) report.close() return #report body report.write(self._format_report_body()) report.close() print '\n%s report was written to:\n %s' % ( self._PCR_report_suffix, self._PCR_report_filename) report_name = self._PCR_report_suffix.replace('_', ' ').replace('-', ' ') self._add_report(report_name, self._PCR_report_filename)
def write_hits_report(self): if not self._have_blast_results: return blast_report = self._open_report('blast hits report', self._hits_report_filename) if not blast_report: return #header blast_report.write(time_hr()) blast_report.write(wrap_text('All hits are filtered by dG of the annealing ' 'of alignments and, if --no-exonuclease ' 'option was provided, hits with mismatches on ' "3'-end are ignored.\n")) blast_report.write('\n') #filter parameters blast_report.write(hr(' filtration parameters ')) if self._with_exonuclease: blast_report.write("DNA polymerase HAS 3'-5'-exonuclease activity\n") else: blast_report.write("DNA polymerase doesn't have 3'-5'-exonuclease activity\n") blast_report.write('Maximum dG of an alignment: %.2f kcal/mol\n' % max_dimer_dG) blast_report.write('\n') blast_report.write(hr('')) blast_report.write('\n\n') #print records for r, blast_record in enumerate(self._blast_results): num_hits = len(blast_record.alignments) blast_report.write(hr(' query ID: %s ' % blast_record.query, symbol='#')) #filter hits by alignments and format report text for each hit hits = [] for h in xrange(num_hits): hit = blast_record.alignments[h] desc = blast_record.descriptions[h] #check and format hsps hsps = [] for hsp in hit.hsps: hsp_duplex = self._duplex_from_hsp(hsp) #check if any stable dimers are formed by this duplex if not hsp_duplex: continue #check 3' mismatch if not self._with_exonuclease \ and not hsp_duplex.have_3_matches: continue #get primer concentration for primer in self._primers: if primer.has_subsequence(hsp_duplex.fwd_seq): hsp_primer_concentration = primer.concentration break #format hsps representation hsp_text = ('score: %d; bits: %d; E-value: %.2e;\n\n' % (hsp.score, hsp.bits, hsp.expect)) hsp_text += hsp_duplex.print_most_stable(include_fwd_3_mismatch=self._with_exonuclease) hsp_text += 'Conversion degree = %.2f%%\n\n' \ % (tdf.primer_DNA_conversion_degree(hsp_primer_concentration, hsp_duplex.K)*100) hsp_text += 'Template strand: ' if hsp.frame[1] == 1: hsp_text += 'antisense\n' hsp_text += 'Position on template: %d ==> %d\n' \ % (hsp.sbjct_start, hsp.sbjct_end) elif hsp.frame[1] == -1: hsp_text += 'sense\n' hsp_text += 'Position on template: %d <== %d\n' \ % (hsp.sbjct_start, hsp.sbjct_end) hsp_text += hr('', '.') hsps.append((hsp_duplex.dG, hsp_text)) #no need to include weak hits to the report if not hsps: continue #sort hsps by minimum dG hsps.sort(key=lambda(x): x[0]) #format hit hit_str = wrap_text(hit.title)+'\n' hit_str += 'Length: %d\n' % hit.length hit_str += 'Max bits: %d\n' % desc.bits hit_str += 'Alignments: %d\n' % len(hit.hsps) hit_str += '\n' hit_str += hr(' %d alignments after filtration ' % len(hsps)) hit_str += ''.join(_hsp[1] for _hsp in hsps)[:-1] hits.append((hsps[0][0], desc.title, desc.score, desc.bits, desc.e, len(hsps), hit_str)) if not hits: blast_report.write(wrap_text('All hits were filtered out.\n')) #write report to the file else: #print the short list of all hits num_hits = len(hits) num_hits_len = len(str(num_hits)) #sort hits by minimum dG hits.sort(key=lambda(x): x[0]) #print header blast_report.write(hr(' %d hits ' % num_hits, symbol='#')) for h, hit in enumerate(hits): spacer = ' '*(num_hits_len-len(str(h))) blast_report.write(wrap_text('%d.%s %s\n' % (h+1, spacer, (hit[1].split('|')[-1]).strip()))) blast_report.write(('%s min dG: %.2f; score: %d; bits: %d; ' 'E-value: %.2e; alignments: %d\n\n') % (' '*num_hits_len, hit[0], hit[2], hit[3], hit[4], hit[5])) blast_report.write('\n') #print each formatted hit for h, hit in enumerate(hits): blast_report.write(hr(' Hit #%d ' % (h+1), symbol='=')) blast_report.write(hit[6]) blast_report.write(hr('', symbol='=')) if h < num_hits-1: blast_report.write('\n\n') blast_report.write(hr('', symbol='#')) if r < len(self._blast_results)-1: blast_report.write('\n\n') blast_report.close() print '\nTop hits with top HSPs from BLAST results were written to:\n ' + \ self._hits_report_filename self._add_report('BLAST hits', self._hits_report_filename)