From d100658655ed7c92a3150bb7bbd647af79d52b80 Mon Sep 17 00:00:00 2001
From: Vermaas <vermaas@astron.nl>
Date: Wed, 21 Jun 2023 12:38:05 +0200
Subject: [PATCH] finish algorithm add validation button to Validation page

---
 atdb/taskdatabase/models.py                   | 86 ++++++++++---------
 .../validation/validation_buttons.html        |  4 +
 atdb/taskdatabase/views.py                    | 14 +++
 3 files changed, 64 insertions(+), 40 deletions(-)

diff --git a/atdb/taskdatabase/models.py b/atdb/taskdatabase/models.py
index 6679e14a..3ab371f8 100644
--- a/atdb/taskdatabase/models.py
+++ b/atdb/taskdatabase/models.py
@@ -69,12 +69,22 @@ def convert_summary_to_list_for_template(task):
 
 
 
-
-
 def calculate_qualities(task):
     """"
     calculate the quality for this task, but also the quality for all the combined tasks of this sas_id
     """
+
+    # read the quality_thresholds from the Configuration table
+    try:
+        quality_thresholds = json.loads(Configuration.objects.get(key='quality_thresholds').value)
+    except:
+        quality_thresholds = {
+            "moderate": 20,
+            "poor": 50,
+            "overall_poor": 50,
+            "overall_good": 90,
+        }
+
     def calculate_quality_task(task):
         """"
         calculate the quality of this task based on rfi_percent values
@@ -87,19 +97,9 @@ def calculate_qualities(task):
                 except when rfi_percent	= 0
         """
         try:
-            # read the quality_thresholds from the Configuration table
-            try:
-                quality_thresholds = json.loads(Configuration.objects.get(key='quality_thresholds').value)
-            except:
-                quality_thresholds = {
-                    "moderate": 20,
-                    "poor": 50,
-                    "overall_poor": 50,
-                    "overall_good": 90,
-                }
 
             summary = task.quality_json["summary"]
-            quality = task.calculated_quality
+            quality = None
 
             for key in summary:
                 record = summary[key]
@@ -115,7 +115,7 @@ def calculate_qualities(task):
         except Exception as error:
             logger.info(error)
 
-    def calculate_quality_sasid(task):
+    def calculate_quality_sasid(unsaved_task):
         """
         calculate the overall quality per sas_id, based on other tasks with the same sas_id
         The threshold values are written from a configuration json blob
@@ -126,27 +126,31 @@ def calculate_qualities(task):
              otherwise is moderate.
         """
         try:
-            # read the quality_thresholds from the Configuration table
-            try:
-                quality_thresholds = json.loads(Configuration.objects.get(key='quality_thresholds').value)
-            except:
-                quality_thresholds = {
-                    "moderate": 20,
-                    "poor": 50,
-                    "overall_poor": 50,
-                    "overall_good": 90,
-                }
-
             # gather the results of all the calculated_quality values for this sas_id
             d = {'poor': 0, 'moderate': 0, 'good': 0}
-            for task in Task.objects.filter(sas_id=task.sas_id):
-                d[task.calculated_quality] = d[task.calculated_quality] + 1
 
-            quality_sasid = "moderate"
+            for task in Task.objects.filter(sas_id=unsaved_task.sas_id):
+
+                # because this all happens in the overridden 'Task.save', the actual saving has not yet occurred
+                # So use the calculated quality from the unsaved task instead.
+                if task.id == unsaved_task.id:
+                    t = unsaved_task
+                else:
+                    t = task
+
+                try:
+                    key = t.calculated_qualities['per_task']
+                    d[key] = d[key] + 1
+                except:
+                    # ignore the tasks that have no calculated quality (they are probably not 'stored').
+                    pass
+
+
             total = d['poor'] + d['moderate'] + d['good']
             if total > 0:
                 percentage_poor = (d['poor'] / total) * 100
                 percentage_good = (d['good'] / total) * 100
+                quality_sasid = "moderate"
 
                 if percentage_poor >= quality_thresholds['overall_poor']:
                     quality_sasid = 'poor'
@@ -160,22 +164,24 @@ def calculate_qualities(task):
             logger.info(error)
 
 
-        # --- main function body ---
-        # calculate the quality for this task
-        calculated_quality_task = calculate_quality_task(task)
+    # --- main function body ---
+    # calculate the quality for this task
+    calculated_quality_task = calculate_quality_task(task)
 
-        # update the overall quality of all tasks for this sas_id
-        calculated_quality_sasid = calculate_quality_sasid(task)
+    # store the result in task.calculated_qualities (not yet saved in the database)
+    d = task.calculated_qualities
+    if not d:
+        d = {}
+    d['per_task'] = calculated_quality_task
+    task.calculated_qualities = d
 
-        # combine both calculated qualities in the json field (dict)
-        d = task.calculated_qualities
-        if not d:
-            d = {}
+    # update the overall quality of all tasks for this sas_id
+    calculated_quality_sasid = calculate_quality_sasid(task)
 
-        d['per_task'] = calculated_quality_task
-        d['per_sasid'] = calculated_quality_sasid
+    # store the result in task.calculated_qualities (not yet saved in the database)
+    d['per_sasid'] = calculated_quality_sasid
 
-        return d
+    return d
 
 class Task(models.Model):
 
diff --git a/atdb/taskdatabase/templates/taskdatabase/validation/validation_buttons.html b/atdb/taskdatabase/templates/taskdatabase/validation/validation_buttons.html
index a5a9d1c7..3370f9cf 100644
--- a/atdb/taskdatabase/templates/taskdatabase/validation/validation_buttons.html
+++ b/atdb/taskdatabase/templates/taskdatabase/validation/validation_buttons.html
@@ -10,3 +10,7 @@
  {% if task.sasid_is_verified %}
     <a href="{% url 'task-validate-view' task.pk 'good' 'validated' my_tasks.number %}" class="btn btn-success btn-sm" role="button"><i class="fas fa-check"></i> G</a>
  {% endif %}
+
+  {% if task.sasid_is_verified %}
+    <a href="{% url 'task-validate-view' task.pk 'calculated' 'validated' my_tasks.number %}" class="btn btn-success btn-sm" role="button"><i class="fas fa-check"></i> Validate</a>
+ {% endif %}
diff --git a/atdb/taskdatabase/views.py b/atdb/taskdatabase/views.py
index f732752c..b6d0e41e 100644
--- a/atdb/taskdatabase/views.py
+++ b/atdb/taskdatabase/views.py
@@ -1069,7 +1069,13 @@ def TaskSetStatus(request, pk, new_status, page=0):
 
 @login_required
 def TaskValidate(request, pk, quality, new_status, page=0):
+    """
+    find all tasks with the same SAS_ID of the given task (pk), and set its quality to all of them
+    This is used by the 'P/M/G/Validate' buttons on the Validation Page
 
+    There is one special 'quality', if its value is 'calculated' then use the calculated quality of the task.
+    Unless there is no calculated quality, then don't change the quality and just set the status to 'validated'
+    """
     task = Task.objects.get(pk=pk)
 
     # find all tasks with the same SAS_ID, and set this quality to all of them
@@ -1077,6 +1083,14 @@ def TaskValidate(request, pk, quality, new_status, page=0):
     tasks = Task.objects.filter(sas_id=sas_id)
     for task in tasks:
         if task.status == 'stored':
+
+            if quality == 'calculated':
+                try:
+                    quality = task.calculated_qualities['per_sasid']
+                except:
+                    # no calculated quality present, just the existing quality (so no change)
+                    quality = task.quality
+
             task.quality = quality
             task.new_status = new_status
             task.save()
-- 
GitLab