Coverage for pybeepop/beepop/spores.py: 51%
53 statements
« prev ^ index » next coverage.py v7.11.0, created at 2025-10-30 13:34 +0000
« prev ^ index » next coverage.py v7.11.0, created at 2025-10-30 13:34 +0000
1"""
2Spores Module for BeePop+ Biocontrol Simulation
4Not yet implemented
6Classes:
7 Spores: Biocontrol agent spore dynamics and efficacy modeling
8"""
11class Spores:
12 """
13 Biocontrol spore dynamics and treatment efficacy model for BeePop+ simulation.
15 Models the vitality degradation and treatment efficacy of biological control
16 spores over time. Implements William Meikle's research-based spore survival
17 data and mortality functions for accurate biocontrol agent modeling in
18 honey bee colonies.
20 Not yet implemented
22 Note:
23 Vitality data based on William Meikle's email of May 23, 2005. May transition
24 to polynomial functions as additional research data becomes available.
25 """
27 class IntDoub:
28 def __init__(self, int_val=0, doub_val=0.0):
29 self.int_val = int_val
30 self.doub_val = doub_val
32 def __init__(self):
33 # The Spore Vitality Data is from William Meikle's email of May 23, 2005.
34 # The Vitality is the percentage of live spores left after a number of days
35 # The DayPoints are the days after application that the vitality was measured.
36 # Most likely will change to a polynomial function
37 self.m_InitialSporeCount = 0
38 self.m_SporeVitalityMatrix = [self.IntDoub() for _ in range(10)]
39 self.m_MortalityFunctionPts = [self.IntDoub() for _ in range(10)]
40 self.m_SporeVitalityMatrix[0].doub_val = 1.0 # Sample Values
41 self.m_SporeVitalityMatrix[1].doub_val = 0.16
42 self.m_SporeVitalityMatrix[2].doub_val = 0.26
43 self.m_SporeVitalityMatrix[3].doub_val = 0.13
44 self.m_SporeVitalityMatrix[4].doub_val = 0.01
45 self.m_SporeVitalityMatrix[5].doub_val = 0.003
46 self.m_SporeVitalityMatrix[0].int_val = 1 # Sample Days
47 self.m_SporeVitalityMatrix[1].int_val = 3
48 self.m_SporeVitalityMatrix[2].int_val = 6
49 self.m_SporeVitalityMatrix[3].int_val = 13
50 self.m_SporeVitalityMatrix[4].int_val = 20
51 self.m_SporeVitalityMatrix[5].int_val = 42
52 self.m_SporeVitalityPtCount = 6
53 self.m_MortFunctPtCount = 0
55 def set_mortality_function(self, percent_mortality, spore_density, index):
56 """
57 Sets the Varroa mortality rate as a function of spore density.
58 For now, this will be set from the CAction dialog and will simply consist
59 of pairs of proportion of mortality and spore density (spores per mite).
60 This may ultimately become a polynomial function once we have data.
61 """
62 self.m_MortalityFunctionPts[index].doub_val = percent_mortality
63 self.m_MortalityFunctionPts[index].int_val = spore_density
64 self.m_MortFunctPtCount += 1
66 def get_day_mortality_rate(self, treatment_day_number):
67 """
68 The mortality rate for a specific day after treatment begins is a function
69 of the Mortality Rate vs Spore Density and the Degradation of spores over time.
70 """
71 current_spores = int(
72 self.m_InitialSporeCount
73 * self._interpolation(
74 self.m_SporeVitalityMatrix,
75 self.m_SporeVitalityPtCount,
76 treatment_day_number,
77 )
78 )
79 mort_rate = self._interpolation(
80 self.m_MortalityFunctionPts, self.m_MortFunctPtCount, current_spores
81 )
82 return mort_rate
84 def _interpolation(self, id_array, array_size, int_var):
85 """
86 Performs a linear interpolation of an IntDoub array using int_var as the independent variable.
87 If the interpolation is not found, returns 0.
88 """
89 if array_size == 0:
90 return 0.0
91 if int_var >= id_array[array_size - 1].int_val:
92 return id_array[array_size - 1].doub_val
93 elif int_var <= id_array[0].int_val:
94 return id_array[0].doub_val
95 else:
96 for index in range(array_size - 1):
97 if id_array[index].int_val <= int_var <= id_array[index + 1].int_val:
98 # Linear interpolation
99 return (
100 (int_var - id_array[index].int_val)
101 / (id_array[index + 1].int_val - id_array[index].int_val)
102 ) * (
103 id_array[index + 1].doub_val - id_array[index].doub_val
104 ) + id_array[
105 index
106 ].doub_val
107 return 0.0
109 def _interpolation_doub(self, id_array, array_size, doub_val):
110 """
111 Performs a linear interpolation of an IntDoub array using doub_val as the independent variable.
112 If the interpolation is not found, returns 0.
113 """
114 if array_size == 0:
115 return 0
116 if doub_val >= id_array[array_size - 1].doub_val:
117 return id_array[array_size - 1].int_val
118 elif doub_val <= id_array[0].doub_val:
119 return id_array[0].int_val
120 else:
121 for index in range(array_size - 1):
122 if id_array[index].doub_val <= doub_val <= id_array[index + 1].doub_val:
123 # Linear interpolation
124 return int(
125 (
126 (doub_val - id_array[index].doub_val)
127 / (id_array[index + 1].doub_val - id_array[index].doub_val)
128 )
129 * (id_array[index + 1].int_val - id_array[index].int_val)
130 + id_array[index].int_val
131 )
132 return 0