Skip to content

Commit 1e809fa

Browse files
committed
Preserve NWB subject age reference in metadata
1 parent c3931cc commit 1e809fa

3 files changed

Lines changed: 57 additions & 0 deletions

File tree

‎dandi/consts.py‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232

3333
metadata_nwb_subject_fields = (
3434
"age",
35+
"age__reference",
3536
"date_of_birth",
3637
"genotype",
3738
"sex",

‎dandi/metadata/util.py‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,8 @@ def extract_age(metadata: dict) -> models.PropertyValue | None:
247247
except (KeyError, TypeError, ValueError):
248248
if metadata.get("age") is not None:
249249
duration, ref = parse_age(metadata["age"])
250+
if metadata.get("age__reference") == "gestational":
251+
ref = "Gestational"
250252
else:
251253
return None
252254
else:

‎dandi/tests/test_metadata.py‎

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
import numpy as np
3535
from pydantic import ByteSize
3636
from pynwb import NWBHDF5IO, NWBFile, TimeSeries
37+
from pynwb.file import Subject
3738
import pytest
3839
import requests
3940
from semantic_version import Version
@@ -475,6 +476,59 @@ def test_time_extract() -> None:
475476
)
476477

477478

479+
@pytest.mark.ai_generated
480+
@pytest.mark.parametrize("reference", ["birth", "gestational"])
481+
def test_age_reference_roundtrip(tmp_path: Path, reference: str) -> None:
482+
path = tmp_path / "age.nwb"
483+
nwb = NWBFile("age reference", "age", datetime(2020, 1, 1, tzinfo=tzutc()))
484+
nwb.subject = Subject(age="P3W", age__reference=reference)
485+
with NWBHDF5IO(str(path), "w") as io:
486+
io.write(nwb)
487+
metadata = get_metadata(path)
488+
assert metadata["age__reference"] == reference
489+
age = extract_age(metadata)
490+
assert age is not None
491+
assert age.value == "P3W"
492+
expected = (
493+
AgeReferenceType.GestationalReference
494+
if reference == "gestational"
495+
else AgeReferenceType.BirthReference
496+
)
497+
assert age.valueReference == PropertyValue(value=expected)
498+
499+
500+
@pytest.mark.ai_generated
501+
@pytest.mark.parametrize("reference", ["birth", None])
502+
@pytest.mark.parametrize("legacy", [False, True])
503+
def test_age_reference_legacy(reference: str | None, legacy: bool) -> None:
504+
age = extract_age(
505+
{"age": "Gestational week 3" if legacy else "P3W", "age__reference": reference}
506+
)
507+
assert age is not None
508+
assert age.value == "P3W"
509+
assert age.valueReference == PropertyValue(
510+
value=AgeReferenceType.GestationalReference
511+
if legacy
512+
else AgeReferenceType.BirthReference
513+
)
514+
515+
516+
@pytest.mark.ai_generated
517+
@pytest.mark.parametrize("reference", ["birth", "gestational", None])
518+
def test_age_reference_preserves_birth_dates(reference: str | None) -> None:
519+
age = extract_age(
520+
{
521+
"age": "P3W",
522+
"age__reference": reference,
523+
"date_of_birth": "2020-01-01T00:00:00Z",
524+
"session_start_time": "2020-01-03T00:00:00Z",
525+
}
526+
)
527+
assert age is not None
528+
assert age.value == "P2D"
529+
assert age.valueReference == PropertyValue(value=AgeReferenceType.BirthReference)
530+
531+
478532
def test_time_extract_gest() -> None:
479533
"""extract age with Gestational ref"""
480534
meta_birth = {

0 commit comments

Comments
 (0)