Skip to main content

ALOTT-MEDS

PyPI - Version codecov tests code-quality python Static Badge license PRs contributors DOI

ALOTT (ALarms, Outcomes Telemetry with Timing) is a pilot bedside-EMR database from two hospitals, collected to support algorithms that predict emergency response team events. It pairs bedside telemetry from 270 beds (alarms, monitor measurements and waveforms) with electronic medical record data: admissions, diagnoses, ICU stays and bed moves, labs, orders, medications and nursing flowsheets. This pipeline extracts the EMR tables of ALOTT (from PhysioNet, https://physionet.org/content/alott/) into the MEDS format. It is built the same way as MIMIC_IV_MEDS: one declarative MEDS-Extract spec, no Python.

Usage:

pip install git+https://github.com/rvandewater/ALOTT_MEDS
export DATASET_DOWNLOAD_USERNAME=$PHYSIONET_USERNAME
export DATASET_DOWNLOAD_PASSWORD=$PHYSIONET_PASSWORD

meds-extract-run spec=ALOTT output_dir=$MEDS_OUTPUT_DIR

That downloads only the emr-datasets/ folder of the ALOTT 1.0.0 release (the telemetry is skipped) into $MEDS_OUTPUT_DIR/.meds_extract_run/raw_input and runs the full MEDS-Extract pipeline, writing data/ and metadata/ to $MEDS_OUTPUT_DIR. Files that already exist and verify against PhysioNet's checksums are skipped, so an interrupted download resumes. Pass download_dest_dir=$RAW_INPUT_DIR to keep the raw data somewhere durable.

ALOTT is a credentialed release: the PhysioNet account must have signed the ALOTT data use agreement.

To reuse a download you already have, point input_dir at the directory that contains emr-datasets/:

meds-extract-run spec=ALOTT output_dir=$MEDS_OUTPUT_DIR do_download=false input_dir=$RAW_INPUT_DIR

Run meds-extract-run --help for the full set of arguments.

Configuration

The whole pipeline is one file, src/ALOTT_MEDS/event_configs.yaml, written in MESSY (MEDS-Extract Specification Syntax YAML) and registered under the MEDS_extract.pipelines entry-point group as ALOTT. That registration is what makes spec=ALOTT work from anywhere and what stamps the output's metadata/dataset.json with <ALOTT release>:<this package's version>. The file holds:

  • a sources: block pointing at the PhysioNet release, restricted to emr-datasets/*;
  • an etl: block with the run's few knobs;
  • one block per raw EMR table describing the events extracted from it.

Timestamps

ALOTT shifts each patient's dates by a random -180..180 days but keeps the time of day. Most tables store each timestamp as one shifted %Y-%m-%d %H:%M:%S column. Labs and orders carry only a shifted date, and medication start and end times are always 00:00:00, i.e. dates too. Those events are placed at the end of that day (23:59:59): midnight would make a result or a new medication visible before it existed, which leaks the future into any prediction made later that day. Same-day lab orders and results therefore share a time. Medication administrations keep their recorded time of day. A row with a null timestamp produces no event.

Absolute dates are shifted per patient, so only differences within a subject are meaningful.

IDs

aMRN is the MEDS subject_id; the encounter key aCSN is carried as hadm_id. Lab and order results use the resulting encounter, and orders the ordering one. The release writes the string nan for an unresulted encounter; it is cast leniently, so it becomes a null and hadm_id stays Int64.

Codes

Every code is FAMILY//..., from general to specific, so a prefix selects a group (all labs, one lab panel, one drug). Where a table records both an order and its outcome, the second component says which: ORDERED or RESULT, START or STOP, or MAR (Medication Administration Record: the bedside log of each dose given, held or refused). UNK stands for a null component that must not drop the row (see Null handling).

Code Table Time Value and extra columns
HOSPITAL_ADMISSION//<admission type>//<source> admission admission reason for visit in text_value
HOSPITAL_DISCHARGE//<destination> admission discharge
DIAGNOSIS//ICD//10//<ICD-10-CM code> admission discharge diagnosis text; diagnosis_rank PRIMARY or SECONDARY
<FIELD>//<value> demographics static FIELD is GENDER, MARITAL_STATUS, RACE, ETHNICITY, LANGUAGE or BLOOD_TYPE
ALLERGY//<allergen> allergy static reaction in text_value
FLOWSHEET//<FLO_MEAS_ID> flowsheet recorded reading or score; flow_type
ICU_ADMISSION, ICU_DISCHARGE icu start, end
TRANSFER location start
MEDICATION//START//<drug> medications start date, 23:59:59 ordered dose (raw text if a range); dose_unit, frequency
MEDICATION//STOP//<drug> medications end date, 23:59:59
MEDICATION//MAR//<drug>//<action> medications administration given dose; dose_unit, route
LAB//ORDERED//<PROC_ID> labs order date, 23:59:59
LAB//RESULT//<PROC_ID>//<component> labs result date, 23:59:59 result; order_status
ORDER//ORDERED//<order type>//<PROC_ID> orders order date, 23:59:59 order_status
ORDER//RESULT//<order type>//<PROC_ID> orders result date, 23:59:59 result; order_status

codes.parquet carries a description for flowsheet, lab and order codes, taken from the release's display names.

Null handling

A null component of a composite code drops the row under MEDS-Extract 0.7. Components are therefore coalesced with ?? 'UNK' wherever a null must not drop the row (admission type and source, discharge destination, lab component, order type, medication administration action).

The rest are deliberately left uncoalesced. In the release, the code columns of flowsheets, labs, orders and allergies are never null, and MEDICATION is null in 10 of 12,698,867 rows, so a coalesce would add nothing. A missing ICD-10 code or demographic produces no event rather than an UNK category, because a missing value is not an observed one.

Diagnoses

The primary and secondary ICD-10 codes on each visit become DIAGNOSIS//ICD//10//<code> events at discharge time, with diagnosis_rank set to PRIMARY or SECONDARY. About 4% of cells list up to four codes separated by a comma and a space; each code becomes its own event, carrying the cell's full diagnosis text. No parent_codes metadata is attached: the same code occurs as both primary and secondary, and MEDS-Extract rejects one code produced by two code templates. DIAGNOSIS//ICD//10//<code> maps to ICD10CM/<code> directly.

Other tables

  • ICU stays and bed moves carry only their start and end times in the release (no unit, room or bed), so they become bare ICU_ADMISSION, ICU_DISCHARGE and TRANSFER events.
  • Demographics and allergies carry no time in the release and are static events.
  • Flowsheet, lab and order-result values are free text. The numeric reading is kept where it parses; scored flowsheet items charted as <score>--><label> (e.g. -1-->Drowsy) keep their score. The raw string goes to text_value unless it is just the number. Epic's nonnumeric sentinel 9999999 never becomes a numeric value.
  • Medications: each row of the release is one administration and repeats its order's start and end, so an order yields one START, one STOP and one MAR event per administration.
  • Orders hold every order type except labs; roughly half carry a single result.
  • Birth and death: the release has no birth date, age or death time, so there are no MEDS_BIRTH or MEDS_DEATH events.
  • Not extracted: the telemetry (alarms, 2-second measurements, waveforms; per-admission files keyed by file name, far larger than the EMR), social_hx (no event times and unlabeled Epic category codes), and the medication order date.

Validation against the release

The spec was first written from the authors' release code (Carescape) and did not run on the published files. Profiling the 1.0.0 EMR CSVs (value shapes and null counts only, never values) showed what had to change:

  • Tables are lowercase (admission, labs, ...) rather than Patient, Labs, ...; the keys are aMRN and aCSN, not csID and CS_PAT_ENC_CSN_ID.
  • Each timestamp is one already-shifted column rather than a date plus an HH:MM:SS column. Labs and orders keep only the date (see Timestamps).
  • icu and location have no department, event type, room or bed columns.
  • resulting_aCSN holds the string nan for unresulted rows.
  • 1,536 ICD-10 codes occur as both primary and secondary diagnoses, and some cells list several codes (see Diagnoses). The synthetic test covers both.
  • Medication start and end times are always midnight, and orders carries results of its own (it holds no lab orders).

All ten CSVs are valid UTF-8. On the full 1.0.0 EMR tables (6.3 GB of CSVs read), meds-extract-run with MEDS-Extract 0.7.1 finishes in about 90 seconds on a laptop with about 6.5 GB peak memory, producing 52.6M events for 18,472 subjects. Fewer lab, order and medication start/stop events come out than raw rows because identical events are merged: lab and order times have day resolution, and the medication table repeats an order's start and end on every administration row.

MEDS-transforms settings

If you want to convert a large dataset, you can parallelize the MEDS-transforms stages (the MEDS-transformation step that takes the longest).

Using local parallelization with the hydra-joblib-launcher package:

pip install hydra-joblib-launcher --upgrade

Then write a stage-runner file and pass it to the run:

# runner.yaml
parallelize:
  n_workers: 8
  launcher: joblib
meds-extract-run spec=ALOTT output_dir=$MEDS_OUTPUT_DIR stage_runner_fp=runner.yaml

The number of subjects per shard is n_subjects_per_shard in the spec's etl: block (1000 by default); raise it to cut the parallelization overhead.

Development

uv sync --group dev
uv run pytest tests/
uv run pre-commit run --all-files

A release bumps the version in pyproject.toml with uv version --bump, commits it and pushes a tag of that exact version, which publishes to PyPI and creates the GitHub release. See RELEASING.md for choosing the version, the one-time PyPI setup and recovering from a failed release.

ALOTT has no open demo, so CI runs the spec end to end over a small synthetic input generated in tests/e2e_synthetic_test.py. That checks the spec's mechanics, not its agreement with the real release. Never commit raw ALOTT data or MEDS output derived from it.

Citation

Please cite the following original dataset when using ALOTT:

@article{PhysioNet-alott-1.0.0,
  author = {Lawrence, John and Rayo, Mike and Huerta, Timothy},
  title = {{ALarms, Outcomes Telemetry with Timing (ALOTT): a Bedside-EMR Database}},
  journal = {{PhysioNet}},
  year = {2025},
  month = mar,
  note = {Version 1.0.0},
  doi = {10.13026/sbq5-dy17},
  url = {https://doi.org/10.13026/sbq5-dy17}
}

Also cite the ETL framework used to extract the dataset:

@software{van_de_Water_ALOTT_MEDS_ETL_2025,
author = {van de Water, Robin Philippus},
license = {MIT},
month = apr,
title = {{ALOTT\_MEDS ETL}},
url = {https://github.com/rvandewater/ALOTT_MEDS},
year = {2025}
}

For citing MEDS in general:

@article{mcdermott2026meds,
  title={MEDS—An Emerging Data Standard and Ecosystem for Health AI Research},
  author={McDermott, Matthew BA and Steinberg, Ethan and Fries, Jason A and van de Water, Robin P and Pang, Chao and Rockenschaub, Patrick and Renc, Pawel and Oh, Jungwoo and Stankevi{\v{c}}i{\=u}t{\.e}, Kamil{\.e} and Xu, Justin and others},
  journal={NEJM AI},
  volume={3},
  number={6},
  pages={AIra2501253},
  year={2026},
  publisher={Massachusetts Medical Society}
}

Metadata

Release files for ALOTT-MEDS 0.0.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for ALOTT-MEDS 0.0.1
File Size Uploaded Provenance
alott_meds-0.0.1.tar.gz 18.0 kB With provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for ALOTT-MEDS 0.0.1
File Interpreter ABI Platform
alott_meds-0.0.1-py3-none-any.whl Python 3 none any Details

Total release size: 31.3 kB

Release files / alott_meds-0.0.1.tar.gz

Download URL alott_meds-0.0.1.tar.gz
Size 18.0 kB
Tags Source
SHA-256 checksum
How to use checksums
b6110566d0a5f50a0cd9c03335a81dba776dcb2a1d4e7f33c9cb5d969a987a62
BLAKE2b-256 checksum
How to use checksums
c10316f1b5ef5a7343a18d1eb10be8ad8d0ada26094e6a871a055fc5282258fb
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 27, 2026.

Transparency log

Release files / alott_meds-0.0.1-py3-none-any.whl

Download URL alott_meds-0.0.1-py3-none-any.whl
Size 13.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
0d4fefc4d547edaa803d234c90ba363a3977636d16b5637cc1a1a6cdc5e5547f
BLAKE2b-256 checksum
How to use checksums
7b63bad13c8c882cd03659f9dc8bb2d86d3a85ba6f23665de8dd81162da49ec9
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 27, 2026.

Transparency log

Security for ALOTT-MEDS 0.0.1

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for alott_meds-0.0.1.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 27, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.0.1 This release

2 release files Full provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page