Example #1
0
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 {}
Example #2
0
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 {}
Example #3
0
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")
Example #4
0
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")