Пример #1
0
def history(request, pk):
    try:
        model = DesignModel.objects.get(user=UserProfile.get_profile(
            request.user),
                                        pk=pk)
        revisions = model.revisions.all()
    except ObjectDoesNotExist:
        return render_queryset_to_response_error(request,
                                                 error=404,
                                                 msg="Model not found")

    entries = []

    from itertools import groupby
    for k, v in groupby(revisions, key=lambda x: x.date.date()):
        v = list(v)[::-1]
        for vv in v:
            try:
                vv.changes = json.dumps(vv.changes["changes"])
            except KeyError:
                vv.changes = json.dumps({})

        entries.append([k, list(v)[::-1]])

    data = {"model": model, "revisions": entries}

    return render_queryset_to_response(request,
                                       template="cyanodesign/history.html",
                                       data=data)
Пример #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
Пример #3
0
def save_as(request, pk):
    if request.method == 'POST':
        form = SaveModelAsForm(request.POST, request.FILES)

        if form.is_valid():
            name = form.cleaned_data.get('saveas_name')
            summary = form.cleaned_data.get('saveas_summary')

            request.POST = request.POST.copy()
            request.POST["summary"] = summary
            save(request, pk)

            model = DesignModel.objects.get(user=UserProfile.get_profile(
                request.user),
                                            pk=pk)

            dm = DesignModel.objects.create(user=request.user.profile,
                                            name=name,
                                            filename=model.filename,
                                            content=model.content)

            # Repoint to new model
            rev = model.get_latest_revision()
            rev.model = dm
            rev.save()

            return {
                'success': True,
                'url': reverse("cyanodesign:design", kwargs={"pk": dm.pk})
            }
        else:
            form_html = render_crispy_form(form, context=request)
            return {'success': False, 'form_html': form_html}

    return BadRequest()
Пример #4
0
def design(request, pk):
    try:
        item = DesignModel.objects.get(user=UserProfile.get_profile(request.user), pk=pk)
        current = item.get_latest_revision()
    except ObjectDoesNotExist:
        return render_queryset_to_response_error(request, error=404, msg="Model not found")

    try:
        revision = request.GET["revision"]
        try:
            revision = Revision.objects.get(model=item, pk=revision)
        except ObjectDoesNotExist:
            return render_queryset_to_response_error(request, error=404, msg="Revision not found")
    except KeyError:
        revision = current

    data = {
        "pk": pk,
        "name": item.name,
        "revision": None if current.pk == revision.pk else revision,
        "save_form": SaveModelForm(None),
        "saveas_form": SaveModelAsForm(None)
    }

    return render_queryset_to_response(request, template="cyanodesign/design.html", data=data)
Пример #5
0
def design(request, pk):
    try:
        item = DesignModel.objects.get(user=UserProfile.get_profile(
            request.user),
                                       pk=pk)
        current = item.get_latest_revision()
    except ObjectDoesNotExist:
        return render_queryset_to_response_error(request,
                                                 error=404,
                                                 msg="Model not found")

    try:
        revision = request.GET["revision"]
        try:
            revision = Revision.objects.get(model=item, pk=revision)
        except ObjectDoesNotExist:
            return render_queryset_to_response_error(request,
                                                     error=404,
                                                     msg="Revision not found")
    except KeyError:
        revision = current

    data = {
        "pk": pk,
        "name": item.name,
        "revision": None if current.pk == revision.pk else revision,
        "save_form": SaveModelForm(None),
        "saveas_form": SaveModelAsForm(None)
    }

    return render_queryset_to_response(request,
                                       template="cyanodesign/design.html",
                                       data=data)
Пример #6
0
def save_as(request, pk):
    if request.method == 'POST':
        form = SaveModelAsForm(request.POST, request.FILES)

        if form.is_valid():
            name = form.cleaned_data.get('saveas_name')
            summary = form.cleaned_data.get('saveas_summary')

            request.POST = request.POST.copy()
            request.POST["summary"] = summary
            save(request, pk)
    
            model = DesignModel.objects.get(user=UserProfile.get_profile(request.user), pk=pk)

            dm = DesignModel.objects.create(
                user=request.user.profile,
                name=name,
                filename=model.filename,
                content=model.content
            )

            # Repoint to new model
            rev = model.get_latest_revision()
            rev.model = dm
            rev.save()

            return {'success': True, 'url': reverse("cyano-design-design", kwargs={"pk":dm.pk})}
        else:
            form_html = render_crispy_form(form, context=RequestContext(request))
            return {'success': False, 'form_html': form_html}

    return BadRequest()
Пример #7
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 = Metabolism(StringIO(content))

    ss = StringIO()

    if form == "sbml":
        org.write_sbml(ss)
    elif form == "bioopt":
        org.write_bioopt(ss)

    #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
Пример #8
0
def delete(request):
    pk = request.POST.get("id", 0)

    try:
        DesignModel.objects.get(user=UserProfile.get_profile(request.user), pk=pk).delete()
    except ObjectDoesNotExist:
        return BadRequest("Bad Model")

    return {}
Пример #9
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 {}
Пример #10
0
def delete(request):
    pk = request.POST.get("id", 0)

    try:
        DesignModel.objects.get(user=UserProfile.get_profile(request.user),
                                pk=pk).delete()
    except ObjectDoesNotExist:
        return BadRequest("Bad Model")

    return {}
Пример #11
0
def index(request):
    upload_form = UploadModelForm(None)

    templates = DesignTemplate.objects.values_list("pk", "name")
    template_form = ModelFromTemplateForm(choices=templates)

    models = DesignModel.objects.filter(user=UserProfile.get_profile(request.user))

    return render_queryset_to_response(
        request,
        template="cyanodesign/list.html",
        queryset=models,
        data={'upload_form': upload_form, "template_form": template_form}
    )
Пример #12
0
def index(request):
    upload_form = UploadModelForm(None)

    templates = DesignTemplate.objects.values_list("pk", "name")
    template_form = ModelFromTemplateForm(choices=templates)

    models = DesignModel.objects.filter(
        user=UserProfile.get_profile(request.user))

    return render_queryset_to_response(request,
                                       template="cyanodesign/list.html",
                                       queryset=models,
                                       data={
                                           'upload_form': upload_form,
                                           "template_form": template_form
                                       })
Пример #13
0
def get_reactions(request, pk):
    try:
        item = DesignModel.objects.get(user=UserProfile.get_profile(request.user), pk=pk)
    except ObjectDoesNotExist:
        return BadRequest("Bad Model")

    try:
        revision = request.GET["revision"]
        try:
            revision = Revision.objects.get(model=item, pk=revision)
        except ObjectDoesNotExist:
            return BadRequest("Bad Revision")
    except KeyError:
        revision = item.get_latest_revision()

    return revision.content
Пример #14
0
def get_reactions(request, pk):
    try:
        item = DesignModel.objects.get(user=UserProfile.get_profile(
            request.user),
                                       pk=pk)
    except ObjectDoesNotExist:
        return BadRequest("Bad Model")

    try:
        revision = request.GET["revision"]
        try:
            revision = Revision.objects.get(model=item, pk=revision)
        except ObjectDoesNotExist:
            return BadRequest("Bad Revision")
    except KeyError:
        revision = item.get_latest_revision()

    return JsonModel.from_sbml(revision.content).to_json()
Пример #15
0
def history(request, pk):
    try:
        model = DesignModel.objects.get(user=UserProfile.get_profile(request.user), pk=pk)
        revisions = model.revisions.all()
    except ObjectDoesNotExist:
        return render_queryset_to_response_error(request, error=404, msg="Model not found")

    entries = []

    from itertools import groupby
    for k,v in groupby(revisions, key=lambda x: x.date.date()):
        v = list(v)[::-1]
        for vv in v:
            try:
                vv.changes = json.dumps(vv.changes["changes"])
            except KeyError:
                vv.changes = json.dumps({})

        entries.append([k, list(v)[::-1]])

    data = {"model": model, "revisions": entries}

    return render_queryset_to_response(request, template="cyanodesign/history.html", data=data)
Пример #16
0
def upload(request, pk):
    data = {}

    if request.method == 'POST':
        if pk == "1":
            # Uploaded model
            form = UploadModelForm(request.POST, request.FILES)

            if form.is_valid():
                name = form.cleaned_data.get('name')

                #save to temporary file
                freq = request.FILES['file']
                filename = freq.name

                ss = StringIO()
                for chunk in freq.chunks():
                    try:
                        ss.write(chunk.decode("utf-8"))
                    except UnicodeDecodeError:
                        form.add_error("file",
                                       "File does not have UTF-8 encoding")
                        form_html = render_crispy_form(form, context=request)
                        return {'success': False, 'form_html': form_html}

                #try:
                ss.seek(0)
                model = Metabolism(ss, filename=freq.name)

                if len(model.enzymes) == 0 or len(model.mets) == 0:
                    raise ValueError("Model is empty")
                #except Exception as e:
                #    form.add_error("file", "Not a valid model: " + str(e))
                #    form_html = render_crispy_form(form, context=request)
                #    return {'success': False, 'form_html': form_html}

                dm = DesignModel.objects.create(user=request.user.profile,
                                                name=name,
                                                filename=filename,
                                                content=ss.getvalue())

                #try:
                #    jm = JsonModel.from_model(model).to_json()
                #except ValueError:
                #    return BadRequest(str(ValueError))

                sio = StringIO()
                model.write_sbml(fileout=sio)

                Revision(model=dm,
                         content=sio.getvalue(),
                         reason="Initial version").save()

                return {'success': True}
            else:
                form_html = render_crispy_form(form, context=request)
                return {'success': False, 'form_html': form_html}
        if pk == "2":
            # from template
            templates = DesignTemplate.objects.values_list("pk", "name")
            form = ModelFromTemplateForm(templates, request.POST,
                                         request.FILES)

            if form.is_valid():
                name = form.cleaned_data.get('name')
                choice = form.cleaned_data.get('choice')

                template = DesignTemplate.objects.get(pk=choice)

                dm = DesignModel.objects.create(user=UserProfile.get_profile(
                    request.user),
                                                name=name,
                                                filename=template.filename,
                                                content="")

                Revision(model=dm,
                         content=template.content,
                         reason="Initial version").save()

                return {'success': True}
            else:
                form_html = render_crispy_form(form, context=request)
                return {'success': False, 'form_html': form_html}

    return BadRequest()
Пример #17
0
def upload(request, pk):
    data = {}

    if request.method == 'POST':
        if pk == "1":
            # Uploaded model
            form = UploadModelForm(request.POST, request.FILES)

            if form.is_valid():
                name = form.cleaned_data.get('name')

                #save to temporary file
                freq = request.FILES['file']
                filename = freq.name

                ss = StringIO()
                for chunk in freq.chunks():
                    try:
                        ss.write(chunk.decode("utf-8"))
                    except UnicodeDecodeError:
                        form.add_error("file", "File does not have UTF-8 encoding")
                        form_html = render_crispy_form(form, context=request)
                        return {'success': False, 'form_html': form_html}

                try:
                    model = Metabolism(ss)
                except:
                    form.add_error("file", "Not a valid model")
                    form_html = render_crispy_form(form, context=request)
                    return {'success': False, 'form_html': form_html}

                dm = DesignModel.objects.create(
                    user=request.user.profile,
                    name=name,
                    filename=filename,
                    content=ss.getvalue()
                )

                try:
                    jm = JsonModel.from_model(model).to_json()
                except ValueError:
                    return BadRequest(str(ValueError))

                Revision(
                    model=dm,
                    content=jm,
                    reason="Initial version"
                ).save()

                return {'success': True}
            else:
                form_html = render_crispy_form(form, context=request)
                return {'success': False, 'form_html': form_html}
        if pk == "2":
            # from template
            templates = DesignTemplate.objects.values_list("pk", "name")
            form = ModelFromTemplateForm(templates, request.POST, request.FILES)

            if form.is_valid():
                name = form.cleaned_data.get('name')
                choice = form.cleaned_data.get('choice')

                template = DesignTemplate.objects.get(pk=choice)

                dm = DesignModel.objects.create(
                    user=UserProfile.get_profile(request.user),
                    name=name,
                    filename=template.filename,
                    content=""
                )

                Revision(
                    model=dm,
                    content=template.content,
                    reason="Initial version"
                ).save()

                return {'success': True}
            else:
                form_html = render_crispy_form(form, context=request)
                return {'success': False, 'form_html': form_html}

    return BadRequest()
Пример #18
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 {}
Пример #19
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")
Пример #20
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")