reintroduces envipytags

This commit is contained in:
Tim Lorsbach
2025-11-11 12:47:24 +01:00
parent 34d3b75c6f
commit 34d5318534
2 changed files with 401 additions and 276 deletions

View File

@ -1,5 +1,6 @@
{% extends "framework.html" %} {% extends "framework.html" %}
{% load static %} {% load static %}
{% load envipytags %}
{% block content %} {% block content %}
{% block action_modals %} {% block action_modals %}
@ -12,18 +13,34 @@
<!-- Include required libs --> <!-- Include required libs -->
<script src="https://d3js.org/d3.v5.min.js"></script> <script src="https://d3js.org/d3.v5.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/c3@0.7.20/c3.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/c3@0.7.20/c3.min.js"></script>
<link href="https://cdn.jsdelivr.net/npm/c3@0.7.20/c3.min.css" rel="stylesheet"> <link
href="https://cdn.jsdelivr.net/npm/c3@0.7.20/c3.min.css"
rel="stylesheet"
/>
<div class="panel-group" id="model-detail"> <div class="panel-group" id="model-detail">
<div class="panel panel-default"> <div class="panel panel-default">
<div class="panel-heading" id="headingPanel" style="font-size:2rem;height: 46px"> <div
class="panel-heading"
id="headingPanel"
style="font-size:2rem;height: 46px"
>
{{ model.name|safe }} {{ model.name|safe }}
<div id="actionsButton" <div
id="actionsButton"
style="float: right;font-weight: normal;font-size: medium;position: relative; top: 50%; transform: translateY(-50%);z-index:100;display: none;" style="float: right;font-weight: normal;font-size: medium;position: relative; top: 50%; transform: translateY(-50%);z-index:100;display: none;"
class="dropdown"><a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" class="dropdown"
aria-haspopup="true" aria-expanded="false"><span >
class="glyphicon glyphicon-wrench"></span> Actions <span class="caret"></span><span <a
style="padding-right:1em"></span></a> href="#"
class="dropdown-toggle"
data-toggle="dropdown"
role="button"
aria-haspopup="true"
aria-expanded="false"
><span class="glyphicon glyphicon-wrench"></span> Actions
<span class="caret"></span><span style="padding-right:1em"></span
></a>
<ul id="actionsList" class="dropdown-menu"> <ul id="actionsList" class="dropdown-menu">
{% block actions %} {% block actions %}
{% include "actions/objects/model.html" %} {% include "actions/objects/model.html" %}
@ -36,77 +53,131 @@
</div> </div>
{% if model|classname == 'MLRelativeReasoning' or model|classname == 'RuleBasedRelativeReasoning' %} {% if model|classname == 'MLRelativeReasoning' or model|classname == 'RuleBasedRelativeReasoning' %}
<!-- Rule Packages --> <!-- Rule Packages -->
<div class="panel panel-default panel-heading list-group-item" style="background-color:silver"> <div
class="panel panel-default panel-heading list-group-item"
style="background-color:silver"
>
<h4 class="panel-title"> <h4 class="panel-title">
<a id="rule-package-link" data-toggle="collapse" data-parent="#model-detail" <a
href="#rule-package">Rule Packages</a> id="rule-package-link"
data-toggle="collapse"
data-parent="#model-detail"
href="#rule-package"
>Rule Packages</a
>
</h4> </h4>
</div> </div>
<div id="rule-package" class="panel-collapse collapse in"> <div id="rule-package" class="panel-collapse collapse in">
<div class="panel-body list-group-item"> <div class="panel-body list-group-item">
{% for p in model.rule_packages.all %} {% for p in model.rule_packages.all %}
<a class="list-group-item" href="{{ p.url }}">{{ p.name|safe }}</a> <a class="list-group-item" href="{{ p.url }}"
>{{ p.name|safe }}</a
>
{% endfor %} {% endfor %}
</div> </div>
</div> </div>
<!-- Reaction Packages --> <!-- Reaction Packages -->
<div class="panel panel-default panel-heading list-group-item" style="background-color:silver"> <div
class="panel panel-default panel-heading list-group-item"
style="background-color:silver"
>
<h4 class="panel-title"> <h4 class="panel-title">
<a id="reaction-package-link" data-toggle="collapse" data-parent="#model-detail" <a
href="#reaction-package">Rule Packages</a> id="reaction-package-link"
data-toggle="collapse"
data-parent="#model-detail"
href="#reaction-package"
>Rule Packages</a
>
</h4> </h4>
</div> </div>
<div id="reaction-package" class="panel-collapse collapse in"> <div id="reaction-package" class="panel-collapse collapse in">
<div class="panel-body list-group-item"> <div class="panel-body list-group-item">
{% for p in model.data_packages.all %} {% for p in model.data_packages.all %}
<a class="list-group-item" href="{{ p.url }}">{{ p.name|safe }}</a> <a class="list-group-item" href="{{ p.url }}"
>{{ p.name|safe }}</a
>
{% endfor %} {% endfor %}
</div> </div>
</div> </div>
{% if model.eval_packages.all|length > 0 %} {% if model.eval_packages.all|length > 0 %}
<!-- Eval Packages --> <!-- Eval Packages -->
<div class="panel panel-default panel-heading list-group-item" style="background-color:silver"> <div
class="panel panel-default panel-heading list-group-item"
style="background-color:silver"
>
<h4 class="panel-title"> <h4 class="panel-title">
<a id="eval-package-link" data-toggle="collapse" data-parent="#model-detail" <a
href="#eval-package">Rule Packages</a> id="eval-package-link"
data-toggle="collapse"
data-parent="#model-detail"
href="#eval-package"
>Rule Packages</a
>
</h4> </h4>
</div> </div>
<div id="eval-package" class="panel-collapse collapse in"> <div id="eval-package" class="panel-collapse collapse in">
<div class="panel-body list-group-item"> <div class="panel-body list-group-item">
{% for p in model.eval_packages.all %} {% for p in model.eval_packages.all %}
<a class="list-group-item" href="{{ p.url }}">{{ p.name|safe }}</a> <a class="list-group-item" href="{{ p.url }}"
>{{ p.name|safe }}</a
>
{% endfor %} {% endfor %}
</div> </div>
</div> </div>
{% endif %} {% endif %}
<!-- Model Status --> <!-- Model Status -->
<div class="panel panel-default panel-heading list-group-item" style="background-color:silver"> <div
class="panel panel-default panel-heading list-group-item"
style="background-color:silver"
>
<h4 class="panel-title"> <h4 class="panel-title">
<a id="model-status-link" data-toggle="collapse" data-parent="#model-detail" <a
href="#model-status">Model Status</a> id="model-status-link"
data-toggle="collapse"
data-parent="#model-detail"
href="#model-status"
>Model Status</a
>
</h4> </h4>
</div> </div>
<div id="model-status" class="panel-collapse collapse in"> <div id="model-status" class="panel-collapse collapse in">
<div class="panel-body list-group-item"> <div class="panel-body list-group-item">{{ model.status }}</div>
{{ model.status }}
</div>
</div> </div>
{% endif %} {% endif %}
{% if model.ready_for_prediction %} {% if model.ready_for_prediction %}
<!-- Predict Panel --> <!-- Predict Panel -->
<div class="panel panel-default panel-heading list-group-item" style="background-color:silver"> <div
class="panel panel-default panel-heading list-group-item"
style="background-color:silver"
>
<h4 class="panel-title"> <h4 class="panel-title">
<a id="predict-smiles-link" data-toggle="collapse" data-parent="#model-detail" <a
href="#predict-smiles">Predict</a> id="predict-smiles-link"
data-toggle="collapse"
data-parent="#model-detail"
href="#predict-smiles"
>Predict</a
>
</h4> </h4>
</div> </div>
<div id="predict-smiles" class="panel-collapse collapse in"> <div id="predict-smiles" class="panel-collapse collapse in">
<div class="panel-body list-group-item"> <div class="panel-body list-group-item">
<div class="input-group"> <div class="input-group">
<input id="smiles-to-predict" type="text" class="form-control" <input
placeholder="CCN(CC)C(=O)C1=CC(=CC=C1)C"> id="smiles-to-predict"
type="text"
class="form-control"
placeholder="CCN(CC)C(=O)C1=CC(=CC=C1)C"
/>
<span class="input-group-btn"> <span class="input-group-btn">
<button class="btn btn-default" type="submit" id="predict-button">Predict!</button> <button
class="btn btn-default"
type="submit"
id="predict-button"
>
Predict!
</button>
</span> </span>
</div> </div>
<div id="predictLoading"></div> <div id="predictLoading"></div>
@ -118,18 +189,37 @@
{% if model.ready_for_prediction and model.app_domain %} {% if model.ready_for_prediction and model.app_domain %}
<!-- App Domain --> <!-- App Domain -->
<div class="panel panel-default panel-heading list-group-item" style="background-color:silver"> <div
class="panel panel-default panel-heading list-group-item"
style="background-color:silver"
>
<h4 class="panel-title"> <h4 class="panel-title">
<a id="app-domain-assessment-link" data-toggle="collapse" data-parent="#model-detail" <a
href="#app-domain-assessment">Applicability Domain Assessment</a> id="app-domain-assessment-link"
data-toggle="collapse"
data-parent="#model-detail"
href="#app-domain-assessment"
>Applicability Domain Assessment</a
>
</h4> </h4>
</div> </div>
<div id="app-domain-assessment" class="panel-collapse collapse in"> <div id="app-domain-assessment" class="panel-collapse collapse in">
<div class="panel-body list-group-item"> <div class="panel-body list-group-item">
<div class="input-group"> <div class="input-group">
<input id="smiles-to-assess" type="text" class="form-control" placeholder="CCN(CC)C(=O)C1=CC(=CC=C1)C"> <input
id="smiles-to-assess"
type="text"
class="form-control"
placeholder="CCN(CC)C(=O)C1=CC(=CC=C1)C"
/>
<span class="input-group-btn"> <span class="input-group-btn">
<button class="btn btn-default" type="submit" id="assess-button">Assess!</button> <button
class="btn btn-default"
type="submit"
id="assess-button"
>
Assess!
</button>
</span> </span>
</div> </div>
<div id="appDomainLoading"></div> <div id="appDomainLoading"></div>
@ -141,23 +231,34 @@
{% if model.model_status == 'FINISHED' %} {% if model.model_status == 'FINISHED' %}
<!-- Single Gen Curve Panel --> <!-- Single Gen Curve Panel -->
<div class="panel panel-default panel-heading list-group-item" style="background-color:silver"> <div
class="panel panel-default panel-heading list-group-item"
style="background-color:silver"
>
<h4 class="panel-title"> <h4 class="panel-title">
<a id="sg-curve-link" data-toggle="collapse" data-parent="#model-detail" <a
href="#sg-curve">Precision Recall Curve</a> id="sg-curve-link"
data-toggle="collapse"
data-parent="#model-detail"
href="#sg-curve"
>Precision Recall Curve</a
>
</h4> </h4>
</div> </div>
<div id="sg-curve" class="panel-collapse collapse in"> <div id="sg-curve" class="panel-collapse collapse in">
<div class="panel-body list-group-item"> <div class="panel-body list-group-item">
<!-- Center container contents --> <!-- Center container contents -->
<div class="container" style="display: flex;justify-content: center;"> <div
class="container"
style="display: flex;justify-content: center;"
>
<div id="sg-curve-plotdiv" class="chart"> <div id="sg-curve-plotdiv" class="chart">
<div id="sg-chart"></div> <div id="sg-chart"></div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
{# prettier-ignore-start #}
<script> <script>
$(function () { $(function () {
if (!($('#sg-chart').length > 0)) { if (!($('#sg-chart').length > 0)) {
@ -264,44 +365,61 @@
}); });
}); });
</script> </script>
{# prettier-ignore-end #}
<!-- End Single Gen Curve Panel --> <!-- End Single Gen Curve Panel -->
{% endif %} {% endif %}
</div> </div>
</div> </div>
<script> <script>
function handlePredictionResponse(data) { function handlePredictionResponse(data) {
res = "<table class='table table-striped'>" res = "<table class='table table-striped'>";
res += "<thead>" res += "<thead>";
res += "<th scope='col'>#</th>" res += "<th scope='col'>#</th>";
columns = ['products', 'image', 'probability', 'btrule'] columns = ["products", "image", "probability", "btrule"];
for (col in columns) { for (col in columns) {
res += "<th scope='col'>" + columns[col] + "</th>" res += "<th scope='col'>" + columns[col] + "</th>";
} }
res += "</thead>" res += "</thead>";
res += "<tbody>" res += "<tbody>";
var cnt = 1; var cnt = 1;
for (transformation in data) { for (transformation in data) {
res += "<tr>" res += "<tr>";
res += "<th scope='row'>" + cnt + "</th>" res += "<th scope='row'>" + cnt + "</th>";
res += "<th scope='row'>" + data[transformation]['products'][0].join(', ') + "</th>" res +=
res += "<th scope='row'>" + "<img width='400' src='{% url 'depict' %}?smiles=" + encodeURIComponent(data[transformation]['products'][0].join('.')) + "'></th>" "<th scope='row'>" +
res += "<th scope='row'>" + data[transformation]['probability'].toFixed(3) + "</th>" data[transformation]["products"][0].join(", ") +
if (data[transformation]['btrule'] != null) { "</th>";
res += "<th scope='row'>" + "<a href='" + data[transformation]['btrule']['url'] + "'>" + data[transformation]['btrule']['name'] + "</a>" + "</th>" res +=
"<th scope='row'>" +
"<img width='400' src='{% url 'depict' %}?smiles=" +
encodeURIComponent(data[transformation]["products"][0].join(".")) +
"'></th>";
res +=
"<th scope='row'>" +
data[transformation]["probability"].toFixed(3) +
"</th>";
if (data[transformation]["btrule"] != null) {
res +=
"<th scope='row'>" +
"<a href='" +
data[transformation]["btrule"]["url"] +
"'>" +
data[transformation]["btrule"]["name"] +
"</a>" +
"</th>";
} else { } else {
res += "<th scope='row'>N/A</th>" res += "<th scope='row'>N/A</th>";
} }
res += "</tr>" res += "</tr>";
cnt += 1; cnt += 1;
} }
res += "</tbody>" res += "</tbody>";
res += "</table>" res += "</table>";
$("#predictResultTable").append(res); $("#predictResultTable").append(res);
} }
@ -310,37 +428,40 @@
$("#" + divid).empty(); $("#" + divid).empty();
} }
if ($('#predict-button').length > 0) { if ($("#predict-button").length > 0) {
$("#predict-button").on("click", function (e) { $("#predict-button").on("click", function (e) {
e.preventDefault(); e.preventDefault();
clear("predictResultTable"); clear("predictResultTable");
data = { data = {
"smiles": $("#smiles-to-predict").val(), smiles: $("#smiles-to-predict").val(),
"classify": "ILikeCats!" classify: "ILikeCats!",
} };
if (data["smiles"].trim() === "") { if (data["smiles"].trim() === "") {
$("#predictResultTable").addClass("alert alert-danger"); $("#predictResultTable").addClass("alert alert-danger");
$("#predictResultTable").append("Please enter a SMILES string to predict!"); $("#predictResultTable").append(
"Please enter a SMILES string to predict!",
);
return; return;
} }
makeLoadingGif("#predictLoading", "{% static '/images/wait.gif' %}"); makeLoadingGif("#predictLoading", "{% static '/images/wait.gif' %}");
$.ajax({ $.ajax({
type: 'get', type: "get",
data: data, data: data,
url: '', url: "",
success: function (data, textStatus) { success: function (data, textStatus) {
try { try {
$("#predictLoading").empty(); $("#predictLoading").empty();
handlePredictionResponse(data); handlePredictionResponse(data);
} catch (error) { } catch (error) {
$("#predictLoading").empty(); $("#predictLoading").empty();
$("#predictResultTable").addClass("alert alert-danger"); $("#predictResultTable").addClass("alert alert-danger");
$("#predictResultTable").append("Error while processing response :/"); $("#predictResultTable").append(
"Error while processing response :/",
);
} }
}, },
error: function (jqXHR, textStatus, errorThrown, x) { error: function (jqXHR, textStatus, errorThrown, x) {
@ -352,30 +473,30 @@
}); });
} }
if ($('#assess-button').length > 0) { if ($("#assess-button").length > 0) {
$("#assess-button").on("click", function (e) { $("#assess-button").on("click", function (e) {
e.preventDefault(); e.preventDefault();
clear("appDomainAssessmentResultTable"); clear("appDomainAssessmentResultTable");
data = { data = {
"smiles": $("#smiles-to-assess").val(), smiles: $("#smiles-to-assess").val(),
"app-domain-assessment": "ILikeCats!" "app-domain-assessment": "ILikeCats!",
} };
if (data["smiles"].trim() === "") { if (data["smiles"].trim() === "") {
$("#appDomainAssessmentResultTable").addClass("alert alert-danger"); $("#appDomainAssessmentResultTable").addClass("alert alert-danger");
$("#appDomainAssessmentResultTable").append("Please enter a SMILES string to predict!"); $("#appDomainAssessmentResultTable").append(
"Please enter a SMILES string to predict!",
);
return; return;
} }
makeLoadingGif("#appDomainLoading", "{% static '/images/wait.gif' %}"); makeLoadingGif("#appDomainLoading", "{% static '/images/wait.gif' %}");
$.ajax({ $.ajax({
type: 'get', type: "get",
data: data, data: data,
url: '', url: "",
success: function (data, textStatus) { success: function (data, textStatus) {
try { try {
$("#appDomainLoading").empty(); $("#appDomainLoading").empty();
@ -383,19 +504,23 @@
console.log(data); console.log(data);
} catch (error) { } catch (error) {
$("#appDomainLoading").empty(); $("#appDomainLoading").empty();
$("#appDomainAssessmentResultTable").addClass("alert alert-danger"); $("#appDomainAssessmentResultTable").addClass(
$("#appDomainAssessmentResultTable").append("Error while processing response :/"); "alert alert-danger",
);
$("#appDomainAssessmentResultTable").append(
"Error while processing response :/",
);
} }
}, },
error: function (jqXHR, textStatus, errorThrown) { error: function (jqXHR, textStatus, errorThrown) {
$("#appDomainLoading").empty(); $("#appDomainLoading").empty();
$("#appDomainAssessmentResultTable").addClass("alert alert-danger"); $("#appDomainAssessmentResultTable").addClass("alert alert-danger");
$("#appDomainAssessmentResultTable").append(jqXHR.responseJSON.error); $("#appDomainAssessmentResultTable").append(
} jqXHR.responseJSON.error,
);
},
}); });
}); });
} }
</script> </script>
{% endblock content %} {% endblock content %}