puda-drivers 0.0.10__tar.gz → 0.0.11__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. {puda_drivers-0.0.10 → puda_drivers-0.0.11}/PKG-INFO +3 -3
  2. {puda_drivers-0.0.10 → puda_drivers-0.0.11}/README.md +2 -2
  3. {puda_drivers-0.0.10 → puda_drivers-0.0.11}/pyproject.toml +1 -1
  4. {puda_drivers-0.0.10 → puda_drivers-0.0.11}/src/puda_drivers/labware/polyelectric_8_wellplate_30000ul.json +1 -1
  5. {puda_drivers-0.0.10 → puda_drivers-0.0.11}/src/puda_drivers/labware/trash_bin.json +1 -1
  6. {puda_drivers-0.0.10 → puda_drivers-0.0.11}/src/puda_drivers/machines/first.py +59 -8
  7. {puda_drivers-0.0.10 → puda_drivers-0.0.11}/tests/first.py +2 -2
  8. {puda_drivers-0.0.10 → puda_drivers-0.0.11}/uv.lock +1 -1
  9. {puda_drivers-0.0.10 → puda_drivers-0.0.11}/.gitignore +0 -0
  10. {puda_drivers-0.0.10 → puda_drivers-0.0.11}/LICENSE +0 -0
  11. {puda_drivers-0.0.10 → puda_drivers-0.0.11}/src/puda_drivers/__init__.py +0 -0
  12. {puda_drivers-0.0.10 → puda_drivers-0.0.11}/src/puda_drivers/core/__init__.py +0 -0
  13. {puda_drivers-0.0.10 → puda_drivers-0.0.11}/src/puda_drivers/core/logging.py +0 -0
  14. {puda_drivers-0.0.10 → puda_drivers-0.0.11}/src/puda_drivers/core/position.py +0 -0
  15. {puda_drivers-0.0.10 → puda_drivers-0.0.11}/src/puda_drivers/core/serialcontroller.py +0 -0
  16. {puda_drivers-0.0.10 → puda_drivers-0.0.11}/src/puda_drivers/cv/__init__.py +0 -0
  17. {puda_drivers-0.0.10 → puda_drivers-0.0.11}/src/puda_drivers/cv/camera.py +0 -0
  18. {puda_drivers-0.0.10 → puda_drivers-0.0.11}/src/puda_drivers/labware/__init__.py +0 -0
  19. {puda_drivers-0.0.10 → puda_drivers-0.0.11}/src/puda_drivers/labware/labware.py +0 -0
  20. {puda_drivers-0.0.10 → puda_drivers-0.0.11}/src/puda_drivers/labware/opentrons_96_tiprack_300ul.json +0 -0
  21. {puda_drivers-0.0.10 → puda_drivers-0.0.11}/src/puda_drivers/machines/__init__.py +0 -0
  22. {puda_drivers-0.0.10 → puda_drivers-0.0.11}/src/puda_drivers/move/__init__.py +0 -0
  23. {puda_drivers-0.0.10 → puda_drivers-0.0.11}/src/puda_drivers/move/deck.py +0 -0
  24. {puda_drivers-0.0.10 → puda_drivers-0.0.11}/src/puda_drivers/move/gcode.py +0 -0
  25. {puda_drivers-0.0.10 → puda_drivers-0.0.11}/src/puda_drivers/move/grbl/__init__.py +0 -0
  26. {puda_drivers-0.0.10 → puda_drivers-0.0.11}/src/puda_drivers/move/grbl/api.py +0 -0
  27. {puda_drivers-0.0.10 → puda_drivers-0.0.11}/src/puda_drivers/move/grbl/constants.py +0 -0
  28. {puda_drivers-0.0.10 → puda_drivers-0.0.11}/src/puda_drivers/py.typed +0 -0
  29. {puda_drivers-0.0.10 → puda_drivers-0.0.11}/src/puda_drivers/transfer/liquid/sartorius/__init__.py +0 -0
  30. {puda_drivers-0.0.10 → puda_drivers-0.0.11}/src/puda_drivers/transfer/liquid/sartorius/api.py +0 -0
  31. {puda_drivers-0.0.10 → puda_drivers-0.0.11}/src/puda_drivers/transfer/liquid/sartorius/constants.py +0 -0
  32. {puda_drivers-0.0.10 → puda_drivers-0.0.11}/src/puda_drivers/transfer/liquid/sartorius/sartorius.py +0 -0
  33. {puda_drivers-0.0.10 → puda_drivers-0.0.11}/tests/example.py +0 -0
  34. {puda_drivers-0.0.10 → puda_drivers-0.0.11}/tests/pipette.py +0 -0
  35. {puda_drivers-0.0.10 → puda_drivers-0.0.11}/tests/qubot.py +0 -0
  36. {puda_drivers-0.0.10 → puda_drivers-0.0.11}/tests/webcam.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: puda-drivers
3
- Version: 0.0.10
3
+ Version: 0.0.11
4
4
  Summary: Hardware drivers for the PUDA platform.
5
5
  Project-URL: Homepage, https://github.com/zhao-bears/puda-drivers
6
6
  Project-URL: Issues, https://github.com/zhao-bears/puda-drivers/issues
@@ -123,8 +123,8 @@ machine.camera.start_video_recording()
123
123
 
124
124
  # Perform liquid handling operations
125
125
  machine.attach_tip(slot="A3", well="G8")
126
- machine.aspirate_from(slot="C2", well="A1", amount=100)
127
- machine.dispense_to(slot="C2", well="B4", amount=100)
126
+ machine.aspirate_from(slot="C2", well="A1", amount=100, height_from_bottom=10.0)
127
+ machine.dispense_to(slot="C2", well="B4", amount=100, height_from_bottom=30.0)
128
128
  machine.drop_tip(slot="C1", well="A1")
129
129
 
130
130
  # Stop video recording
@@ -102,8 +102,8 @@ machine.camera.start_video_recording()
102
102
 
103
103
  # Perform liquid handling operations
104
104
  machine.attach_tip(slot="A3", well="G8")
105
- machine.aspirate_from(slot="C2", well="A1", amount=100)
106
- machine.dispense_to(slot="C2", well="B4", amount=100)
105
+ machine.aspirate_from(slot="C2", well="A1", amount=100, height_from_bottom=10.0)
106
+ machine.dispense_to(slot="C2", well="B4", amount=100, height_from_bottom=30.0)
107
107
  machine.drop_tip(slot="C1", well="A1")
108
108
 
109
109
  # Stop video recording
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "puda-drivers"
3
- version = "0.0.10"
3
+ version = "0.0.11"
4
4
  description = "Hardware drivers for the PUDA platform."
5
5
  readme = "README.md"
6
6
  authors = [
@@ -30,7 +30,7 @@
30
30
  "dimensions": {
31
31
  "xDimension": 128,
32
32
  "yDimension": 85.5,
33
- "zDimension": 74
33
+ "zDimension": 54
34
34
  },
35
35
  "wells": {
36
36
  "A1": {
@@ -11,7 +11,7 @@
11
11
  "dimensions": {
12
12
  "xDimension": 127.76,
13
13
  "yDimension": 85.48,
14
- "zDimension": 20
14
+ "zDimension": 0
15
15
  },
16
16
  "wells": {
17
17
  "A1": {
@@ -185,14 +185,30 @@ class First:
185
185
  self.qubot.home(axis="Z")
186
186
  self._logger.debug("Z axis homed after tip attachment")
187
187
 
188
- def drop_tip(self, slot: str, well: str):
189
- """Drop a tip into a slot."""
188
+ def drop_tip(self, slot: str, well: str, height_from_bottom: float = 0.0):
189
+ """
190
+ Drop a tip into a slot.
191
+
192
+ Args:
193
+ slot: Slot name (e.g., 'A1', 'B2')
194
+ well: Well name within the slot (e.g., 'A1' for a well in a tiprack)
195
+ height_from_bottom: Height from the bottom of the well in mm. Defaults to 0.0.
196
+ Positive values move up from the bottom. Negative values
197
+ may cause a ValueError if the resulting position is outside
198
+ the Z axis limits.
199
+
200
+ Raises:
201
+ ValueError: If no tip is attached, or if the resulting position is outside
202
+ the Z axis limits.
203
+ """
190
204
  if not self.pipette.is_tip_attached():
191
205
  self._logger.error("Cannot drop tip: no tip attached")
192
206
  raise ValueError("Tip not attached")
193
207
 
194
208
  self._logger.info("Dropping tip into slot '%s', well '%s'", slot, well)
195
209
  pos = self.get_absolute_z_position(slot, well)
210
+ # add height from bottom
211
+ pos += Position(z=height_from_bottom)
196
212
  # move up by the tip length
197
213
  pos += Position(z=self.TIP_LENGTH)
198
214
  self._logger.debug("Moving to position %s (adjusted for tip length) for tip drop", pos)
@@ -204,31 +220,67 @@ class First:
204
220
  self.pipette.set_tip_attached(attached=False)
205
221
  self._logger.info("Tip dropped successfully")
206
222
 
207
- def aspirate_from(self, slot:str, well:str, amount:int):
208
- """Aspirate a volume of liquid from a slot."""
223
+ def aspirate_from(self, slot:str, well:str, amount:int, height_from_bottom: float = 0.0):
224
+ """
225
+ Aspirate a volume of liquid from a slot.
226
+
227
+ Args:
228
+ slot: Slot name (e.g., 'A1', 'B2')
229
+ well: Well name within the slot (e.g., 'A1')
230
+ amount: Volume to aspirate in µL
231
+ height_from_bottom: Height from the bottom of the well in mm. Defaults to 0.0.
232
+ Positive values move up from the bottom. Negative values
233
+ may cause a ValueError if the resulting position is outside
234
+ the Z axis limits.
235
+
236
+ Raises:
237
+ ValueError: If no tip is attached, or if the resulting position is outside
238
+ the Z axis limits.
239
+ """
209
240
  if not self.pipette.is_tip_attached():
210
241
  self._logger.error("Cannot aspirate: no tip attached")
211
242
  raise ValueError("Tip not attached")
212
243
 
213
244
  self._logger.info("Aspirating %d µL from slot '%s', well '%s'", amount, slot, well)
214
245
  pos = self.get_absolute_z_position(slot, well)
246
+ # add height from bottom
247
+ pos += Position(z=height_from_bottom)
215
248
  self._logger.debug("Moving Z axis to position %s", pos)
216
249
  self.qubot.move_absolute(position=pos)
250
+
217
251
  self._logger.debug("Aspirating %d µL", amount)
218
252
  self.pipette.aspirate(amount=amount)
219
253
  time.sleep(5)
220
254
  self._logger.info("Aspiration completed: %d µL from slot '%s', well '%s'", amount, slot, well)
221
255
 
222
- def dispense_to(self, slot:str, well:str, amount:int):
223
- """Dispense a volume of liquid to a slot."""
256
+ def dispense_to(self, slot:str, well:str, amount:int, height_from_bottom: float = 0.0):
257
+ """
258
+ Dispense a volume of liquid to a slot.
259
+
260
+ Args:
261
+ slot: Slot name (e.g., 'A1', 'B2')
262
+ well: Well name within the slot (e.g., 'A1')
263
+ amount: Volume to dispense in µL
264
+ height_from_bottom: Height from the bottom of the well in mm. Defaults to 0.0.
265
+ Positive values move up from the bottom. Negative values
266
+ may cause a ValueError if the resulting position is outside
267
+ the Z axis limits.
268
+
269
+ Raises:
270
+ ValueError: If no tip is attached, or if the resulting position is outside
271
+ the Z axis limits.
272
+ """
224
273
  if not self.pipette.is_tip_attached():
225
274
  self._logger.error("Cannot dispense: no tip attached")
226
275
  raise ValueError("Tip not attached")
227
276
 
228
277
  self._logger.info("Dispensing %d µL to slot '%s', well '%s'", amount, slot, well)
229
278
  pos = self.get_absolute_z_position(slot, well)
279
+ # add height from bottom
280
+ pos += Position(z=height_from_bottom)
230
281
  self._logger.debug("Moving Z axis to position %s", pos)
231
282
  self.qubot.move_absolute(position=pos)
283
+
232
284
  self._logger.debug("Dispensing %d µL", amount)
233
285
  self.pipette.dispense(amount=amount)
234
286
  time.sleep(5)
@@ -275,8 +327,7 @@ class First:
275
327
  # the deck is rotated 90 degrees clockwise for this machine
276
328
  pos += well_pos.swap_xy()
277
329
  # get z
278
- z = Position(z=self.deck[slot].get_height() - self.CEILING_HEIGHT)
279
- pos += z
330
+ pos += Position(z=self.deck[slot].get_height() - self.CEILING_HEIGHT)
280
331
  self._logger.debug("Absolute Z position for slot '%s', well '%s': %s", slot, well, pos)
281
332
  else:
282
333
  self._logger.debug("Absolute Z position for slot '%s': %s", slot, pos)
@@ -40,8 +40,8 @@ if __name__ == "__main__":
40
40
 
41
41
  machine.camera.start_video_recording()
42
42
  machine.attach_tip(slot="A3", well="G8")
43
- machine.aspirate_from(slot="C2", well="A1", amount=100)
44
- machine.dispense_to(slot="C2", well="B4", amount=100)
43
+ machine.aspirate_from(slot="C2", well="A1", amount=100, height_from_bottom=10)
44
+ machine.dispense_to(slot="C2", well="B4", amount=100, height_from_bottom=50)
45
45
  machine.drop_tip(slot="C1", well="A1")
46
46
 
47
47
  # tiprack_wells = machine.deck["A3"].wells
@@ -186,7 +186,7 @@ wheels = [
186
186
 
187
187
  [[package]]
188
188
  name = "puda-drivers"
189
- version = "0.0.10"
189
+ version = "0.0.11"
190
190
  source = { editable = "." }
191
191
  dependencies = [
192
192
  { name = "opencv-python" },
File without changes
File without changes