File indexing completed on 2026-04-27 07:41:44
0001 {% extends 'base.html' %}
0002
0003 {% block title %}Create Dataset - PCS{% endblock %}
0004
0005 {% block content %}
0006 {% csrf_token %}
0007 <div class="container mt-4">
0008 <nav aria-label="breadcrumb">
0009 <ol class="breadcrumb">
0010 <li class="breadcrumb-item"><a href="{% url 'pcs:pcs_hub' %}">PCS</a></li>
0011 <li class="breadcrumb-item"><a href="{% url 'pcs:datasets_compose' %}">Datasets</a></li>
0012 <li class="breadcrumb-item active">Create</li>
0013 </ol>
0014 </nav>
0015
0016 <h2>Create Dataset</h2>
0017 <p>Compose a dataset from locked tags. Block 1 is created automatically. Only locked tags appear in the dropdowns.</p>
0018
0019 <div class="mt-3" style="max-width: 700px;" id="dataset-form">
0020
0021 <div class="row mb-3">
0022 <div class="col-md-4">
0023 <label for="id_scope" class="form-label"><strong>Scope</strong></label>
0024 <input type="text" name="scope" id="id_scope" class="form-control" value="{{ form.scope.value|default:"group.EIC" }}">
0025 </div>
0026 <div class="col-md-4">
0027 <label for="id_detector_version" class="form-label"><strong>Detector Version</strong></label>
0028 <input type="text" name="detector_version" id="id_detector_version" class="form-control" value="{{ form.detector_version.value|default:"" }}" placeholder="e.g. 26.02.0">
0029 </div>
0030 <div class="col-md-4">
0031 <label for="id_detector_config" class="form-label"><strong>Detector Config</strong></label>
0032 <input type="text" name="detector_config" id="id_detector_config" class="form-control" value="{{ form.detector_config.value|default:"" }}" placeholder="e.g. epic_craterlake">
0033 </div>
0034 </div>
0035
0036 <div class="row mb-3">
0037 <div class="col-md-6">
0038 <label for="id_physics_tag" class="form-label"><strong>Physics Tag</strong></label>
0039 <select name="physics_tag" id="id_physics_tag" class="form-select" onchange="updatePreview()">
0040 <option value="">Select physics tag</option>
0041 {% for tag in form.physics_tag.field.queryset %}
0042 <option value="{{ tag.pk }}" data-label="{{ tag.tag_label }}" {% if form.physics_tag.value|stringformat:"s" == tag.pk|stringformat:"s" %}selected{% endif %}>{{ tag.tag_label }} — {{ tag.description|truncatewords:8 }}</option>
0043 {% endfor %}
0044 </select>
0045 </div>
0046 <div class="col-md-6">
0047 <label for="id_evgen_tag" class="form-label"><strong>EvGen Tag</strong></label>
0048 <select name="evgen_tag" id="id_evgen_tag" class="form-select" onchange="updatePreview()">
0049 <option value="">Select evgen tag</option>
0050 {% for tag in form.evgen_tag.field.queryset %}
0051 <option value="{{ tag.pk }}" data-label="{{ tag.tag_label }}" {% if form.evgen_tag.value|stringformat:"s" == tag.pk|stringformat:"s" %}selected{% endif %}>{{ tag.tag_label }} — {{ tag.description|truncatewords:8 }}</option>
0052 {% endfor %}
0053 </select>
0054 </div>
0055 </div>
0056
0057 <div class="row mb-3">
0058 <div class="col-md-6">
0059 <label for="id_simu_tag" class="form-label"><strong>Simu Tag</strong></label>
0060 <select name="simu_tag" id="id_simu_tag" class="form-select" onchange="updatePreview()">
0061 <option value="">Select simu tag</option>
0062 {% for tag in form.simu_tag.field.queryset %}
0063 <option value="{{ tag.pk }}" data-label="{{ tag.tag_label }}" {% if form.simu_tag.value|stringformat:"s" == tag.pk|stringformat:"s" %}selected{% endif %}>{{ tag.tag_label }} — {{ tag.description|truncatewords:8 }}</option>
0064 {% endfor %}
0065 </select>
0066 </div>
0067 <div class="col-md-6">
0068 <label for="id_reco_tag" class="form-label"><strong>Reco Tag</strong></label>
0069 <select name="reco_tag" id="id_reco_tag" class="form-select" onchange="updatePreview()">
0070 <option value="">Select reco tag</option>
0071 {% for tag in form.reco_tag.field.queryset %}
0072 <option value="{{ tag.pk }}" data-label="{{ tag.tag_label }}" {% if form.reco_tag.value|stringformat:"s" == tag.pk|stringformat:"s" %}selected{% endif %}>{{ tag.tag_label }} — {{ tag.description|truncatewords:8 }}</option>
0073 {% endfor %}
0074 </select>
0075 </div>
0076 </div>
0077
0078 <div class="mb-3">
0079 <label class="form-label"><strong>Dataset Name Preview</strong></label>
0080 <div id="name-preview" class="form-control bg-light" style="font-family: monospace; min-height: 38px;"></div>
0081 <small class="text-muted">Max 255 characters. <span id="char-count"></span></small>
0082 </div>
0083
0084 <div class="mb-3">
0085 <label for="id_description" class="form-label"><strong>Description</strong></label>
0086 <textarea name="description" id="id_description" class="form-control" rows="3">{{ form.description.value|default:"" }}</textarea>
0087 </div>
0088
0089 <div class="alert alert-danger" id="form-errors" style="display:none;"></div>
0090
0091 <button type="button" class="btn btn-primary btn-sm" onclick="createDataset()">Create Dataset</button>
0092 <a href="{% url 'pcs:datasets_compose' %}" class="btn btn-secondary btn-sm">Cancel</a>
0093 </div>
0094 </div>
0095
0096 <script>
0097 function getSelectedLabel(selectId) {
0098 const sel = document.getElementById(selectId);
0099 const opt = sel.options[sel.selectedIndex];
0100 return opt && opt.dataset.label ? opt.dataset.label : '?';
0101 }
0102
0103 function updatePreview() {
0104 const scope = document.getElementById('id_scope').value || '?';
0105 const version = document.getElementById('id_detector_version').value || '?';
0106 const config = document.getElementById('id_detector_config').value || '?';
0107 const p = getSelectedLabel('id_physics_tag');
0108 const e = getSelectedLabel('id_evgen_tag');
0109 const s = getSelectedLabel('id_simu_tag');
0110 const r = getSelectedLabel('id_reco_tag');
0111 const name = `${scope}.${version}.${config}.${p}.${e}.${s}.${r}`;
0112 document.getElementById('name-preview').textContent = name;
0113 const len = name.length;
0114 const counter = document.getElementById('char-count');
0115 counter.textContent = `${len}/255`;
0116 counter.style.color = len > 255 ? 'red' : 'inherit';
0117 }
0118
0119 document.getElementById('id_scope').addEventListener('input', updatePreview);
0120 document.getElementById('id_detector_version').addEventListener('input', updatePreview);
0121 document.getElementById('id_detector_config').addEventListener('input', updatePreview);
0122 updatePreview();
0123
0124 async function createDataset() {
0125 const csrfToken = document.querySelector('[name=csrfmiddlewaretoken]')?.value || '';
0126 const headers = {'Content-Type': 'application/json'};
0127 if (csrfToken) headers['X-CSRFToken'] = csrfToken;
0128 const payload = {
0129 scope: document.getElementById('id_scope').value,
0130 detector_version: document.getElementById('id_detector_version').value,
0131 detector_config: document.getElementById('id_detector_config').value,
0132 physics_tag: document.getElementById('id_physics_tag').value,
0133 evgen_tag: document.getElementById('id_evgen_tag').value,
0134 simu_tag: document.getElementById('id_simu_tag').value,
0135 reco_tag: document.getElementById('id_reco_tag').value,
0136 description: document.getElementById('id_description').value,
0137 };
0138 const errDiv = document.getElementById('form-errors');
0139 errDiv.style.display = 'none';
0140 const resp = await fetch('/swf-monitor/pcs/api/datasets/', {
0141 method: 'POST', headers, body: JSON.stringify(payload)
0142 });
0143 if (resp.ok) {
0144 const data = await resp.json();
0145 window.location.href = `{% url 'pcs:datasets_compose' %}?selected=${encodeURIComponent(data.dataset_name || data.name || data.id)}`;
0146 } else {
0147 const errors = await resp.json();
0148 let html = '';
0149 for (const [field, msgs] of Object.entries(errors)) {
0150 html += `<p><strong>${field}:</strong> ${Array.isArray(msgs) ? msgs.join(', ') : msgs}</p>`;
0151 }
0152 errDiv.innerHTML = html;
0153 errDiv.style.display = 'block';
0154 }
0155 }
0156 </script>
0157 {% endblock %}