Metadata-Version: 2.4
Name: arcasleep
Version: 0.1.1
Summary: Arcascope's open sleep-stage models: training, evaluation, release and inference
Author-email: Arcascope Inc <support@arcascope.com>
License-Expression: MIT
Project-URL: Homepage, https://github.com/Arcascope/sleep-models
Project-URL: Repository, https://github.com/Arcascope/sleep-models
Project-URL: Issues, https://github.com/Arcascope/sleep-models/issues
Project-URL: Documentation, https://huggingface.co/arcascope
Keywords: sleep,actigraphy,accelerometer,sleep-staging,wearables
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Science/Research
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Topic :: Scientific/Engineering
Requires-Python: >=3.12
Description-Content-Type: text/markdown
License-File: LICENSE
Provides-Extra: pisces
Requires-Dist: pisces-lite>=4.1.1; extra == "pisces"
Provides-Extra: bidoze
Requires-Dist: jax; extra == "bidoze"
Requires-Dist: flax; extra == "bidoze"
Requires-Dist: optax; extra == "bidoze"
Provides-Extra: unet
Requires-Dist: jax; extra == "unet"
Requires-Dist: flax; extra == "unet"
Requires-Dist: optax; extra == "unet"
Provides-Extra: inference
Requires-Dist: jax; extra == "inference"
Requires-Dist: flax; extra == "inference"
Requires-Dist: pisces-lite[jax,proc]; extra == "inference"
Requires-Dist: arcasleep[pisces]; extra == "inference"
Requires-Dist: safetensors; extra == "inference"
Provides-Extra: hub
Requires-Dist: safetensors; extra == "hub"
Requires-Dist: huggingface_hub; extra == "hub"
Provides-Extra: prep
Requires-Dist: pisces-lite[proc]; extra == "prep"
Requires-Dist: arcasleep[pisces]; extra == "prep"
Provides-Extra: train
Requires-Dist: jax; extra == "train"
Requires-Dist: flax; extra == "train"
Requires-Dist: optax; extra == "train"
Requires-Dist: arcasleep[pisces]; extra == "train"
Requires-Dist: matplotlib; extra == "train"
Provides-Extra: report
Requires-Dist: matplotlib; extra == "report"
Requires-Dist: pandas; extra == "report"
Provides-Extra: aws
Requires-Dist: boto3>=1.34; extra == "aws"
Provides-Extra: publish
Requires-Dist: safetensors; extra == "publish"
Requires-Dist: matplotlib; extra == "publish"
Requires-Dist: pandas; extra == "publish"
Provides-Extra: preview
Requires-Dist: markdown-it-py>=3; extra == "preview"
Provides-Extra: all
Requires-Dist: arcasleep[aws,bidoze,hub,inference,prep,preview,publish,report,train,unet]; extra == "all"
Provides-Extra: dev
Requires-Dist: pytest>=8; extra == "dev"
Requires-Dist: ruff>=0.8; extra == "dev"
Dynamic: license-file

# Arcasleep

Arcascope's open source, open weights sleep models.

---

One Python distribution, `arcasleep`, carries the shared data handling, training,
evaluation and release tooling (`core/`, the `arcasleep` import package) and
every model family (`bidoze/` and `unet/`, the `arcasleep_bidoze` and
`arcasleep_unet` import packages). Model
weights are released on the Hugging Face Hub, one repository per model variant.

## Install

The base install is dependency-free: it provides the manifest tools and a
working CLI, and every other command imports its dependencies on demand.

```bash
pip install arcasleep                           # CLI + manifest tools, no heavy deps
pip install "arcasleep[bidoze,inference,hub]"   # run a released BiDoze model
pip install "arcasleep[unet,train]"             # training stack (adds optax, matplotlib)
pip install "arcasleep[prep]"                   # build the feature cache
pip install "arcasleep[aws]"                    # S3 manifests and result upload
pip install "arcasleep[publish]"                # build a release bundle
pip install "arcasleep[all]"                    # installs all extras
```

`pisces-lite` and `arcascope-senpy` are public on PyPI; pisces-lite supplies
the dataset/IO layer and the metric registry, and its `[proc]` extra (pulled by
`[prep]`) the prebuilt senpy NUFFT wheel.

## Commands

Every model family reads the same feature cache, so the cache and results
commands are shared; training, scoring and release sit under each family:

```bash
arcasleep process          # build the feature cache (needs [prep])
arcasleep splits-plan / splits-apply
arcasleep summarize        # pool finished phases into a metrics_summary.csv
arcasleep compare          # draw a metric grid across summaries
arcasleep hypnogram        # hypnogram PNGs from prediction CSVs
arcasleep card-preview     # render a built bundle's model card to HTML
arcasleep manifest-local / manifest-s3 / upload-results

arcasleep bidoze train     # run the recipe from a feature cache
arcasleep bidoze evaluate  # score a checkpoint on a cohort
arcasleep bidoze publish   # build a safetensors release bundle, optionally upload it
arcasleep bidoze predict   # per-epoch stages for raw accelerometer files

arcasleep unet train | evaluate | publish | predict
```

## Models

The current pediatric model variants are trained on the clinical pediatric pool described in [Weaver et al. 2026](https://pubmed.ncbi.nlm.nih.gov/40676371/). This set has subjects with no recorded diagnosis (n=37), as well as mild (n=94), moderate (n=33), and severe (n=38) obstructive sleep apnea (OSA). We are grateful to Glenn Weaver and his group for sharing their data with us.

### BiDoze

Published on Hugging Face as [`arcascope/arcasleep-bidoze-pediatric`](https://huggingface.co/arcascope/arcasleep-bidoze-pediatric); the model lives in [`bidoze/`](bidoze/).

Wake/Light/Deep/REM predictions, plus a 5th head for identifying gaps in accelerometer. 

1. **Architecture:** `[CNN encoder] -> [ALiBi Transformers] -> [5-head MLP]`.
2. Developed via a semi-autonomous research loop using LLMs.
    1. Agents were given the goal to optimize model architecture and training regime with fixed train/test splits. 
    2. "Best" as measured by the geometric mean of TST and WASO MAPE. 

## UNet

Published on Hugging Face as [`arcascope/arcasleep-unet-pediatric`](https://huggingface.co/arcascope/arcasleep-unet-pediatric); the model lives in [`unet/`](unet/).

Wake/Light/Deep/REM predictions, plus a 5th head for identifying gaps in accelerometer.

1. **Architecture:** the temporal U-Net described in Olsen et al., "A flexible deep learning architecture for temporal sleep stage classification using accelerometry and photoplethysmography," IEEE TBME 2022 ([doi:10.1109/TBME.2022.3187945](https://doi.org/10.1109/TBME.2022.3187945)), over raw 2-s spectrogram frames.
2. Trained with the paper's procedure: class-balanced segment sampling and loss, early stopping on held-out subjects.

## Releasing the package

The distribution is published to PyPI from CI with
[Trusted Publishing](https://docs.pypi.org/trusted-publishers/) (OIDC): no API
token is stored. `.github/workflows/release.yml` builds sdist + wheel from the
repository root, tests the built wheel, and publishes when a GitHub Release is
published for an `arcasleep-vX.Y.Z` tag.

The tag is the source of truth for the version: `setuptools-scm` reads the
nearest `arcasleep-vX.Y.Z` tag (configured in `pyproject.toml`), so the
distribution version and the release tag cannot drift. To release, push an
`arcasleep-vX.Y.Z` tag and publish a GitHub Release for it -- there is no
version literal to edit. The workflow fails if the tag and the built version
disagree. A manual `workflow_dispatch` runs the build and wheel tests without
publishing; commits past a tag build as the next patch dev version
(`X.Y.(Z+1).devN`), which is what `.github/workflows/dry-run-testpypi.yml`
rehearses against TestPyPI.
