forked from enviPath/enviPy
Merge remote-tracking branch 'origin/develop' into feature/frontend_update
This commit is contained in:
268
epdb/views.py
268
epdb/views.py
@ -46,6 +46,8 @@ from .models import (
|
||||
Edge,
|
||||
ExternalDatabase,
|
||||
ExternalIdentifier,
|
||||
EnzymeLink,
|
||||
JobLog,
|
||||
)
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
@ -756,8 +758,8 @@ def package_models(request, package_uuid):
|
||||
context["unreviewed_objects"] = unreviewed_model_qs
|
||||
|
||||
context["model_types"] = {
|
||||
"ML Relative Reasoning": "ml-relative-reasoning",
|
||||
"Rule Based Relative Reasoning": "rule-based-relative-reasoning",
|
||||
"ML Relative Reasoning": "mlrr",
|
||||
"Rule Based Relative Reasoning": "rbrr",
|
||||
}
|
||||
|
||||
if s.FLAGS.get("ENVIFORMER", False):
|
||||
@ -777,69 +779,67 @@ def package_models(request, package_uuid):
|
||||
|
||||
model_type = request.POST.get("model-type")
|
||||
|
||||
# Generic fields for ML and Rule Based
|
||||
rule_packages = request.POST.getlist("model-rule-packages")
|
||||
data_packages = request.POST.getlist("model-data-packages")
|
||||
|
||||
# Generic params
|
||||
params = {
|
||||
"package": current_package,
|
||||
"name": name,
|
||||
"description": description,
|
||||
"data_packages": [
|
||||
PackageManager.get_package_by_url(current_user, p) for p in data_packages
|
||||
],
|
||||
}
|
||||
|
||||
if model_type == "enviformer":
|
||||
threshold = float(request.POST.get(f"{model_type}-threshold", 0.5))
|
||||
threshold = float(request.POST.get("model-threshold", 0.5))
|
||||
params["threshold"] = threshold
|
||||
|
||||
mod = EnviFormer.create(current_package, name, description, threshold)
|
||||
mod = EnviFormer.create(**params)
|
||||
elif model_type == "mlrr":
|
||||
# ML Specific
|
||||
threshold = float(request.POST.get("model-threshold", 0.5))
|
||||
# TODO handle additional fingerprinter
|
||||
# fingerprinter = request.POST.get("model-fingerprinter")
|
||||
|
||||
elif model_type == "ml-relative-reasoning" or model_type == "rule-based-relative-reasoning":
|
||||
# Generic fields for ML and Rule Based
|
||||
rule_packages = request.POST.getlist("package-based-relative-reasoning-rule-packages")
|
||||
data_packages = request.POST.getlist("package-based-relative-reasoning-data-packages")
|
||||
eval_packages = request.POST.getlist(
|
||||
"package-based-relative-reasoning-evaluation-packages", []
|
||||
)
|
||||
params["rule_packages"] = [
|
||||
PackageManager.get_package_by_url(current_user, p) for p in rule_packages
|
||||
]
|
||||
|
||||
# Generic params
|
||||
params = {
|
||||
"package": current_package,
|
||||
"name": name,
|
||||
"description": description,
|
||||
"rule_packages": [
|
||||
PackageManager.get_package_by_url(current_user, p) for p in rule_packages
|
||||
],
|
||||
"data_packages": [
|
||||
PackageManager.get_package_by_url(current_user, p) for p in data_packages
|
||||
],
|
||||
"eval_packages": [
|
||||
PackageManager.get_package_by_url(current_user, p) for p in eval_packages
|
||||
],
|
||||
}
|
||||
# App Domain related parameters
|
||||
build_ad = request.POST.get("build-app-domain", False) == "on"
|
||||
num_neighbors = request.POST.get("num-neighbors", 5)
|
||||
reliability_threshold = request.POST.get("reliability-threshold", 0.5)
|
||||
local_compatibility_threshold = request.POST.get("local-compatibility-threshold", 0.5)
|
||||
|
||||
if model_type == "ml-relative-reasoning":
|
||||
# ML Specific
|
||||
threshold = float(request.POST.get(f"{model_type}-threshold", 0.5))
|
||||
# TODO handle additional fingerprinter
|
||||
# fingerprinter = request.POST.get(f"{model_type}-fingerprinter")
|
||||
params["threshold"] = threshold
|
||||
# params['fingerprinter'] = fingerprinter
|
||||
params["build_app_domain"] = build_ad
|
||||
params["app_domain_num_neighbours"] = num_neighbors
|
||||
params["app_domain_reliability_threshold"] = reliability_threshold
|
||||
params["app_domain_local_compatibility_threshold"] = local_compatibility_threshold
|
||||
|
||||
# App Domain related parameters
|
||||
build_ad = request.POST.get("build-app-domain", False) == "on"
|
||||
num_neighbors = request.POST.get("num-neighbors", 5)
|
||||
reliability_threshold = request.POST.get("reliability-threshold", 0.5)
|
||||
local_compatibility_threshold = request.POST.get(
|
||||
"local-compatibility-threshold", 0.5
|
||||
)
|
||||
mod = MLRelativeReasoning.create(**params)
|
||||
elif model_type == "rbrr":
|
||||
params["rule_packages"] = [
|
||||
PackageManager.get_package_by_url(current_user, p) for p in rule_packages
|
||||
]
|
||||
|
||||
params["threshold"] = threshold
|
||||
# params['fingerprinter'] = fingerprinter
|
||||
params["build_app_domain"] = build_ad
|
||||
params["app_domain_num_neighbours"] = num_neighbors
|
||||
params["app_domain_reliability_threshold"] = reliability_threshold
|
||||
params["app_domain_local_compatibility_threshold"] = local_compatibility_threshold
|
||||
|
||||
mod = MLRelativeReasoning.create(**params)
|
||||
else:
|
||||
mod = RuleBasedRelativeReasoning.create(**params)
|
||||
|
||||
from .tasks import build_model
|
||||
|
||||
build_model.delay(mod.pk)
|
||||
mod = RuleBasedRelativeReasoning.create(**params)
|
||||
elif s.FLAGS.get("PLUGINS", False) and model_type in s.CLASSIFIER_PLUGINS.values():
|
||||
pass
|
||||
else:
|
||||
return error(
|
||||
request, "Invalid model type.", f'Model type "{model_type}" is not supported."'
|
||||
)
|
||||
return redirect(mod.url)
|
||||
|
||||
from .tasks import dispatch, build_model
|
||||
|
||||
dispatch(current_user, build_model, mod.pk)
|
||||
|
||||
return redirect(mod.url)
|
||||
else:
|
||||
return HttpResponseNotAllowed(["GET", "POST"])
|
||||
|
||||
@ -867,6 +867,10 @@ def package_model(request, package_uuid, model_uuid):
|
||||
return JsonResponse({"error": f'"{smiles}" is not a valid SMILES'}, status=400)
|
||||
|
||||
if classify:
|
||||
from epdb.tasks import dispatch_eager, predict_simple
|
||||
|
||||
res = dispatch_eager(current_user, predict_simple, current_model.pk, stand_smiles)
|
||||
|
||||
pred_res = current_model.predict(stand_smiles)
|
||||
res = []
|
||||
|
||||
@ -911,9 +915,25 @@ def package_model(request, package_uuid, model_uuid):
|
||||
current_model.delete()
|
||||
return redirect(current_package.url + "/model")
|
||||
elif hidden == "evaluate":
|
||||
from .tasks import evaluate_model
|
||||
from .tasks import dispatch, evaluate_model
|
||||
|
||||
eval_type = request.POST.get("model-evaluation-type")
|
||||
|
||||
if eval_type not in ["sg", "mg"]:
|
||||
return error(
|
||||
request,
|
||||
"Invalid evaluation type",
|
||||
f'Evaluation type "{eval_type}" is not supported. Only "sg" and "mg" are supported.',
|
||||
)
|
||||
|
||||
multigen = eval_type == "mg"
|
||||
|
||||
eval_packages = request.POST.getlist("model-evaluation-packages")
|
||||
eval_package_ids = [
|
||||
PackageManager.get_package_by_url(current_user, p).id for p in eval_packages
|
||||
]
|
||||
dispatch(current_user, evaluate_model, current_model.pk, multigen, eval_package_ids)
|
||||
|
||||
evaluate_model.delay(current_model.pk)
|
||||
return redirect(current_model.url)
|
||||
else:
|
||||
return HttpResponseBadRequest()
|
||||
@ -1253,7 +1273,16 @@ def package_compound_structures(request, package_uuid, compound_uuid):
|
||||
structure_smiles = request.POST.get("structure-smiles")
|
||||
structure_description = request.POST.get("structure-description")
|
||||
|
||||
cs = current_compound.add_structure(structure_smiles, structure_name, structure_description)
|
||||
try:
|
||||
cs = current_compound.add_structure(
|
||||
structure_smiles, structure_name, structure_description
|
||||
)
|
||||
except ValueError:
|
||||
return error(
|
||||
request,
|
||||
"Adding structure failed!",
|
||||
"The structure could not be added as normalized structures don't match!",
|
||||
)
|
||||
|
||||
return redirect(cs.url)
|
||||
|
||||
@ -1456,12 +1485,20 @@ def package_rule(request, package_uuid, rule_uuid):
|
||||
logger.info(
|
||||
f"Rule {current_rule.uuid} returned multiple product sets on {smiles}, picking the first one."
|
||||
)
|
||||
|
||||
smirks = f"{stand_smiles}>>{'.'.join(sorted(res[0]))}"
|
||||
# Some Rules are touching unrelated areas which might result in ~ indicating
|
||||
# any bond (-, =, #). For drawing we need a concrete bond. -> use single bond
|
||||
product_smiles = [x.replace("~", "-") for x in res[0]]
|
||||
smirks = f"{stand_smiles}>>{'.'.join(sorted(product_smiles))}"
|
||||
# Usually the functional groups are a mapping of fg -> count
|
||||
# As we are doing it on the fly here fake a high count to ensure that its properly highlighted
|
||||
educt_functional_groups = {x: 1000 for x in current_rule.reactants_smarts}
|
||||
product_functional_groups = {x: 1000 for x in current_rule.products_smarts}
|
||||
|
||||
if isinstance(current_rule, SimpleAmbitRule):
|
||||
educt_functional_groups = {current_rule.reactants_smarts: 1000}
|
||||
product_functional_groups = {current_rule.products_smarts: 1000}
|
||||
else:
|
||||
educt_functional_groups = {x: 1000 for x in current_rule.reactants_smarts}
|
||||
product_functional_groups = {x: 1000 for x in current_rule.products_smarts}
|
||||
|
||||
return HttpResponse(
|
||||
IndigoUtils.smirks_to_svg(
|
||||
smirks,
|
||||
@ -1531,6 +1568,32 @@ def package_rule(request, package_uuid, rule_uuid):
|
||||
return HttpResponseNotAllowed(["GET", "POST"])
|
||||
|
||||
|
||||
@package_permission_required()
|
||||
def package_rule_enzymelink(request, package_uuid, rule_uuid, enzymelink_uuid):
|
||||
current_user = _anonymous_or_real(request)
|
||||
current_package = PackageManager.get_package_by_id(current_user, package_uuid)
|
||||
current_rule = Rule.objects.get(package=current_package, uuid=rule_uuid)
|
||||
current_enzymelink = EnzymeLink.objects.get(rule=current_rule, uuid=enzymelink_uuid)
|
||||
|
||||
if request.method == "GET":
|
||||
context = get_base_context(request)
|
||||
|
||||
context["title"] = f"enviPath - {current_package.name} - {current_rule.name}"
|
||||
|
||||
context["meta"]["current_package"] = current_package
|
||||
context["object_type"] = "enzyme"
|
||||
context["breadcrumbs"] = breadcrumbs(
|
||||
current_package, "rule", current_rule, "enzymelink", current_enzymelink
|
||||
)
|
||||
|
||||
context["enzymelink"] = current_enzymelink
|
||||
context["current_object"] = current_enzymelink
|
||||
|
||||
return render(request, "objects/enzymelink.html", context)
|
||||
|
||||
return HttpResponseNotAllowed(["GET"])
|
||||
|
||||
|
||||
@package_permission_required()
|
||||
def package_reactions(request, package_uuid):
|
||||
current_user = _anonymous_or_real(request)
|
||||
@ -1768,9 +1831,9 @@ def package_pathways(request, package_uuid):
|
||||
pw.setting = prediction_setting
|
||||
pw.save()
|
||||
|
||||
from .tasks import predict
|
||||
from .tasks import dispatch, predict
|
||||
|
||||
predict.delay(pw.pk, prediction_setting.pk, limit=limit)
|
||||
dispatch(current_user, predict, pw.pk, prediction_setting.pk, limit=limit)
|
||||
|
||||
return redirect(pw.url)
|
||||
|
||||
@ -1889,10 +1952,16 @@ def package_pathway(request, package_uuid, pathway_uuid):
|
||||
if node_url:
|
||||
n = current_pathway.get_node(node_url)
|
||||
|
||||
from .tasks import predict
|
||||
from .tasks import dispatch, predict
|
||||
|
||||
dispatch(
|
||||
current_user,
|
||||
predict,
|
||||
current_pathway.pk,
|
||||
current_pathway.setting.pk,
|
||||
node_pk=n.pk,
|
||||
)
|
||||
|
||||
# Dont delay?
|
||||
predict(current_pathway.pk, current_pathway.setting.pk, node_pk=n.pk)
|
||||
return JsonResponse({"success": current_pathway.url})
|
||||
|
||||
return HttpResponseBadRequest()
|
||||
@ -1969,9 +2038,42 @@ def package_pathway_node(request, package_uuid, pathway_uuid, node_uuid):
|
||||
|
||||
if request.method == "GET":
|
||||
is_image_request = request.GET.get("image")
|
||||
is_highlight_request = request.GET.get("highlight", False)
|
||||
is_highlight_reactivity = request.GET.get("highlightReactivity", False)
|
||||
if is_image_request:
|
||||
if is_image_request == "svg":
|
||||
svg_data = current_node.as_svg
|
||||
# TODO optimize this chain
|
||||
if is_highlight_request:
|
||||
# User functional groups covered by the model training data
|
||||
fgs = {}
|
||||
if current_pathway.setting:
|
||||
if current_pathway.setting.model:
|
||||
if current_pathway.setting.model.app_domain:
|
||||
fgs = current_pathway.setting.model.app_domain.functional_groups
|
||||
|
||||
svg_data = IndigoUtils.mol_to_svg(
|
||||
current_node.default_node_label.smiles, functional_groups=fgs
|
||||
)
|
||||
elif is_highlight_reactivity:
|
||||
# Use reactant smarts to show all reaction sites
|
||||
# set a high count to obtain a strong color
|
||||
ad_data = current_node.get_app_domain_assessment_data()
|
||||
fgs = {}
|
||||
for t in ad_data.get("assessment", {}).get("transformations", []):
|
||||
r = Rule.objects.get(url=t["rule"]["url"])
|
||||
|
||||
if isinstance(r, SimpleAmbitRule):
|
||||
fgs[r.reactants_smarts] = 1000
|
||||
else:
|
||||
for sr in r.srs:
|
||||
fgs[sr.reactants_smarts] = 1000
|
||||
|
||||
svg_data = IndigoUtils.mol_to_svg(
|
||||
current_node.default_node_label.smiles, functional_groups=fgs
|
||||
)
|
||||
else:
|
||||
svg_data = current_node.as_svg
|
||||
|
||||
return HttpResponse(svg_data, content_type="image/svg+xml")
|
||||
|
||||
context = get_base_context(request)
|
||||
@ -2631,6 +2733,24 @@ def setting(request, setting_uuid):
|
||||
pass
|
||||
|
||||
|
||||
def jobs(request):
|
||||
current_user = _anonymous_or_real(request)
|
||||
context = get_base_context(request)
|
||||
|
||||
if request.method == "GET":
|
||||
context["object_type"] = "joblog"
|
||||
context["breadcrumbs"] = [
|
||||
{"Home": s.SERVER_URL},
|
||||
{"Jobs": s.SERVER_URL + "/jobs"},
|
||||
]
|
||||
if current_user.is_superuser:
|
||||
context["jobs"] = JobLog.objects.all().order_by("-created")
|
||||
else:
|
||||
context["jobs"] = JobLog.objects.filter(user=current_user).order_by("-created")
|
||||
|
||||
return render(request, "collections/joblog.html", context)
|
||||
|
||||
|
||||
###########
|
||||
# KETCHER #
|
||||
###########
|
||||
@ -2705,49 +2825,49 @@ def userinfo(request):
|
||||
|
||||
|
||||
# Static Pages
|
||||
def terms_of_use(request):
|
||||
def static_terms_of_use(request):
|
||||
context = get_base_context(request)
|
||||
context["title"] = "enviPath - Terms of Use"
|
||||
return render(request, "static/terms_of_use.html", context)
|
||||
|
||||
|
||||
def privacy_policy(request):
|
||||
def static_privacy_policy(request):
|
||||
context = get_base_context(request)
|
||||
context["title"] = "enviPath - Privacy Policy"
|
||||
return render(request, "static/privacy_policy.html", context)
|
||||
|
||||
|
||||
def cookie_policy(request):
|
||||
def static_cookie_policy(request):
|
||||
context = get_base_context(request)
|
||||
context["title"] = "enviPath - Cookie Policy"
|
||||
return render(request, "static/cookie_policy.html", context)
|
||||
|
||||
|
||||
def about_us(request):
|
||||
def static_about_us(request):
|
||||
context = get_base_context(request)
|
||||
context["title"] = "enviPath - About Us"
|
||||
return render(request, "static/about_us.html", context)
|
||||
|
||||
|
||||
def contact_support(request):
|
||||
def static_contact_support(request):
|
||||
context = get_base_context(request)
|
||||
context["title"] = "enviPath - Contact & Support"
|
||||
return render(request, "static/contact.html", context)
|
||||
|
||||
|
||||
def jobs(request):
|
||||
def static_jobs(request):
|
||||
context = get_base_context(request)
|
||||
context["title"] = "enviPath - Jobs & Careers"
|
||||
return render(request, "static/jobs.html", context)
|
||||
|
||||
|
||||
def cite(request):
|
||||
def static_cite(request):
|
||||
context = get_base_context(request)
|
||||
context["title"] = "enviPath - How to Cite"
|
||||
return render(request, "static/cite.html", context)
|
||||
|
||||
|
||||
def legal(request):
|
||||
def static_legal(request):
|
||||
context = get_base_context(request)
|
||||
context["title"] = "enviPath - Legal Information"
|
||||
return render(request, "static/legal.html", context)
|
||||
|
||||
Reference in New Issue
Block a user