Skip to content

Commit ffbeea6

Browse files
committed
two more height functions
1 parent 8d0e5ff commit ffbeea6

File tree

1 file changed

+100
-18
lines changed

1 file changed

+100
-18
lines changed

pylabrobot/resources/height_functions.py

+100-18
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,26 @@
44
import math
55

66

7+
def _height_of_volume_in_spherical_cap(
8+
r: float,
9+
liquid_volume: float
10+
) -> float:
11+
def volume_of_spherical_cap(h: float):
12+
return (1/3) * math.pi * h**2 * (3*r - h)
13+
14+
# Binary search to solve for h
15+
low, high = 0.0, r
16+
tolerance = 1e-6
17+
while high - low > tolerance:
18+
mid = (low + high) / 2
19+
if volume_of_spherical_cap(mid) < liquid_volume:
20+
low = mid
21+
else:
22+
high = mid
23+
liquid_height = (low + high) / 2
24+
return liquid_height
25+
26+
727
def calculate_liquid_height_in_container_2segments_square_vbottom(
828
x: float,
929
y: float,
@@ -74,20 +94,7 @@ def calculate_liquid_height_in_container_2segments_square_ubottom(
7494

7595
if liquid_volume <= full_hemisphere_volume:
7696
# Liquid volume is within the hemisphere
77-
def volume_of_spherical_cap(h: float):
78-
return (1/3) * math.pi * h**2 * (3*r - h)
79-
80-
# Binary search to solve for h
81-
low, high = 0.0, r
82-
tolerance = 1e-6
83-
while high - low > tolerance:
84-
mid = (low + high) / 2
85-
if volume_of_spherical_cap(mid) < liquid_volume:
86-
low = mid
87-
else:
88-
high = mid
89-
liquid_height = (low + high) / 2
90-
97+
liquid_height = _height_of_volume_in_spherical_cap(r=r, liquid_volume=liquid_volume)
9198
else:
9299
# Liquid volume extends into the cuboid
93100
cuboid_liquid_volume = liquid_volume - full_hemisphere_volume
@@ -105,17 +112,92 @@ def calculate_liquid_height_in_container_2segments_round_vbottom(
105112
d: float,
106113
h_cone: float,
107114
h_cylinder: float,
108-
liquid_height: float
115+
liquid_volume: float
109116
) -> float:
110-
raise NotImplementedError()
117+
"""
118+
Calculate the height of liquid in a container consisting of an upside-down circular cone at the
119+
bottom and a cylinder on top. The container has the same diameter for both the cone and the
120+
cylinder. The function calculates the height based on the given liquid volume.
121+
122+
Parameters:
123+
d (float): The diameter of the base of the cone and cylinder in mm.
124+
h_cone (float): The height of the circular cone in mm.
125+
h_cylinder (float): The height of the cylinder in mm.
126+
liquid_volume (float): The volume of the liquid in the container in cubic millimeters.
127+
128+
Returns:
129+
float: The height of the liquid in the container in mm.
130+
"""
131+
132+
radius = d / 2
133+
base_area = math.pi * (radius ** 2)
134+
135+
# Calculating the full volume of the cone
136+
full_cone_volume = (1 / 3) * base_area * h_cone
137+
138+
# Calculate total container volume
139+
total_container_volume = full_cone_volume + (base_area * h_cylinder)
140+
141+
# Check for overflow
142+
if liquid_volume > total_container_volume:
143+
raise ValueError("WARNING: Liquid overflow detected; check your labware definition and/or that "
144+
"you are using the right labware.")
145+
146+
if liquid_volume <= full_cone_volume:
147+
# Liquid volume is within the cone
148+
scale_factor: float = (liquid_volume / full_cone_volume) ** (1 / 3)
149+
liquid_height = scale_factor * h_cone
150+
else:
151+
# Liquid volume extends into the cylinder
152+
cylinder_liquid_volume = liquid_volume - full_cone_volume
153+
cylinder_liquid_height = cylinder_liquid_volume / base_area
154+
liquid_height = h_cone + cylinder_liquid_height
155+
156+
return liquid_height
111157

112158

113159
def calculate_liquid_height_in_container_2segments_round_ubottom(
114160
d: float,
115161
h_cylinder: float,
116-
liquid_height: float
162+
liquid_volume: float
117163
) -> float:
118-
raise NotImplementedError()
164+
"""
165+
Calculate the height of liquid in a container consisting of a hemispherical bottom and a
166+
cylindrical top. The container has the same diameter for both the hemisphere and the cylinder. The
167+
function calculates the height based on the given liquid volume.
168+
169+
Parameters:
170+
d (float): The diameter of the base of the hemisphere and cylinder in mm.
171+
h_cylinder (float): The height of the cylinder in mm.
172+
liquid_volume (float): The volume of the liquid in the container in cubic millimeters.
173+
174+
Returns:
175+
float: The height of the liquid in the container in mm.
176+
"""
177+
178+
radius = d / 2
179+
hemisphere_volume = (2 / 3) * math.pi * (radius ** 3)
180+
base_area = math.pi * (radius ** 2)
181+
182+
# Calculate total container volume
183+
cylinder_volume = base_area * h_cylinder
184+
total_container_volume = hemisphere_volume + cylinder_volume
185+
186+
# Check for overflow
187+
if liquid_volume > total_container_volume:
188+
raise ValueError("WARNING: Liquid overflow detected; check your labware definition and/or that "
189+
"you are using the right labware.")
190+
191+
if liquid_volume <= hemisphere_volume:
192+
# Liquid volume is within the hemisphere
193+
liquid_height = _height_of_volume_in_spherical_cap(r=radius, liquid_volume=liquid_volume)
194+
else:
195+
# Liquid volume extends into the cylinder
196+
cylinder_liquid_volume = liquid_volume - hemisphere_volume
197+
cylinder_liquid_height = cylinder_liquid_volume / base_area
198+
liquid_height = radius + cylinder_liquid_height
199+
200+
return liquid_height
119201

120202

121203
def calculate_liquid_height_container_1segment_round_fbottom(

0 commit comments

Comments
 (0)