Ejemplo n.º 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 {}
Ejemplo n.º 2
0
def export(request, pk):
    form = request.GET.get("format", "bioopt")

    if form not in ["bioopt", "sbml"]:
        return HttpResponseBadRequest("Bad format")

    try:
        model = DesignModel.objects.get(user=UserProfile.get_profile(request.user), pk=pk)
        content = model.get_latest_revision().content
    except ObjectDoesNotExist:
        return HttpResponseBadRequest("Bad Model")

    org = model_from_string(content)

    ss = StringIO()

    org.to_model().dump(fileout=ss, filetype="opt" if form == "bioopt" else "sbml")

    response = HttpResponse(
        ss.getvalue(),
        content_type="application/x-bioopt" if form=="bioopt" else "application/sbml+xml"
    )

    ss.close()

    response['Content-Disposition'] = "attachment; filename=" + model.filename

    return response
Ejemplo n.º 3
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")