@@ -2488,6 +2488,9 @@ def get_best_prediction(self, filters: dict = {}) -> Classification | None:
2488
2488
# If no terminal classification exists, fall back to non-terminal
2489
2489
return all_classifications .filter (terminal = False ).order_by ("-score" ).first ()
2490
2490
2491
+ def get_best_ood_prediction (self ) -> Classification | None :
2492
+ return self .get_best_prediction (filters = {"ood_score__isnull" : False })
2493
+
2491
2494
def get_best_identification (self ) -> Identification | None :
2492
2495
"""
2493
2496
The most recent human identification is used as the best identification.
@@ -2500,13 +2503,11 @@ def get_determination_score(self, prediction: Classification | None = None) -> f
2500
2503
"""
2501
2504
Always return a score from an algorithm, even if a human has identified the occurrence.
2502
2505
"""
2503
- if not self .determination :
2504
- return None
2505
2506
best_prediction = prediction or self .get_best_prediction ()
2506
- if best_prediction :
2507
- return best_prediction .score
2508
- else :
2507
+ if not best_prediction :
2509
2508
return None
2509
+ else :
2510
+ return best_prediction .score
2510
2511
2511
2512
def get_determination_ood_score (self , prediction : Classification | None = None ) -> float | None :
2512
2513
"""
@@ -2517,16 +2518,16 @@ def get_determination_ood_score(self, prediction: Classification | None = None)
2517
2518
"""
2518
2519
# Get the best prediction that has an OOD score
2519
2520
# this should be the last classification before the clustering algorithm
2520
- # @TODO copy the OOD score from the best classification to the clustering classification during clustering
2521
- best_prediction = prediction or self .get_best_prediction (filters = {"ood_score__isnull" : False })
2521
+ best_prediction = prediction or self .get_best_ood_prediction ()
2522
2522
if not best_prediction :
2523
2523
return None
2524
- mean_ood_score = Classification .objects .filter (
2525
- detection__occurrence = self ,
2526
- ood_score__isnull = False ,
2527
- algorithm = best_prediction .algorithm ,
2528
- ).aggregate (models .Avg ("ood_score" ),)["ood_score__avg" ]
2529
- return mean_ood_score
2524
+ else :
2525
+ mean_ood_score = Classification .objects .filter (
2526
+ detection__occurrence = self ,
2527
+ ood_score__isnull = False ,
2528
+ algorithm = best_prediction .algorithm ,
2529
+ ).aggregate (models .Avg ("ood_score" ),)["ood_score__avg" ]
2530
+ return mean_ood_score
2530
2531
2531
2532
def context_url (self ):
2532
2533
detection = self .best_detection
@@ -2583,7 +2584,8 @@ def update_occurrence_determination(
2583
2584
2584
2585
# Collect all necessary values first
2585
2586
best_identification = occurrence .get_best_identification ()
2586
- best_prediction = occurrence .get_best_prediction () if not best_identification else None
2587
+ best_prediction = occurrence .get_best_prediction ()
2588
+ best_ood_prediction = occurrence .get_best_ood_prediction ()
2587
2589
2588
2590
# Best detection is used as the representative image for the occurrence in either case
2589
2591
best_detection = occurrence .get_best_detection ()
@@ -2598,8 +2600,8 @@ def update_occurrence_determination(
2598
2600
new_determination = best_prediction .taxon
2599
2601
2600
2602
# Update scores, which may or may not come from the same source as the determination
2601
- new_determination_score = occurrence .get_determination_score ()
2602
- new_determination_ood_score = occurrence .get_determination_ood_score ()
2603
+ new_determination_score = occurrence .get_determination_score (prediction = best_prediction )
2604
+ new_determination_ood_score = occurrence .get_determination_ood_score (prediction = best_ood_prediction )
2603
2605
2604
2606
# Prepare fields that need to be updated (using a dictionary for bulk update)
2605
2607
update_fields = {}
0 commit comments