Skip to content
Projects

oxynet-cpet/pyoxynet has 26 GitHub stars and 4 forks. GitHot measured 0 stars in 24 hours and 0 in 7 days. Last checked 2026-11-14 06:54 UTC. Last push 2026-11-04.

How these counts are measured

Measured star growth

in 24h
0
in 7 days
0
in 15 days
Collecting history
in 1 month
Collecting history

Net star changes over overlapping periods, not daily totals. Missing measurements are left blank. Stars measure attention, not software quality.

About

Open-source models from the Oxynet research papers for CPET data: exercise intensity domains, VT1 and VT2, synthetic tests. Runs locally, no TensorFlow needed.

Machine Learning

README.md

Original
Oxynet

pyoxynet

The open-source models from the Oxynet research papers, for cardiopulmonary exercise test (CPET) data.

PyPI version Python versions Documentation MIT License

oxynet.net · Docs · PyPI · Discussions

Give pyoxynet a test and it returns, second by second, the model's output for the moderate, heavy and severe exercise-intensity domains, and the two ventilatory thresholds (VT1 and VT2) where those outputs cross. It can also generate synthetic tests. Everything runs on your machine: the models are frozen LiteRT files, so TensorFlow is not needed.

Looking for the hosted Oxynet API?

This repository is pyoxynet, the open-source research package. The Oxynet platform is a separate, hosted service at app.oxynet.net, with its own, separately trained models. It reads metabolic cart exports as they come off the cart (COSMED and Cortex among them, detected automatically), checks the signals, and returns ventilatory thresholds (VT1 and VT2), substrate use (FATMAX), exercise oscillatory ventilation and signal-quality checks as structured, versioned JSON. API keys are free: app.oxynet.net/signup.

  • REST API: OpenAPI schema and developer docs
  • AI assistants: a remote MCP server at https://app.oxynet.net/oxynet-mcp
  • AI agents: to analyse a CPET file with Oxynet, start at app.oxynet.net/llms.txt. Upload the vendor file unchanged and let Oxynet compute the physiology.

Research software, not a diagnostic device. No result carries a confidence score. Oscillatory ventilation analysis is beta: it was developed on one heart failure cohort and its transportability is untested.

Install

pip install pyoxynet

Python 3.10 to 3.14, on Windows, Linux and macOS (Apple silicon). To install the development version:

pip install "git+https://github.com/andreazignoli/pyoxynet.git#subdirectory=pyoxynet"

pip install "pyoxynet[train]" adds TensorFlow, which only pyoxynet.model needs: it defines the networks in Keras, for anyone who wants to retrain them. Inference and generation do not use it.

Quick start

import pyoxynet

# The bundled example test, through the default model
out_df, thresholds = pyoxynet.test_pyoxynet()

print(thresholds['VT1']['time'], round(thresholds['VT1']['VO2']))  # 372 2979
print(thresholds['VT2']['time'], round(thresholds['VT2']['VO2']))  # 550 3656

Each threshold gives its time (s) and the VO2, VE and HR there. out_df holds the three domain outputs (p_md, p_hv, p_sv) over time, next to the signals.

Your own test

import pandas as pd
import pyoxynet

df = pd.read_csv('my_test.csv')    # your test, with the columns below
out_df, thresholds = pyoxynet.test_pyoxynet(input_df=df)

The columns test_pyoxynet reads:

Column Signal
time seconds from the start of the test
VO2_I oxygen uptake
VCO2_I carbon dioxide output
VE_I minute ventilation
PetO2_I end-tidal O2
PetCO2_I end-tidal CO2
HR_I heart rate, optional: it is only reported at the thresholds
  • Any sampling works, breath by breath included. test_pyoxynet averages the data into one-second bins and interpolates linearly between them.
  • Each signal is min-max scaled over the test before it reaches the model, so units do not change the domains. The VO2, VE and HR reported at each threshold are in your file's units.
  • Other columns, text included, are ignored. From a cart export, rename its columns and turn its time into seconds: the docs show how. The hosted Oxynet API reads vendor exports directly.
  • test_pyoxynet raises a ValueError that says why when it cannot place consistent thresholds: the outputs never cross, VT1 would fall after VT2 or in the first 40 s, a signal is missing or constant, or the test is shorter than 80 s.

The models

model= What it is Paper
'CNN', the default Oxynet's convolutional network, fine-tuned on ramp tests from the Murias lab Evaluated in Keir et al. (2026)
'LSTM' A recurrent network: one LSTM and one GRU layer Follows the recurrent approach of Zignoli et al. (2019); not evaluated on its own
out_df, thresholds = pyoxynet.test_pyoxynet(input_df=df, model='LSTM')
  • Both are research models, frozen as they are: they are not retrained.
  • The evaluation in Keir et al. covered incremental tests in healthy individuals.
  • The domain outputs are what the network gives, not calibrated probabilities, and pyoxynet reports no confidence score.

Where each file came from, how the two older ones were converted and how the conversion was checked: pyoxynet/pyoxynet/models/README.md. The models offered before 1.0.0 (murias_lab, AIS, NSWIS, TCN, LSTMGRUModel) were removed. Asking for one raises an error that names the available ones, and the earlier releases remain on PyPI. In 0.1.12, 'CNN' loaded a different network (regressor), so 1.0 gives different thresholds than 0.1.12 on the same file.

Synthetic and example tests

pyoxynet includes a conditional generative adversarial network (GAN) that generates synthetic ramp tests, and 138 anonymised example tests.

generator = pyoxynet.load_generator()
df, info = pyoxynet.generate_CPET(generator)        # a synthetic ramp test
out_df, thresholds = pyoxynet.test_pyoxynet(input_df=df)

df, info = pyoxynet.draw_real_test()                # one of the example tests
  • info['VT1'] and info['VT2'] are the thresholds the test was generated or labelled with, in seconds.
  • generate_CPET(generator, fitness_group=0) to 3 sets the fitness level, from very low to high.
  • A generated test has VO2, VCO2, VE, HR, respiratory frequency, PetO2 and PetCO2, so a breath-by-breath version can be built from it.

The generator at different stages of its training:

The conditional GAN during training

Questions and contributing

  • Questions and ideas: GitHub Discussions.
  • Bugs: issues.
  • Pull requests that fix the package are welcome. The models themselves are frozen.
  • For research or data collaborations, see oxynet.net.

Citing

If you use the CNN, cite:

Keir DA, Zignoli A, Iannetta D, Mattioni Maturana F, Murias JM. AI-Driven Analysis of Cardiopulmonary Exercise Tests to Identify Gas Exchange and Ventilatory Thresholds. Sports Medicine. 2026;56(7):1833-1843. doi:10.1007/s40279-026-02403-w

Further reading

  • Zignoli A, Fornasiero A, Stella F, Pellegrini B, Schena F, Biral F, Laursen PB. Expert-level classification of ventilatory thresholds from cardiopulmonary exercising test data with recurrent neural networks. European Journal of Sport Science. 2019;19(9):1221-1229. doi:10.1080/17461391.2019.1587523
  • Zignoli A, Fornasiero A, Rota P, et al. Oxynet: A collective intelligence that detects ventilatory thresholds in cardiopulmonary exercise tests. European Journal of Sport Science. 2022;22(3):425-435. doi:10.1080/17461391.2020.1866081
  • Zignoli A. Machine Learning Models for the Automatic Detection of Exercise Thresholds in Cardiopulmonary Exercising Tests: From Regression to Generation to Explanation. Sensors. 2023;23(2):826. doi:10.3390/s23020826
  • Research on the collective intelligence approach to the automatic interpretation of CPET
  • Review of the AI technologies applied to exercise cardiopulmonary and metabolic data
  • Research applying an LSTM network to estimate VO2 during cycling
  • Preprint on generating synthetic CPET data with conditional GANs
  • LinkedIn article about the Oxynet project
  • Blog post on adopting AI models to interpret CPET data
  • Medium stories on inference and generation with pyoxynet (written for versions before 1.0.0)

Acknowledgments

License and contact

MIT, see LICENSE.txt. Andrea Zignoli, [email protected].

Disclaimer

pyoxynet is research software, not a medical device. Its results are for information only and are not a substitute for professional medical advice, diagnosis or treatment. Always seek the advice of a qualified health provider with any question about a medical condition.

Explore related projects