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

1""" 

2Spores Module for BeePop+ Biocontrol Simulation 

3 

4Not yet implemented 

5 

6Classes: 

7 Spores: Biocontrol agent spore dynamics and efficacy modeling 

8""" 

9 

10 

11class Spores: 

12 """ 

13 Biocontrol spore dynamics and treatment efficacy model for BeePop+ simulation. 

14 

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. 

19 

20 Not yet implemented 

21 

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 """ 

26 

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 

31 

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 

54 

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 

65 

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 

83 

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 

108 

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