Source code for allensdk.brain_observatory.behavior.data_objects.metadata.subject_metadata.age

import re
import warnings
from typing import Optional

from pynwb import NWBFile

from allensdk.core import DataObject
from allensdk.core import \
    JsonReadableInterface, LimsReadableInterface, NwbReadableInterface
from allensdk.internal.api import PostgresQueryMixin


[docs]class Age(DataObject, JsonReadableInterface, LimsReadableInterface, NwbReadableInterface): """Age of animal (in days)""" def __init__(self, age: int): super().__init__(name="age_in_days", value=age)
[docs] @classmethod def from_json(cls, dict_repr: dict) -> "Age": age = dict_repr["age"] age = cls._age_code_to_days(age=age) return cls(age=age)
[docs] @classmethod def from_lims(cls, behavior_session_id: int, lims_db: PostgresQueryMixin) -> "Age": query = f""" SELECT a.name AS age FROM behavior_sessions bs JOIN donors d ON d.id = bs.donor_id JOIN ages a ON a.id = d.age_id WHERE bs.id = {behavior_session_id}; """ age = lims_db.fetchone(query, strict=True) age = cls._age_code_to_days(age=age) return cls(age=age)
[docs] @classmethod def from_nwb(cls, nwbfile: NWBFile) -> "Age": age = cls._age_code_to_days(age=nwbfile.subject.age) return cls(age=age)
[docs] @staticmethod def to_iso8601(age: int): if age is None: return 'null' return f'P{age}D'
@staticmethod def _age_code_to_days(age: str, warn=False) -> Optional[int]: """Converts the age code into a numeric days representation Parameters ---------- age age code, ie P123 warn Whether to output warning if parsing fails """ if not age.startswith('P'): if warn: warnings.warn('Could not parse numeric age from age code ' '(age code does not start with "P")') return None match = re.search(r'\d+', age) if match is None: if warn: warnings.warn('Could not parse numeric age from age code ' '(no numeric values found in age code)') return None start, end = match.span() return int(age[start:end])