Files
enviPy-bayer/templates/objects/model.html

527 lines
18 KiB
HTML

{% extends "framework.html" %}
{% load static %}
{% load envipytags %}
{% block content %}
{% block action_modals %}
{% include "modals/objects/edit_model_modal.html" %}
{% include "modals/objects/evaluate_model_modal.html" %}
{% include "modals/objects/retrain_model_modal.html" %}
{% include "modals/objects/generic_delete_modal.html" %}
{% endblock action_modals %}
<!-- Include required libs -->
<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>
<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 panel-default">
<div
class="panel-heading"
id="headingPanel"
style="font-size:2rem;height: 46px"
>
{{ model.name|safe }}
<div
id="actionsButton"
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"
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">
{% block actions %}
{% include "actions/objects/model.html" %}
{% endblock %}
</ul>
</div>
</div>
<div class="panel-body">
<p>{{ model.description|safe }}</p>
</div>
{% if model|classname == 'MLRelativeReasoning' or model|classname == 'RuleBasedRelativeReasoning' %}
<!-- Rule Packages -->
<div
class="panel panel-default panel-heading list-group-item"
style="background-color:silver"
>
<h4 class="panel-title">
<a
id="rule-package-link"
data-toggle="collapse"
data-parent="#model-detail"
href="#rule-package"
>Rule Packages</a
>
</h4>
</div>
<div id="rule-package" class="panel-collapse in collapse">
<div class="panel-body list-group-item">
{% for p in model.rule_packages.all %}
<a class="list-group-item" href="{{ p.url }}"
>{{ p.name|safe }}</a
>
{% endfor %}
</div>
</div>
<!-- Reaction Packages -->
<div
class="panel panel-default panel-heading list-group-item"
style="background-color:silver"
>
<h4 class="panel-title">
<a
id="reaction-package-link"
data-toggle="collapse"
data-parent="#model-detail"
href="#reaction-package"
>Rule Packages</a
>
</h4>
</div>
<div id="reaction-package" class="panel-collapse in collapse">
<div class="panel-body list-group-item">
{% for p in model.data_packages.all %}
<a class="list-group-item" href="{{ p.url }}"
>{{ p.name|safe }}</a
>
{% endfor %}
</div>
</div>
{% if model.eval_packages.all|length > 0 %}
<!-- Eval Packages -->
<div
class="panel panel-default panel-heading list-group-item"
style="background-color:silver"
>
<h4 class="panel-title">
<a
id="eval-package-link"
data-toggle="collapse"
data-parent="#model-detail"
href="#eval-package"
>Rule Packages</a
>
</h4>
</div>
<div id="eval-package" class="panel-collapse in collapse">
<div class="panel-body list-group-item">
{% for p in model.eval_packages.all %}
<a class="list-group-item" href="{{ p.url }}"
>{{ p.name|safe }}</a
>
{% endfor %}
</div>
</div>
{% endif %}
<!-- Model Status -->
<div
class="panel panel-default panel-heading list-group-item"
style="background-color:silver"
>
<h4 class="panel-title">
<a
id="model-status-link"
data-toggle="collapse"
data-parent="#model-detail"
href="#model-status"
>Model Status</a
>
</h4>
</div>
<div id="model-status" class="panel-collapse in collapse">
<div class="panel-body list-group-item">{{ model.status }}</div>
</div>
{% endif %}
{% if model.ready_for_prediction %}
<!-- Predict Panel -->
<div
class="panel panel-default panel-heading list-group-item"
style="background-color:silver"
>
<h4 class="panel-title">
<a
id="predict-smiles-link"
data-toggle="collapse"
data-parent="#model-detail"
href="#predict-smiles"
>Predict</a
>
</h4>
</div>
<div id="predict-smiles" class="panel-collapse in collapse">
<div class="panel-body list-group-item">
<div class="input-group">
<input
id="smiles-to-predict"
type="text"
class="form-control"
placeholder="CCN(CC)C(=O)C1=CC(=CC=C1)C"
/>
<span class="input-group-btn">
<button
class="btn btn-default"
type="submit"
id="predict-button"
>
Predict!
</button>
</span>
</div>
<div id="predictLoading"></div>
<div id="predictResultTable"></div>
</div>
</div>
<!-- End Predict Panel -->
{% endif %}
{% if model.ready_for_prediction and model.app_domain %}
<!-- App Domain -->
<div
class="panel panel-default panel-heading list-group-item"
style="background-color:silver"
>
<h4 class="panel-title">
<a
id="app-domain-assessment-link"
data-toggle="collapse"
data-parent="#model-detail"
href="#app-domain-assessment"
>Applicability Domain Assessment</a
>
</h4>
</div>
<div id="app-domain-assessment" class="panel-collapse in collapse">
<div class="panel-body list-group-item">
<div class="input-group">
<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">
<button
class="btn btn-default"
type="submit"
id="assess-button"
>
Assess!
</button>
</span>
</div>
<div id="appDomainLoading"></div>
<div id="appDomainAssessmentResultTable"></div>
</div>
</div>
<!-- End App Domain -->
{% endif %}
{% if model.model_status == 'FINISHED' %}
<!-- Single Gen Curve Panel -->
<div
class="panel panel-default panel-heading list-group-item"
style="background-color:silver"
>
<h4 class="panel-title">
<a
id="sg-curve-link"
data-toggle="collapse"
data-parent="#model-detail"
href="#sg-curve"
>Precision Recall Curve</a
>
</h4>
</div>
<div id="sg-curve" class="panel-collapse in collapse">
<div class="panel-body list-group-item">
<!-- Center container contents -->
<div
class="container"
style="display: flex;justify-content: center;"
>
<div id="sg-curve-plotdiv" class="chart">
<div id="sg-chart"></div>
</div>
</div>
</div>
</div>
{# prettier-ignore-start #}
<script>
$(function () {
if (!($('#sg-chart').length > 0)) {
return;
}
var x = ['Recall'];
var y = ['Precision'];
var thres = ['threshold'];
// Compare function for the given array
function compare(a, b) {
if (a.threshold < b.threshold)
return -1;
else if (a.threshold > b.threshold)
return 1;
else
return 0;
}
function getIndexForValue(data, val, val_name) {
for (var idx in data) {
if (data[idx][val_name] == val) {
return idx;
}
}
return -1;
}
var data = {{ model.pr_curve|safe }}
var dataLength = Object.keys(data).length;
data.sort(compare);
for (var idx in data) {
var d = data[idx];
x.push(d.recall);
y.push(d.precision);
thres.push(d.threshold);
}
var chart = c3.generate({
bindto: '#sg-chart',
data: {
onclick: function (d, e) {
var idx = d.index;
var thresh = data[dataLength - idx - 1].threshold;
//onclick(thresh)
},
x: 'Recall',
y: 'Precision',
columns: [
x,
y,
//thres
]
},
size: {
height: 400, // TODO: Make variable to current modal width
width: 480
},
axis: {
x: {
max: 1,
min: 0,
label: 'Recall',
padding: 0,
tick: {
fit: true,
values: [0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0]
}
},
y: {
max: 1,
min: 0,
label: 'Precision',
padding: 0,
tick: {
fit: true,
values: [0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0]
}
}
},
point: {
r: 4
},
tooltip: {
format: {
title: function (recall) {
idx = getIndexForValue(data, recall, "recall");
if (idx != -1) {
return "Threshold: " + data[idx].threshold;
}
return "";
},
value: function (precision, ratio, id) {
return undefined;
}
}
},
zoom: {
enabled: true
}
});
});
</script>
{# prettier-ignore-end #}
<!-- End Single Gen Curve Panel -->
{% endif %}
</div>
</div>
<script>
function handlePredictionResponse(data) {
res = "<table class='table table-striped'>";
res += "<thead>";
res += "<th scope='col'>#</th>";
columns = ["products", "image", "probability", "btrule"];
for (col in columns) {
res += "<th scope='col'>" + columns[col] + "</th>";
}
res += "</thead>";
res += "<tbody>";
var cnt = 1;
for (transformation in data) {
res += "<tr>";
res += "<th scope='row'>" + cnt + "</th>";
res +=
"<th scope='row'>" +
data[transformation]["products"][0].join(", ") +
"</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 {
res += "<th scope='row'>N/A</th>";
}
res += "</tr>";
cnt += 1;
}
res += "</tbody>";
res += "</table>";
$("#predictResultTable").append(res);
}
function clear(divid) {
$("#" + divid).removeClass("alert alert-danger");
$("#" + divid).empty();
}
if ($("#predict-button").length > 0) {
$("#predict-button").on("click", function (e) {
e.preventDefault();
clear("predictResultTable");
data = {
smiles: $("#smiles-to-predict").val(),
classify: "ILikeCats!",
};
if (data["smiles"].trim() === "") {
$("#predictResultTable").addClass("alert alert-danger");
$("#predictResultTable").append(
"Please enter a SMILES string to predict!",
);
return;
}
makeLoadingGif("#predictLoading", "{% static '/images/wait.gif' %}");
$.ajax({
type: "get",
data: data,
url: "",
success: function (data, textStatus) {
try {
$("#predictLoading").empty();
handlePredictionResponse(data);
} catch (error) {
$("#predictLoading").empty();
$("#predictResultTable").addClass("alert alert-danger");
$("#predictResultTable").append(
"Error while processing response :/",
);
}
},
error: function (jqXHR, textStatus, errorThrown, x) {
$("#predictLoading").empty();
$("#predictResultTable").addClass("alert alert-danger");
$("#predictResultTable").append(jqXHR.responseJSON.error);
},
});
});
}
if ($("#assess-button").length > 0) {
$("#assess-button").on("click", function (e) {
e.preventDefault();
clear("appDomainAssessmentResultTable");
data = {
smiles: $("#smiles-to-assess").val(),
"app-domain-assessment": "ILikeCats!",
};
if (data["smiles"].trim() === "") {
$("#appDomainAssessmentResultTable").addClass("alert alert-danger");
$("#appDomainAssessmentResultTable").append(
"Please enter a SMILES string to predict!",
);
return;
}
makeLoadingGif("#appDomainLoading", "{% static '/images/wait.gif' %}");
$.ajax({
type: "get",
data: data,
url: "",
success: function (data, textStatus) {
try {
$("#appDomainLoading").empty();
handleAssessmentResponse("{% url 'depict' %}", data);
console.log(data);
} catch (error) {
$("#appDomainLoading").empty();
$("#appDomainAssessmentResultTable").addClass(
"alert alert-danger",
);
$("#appDomainAssessmentResultTable").append(
"Error while processing response :/",
);
}
},
error: function (jqXHR, textStatus, errorThrown) {
$("#appDomainLoading").empty();
$("#appDomainAssessmentResultTable").addClass("alert alert-danger");
$("#appDomainAssessmentResultTable").append(
jqXHR.responseJSON.error,
);
},
});
});
}
</script>
{% endblock content %}