Diving decompression library (MN90, compartment model)
Project description
Decompression — bibliothèque Python & DivePlanner Android
Ce dépôt regroupe :
- Bibliothèque Python
decompression-diver(v1.1.0) — saturation en azote / modèles de décompression : tables MN90, modèle dynamique par compartiments (Haldane, Schreiner) et modèle Bühlmann ZHL-16, avec support Nitrox (voirREADME_NITROX.md). - Application Android DivePlanner (v1.0.0) — planification, mélanges et blocs gazeux, calculs Haldane, Bühlmann ZHL-16C et MN90. Détails dans
android/README.md.
Historique des changements : CHANGELOG.md.
Publication PyPI : voir Makefile.
- Pour créer les archives :
make dist - Pour déployer vers le dépôt PyPI configuré par défaut dans
~/.pypirc:make dist-deploy - Pour déployer vers TestPyPI :
make dist-testpypi
Fonctionnalités (Python)
✅ Modèles de Décompression
- Tables MN90 : Implémentation des tables françaises de décompression FFESSM
- Modèle Compartiments Dynamique : Équations de Haldane et Schreiner avec multiples compartiments
✅ Modèle Bühlmann ZHL-16 avec Gradient Factors
- 16 compartiments avec périodes de 4 à 635 minutes
- Gradient Factors configurables (GF Low/GF High) pour ajuster la conservativité
- GF Low (30-100%) : tolérance à la narcose pendant la descente
- GF High (70-100%) : tolérance aux bulles pendant la remontée
- Calcul automatique des paliers avec optimisation des profondeurs
- Exemple d'utilisation :
from deco.modelfactory import DecompressionModelFactory # Modèle conservateur (GF 30/70) model = DecompressionModelFactory.create('BUHLMANN', gf_low=30, gf_high=70) model.append(30, 50) # 30 min à 50m stops = model.decompression_stop() # Retourne les paliers
✅ Compartment-Based Decompression Model
- Haldane Equation implementation for constant depth
- Schreiner Equation for variable pressure (descent/ascent)
- Multiple compartments with different periods (5, 10, 20, 40, 80 minutes)
- Physiologically correct initialization (atmospheric pressure)
- Validated algorithms with comprehensive test suite
✅ Nitrox Support
- Gas mixture management (Air, Nitrox 32, 50, 80, etc.)
- Gas switching during dive
- Oxygen toxicity consideration (1.6 bar max)
- Realistic dive profiles with proper ascent rates
✅ Comprehensive Testing
- 52 tests covering all functionality
- Algorithm validation (Haldane, Schreiner, Bühlmann, compartment behavior)
- Physiological consistency checks
- Multi-compartment behavior validation
code validation and coverage
A makefile is available, run test and coverage:
Prepare the virtual environment:
$> make venv
Once run the python environment is ready to use with the command line:
$> source venv/bin/activate
Run tests
$> make test
----------------------------------------------------------------------
Ran 52 tests in 0.055s
OK
test_haldane_surface_to_const_depth (test_DecompressionDynamique.TestDecoDynamique) ... ok
test_multiple_compartments_ascent (test_DecompressionDynamique.TestDecoDynamique) ... ok
test_multiple_compartments_descent (test_DecompressionDynamique.TestDecoDynamique) ... ok
test_saturation_curve_validation (test_DecompressionDynamique.TestDecoDynamique) ... ok
test_choose_depth (test_DecompressionModelMn90.TestMN90) ... ok
test_choose_depth_exact (test_DecompressionModelMn90.TestMN90) ... ok
...
----------------------------------------------------------------------
Ran 49 tests in 0.055s
OK
Run tests coverage
$> make coverage
. venv/bin/activate ; pip install coverage
Requirement already satisfied: coverage in ./venv/lib/python3.6/site-packages
. venv/bin/activate
coverage run -m unittest discover
coverage report -m
coverage html
...................................
----------------------------------------------------------------------
Ran 49 tests in 0.055s
OK
Name Stmts Miss Cover Missing
------------------------------------------------------------------------
deco/__init__.py 0 0 100%
deco/model.py 3 0 100%
deco/modelmn90.py 123 0 100%
deco/modelcompartment.py 150 0 100%
deco/test/__init__.py 0 0 100%
deco/test/test_DecompressionModelMn90.py 132 7 95% 34, 58, 102, 112, 138, 145, 188
deco/test/test_DecompressionDynamique.py 200 0 100%
------------------------------------------------------------------------
TOTAL 608 7 99%
cleanup the dev environment
$> make clean
rm -rf venv htmlcov
find -iname "*.pyc" -delete
find -iname ".coverage" -delete
rm -rf .pytest_cache
rm -rf deco/__pycache__
rm -rf deco/test/__pycache__
API
API for this module is quite simple.
The UML Class diagram:
The decompression factory
It implements a factory to select the desired decompression algorithm. Its usage can be done as following:
from deco.modelfactory import DecompressionModelFactory
deco = DecompressionModelFactory.create(DecompressionModelFactory.MODEL_MN90)
deco.append(time=0, depth=0)
deco.append(5, 10)
deco.append(10, 20)
deco.append(20, 20)
deco.append(30, 21)
deco.append(30, 24)
deco.append(40, 23)
deco.append(50, 20)
deco.append(60, 10)
deco.append(69, 5)
print(deco.deco.decompression_stop())
returns
(70, 25, 0, 0, 1, 41, 'M')
means:
computed dive time = 70mn
computed dive depth = 25m
step 12m = 0 mn
step 9m = 0mn
step 6m = 1mn
step 3m = 41mn
GPS = M
It is possible to include a majoration :
print(deco.deco.decompression_stop(majoration=12))
returns
(85, 25, 0, 0, 9, 48, '*')
means:
computed dive time = 85mn
computed dive depth = 25m
step 12m = 0mn
step 9m = 0mn
step 6m = 9mn
step 3m = 48mn
GPS = not applicable with majoration
The model interface
The model interface defines the methods to be implemented for each models:
def append(self, time: int, depth: int, **options)
Append method aims to add new chunk (time, depth) of the dive into the algorithm. Optional inputs information could be provided, according to the implementation, to fine tune the compression model.
def reset(self)
Resets the model. Nothing is kept in memory.
def deco.decompression_stop(self, **kwargs)
Computes and return decompression tuple: (computed time, computed depth, step 12m, step 9m, step 6m, step 3m, GPS). kwargs may contains additional and optional information for extended usage of the floor computation.
Implemented models
MN90 Model
The MN90 model compute the decompression thanks to the MN90 tables. It implements the possibility to compute successive dives with the management of residual computation and extra time to include the the second dive. The example here before demonstrates this computation. Moreover this model implement methods not mandatory for the common interface. Most important one is the methods to retrieves residual nitrogen value from GPS, and majoration from residual and ground time interval:
from deco.modelmn90 import MN90
# Residual nitrogen after 4hours (4*60 mn) and previous GPS=L
print ("residual=" + str(MN90().residual_nitrogen(240, 'J')))
print ("residual=" + str(MN90().residual_nitrogen(239, 'J')))
results
residual=0.93
residual=0.96
Then to retrieve residual nitrogen time from residual nitrogen and depth:
from deco.modelfactory import DecompressionModelFactory
deco = DecompressionModelFactory.create(DecompressionModelFactory.MODEL_MN90)
print ("majoration=" + str(deco.residual_nitrogen_time(interval=240, gps='J', depth=20)))
results
majoration=13
Compartment-Based Model ✅
The compartment-based model implements the Haldane and Schreiner equations for dynamic decompression calculation.
Basic Usage:
from deco.modelcompartment import DecompressionModelCompartment
# Create model with 10-minute compartment
deco = DecompressionModelCompartment(
period=10*60, # 10 minutes in seconds
sc=2.75, # Critical threshold
gas_mixture={"N2": 0.7902, "O2": 0.2095, "Ar": 0.0003} # Air
)
# Simple dive profile
deco.append(0, 0) # Surface
deco.append(3, 30) # Descent to 30m
deco.append(20, 30) # 20 minutes at 30m
deco.append(3, 0) # Ascent to surface
# Get final tension
print(f"Final tension: {deco.current_tension:.3f} bar")
Nitrox Support:
from deco.modelcompartment import DecompressionModelCompartment, create_nitrox_mixture
# Create Nitrox 32
nitrox_32 = create_nitrox_mixture(32)
deco = DecompressionModelCompartment(
period=10*60,
sc=2.75,
gas_mixture=nitrox_32
)
# Gas switching during dive
deco.append(0, 0) # Surface with Nitrox 32
deco.append(5, 30) # Descent
deco.append(20, 30) # Bottom time
# Switch to Nitrox 80 for decompression
nitrox_80 = create_nitrox_mixture(80)
deco.append(0, 30, gas_mixture=nitrox_80) # Gas switch
deco.append(10, 15) # Decompression stops
deco.append(5, 6) # More stops
deco.append(3, 0) # Surface
Multi-Compartment Analysis:
# Analyze multiple compartments
periods = [5*60, 10*60, 20*60, 40*60] # 5, 10, 20, 40 minutes
compartments = []
for period in periods:
comp = DecompressionModelCompartment(period=period, sc=2.75)
comp.append(0, 0)
comp.append(3, 30)
comp.append(20, 30)
comp.append(3, 0)
compartments.append(comp)
# Compare final tensions
for i, comp in enumerate(compartments):
print(f"Compartment {periods[i]//60}min: {comp.current_tension:.3f} bar")
Key Features:
- ✅ Physiologically correct initialization (atmospheric pressure)
- ✅ Haldane equation for constant depth
- ✅ Schreiner equation for variable pressure
- ✅ Gas mixture support (Air, Nitrox, etc.)
- ✅ Gas switching during dive
- ✅ Oxygen toxicity consideration
- ✅ Comprehensive validation with 49 tests
Validation Results:
- Haldane Law: Tension increases by half the gradient in one period ✅
- Descent/Ascent Consistency: Physiologically realistic behavior ✅
- Multi-compartment Behavior: Fast compartments saturate/desaturate faster ✅
- Gas Switching: Proper handling of different mixtures ✅
Project details
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 decompression_diver-1.2.0.tar.gz.
File metadata
- Download URL: decompression_diver-1.2.0.tar.gz
- Upload date:
- Size: 24.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4b91bf43d1ce84e770c0264daa41e5085c6d8c18a8fce82815277ce8509b8e87
|
|
| MD5 |
b8e580c17d06092f6f0424934c161fe3
|
|
| BLAKE2b-256 |
5e8ba3dde4b1b29e2c4324141856b1d81cc7bbcea24b58c05daf8a274a38b665
|
File details
Details for the file decompression_diver-1.2.0-py3-none-any.whl.
File metadata
- Download URL: decompression_diver-1.2.0-py3-none-any.whl
- Upload date:
- Size: 22.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
acac7f9acfa669b4748c0c37cfe8d8ac3fd5bb2fa51251b67c85b200b1c8a153
|
|
| MD5 |
c3ebbf82d11baf7b252a7d24f8eec19f
|
|
| BLAKE2b-256 |
b47182b54fae45e7c96e6ede53d40ef9d7dd2e1b40140514b2b075c0c6befc42
|