NaseefNazrul commited on
Commit
0e40918
·
verified ·
1 Parent(s): f0b20e0

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +56 -23
app.py CHANGED
@@ -853,36 +853,69 @@ async def predict_bloom(req: BloomPredictionRequest):
853
 
854
  # Decide status based on peak_score and bell shape
855
  bell_ok, bell_diag = is_bell_shaped(list(monthly_perc))
856
- if peak_score < MIN_PEAK_FOR_BELL or not bell_ok or ambiguous:
 
 
 
 
 
 
 
 
 
857
  status = "NO_BLOOM"
858
  top_species = None
859
  bloom_window = None
860
  peak_month_out = None
861
  peak_prob_out = None
862
- elif peak_score < MIN_BLOOM_THRESHOLD:
863
- status = "LOW_CONFIDENCE"
864
- top_species = None
865
- bloom_window = [i+1 for i, p in enumerate(monthly_scores) if p > (MIN_BLOOM_THRESHOLD * 0.5)]
866
- peak_month_out = peak_month
867
- peak_prob_out = peak_score
868
  else:
869
- status = "BLOOM_DETECTED"
870
- bloom_window = [i+1 for i, p in enumerate(monthly_scores) if p > MIN_BLOOM_THRESHOLD]
871
- peak_month_out = peak_month
872
- peak_prob_out = peak_score
873
-
874
- # species prediction when strong bloom signal
875
- try:
876
- peak_result = monthly_results[peak_idx]
877
- if isinstance(peak_result, dict):
878
- doy = peak_result.get("day_of_year")
879
- else:
880
- doy = date(year, peak_month, 15).timetuple().tm_yday
881
- species_predictions = predict_species_by_elevation(elevation, doy=doy, top_k=TOP_K_SPECIES)
882
- top_species = [SpeciesResult(name=sp, probability=round(prob * 100.0, 2)) for sp, prob in species_predictions]
883
- except Exception as e:
884
- print("❌ species prediction error at final stage:", e)
 
 
 
885
  top_species = None
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
886
 
887
  processing_time = round(time.time() - start_time, 2)
888
 
 
853
 
854
  # Decide status based on peak_score and bell shape
855
  bell_ok, bell_diag = is_bell_shaped(list(monthly_perc))
856
+ mean_score = float(np.mean(monthly_scores))
857
+ median_score = float(np.median(monthly_scores))
858
+ near_peak_count = sum(1 for s in monthly_scores if s >= (peak_score * 0.9))
859
+ months_above_threshold = sum(1 for s in monthly_scores if s >= MIN_BLOOM_THRESHOLD)
860
+
861
+ print(f"DEBUG detection: peak_score={peak_score}, mean={mean_score:.2f}, median={median_score:.2f}, near_peak_count={near_peak_count}, months_above_{MIN_BLOOM_THRESHOLD}={months_above_threshold}, bell_ok={bell_ok}, bell_diag={bell_diag}")
862
+
863
+ # Heuristic decision:
864
+ # 1) If the absolute peak is below MIN_PEAK_FOR_BELL -> NO_BLOOM
865
+ if peak_score < MIN_PEAK_FOR_BELL:
866
  status = "NO_BLOOM"
867
  top_species = None
868
  bloom_window = None
869
  peak_month_out = None
870
  peak_prob_out = None
 
 
 
 
 
 
871
  else:
872
+ # 2) If peak is high enough, accept bloom even if not perfectly bell-shaped,
873
+ # unless the season is extremely ambiguous (many months nearly at peak).
874
+ # Use a dominance ratio: peak relative to mean/median.
875
+ dominance_ratio = (peak_score / (mean_score + 1e-9))
876
+ # Criteria to accept bloom:
877
+ accept_bloom = False
878
+ # a) clear bell-shaped + peak high -> accept
879
+ if bell_ok:
880
+ accept_bloom = True
881
+ # b) peak strongly dominates the rest -> accept
882
+ elif dominance_ratio >= 1.25 and near_peak_count <= 4:
883
+ accept_bloom = True
884
+ # c) several months above bloom threshold (broad season) but peak high -> accept but mark low confidence
885
+ elif months_above_threshold >= 3 and peak_score >= (MIN_BLOOM_THRESHOLD + 10):
886
+ accept_bloom = True
887
+
888
+ if not accept_bloom:
889
+ # Ambiguous/flat high-months case -> LOW_CONFIDENCE
890
+ status = "LOW_CONFIDENCE"
891
  top_species = None
892
+ bloom_window = [i+1 for i, s in enumerate(monthly_scores) if s > (MIN_BLOOM_THRESHOLD * 0.5)]
893
+ peak_month_out = peak_month
894
+ peak_prob_out = peak_score
895
+ else:
896
+ # Strong enough to declare bloom
897
+ # If the peak is only moderately high, use LOW_CONFIDENCE; otherwise BLOOM_DETECTED
898
+ if peak_score < (MIN_BLOOM_THRESHOLD + 5):
899
+ status = "LOW_CONFIDENCE"
900
+ else:
901
+ status = "BLOOM_DETECTED"
902
+
903
+ bloom_window = [i+1 for i, p in enumerate(monthly_scores) if p > MIN_BLOOM_THRESHOLD]
904
+ peak_month_out = peak_month
905
+ peak_prob_out = peak_score
906
+
907
+ # species prediction when we accept bloom
908
+ try:
909
+ peak_result = monthly_results[peak_idx]
910
+ if isinstance(peak_result, dict):
911
+ doy = peak_result.get("day_of_year")
912
+ else:
913
+ doy = date(year, peak_month, 15).timetuple().tm_yday
914
+ species_predictions = predict_species_by_elevation(elevation, doy=doy, top_k=TOP_K_SPECIES)
915
+ top_species = [SpeciesResult(name=sp, probability=round(prob * 100.0, 2)) for sp, prob in species_predictions]
916
+ except Exception as e:
917
+ print(f"❌ species prediction error at final stage: {e}")
918
+ top_species = None
919
 
920
  processing_time = round(time.time() - start_time, 2)
921