def save(request, pk): if not all(x in request.POST for x in ["changes", "objectives"]): raise BadRequest("Request incomplete") try: model = DesignModel.objects.get(user=UserProfile.get_profile(request.user), pk=pk) except ObjectDoesNotExist: raise BadRequest("Bad Model") try: revision = request.POST["revision"] try: revision = Revision.objects.get(model=model, pk=revision) except ObjectDoesNotExist: raise BadRequest("Bad Revision") except KeyError: revision = model.get_latest_revision() org = model_from_string(revision.content) try: changes = json.loads(request.POST["changes"]) objectives = json.loads(request.POST["objectives"]) except ValueError: return BadRequest("Invalid JSON data") summary = request.POST.get("summary") try: apply_commandlist(org, changes) org = model_from_string(revision.content) changes = compress_command_list(changes) apply_commandlist(org, changes) if objectives: org.objectives = [] for obj in objectives: if len(obj["name"]) > 0: obj_reac = org.get_reaction(obj["name"]) if obj_reac is None: raise BadRequest("Objective not in model: " + obj["name"]) org.objectives.append(JsonModel.Objective(**obj)) except ValueError as e: raise BadRequest("Model error: " + str(e)) if len(changes) == 0: raise BadRequest("Model not saved: No changes found") Revision( model=model, content=org.to_json(), changes=dict(changes=changes,objectives=objectives), reason=summary ).save() return {}
def save(request, pk): if not all(x in request.POST for x in ["changes", "objectives"]): raise BadRequest("Request incomplete") try: model = DesignModel.objects.get(user=UserProfile.get_profile( request.user), pk=pk) except ObjectDoesNotExist: raise BadRequest("Bad Model") try: revision = request.POST["revision"] try: revision = Revision.objects.get(model=model, pk=revision) except ObjectDoesNotExist: raise BadRequest("Bad Revision") except KeyError: revision = model.get_latest_revision() org = Metabolism(StringIO(revision.content)) try: changes = json.loads(request.POST["changes"]) objectives = json.loads(request.POST["objectives"]) except ValueError: return BadRequest("Invalid JSON data") summary = request.POST.get("summary") try: apply_commandlist(org, changes) org = Metabolism(StringIO(revision.content)) changes = compress_command_list(changes) apply_commandlist(org, changes) if objectives: org.objectives = [] for obj in objectives: if len(obj["name"]) > 0: obj_reac = org.get_reaction(obj["name"]) if obj_reac is None: raise BadRequest("Objective not in model: " + obj["name"]) org.obj = [] org.obj.append( [obj_reac.id, "1" if obj["maximize"] else "-1"]) except ValueError as e: raise BadRequest("Model error: " + str(e)) if len(changes) == 0: raise BadRequest("Model not saved: No changes found") sio = StringIO() org.write_sbml(fileout=sio) Revision(model=model, content=sio.getvalue(), changes=dict(changes=changes, objectives=objectives), reason=summary).save() return {}
def simulate(request, pk): if not all(x in request.POST for x in [ "changes", "objectives", "design_objectives", "target_reactions", "display", "auto_flux", "type" ]): return HttpResponseBadRequest("Request incomplete") output_format = request.POST.get("format", "json") dry_run = request.POST.get("dry_run", False) try: model = DesignModel.objects.get(user=UserProfile.get_profile( request.user), pk=pk) except ObjectDoesNotExist: return HttpResponseBadRequest("Bad Model") try: revision = request.POST["revision"] try: revision = Revision.objects.get(model=model, pk=revision) except ObjectDoesNotExist: return HttpResponseBadRequest("Bad Revision") except KeyError: revision = model.get_latest_revision() org = Metabolism(StringIO(revision.content)) try: changes = json.loads(request.POST["changes"]) objectives = json.loads(request.POST["objectives"]) design_objectives = json.loads(request.POST["design_objectives"]) target_reactions = json.loads(request.POST["target_reactions"]) display = json.loads(request.POST["display"]) auto_flux = json.loads(request.POST["auto_flux"]) simtype = json.loads(request.POST["type"]) except ValueError: return HttpResponseBadRequest("Invalid JSON data") try: auto_flux = bool(auto_flux) except ValueError: return HttpResponseBadRequest("Invalid data type") if str(simtype) not in ["fba", "mba", "sa"]: return HttpResponseBadRequest( "Unsupported simulation type: {}".format(simtype)) try: apply_commandlist(org, changes) org = Metabolism(StringIO(revision.content)) changes = compress_command_list(changes) apply_commandlist(org, changes) if not objectives: raise ValueError("No objective specified") org.obj = [] for obj in objectives: obj_reac = org.get_reaction(obj["name"]) if obj_reac is None: raise ValueError("Objective not in model: " + obj["name"]) if obj_reac.disabled: return HttpResponseBadRequest("Objective disabled: " + obj_reac.name) org.obj.append([obj["name"], "1" if obj["maximize"] else "0"]) if simtype == "mba" or simtype == "sa": org.design_obj = [] for obj in design_objectives: obj_reac = org.get_reaction(obj["name"]) if obj_reac is None: raise ValueError("Design objective not in model: " + obj["name"]) if obj_reac.disabled: return HttpResponseBadRequest( "Design objective disabled: " + obj_reac.name) org.design_obj.append( [obj["name"], "1" if obj["maximize"] else "0"]) org.target_reactions = [] if simtype == "sa": for obj in target_reactions: obj_reac = org.get_reaction(obj["name"]) if obj_reac is None: raise ValueError("Target reaction not in model: " + obj["name"]) if obj_reac.disabled: return HttpResponseBadRequest( "Target reaction disabled: " + obj_reac.name) org.target_reactions.append( [obj["name"], "1" if obj["maximize"] else "0"]) except ValueError as e: return HttpResponseBadRequest("Model error: " + str(e)) try: fba = org.fba() except ValueError as e: return HttpResponseBadRequest("FBA error: " + str(e)) if simtype == "fba": if dry_run: return HttpResponse(json.dumps({"solution": fba.get_status()}), content_type="application/json") full_g, nodeIDs = calc_reactions(org, fba) display = list( filter(lambda x: len(x) > 0 and org.has_reaction(x), display)) dflux = {} for reac, flux in zip(map(lambda x: x, fba.reacs), fba.flux): dflux[reac.id] = flux # Auto filter by FBA if auto_flux: if len(full_g.edges()) <= 30: full_eg = full_g else: full_eg = nx.ego_graph(full_g.reverse(), nodeIDs[org.obj[0][0]], radius=3, center=False, undirected=False) full_g.remove_edges_from( full_g.in_edges(nodeIDs[org.obj[0][0]]) + full_g.out_edges(nodeIDs[org.obj[0][0]])) all_edges = map( lambda x: full_eg.get_edge_data(*x)["object"]["id"], full_eg.edges()) # Get fluxes of "edges" flux = [] for reac in set(all_edges): flux.append([reac, dflux[reac]]) flux = sorted(flux, key=lambda x: -x[1]) display = list(map(lambda x: x[0], flux[:30])) else: full_g.remove_edges_from( full_g.in_edges(nodeIDs[org.obj[0][0]]) + full_g.out_edges(nodeIDs[org.obj[0][0]])) display.append(org.obj[0][0]) g = get_selected_reaction(json_graph.node_link_data(full_g), nodeIDs, display, org) # Work around a bug in nx 1.11 breaking nx.to_agraph function graph = nx.drawing.nx_agraph.to_agraph(g) graph.graph_attr.update(splines=True, overlap=False, rankdir="LR") graph.node_attr.update(style="filled", colorscheme="pastel19") outgraph = str(graph.to_string()) outgraph = pygraphviz.AGraph(outgraph) #outgraph = outgraph.draw(format="svg", prog="dot") if output_format == "json": return HttpResponse(json.dumps({ "graph": None, "graphstr": str(graph.to_string()), "solution": fba.get_status(), "flux": dflux }), content_type="application/json") elif output_format == "png": import wand.image with wand.image.Image(blob=outgraph, format="svg") as image: png_image = image.make_blob("png") r = HttpResponse(png_image, content_type="image/png") r['Content-Disposition'] = 'attachment; filename={}.png'.format( model.filename) return r elif output_format == "svg": r = HttpResponse(outgraph.decode("utf-8"), content_type="image/svg+xml") r['Content-Disposition'] = 'attachment; filename={}.svg'.format( model.filename) return r elif output_format == "csv": s = StringIO() for reac, flux in zip(fba.reacs, fba.flux): s.write(reac.name) s.write("\t") s.write(str(flux)) s.write("\r\n") r = HttpResponse(s.getvalue(), content_type="text/csv") r['Content-Disposition'] = 'attachment; filename={}.csv'.format( model.filename) return r else: return HttpResponseBadRequest("Unknown format") elif simtype == "mba": # Determine optimal steps obj = org.obj[:] dobj = org.design_obj[:] # Absolute design_result = [["x"], [dobj[0][0]]] #design_result[0] += [0, 0.01, 0.02, 0.03, 0.04, 0.05, 0.06, 0.07, 0.08, 0.09, 0.1] sim_result = fba.design_fba() #dflux = [list(str(x[fba.reac_names.index(obj[0][0])]) for x in sim_result), # list(x[fba.reac_names.index(dobj[0][0])] for x in sim_result)] dflux = list([x[0]] for x in sim_result) for lst, sim_res in zip(dflux, sim_result): lst.append({}) for name, flux in zip(fba.reac_names, sim_res[1]): lst[1][name] = flux graph = [["x"], [dobj[0][0]]] for d in dflux: graph[0].append(d[0]) graph[1].append(d[1][dobj[0][0]]) if output_format == "json": return HttpResponse(json.dumps({ "solution": fba.get_status(), "flux": dflux, "graph": graph }), content_type="application/json") else: return HttpResponseBadRequest("Unknown format") elif simtype == "sa": # Percentage # 1. WT conditions obj = org.obj[:] dobj = org.design_obj[:] tobj = target_reactions[0]["name"] obj_r = org.get_reaction(obj[0][0]) target = org.get_reaction(tobj) target_flux = fba.flux[fba.reac_names.index(target.id)] design_result = [["x"], [obj[0][0]], [dobj[0][0]], ["Yield"]] dflux = list([x] for x in [1.0, 0.8, 0.6, 0.4, 0.2, 0.0]) # 2. Limit target reaction for i, limit in enumerate([1.0, 0.8, 0.6, 0.4, 0.2, 0.0]): # Limit to a % of the target flux target.constraint = (target.constraint[0], target_flux * limit) # Optimize limited growth org.obj = obj fba = org.fba() growth = fba.Z # Optimize production obj_r.constraint = (growth, growth) org.obj = dobj fba = org.fba() production = fba.Z # Reset production constraint obj_r.constraint = (0, None) design_result[0].append(str(int(limit * 100)) + "%") design_result[1].append(round(growth, 4)) design_result[2].append(round(production, 4)) design_result[3].append(round(growth * production, 4)) dflux[i].append({}) for reac, flux in zip(map(lambda x: x.name, fba.reacs), fba.flux): dflux[i][-1][reac] = flux dflux.append(target_flux) if output_format == "json": return HttpResponse(json.dumps({ "solution": fba.get_status(), "flux": dflux, "graph": design_result }), content_type="application/json") else: return HttpResponseBadRequest("Unknown format")
def simulate(request, pk): if not all(x in request.POST for x in ["changes", "objectives", "display", "auto_flux"]): return HttpResponseBadRequest("Request incomplete") output_format = request.POST.get("format", "json") dry_run = request.POST.get("dry_run", False) try: model = DesignModel.objects.get(user=UserProfile.get_profile(request.user), pk=pk) except ObjectDoesNotExist: return HttpResponseBadRequest("Bad Model") try: revision = request.POST["revision"] try: revision = Revision.objects.get(model=model, pk=revision) except ObjectDoesNotExist: return HttpResponseBadRequest("Bad Revision") except KeyError: revision = model.get_latest_revision() org = model_from_string(revision.content) try: changes = json.loads(request.POST["changes"]) objectives = json.loads(request.POST["objectives"]) display = json.loads(request.POST["display"]) auto_flux = json.loads(request.POST["auto_flux"]) except ValueError: return HttpResponseBadRequest("Invalid JSON data") try: auto_flux = bool(auto_flux) except ValueError: return HttpResponseBadRequest("Invalid data type") try: apply_commandlist(org, changes) org = model_from_string(revision.content) changes = compress_command_list(changes) apply_commandlist(org, changes) if not objectives: raise ValueError("No objective specified") org.objectives = [] for obj in objectives: if len(obj["name"]) > 0: obj_reac = org.get_reaction(obj["name"]) if obj_reac is None: raise ValueError("Objective not in model: " + obj["name"]) if obj_reac.disabled: return HttpResponseBadRequest("Objective disabled: " + obj_reac.name) org.objectives.append(JsonModel.Objective(**obj)) else: raise ValueError("No objective specified") except ValueError as e: return HttpResponseBadRequest("Model error: " + str(e)) display = filter(lambda x: not len(x) == 0, display) for item in display: if not org.has_reaction(item): return HttpResponseBadRequest("Unknown reaction in display list: " + item) org = org.to_model() try: fba = org.fba() except ValueError as e: return HttpResponseBadRequest("FBA error: " + str(e)) if dry_run: return HttpResponse( json.dumps({"solution": fba.get_status()}), content_type="application/json") full_g, nodeIDs = calc_reactions(org, fba) display = json.loads(request.POST["display"]) display = list(filter(lambda x: len(x) > 0 and org.has_reaction(x), display)) dflux = {} for reac, flux in zip(map(lambda x: x.name, fba.reacs), fba.flux): dflux[reac] = flux # Auto filter by FBA if auto_flux: if len(full_g.edges()) <= 30: full_eg = full_g else: full_eg = nx.ego_graph(full_g.reverse(), nodeIDs[org.obj[0][0]], radius=3, center=False, undirected=False) full_g.remove_edges_from(full_g.in_edges(nodeIDs[org.obj[0][0]]) + full_g.out_edges(nodeIDs[org.obj[0][0]])) all_edges = map(lambda x: full_eg.get_edge_data(*x)["object"].name, full_eg.edges()) # Get fluxes of "edges" flux = [] for reac in all_edges: flux.append([reac, dflux[reac]]) flux = sorted(flux, key=lambda x: -x[1]) display = list(map(lambda x: x[0], flux[:30])) else: full_g.remove_edges_from(full_g.in_edges(nodeIDs[org.obj[0][0]]) + full_g.out_edges(nodeIDs[org.obj[0][0]])) display.append(org.obj[0][0]) g = get_selected_reaction(json_graph.node_link_data(full_g), nodeIDs, display, org) graph = nx.to_agraph(g) graph.graph_attr.update(splines=True, overlap=False, rankdir="LR") graph.node_attr.update(style="filled", colorscheme="pastel19") outgraph = str(graph.to_string()) outgraph = pygraphviz.AGraph(outgraph) outgraph = outgraph.draw(format="svg", prog="dot") if output_format == "json": return HttpResponse(json.dumps( {"graph": outgraph.decode("utf-8"), "solution": fba.get_status(), "flux": dflux }), content_type="application/json" ) elif output_format == "png": import wand.image with wand.image.Image(blob=outgraph, format="svg") as image: png_image = image.make_blob("png") r = HttpResponse(png_image, content_type="image/png") r['Content-Disposition'] = 'attachment; filename={}.png'.format(model.filename) return r elif output_format == "svg": r = HttpResponse(outgraph.decode("utf-8"), content_type="image/svg+xml") r['Content-Disposition'] = 'attachment; filename={}.svg'.format(model.filename) return r elif output_format == "csv": s = StringIO() for reac, flux in zip(fba.reacs, fba.flux): s.write(reac.name) s.write("\t") s.write(str(flux)) s.write("\r\n") r = HttpResponse(s.getvalue(), content_type="text/csv") r['Content-Disposition'] = 'attachment; filename={}.csv'.format(model.filename) return r else: return HttpResponseBadRequest("Unknown format")