def get_response_content(fs): # get the nucleotide distribution nt_to_weight = SnippetUtil.get_distribution(fs.nucleotides, 'nucleotide', nt_letters) # get the amino acid distribution aa_to_weight = SnippetUtil.get_distribution(fs.aminoacids, 'amino acid', aa_letters) # get results mutation_distribution = [nt_to_weight[nt] for nt in nt_letters] aa_distribution = [aa_to_weight[aa] for aa in aa_letters] pair = DirectProtein.get_nt_distribution_and_aa_energies( mutation_distribution, aa_distribution) nt_distribution, aa_energies = pair # write something out = StringIO() # write the stationary nucleotide distribution print >> out, 'nucleotide stationary distribution:' for nt, value in zip(nt_letters, nt_distribution): print >> out, '%s : %s' % (nt, value) print >> out, '' # write the amino acid energies print >> out, 'amino acid energies:' for aa, value in zip(aa_letters, aa_energies): print >> out, '%s : %s' % (aa, value) # return the response return out.getvalue()
def get_response_content(fs): # get the nucleotide distribution nt_to_probability = SnippetUtil.get_distribution(fs.nucleotides, 'nucleotide', nt_letters) # get the amino acid distribution aa_to_probability = SnippetUtil.get_distribution(fs.aminoacids, 'amino acid', aa_letters) # convert the dictionaries to lists observed_nt_stationary_distribution = [nt_to_probability[nt] for nt in nt_letters] aa_distribution = [aa_to_probability[aa] for aa in aa_letters] # define the objective function objective_function = MyCodonObjective(aa_distribution, observed_nt_stationary_distribution) initial_stationary_guess = halpern_bruno_nt_estimate(nt_to_probability, aa_to_probability) A, C, G, T = initial_stationary_guess initial_guess = (math.log(C/A), math.log(G/A), math.log(T/A)) iterations = 20 try: best = scipy.optimize.nonlin.broyden2(objective_function, initial_guess, iterations) except Exception, e: debugging_information = objective_function.get_history() raise HandlingError(str(e) + '\n' + debugging_information)
def get_response_content(fs): # read the nexus data nexus = Nexus.Nexus() try: nexus.load(StringIO(fs.nexus)) except Nexus.NexusError as e: raise HandlingError(e) # get the mixture weights mixture_weights = [fs.weight_a, fs.weight_b] # get the kappa values kappa_values = [fs.kappa_a, fs.kappa_b] # get the nucleotide distributions nucleotide_distributions = [] for nt_string in (fs.frequency_a, fs.frequency_b): distribution = SnippetUtil.get_distribution(nt_string, 'nucleotide', list('ACGT')) nucleotide_distributions.append(distribution) # create the nucleotide HKY rate matrix objects rate_matrix_objects = [] for nt_distribution, kappa in zip(nucleotide_distributions, kappa_values): rate_matrix_object = RateMatrix.get_unscaled_hky85_rate_matrix( nt_distribution, kappa) rate_matrix_objects.append(rate_matrix_object) # create the mixture proportions weight_sum = sum(mixture_weights) mixture_proportions = [weight / weight_sum for weight in mixture_weights] # create the mixture model mixture_model = SubModel.MixtureModel(mixture_proportions, rate_matrix_objects) # normalize the mixture model mixture_model.normalize() # return the results return do_analysis(mixture_model, nexus.alignment, nexus.tree) + '\n'
def get_response_content(fs): # read the nexus data nexus = Nexus.Nexus() try: nexus.load(StringIO(fs.nexus)) except Nexus.NexusError as e: raise HandlingError(e) # get the mixture weights mixture_weights = [fs.weight_a, fs.weight_b] # get the kappa values kappa_values = [fs.kappa_a, fs.kappa_b] # get the nucleotide distributions nucleotide_distributions = [] for nt_string in (fs.frequency_a, fs.frequency_b): distribution = SnippetUtil.get_distribution( nt_string, 'nucleotide', list('ACGT')) nucleotide_distributions.append(distribution) # create the nucleotide HKY rate matrix objects rate_matrix_objects = [] for nt_distribution, kappa in zip(nucleotide_distributions, kappa_values): rate_matrix_object = RateMatrix.get_unscaled_hky85_rate_matrix( nt_distribution, kappa) rate_matrix_objects.append(rate_matrix_object) # create the mixture proportions weight_sum = sum(mixture_weights) mixture_proportions = [weight / weight_sum for weight in mixture_weights] # create the mixture model mixture_model = SubModel.MixtureModel( mixture_proportions, rate_matrix_objects) # normalize the mixture model mixture_model.normalize() # return the results return do_analysis(mixture_model, nexus.alignment, nexus.tree) + '\n'
def get_response_content(fs): # get the nucleotide distribution nt_to_probability = SnippetUtil.get_distribution(fs.nucleotides, "nucleotide", nt_letters) # get the amino acid distribution aa_to_probability = SnippetUtil.get_distribution(fs.aminoacids, "amino acid", aa_letters) # convert the dictionaries to lists observed_nt_stationary_distribution = [nt_to_probability[nt] for nt in nt_letters] aa_distribution = [aa_to_probability[aa] for aa in aa_letters] # define the objective function objective_function = MyCodonObjective(aa_distribution, observed_nt_stationary_distribution) initial_stationary_guess = halpern_bruno_nt_estimate(nt_to_probability, aa_to_probability) A, C, G, T = initial_stationary_guess initial_guess = (math.log(C / A), math.log(G / A), math.log(T / A)) iterations = 20 try: best = scipy.optimize.nonlin.broyden2(objective_function, initial_guess, iterations) except Exception, e: debugging_information = objective_function.get_history() raise HandlingError(str(e) + "\n" + debugging_information)
def get_response_content(fs): # get the mutation process nucleotide distribution nt_distribution = SnippetUtil.get_distribution(fs.nucleotides, 'nucleotide', nt_ordered) # get the selection process amino acid energies aa_to_energy = SnippetUtil.get_dictionary(fs.aminoacids, 'amino acid', 'energy', aa_ordered) # create the direct protein rate matrix object nt_distribution_list = [nt_distribution[nt] for nt in nt_ordered] aa_energy_list = [aa_to_energy[aa] for aa in aa_ordered] rate_matrix_object = DirectProtein.DirectProteinRateMatrix(fs.kappa, nt_distribution_list, aa_energy_list) # write the response out = StringIO() if fs.srm: # write the scaled rate matrix rate_matrix_object.normalize() row_major_rate_matrix = rate_matrix_object.get_row_major_rate_matrix() print >> out, MatrixUtil.m_to_string(row_major_rate_matrix) elif fs.urm: # write the unscaled rate matrix row_major_rate_matrix = rate_matrix_object.get_row_major_rate_matrix() print >> out, MatrixUtil.m_to_string(row_major_rate_matrix) elif fs.cstat: # write the codon stationary distribution codon_distribution = rate_matrix_object.get_codon_distribution() for codon in codons_ordered: print >> out, codon, ':', codon_distribution[codon] elif fs.astat: # write the amino acid stationary distribution aa_distribution = rate_matrix_object.get_aa_distribution() for aa in aa_ordered: print >> out, aa, ':', aa_distribution[aa] elif fs.nstat: # write the nucleotide stationary distribution nt_distribution = rate_matrix_object.get_nt_distribution() for nt in nt_ordered: print >> out, nt, ':', nt_distribution[nt] elif fs.sf: # write the rate matrix scaling factor print >> out, rate_matrix_object.get_expected_rate() # return the response return out.getvalue() + '\n'
def get_response_content(fs): # get the nucleotide distribution nt_distribution = SnippetUtil.get_distribution(fs.nucleotides, 'nucleotide', Codon.g_nt_letters) # get the amino acid distribution aa_distribution = SnippetUtil.get_distribution(fs.amino_acids, 'amino acid', Codon.g_aa_letters) # Assert that the nucleotide distribution # is compatible with the amino acid distribution. # According to the Halpern-Bruno assumptions, there should be no codon bias. # This means that if a nucleotide has a frequency of zero, # then the amino acid coded by each codon containing that nucleotide # must also have a frequency of zero. msg_a = 'the given amino acid and nucleotide distributions ' msg_b = 'are incompatible with the assumption of no codon bias' err = HandlingError(msg_a + msg_b) for aa, codons in Codon.g_aa_letter_to_codons.items(): for codon in codons: for nt in codon: if aa_distribution[aa] and not nt_distribution[nt]: raise err # get the codon distribution codon_to_weight = {} for codon in Codon.g_non_stop_codons: aa = Codon.g_codon_to_aa_letter[codon] sibling_codons = Codon.g_aa_letter_to_codons[aa] codon_aa_weight = aa_distribution[aa] codon_nt_weight = np.prod([nt_distribution[nt] for nt in codon]) sibling_nt_weight_sum = 0 for sibling in sibling_codons: product = np.prod([nt_distribution[nt] for nt in sibling]) sibling_nt_weight_sum += product codon_to_weight[codon] = codon_aa_weight * codon_nt_weight codon_to_weight[codon] /= sibling_nt_weight_sum total_weight = sum(codon_to_weight.values()) # return the codon distribution out = StringIO() for codon, weight in sorted(codon_to_weight.items()): print >> out, codon, ':', weight / total_weight return out.getvalue() + '\n'
def get_response_content(fs): # get the codon distribution codons = Codon.g_sorted_non_stop_codons distribution = SnippetUtil.get_distribution(fs.weights, 'codon', codons) # get the rate matrix defined by the weights and kappa and omega r = RateMatrix.get_gy94_rate_matrix(distribution, fs.kappa, fs.omega) # show the rate matrix in convenient text form out = StringIO() for ca in codons: print >> out, '\t'.join(str(r[(ca, cb)]) for cb in codons) return out.getvalue()
def application(environ, start_response): """ This application function is called by the wsgi framework. @param environ: a dictionary of environment variables @param start_response: a function taking (status, response_headers) parameters. @return: the html page or results data """ out = StringIO() status = '200 OK' response_headers = [('Content-Type', 'text/plain')] try: fs = cgi.FieldStorage(fp=environ['wsgi.input'], environ=environ) scriptid = fs.getfirst('scriptid') if scriptid is None: # no snippet id was specified so show the listing response_headers = [('Content-Type', 'text/html')] print >> out, get_directory_html(script_directory, doc_directory) elif scriptid_is_valid(scriptid): # get a snippet form or a snippet response module = __import__(scriptid, globals(), locals(), ['get_form', 'get_response']) if 'getform' in fs: response_headers = [('Content-Type', 'text/html')] form_text = module.get_form() print >> out, '<html>' print >> out, '<body>' print >> out, SnippetUtil.docstring_to_html(module.__doc__) print >> out, '<br/><br/>' print >> out, '<form method="post">' print >> out, '<input type="hidden" name="scriptid" value="%s"/>' % scriptid print >> out, '<input type="hidden" name="getresponse" value="1"/>' print >> out, form_text print >> out, '<br/><br/>' print >> out, '<input type="submit" name="mysubmit" value="Submit"/><br/>' print >> out, '</form>' print >> out, '</body>' print >> out, '</html>' elif 'getresponse' in fs: response_headers, text = module.get_response(fs) print >> out, text else: # there was an error for key, value in environ.items(): print >> out, key, ':', value print >> out, '--- FieldStorage ---' for key in fs: value = fs[key] print >> out, key, ':', value except Exception, e: response_headers = [('Content-Type', 'text/plain')] print >> out, 'Fail:' print >> out, e
def get_response_content(fs): # get the nucleotide distribution d = SnippetUtil.get_distribution(fs.weights, 'nucleotide', list('ACGT')) # get the rate matrix defined by the nucleotide distribution and kappa rate_object = RateMatrix.get_unscaled_hky85_rate_matrix(d, fs.kappa) if fs.scaled: rate_object.normalize() rate_matrix = rate_object.get_dictionary_rate_matrix() # show the rate matrix in convenient text form out = StringIO() for nta in 'ACGT': print >> out, '\t'.join(str(rate_matrix[(nta, ntb)]) for ntb in 'ACGT') return out.getvalue()
def get_response_content(fs): # get a properly formatted newick tree with branch lengths tree = Newick.parse(fs.tree, SpatialTree.SpatialTree) tree.assert_valid() if tree.has_negative_branch_lengths(): msg = 'drawing a tree with negative branch lengths is not implemented' raise HandlingError(msg) tree.add_branch_lengths() # get the dictionary mapping the branch name to the nucleotide name_to_nucleotide = {} # parse the column string for line in iterutils.stripped_lines(fs.column.splitlines()): name_string, nucleotide_string = SnippetUtil.get_state_value_pair(line) if nucleotide_string not in list('acgtACGT'): msg = '"%s" is not a valid nucleotide' % nucleotide_string raise HandlingError(msg) nucleotide_string = nucleotide_string.upper() if name_string in name_to_nucleotide: raise HandlingError('the name "%s" was duplicated' % name_string) name_to_nucleotide[name_string] = nucleotide_string # augment the tips with the nucleotide letters for name, nucleotide in name_to_nucleotide.items(): try: node = tree.get_unique_node(name) except Newick.NewickSearchError as e: raise HandlingError(e) if node.children: msg = 'constraints on internal nodes are not implemented' raise HandlingError(msg) node.state = nucleotide # get the Jukes-Cantor rate matrix object dictionary_rate_matrix = RateMatrix.get_jukes_cantor_rate_matrix() ordered_states = list('ACGT') row_major_rate_matrix = MatrixUtil.dict_to_row_major( dictionary_rate_matrix, ordered_states, ordered_states) rate_matrix_object = RateMatrix.RateMatrix( row_major_rate_matrix, ordered_states) # simulate the ancestral nucleotides rate_matrix_object.simulate_ancestral_states(tree) # simulate a path on each branch # this breaks up the branch into a linear sequence of nodes and adds color for node in tree.gen_non_root_nodes(): simulate_branch_path(tree, node) # do the layout EqualArcLayout.do_layout(tree) # draw the image try: ext = Form.g_imageformat_to_ext[fs.imageformat] return DrawTreeImage.get_tree_image(tree, (640, 480), ext) except CairoUtil.CairoUtilError as e: raise HandlingError(e)
def get_response_content(fs): # get a properly formatted newick tree with branch lengths tree = Newick.parse(fs.tree, SpatialTree.SpatialTree) tree.assert_valid() if tree.has_negative_branch_lengths(): msg = 'drawing a tree with negative branch lengths is not implemented' raise HandlingError(msg) tree.add_branch_lengths() # get the dictionary mapping the branch name to the nucleotide name_to_nucleotide = {} # parse the column string for line in iterutils.stripped_lines(fs.column.splitlines()): name_string, nucleotide_string = SnippetUtil.get_state_value_pair(line) if nucleotide_string not in list('acgtACGT'): msg = '"%s" is not a valid nucleotide' % nucleotide_string raise HandlingError(msg) nucleotide_string = nucleotide_string.upper() if name_string in name_to_nucleotide: raise HandlingError('the name "%s" was duplicated' % name_string) name_to_nucleotide[name_string] = nucleotide_string # augment the tips with the nucleotide letters for name, nucleotide in name_to_nucleotide.items(): try: node = tree.get_unique_node(name) except Newick.NewickSearchError as e: raise HandlingError(e) if node.children: msg = 'constraints on internal nodes are not implemented' raise HandlingError(msg) node.state = nucleotide # get the Jukes-Cantor rate matrix object dictionary_rate_matrix = RateMatrix.get_jukes_cantor_rate_matrix() ordered_states = list('ACGT') row_major_rate_matrix = MatrixUtil.dict_to_row_major( dictionary_rate_matrix, ordered_states, ordered_states) rate_matrix_object = RateMatrix.RateMatrix(row_major_rate_matrix, ordered_states) # simulate the ancestral nucleotides rate_matrix_object.simulate_ancestral_states(tree) # simulate a path on each branch # this breaks up the branch into a linear sequence of nodes and adds color for node in tree.gen_non_root_nodes(): simulate_branch_path(tree, node) # do the layout EqualArcLayout.do_layout(tree) # draw the image try: ext = Form.g_imageformat_to_ext[fs.imageformat] return DrawTreeImage.get_tree_image(tree, (640, 480), ext) except CairoUtil.CairoUtilError as e: raise HandlingError(e)
def get_response_content(fs): # get a properly formatted newick tree with branch lengths tree = Newick.parse(fs.tree, SpatialTree.SpatialTree) tree.assert_valid() if tree.has_negative_branch_lengths(): msg = 'drawing a tree with negative branch lengths is not implemented' raise HandlingError(msg) tree.add_branch_lengths() # get the dictionary mapping the branch name to the rgb color name_to_rgb = {} # parse the coloration string for line in iterutils.stripped_lines(fs.coloration.splitlines()): # get the branch and its color name_string, rgb_string = SnippetUtil.get_state_value_pair(line) rgb_string = rgb_string.upper() # validate the rgb string if len(rgb_string) != 6: msg = 'expected each rgb string to be six characters long' raise HandlingError(msg) bad_letters = set(rgb_string) - set('0123456789ABCDEFabcdef') if bad_letters: msg = 'found invalid rgb characters: %s' % str(tuple(bad_letters)) raise HandlingError(msg) # associate the branch with its color name_to_rgb[name_string] = rgb_string # color the branches for name, rgb in name_to_rgb.items(): try: node = tree.get_unique_node(name) except Newick.NewickSearchError as e: raise HandlingError(e) node.branch_color = rgb # do the layout try: layout = FastDaylightLayout.StraightBranchLayout() layout.do_layout(tree) except RuntimeError as e: pass # draw the image try: ext = Form.g_imageformat_to_ext[fs.imageformat] return DrawTreeImage.get_tree_image(tree, (640, 480), ext) except CairoUtil.CairoUtilError as e: raise HandlingError(e)
def get_response_content(fs): # get a properly formatted newick tree with branch lengths tree = Newick.parse(fs.tree, SpatialTree.SpatialTree) tree.assert_valid() if tree.has_negative_branch_lengths(): msg = 'drawing a tree with negative branch lengths is not implemented' raise HandlingError(msg) tree.add_branch_lengths() # get the dictionary mapping the branch name to the nucleotide name_to_nt = {} lines = Util.get_stripped_lines(fs.column.splitlines()) if lines: name_to_nt = SnippetUtil.get_generic_dictionary(lines, 'name', 'nucleotide', list('acgtACGT')) # augment the tips with the nucleotide letters for name, nt in name_to_nt.items(): try: node = tree.get_unique_node(name) except Newick.NewickSearchError as e: raise HandlingError(e) if node.children: msg = 'constraints on internal nodes are not implemented' raise HandlingError(msg) node.state = nt.upper() # read the rate matrix R = fs.matrix # convert the rate matrix to a rate matrix object states = list('ACGT') rate_matrix_object = RateMatrix.RateMatrix(R.tolist(), states) # simulate the ancestral nucleotides rate_matrix_object.simulate_ancestral_states(tree) # simulate a path on each branch # this breaks up the branch into a linear sequence of nodes and adds color for node in tree.gen_non_root_nodes(): simulate_branch_path(tree, node, rate_matrix_object) # do the layout EqualArcLayout.do_layout(tree) # draw the image try: ext = Form.g_imageformat_to_ext[fs.imageformat] return DrawTreeImage.get_tree_image(tree, (640, 480), ext) except CairoUtil.CairoUtilError as e: raise HandlingError(e)
def get_response_content(fs): # get the tree tree = Newick.parse(fs.tree, Newick.NewickTree) tree.assert_valid() # read the ordered states ordered_states = Util.get_stripped_lines(StringIO(fs.states)) # read the matrix from the form data R = fs.rate_matrix if len(R) < 2: raise HandlingError('the rate matrix should have at least two rows') if len(ordered_states) != len(R): msg_a = 'the number of ordered states should be the same ' msg_b = 'as the number of rows in the matrix' raise HandlingError(msg_a + msg_b) # get the dictionary mapping taxa to states taxon_to_state = SnippetUtil.get_generic_dictionary( StringIO(fs.assignments), 'taxon name', 'state name', ordered_states) # set the states for each of the tree tips for node in tree.gen_tips(): node.state = taxon_to_state[node.name] # create the rate matrix object rate_matrix_object = RateMatrix.RateMatrix(R.tolist(), ordered_states) # repeatedly reroot and calculate root state distributions internal_nodes = list(tree.gen_internal_nodes()) for node in internal_nodes: tree.reroot(node) rate_matrix_object.add_probabilities(tree) weights = [node.state_to_subtree_prob[state] for state in ordered_states] node.state_distribution = Util.weights_to_distribution(weights) # define the response out = StringIO() # show the ancestral state distributions for node in tree.gen_internal_nodes(): if node.name: name = '\t'.join(str(p) for p in node.state_distribution) print >> out, node.name, ':', name # write the response return out.getvalue()
def get_response_content(fs): # get the tree tree = Newick.parse(fs.tree, Newick.NewickTree) tree.assert_valid() # read the ordered states ordered_states = Util.get_stripped_lines(StringIO(fs.states)) # read the matrix from the form data R = fs.rate_matrix if len(R) < 2: raise HandlingError('the rate matrix should have at least two rows') if len(ordered_states) != len(R): msg_a = 'the number of ordered states should be the same ' msg_b = 'as the number of rows in the matrix' raise HandlingError(msg_a + msg_b) # get the dictionary mapping taxa to states taxon_to_state = SnippetUtil.get_generic_dictionary( StringIO(fs.assignments), 'taxon name', 'state name', ordered_states) # set the states for each of the tree tips for node in tree.gen_tips(): node.state = taxon_to_state[node.name] # create the rate matrix object rate_matrix_object = RateMatrix.RateMatrix(R.tolist(), ordered_states) # repeatedly reroot and calculate root state distributions internal_nodes = list(tree.gen_internal_nodes()) for node in internal_nodes: tree.reroot(node) rate_matrix_object.add_probabilities(tree) weights = [ node.state_to_subtree_prob[state] for state in ordered_states ] node.state_distribution = Util.weights_to_distribution(weights) # define the response out = StringIO() # show the ancestral state distributions for node in tree.gen_internal_nodes(): if node.name: name = '\t'.join(str(p) for p in node.state_distribution) print >> out, node.name, ':', name # write the response return out.getvalue()
def get_response_content(fs): # get the tree tree = Newick.parse(fs.tree, Newick.NewickTree) tree.assert_valid() # get the nucleotide distribution distribution = SnippetUtil.get_distribution(fs.weights, 'nucleotide', list('ACGT')) # get the nucleotide alignment try: alignment = Fasta.Alignment(StringIO(fs.alignment)) alignment.force_nucleotide() except Fasta.AlignmentError as e: raise HandlingError(e) # get the rate matrix defined by the nucleotide distribution and kappa row_major_rate_matrix = RateMatrix.get_unscaled_hky85_rate_matrix( distribution, fs.kappa).get_row_major_rate_matrix() rate_matrix = RateMatrix.FastRateMatrix(row_major_rate_matrix, list('ACGT')) rate_matrix.normalize() # get the mle rates mle_rates = get_mle_rates(tree, alignment, rate_matrix) # return the response return get_stockholm_string(tree, alignment, mle_rates) + '\n'
def get_response_content(fs): # get the tree tree = Newick.parse(fs.tree, Newick.NewickTree) tree.assert_valid() # get the nucleotide distribution distribution = SnippetUtil.get_distribution( fs.weights, 'nucleotide', list('ACGT')) # get the nucleotide alignment try: alignment = Fasta.Alignment(StringIO(fs.alignment)) alignment.force_nucleotide() except Fasta.AlignmentError as e: raise HandlingError(e) # get the rate matrix defined by the nucleotide distribution and kappa row_major_rate_matrix = RateMatrix.get_unscaled_hky85_rate_matrix( distribution, fs.kappa).get_row_major_rate_matrix() rate_matrix = RateMatrix.FastRateMatrix( row_major_rate_matrix, list('ACGT')) rate_matrix.normalize() # get the mle rates mle_rates = get_mle_rates(tree, alignment, rate_matrix) # return the response return get_stockholm_string(tree, alignment, mle_rates) + '\n'
def get_response(fs): """ @param fs: a FieldStorage object containing the cgi arguments @return: a (response_headers, response_text) pair """ # parse the tree try: tree = Newick.parse(fs.tree, Newick.NewickTree) tree.assert_valid() except Newick.NewickSyntaxError as e: raise HandlingError(str(e)) # get the mixture weights mixture_weights = [fs.weight_a, fs.weight_b] # get the kappa values kappa_values = [fs.kappa_a, fs.kappa_b] # get the nucleotide distributions frequency_strings = (fs.frequency_a, fs.frequency_b) nucleotide_distributions = [] for nt_string in frequency_strings: d = SnippetUtil.get_distribution(nt_string, 'nucleotide', list('ACGT')) nucleotide_distributions.append(d) # create the nucleotide HKY rate matrix objects rate_matrix_objects = [] for nt_distribution, kappa in zip(nucleotide_distributions, kappa_values): rate_matrix_object = RateMatrix.get_unscaled_hky85_rate_matrix( nt_distribution, kappa) rate_matrix_objects.append(rate_matrix_object) # create the mixture proportions weight_sum = sum(mixture_weights) mixture_proportions = [weight / weight_sum for weight in mixture_weights] # create the mixture model mixture_model = SubModel.MixtureModel(mixture_proportions, rate_matrix_objects) # normalize the mixture model mixture_model.normalize() # simulate the alignment try: alignment = PhyLikelihood.simulate_alignment(tree, mixture_model, fs.ncols) except PhyLikelihood.SimulationError as e: raise HandlingError(e) # get the output string output_string = '' if fs.fasta: # the output is the alignment arr = [] for node in tree.gen_tips(): arr.append(alignment.get_fasta_sequence(node.name)) alignment_string = '\n'.join(arr) output_string = alignment_string elif fs.nex: # the output is the alignment and the tree nexus = Nexus.Nexus() nexus.tree = tree nexus.alignment = alignment for i in range(2): arr = [] arr.append('weight: %s' % mixture_weights[i]) arr.append('kappa: %s' % kappa_values[i]) nexus.add_comment('category %d: %s' % (i + 1, ', '.join(arr))) output_string = str(nexus) # define the filename if fs.fasta: filename_extension = 'fasta' elif fs.nex: filename_extension = 'nex' filename = 'sample.' + fs.fmt #TODO use the correct filename extension in the output return output_string
def get_response_content(fs): # get the nucleotide distribution nt_to_weight = SnippetUtil.get_distribution(fs.nucleotides, 'nucleotide', nt_letters) # get the amino acid distribution aa_to_weight = SnippetUtil.get_distribution(fs.aminoacids, 'amino acid', aa_letters) # get distributions in convenient list form stationary_nt_distribution = [nt_to_weight[nt] for nt in nt_letters] aa_distribution = [aa_to_weight[aa] for aa in aa_letters] codon_distribution = [] implied_stationary_nt_distribution = [] if fs.corrected: # define the objective function objective_function = MyObjective(aa_distribution, stationary_nt_distribution) initial_guess = (0, 0, 0) iterations = 20 best = scipy.optimize.nonlin.broyden2(objective_function, initial_guess, iterations) x, y, z = best best_mutation_weights = (1, math.exp(x), math.exp(y), math.exp(z)) best_mutation_distribution = normalized(best_mutation_weights) # Given the mutation distribution and the amino acid distribution, # get the stationary distribution. result = DirectProtein.get_nt_distribution_and_aa_energies( best_mutation_distribution, aa_distribution) implied_stationary_nt_distribution, result_aa_energies = result # Get the codon distribution; # kappa doesn't matter because we are only concerned # with stationary distributions kappa = 1.0 dpm = DirectProtein.DirectProteinRateMatrix( kappa, best_mutation_distribution, result_aa_energies) codon_distribution = dpm.get_stationary_distribution() elif fs.hb: # get the codon distribution unnormalized_codon_distribution = [] for codon in codons: aa = Codon.g_codon_to_aa_letter[codon] sibling_codons = Codon.g_aa_letter_to_codons[aa] codon_aa_weight = aa_to_weight[aa] codon_nt_weight = np.prod([nt_to_weight[nt] for nt in codon]) sibling_nt_weight_sum = sum( np.prod([nt_to_weight[nt] for nt in sibling]) for sibling in sibling_codons) weight = codon_aa_weight * codon_nt_weight weight /= sibling_nt_weight_sum unnormalized_codon_distribution.append(weight) codon_distribution = normalized(unnormalized_codon_distribution) nt_to_weight = dict(zip(nt_letters, [0] * 4)) for codon, p in zip(codons, codon_distribution): for nt in codon: nt_to_weight[nt] += p implied_stationary_nt_distribution = normalized(nt_to_weight[nt] for nt in nt_letters) # start the output text string out = StringIO() # write the codon stationary distribution print >> out, 'estimated codon stationary distribution:' for codon, p in zip(codons, codon_distribution): print >> out, '%s : %s' % (codon, p) print >> out, '' # write the nucleotide stationary distribution print >> out, 'implied nucleotide stationary distribution:' for nt, p in zip(nt_letters, implied_stationary_nt_distribution): print >> out, '%s : %s' % (nt, p) # return the response return out.getvalue()
def handler(req): """ If no arguments were provided then display the directory of scripts. Otherwise if a valid myscript identifier was provided then dispatch the request to the script. Otherwise show an error message. """ try: field_storage = mod_python.util.FieldStorage(req) scriptid = field_storage.getfirst('myscript') if not req.args: # if the page was called with no arguments then show a directory html page try: script_directory = get_script_directory(req) doc_directory = os.path.join(get_doc_root(req), 'phydoc') except DirectoryError as e: req.content_type = "text/plain" print >> req, 'Error:', e else: req.content_type = "text/html" page_buffer = StringIO() write_directory_html(script_directory, doc_directory, page_buffer) req.write(page_buffer.getvalue()) else: # the page was called with arguments so get a response from the module if not scriptid: raise DispatchError('no script snippet was specified') if not re.match(r'^\d{8}[a-zA-Z]$', scriptid): raise DispatchError( 'the specified script name did not meet the format requirements' ) try: module = __import__( scriptid, globals(), locals(), ['__doc__', 'handler', 'get_form', 'get_response']) except ImportError: raise DispatchError('the script could not be imported') # process the module differently depending on its type if hasattr(module, 'get_form') and hasattr(module, 'get_response'): # This is the more advanced dispatch method. # Determine whether we are asking for a form or for a response. if len(field_storage.keys()) == 1: # send a form form_html = module.get_form() req.content_type = "text/html" print >> req, '<html>' title = SnippetUtil.docstring_to_title(module.__doc__) if title: print >> req, '<head>' print >> req, '<title>' print >> req, title print >> req, '</title>' print >> req, '</head>' print >> req, '<body>' print >> req, SnippetUtil.docstring_to_html(module.__doc__) print >> req, '<br/><br/>' print >> req, '<form method="post">' print >> req, '<input type="hidden" name="myscript" value="%s"/>' % scriptid print >> req, form_html print >> req, '<br/><br/>' print >> req, '<input type="submit" name="mysubmit" value="Submit"/><br/>' print >> req, '</form>' print >> req, '</body>' print >> req, '</html>' else: content_info, content_text = module.get_response( field_storage) for key, value in content_info: if key == 'Content-Type': req.content_type = value else: req.headers_out[key] = value req.write(content_text) else: raise DispatchError( 'no web interface was found for this script') except DispatchError as e: req.content_type = "text/plain" print >> req, 'Error:', e except HandlingError as e: req.content_type = "text/plain" print >> req, 'Error:', e # pretend everything is OK return mod_python.apache.OK
def handler(req): """ If no arguments were provided then display the directory of scripts. Otherwise if a valid myscript identifier was provided then dispatch the request to the script. Otherwise show an error message. """ import mod_python # redirect to the code page if no args were passed if not req.args: req.content_type = "text/html" print >> req, '<head>' print >> req, '<meta HTTP-EQUIV="REFRESH" content="0; url=/code">' print >> req, '</head>' print >> req, '<body></body>' return mod_python.apache.OK try: field_storage = mod_python.util.FieldStorage(req) scriptid = field_storage.getfirst('myscript') if not scriptid: raise DispatchError('no script snippet was specified') if not re.match(r'^\d{8}[a-zA-Z]$', scriptid): raise DispatchError('the specified script name did not meet the format requirements') try: module = __import__(scriptid, globals(), locals(), ['__doc__', 'handler', 'get_form', 'get_response']) except ImportError: raise DispatchError('the script could not be imported') # process the module differently depending on its type if hasattr(module, 'get_form') and hasattr(module, 'get_response'): # This is the more advanced dispatch method. # Get the form data. form_data = module.get_form() # Determine whether we are asking for a form or for a response. if len(field_storage.keys()) == 1: # the form from the module is either a string or a list of form objects if type(form_data) is str: form_html = form_data else: form_html = Form.get_html_string(form_data) req.content_type = str('text/html') print >> req, '<html>' title = SnippetUtil.docstring_to_title(module.__doc__) if title: print >> req, '<head>' print >> req, '<title>' print >> req, title print >> req, '</title>' print >> req, '</head>' print >> req, '<body>' print >> req, SnippetUtil.docstring_to_html(module.__doc__) print >> req, '<br/><br/>' print >> req, '<form method="post">' print >> req, '<input type="hidden" name="myscript" value="%s"/>' % scriptid print >> req, form_html print >> req, '<br/><br/>' print >> req, '<input type="submit" name="mysubmit" value="Submit"/><br/>' print >> req, '</form>' print >> req, '</body>' print >> req, '</html>' else: # possibly parse the field storage data according to the form data if type(form_data) is not str: for form_item in form_data: form_item.process_fieldstorage(field_storage) # get the response content_info, content_text = module.get_response(field_storage) for key, value in content_info: if key == 'Content-Type': req.content_type = value else: req.headers_out[key] = value req.write(content_text) else: raise DispatchError('no web interface was found for this script') except ImportError as e: req.content_type = "text/plain" print >> req, 'Uncaught ImportError:', e except DispatchError as e: req.content_type = "text/plain" print >> req, 'Error:', e except HandlingError as e: req.content_type = "text/plain" print >> req, 'Error:', e except Form.FormError as e: req.content_type = "text/plain" print >> req, 'Form validation error:', e # pretend everything is OK return mod_python.apache.OK
def get_response(fs): """ @param fs: a FieldStorage object containing the cgi arguments @return: a (response_headers, response_text) pair """ # parse the tree try: tree = Newick.parse(fs.tree, Newick.NewickTree) tree.assert_valid() except Newick.NewickSyntaxError as e: raise HandlingError(str(e)) # get the mixture weights mixture_weights = [fs.weight_a, fs.weight_b] # get the kappa values kappa_values = [fs.kappa_a, fs.kappa_b] # get the nucleotide distributions frequency_strings = (fs.frequency_a, fs.frequency_b) nucleotide_distributions = [] for nt_string in frequency_strings: d = SnippetUtil.get_distribution(nt_string, 'nucleotide', list('ACGT')) nucleotide_distributions.append(d) # create the nucleotide HKY rate matrix objects rate_matrix_objects = [] for nt_distribution, kappa in zip(nucleotide_distributions, kappa_values): rate_matrix_object = RateMatrix.get_unscaled_hky85_rate_matrix( nt_distribution, kappa) rate_matrix_objects.append(rate_matrix_object) # create the mixture proportions weight_sum = sum(mixture_weights) mixture_proportions = [weight / weight_sum for weight in mixture_weights] # create the mixture model mixture_model = SubModel.MixtureModel( mixture_proportions, rate_matrix_objects) # normalize the mixture model mixture_model.normalize() # simulate the alignment try: alignment = PhyLikelihood.simulate_alignment( tree, mixture_model, fs.ncols) except PhyLikelihood.SimulationError as e: raise HandlingError(e) # get the output string output_string = '' if fs.fasta: # the output is the alignment arr = [] for node in tree.gen_tips(): arr.append(alignment.get_fasta_sequence(node.name)) alignment_string = '\n'.join(arr) output_string = alignment_string elif fs.nex: # the output is the alignment and the tree nexus = Nexus.Nexus() nexus.tree = tree nexus.alignment = alignment for i in range(2): arr = [] arr.append('weight: %s' % mixture_weights[i]) arr.append('kappa: %s' % kappa_values[i]) nexus.add_comment('category %d: %s' % (i+1, ', '.join(arr))) output_string = str(nexus) # define the filename if fs.fasta: filename_extension = 'fasta' elif fs.nex: filename_extension = 'nex' filename = 'sample.' + fs.fmt #TODO use the correct filename extension in the output return output_string
def get_ordered_ids(tree): """ Maybe I could use postorder here instead. @param tree: a tree @return: a list of ids beginning with the leaves """ ordered_ids = [] ordered_ids.extend(id(node) for node in tree.gen_tips()) ordered_ids.extend(id(node) for node in tree.gen_internal_nodes()) return ordered_ids def main(args): print process(args.ntaxa, args.nseconds) if __name__ == '__main__': parser = argparse.ArgumentParser( description=SnippetUtil.docstring_to_title(__doc__)) parser.add_argument('--nseconds', type=int, default=0, help='seconds to run or 0 to run until ctrl-c') parser.add_argument('--ntaxa', type=int, default=5, help='number of taxa in each sampled tree topology') args = parser.parse_args() main(args)
def index(self): out = StringIO() self._init_form() form_html = Form.get_html_string(self.form_objects) print >> out, '<html>' print >> out, '<head>' title = SnippetUtil.docstring_to_title(self.module.__doc__) if title: print >> out, '<title>' print >> out, title print >> out, '</title>' print >> out, FormHeaderJs.get_header_script_text( self.form_objects, self.form_presets) print >> out, '</head>' print >> out, '<body>' lines = smallutil.get_stripped_lines(StringIO(self.module.__doc__)) if lines: print >> out, lines[0] else: print >> out, gray_span('untitled') print >> out, '<br/>' print >> out, '<code>', if self.source_link: relative_link = '../' + self.source_link print >> out, '<a href="%s">source code</a>' % relative_link else: print >> out, gray_span('source code') print >> out, '</code>' print >> out, '<br/><br/>' print >> out if len(lines) > 1: print >> out, '<!-- long description -->' for line in lines[1:]: print >> out, line print >> out, '<br/><br/>' else: print >> out, '<!-- no long description available -->' print >> out print >> out, '<!-- main form -->' print >> out, '<div style="float: left;">' print >> out, '<form id="mainform" action="process" method="post">' if form_html: print >> out, form_html print >> out, '<br/><br/>' print >> out, '<input type="submit" name="submit" value="view"/>' print >> out, '<input type="submit" name="submit" value="download"/>' print >> out, '<br/>' print >> out, '</form>' print >> out, '</div>' print >> out if self.form_presets: print >> out, '<!-- preset configurations -->' print >> out, '<div style="float: left;">' print >> out, '<fieldset>' print >> out, '<legend>preset configurations</legend>' button_tags = [] default_preset = Form.get_default_preset(self.form_objects) for i, preset in enumerate([default_preset] + self.form_presets): tag = get_preset_button_tag(i, preset.description) button_tags.append(tag) print >> out, '<br/>\n'.join(button_tags) print >> out, '</fieldset>' print >> out, '</div>' print >> out print >> out, '</body>' print >> out, '</html>' return out.getvalue().rstrip()
def handler(req): """ If no arguments were provided then display the directory of scripts. Otherwise if a valid myscript identifier was provided then dispatch the request to the script. Otherwise show an error message. """ import mod_python # redirect to the code page if no args were passed if not req.args: req.content_type = "text/html" print >> req, '<head>' print >> req, '<meta HTTP-EQUIV="REFRESH" content="0; url=/code">' print >> req, '</head>' print >> req, '<body></body>' return mod_python.apache.OK try: field_storage = mod_python.util.FieldStorage(req) scriptid = field_storage.getfirst('myscript') if not scriptid: raise DispatchError('no script snippet was specified') if not re.match(r'^\d{8}[a-zA-Z]$', scriptid): raise DispatchError( 'the specified script name did not meet the format requirements' ) try: module = __import__( scriptid, globals(), locals(), ['__doc__', 'handler', 'get_form', 'get_response']) except ImportError: raise DispatchError('the script could not be imported') # process the module differently depending on its type if hasattr(module, 'get_form') and hasattr(module, 'get_response'): # This is the more advanced dispatch method. # Get the form data. form_data = module.get_form() # Determine whether we are asking for a form or for a response. if len(field_storage.keys()) == 1: # the form from the module is either a string or a list of form objects if type(form_data) is str: form_html = form_data else: form_html = Form.get_html_string(form_data) req.content_type = str('text/html') print >> req, '<html>' title = SnippetUtil.docstring_to_title(module.__doc__) if title: print >> req, '<head>' print >> req, '<title>' print >> req, title print >> req, '</title>' print >> req, '</head>' print >> req, '<body>' print >> req, SnippetUtil.docstring_to_html(module.__doc__) print >> req, '<br/><br/>' print >> req, '<form method="post">' print >> req, '<input type="hidden" name="myscript" value="%s"/>' % scriptid print >> req, form_html print >> req, '<br/><br/>' print >> req, '<input type="submit" name="mysubmit" value="Submit"/><br/>' print >> req, '</form>' print >> req, '</body>' print >> req, '</html>' else: # possibly parse the field storage data according to the form data if type(form_data) is not str: for form_item in form_data: form_item.process_fieldstorage(field_storage) # get the response content_info, content_text = module.get_response(field_storage) for key, value in content_info: if key == 'Content-Type': req.content_type = value else: req.headers_out[key] = value req.write(content_text) else: raise DispatchError('no web interface was found for this script') except ImportError as e: req.content_type = "text/plain" print >> req, 'Uncaught ImportError:', e except DispatchError as e: req.content_type = "text/plain" print >> req, 'Error:', e except HandlingError as e: req.content_type = "text/plain" print >> req, 'Error:', e except Form.FormError as e: req.content_type = "text/plain" print >> req, 'Form validation error:', e # pretend everything is OK return mod_python.apache.OK
print >> out, 'S:' print >> out, S print >> out print >> out, 'pseudoinverse of S:' print >> out, S_pinv print >> out return out.getvalue().strip() def get_response_content(fs): return process(fs.ntaxa) + '\n' def get_ordered_ids(tree): """ Maybe I could use postorder here instead. @param tree: a tree @return: a list of ids beginning with the leaves """ ordered_ids = [] ordered_ids.extend(id(node) for node in tree.gen_tips()) ordered_ids.extend(id(node) for node in tree.gen_internal_nodes()) return ordered_ids def main(args): print process(args.ntaxa) if __name__ == '__main__': parser = argparse.ArgumentParser(description=SnippetUtil.docstring_to_title(__doc__)) parser.add_argument('--ntaxa', type=int, default=5, help='number of taxa in the tree') args = parser.parse_args() main(args)
def get_response_content(fs): # get the nucleotide distribution nt_to_weight = SnippetUtil.get_distribution(fs.nucleotides, 'nucleotide', nt_letters) # get the amino acid distribution aa_to_weight = SnippetUtil.get_distribution(fs.aminoacids, 'amino acid', aa_letters) # get distributions in convenient list form stationary_nt_distribution = [nt_to_weight[nt] for nt in nt_letters] aa_distribution = [aa_to_weight[aa] for aa in aa_letters] codon_distribution = [] implied_stationary_nt_distribution = [] if fs.corrected: # define the objective function objective_function = MyObjective(aa_distribution, stationary_nt_distribution) initial_guess = (0, 0, 0) iterations = 20 best = scipy.optimize.nonlin.broyden2(objective_function, initial_guess, iterations) x, y, z = best best_mutation_weights = (1, math.exp(x), math.exp(y), math.exp(z)) best_mutation_distribution = normalized(best_mutation_weights) # Given the mutation distribution and the amino acid distribution, # get the stationary distribution. result = DirectProtein.get_nt_distribution_and_aa_energies( best_mutation_distribution, aa_distribution) implied_stationary_nt_distribution, result_aa_energies = result # Get the codon distribution; # kappa doesn't matter because we are only concerned # with stationary distributions kappa = 1.0 dpm = DirectProtein.DirectProteinRateMatrix( kappa, best_mutation_distribution, result_aa_energies) codon_distribution = dpm.get_stationary_distribution() elif fs.hb: # get the codon distribution unnormalized_codon_distribution = [] for codon in codons: aa = Codon.g_codon_to_aa_letter[codon] sibling_codons = Codon.g_aa_letter_to_codons[aa] codon_aa_weight = aa_to_weight[aa] codon_nt_weight = np.prod([nt_to_weight[nt] for nt in codon]) sibling_nt_weight_sum = sum(np.prod([nt_to_weight[nt] for nt in sibling]) for sibling in sibling_codons) weight = codon_aa_weight * codon_nt_weight weight /= sibling_nt_weight_sum unnormalized_codon_distribution.append(weight) codon_distribution = normalized(unnormalized_codon_distribution) nt_to_weight = dict(zip(nt_letters, [0]*4)) for codon, p in zip(codons, codon_distribution): for nt in codon: nt_to_weight[nt] += p implied_stationary_nt_distribution = normalized(nt_to_weight[nt] for nt in nt_letters) # start the output text string out = StringIO() # write the codon stationary distribution print >> out, 'estimated codon stationary distribution:' for codon, p in zip(codons, codon_distribution): print >> out, '%s : %s' % (codon, p) print >> out, '' # write the nucleotide stationary distribution print >> out, 'implied nucleotide stationary distribution:' for nt, p in zip(nt_letters, implied_stationary_nt_distribution): print >> out, '%s : %s' % (nt, p) # return the response return out.getvalue()
def do_cgi(): """ This is called when the script is run as a cgi script. """ # get the fields sent by the browser fs = cgi.FieldStorage() # start writing a response out = StringIO() # initialize the header dictionary header_dict = {} # get some environment variables from the cgi document_root = os.getenv('DOCUMENT_ROOT') script_filename = os.getenv('SCRIPT_FILENAME') # try to generate some useful data to send to the user try: if not list(fs): # if the page was called with no arguments then show a directory html page doc_directory = os.path.join(document_root, 'phydoc') header_dict['Content-Type'] = 'text/html' write_directory_html(script_directory, doc_directory, out) else: # the page was called with arguments so get a response from the module scriptid = fs.getfirst('myscript') if not scriptid: raise DispatchError('no script snippet was specified') if not re.match(r'^\d{8}[a-zA-Z]$', scriptid): raise DispatchError( 'the specified script name did not meet the format requirements' ) try: module = __import__( scriptid, globals(), locals(), ['__doc__', 'handler', 'get_form', 'get_response']) except ImportError: raise DispatchError('the script could not be imported') # process the module differently depending on its type if hasattr(module, 'get_form') and hasattr(module, 'get_response'): # This is the more advanced dispatch method. # Determine whether we are asking for a form or for a response. if len(fs.keys()) == 1: # send a form form_html = module.get_form() header_dict['Content-Type'] = 'text/html' print >> out, '<html>' title = SnippetUtil.docstring_to_title(module.__doc__) if title: print >> out, '<head>' print >> out, '<title>' print >> out, title print >> out, '</title>' print >> out, '</head>' print >> out, '<body>' print >> out, SnippetUtil.docstring_to_html(module.__doc__) print >> out, '<br/><br/>' print >> out, '<form method="post">' print >> out, '<input type="hidden" name="myscript" value="%s"/>' % scriptid print >> out, form_html print >> out, '<br/><br/>' print >> out, '<input type="submit" name="mysubmit" value="Submit"/><br/>' print >> out, '</form>' print >> out, '</body>' print >> out, '</html>' else: content_info, content_text = module.get_response(fs) header_dict.update(content_info) out.write(content_text) else: raise DispatchError( 'no web interface was found for this script') except (DirectoryError, DispatchError, HandlingError), e: header_dict['Content-Type'] = 'text/plain' print >> out, 'Error:', e
def do_cgi(): """ This is called when the script is run as a cgi script. """ # get the fields sent by the browser fs = cgi.FieldStorage() # start writing a response out = StringIO() # initialize the header dictionary header_dict = {} # get some environment variables from the cgi document_root = os.getenv('DOCUMENT_ROOT') script_filename = os.getenv('SCRIPT_FILENAME') # try to generate some useful data to send to the user try: if not list(fs): # if the page was called with no arguments then show a directory html page doc_directory = os.path.join(document_root, 'phydoc') header_dict['Content-Type'] = 'text/html' write_directory_html(script_directory, doc_directory, out) else: # the page was called with arguments so get a response from the module scriptid = fs.getfirst('myscript') if not scriptid: raise DispatchError('no script snippet was specified') if not re.match(r'^\d{8}[a-zA-Z]$', scriptid): raise DispatchError('the specified script name did not meet the format requirements') try: module = __import__(scriptid, globals(), locals(), ['__doc__', 'handler', 'get_form', 'get_response']) except ImportError: raise DispatchError('the script could not be imported') # process the module differently depending on its type if hasattr(module, 'get_form') and hasattr(module, 'get_response'): # This is the more advanced dispatch method. # Determine whether we are asking for a form or for a response. if len(fs.keys()) == 1: # send a form form_html = module.get_form() header_dict['Content-Type'] = 'text/html' print >> out, '<html>' title = SnippetUtil.docstring_to_title(module.__doc__) if title: print >> out, '<head>' print >> out, '<title>' print >> out, title print >> out, '</title>' print >> out, '</head>' print >> out, '<body>' print >> out, SnippetUtil.docstring_to_html(module.__doc__) print >> out, '<br/><br/>' print >> out, '<form method="post">' print >> out, '<input type="hidden" name="myscript" value="%s"/>' % scriptid print >> out, form_html print >> out, '<br/><br/>' print >> out, '<input type="submit" name="mysubmit" value="Submit"/><br/>' print >> out, '</form>' print >> out, '</body>' print >> out, '</html>' else: content_info, content_text = module.get_response(fs) header_dict.update(content_info) out.write(content_text) else: raise DispatchError('no web interface was found for this script') except (DirectoryError, DispatchError, HandlingError), e: header_dict['Content-Type'] = 'text/plain' print >> out, 'Error:', e
def handler(req): """ If no arguments were provided then display the directory of scripts. Otherwise if a valid myscript identifier was provided then dispatch the request to the script. Otherwise show an error message. """ try: field_storage = mod_python.util.FieldStorage(req) scriptid = field_storage.getfirst('myscript') if not req.args: # if the page was called with no arguments then show a directory html page try: script_directory = get_script_directory(req) doc_directory = os.path.join(get_doc_root(req), 'phydoc') except DirectoryError as e: req.content_type = "text/plain" print >> req, 'Error:', e else: req.content_type = "text/html" page_buffer = StringIO() write_directory_html(script_directory, doc_directory, page_buffer) req.write(page_buffer.getvalue()) else: # the page was called with arguments so get a response from the module if not scriptid: raise DispatchError('no script snippet was specified') if not re.match(r'^\d{8}[a-zA-Z]$', scriptid): raise DispatchError('the specified script name did not meet the format requirements') try: module = __import__(scriptid, globals(), locals(), ['__doc__', 'handler', 'get_form', 'get_response']) except ImportError: raise DispatchError('the script could not be imported') # process the module differently depending on its type if hasattr(module, 'get_form') and hasattr(module, 'get_response'): # This is the more advanced dispatch method. # Determine whether we are asking for a form or for a response. if len(field_storage.keys()) == 1: # send a form form_html = module.get_form() req.content_type = "text/html" print >> req, '<html>' title = SnippetUtil.docstring_to_title(module.__doc__) if title: print >> req, '<head>' print >> req, '<title>' print >> req, title print >> req, '</title>' print >> req, '</head>' print >> req, '<body>' print >> req, SnippetUtil.docstring_to_html(module.__doc__) print >> req, '<br/><br/>' print >> req, '<form method="post">' print >> req, '<input type="hidden" name="myscript" value="%s"/>' % scriptid print >> req, form_html print >> req, '<br/><br/>' print >> req, '<input type="submit" name="mysubmit" value="Submit"/><br/>' print >> req, '</form>' print >> req, '</body>' print >> req, '</html>' else: content_info, content_text = module.get_response(field_storage) for key, value in content_info: if key == 'Content-Type': req.content_type = value else: req.headers_out[key] = value req.write(content_text) else: raise DispatchError('no web interface was found for this script') except DispatchError as e: req.content_type = "text/plain" print >> req, 'Error:', e except HandlingError as e: req.content_type = "text/plain" print >> req, 'Error:', e # pretend everything is OK return mod_python.apache.OK