Biofuel-Optimiser / templates /screening.html
carrotcake3's picture
Update templates/screening.html
6af413c verified
Raw
History Blame Contribute Delete
8.39 kB
{% extends "base.html" %}
{% block content %}
<div class="container py-4">
<!-- Header -->
<div class="mb-4">
<h2 class="fw-bold mb-2">Biofuel Screening Tool</h2>
<p class="page-intro-text mb-0">
Screen candidate fuels from a CSV file using property prediction, cetane number targeting,
filtering, and Pareto ranking.
</p>
</div>
{% if error %}
<div class="alert alert-danger">
<i class="bi bi-exclamation-triangle me-2"></i>{{ error }}
</div>
{% endif %}
{% if info %}
<div class="alert alert-info">
<i class="bi bi-info-circle me-2"></i>{{ info }}
</div>
{% endif %}
<!-- Input Form -->
<div class="card card-metric p-4 mb-4">
<h5 class="fw-bold mb-3">Screening Configuration</h5>
<form method="POST" enctype="multipart/form-data">
<div class="row g-3">
<div class="col-md-4">
<label class="form-label fw-semibold">Screening Mode</label>
<select name="mode" id="screeningMode" class="form-select" onchange="toggleFilterPanel()">
<option value="pure_component">Pure Component Screening</option>
<option value="mixture">Mixture Screening</option>
</select>
<div class="form-text">
Pure mode expects a CSV with a <code>smiles</code> column.
Mixture mode expects mixture database format.
</div>
</div>
<div class="col-md-4">
<label class="form-label fw-semibold">Target CN</label>
<input type="number" step="0.01" name="target_cn" class="form-control" value="50">
</div>
<div class="col-md-4">
<label class="form-label fw-semibold">CSV File</label>
<input type="file" name="csv_file" accept=".csv" class="form-control">
<div class="mt-2">
<div class="small fw-semibold text-muted mb-1">CSV downloads</div>
<div class="d-flex flex-wrap gap-2">
<a href="{{ url_for('download_pure_screening_template') }}"
class="btn btn-outline-primary btn-sm">
Pure Template
</a>
<a href="{{ url_for('download_pure_screening_example') }}"
class="btn btn-outline-secondary btn-sm">
Pure Example
</a>
<a href="{{ url_for('download_mixture_screening_template') }}"
class="btn btn-outline-primary btn-sm">
Mixture Template
</a>
<a href="{{ url_for('download_mixture_screening_example') }}"
class="btn btn-outline-secondary btn-sm">
Mixture Example
</a>
</div>
</div>
</div>
</div>
<!-- Pure component filters -->
<div id="filterPanel" class="border rounded-3 p-3 mt-4">
<h6 class="fw-bold mb-3">Property Filters for Pure Component Screening</h6>
<div class="row g-3">
<div class="col-md-3">
<label class="form-label small fw-semibold">Min BP (°C)</label>
<input type="number" step="0.01" name="bp_min" class="form-control" value="60">
</div>
<div class="col-md-3">
<label class="form-label small fw-semibold">Max BP (°C)</label>
<input type="number" step="0.01" name="bp_max" class="form-control" value="250">
</div>
<div class="col-md-2">
<label class="form-label small fw-semibold">Min Density</label>
<input type="number" step="0.01" name="density_min" class="form-control" value="720">
</div>
<div class="col-md-2">
<label class="form-label small fw-semibold">Min LHV</label>
<input type="number" step="0.01" name="lhv_min" class="form-control" value="30">
</div>
<div class="col-md-2">
<label class="form-label small fw-semibold">Min Viscosity</label>
<input type="number" step="0.01" name="viscosity_min" class="form-control" value="2">
</div>
</div>
<div class="form-text mt-2">
Default filters match the CLI settings: BP 60–250 °C, density ≥ 720 kg/m³,
LHV ≥ 30 MJ/kg, and viscosity ≥ 2 cSt.
</div>
</div>
<button type="submit" class="btn btn-primary mt-4">
Run Screening
</button>
</form>
</div>
<!-- Run summary -->
{% if run_info %}
<div class="card card-metric p-4 mb-4">
<h5 class="fw-bold mb-3">Screening Summary</h5>
<div class="row g-3">
<div class="col-md-3">
<div class="border rounded-3 p-3 bg-white">
<p class="text-muted small mb-1">Mode</p>
<h6 class="fw-bold mb-0">{{ run_info.mode }}</h6>
</div>
</div>
<div class="col-md-3">
<div class="border rounded-3 p-3 bg-white">
<p class="text-muted small mb-1">Target CN</p>
<h6 class="fw-bold mb-0">{{ run_info.target_cn }}</h6>
</div>
</div>
<div class="col-md-2">
<div class="border rounded-3 p-3 bg-white">
<p class="text-muted small mb-1">All</p>
<h6 class="fw-bold mb-0">{{ run_info.n_all }}</h6>
</div>
</div>
<div class="col-md-2">
<div class="border rounded-3 p-3 bg-white">
<p class="text-muted small mb-1">Filtered</p>
<h6 class="fw-bold mb-0">{{ run_info.n_filtered }}</h6>
</div>
</div>
<div class="col-md-2">
<div class="border rounded-3 p-3 bg-white">
<p class="text-muted small mb-1">Pareto</p>
<h6 class="fw-bold mb-0">{{ run_info.n_pareto }}</h6>
</div>
</div>
</div>
</div>
{% endif %}
<!-- Filtered results -->
{% if filtered_table %}
<div class="card card-metric p-4 mb-4">
<div class="d-flex justify-content-between align-items-center flex-wrap gap-2 mb-3">
<h5 class="fw-bold mb-0">Top / Filtered Candidates</h5>
<form method="POST" action="{{ url_for('download_screening_result', result_type='filtered') }}">
<input type="hidden" name="results_data" value='{{ filtered_records | tojson }}'>
<button type="submit" class="btn btn-outline-success btn-sm">
Download Filtered CSV
</button>
</form>
</div>
<div class="table-responsive app-table-wrap molecule-table">
{{ filtered_table | safe }}
</div>
</div>
{% endif %}
<!-- Pareto results -->
{% if pareto_table %}
<div class="card card-metric p-4 mb-4">
<div class="d-flex justify-content-between align-items-center flex-wrap gap-2 mb-3">
<h5 class="fw-bold mb-0">Pareto Front</h5>
<form method="POST" action="{{ url_for('download_screening_result', result_type='pareto') }}">
<input type="hidden" name="results_data" value='{{ pareto_records | tojson }}'>
<button type="submit" class="btn btn-outline-primary btn-sm">
Download Pareto CSV
</button>
</form>
</div>
<p class="text-muted small">
Pareto candidates balance low CN error with low YSI.
</p>
<div class="table-responsive app-table-wrap molecule-table">
{{ pareto_table | safe }}
</div>
</div>
{% endif %}
<!-- All candidates -->
{% if all_table %}
<div class="card card-metric p-4 mb-4">
<div class="d-flex justify-content-between align-items-center flex-wrap gap-2 mb-3">
<h5 class="fw-bold mb-0">All Candidates</h5>
<form method="POST" action="{{ url_for('download_screening_result', result_type='all') }}">
<input type="hidden" name="results_data" value='{{ all_records | tojson }}'>
<button type="submit" class="btn btn-outline-secondary btn-sm">
Download All CSV
</button>
</form>
</div>
<div class="table-responsive app-table-wrap molecule-table">
{{ all_table | safe }}
</div>
</div>
{% endif %}
</div>
<script>
function toggleFilterPanel() {
const mode = document.getElementById("screeningMode").value;
const panel = document.getElementById("filterPanel");
if (mode === "pure_component") {
panel.style.display = "block";
} else {
panel.style.display = "none";
}
}
document.addEventListener("DOMContentLoaded", toggleFilterPanel);
</script>
{% endblock %}