For the automatic creation and sync of .PPL files, used for pump programming
Project description
For the automatic creation and sync of .PPL files, used for pump programming
Created by me while under employment with the University of Toronto, as goverened by: University of Toronto Governing Council | Inventions Policy
Below is documentation created by Claude AI:
pumpz
A Python package for controlling syringe pumps using the PPL pump programming language.
Version: 0.2.1
Author: Faisal Shahbaz
Installation
>> pip install pumpz
import pumpz as pz
Core Classes
Masterppl
A class for managing multiple pumps through a master PPL file.
Constructor
Masterppl(file, adrs=[])
Parameters:
file: File object where PPL commands will be writtenadrs: List of pump addresses (optional)
Attributes
file: File object for writing PPL commandsadrs: List storing pump addresses
Methods
add(adr: int, ppl)
Add a pump configuration to the master file.
- Parameters:
adr: Integer address for the pumpppl: pump object containing the pump's configuration
- Returns: None
- Effect: Writes pump address and configuration to the master file
clearall()
Clear all pump configurations.
- Parameters: None
- Returns: None
- Effect: Writes clear commands for all registered pump addresses
beepall()
Trigger beep sound on all pumps.
- Parameters: None
- Returns: None
- Effect: Writes beep commands for all registered pump addresses
quickset(all: dict)
Quickly configure multiple pumps.
- Parameters:
all: Dictionary mapping pump addresses to their PPL configurations
- Returns: None
- Effect: Adds all pumps, clears their configurations, and triggers beep
Pump
A class representing an individual syringe pump.
Constructor
Pump(file, dia: float, rate_units: str = 'mm', vol_units: str = '', time: float = 0)
Parameters:
file: File object for PPL commandsdia: Syringe diameter (0.1-50.0 mm)rate_units: Flow rate units ('mm' for mL/min, 'um' for μL/min, 'mh' for mL/hr, 'uh' for μL/h)vol_units: Volume units ('mcL' or 'mL', auto-selected based on diameter if not specified)time: Initial time in seconds
Attributes
Core Attributes
file: File object for writing PPL commandsdia: Float storing syringe diametertime: Float tracking elapsed timerate_units: String storing current rate unitsvol_units: String storing volume units
State Tracking
loop: List tracking current loops__dir: String storing current direction ('inf' or 'wdr')__rat: Float storing current ratephase_name: String storing current phase namephase_num: Integer tracking current phase numberphase_ref: Dictionary mapping phase names to numberssync_is_useable: Boolean indicating if sync is available
Methods
Initialization and Configuration
init(*args)
Initialize pump(s) with default values.
- Parameters:
*args: Any number of pump objects
- Returns: None
- Effect: Sets diameter, alarm, buzzer, power failure mode
change_rate_units(rate_units: str)
Change the flow rate units.
- Parameters:
rate_units: New rate units ('mm', 'um', 'mh', 'uh')
- Returns: None
- Effect: Updates pump's rate units
label(label: str)
Label the next phase.
- Parameters:
label: String label for the phase
- Returns: The label string
- Effect: Sets phase_name for next phase
Flow Control
rate(rate: float, vol: float, dir: str)
Set flow rate, volume, and direction.
- Parameters:
rate: Flow rate in current rate unitsvol: Volume in current volume unitsdir: Direction ('inf' for infuse, 'wdr' for withdraw)
- Returns: None
- Effect: Configures pump flow and updates timing
pause(length: int, phases = 0)
Create pause in program execution.
- Parameters:
length: Duration in secondsphases: Internal counter for recursive calls
- Returns: Number of phases used
- Effect: Creates optimal pause sequence
Loop Control
loopstart(count: int)
Start a loop with specified count.
- Parameters:
count: Number of loop iterations
- Returns: None
- Effect: Begins a loop sequence (max 3 nested)
loopend()
End the current loop.
- Parameters: None
- Returns: None
- Effect: Closes current loop sequence
getloop()
Get current loop multiplication factor.
- Parameters: None
- Returns: Product of all active loop counts
- Effect: None
Program Flow Control
jump(phase: str)
Jump to specified phase.
- Parameters:
phase: Phase number or name
- Returns: None
- Effect: Creates jump instruction, disables sync
if_low(phase)
Conditional jump if input is low.
- Parameters:
phase: Target phase
- Returns: None
- Effect: Creates conditional jump, disables sync
event_trap(phase)
Set event trap to specified phase.
- Parameters:
phase: Target phase
- Returns: None
- Effect: Creates event trap, disables sync
event_trap_sq(phase)
Set sequential event trap.
- Parameters:
phase: Target phase
- Returns: None
- Effect: Creates sequential event trap, disables sync
event_reset()
Reset event trap.
- Parameters: None
- Returns: None
- Effect: Resets event trap state
Signal and Output Control
beep()
Trigger beep sound.
- Parameters: None
- Returns: None
- Effect: Triggers pump buzzer
trg(num: int)
Set trigger.
- Parameters:
num: Trigger number
- Returns: None
- Effect: Sets specified trigger
out(n)
Set output signal.
- Parameters:
n: Output value
- Returns: None
- Effect: Sets output signal state
Synchronization
stop(*args)
Stop pump operation.
- Parameters:
*args: Pump objects to stop
- Returns: None
- Effect: Stops specified pumps
sync(*args)
Synchronize multiple pump operations.
- Parameters:
*args: Pump objects to synchronize
- Returns: None
- Effect: Adds pauses to align pump timing
- Raises: Exception if sync is not useable
Utility Functions
decompose_dict(dict: dict)
Decompose a dictionary into a list of its factors.
- Parameters:
dict: Dictionary of factors and their counts
- Returns: List of individual factors
- Usage: Internal use for timing calculations
factor_check(initial_factor, attempt=0)
Check and optimize factors for timing calculations.
- Parameters:
initial_factor: Integer or list of factorsattempt: Recursion counter
- Returns: Tuple of optimized factors
- Usage: Internal use for pause optimization
Error Handling
Common Exceptions
-
Diameter Error
if self.dia < 0.1 or self.dia > 50.0: raise Exception('Diameter is invalid. Must be between 0.1 - 50.0 mm')
-
Loop Nesting Error
if len(self.loop) > 3: raise Exception("Up to three nested loops, you have too many")
-
Sync Compatibility Error
if arg.sync_is_useable == False: raise Exception(f'sync isn\'t useable with {arg}')
Examples
Basic Usage
# Create a simple infusion program
with open('pump1.ppl', 'w') as pump_file:
p1 = Pump(pump_file, dia=14.0, rate_units='mm')
p1.init()
p1.rate(1.0, 5.0, 'inf') # Infuse 5mL at 1mL/min
Multiple Pumps
# Control multiple pumps with synchronization
with open('master.ppl', 'w') as master_file:
master = Masterppl(master_file)
with open('pump1.ppl', 'w') as p1_file:
p1 = Pump(p1_file, dia=14.0)
p1.init()
p1.rate(1.0, 5.0, 'inf')
with open('pump2.ppl', 'w') as p2_file:
p2 = Pump(p2_file, dia=10.0)
p2.init()
p2.rate(0.5, 2.0, 'inf')
Pump.sync(p1, p2) # Synchronize pump operations
master.quickset({1: p1, 2: p2})
Complex Program
# Create a program with loops and events
with open('complex.ppl', 'w') as pump_file:
p = pump(pump_file, dia=14.0)
p.init()
p.label("start")
p.loopstart(5) # Repeat 5 times
p.rate(1.0, 1.0, 'inf')
p.pause(30)
p.rate(1.0, 1.0, 'wdr')
p.loopend()
p.event_trap("start") # Jump to start on event
p.beep() # Signal completion
Complete Working Example
This section demonstrates a complete example of controlling two pumps with synchronized operations.
Example Setup
import pumpz as pz
import math
# Create file handles for PPL output
f_aq = open("aq.ppl", "w")
f_org = open("org.ppl", "w")
f_master = open("master.ppl", "w")
# Initialize two pumps with identical configuration
aq = pz.Pump(f_aq, 26.59, "mm", "mL") # Pump for aqueous solution
org = pz.Pump(f_org, 26.59, "mm", "mL") # Pump for organic solution
# Create master controller and configure both pumps
master = pz.Masterppl(f_master)
master.quickset({0: org, 1: aq}) # Assign addresses 0 and 1
Program Flow
# Initialize both pumps with default settings
pz.Pump.init(aq, org)
# Initial withdrawal phase - both pumps
aq.rate(22, 20, "wdr")
org.rate(22, 20, "wdr")
# Aqueous pump infusion with delay
aq.rate(10, 20, "inf")
aq.pause(5 * 60) # 5 minute pause
pz.Pump.sync(aq, org) # Synchronize pumps
# Organic pump infusion with timing calculation
org.rate(10, 20, "inf")
t0 = math.ceil(org.time) # Store current time
org.pause(60) # 1 minute pause
pz.Pump.sync(aq, org)
# Withdrawal phase with calculated pause
aq.rate(22, 50, "wdr")
org.rate(22, 50, "wdr")
t1 = math.ceil(org.time)
pause_length = t0 + 500 - t1 # Calculate required pause
if pause_length < 0:
print("Error: timing is incompatible")
org.pause(pause_length)
pz.Pump.sync(aq, org)
# Repeated infusion/withdrawal cycle
aq.loopstart(2)
org.loopstart(2)
aq.rate(22, 50, "inf")
org.rate(22, 50, "inf")
aq.rate(22, 50, "wdr")
org.rate(22, 50, "wdr")
aq.loopend()
org.loopend()
# Final infusion
aq.rate(22, 50, "inf")
org.rate(22, 50, "inf")
# Stop
pz.Pump.stop(aq,org)
Generated Output Files
master.ppl
Set adr=0
call org.ppl
Set adr=1
call aq.ppl
0cldinf
0cldwdr
0dis
1cldinf
1cldwdr
1dis
0buz13
1buz13
aq.ppl (Pump 1)
dia 26.6
al 1
bp 1
PF 0
phase
fun rat
rat 22 mm
vol 20
dir wdr
phase
fun rat
rat 10 mm
vol 20
dir inf
phase
fun lps
phase
fun pas 60
phase
fun lop 5
phase
fun pas 99
phase
fun pas 81
phase
fun rat
rat 22 mm
vol 50
dir wdr
phase
fun lps
phase
fun pas 5
phase
fun lop 61
phase
fun lps
phase
fun rat
rat 22 mm
vol 50
dir inf
phase
fun rat
rat 22 mm
vol 50
dir wdr
phase
fun lop 2
phase
fun rat
rat 22 mm
vol 50
dir inf
phase
fun stp
org.ppl (Pump 0)
dia 26.6
al 1
bp 1
PF 0
phase
fun rat
rat 22 mm
vol 20
dir wdr
phase
fun lps
phase
fun pas 60
phase
fun lop 7
phase
fun rat
rat 10 mm
vol 20
dir inf
phase
fun pas 60
phase
fun rat
rat 22 mm
vol 50
dir wdr
phase
fun lps
phase
fun pas 16
phase
fun lop 19
phase
fun lps
phase
fun rat
rat 22 mm
vol 50
dir inf
phase
fun rat
rat 22 mm
vol 50
dir wdr
phase
fun lop 2
phase
fun rat
rat 22 mm
vol 50
dir inf
phase
fun stp
Key Features Demonstrated
-
Pump Synchronization
- Both pumps are initialized with identical configurations
- Operations are synchronized using
pump.sync() - Timing calculations ensure proper coordination
-
Complex Flow Control
- Multiple rate changes
- Withdrawal and infusion operations
- Nested loops for repeated operations
- Calculated pauses for timing alignment
-
Master Control
- Multiple pump management through master PPL file
- Address assignment and initialization
- Coordinated start/stop operations
-
Timing Management
- Use of mathematical calculations for pause lengths
- Error checking for timing compatibility
- Synchronized operations across multiple pumps
Usage Notes
- The example uses two identical pumps with 26.59mm diameter syringes
- Flow rates are specified in mL/min (mm units)
- Volumes are specified in mL
- The program includes error checking for timing compatibility
- The master PPL file coordinates both pumps through address assignments 0 and 1
This example demonstrates many of the package's key features including:
- Multi-pump coordination
- Complex timing calculations
- Loop operations
- Rate control
- Direction control
- Error checking
- Master/slave configuration
Credits
All code is original by me, Faisal Shahbaz, except where edited by Claude AI
Documentation was written by Claude AI and edited by me
masterppl class based on the default master PPL file format by Tim Burgess, SyringePumpPro (https://SyringePumpPro.com)
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pumpz-0.2.1.tar.gz.
File metadata
- Download URL: pumpz-0.2.1.tar.gz
- Upload date:
- Size: 17.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.0.1 CPython/3.11.1
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d02ed7619473b682aa3db6045423d64287049b36b78a0193a77173e5d95ab99c
|
|
| MD5 |
3c7d0936023f923d16f5d0a64fd2f71f
|
|
| BLAKE2b-256 |
b8a763ac680132513b836b81018068ff37c9087b36413dbbb0a88004e7ea170a
|
File details
Details for the file pumpz-0.2.1-py3-none-any.whl.
File metadata
- Download URL: pumpz-0.2.1-py3-none-any.whl
- Upload date:
- Size: 16.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.0.1 CPython/3.11.1
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1f4e3dc999aa14af64cd08c8e1f61339719f30d9426e93935e9005fe7b10e5a7
|
|
| MD5 |
da8965b3ea1cece9ccc713cc1a5c50db
|
|
| BLAKE2b-256 |
11922fde881bdaa4182fadd6b898282426ec651462cfe2fad5c1183b928b0811
|