Skip to content

Commit

Permalink
Improved services.py algorithm
Browse files Browse the repository at this point in the history
  • Loading branch information
Zalo committed Dec 23, 2024
1 parent bfd75d9 commit 7c56f43
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 50 deletions.
1 change: 0 additions & 1 deletion src/planscape/impacts/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -324,7 +324,6 @@ class TreatmentResultsPlotSerializer(serializers.Serializer):


class StandQuerySerializer(serializers.Serializer):
# Use PrimaryKeyRelatedField to ensure stand_id is valid PK from Stand model
stand_id = serializers.PrimaryKeyRelatedField(
queryset=Stand.objects.all(), required=True
)
58 changes: 20 additions & 38 deletions src/planscape/impacts/services.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
#Temporary endpoint imports
from collections import defaultdict
from impacts.models import TreatmentResult, ImpactVariable

import logging
import itertools
import json
Expand Down Expand Up @@ -530,56 +534,34 @@ def calculate_project_area_deltas(
return results


from impacts.models import TreatmentResult, ImpactVariable


def get_treatment_results_table_data(treatment_plan, stand_id):
"""
Retrieves treatment results for RATE_OF_SPREAD and FLAME_LENGTH for the given stand and treatment plan.
Return a list of dictionaries: [{"year": ..., "rate_of_spread": ..., "flame_length": ...}, ...]
Retrieves a list of dictionaries, with each dictionary representing a year and its variables.
"""
# Filter results for the given stand and plan, for the two variables we need
# Use single query to retrieve all results at once
queryset = TreatmentResult.objects.filter(
treatment_plan=treatment_plan,
stand_id=stand_id,
variable__in=[ImpactVariable.RATE_OF_SPREAD, ImpactVariable.FLAME_LENGTH],
)
).values("year", "variable", "value")

# If no results, return an empty list
if not queryset.exists():
return []

# Extract distinct years
years = queryset.values_list("year", flat=True).distinct().order_by("year")

# Build table rows
table_data = []
for year in years:
# For each year, get the corresponding records
year_results = queryset.filter(year=year)

# Extract the rate_of_spread value
rate_of_spread_val = (
year_results.filter(variable=ImpactVariable.RATE_OF_SPREAD)
.values_list("value", flat=True)
.first()
)
# Creates dictionary of { year: { variable: value } }
data_map = defaultdict(dict)

# Extract the flame_length value
flame_length_val = (
year_results.filter(variable=ImpactVariable.FLAME_LENGTH)
.values_list("Value", flat=True)
.first()
)
for row in queryset:
year = row["year"]
var = row["variable"]
val = row["value"]
data_map[year][var] = val

# Add a dictionary -- table row -- for each avaialble year
table_data.append(
{
"year": year,
"rate_of_spread": rate_of_spread_val,
"flame_length": flame_length_val,
}
)
# Convert data_map into a sorted list by year
table_data = []
for year in sorted(data_map.keys()):
row = {"year": year}
row.update(data_map[year])
table_data.append(row)

# returns list of rows to view
return table_data
22 changes: 11 additions & 11 deletions src/planscape/impacts/views.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
# Temporary endpoint Imports
from rest_framework import status, response
from rest_framework.decorators import action
from drf_spectacular.utils import extend_schema
from planscape.serializers import BaseErrorMessageSerializer
from impacts.serializers import StandQuerySerializer
from impacts.services import get_treatment_results_table_data
from impacts.models import TreatmentResult, ImpactVariable

import logging
from rest_framework import mixins, viewsets, response, status
from rest_framework.decorators import action
Expand Down Expand Up @@ -257,14 +266,7 @@ def plot(self, request, pk=None):
)
return Response(data=data_to_plot, status=status.HTTP_200_OK)

# Imports
from rest_framework import status, response
from rest_framework.decorators import action
from drf_spectacular.utils import extend_schema
from planscape.serializers import BaseErrorMessageSerializer
from impacts.serializers import StandQuerySerializer
from impacts.services import get_treatment_results_table_data
from impacts.models import TreatmentResult, ImpactVariable


@extend_schema(
description="Retrieve treatment result information for a specific stand.",
Expand Down Expand Up @@ -297,9 +299,7 @@ def stand_treatment_results(self, request, pk=None):

if not table_data:
return response.Response(
{
"detail": "No treatment results found for this stand in the given treatment plan."
},
{"detail": "No treatment results found."},
status=status.HTTP_404_NOT_FOUND,
)

Expand Down

0 comments on commit 7c56f43

Please sign in to comment.