Repository navigation
Conversation
1363751 to
43d9215
Compare
Test CoverageTotal: 73.64% (20110 / 27310 lines)
|
43d9215 to
e95e18e
Compare
e95e18e to
9a279fb
Compare
9a279fb to
76bdfff
Compare
76bdfff to
4459ca6
Compare
4459ca6 to
fcfebb5
Compare
fcfebb5 to
794ef79
Compare
|
/review |
There was a problem hiding this comment.
Previous review
AI Review
suggestion: need change
decision: human review
Thank you for this contribution. It adds the five YAIB MIMIC-IV benchmark tasks, with a very thorough parity check against YAIB-cohorts and clear documentation of the deviations. Coverage is 85.15% for yaib_mimic4.py (above the 80% bar) and 72.69% for the whole repository (above the 60% bar).
A maintainer will take a look as well. The change adds a required column (admissions.deathtime) and six new tables to the shared mimic4_ehr.yaml config, which every MIMIC4EHRDataset user loads, so the loader's requirements change for existing users. That touches a core area.
To get this merged:
- YAIBMortalityMIMIC4 leaves
_EXTRA_TABLESempty, but_icu_deathsneeds thetransferstable. If a user omitstransfers,pre_filterpasses and the task then fails with a raw polars column error for any patient with an in-hospital death. Set_EXTRA_TABLES = ("transfers",)for the mortality task so it raises the same clear ValueError as the others. Add a test for this. - All tests call
task.__call__on hand-built Patient objects. Please add at least one integration test that goes through the dataset load path for the new yaml tables andset_task, including processor fitting. For example, use the mimic4demo fixture, as the existing MIMIC-IV task tests do. This would check the new config entries and the declared input_schema.
Optional suggestions:
- State in the AKI and sepsis docstrings that onsets before ICU admission (negative hours) also lead to exclusion.
- Requiring
deathtimemeans admissions files without that column will fail to load. Consider mentioning this in the docs, or making the column optional.
Reviewed commit a504416
44db391 to
79dfb54
Compare
|
/review |
There was a problem hiding this comment.
Previous review
AI Review
suggestion: need change
decision: human review
Thank you for this contribution. Porting the five YAIB MIMIC-IV cohorts, with exact-match checks against YAIB-cohorts on the demo data, is a substantial addition. Coverage is above the bar: yaib_mimic4.py is at 86.4% (bar 80%), and the repository total is 73.3% (bar 60%).
A maintainer will also take a look. The change edits the shared mimic4_ehr.yaml, so every MIMIC4EHRDataset load now requires an admissions.deathtime column. Real MIMIC-IV has that column, but this changes the loading behavior for existing users. The shared test fixture changed too.
To get this merged:
- Null care unit in the ICU death check. In
_icu_deaths,~pl.col("careunit").is_in(icu_wards).fill_null(False)treats a nullcareuniton the last ward before discharge as non-ICU. That drops the death from the label. The docstring says a death is non-ICU only when the ward is known and not an ICU ward. Either make null count as unknown, so the death stays an ICU death, or change the docstring to describe the current behavior. If the current behavior is what ricu does, please say so in a comment. Please also add a test for the null case. - Missing test for
YAIBLengthOfStayMIMIC4. Please add a small test. It should check that the label ismin(168, end - hour)on the same grid asdynamic, and that stays are capped at 7 days.
Optional suggestions:
- Add direct tests for the vasopressor, ventilation and intubation paths feeding SOFA.
- Add a docs entry or a short example for the new tasks.
- Add a test that loads the updated YAML config and the demo fixture, so the
deathtimerequirement is exercised.
Reviewed commit 79dfb54
79dfb54 to
8baeb1e
Compare
|
/review |
| - "seq_num" | ||
| - "short_description" | ||
|
|
||
| transfers: |
There was a problem hiding this comment.
[medium] New MIMIC-IV tables are not exercised by any dataset-level test
The six tables added here (transfers, microbiologyevents, chartevents, outputevents, inputevents, procedureevents) are only read through hand-built Patient objects in tests/core/test_yaib_mimic4.py. No test loads them through MIMIC4EHRDataset, runs YAIB's pre_filter through set_task, or checks the config column names against a real table layout. The demo fixture in test-resources/core/mimic4demo has none of these tables, while existing MIMIC-IV task tests (tests/core/test_mimic4_los.py, tests/core/test_mimic4_dka.py) run set_task on that fixture. Fix: add minimal CSV fixtures for these tables (or extend the demo fixture) and one set_task test per task family, including the missing-table ValueError path through the real loader.
| "na": (110, 165, [_lab(50983)]), | ||
| "neut": (0, 100, [_lab(51256)]), | ||
| # Deviates from YAIB, see the o2sat note in _YAIBMIMIC4Task. | ||
| "o2sat": (50, 100, [_chart(220277, 226253, 220227), _lab(50817)]), |
There was a problem hiding this comment.
[low] o2sat includes the SpO2 desaturation alarm limit (226253)
Item 226253 is 'SpO2 Desat Limit', which the docstring itself says is a monitor alarm threshold rather than a measurement. Including it in the o2sat feature mixes a setting into the measured series. The PR says it is kept for consistency with ricu, so this is a documented choice, not a bug. Consider dropping it, or at least marking the choice in the feature table, once the YAIB-match claim is settled.
| VariantClassificationClinVar, | ||
| ) | ||
| from .patient_linkage_mimic3 import PatientLinkageMIMIC3Task | ||
| from .yaib_mimic4 import ( |
There was a problem hiding this comment.
[low] New public tasks have no API docs entry
Five public task classes are exported here, but no docs/api/tasks/*.rst file or docs/api/tasks.rst toctree entry is added, unlike other task modules such as InHospitalMortalityMIMIC4. Add an autoclass page per task (or one for the module) so the new tasks appear in the API reference.
There was a problem hiding this comment.
AI Review
suggestion: approve
decision: human review
Thank you for this contribution. It adds the five YAIB MIMIC-IV benchmark tasks (mortality, kidney function, remaining length of stay, AKI and sepsis), ported carefully from ricu and YAIB-cohorts. Your write-up of the verification against YAIB output and of the two deliberate deviations is very clear.
The code looks correct and complete as far as I can tell, and it does what the description says. It doesn't appear to duplicate existing PyHealth functionality. Coverage meets the bar: pyhealth/tasks/yaib_mimic4.py is at 91.43% (bar 80%), pyhealth/tasks/__init__.py is at 89.47%, and the whole repository is at 73.64% (bar 60%).
A maintainer will take a look before this is merged. The change adds admissions.deathtime to the shared MIMIC-IV EHR config as a column that is always loaded, and the dataset loader requires every configured column to exist. That changes what every MIMIC-IV EHR dataset needs from its input data, and it is why the test fixture had to change. This is a shared contract, so a maintainer should confirm it is acceptable. I can't promise the outcome.
Optional suggestions:
- Add a test that loads the new config tables through
MIMIC4EHRDataset, then runsset_taskwithpre_filterand processor fitting. The current tests only calltask(patient)on hand-built patients. This would exercise the dataset path end to end. - Add a docs/api entry and an example script for the new tasks.
o2satincludes item 226253, the SpO2 desat limit, which your docstring notes is an alarm threshold rather than a measurement. You keep it for consistency with ricu, which is reasonable. Please consider whether to keep it.
Reviewed commit 8baeb1e
Port the five MIMIC-IV tasks of YAIB (Yet Another ICU Benchmark, van de Water et al., ICLR 2024) from YAIB-cohorts and the ricu version it pins: ICU mortality after 24 hours, kidney function (day 2 creatinine), remaining length of stay, AKI (KDIGO) and sepsis (Sepsis-3), the last three predicted at every hour with the timeseries_* label modes. All tasks share the YAIB base cohort and 48 hourly dynamic and 4 static features with ricu's item IDs, unit conversions and plausibility bounds, and declare YAIB's preprocessing (zscore, missing-value indicators, forward fill) in their input schema. The MIMIC-IV EHR config gains the transfers, microbiologyevents, chartevents, outputevents, inputevents and procedureevents tables and admissions.deathtime. Verified against the YAIB-cohorts output on the MIMIC-IV demo: with ricu 0.6.0's definitions, every task matches exactly (cohort, labels and every hourly and static feature value). Two ricu 0.6.0 bugs that YAIB inherits are fixed and documented: o2sat now includes arterial oxygen saturation, and the SOFA grid runs to the last hour of data.
The MIMIC-IV EHR config now loads admissions.deathtime, which the YAIB mortality task needs, and the loader requires every configured column. The real MIMIC-IV admissions table has this column (right after dischtime) in both the demo (2.2) and 3.1; the hand-made fixture in test-resources/core/mimic4demo did not, so every test loading admissions from it failed with a KeyError. Add the column; deceased rows (hospital_expire_flag = 1) get their dischtime, as for 93% of in-hospital deaths in MIMIC-IV 3.1, and the others are empty.
…ntilation and GCS paths
8baeb1e to
6ac17e7
Compare
Summary
Adds the five MIMIC-IV tasks of YAIB (Yet Another ICU Benchmark, van de Water et al., ICLR 2024) to
pyhealth.tasks. The three hourly tasks use thetimeseries_binary/timeseries_regressionlabel modes and processors.YAIBMortalityMIMIC4binaryYAIBKidneyFunctionMIMIC4regressionYAIBLengthOfStayMIMIC4timeseries_regression(per hour)YAIBAKIMIMIC4timeseries_binary(per hour)YAIBSepsisMIMIC4timeseries_binary(per hour)YAIB builds its cohorts with the YAIB-cohorts R scripts on top of the ricu R package. The tasks port that logic: the YAIB base cohort, the 48 hourly dynamic and 4 static features (ricu's item IDs, unit conversions and plausibility bounds, hourly binning from ICU admission, ricu's mapping of admission-level labs onto ICU stays), the task-specific exclusions and labels, and for AKI and sepsis the KDIGO staging, the SOFA score and the suspected-infection rule of the ricu version YAIB pins (
prockenschaub/ricu-packageat0969a52, 0.6.0). The tasks declare YAIB's preprocessing in theirinput_schema; fit it on the training patients withset_task(task, split=...).The MIMIC-IV EHR config gains the
transfers,microbiologyevents,chartevents,outputevents,inputeventsandprocedureeventstables, which are only loaded when listed intables, and thedeathtimecolumn ofadmissions, which is always loaded (see Test fixture below).Verification against YAIB
YAIB-cohorts was run unchanged in its Docker image on the MIMIC-IV demo (2.2), and each task's cohort, labels and features were compared with its output. With ricu 0.6.0's definitions (see the deviations below), every task matches exactly:
For sepsis, the intermediate values were also compared with ricu's own output for every demo ICU stay: all 28,714 hourly SOFA values, the continuous antibiotic starts, the sample hours, the suspected infection times and the onsets are identical.
On full MIMIC-IV 3.1 (YAIB used 2.2, which has fewer ICU stays), the cohorts scale consistently with the paper:
The verification scripts and the YAIB-cohorts setup are not part of this PR.
Deviations from YAIB
Two ricu 0.6.0 bugs that YAIB inherits are fixed and documented in the task docstrings. With the buggy behaviour swapped back in, the results above match YAIB exactly.
o2sat: ricu 0.6.0 lists the blood gas item 50817 underchartevents(it is alabeventsitem), so arterial oxygen saturation never matches, and the charted arterial saturation (220227) is missing. Both items exist in MIMIC-IV 2.2, and ricu'so2satfor eICU and AUMCdb already combined pulse oximetry with arterial saturation; ricu fixed this in July 2024. On the demo, this changes 57 of 115,200 mortality feature values, allo2sat.fill_gapstakes the duration of a stay's time range as its end, so the hourly SOFA grid runs tolast - firstinstead of the last hour of data. The SOFA score is now computed up to the last hour; on the demo this changes no sepsis onset.Other YAIB details are kept as they are, for example that AKI urine output is not divided by weight for stays without any weight record (dividing by 75 kg instead changes 3 demo stays relative to YAIB).
Tests
tests/core/test_yaib_mimic4.pycovers each task on synthetic patients: the base cohort exclusions, labels, unit conversions, lab attribution to stays, ICU death attribution, the kidney function window, the AKI creatinine and urine stages, and the sepsis suspected infection, PaO2/FiO2 pairing, GCS, 24-hour urine, range merging and onset.Test fixture
The mortality task needs the time of death, so the config now also loads
admissions.deathtime, and the dataset loader requires every configured column to exist. The real MIMIC-IVhosp/admissionstable has this column, right afterdischtime, in both MIMIC-IV 2.2 and 3.1:hospital_expire_flag = 1)deathtimedeathtimeis only set for in-hospital deaths. The hand-made fixture intest-resources/core/mimic4demo/hosp/admissions.csvomitted the column, so every test loading admissions from it failed withKeyError: "['admissions/deathtime'] not in index"(24 tests intest_mimic4_dka,test_mimic4_los,test_mimic4_readmission_prediction,test_stagenet_task_leakage_preventionandtest_drug_recommendation_atc3). This PR adds the column to the fixture at the same position as in MIMIC-IV: the two deceased rows get theirdischtime(in MIMIC-IV 3.1,deathtimeequalsdischtimefor 93% of in-hospital deaths) and the others are empty. None of those tasks readdeathtime, so their results are unchanged.