Sucker Rod Design Library
Project description
libzrod
Sucker Rod Design Library (Wave Equation / Gibbs / Everitt-Jennings)
A wave equation library for sucker rod pump design and analysis, written in C/C++ and wrapped in Python.
Overview
libzrod solves the 1D damped wave equation to calculate dynamometer cards for both diagnostic (measured card in, pump card out) and predictive (parameters in, surface + pump cards out) analysis of sucker rod pumping systems. The core engine is cross-platform C++, exposed to Python via ctypes.
Key capabilities:
- Diagnostic analysis: transform a measured surface dynamometer card into a downhole pump card
- Predictive analysis: generate surface and pump cards from well parameters (rod string, pump, fluid, geometry)
- Rod loading analysis: max/min stress per rod section with Modified Goodman limits
- Pump velocity and chamber pressure visualization
- Multi-format file I/O (.dyn, .rsdx/.rsvx, .inp6/.inp6e, .qrd, .zrod, .DAT)
- Cloud design management (save, fetch, share via AWS)
Installation
pip install libzrod
Requirements: Python 3.9 - 3.13, numpy. Supported platforms: Windows (x86_64), macOS (x86_64/ARM), Linux (x86_64).
Authorization
An account is required to use the library:
- Create an account at zrod.io
- Email for manual authorization of your trial account (account creation is not monitored)
- Note: The beta library includes time restrictions
Or see the Colab Example for a quick demo.
Quick Start
This self-contained example runs a full diagnostic + predictive analysis using inline card data (no external files needed). Save it as test_libzrod.py and run with python test_libzrod.py.
import libzrod
from libzrod import zrod, TaperBase_t, TubingBase_t, WaveParams_t, PuApi_t
# ── Create engine and login ──────────────────────────────────────────
myzrod = zrod()
print(f"libzrod library version: v{myzrod.GetZrodVersionString()}")
print(f"libzrod package version: v{libzrod.__version__}")
if(not myzrod.Login("demo", "password1")):
print("Login failed!")
exit(1)
print("Login OK\n")
result = myzrod.SetUpscaledDynoPointCount(4000) #this is for the smoothed/curve-fitted measured surface card
result = myzrod.SetFourierCoeffCountPos(23) #these are for the curve fitting of a measured dyno card
result = myzrod.SetFourierCoeffCountLoad(50)
# ── Well parameters ──────────────────────────────────────────────────
waveParams = myzrod.GetWaveParams()
waveParams.WellDepth = 5900
waveParams.diagSpm = 8.0
waveParams.predSpm = 8.0
waveParams.diagDampUp = 0.2
waveParams.diagDampDn = 0.2
waveParams.predDampUp = 0.2
waveParams.predDampDn = 0.2
waveParams.diagPumpPlungerDiameter = 1.5
waveParams.predPumpPlungerDiameter = 1.5
waveParams.predFluidSG = 1.0
waveParams.predFluidLevel = 2000
waveParams.predCasingPressure = 93
waveParams.predTubingPressure = 200.2
waveParams.predFo = 4000
waveParams.usePumpingUnitForPosition = True
myzrod.SetWaveParams(waveParams)
# ── Rod string (3 tapers) ───────────────────────────────────────────
tarr = (TaperBase_t * 3)()
tarr[0] = TaperBase_t(id=b"", L=3200, D=0.875, W=2.224, E=30500000, R=492)
tarr[1] = TaperBase_t(id=b"", L=2400, D=0.750, W=1.630, E=30500000, R=492)
tarr[2] = TaperBase_t(id=b"", L= 300, D=1.500, W=6.500, E=30500000, R=492)
myzrod.xSetDiagTapers(tarr, 1.0)
myzrod.xSetPredTapers(tarr, 1.0)
# ── Tubing ───────────────────────────────────────────────────────────
tuarr = (TubingBase_t * 1)()
tuarr[0] = TubingBase_t(L=5900, innerDiameter=2.441, outerDiameter=2.875,
weight=6.5, W=2.904, E=30500000, R=490)
myzrod.xSetDiagTubings(tuarr)
myzrod.xSetPredTubings(tuarr)
# ── Pumping unit geometry ────────────────────────────────────────────
puapi = PuApi_t()
puapi.Type = ord("C")
puapi.Rotate = 1
puapi.A = 158.375
puapi.P = 122.499992
puapi.C = 100
puapi.I = 110
puapi.K = 164.639999
puapi.R = 43
puapi.CBE = 450.0
puapi.Torque = 456000
puapi.Structure = 21300
puapi.MaxStroke = 144.0
puapi.S = 144.0
myzrod.SetPuApi(puapi)
# ── Load a measured surface card (inline data) ───────────────────────
surface_x = [
687.0, 642.2, 596.5, 550.4, 504.4, 459.0, 414.3, 370.5, 327.7, 286.1,
246.0, 207.9, 172.2, 139.0, 108.5, 80.8, 56.0, 34.8, 17.8, 5.9,
0.1, 0.4, 6.8, 18.5, 34.4, 53.9, 76.1, 100.9, 128.2, 157.8,
189.8, 223.8, 259.7, 297.3, 336.5, 377.1, 419.1, 462.2, 506.4, 551.2,
596.6, 642.4, 688.4, 734.5, 780.5, 826.4, 872.0, 917.0, 961.2, 1004.4,
1046.5, 1087.3, 1126.5, 1164.2, 1200.0, 1233.8, 1265.4, 1294.8, 1321.6, 1345.9,
1367.7, 1386.8, 1403.4, 1417.4, 1428.9, 1437.8, 1444.2, 1448.2, 1449.9, 1449.4,
1446.7, 1442.0, 1435.3, 1426.7, 1416.3, 1404.2, 1390.4, 1375.1, 1358.2, 1339.7,
1319.8, 1298.5, 1275.8, 1251.7, 1226.1, 1199.2, 1170.9, 1141.2, 1110.2, 1077.9,
1044.1, 1009.0, 972.5, 934.7, 895.8, 855.9, 815.1, 773.5, 730.8, 687.0,
]
surface_x = [x / 10.0 for x in surface_x] # convert to inches
surface_y = [
10583, 10409, 10157, 9891, 9681, 9575, 9576, 9653, 9778, 9956,
10230, 10641, 11186, 11799, 12374, 12827, 13139, 13359, 13555, 13756,
13927, 14009, 13982, 13917, 13957, 14243, 14815, 15585, 16380, 17054,
17575, 18039, 18592, 19305, 20096, 20749, 21024, 20791, 20107, 19183,
18275, 17545, 17007, 16557, 16076, 15529, 15001, 14650, 14606, 14884,
15369, 15875, 16241, 16412, 16447, 16456, 16517, 16613, 16642, 16488,
16099, 15538, 14952, 14494, 14242, 14160, 14143, 14084, 13945, 13766,
13615, 13522, 13446, 13295, 12996, 12547, 12030, 11557, 11196, 10923,
10643, 10250, 9700, 9046, 8409, 7918, 7651, 7615, 7766, 8045,
8402, 8802, 9219, 9619, 9975, 10265, 10479, 10612, 10651, 10583,
]
myzrod.LoadDyn(8.1, surface_x, surface_y)
# ── Validate before running ──────────────────────────────────────────
issues = myzrod.ValidateDesign()
if(issues):
print("Validation issues:")
for issue in issues:
severity = "WARN" if(issue["severity"] == 1) else "ERROR"
print(f" [{severity}] {issue['code']}: {issue['message']}")
print()
# ── Run the wave equation solver ─────────────────────────────────────
print("Running design...")
if(not myzrod.RunDesign()):
print("RunDesign() FAILED")
exit(1)
print("RunDesign() OK\n")
# ── Fetch results ────────────────────────────────────────────────────
results = myzrod.GetWaveResults()
print("=== Diagnostic Results ===")
print(f" Rod weight in air: {results.diag.Rwa:.0f} lbs")
print(f" Rod weight in fluid: {results.diag.Rwf:.0f} lbs")
print(f" Fo (SKr): {results.diag.FoSKr:.0f} lbs")
print(f" Kr: {results.diag.Kr:.1f} lb/in")
print(f" N/No: {results.diag.NNo:.3f}")
print(f" Stroke length: {results.diag.SL:.2f} in")
print(f" Pump stroke (net): {results.diag.PumpStrokeNet:.2f} in")
print(f" Production (100%): {results.diag.BblPerDay100:.1f} bbl/day")
print(f" Solver time: {results.LastExecutionTimeMs} ms")
print()
print("=== Predictive Results ===")
print(f" Rod weight in air: {results.pred.Rwa:.0f} lbs")
print(f" Rod weight in fluid: {results.pred.Rwf:.0f} lbs")
print(f" Fo (SKr): {results.pred.FoSKr:.0f} lbs")
print(f" Kr: {results.pred.Kr:.1f} lb/in")
print(f" N/No: {results.pred.NNo:.3f}")
print(f" Stroke length: {results.pred.SL:.2f} in")
print(f" Pump stroke (net): {results.pred.PumpStrokeNet:.2f} in")
print(f" Production (100%): {results.pred.BblPerDay100:.1f} bbl/day")
print()
# ── Fetch dyno card arrays ───────────────────────────────────────────
(surfX, surfY) = myzrod.GetMeasuredDyno()
(pumpX, pumpY) = myzrod.GetMeasuredPump()
(upscX, upscY) = myzrod.GetUpscaledDyno()
(upscPX, upscPY) = myzrod.GetUpscaledPump()
(predDynX, predDynY) = myzrod.GetPredDyno()
(predPmpX, predPmpY) = myzrod.GetPredPump()
print("=== Card Point Counts ===")
print(f" Measured surface: {len(surfX)} pts")
print(f" Measured pump: {len(pumpX)} pts")
print(f" Upscaled surface: {len(upscX)} pts")
print(f" Upscaled pump: {len(upscPX)} pts")
print(f" Predicted surface: {len(predDynX)} pts")
print(f" Predicted pump: {len(predPmpX)} pts")
print()
# ── Rod loading ──────────────────────────────────────────────────────
(depth, lbsMax, lbsMin, pctMax, pctMin) = myzrod.xGetUpscaledRodLoading()
print("=== Rod Loading (Upscaled) ===")
for i in range(len(depth)):
print(f" Depth {depth[i]:7.0f} ft | Max {lbsMax[i]:8.0f} lbs ({pctMax[i]:5.1f}%)"
f" | Min {lbsMin[i]:8.0f} lbs ({pctMin[i]:5.1f}%)")
print()
# ── Optional: plot if matplotlib is available ────────────────────────
try:
import matplotlib.pyplot as plt
fig, axes = plt.subplots(1, 2, figsize=(12, 5))
# Surface cards
axes[0].set_title("Surface Dynamometer Cards")
axes[0].plot(surfX, surfY, ".", ms=2, color="gray", label="Measured")
axes[0].plot(upscX, upscY, color="blue", label="Upscaled")
axes[0].plot(predDynX, predDynY, color="red", label="Predicted")
axes[0].set_xlabel("Position (in)")
axes[0].set_ylabel("Load (lbs)")
axes[0].legend()
# Pump cards
axes[1].set_title("Pump Cards")
axes[1].plot(pumpX, pumpY, ".", ms=2, color="gray", label="Measured")
axes[1].plot(upscPX, upscPY, color="green", label="Upscaled")
axes[1].plot(predPmpX, predPmpY, color="lime", label="Predicted")
axes[1].set_xlabel("Position (in)")
axes[1].set_ylabel("Load (lbs)")
axes[1].legend()
plt.tight_layout()
plt.savefig("test_libzrod_output.png", dpi=150)
print("Plot saved to test_libzrod_output.png")
plt.show()
except ImportError:
print("matplotlib not installed — skipping plot (pip install matplotlib)")
myzrod.Logout()
print("\nDone.")
API Reference
Initialization & Auth
| Method | Description |
|---|---|
zrod() |
Create engine instance (singleton) |
Login(username, password) -> bool |
Authenticate with zrod.io |
Logout() -> bool |
End session |
SetClientVersion(platform, major, minor, rev, build) |
Set client identifier |
GetZrodVersion() -> np.ndarray |
Get C++ library version [major, minor, rev, build] |
GetZrodVersionString() -> str |
Get version as "M.m.r.b" string |
Configuration
| Method | Description |
|---|---|
GetWaveParams() -> WaveParams_t |
Get current wave parameters |
SetWaveParams(params) -> bool |
Set wave parameters |
GetWaveSettings() -> WaveSettings_t |
Get advanced solver settings |
SetWaveSettings(settings) -> bool |
Set advanced solver settings |
xSetDiagTapers(tapers, fluidSG) -> bool |
Set diagnostic rod string (infers count) |
xSetPredTapers(tapers, fluidSG) -> bool |
Set predictive rod string (infers count) |
SetDiagTapers(tapers, count, fluidSG) -> bool |
Set diagnostic rod string (manual count) |
SetPredTapers(tapers, count, fluidSG) -> bool |
Set predictive rod string (manual count) |
xSetDiagTubings(tubings) -> bool |
Set diagnostic tubing string (infers count) |
xSetPredTubings(tubings) -> bool |
Set predictive tubing string (infers count) |
SetDiagTubings(tubings, count) -> bool |
Set diagnostic tubing string (manual count) |
SetPredTubings(tubings, count) -> bool |
Set predictive tubing string (manual count) |
xSetCasings(casings) -> bool |
Set casing string (infers count) |
SetCasings(casings, count) -> bool |
Set casing string (manual count) |
SetDiagApiTaperByNumber(num, pumpDia, pumpDepth) -> bool |
Set diagnostic taper from API rod number |
SetPredApiTaperByNumber(num, pumpDia, pumpDepth) -> bool |
Set predictive taper from API rod number |
SetPuApi(puApi) -> bool |
Set pumping unit geometry |
SetPuInfo(puInfo) -> bool |
Set pumping unit info (with designation) |
SetPuByName(name) -> bool |
Set pumping unit by database name |
SetFourierCoeffCountPos(count) |
Set Fourier coefficients for position curve fitting |
SetFourierCoeffCountLoad(count) |
Set Fourier coefficients for load curve fitting |
SetUpscaledDynoPointCount(count) |
Set upscaled output resolution |
Calculation
| Method | Description |
|---|---|
RunDesign() -> bool |
Execute wave equation solver (diagnostic + predictive) |
CalculateFo() -> float |
Calculate fluid load from pump/pressure parameters (lbs) |
CalculateKrToDepth(depth) -> float |
Calculate rod spring constant to a given depth |
ValidateDesign() -> list[dict] |
Validate current design, returns list of issues |
Results — Diagnostic
| Method | Returns | Description |
|---|---|---|
GetMeasuredDyno() |
(pos, load) |
Measured surface card |
GetMeasuredPump() |
(pos, load) |
Calculated downhole pump card |
GetMeasuredPumpColors() |
np.ndarray[int32] |
Pump valve state colors per point |
GetMeasuredPumpVelocity() |
np.ndarray |
Plunger velocity (in/sec) |
GetMeasuredPumpVelocityNormalized() |
np.ndarray |
Plunger velocity (0-100 scale) |
GetMeasuredPumpChamberPressure() |
np.ndarray |
Chamber pressure (psi) |
GetMeasuredPumpChamberPressureNormalized() |
np.ndarray |
Chamber pressure (0-100 scale) |
GetUpscaledDyno() |
(pos, load) |
Curve-fitted surface card |
GetUpscaledPump() |
(pos, load) |
Pump card from curve-fitted input |
GetUpscaledPumpColors() |
np.ndarray[int32] |
Valve state colors |
GetUpscaledPumpVelocity() |
np.ndarray |
Plunger velocity |
GetUpscaledPumpVelocityNormalized() |
np.ndarray |
Plunger velocity (0-100) |
GetUpscaledPumpChamberPressure() |
np.ndarray |
Chamber pressure |
GetUpscaledPumpChamberPressureNormalized() |
np.ndarray |
Chamber pressure (0-100) |
Results — Predictive
| Method | Returns | Description |
|---|---|---|
GetPredDyno() |
(pos, load) |
Predicted surface card |
GetPredPump() |
(pos, load) |
Predicted pump card |
GetPredPumpColors() |
np.ndarray[int32] |
Valve state colors |
GetPredPumpVelocity() |
np.ndarray |
Plunger velocity |
GetPredPumpVelocityNormalized() |
np.ndarray |
Plunger velocity (0-100) |
GetPredPumpChamberPressure() |
np.ndarray |
Chamber pressure |
GetPredPumpChamberPressureNormalized() |
np.ndarray |
Chamber pressure (0-100) |
Results — Rod Loading
| Method | Returns | Description |
|---|---|---|
xGetMeasuredRodLoading() |
(depth, lbsMax, lbsMin, pctMax, pctMin) |
Measured rod loading per section |
xGetUpscaledRodLoading() |
(depth, lbsMax, lbsMin, pctMax, pctMin) |
Upscaled rod loading |
xGetPredRodLoading() |
(depth, lbsMax, lbsMin, pctMax, pctMin) |
Predicted rod loading |
Results — Other
| Method | Returns | Description |
|---|---|---|
GetWaveResults() |
WaveResults_t |
Numeric results (Fo, Kr, pump stroke, production, etc.) |
GetWaveParamsReadOnly() |
WaveParamsReadOnly_t |
Computed parameters (point counts, DT, buoyancy) |
GetIntermediateCard(nodeindex, dynotype) |
(pos, load) |
FEA node card (dynotype: 1=meas, 2=upsc, 3=pred) |
GetIntermediateTimeSlice(timestep, dynotype) |
(pos, load) |
All nodes at one timestep |
GetPermissibleLoads(destX, destY, count, clipmin, clipmax) |
bool |
Modified Goodman envelope |
File I/O
| Method | Description |
|---|---|
LoadDyn(spm, pos_array, load_array) -> bool |
Load measured card from arrays |
LoadDynFromFile(filepath) -> bool |
Load .dyn file |
LoadDynFromFileContents(text) -> bool |
Load .dyn from string |
LoadDynFromDAT(filepath) -> bool |
Load .DAT format (Python-only parser) |
ParseDesignFile(filepath) -> bool |
Parse design file (.zrod, .rsdx, .inp6, etc.) |
ParseDesignFileContents(contents, ftype) -> bool |
Parse from string |
WriteDesignFile(filepath) -> bool |
Write .zrod design file |
WriteDesignFileWithTemplate(filepath, templatepath) -> bool |
Write with template |
Design Management (Cloud)
Note: Cloud design management is a work in progress and subject to change.
| Method | Description |
|---|---|
FetchDesigns(fromserver) -> int |
Fetch design list (True=server, False=cached). Returns count. |
GetDesigns() -> list[DesignInfo] |
Get list of DesignInfo objects |
GetDesign(designId) -> bool |
Load a design by ID |
SaveCurrentDesign(overwrite) -> bool |
Save current design to cloud |
SubmitDesign(email, nonblocking) -> bool |
Submit design for review |
DeleteDesign(designId) -> bool |
Delete a cloud design |
SetDesignTitle(title) -> bool |
Set design title |
GetDesignTitle() -> str |
Get design title |
SetComment(comment) -> bool |
Set design comment |
GetComment() -> str |
Get design comment |
GetDesignID() -> str |
Get current design ID (compact UUID) |
Metadata & Debug
| Method | Description |
|---|---|
GetPuInfo() -> PuInfo_t |
Get pumping unit info |
GetCasingCount() -> int |
Get casing section count |
GetCasings() -> list[CasingBase_t] |
Get casing sections |
GetDeviationSurveyCount() -> int |
Get deviation survey point count |
GetDeviationSurvey() -> list[DeviationSurveyPoint_t] |
Get deviation survey |
PrintZrodObj() |
Print internal state to console |
DebugZrodObj(filepath) |
Dump debug info to file (if available) |
Data Structures
TaperBase_t — Rod Section
| Field | Type | Unit | Description |
|---|---|---|---|
id |
bytes[32] |
— | Rod grade identifier (e.g. b"D") |
L |
float |
feet | Section length |
D |
float |
inches | Rod body diameter |
W |
float |
lb/ft | Weight per foot |
T |
float |
psi | Minimum tensile strength |
E |
float |
psi | Young's modulus (typically 30,500,000) |
R |
float |
lb/ft^3 | Density (typically 490 for steel) |
RL |
float |
feet | Individual rod length for UI (default 25) |
K |
float |
— | Modified Goodman K constant (default 2.8) |
M |
float |
— | Modified Goodman M constant (default 0.375) |
TubingBase_t — Tubing Section
| Field | Type | Unit | Description |
|---|---|---|---|
L |
float |
feet | Section length |
innerDiameter |
float |
inches | Tubing ID |
outerDiameter |
float |
inches | Tubing OD |
weight |
float |
lb/ft | Weight per foot |
W |
float |
lb/ft | Rod-in-tubing weight factor |
T |
float |
psi | Tensile strength |
E |
float |
psi | Young's modulus |
R |
float |
lb/ft^3 | Density |
WaveParams_t — Core Parameters
Key fields (see CLAUDE.md for full list):
| Field | Type | Unit | Description |
|---|---|---|---|
WellDepth |
float |
feet | Total well depth |
diagSpm / predSpm |
float |
SPM | Strokes per minute |
diagDampUp / diagDampDn |
float |
— | Damping factors (0.0–1.0, typical 0.05) |
predDampUp / predDampDn |
float |
— | Predictive damping factors |
diagFluidSG / predFluidSG |
float |
— | Fluid specific gravity |
diagPumpPlungerDiameter |
float |
inches | Plunger diameter |
diagPumpDepth / predPumpDepth |
float |
feet | Pump setting depth |
predFo |
float |
lbs | Target fluid load (or use CalculateFo()) |
predFillage |
float |
% | Pump fillage (0–100) |
predCompression |
float |
— | Gas compression ratio |
usePumpingUnitForPosition |
bool |
— | Use PU geometry for position (vs measured) |
Naming Conventions
x-prefix methods (e.g. xSetDiagTapers, xGetMeasuredRodLoading) are Pythonic convenience wrappers:
xSet*infers the array count fromlen()and passesctypes.byref()automaticallyxGet*allocates numpy output arrays automatically and returns them
The non-x versions require you to pass count and pre-allocated arrays manually.
Workflow Patterns
Diagnostic + Predictive Analysis
1. zrod() → Login()
2. GetWaveParams() → set fields → SetWaveParams()
3. xSetDiagTapers() + xSetPredTapers()
4. xSetDiagTubings() + xSetPredTubings()
5. LoadDyn() or LoadDynFromDAT() or ParseDesignFile()
6. RunDesign()
7. GetMeasuredDyno(), GetMeasuredPump(), GetPredDyno(), GetPredPump()
8. GetWaveResults() for numeric output
Predictive-Only (No Measured Card)
1. zrod() → Login()
2. GetWaveParams() → set fields, usePumpingUnitForPosition=True → SetWaveParams()
3. SetPuApi() or SetPuByName()
4. xSetPredTapers(), xSetPredTubings()
5. CalculateFo() or set predFo manually
6. RunDesign()
7. GetPredDyno(), GetPredPump()
File Round-Trip
1. ParseDesignFile("input.zrod") # loads all parameters + measured card
2. RunDesign()
3. WriteDesignFile("output.zrod") # saves current state
Constants
# Prediction algorithm types (for WaveSettings_t.predAlgorithmType)
# Note: Integer values are subject to change — use the PRED_ALGORITHM_* names.
PRED_ALGORITHM_STANDARD = 0 # Default
PRED_ALGORITHM_OLD = 1 # Legacy algorithm
PRED_ALGORITHM_EXPERIMENTAL = 2 # Experimental
PRED_ALGORITHM_LEAKAGE = 3 # With leakage modeling
Known Limitations
The following C API functions are not yet wrapped in the Python interface:
| C Function | Purpose |
|---|---|
SetDeviationSurvey() |
Set wellbore deviation survey |
SetDeviationSurveyWithMIA() |
Set deviation survey (interleaved format) |
SetSaveIntermediateCards() |
Enable intermediate FEA node card output |
SetStatusCallback() |
Async status callbacks |
GetDiagTaperCount/GetPredTaperCount |
Query rod section counts |
GetDiagTapers/GetPredTapers |
Retrieve rod sections |
GetDiagTubingCount/GetPredTubingCount |
Query tubing section counts |
GetDiagTubings/GetPredTubings |
Retrieve tubing sections |
Platform Support
| Platform | Architecture | Python Versions |
|---|---|---|
| Windows | x86_64 | 3.9 - 3.13 |
| macOS | x86_64, ARM64 | 3.9 - 3.13 |
| Linux | x86_64 | 3.9 - 3.13 |
Mobile Apps
Beta access available for iOS and Android demo apps. Contact for access.
Web App
The ZROD web app demonstrates the full feature set of the library, including interactive dynamometer card visualization, rod loading analysis, pump velocity display, multi-format file import/export, and cloud design management.
Troubleshooting
RunDesign() returns False: Call ValidateDesign() to get a list of issues with codes and messages. Common causes: missing rod string, missing measured card (when usePumpingUnitForPosition=False), zero SPM, or invalid pump parameters.
Singleton warning: zrod is a singleton. Creating a second instance returns the same object with a warning. Use del myzrod before creating a new one if needed.
Platform binary not found: The library ships platform-specific binaries. Ensure your Python version and platform match a supported wheel.
Contact & Licensing
For licensing inquiries, reach out via LinkedIn.
Legal
*Help improve this document. Contact me with feedback or ambiguities.
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 Distributions
Built Distributions
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 libzrod-0.1.29-cp314-cp314t-manylinux_2_28_x86_64.whl.
File metadata
- Download URL: libzrod-0.1.29-cp314-cp314t-manylinux_2_28_x86_64.whl
- Upload date:
- Size: 7.9 MB
- Tags: CPython 3.14t, manylinux: glibc 2.28+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e9ec11f0fbb8fdfd27d14b97c3dd1c355c3551d29f7ba6afdb30911766f03852
|
|
| MD5 |
ceb2c3951be34ca6c5814c98f488de8d
|
|
| BLAKE2b-256 |
0b232d9afed51e83b8aadd28989351eface453f269a9ed6f14b8c2e6137aea7c
|
File details
Details for the file libzrod-0.1.29-cp314-cp314-manylinux_2_28_x86_64.whl.
File metadata
- Download URL: libzrod-0.1.29-cp314-cp314-manylinux_2_28_x86_64.whl
- Upload date:
- Size: 7.9 MB
- Tags: CPython 3.14, manylinux: glibc 2.28+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
46947a5b7e32f75b5806d5bd76ae153f7c577fdde55b68957ae3ca518d2fae56
|
|
| MD5 |
9641727fac4c72e43a280ee2574008d5
|
|
| BLAKE2b-256 |
0b589ca9fcf6943e7596380fb6d2610dfeed078f594ba5cfb2c3fc0f7222748f
|
File details
Details for the file libzrod-0.1.29-cp313-cp313-manylinux_2_28_x86_64.whl.
File metadata
- Download URL: libzrod-0.1.29-cp313-cp313-manylinux_2_28_x86_64.whl
- Upload date:
- Size: 7.9 MB
- Tags: CPython 3.13, manylinux: glibc 2.28+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b7ae501b243f7f6edb2ba62b587753dc1ebb2009b5078492cc43545b3477a964
|
|
| MD5 |
7efdb8bee9d2abcb510a56500b8c4e7f
|
|
| BLAKE2b-256 |
d39c7dbf8dddd4d439e3618182aeee6c825bb9017c556e9f6ef4e15778183b4c
|
File details
Details for the file libzrod-0.1.29-cp312-cp312-manylinux_2_28_x86_64.whl.
File metadata
- Download URL: libzrod-0.1.29-cp312-cp312-manylinux_2_28_x86_64.whl
- Upload date:
- Size: 7.9 MB
- Tags: CPython 3.12, manylinux: glibc 2.28+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1f67822c6d8cfefa5ed722fcd41667ff05446a7ce99f8ac6bf1fdfcd62bd96c4
|
|
| MD5 |
59e9fb6534191166496f3cc525aab32f
|
|
| BLAKE2b-256 |
73f5d3d284da762d562abf187b6fd7bbae680bf51cbb96099542a7e76d5697c5
|
File details
Details for the file libzrod-0.1.29-cp311-cp311-manylinux_2_28_x86_64.whl.
File metadata
- Download URL: libzrod-0.1.29-cp311-cp311-manylinux_2_28_x86_64.whl
- Upload date:
- Size: 7.9 MB
- Tags: CPython 3.11, manylinux: glibc 2.28+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5b8b1f1d94680acd37dc753af7637c02ab51b805d14b14c2670e4597ab1bab61
|
|
| MD5 |
de56da7fcb9aec79613ac97fc12a2470
|
|
| BLAKE2b-256 |
129e6f770cdaae9b293c3b6867c068a2c0615e04359e95a68028218dcd505ed7
|
File details
Details for the file libzrod-0.1.29-cp310-cp310-manylinux_2_28_x86_64.whl.
File metadata
- Download URL: libzrod-0.1.29-cp310-cp310-manylinux_2_28_x86_64.whl
- Upload date:
- Size: 7.9 MB
- Tags: CPython 3.10, manylinux: glibc 2.28+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1598520cf6638d20279c315b5ff8dca03540258868ceea520cbea59957780199
|
|
| MD5 |
d92819ed47bd29a6fe909f87f8e15598
|
|
| BLAKE2b-256 |
ef77bb0b8cf325f1298186a692673502ba19c560102361b44b8add7641f3bfe2
|
File details
Details for the file libzrod-0.1.29-cp39-cp39-manylinux_2_28_x86_64.whl.
File metadata
- Download URL: libzrod-0.1.29-cp39-cp39-manylinux_2_28_x86_64.whl
- Upload date:
- Size: 7.9 MB
- Tags: CPython 3.9, manylinux: glibc 2.28+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6ba3b9b89604294f4c741490edc6d045c3eb38601f66f2d6fcc6f9a6385b8993
|
|
| MD5 |
78d91387afab8ca4594e049769bb9858
|
|
| BLAKE2b-256 |
2666588cedbcf2fe9a43403bbbcb6d48d0f78918d6423b476c1bc7bfa1936330
|