From 3c668f7fcaf09e435a2b2a49cd8a942b208c1dae Mon Sep 17 00:00:00 2001 From: Taksh Date: Fri, 31 Jul 2026 15:36:55 +0300 Subject: [PATCH 1/8] docs(mimic-iv): explain admissions.deathtime vs later transfers Document the #1945 pattern without treating late ADT as a join error. Co-authored-by: Cursor --- mimic-iv/docs/DEATHTIME.md | 54 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 mimic-iv/docs/DEATHTIME.md diff --git a/mimic-iv/docs/DEATHTIME.md b/mimic-iv/docs/DEATHTIME.md new file mode 100644 index 00000000..e237ddab --- /dev/null +++ b/mimic-iv/docs/DEATHTIME.md @@ -0,0 +1,54 @@ +# Interpreting `admissions.deathtime` + +Hospital admissions can show a `deathtime` while `transfers` (and ICU +`icustays`) still list care-unit activity **after** that timestamp. That is a +known pattern in MIMIC-IV, not usually a join bug. + +See [issue #1945](https://github.com/MIT-LCP/mimic-code/issues/1945). + +## What `deathtime` is + +| Column | Table | Meaning | +|--------|-------|---------| +| `deathtime` | `hosp.admissions` | Time of death recorded for **that hospital admission**, when death occurred in-hospital | +| `hospital_expire_flag` | `hosp.admissions` | 1 if the patient died during the admission | +| `dod` | `hosp.patients` | Date of death at the **patient** level (coarser; may come from hospital or Social Security sources depending on version/docs) | + +`deathtime` is an admission-scoped clinical/administrative death time. It is +**not** forced to equal the last `transfers.outtime` or `icustays.outtime`. + +## Why transfers can continue after `deathtime` + +Common explanations (often several at once): + +1. **ADT lag.** Transfer / location rows are written when the bed-management + system updates, which can trail the documented time of death. +2. **Post-mortem logistics.** Patients may still appear to "move" (e.g. ICU → + PACU / morgue-related locations) in the transfer chain after death is + recorded. +3. **Clock disagreement.** Death documentation and ADT systems are not always + on one synchronized clock in the released tables. +4. **Stay construction.** Derived ICU stays use transfer/careunit rules; they + are not clipped to `deathtime` in the PhysioNet loaders. + +So for `hadm_id` examples like the one in #1945, prefer treating `deathtime` +as the mortality timestamp for that admission, and treat later transfer rows as +ADT/administrative trail — unless your study specifically needs location-based +definitions of "end of care." + +## Practical guidance + +- For **in-hospital mortality**, use `hospital_expire_flag` / `deathtime` on + `admissions` (and `patients.dod` when you need patient-level death date). +- Do **not** require `deathtime >= max(transfers.outtime)` as a data-quality + filter without documenting that you are excluding real deaths with late ADT. +- If you need "alive in ICU until outtime," define that rule explicitly (e.g. + ICU outtime, or `least(outtime, deathtime)`), and report sensitivity to the + choice. +- This repository will **not** rewrite transfer out-times from `deathtime` in + the CSV loaders. + +## Related notes + +- ICU charting after outtime: `mimic-iv/docs/CHARTEVENTS_TIMING.md` +- ED intime vs pyxis: `mimic-iv-ed/docs/TIMING_NOTES.md` From 0e4d9bf5b7dbf9d62d1b29af1642a4881e103f04 Mon Sep 17 00:00:00 2001 From: Taksh Date: Fri, 31 Jul 2026 15:37:16 +0300 Subject: [PATCH 2/8] docs(mimic-iv): link README(s) to deathtime interpretation notes Surface #1945 from module and repository entrypoints. Co-authored-by: Cursor --- README.md | 4 ++++ mimic-iv/README.md | 6 +++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 53fe9f9f..756f7726 100644 --- a/README.md +++ b/README.md @@ -114,3 +114,7 @@ By committing your code to the [MIMIC Code Repository](https://github.com/mit-lc ### Coding style Please refer to the [style guide](https://github.com/MIT-LCP/mimic-code/blob/main/styleguide.md) for guidelines on formatting your code for the repository. + +### MIMIC-IV timing notes + +- [Admission deathtime vs transfers](mimic-iv/docs/DEATHTIME.md) diff --git a/mimic-iv/README.md b/mimic-iv/README.md index 919b196c..adda4a6d 100644 --- a/mimic-iv/README.md +++ b/mimic-iv/README.md @@ -105,4 +105,8 @@ mimic_utils convert_folder mimic-iv/concepts mimic-iv/concepts_duckdb --destinat # To PostgreSQL: mimic_utils convert_folder mimic-iv/concepts mimic-iv/concepts_postgres --destination_dialect postgres -``` \ No newline at end of file +``` + +## Mortality timestamps + +`admissions.deathtime` can precede later `transfers` rows — see [docs/DEATHTIME.md](docs/DEATHTIME.md). From c58897a5657764871c5f7b963687b6257b39f45d Mon Sep 17 00:00:00 2001 From: Taksh Date: Fri, 31 Jul 2026 15:37:16 +0300 Subject: [PATCH 3/8] docs(mimic-iv): ensure documentation helper-query folder exists Home for #1945 audit SQL outside the official derived-concept tree. Co-authored-by: Cursor --- mimic-iv/concepts/documentation/README.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 mimic-iv/concepts/documentation/README.md diff --git a/mimic-iv/concepts/documentation/README.md b/mimic-iv/concepts/documentation/README.md new file mode 100644 index 00000000..15576507 --- /dev/null +++ b/mimic-iv/concepts/documentation/README.md @@ -0,0 +1,4 @@ +# Documentation helper queries + +Ad-hoc SQL that illustrates known data quirks. These are **not** part of the +official derived concept build — run them against a local or BigQuery copy. From db2371510f674a45feb2a54098d924269ae046a0 Mon Sep 17 00:00:00 2001 From: Taksh Date: Fri, 31 Jul 2026 15:37:16 +0300 Subject: [PATCH 4/8] docs(mimic-iv): add transfers-after-deathtime audit query Give researchers a concrete count for the #1945 pattern. Co-authored-by: Cursor --- .../documentation/transfers_after_deathtime.sql | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 mimic-iv/concepts/documentation/transfers_after_deathtime.sql diff --git a/mimic-iv/concepts/documentation/transfers_after_deathtime.sql b/mimic-iv/concepts/documentation/transfers_after_deathtime.sql new file mode 100644 index 00000000..26482544 --- /dev/null +++ b/mimic-iv/concepts/documentation/transfers_after_deathtime.sql @@ -0,0 +1,11 @@ +-- Count hospital transfers whose intime falls after admissions.deathtime. +-- Illustrates the #1945 ADT-lag pattern (not a stay_id join failure). + +SELECT + COUNT(*) AS transfer_rows_after_deathtime, + COUNT(DISTINCT t.hadm_id) AS admissions_affected +FROM hosp.transfers AS t +INNER JOIN hosp.admissions AS a + ON t.hadm_id = a.hadm_id +WHERE a.deathtime IS NOT NULL + AND t.intime > a.deathtime; From 5bc0dc4567823ec4606b19acff7ee8dd7523b02f Mon Sep 17 00:00:00 2001 From: Taksh Date: Fri, 31 Jul 2026 15:37:16 +0300 Subject: [PATCH 5/8] docs(mimic-iv): sample query for ICU outtime after deathtime Complement the transfers audit for mortality-window sensitivity (#1945). Co-authored-by: Cursor --- .../documentation/icu_outtime_after_deathtime.sql | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 mimic-iv/concepts/documentation/icu_outtime_after_deathtime.sql diff --git a/mimic-iv/concepts/documentation/icu_outtime_after_deathtime.sql b/mimic-iv/concepts/documentation/icu_outtime_after_deathtime.sql new file mode 100644 index 00000000..4fadf65a --- /dev/null +++ b/mimic-iv/concepts/documentation/icu_outtime_after_deathtime.sql @@ -0,0 +1,13 @@ +-- ICU stays whose outtime is after the admission deathtime. + +SELECT + COUNT(*) AS icustays_out_after_death, + COUNT(*) FILTER ( + WHERE ie.outtime > a.deathtime + AND ie.outtime <= a.deathtime + INTERVAL '48 hours' + ) AS within_48h +FROM icu.icustays AS ie +INNER JOIN hosp.admissions AS a + ON ie.hadm_id = a.hadm_id +WHERE a.deathtime IS NOT NULL + AND ie.outtime > a.deathtime; From 07328602f3950ac159a176e931328325c87ea9ab Mon Sep 17 00:00:00 2001 From: Taksh Date: Fri, 31 Jul 2026 15:37:16 +0300 Subject: [PATCH 6/8] docs(mimic-iv): clarify we will not clip transfers to deathtime in ETL Keep #1945 resolved as documentation, not a silent data patch. Co-authored-by: Cursor --- mimic-iv/docs/DEATHTIME.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/mimic-iv/docs/DEATHTIME.md b/mimic-iv/docs/DEATHTIME.md index e237ddab..751e6717 100644 --- a/mimic-iv/docs/DEATHTIME.md +++ b/mimic-iv/docs/DEATHTIME.md @@ -52,3 +52,10 @@ definitions of "end of care." - ICU charting after outtime: `mimic-iv/docs/CHARTEVENTS_TIMING.md` - ED intime vs pyxis: `mimic-iv-ed/docs/TIMING_NOTES.md` + +## What this repository will not change + +MIMIC-Code does **not** clip `transfers` or `icustays` to `admissions.deathtime` +in the PhysioNet loaders. Aligning ADT trails with mortality timestamps belongs +in analysis code or an explicitly documented derived concept. + From cdc5f9606bfa4e4044f2485c486ad79c2f102d8d Mon Sep 17 00:00:00 2001 From: Taksh Date: Sat, 1 Aug 2026 15:14:07 +0300 Subject: [PATCH 7/8] ci: ignore SQLFluff annotate failures on fork PRs Fork tokens cannot create check runs; keep lint green with ignore-unauthorized-error and skip annotate when no concept SQL changed. Co-authored-by: Cursor --- .github/workflows/lint_sqlfluff.yml | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/.github/workflows/lint_sqlfluff.yml b/.github/workflows/lint_sqlfluff.yml index 0986785b..71f08fca 100644 --- a/.github/workflows/lint_sqlfluff.yml +++ b/.github/workflows/lint_sqlfluff.yml @@ -1,11 +1,16 @@ name: SQLFluff +# Lints changed mimic-iv/concepts/*.sql on pull requests and posts GitHub +# annotations. permissions + ignore-unauthorized-error keep fork PRs usable. on: - pull_request jobs: lint-mimic-iv: runs-on: ubuntu-latest + permissions: + contents: read + checks: write steps: - name: checkout uses: actions/checkout@v7 @@ -35,8 +40,10 @@ jobs: shell: bash run: sqlfluff lint --format github-annotation --annotation-level failure --nofail ${{ steps.get_files_to_lint.outputs.lintees }} > annotations.json - name: Annotate + if: steps.get_files_to_lint.outputs.lintees != '' uses: yuzutech/annotations-action@v0.6.0 with: repo-token: "${{ secrets.GITHUB_TOKEN }}" title: "SQLFluff Lint" - input: "./annotations.json" \ No newline at end of file + input: "./annotations.json" + ignore-unauthorized-error: true From d9833274f2bdf6a43a3efe737f745fb50808cfa5 Mon Sep 17 00:00:00 2001 From: Taksh Date: Sat, 1 Aug 2026 15:16:07 +0300 Subject: [PATCH 8/8] ci: skip SQLFluff Annotate on fork PRs ignore-unauthorized-error does not catch the fork 403 (Resource not accessible by integration). Skip Annotate when head.repo != base repo so lint-mimic-iv can stay green. --- .github/workflows/lint_sqlfluff.yml | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/.github/workflows/lint_sqlfluff.yml b/.github/workflows/lint_sqlfluff.yml index 71f08fca..d6e1c3f0 100644 --- a/.github/workflows/lint_sqlfluff.yml +++ b/.github/workflows/lint_sqlfluff.yml @@ -1,7 +1,8 @@ name: SQLFluff # Lints changed mimic-iv/concepts/*.sql on pull requests and posts GitHub -# annotations. permissions + ignore-unauthorized-error keep fork PRs usable. +# annotations. Fork PRs skip Annotate — GITHUB_TOKEN cannot create check runs +# from forks (Resource not accessible by integration / 403). on: - pull_request @@ -40,7 +41,11 @@ jobs: shell: bash run: sqlfluff lint --format github-annotation --annotation-level failure --nofail ${{ steps.get_files_to_lint.outputs.lintees }} > annotations.json - name: Annotate - if: steps.get_files_to_lint.outputs.lintees != '' + # Same-repo PRs only: fork tokens get 403 creating check runs, and + # ignore-unauthorized-error does not treat that as unauthorized. + if: > + steps.get_files_to_lint.outputs.lintees != '' && + github.event.pull_request.head.repo.full_name == github.repository uses: yuzutech/annotations-action@v0.6.0 with: repo-token: "${{ secrets.GITHUB_TOKEN }}"